Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5
2732 字
14 分钟
CTFHUB-skilltree-Bypass disable_function

CTFHUB-skilltree-Bypass disable_function#

声明#

  1. 本文为CTFHUB平台技能树WEB进阶模块部分习题解题记录,用于个人学习总结和原理分享,部分内容为经查阅总结所得,可能存在错误或者表述不当,仅供参考,以及因能力有限和时间原因,暂时仅给出蚁剑插件利用过程和原理分析,后续可能会有其它解法补充。
  2. 蚁剑插件源码下载’https://github.com/Medicean/as_bypass_php_disable_functions/‘,可直接在蚁剑应用内插件商店直接下载。

T1 LD_PRELOAD#

  1. CTFHub官方WP:LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。putenv()用来改变或增加环境变量的内容. 参数string 的格式为name=value, 如果该环境变量原先存在, 则变量内容会依参数string 改变, 否则此参数内容会成为新的环境变量.
  2. 来到靶场,看到该页面存在一个小马,用ant连接,打开蚁剑连接该文件。 web
  3. 连接后经过检查发现无法在虚拟终端执行命令,选择蚁剑插件的disable_functions插件,选择LD_PRELOAD模式点确认,提示生成了一个名为.antproxy.php,其作用流程大致如下(以whoami为例):
  • 蚁剑终端输入 whoami;
  • 发送加密命令到 .antproxy.php;
  • .antproxy.php 解密命令;
  • 检查 /tmp/hack.so 是否存在;
  • 不存在则写入 hack.so;
  • putenv(“LD_PRELOAD=/tmp/hack.so”);
  • error_log(“whoami”, 1) 触发 sendmail;
  • sendmail 进程加载 hack.so;
  • hack.so 构造函数执行;
  • unsetenv(“LD_PRELOAD”);
  • system(“whoami”) 执行;
  • 结果写入 /tmp/result;
  • .antproxy.php 读取 /tmp/result;
  • 加密输出结果;
  • 返回加密结果给蚁剑;
  • 蚁剑解密并显示 whoami 输出)。 process
  1. 重新配置并连接该.antproxy.php文件。 process
  2. 浏览根目录发现/readflag和/flag文件,flag无法直接读取,看到/readfile执行读取flag的命令,并且认为tac是可用的,对flag进行读取。 process process
  3. 或者更好是执行./readflag,会自动读取flag内容。 flag
  4. 对于LD_PRELOAD的利用条件,可参考下图总结。 sum

T2 SHELL_SHOCK#

  1. Shellshock是Bash程序的一个漏洞。当Bash遇到以(){开头的环境变量时,会错误地执行后面跟的命令。 Apache的mod_cgi模块会把 HTTP 请求头(比如 User-Agent)设置成环境变量传给CGI脚本。如果CGI脚本由Bash执行,攻击者可以把恶意命令放在请求头里,比如 User-Agent: () { :; }; /bin/ls,Bash解析时就会触发漏洞,额外执行/bin/ls。
  2. 回到靶场,题目依旧给出小马,用蚁剑连接。 process
  3. 连接时候注意编码,不然连不上,可切换base64编解码,成功连接。 process
  4. 发现其它目录权限被禁止。 process
  5. 用Apache_mod_cgi模式拿到flag。 flag

T3 Apache_mod_cgi#

  1. Apache_mod_cgi模式的核心原理,是完全不依赖PHP来执行系统命令,直接绕过了整个disable_functions的限制机制,通过上传配置文件.htaccess使得Apache将所有以.xxx结尾的文件,都当成CGI程序来执行,这之后上传一个该后缀名的恶意shell脚本,通过访问该脚本,运行该shell脚本。
  2. 利用需要满足条件为:
  • Web 服务器必须是 Apache。
  • Apache 必须加载了 mod_cgi 模块。
  • Apache 的配置必须允许使用.htaccess文件(即AllowOverride不为None)。
  • 当前目录必须有文件写入权限。
  1. 执行如T2流程,拿到flag。 flag
  2. 联想:这种思路在文件上传漏洞利用的时候也有用到,通过上传图片马和.htaccess将图片作php解析来连接,利用条件近似,只不过本模式将目标执行环境转化为系统shell执行。

T4 PHP-FPM#

  1. 简介:PHP-FPM(PHP FastCGI Process Manager)是PHP的一个进程管理器,它作为FastCGI进程管理器来运行,负责处理来自Web服务器(如 Nginx、Apache)的PHP请求。
  2. 该模式原理:伪造一个FastCGI客户端,直接和PHP-FPM通信,PHP-FPM通过FastCGI协议接收请求时,允许客户端传递PHP_VALUE和PHP_ADMIN_VALUE参数,动态修改PHP配置,比如设置auto_prepend_file = php://input让PHP执行HTTP请求体中的代码、临时覆盖disable_functions
  3. 将插件配置中地址选择为如图地址(即PHP-FPM运行端口),添加数据连接上传的.antproxy.php。 process
  4. 一样到根目录执行./readflag拿到flag。 flag

T5 GC UAF#

  1. 本题环境为php7-gc-bypass漏洞,影响范围是linux、php7.0-7.3,可利用PHP garbage collector程序中的堆溢出触发进而执行命令。
  2. 蚁剑的GC-UAF模式利用的是PHP7.0-7.3版本中垃圾回收机制的一个内存漏洞,通过向服务器发送一个特制的反序列化字符串,在PHP堆中构造出一个包含循环引用的复杂数据结构,当垃圾回收器处理这个结构时会产生逻辑错误,导致一个正在被使用的PHP数组对象被错误地提前释放形成UAF状态,随后通过精确的内存布局操作在被释放的内存空间上覆盖一个伪造的zend_object结构,将其内部的函数表指针劫持指向system等危险函数,最终当PHP代码(如对象析构时的__destruct方法)间接调用这个伪造对象时,程序流程就被成功劫持并执行任意系统命令,从而完全绕过disable_functions的限制。
  3. 通过蚁剑利用方法还是很简单的,依旧选择该模式到根目录执行./readflag拿到flag。 flag

T6 Json Serializer UAF#

  1. 漏洞介绍报告可参考’https://bugs.php.net/bug.php?id=77843’,简单说,在PHP 7.3.3 及之前的多个版本中,存在释放后使用(Use-After-Free,UAF),可能导致内存破坏,在特定条件下可被利用执行任意代码,如下图测试代码,json_encode([&$arr])开始执行,编码器发现$arr是一个数组,开始遍历其元素,$arr[0]是一个实现了JsonSerializable接口的X对象实例,在jsonSerialize()方法内执行了unset($arr[0]),删除了外层数组$arr的第一个元素,即正在被编码的这个对象本身,此时该数组不在引用X对象,PHP垃圾回收机制可能会将内存回收,jsonSerialize()方法执行完毕,返回$this,而此处内存已经被释放,导致程序崩溃。 flag
  2. 该插件利用已有的一句话木马,上传一个php代码触发UAF漏洞,通过操纵内存布局,将程序中原有的函数指针,覆盖为system等危险函数的地址,从而生成一个代理shell。
  3. 同样的利用思路,选择对应模式拿到flag。 flag

T7 BackTrace UAF#

  1. 漏洞介绍报告可参考’https://bugs.php.net/bug.php?id=76047&edit=1’,给出的测试php代码如下(关键代码已标注功能),在蚁剑中,通过原shell上传脚本,通过改造的vuln类,探测版本确定偏移量,搜索system地址,在释放内存位置写入恶意数据,然后触发__destruct()来触发UAF,并访问已经被释放内存,执行恶意数据。
<?php
class Vuln {
public $a;
public function __destruct() {
global $backtrace;
unset($this->a); //释放$a指向的字符串
$backtrace = (new Exception)->getTrace(); //生成异常回溯信息(调用时会遍历调用栈,收集每个栈帧信息,且会访问栈帧的变量:包括释放的变量,进而触发UAF)
}
}
function trigger_uaf($arg) {
$arg = str_shuffle(str_repeat('A', 79));//创建一个字符串
$vuln = new Vuln();
$vuln->a = $arg;//该对象a属性指向字符串
}
// 调用触发
trigger_uaf('x');
  1. 同样的利用思路,选择对应模式拿到flag。 flag

T8 FFI 扩展#

  1. 题目:FFI 扩展已经通过RFC, 正式成为PHP7.4的捆绑扩展库, FFI 扩展允许 PHP 执行嵌入式 C 代码。并且环境中给出参考的FFI详解:‘https://www.laruence.com/2020/03/11/5475.html’
  2. 阅读完FFI扩展的基本功能,大致能绕过原理:通过FFI直接调用C标准库的system()等函数,完全绕过PHP层面的disable_functions限制。插件可能的功能和流程为:利用shell上传利用脚本->检测PHP版本和FFI扩展->用FFI::cdef()加载libc.so->向FFI声明C语言system()函数原型->调用函数并且返回执行结果。
  3. 插件利用方式如图,不多介绍。 flag
  4. 对于使用FFI扩展的防护方法,文章给出通过设置ffi.enable=preload,把所有会调用FFI API的函数都定义在preload脚本中,所有的FFI API只能被可控制的preload脚本调用,详细可以阅读原文。

T9 iconv#

  1. 使用相同的利用插件思路可以轻松拿到flag,暂时不放过程了。
  2. 利用背景条件:当linux系统下,PHP环境启用了iconv扩展且putenv()函数未被禁用时,可以利用PHP的iconv扩展 + GCONV环境变量劫持来绕过disable_functions。
  3. 通过分析插件原码’https://github.com/Medicean/as_bypass_php_disable_functions/blob/master/core/iconv/index.js’,在插件对环境进行检查后,通过下列代码生成了恶意的gconv模块,此句cmd用PHP内置的Web服务器在随机端口启动服务(该环境不受Web环境disable_functions限制)。
let cmd = `${phpbinary} -n -S 127.0.0.1:${port} -t ${webrootdir}`;
let fileBuffer = self.generateExt(cmd);

之后如下代码将生成的.so文件传到可写目录,通过new Promise包装上传操作,上传成功后调用res(ext_path)将.so文件的路径传递出去,在后续.then((p) => {…})中接收这个路径,一方面通过path.dirname(p)获取目录用于设置GCONV_PATH,另一方面用p.substring(0, p.length-3)去掉.so 后缀后写入gconv-modules 配置文件中。

let ext_path = `${wdir}/.${String(Math.random()).substr(2, 5)}${self.ext_name}`;
core.request(
core.filemanager.upload_file({
path: ext_path,
content: fileBuffer
})
)

下面这段中,payload内容为写入gconv-modules配置文件,指定自定义gconv目录,触发iconv()调用加载.so模块,进而启动PHP内置Web服务器。

var payload = `file_put_contents("${payloaddir}/gconv-modules",base64_decode("${gconvmodules}")); //在gconv-modules配置文件写入恶意.so的目录。
putenv("GCONV_PATH=${payloaddir}"); //让iconv()在${payloaddir}目录读取gconv-modules配置文件
if(function_exists('iconv')){
iconv("payload","UTF-8","whatever"); //iconv被触发,按照顺序执行payload。
}else if(function_exists('iconv_strlen')){ //备选
iconv_strlen("1","payload");
}else if(function_exists('file_get_contents')){ //备选
@file_get_contents("php://filter/convert.iconv.payload.UTF-8/resource=data://text/plain;base64,MQ==");
}else{
@fopen('php://filter/convert.iconv.payload.UTF-8/resource=data://text/plain;base64,MQ==','r');
};
echo(1);`;

由于本块篇幅过长,后面代码分析暂时省略,大致是通过请求传递payload,插件通过fsockopen()检测指定端口是否开放,确认PHP内置Web服务器成功启动,接着通过uploadProxyScript()方法写入一个代理脚本(.antproxy.php),蚁剑自动添加该脚本作为新的Shell连接,便获得了一个绕过disable_functions限制的WebShell。

CTFHUB-skilltree-Bypass disable_function
http://124.70.202.140/posts/post-21/21/
作者
Ne+N3k_O
发布于
2026-04-01
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时