关于SHA1碰撞——比较两个binary的不同之处

来源:互联网 发布:李荣浩2017新专辑知乎 编辑:程序博客网 时间:2024/06/05 07:22

参考:
How do I compare binary files in Linux?
https://shattered.it
Boston Key Party CTF 2017 Writeup: Prudentialv2

在这篇文章中,在作者打CTF的过程中碰到一个验证登录的问题。通过查看php源码,发现这样一个奇怪的逻辑:
username和password字段的值不能相同,但是他们的SHA1值必须相同,才能登录成功(getflag)。
源码如下:

<?phprequire 'flag.php';if (isset($_GET['name']) and isset($_GET['password'])) {    $name = (string)$_GET['name'];    $password = (string)$_GET['password'];    if ($name == $password) {        print 'Your password can not be your name.';    } else if (sha1($name) === sha1($password)) {      die('Flag: '.$flag);    } else {        print '<p class="alert">Invalid password.</p>';    }}?>

这篇文章提到google放出两个SHA1值相同而不一样(SHA256的值不通)的pdf文件, shattered-1.pdf和shattered-2.pdf
然而如何比较这两个文件的不同之处到底在哪里呢?
1. 通过cmp命令

cmp -l shattered-1.pdf shattered-2.pdf

输出发现不同的部分在前320个字节。
2. 用xxd将pdf文件dump到16进制文件中

xxd shattered-1.pdf > shattered-1.pdf.hexxxd shattered-2.pdf > shattered-2.pdf.hex

然后用colordiff来比较

colordiff shattered-1.pdf.hex shattered-2.pdf.hex

这里写图片描述
或者

$ vimdiff shattered-1.pdf.hex shattered-2.pdf.hex2 files to edit

在比较的同时还可以编辑。
这里写图片描述
但是如何把这个部分拿去登录呢?
使用Python的urllib库将两个文件的前320个字节用url编码(urlencode)。

➜  CTF/Boston_Key_Party_CTF2017 master ✓ python                                                                                                     [19:45:01]Python 2.7.12 (default, Sep 28 2016, 18:41:32)[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import urllib>>> urllib.quote(open("shattered-1.pdf", "rb").read()[:320])'%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1'>>> urllib.quote(open("shattered-2.pdf", "rb").read()[:320])'%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1'>>> urllib.quote(open("shattered-2.pdf", "rb").read()[:5])'%25PDF-'>>> urllib.quote(open("shattered-2.pdf", "rb").read()[:1])'%25'>>> urllib.quote(open("shattered-2.pdf", "rb").read()[:2])'%25P'

若不用urlencode,则得到的是这样的(16进制?)的字符串。

>>> urllib.quote(open("shattered-2.pdf", "rb").read()[:40])'%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/'>>> open("shattered-2.pdf", "rb").read()[:40]'%PDF-1.3\n%\xe2\xe3\xcf\xd3\n\n\n1 0 obj\n<</Width 2 0 R/'>>> type(open("shattered-2.pdf", "rb").read()[:40])<type 'str'>

然后这样构造HTTP请求:

GET http://54.202.82.13/?name=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&password=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1 HTTP/1.1Host: 54.202.82.13User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-US,en;q=0.5Referer: http://54.202.82.13/Connection: keep-alive

得到响应:

HTTP/1.1 200 OKVary: Accept-EncodingKeep-Alive: timeout=5, max=100Connection: Keep-AliveContent-Length: 165Content-Type: text/html; charset=UTF-8Date: Sun, 26 Feb 2017 03:24:42 GMTServer: Apache/2.4.18 (Ubuntu)<html><head>    <title>level1</title>    <link rel='stylesheet' href='style.css' type='text/css'></head><body>Flag: FLAG{AfterThursdayWeHadToReduceThePointValue}
0 0
原创粉丝点击