无字母数字Webshell之提高篇
字数 1051 2025-08-18 11:37:41
无字母数字Webshell高级利用技术
一、问题背景
给定PHP代码限制条件:
<?php
if(isset($_GET['code'])){
$code = $_GET['code'];
if(strlen($code)>35){
die("Long.");
}
if(preg_match("/[A-Za-z0-9_$]+/",$code)){
die("NO.");
}
eval($code);
}else{
highlight_file(__FILE__);
}
限制条件:
- 代码长度不超过35个字符
- 不能包含字母、数字、下划线(_)和美元符号($)
二、PHP7解决方案
技术原理
PHP7修改了表达式执行顺序,支持($a)();这样的动态函数执行方式。
实现方法
使用取反(~)操作生成字符串:
(~%8F%97%8F%96%91%99%90)();
%8F%97%8F%96%91%99%90是"phpinfo"取反后的URL编码~操作符将字符串取反还原- 最后加
()执行函数
三、PHP5解决方案
技术难点
PHP5不支持($a)();这种动态函数执行方式,需要另寻他法。
解决思路
利用PHP反引号执行系统命令,结合Linux shell特性绕过限制。
关键点1:反引号执行命令
PHP中反引号可以执行系统命令,且不属于字母、数字或特殊字符。
关键点2:Linux glob通配符
.或source命令可以执行文件内容- Linux文件名支持glob通配符:
*匹配任意数量字符?匹配单个字符[^x]匹配非x字符[@-[]匹配大写字母(ASCII码中@到[之间的字符)
具体实现步骤
-
上传临时文件:
- 发送文件上传POST请求,PHP会生成
/tmp/phpXXXXXX临时文件 - 文件名最后6个字符是随机大小写字母
- 发送文件上传POST请求,PHP会生成
-
定位临时文件:
- 使用
/tmp/php*匹配临时文件 - 使用
[@-[]匹配大写字母,精准定位PHP生成的临时文件
- 使用
-
执行命令:
<?= . /tmp/php* [@-[];?>或更简洁的形式:
?><?= . ;?>
四、关键知识点总结
-
PHP7新特性:
- 支持
(expression)();直接执行动态函数 - 可利用取反操作生成所需函数名
- 支持
-
PHP5绕过技术:
- 反引号执行系统命令
- 结合Linux shell特性:
.命令执行文件- glob通配符高级用法
- ASCII码范围匹配
-
通配符技巧:
[@-[]匹配大写字母[^x]排除特定字符- 组合使用缩小匹配范围
五、防御建议
- 禁用危险函数:
eval()、system()、exec()等 - 严格过滤输入,不限于字母数字检查
- 限制临时文件目录权限
- 升级到PHP7+并禁用危险特性
- 使用disable_functions禁用危险函数
六、扩展思考
- 其他字符编码方式:异或、位运算等
- 不同环境下的利用方式差异
- 无字母数字限制下的其他语言webshell构造方法
通过深入理解语言特性和系统特性,即使在严格限制下也能找到突破方法,这对攻防双方都具有重要参考价值。