收藏 [登录/注册] 欢迎
榕基门户网及子站
联系我们
  • 福建榕基软件股份有限公司
  • 电话:0591-87860988
  • 传真:0591-87869595
  • 地址:福建省福州市鼓楼区
  •    软件大道89号
  •    A区15座
  • 邮编:350003
您的当前位置:首页 > 技术支持 > 安全公告

如何使用黑盒方式检测弱密码散列算法(基于碰撞哈希算法)

2017年2月份,一群来自Google的工程师发现了首次SHA-1碰撞。即使NIST在2011年的时候就已经将这个哈希算法归类为“已过时算法”了,但它目前仍然在大规模地使用。

什么是哈希碰撞?

简单来说,当两个不同的明文值生成的是相同的哈希值时,便会发生一次哈希碰撞。哈希碰撞会导致各种各样的问题出现,但我们在这篇文章中不打算讨论这些问题。

在这篇文章中,我们将会从另一个角度来讨论有关哈希碰撞的问题。我们将跟大家介绍一种能够帮助我们检测一个网站是否使用了弱哈希函数的方法,而且整个过程不需要访问Web应用的源代码。我们姑且将这个方法称作“基于碰撞的哈希函数披露”(Collision Based Hashing Algorithm Disclosure)。

Google工程师所发现的碰撞将允许任何人创建出两个内容不同但哈希值相同的PDF文件。下面给出的是Google工程师所用的明文值:

字符串1:

 

255044462D312E330A25E2E3CFD30A0A0A312030206F626A0A3C3C2F57696474682032203020522F4865696768742033203020522F547970652034203020522F537562747970652035203020522F46696C7465722036203020522F436F6C6F7253706163652037203020522F4C656E6774682038203020522F42697473506572436F6D706F6E656E7420383E3E0A73747265616D0AFFD8FFFE00245348412D3120697320646561642121212121852FEC092339759C39B1A1C63C4C97E1FFFE017346DC9166B67E118F029AB621B2560FF9CA67CCA8C7F85BA84C79030C2B3DE218F86DB3A90901D5DF45C14F26FEDFB3DC38E96AC22FE7BD728F0E45BCE046D23C570FEB141398BB552EF5A0A82BE331FEA48037B8B5D71F0E332EDF93AC3500EB4DDC0DECC1A864790C782C76215660DD309791D06BD0AF3F98CDA4BC4629B1

字符串2:

 

255044462D312E330A25E2E3CFD30A0A0A312030206F626A0A3C3C2F57696474682032203020522F4865696768742033203020522F547970652034203020522F537562747970652035203020522F46696C7465722036203020522F436F6C6F7253706163652037203020522F4C656E6774682038203020522F42697473506572436F6D706F6E656E7420383E3E0A73747265616D0AFFD8FFFE00245348412D3120697320646561642121212121852FEC092339759C39B1A1C63C4C97E1FFFE017F46DC93A6B67E013B029AAA1DB2560B45CA67D688C7F84B8C4C791FE02B3DF614F86DB1690901C56B45C1530AFEDFB76038E972722FE7AD728F0E4904E046C230570FE9D41398ABE12EF5BC942BE33542A4802D98B5D70F2A332EC37FAC3514E74DDC0F2CC1A874CD0C78305A21566461309789606BD0BF3F98CDA8044629A1

上面给出的这两个字符串经过了十六进制编码,解码之后你就会发现这两个字符串拥有相同的SHA1值:

 

f92d74e3874587aaf443d1db961d4e26dde13e9c

基于碰撞的哈希函数披露

Web应用中的哈希算法

当你注册了一个在线服务之后,绝大多数的网站都将会把你密码所对应的哈希值存储在数据库中。这是一种非常好的安全实践方法,因为就算攻击者入侵了网站并窃取了数据库中的密码,他们得到的也是一串哈希值而并非明文密码。但这种情况之所以能够成立,前提就是网站必须使用健壮的哈希算法。这也就意味着,类似SHA-1和MD5这样的算法已经不再适用于Web应用了,但目前仍然有很多开发人员正在使用这些算法来计算密码的哈希。

