【Jarvis OJ】Login--password='".md5($pass,true)."'

Login

题目

需要密码才能获得flag哦。
题目链接:http://web.jarvisoj.com:32772

思路:
打开链接是一个提交password界面,放到burp里看一看呀~

 

【Jarvis OJ】Login--password='".md5($pass,true)."'

看到有提示哦~

Hint: "select * from `admin` where password='".md5($pass,true)."'"

一看到md5,我就想到password为md5为0e开头的值。

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

攻击者可以利用这一漏洞,通过输入一个经过哈希后以”0E”开头的字符串,即会被PHP解释为0,如果数据库中存在这种哈希值以”0E”开头的密码的话,他就可以以这个用户的身份登录进去,尽管并没有真正的密码。

输入
password;s878926199a
这时出现了Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /opt/lampp/htdocs/index.php on line 14.才发现以上行不通。出现这个问题的原因是没有理解".md5($pass,true)."的含义呀。

参考文章:https://blog.****.net/March97/article/details/81222922 哈哈,在这里我找到了md5(string,raw)的含义。

【Jarvis OJ】Login--password='".md5($pass,true)."'

mdr(string,raw)

 

关注重点放到

password='".md5($pass,true)."'

如何使".md5($pass,true)."为true呢?

参考:
http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/

原始md5可以包含任何字符,并且脚本将它们按原样放入查询中 - 它是一个sql注入版本。
我们要做的是强制使用原始md5包含'或'的密码,以便查询看起来像

SELECT login FROM admins WHERE  password  =  '<trash>' 或'1 <shit>'

这里使用的php代码

<?php 
for ($i = 0;;) { 
 for ($c = 0; $c < 1000000; $c++, $i++)
  if (stripos(md5($i, true), '\'or\'') !== false)
   echo "\nmd5($i) = " . md5($i, true) . "\n";
 echo ".";
}
?>

通过暴力**,最后找到了这样一个密码呀~I’ve found a password: ffifdyop, with hash: 276f722736c95d99e921722cf9ed621c (‘or’6<trash>).

content: ffifdyop
hex: 276f722736c95d99e921722cf9ed621c
raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
string: 'or'6]!r,b

但是我们思考一下为什么6\xc9]\x99\xe9!r,\xf9\xedb\x1c的布尔值是true呢?

这里引用一篇文章。“a string starting with a 1 is cast as an integer when used as a boolean."
在mysql里面,在用作布尔型判断时,以1开头的字符串会被当做整型数。要注意的是这种情况是必须要有单引号括起来的,比如password=‘xxx’ or ‘1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于password=‘xxx’ or true,所以返回值就是true。当然在我后来测试中发现,不只是1开头,只要是数字开头都是可以的。
当然如果只有数字的话,就不需要单引号,比如password=‘xxx’ or 1,那么返回值也是true。(xxx指代任意字符)