Fork me on GitHub

代码审计补充知识点

参考文献:https://hacksec.xyz/2018/03/23/php-trick/?nsukey=cWDNgiIxMsJayPNWtqM8Rc9amSOIgC0SI9Ko3jxxW2uV9mcoLNLdl4Q1U%2BrV9UhKIs3das0Cizzc8atumDKxG5nHSDPPthMpgeq5Xqa02MDie21AnddLn9BUUyOdXVEOsbvHRrlq1S61OS4%2BRpRffcBRIuwbJUdeL%2FEcZRNmvBtBzhuGQhuRU9fs%2BM9pyrRyVvKRlq5SmzZRSXFYcAjYcQ%3D%3D
https://www.jianshu.com/p/9c8c9272e12e

is_numeric函数
在判断是否是数字时会忽略字符串开头的’ ‘、’\t’、’\n’、’\r’、’\v’、’\f’。
​ 而’.’可以出现在任意位置,E、e能出现在参数中间,仍可以被判断为数字。也就是说

0.1e2”) >> TRUE```
1
intval()函数会忽略’’ ‘\n’、’\r’、’\t’、’\v’、’\0’ ,也就是说```intval(“\r\n\t 12”) >> 12

PHP变量名不能带有点[.] 和空格,否则在会被转化为下划线[_]

1
2
parse_str("na.me=admin&pass wd=123",$test);
var_dump($test);

结果:

1
2
3
4
5
6
array(2) {
["na_me"]=>
string(5) "admin"
["pass_wd"]=>
string(3) "123"
}

htmlspecialchars()函数默认只转义双引号不转义单引号,如果都转义的话需要添加上参数ENT_QUOTES

in_arrary()函数默认进行松散比较(进行类型转换)

1
2
in_arrary(“1asd”,arrart(1,2,3,4))    => true
in_arrary(“1asd”,arrart(1,2,3,4),TRUE) => false \\(需要设置strict参数为true才会进行严格比较,进行类型检测)

sprintf()格式化漏洞(可以吃掉转义后的单引号)
当我们输入的特殊字符被放到引号中进行转义时,但是又使用了sprintf函数进行拼接时,例如

中的 ‘%被当成使用%进行padding```,导致后一个’逃逸了
1
2

还有一种情况就是’被转义成了\’,例如输入```%’ and 1=1#```进入,存在SQL过滤,’被转成了\’,于是sql语句变成了 ```select * from user where username = ‘%\’ and 1=1#’;```如果这个语句被使用sprintf函数进行了拼接,%后的\被吃掉了,导致了’逃逸

<?php
$sql = “select from user where username = ‘%\’ and 1=1#’;”;
$args = “admin”;
echo sprintf( $sql, $args ) ;
//result: select
from user where username = ‘’ and 1=1#’
?>

1
不过这样容易遇到 PHP Warning: sprintf(): Too few arguments的报错,这个时候我们可以使用%1$来吃掉转义添加的\

<?php
$sql = “select from user where username = ‘%1$\’ and 1=1#’ and password=’%s’;”;
$args = “admin”;
echo sprintf( $sql, $args) ;
//result: select
from user where username = ‘’ and 1=1#’ and password=’admin’;
?>

1
2

⑥**php中 = 赋值运算的优先级高于and**

$c = is_numeric($a) and is_numeric($b)

1
2
3
4
5
6
7
程序本意是要a、b都为数字才会继续,但是当\$a为数字时,会先赋值给\$c,所以可能导致$b绕过检测


⑦**url标准的灵活性导致绕过filter_var与parse_url进行ssrf**
parse_url() 是专门用来解析 URL 而不是 URI 的。不过为遵从 PHP 向后兼容的需要有个例外,对 file:// 协议允许三个斜线(file:///...)。其它任何协议都不能这样.

filter_var()函数对于

http://evil.com;google.com

1
会返回false也就是认为url格式错误,但是对于

0://evil.com:80;google.com:80/

1
2
```
0://evil.com:80,google.com:80/

1
0://evil.com:80\google.com:80/

却返回true。

通过file_get_contents获取网页内容并返回到客户端有可能造成xss

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(filter_var($argv[1], FILTER_VALIDATE_URL)) {
// parse URL
$r = parse_url($argv[1]);
print_r($r);
// check if host ends with google.com
if(preg_match('/baidu\.com$/', $r['host'])) {
// get page from URL
$a = file_get_contents($argv[1]);
echo($a);
} else {
echo "Error: Host not allowed";
}
} else {
echo "Error: Invalid URL";
}

虽然通过filter_var函数对url的格式进行检查,并且使用正则对url的host进行限定,
但是可以通过data://baidu.com/plain;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo== 页面会将<script>alert(1)</script>返回给客户端,就有可能造成xss

parse_url与libcurl对与url的解析差异可能导致ssrf

当url中有多个@符号时,parse_url中获取的host是最后一个@符号后面的host,而libcurl则是获取的第一个@符号之后的。因此当代码对http://user@eval.com:80@baidu.com 进行解析时,PHP获取的host是baidu.com是允许访问的域名,而最后调用libcurl进行请求时则是请求的eval.com域名,可以造成ssrf绕过。此外对于https://evil@baidu.com这样的域名进行解析时,php获取的host是`evil@baidu.com`,但是libcurl获取的host却是evil.com

md5碰撞

1
2
3
4
5
6
7
$Param1="\x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x00\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\x55\x5d\x83\x60\xfb\x5f\x07\xfe\xa2"; 
$Param2="\x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x02\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\xd5\x5d\x83\x60\xfb\x5f\x07\xfe\xa2";
#008ee33a9d58b51cfeb425b0959121c9

$data1="\xd1\x31\xdd\x02\xc5\xe6\xee\xc4\x69\x3d\x9a\x06\x98\xaf\xf9\x5c\x2f\xca\xb5\x07\x12\x46\x7e\xab\x40\x04\x58\x3e\xb8\xfb\x7f\x89\x55\xad\x34\x06\x09\xf4\xb3\x02\x83\xe4\x88\x83\x25\xf1\x41\x5a\x08\x51\x25\xe8\xf7\xcd\xc9\x9f\xd9\x1d\xbd\x72\x80\x37\x3c\x5b\xd8\x82\x3e\x31\x56\x34\x8f\x5b\xae\x6d\xac\xd4\x36\xc9\x19\xc6\xdd\x53\xe2\x34\x87\xda\x03\xfd\x02\x39\x63\x06\xd2\x48\xcd\xa0\xe9\x9f\x33\x42\x0f\x57\x7e\xe8\xce\x54\xb6\x70\x80\x28\x0d\x1e\xc6\x98\x21\xbc\xb6\xa8\x83\x93\x96\xf9\x65\xab\x6f\xf7\x2a\x70";
$data2="\xd1\x31\xdd\x02\xc5\xe6\xee\xc4\x69\x3d\x9a\x06\x98\xaf\xf9\x5c\x2f\xca\xb5\x87\x12\x46\x7e\xab\x40\x04\x58\x3e\xb8\xfb\x7f\x89\x55\xad\x34\x06\x09\xf4\xb3\x02\x83\xe4\x88\x83\x25\x71\x41\x5a\x08\x51\x25\xe8\xf7\xcd\xc9\x9f\xd9\x1d\xbd\xf2\x80\x37\x3c\x5b\xd8\x82\x3e\x31\x56\x34\x8f\x5b\xae\x6d\xac\xd4\x36\xc9\x19\xc6\xdd\x53\xe2\xb4\x87\xda\x03\xfd\x02\x39\x63\x06\xd2\x48\xcd\xa0\xe9\x9f\x33\x42\x0f\x57\x7e\xe8\xce\x54\xb6\x70\x80\xa8\x0d\x1e\xc6\x98\x21\xbc\xb6\xa8\x83\x93\x96\xf9\x65\x2b\x6f\xf7\x2a\x70";
#79054025255fb1a26e4bc422aef54eb4

-------------本文结束感谢您的阅读-------------