当你尝试登录一个网站时,网站会计算你在登录表单中所填写密码的哈希值,然后再与后台数据库中存储的用户密码哈希进行对比,如果匹配则登录成功。因此,如果这个Web应用使用的是SHA-1哈希算法,那么就有可能出现哈希值相同但明文数据不同的密码。这也就意味着,我们可以使用两个不同的密码/字符串来登录同一个账号。

如果使用这种技术再配合黑盒测试的话,我们就可以确定一个Web应用是否使用了存在漏洞的哈希算法,请大家继续往下看。

基于碰撞的哈希函数披露是如何工作的?

攻击原理

理论上来说,其实这非常简单。选择一个需要测试的Web应用,然后用“密码1”创建一个账号。此时我们找出一个与“密码1”哈希值相同的“密码2”,并用“密码2”来尝试登录服务,如果登录成功的话,说明目标网站使用的就是SHA-1算法。

演示

假设你在注册Web应用账号时使用的密码为cleartext1,计算之后对应的哈希值为abcd(方便演示):

 

hash(cleartext1) == ‘abcd’

注:为了方便演示,我们这里没有使用加盐的哈希。

然后Web应用会将abcd存储在了数据库中,当你尝试再次进行登录时,系统会使用相同的哈希算法来对你在表单中输入的密码进行哈希计算,计算出的哈希值会跟数据库中存储的密码哈希进行比对,匹配即登录成功。

接下来,假设我们使用明文密码cleartext2来尝试登录,当Web应用使用SHA-1算法来对其进行计算之后,得出的是与cleartext1相同的哈希值:

 

hash(cleartext2) == ‘abcd’

系统会对cleartext2进行哈希计算,计算出的哈希值会跟数据库中存储的密码哈希进行比对,匹配即登录成功。

 

hash(password) == dbhash

但是这种方法也有一定的限制条件,在下列情况下我们的技术将失效:

1.      Web应用限制了登录表单和注册表单可接受的密码长度;

2.      设置了字符白名单;

3.      网站使用了加盐的哈希;

如何确定一个Web应用是否使用了SHA-1哈希算法

下面我们将一步一步告诉大家如何确定一个Web应用是否使用了SHA-1哈希算法。

1.      设置一个拦截代理(例如Netsparker),然后配置浏览器通过它来代理所有的请求。

2.      注册一个Web应用的账号,使用类似!!PASS!!这种识别度高的密码,当你拦截HTTP请求之后这种密码可以比较好发现。

3.      对代理拦截下来的注册请求进行修改,用上文给出的首次碰撞字符串(转换为URL编码)替换所有的!!PASS!!字符串。

 

注:为了对碰撞字符串进行URL编码,你需要在每一个编码字符前加一个%。你可以使用下面给出的PHP代码来完成编码操作:

 

implode(array_map(function($byte){ return'%' . $byte;},str_split($collisionstring,2)));

4.      向Web应用发送修改后的请求之后,系统将会生成对应的哈希值并存储在数据库中。如果Web应用使用的是SHA-1算法,那么生成的哈希值应该是f92d74e3874587aaf443d1db961d4e26dde13e9c。

5.      现在,尝试使用字符串!!PASS!!作为密码来尝试登录Web应用。

6.      拦截HTTP登录请求,使用URL编码后的第二个碰撞字符串替换所有的!!PASS!!。

7.      Web应用会对你提供的密码进行哈希计算,并与数据库中存储的值进行比对,此时的哈希值将仍是f92d74e3874587aaf443d1db961d4e26dde13e9c。

如果Web应用使用的是SHA-1哈希算法,那么即使你使用的是不同的密码,你仍然可以成功登录。

这种方法只适用于SHA-1算法吗?

当然不是,这种方法还适用于其他已知存在碰撞的哈希算法,例如MD5。下面是已知的MD5碰撞实例,你可以将其用于你的测试之中:

 

4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2

 

4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2

上述这两个字符串的哈希如下:

 

008ee33a9d58b51cfeb425b0959121c9

URL编码字符串

