码迷,mamicode.com
首页 > 其他好文 > 详细

初探审计—md5类

时间:2019-07-10 12:26:14      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:use   code   md5值   写法   找不到   比较   ==   等于   构造   

0000 md5()和intval()

这是以下几种绕过技术的依据

01 “==”比较中的转化问题

php的“==”是值比较,不会比较类型。那么不同类型的比较会直接输出false吗?答案是否定的,比如string型==int型解释器会将string转化为int再比较。而string转化int,等价于使用intval(string)得到的返回值。

看看官网对intval()的一些解释:

如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
如果字符串以 "0" 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。

成功时返回 var 的 integer 值,失败时返回 0。
空的 array 返回 0,非空的 array 返回 1。

还有一条note:

Not mentioned elsewhere: intval(NULL) also returns 0.

02 md5

还有md5()函数的一些特点:

md5(array())为null

md5()为null

1111 md5比较绕过

Ox1 源码

<?php

$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
    echo "nctf{*****************}";
} else {
    echo "false!!!";
}}
else{echo "please input a";}

?>

Ox2 函数注解

01 $a = @$_GET[‘a‘]

$a=GET["a"]; 其中的 @ 是为了防止没有 $_GET[‘a‘]出现错误提示.

但是 @ 的代价过高, 一般都用 isset() 来判断一下.

比较通俗的写法是:

if (isset($_GET['a'] ))
{
    $a = $_GET['a'] ;
}else
{
    $a = null;
}

Ox3 payload

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

不讨论具体的环境的话,代码的逻辑是想找到一个和 ‘QNKCDZO‘ 有同一hash值的字符串(hash碰撞)。但在实践的环境下因为“==”弱类型比较和 ‘QNKCDZO‘ md5以‘0e‘开头,可以构造md5值为0eXXXXXXXXXX 的字符串,利用弱类型的转换,将0eXXXXXXXXXX 转成0。

md5('240610708'); // 0e462097431906509019562988736854 
md5('QNKCDZO'); // 0e830400451993494058024219903391 

Ox4 总结

01 md5加密相等绕过

利用条件:使用为加盐的hash,使用弱等于作为hash校验的方式

构造:hash为0eXXXXXXXXXX的字符串

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

md5('240610708'); // 0e462097431906509019562988736854 
md5('QNKCDZO'); // 0e830400451993494058024219903391 

2222 md5($temp)==0

01 hash为0eXXXXXXXXXX的字符串

md5('240610708'); // 0e462097431906509019562988736854 
md5('QNKCDZO'); // 0e830400451993494058024219903391 

url:

http://127.0.0.1/bugs/23.php?password=QNKCDZO

02 $temp=array()

url:

http://127.0.0.1/bugs/23.php?password[]=1

03 $temp=null

url:

http://127.0.0.1/bugs/23.php?password=

333 md5()函数===使用数组绕过

===是比较类型和值,这时候构造“hash为0eXXXXXXXXXX的字符串”的字符不行了。

就利用数组,PHP对数组进行hash计算都会得出null的空值。

url:

http://127.0.0.1/bugs/18.php?username[]=1&password[]=2

总结

到这里其实没什么好总结的,记住0000的md5特性和intval的特性,就会对其绕过有了基本的认识了。

记住这个,免得关键时候找不到:

md5('240610708'); // 0e462097431906509019562988736854 
md5('QNKCDZO'); // 0e830400451993494058024219903391 

Ref

感谢"git主"(滑稽)地整理:github地址

感谢官网助攻:官网手册

php md5()

php password_hash()

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

初探审计—md5类

标签:use   code   md5值   写法   找不到   比较   ==   等于   构造   

原文地址:https://www.cnblogs.com/goodswarm/p/11163089.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!