leak技巧以及DynELF的温习
一个简单的溢出,
read()函数的不正当使用引起的漏洞
我们分析汇编代码,基本可以推断出他的溢出字节是140,因为这里我们要求不提供libc,但是我没需要起shell,那么思路大概就是首先通过DynELF获取到system()的地址后,我们又通过read将“/bin/sh”写入到.bss段上,最后再调用system(.bss),执行“/bin/sh”。
构造Leak函数
pwntools提供的DynELF模块来进行内存搜索。关键我们需要一个leak(addr)函数。一般这种函数的构造如下。
1 | def leak(address): |
随后将这个函数作为参数再调用d = DynELF(leak, elf=ELF(‘./level2’))就可以对DynELF模块进行初始化了。然后可以通过调用system_addr = d.lookup(‘system’, ‘libc’)来得到libc.so中system()在内存中的地址。
关键的是,我们只能调用到sytem(),却不能直接起shell,我们还需要将`/bin/sh``写到BSS段
如何找到bss段
在蒸米的文章中,他是通过readelf -S level2
这样的命令,找打的bss段的地址,而我比较习惯用IDA做前期的分析,所以我会用Shift+F7
来找bss段,效果如下
.bss段是用来保存全局变量的值的,地址固定,并且可以读可写。
查找gadget 构造rop
执行完read()之后,调用的是**system(“/bin/sh/“)**,我们知道的是,read()的参数有三个,所以我们需要保证栈平衡,需要构造一个pop pop pop ret 的gadget,如何找到这gadget呢,正如蒸米大神说的,利用objdump,具体我们可以用如下的命令objdump -D level2 |cat -n |grep pop
效果如下:
这样,我们找到这样连续的3个pop,就能构造rop了。
最终exp
1 | #!/usr/bin/python |