为了方便大家进行测试,下面给出了本文所使用的URL编码字符串:

SHA-1

字符串1:

 

%25%50%44%46%2D%31%2E%33%0A%25%E2%E3%CF%D3%0A%0A%0A%31%20%30%20%6F%62%6A%0A%3C%3C%2F%57%69%64%74%68%20%32%20%30%20%52%2F%48%65%69%67%68%74%20%33%20%30%20%52%2F%54%79%70%65%20%34%20%30%20%52%2F%53%75%62%74%79%70%65%20%35%20%30%20%52%2F%46%69%6C%74%65%72%20%36%20%30%20%52%2F%43%6F%6C%6F%72%53%70%61%63%65%20%37%20%30%20%52%2F%4C%65%6E%67%74%68%20%38%20%30%20%52%2F%42%69%74%73%50%65%72%43%6F%6D%70%6F%6E%65%6E%74%20%38%3E%3E%0A%73%74%72%65%61%6D%0A%FF%D8%FF%FE%00%24%53%48%41%2D%31%20%69%73%20%64%65%61%64%21%21%21%21%21%85%2F%EC%09%23%39%75%9C%39%B1%A1%C6%3C%4C%97%E1%FF%FE%01%73%46%DC%91%66%B6%7E%11%8F%02%9A%B6%21%B2%56%0F%F9%CA%67%CC%A8%C7%F8%5B%A8%4C%79%03%0C%2B%3D%E2%18%F8%6D%B3%A9%09%01%D5%DF%45%C1%4F%26%FE%DF%B3%DC%38%E9%6A%C2%2F%E7%BD%72%8F%0E%45%BC%E0%46%D2%3C%57%0F%EB%14%13%98%BB%55%2E%F5%A0%A8%2B%E3%31%FE%A4%80%37%B8%B5%D7%1F%0E%33%2E%DF%93%AC%35%00%EB%4D%DC%0D%EC%C1%A8%64%79%0C%78%2C%76%21%56%60%DD%30%97%91%D0%6B%D0%AF%3F%98%CD%A4%BC%46%29%B1

字符串2:

 

%25%50%44%46%2D%31%2E%33%0A%25%E2%E3%CF%D3%0A%0A%0A%31%20%30%20%6F%62%6A%0A%3C%3C%2F%57%69%64%74%68%20%32%20%30%20%52%2F%48%65%69%67%68%74%20%33%20%30%20%52%2F%54%79%70%65%20%34%20%30%20%52%2F%53%75%62%74%79%70%65%20%35%20%30%20%52%2F%46%69%6C%74%65%72%20%36%20%30%20%52%2F%43%6F%6C%6F%72%53%70%61%63%65%20%37%20%30%20%52%2F%4C%65%6E%67%74%68%20%38%20%30%20%52%2F%42%69%74%73%50%65%72%43%6F%6D%70%6F%6E%65%6E%74%20%38%3E%3E%0A%73%74%72%65%61%6D%0A%FF%D8%FF%FE%00%24%53%48%41%2D%31%20%69%73%20%64%65%61%64%21%21%21%21%21%85%2F%EC%09%23%39%75%9C%39%B1%A1%C6%3C%4C%97%E1%FF%FE%01%7F%46%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2%56%0B%45%CA%67%D6%88%C7%F8%4B%8C%4C%79%1F%E0%2B%3D%F6%14%F8%6D%B1%69%09%01%C5%6B%45%C1%53%0A%FE%DF%B7%60%38%E9%72%72%2F%E7%AD%72%8F%0E%49%04%E0%46%C2%30%57%0F%E9%D4%13%98%AB%E1%2E%F5%BC%94%2B%E3%35%42%A4%80%2D%98%B5%D7%0F%2A%33%2E%C3%7F%AC%35%14%E7%4D%DC%0F%2C%C1%A8%74%CD%0C%78%30%5A%21%56%64%61%30%97%89%60%6B%D0%BF%3F%98%CD%A8%04%46%29%A1

MD5

字符串1:

 

%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2

字符串2:

 

%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

 * 参考来源:netsparker, FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM