【CTF】代码审计-01

md5加密相等绕过

md5()中需要一个是string类型的参数,但当传递一个array时,md5()不会报错,只是无法正确求出array的md5值,这样会导致任意两个array的md5值都会相等。

1
2
3
4
5
6
7
8
9
10
$test=$_GET['test']; 
$test=md5($test);

if($test=='0') {
print 'You passed stage 1.<br />';
}
else{
print "Game over at stage 1.";
exit();
}

如果hash值以“0e”开头,后边都是数字,再与数字比较,就会被解释为0*10^n,还是为0,就会被判断相等,绕过登录环节。

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以“0e”开头的哈希值都解释为0。如果两个不同的值经过哈希以后,都是“0e”开头,那么PHP将会认为他们相同。

eg:

1
2
QNKCDZO
0e830400451993494058024219903391
1
2
s878926199a
0e545993274517709034328855841020

sha()函数比较绕过

1
2
3
4
5
6
7
8
if ($_GET['name'] == $_GET['password']){
print 'Your password can not be your name.';
exit();
}
else if (sha1($_GET['name']) === sha1($_GET['password'])){
print 'You passed stage 2.<br />';
print 'Flag: '.$flag;
}

看似不可能,但如果把这两个字段构造为数组,如:?name[]=a&password[]=b,这样在第一处判断时两数组确实是不同的,但在第二处判断时由于sha1()函数无法处理数组类型,将报错并返回false,if 条件成立,获得flag。经验证md5()函数同样存在此漏洞。

bool欺骗

当存在json_decode和unserialize的时候,部分结构会被解释成bool类型,也会造成欺骗。

通过数组绕过函数

1
2
3
4
5
6
7
8
9
10
11
12
<?php
if(isset($_GET['content'])){
$filename = 'config.php';
$content = $_GET['content'];

if(is_int(stripos($content, 'php')) || is_int(stripos($content, '<'))) {
echo 'Invalid input';
} else {
file_put_contents($filename, $content);
echo 'Success';
}
}

stripos()函数:查找字符串在另一字符串中第一次出现的位置(不区分大小写),即在content文件中查找‘php’第一次出现的位置和’<’第一次出现的位置,有则返回位置,没有则返回false。字符串位置从 0 开始,不是从 1 开始。

file_put_contents()函数:把一个字符串写入文件中,把content参数的值写入config.php文件中。

绕过stripos()函数,就不用执行if分支。可以使用数组绕过,即让content为数组形式,在config.php里得到flag。

参考链接1

参考链接2