栈溢出——栈迁移
错误思路
漏洞
栈溢出
这里的buf溢出了0x40-0x28 个字节
checksec比较友好,没有开地址随机化。
解决
是一个ret2libc的题目,返回到puts打印libc_start_main的got表地址,确定libc的版本。
这里有一个问题就是我不知道这个count如果在我返回到libc_start_main的话是不是会被初始化,我先试一下。
然后计算system和/bin/sh, 返回到这里。
不行。因为这个libc的基址是后面计算才知道的,没法提前就写进去。
正确
不是这么搞的= =,好累。
正确的思路是栈迁移。
漏洞
还是栈溢出啊。判断是栈迁移的原因有几点
1. 因为count那个地方其实是一个hint,告诉你ret2libc是行不通的。
2. 能够构造成payload的长度是0x40-0x28其实只有0x18太短了。
3. 因为system的地址是算出来的,所以要多次输入,也就是多次返回到read,但是不能直接返回到main函数里面,所以说需要直接返回到read,并且多次通过read再一次栈溢出控制程序流程,所以需要控制栈的地址。但是实在程序加载的时候你是没法确定栈地址的[反正我现在不可以确定],于是就是栈迁移!
思路
栈迁移的基本思路是用leave;ret;
leave;ret;
mov %ebp,%esp
pop %ebp
pop %eip
这样就可以把esp劫持走。
这道题可以把栈迁移到bss。权限和大小是够的。
过程
- 第一次系统自带的read栈溢出需要打印基址以及实现栈迁移。选择bss段一个中间位置,瞎选一个bss+0x500
栈的构造应该是
esp junk data ...... ebp bss+0x500 put_plt pop1ret libc_start_main_got read_plt leave_ret 0 bss+0x500 0x100
- 第二次的栈溢出需要输入/bin/sh,然后执行system。
栈的构造是
esp/ebp bss+0x400
read_plt
pop3ret
0
bss+0x400
0x100
system_addr
0xdeadbeef
bss+0x400(bin_sh_addr)
pop1ret和pop3ret:
错误: 第一次不能实现这么多功能,他只有0x18个数据,payload长度超了。
所以要把他分成两次
- 第一次
esp junk data
... ...
ebp bss+0x500
read_plt
leave_ret
0
bss+0x500
0x100
- 第二次
esp/ebp bss+0x400
put_plt
pop1ret
libc_start_main_got
read_plt
leave_ret
0
bss+0x400
0x100
- 第三次
esp/ebp bss+0x500
read_plt
pop3ret
0
bss+0x500
0x100
system_addr
0xdeadbeef
bss+0x500
exp
1 |
|
后记
本来想用libcsearch找/bin/sh的地址直接返回,但是谁能想到他太不争气了,和本机的libc版本不同导致不知道找了个啥东西,也不知道system是怎么找对的。 还被师傅骂一通TAT还diss我代码写的丑TAT
这里有一个trick,libc=elf.libc,然后就不用导入libc了。
1 |
|