Как не надо сравнивать в PHP
Всем доброго здоровья. Сегодня мы поговорим с вами о такой проблеме, как “Некорректное использование операторов сравнения и динамическая типизация данных в PHP”. А точнее о том, как можно это использовать для обхода авторизации в веб приложениях. Те, кто крутится в теме ИБ, про это уже неоднократно слышали, возможно, не под таким страшным названием, а под названием PHP Magic Hash. Это не какое-то открытие Америки, а дабы собрать все мысли по этому вопросу в одном месте.
Let’s go my little friends!
Для начала небольшое вступление о самой проблеме. Впервые, 5 лет назад об этом заговорил Gregor Kopf http://blog.nibblesec.org/2010/12/typo3-sa-2010-020-typo3-sa-2010-022.html.
Довольно часто, начинающие и не очень программисты используют оператор нестрогого сравнения ==. Это очень удобный инструмент, когда вам не хочется запариваться о поступаемых данных. Ведь при проверке на соответствие таким способом, PHP сначала преобразовывает типы данных к одному виду и только потом проводит операцию их сравнения.
1 | var_dump("0" == "a"); // 0 != a -> FALSE |
Здесь сравниваются две строки string, поэтому результат отрицательный, но:
1 | var_dump(0 == "a"); // 0 == 0 -> TRUE |
Результат сравнения истина, т.к. строка “а” была приведена интерпретатором к числовому типу int:
1 | var_dump((int)"a"); // int(0) |
Если сравниваемые строки состоят только из чисел, то они будет приведены к числовому типу int, а затем проверены на равенство:
1 2 3 | var_dump("1"); // string("1"); var_dump("01"); // string("01"); var_dump("1" == "01"); // 1 == 1 -> TRUE |
Не скучайте, мы уже вплотную подходим к нашей проблеме:
1 | var_dump("200" == "2e2"); 200 == 200 -> true |
Ага! Тут строка “2e2” интерпретируется, как число с плавующей точкой float и означает 2*(10^2). Вот выдержка из руководства по PHP:
[themify_quote]Если строка не содержит какой-либо из символов ‘.’, ‘e’, или ‘E’, и значение числа помещается в пределы целых чисел (определенных PHP_INT_MAX), строка будет распознана как целое число (integer). Во всех остальных случаях она считается числом с плавающей точкой (float).[/themify_quote]
А теперь самое интересное — как все это можно применять.
Сейчас нам не нужно знать, что из себя представляет хэш-функция, об этом вы можете прочитать, например, в вики — https://ru.wikipedia.org/wiki/%D0%A5%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5. Сейчас нас интересует, что результат работы хэш функции — это некая строка символов, которую чаще всего представляют в 16-ричном виде (HEX):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <!DOCTYPE html><html dir="ltr" lang="en-US"><head><title>Online PHP editor | output for cijFt</title><base href="https://3v4l.org/"><meta name="keywords" content="php,test,run,execute,online,interactive,shell,console,codepad,fiddle,xdebug,vld,performance"><meta name="description" content="Run your php code online; get statistics, vld output and compare output from all versions."><meta name="author" content="Sjon Hortensius - root@3v4l.org"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="twitter:card" content="summary"><link rel="manifest" href="/manifest"><link rel="shortcut icon" href="/favicon.ico"><link rel="stylesheet" href="/s/c.49fa43d0.css"></head><body class="new script output"><header><a href="/"><h1>3v4l.org</h1><span>run code in 300+ PHP versions simultaneously</span></a><nav><ul><li><a href="/sponsor">sponsor</a><li><a href="/bughunt">bughunt</a></li><li><a href="/search">search</a></li><li><a href="/last">recent</a></li><li><a href="/about">about</a></li></ul></nav></header><meta property="og:image" content="https://3v4l.org/s/site_thumb.png"><meta property="og:type" content="article"><meta property="og:url" content="https://3v4l.org/cijFt"><meta property="og:description" content="View the output of this script on 3v4l.org: the online PHP shell with 250+ PHP versions"><div itemscope itemtype="http://schema.org/Article"><meta property="og:title" content="cijFt - created on 3v4l.org"><form method="post" action="/new" id="newForm"><div><input class="valid" type="text" name="title" id="title" maxlength="64" placeholder="Untitled" aria-label="Optional title" pattern="^[\x20-\x7e\x80-\xff]*$" /><time itemprop="datePublished" datetime="2015-06-14T08:17:39Z">@ 2015-06-14T08:17:39Z</time></div><div><textarea name="code" aria-label="code you want to submit"></textarea><code itemprop="articleBody" class="required invalid"><?php $t = '12345'; var_dump( md5($t) ); var_dump( sha1($t) ); var_dump( hash('sha256', $t) ); var_dump( hash('sha384', $t) ); var_dump( hash('sha512', $t) ); var_dump( hash('whirlpool', $t) ); var_dump( hash('ripemd160', $t) );</code></div><div><select class="valid" name="version" id="version" data-values='{"8.3.":12,"8.2.":24,"8.1.":30,"8.0.":[30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,3,2,1,0],"7.4.":[33,32,30,29,28,27,26,25,24,23,22,21,20,19,18,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0],"7.3.":33,"7.2.":34,"7.1.":33,"7.0.":33,"5.6.":40,"5.5.":38,"5.4.":45,"5.3.":29,"5.2.":17,"5.1.":6,"5.0.":5,"4.4.":9,"4.3.":11,"git.":["master_jit","master"],"rfc.":["property-hooks"]}'></select></div><input type="submit" value="eval();" title="shortcut: ctrl+enter" /></form><noscript><div class="alert warning"><h2>Enable javascript to submit</h2><p>You have javascript disabled. You will not be able to edit any code.</p></div></noscript><ul id="tabs"><li itemprop="articleSection" class="active"><a href="/cijFt">Output</a></li><li><a href="/cijFt/perf">Performance</a></li><li><a href="/cijFt/vld">VLD</a></li><li><a href="/cijFt/refs">References</a></li><li><a href="/cijFt/rfc">Branches</a></li></ul><div id="tab" itemprop="articleBody"><a id="output"></a><dl><dt id="v5.1.2">Output for <span title="released 2006-01-12">5.1.2</span> - <span title="released 2006-08-24">5.1.6</span>, <span title="released 2006-11-02">5.2.0</span> - <span title="released 2011-01-06">5.2.17</span>, <span title="released 2009-06-30">5.3.0</span> - <span title="released 2014-08-14">5.3.29</span>, <span title="released 2012-03-01">5.4.0</span> - <span title="released 2015-09-03">5.4.45</span>, <span title="released 2013-06-20">5.5.0</span> - <span title="released 2016-07-21">5.5.38</span>, <span title="released 2014-08-28">5.6.0</span> - <span title="released 2019-01-10">5.6.40</span>, <span title="released 2015-12-03">7.0.0</span> - <span title="released 2018-12-06">7.0.33</span>, <span title="released 2016-12-01">7.1.0</span> - <span title="released 2019-10-24">7.1.33</span>, <span title="released 2017-11-30">7.2.0</span> - <span title="released 2020-08-06">7.2.33</span>, <span title="released 2018-12-06">7.3.0</span> - <span title="released 2021-11-18">7.3.33</span>, <span title="released 2019-11-28">7.4.0</span> - <span title="released 2022-11-03">7.4.33</span>, <span title="released 2020-11-26">8.0.0</span> - <span title="released 2023-08-03">8.0.30</span>, <span title="released 2021-11-25">8.1.0</span> - <span title="released 2024-09-26">8.1.30</span>, <span title="released 2022-12-08">8.2.0</span> - <span title="released 2024-09-26">8.2.24</span>, <span title="released 2023-11-23">8.3.0</span> - <span title="released 2024-09-26">8.3.12</span></dt><dd>string(32) "827ccb0eea8a706c4c34a16891f84e7b" string(40) "8cb2237d0679ca88db6464eac60da96345513964" string(64) "5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5" string(96) "0fa76955abfa9dafd83facca8343a92aa09497f98101086611b0bfa95dbc0dcc661d62e9568a5a032ba81960f3e55d4a" string(128) "3627909a29c31381a071ec27f7c9ca97726182aed29a7ddd2e54353322cfb30abb9e3a6df2ac2c20fe23436311d678564d0c8d305930575f60e2d3d048184d79" string(128) "cce08bba3f2e3c029cd257104b06d4b075772d5f514cf1b7789506f9a69d53c51464881d2c18445ab290553b302f67a24b1c69e3e737a46215deaf43517e4960" string(40) "e9cbd2ea8015a084ce9cf83a3c65b51f8fa10a39" </dd><dt id="v5.0.0">Output for <span title="released 2004-07-13">5.0.0</span> - <span title="released 2005-09-05">5.0.5</span>, <span title="released 2005-11-24">5.1.0</span> - <span title="released 2005-11-28">5.1.1</span></dt><dd>string(32) "827ccb0eea8a706c4c34a16891f84e7b" string(40) "8cb2237d0679ca88db6464eac60da96345513964" Fatal error: Call to undefined function hash() in /in/cijFt on line 5 <br/><i>Process exited with code <b title="Generic Error">255</b>.</i></dd><dt id="v4.4.5">Output for <span title="released 2007-02-14">4.4.5</span> - <span title="released 2008-08-07">4.4.9</span></dt><dd>string(32) "827ccb0eea8a706c4c34a16891f84e7b" string(40) "8cb2237d0679ca88db6464eac60da96345513964" Fatal error: Call to undefined function: hash() in /in/cijFt on line 5 <br/><i>Process exited with code <b title="Generic Error">255</b>.</i></dd><dt id="v4.3.2">Output for <span title="released 2003-05-29">4.3.2</span> - <span title="released 2005-03-31">4.3.11</span>, <span title="released 2005-07-11">4.4.0</span> - <span title="released 2006-08-17">4.4.4</span></dt><dd>string(32) "827ccb0eea8a706c4c34a16891f84e7b" string(40) "8cb2237d0679ca88db6464eac60da96345513964" Fatal error: Call to undefined function: hash() in /in/cijFt on line 5 <br/><i>Process exited with code <b title="Generic Error">255</b>.</i></dd><dt id="v4.3.0">Output for <span title="released 2002-12-27">4.3.0</span> - <span title="released 2003-02-17">4.3.1</span></dt><dd>string(32) "827ccb0eea8a706c4c34a16891f84e7b" string(40) "8cb2237d0679ca88db6464eac60da96345513964" Fatal error: Call to undefined function: hash() in /in/cijFt on line 5 </dd></dl></div></div><hr /><div id="prefs">preferences:<input type="checkbox" id="darkMode" /><label for="darkMode">dark mode</label><input type="checkbox" id="livePreview" /><label for="livePreview">live preview</label></div><b>94.73</b> ms | <b>411</b> KiB | <b>5</b> Q<script src="/s/my.js" async></script><script src="/ext/diff.js" async></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/ace.js" integrity="sha384-/HiYf7uts/FC/PC50yfG3bXnxyMdlMFQpgaXPNOqiTJkQIbiBeth3J86SYJowDdK" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/ext-language_tools.js" integrity="sha384-pjdIm81c7GuHpSIwd3CpO3BgZx2B+hNtSvqcFnk7DCwPdEmf0xBCZX5i7jMj/ib6" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/mode-php.js" integrity="sha384-EO1oIq3Wru7Pa4jrHft9hrjz2SKGcYx1J/BteienRTZbIRvIWRADNyaNMCV4AmNN" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/theme-chrome.js" integrity="sha384-uOlVPZfQXFZofTCU/B1H8M3c6hww7F3VOufsGRLzlK4l9blvVqfJeONjYJM5+tnb" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/theme-chaos.js" integrity="sha384-mfoITkRp/u4qWConw/ovtCjvymPkNZiOj9csanbxBv8rdPa/v7wiZdnwF8i+M3UE" crossorigin="anonymous"></script></body></html> |
Хеш содержит символы из диапазона [a-f0-9], а мы знаем, что если в строке будет содержаться символ “e” и она будет состоять только из чисел (не считая “e” разумеется), то она будет приведена PHP к числовому типу. Отсюда и вытекает исследуемая проблема:
1 2 3 4 5 6 7 | <!DOCTYPE html><html dir="ltr" lang="en-US"><head><title>Online PHP editor | output for OL7ik</title><base href="https://3v4l.org/"><meta name="keywords" content="php,test,run,execute,online,interactive,shell,console,codepad,fiddle,xdebug,vld,performance"><meta name="description" content="Run your php code online; get statistics, vld output and compare output from all versions."><meta name="author" content="Sjon Hortensius - root@3v4l.org"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="twitter:card" content="summary"><link rel="manifest" href="/manifest"><link rel="shortcut icon" href="/favicon.ico"><link rel="stylesheet" href="/s/c.49fa43d0.css"></head><body class="new script output"><header><a href="/"><h1>3v4l.org</h1><span>run code in 300+ PHP versions simultaneously</span></a><nav><ul><li><a href="/sponsor">sponsor</a><li><a href="/bughunt">bughunt</a></li><li><a href="/search">search</a></li><li><a href="/last">recent</a></li><li><a href="/about">about</a></li></ul></nav></header><meta property="og:image" content="https://3v4l.org/s/site_thumb.png"><meta property="og:type" content="article"><meta property="og:url" content="https://3v4l.org/OL7ik"><meta property="og:description" content="View the output of this script on 3v4l.org: the online PHP shell with 250+ PHP versions"><div itemscope itemtype="http://schema.org/Article"><meta property="og:title" content="hash wrong equals - created on 3v4l.org"><form method="post" action="/new" id="newForm"><div><input class="valid" type="text" name="title" id="title" maxlength="64" placeholder="Untitled" aria-label="Optional title" value="hash wrong equals" pattern="^[\x20-\x7e\x80-\xff]*$" /><time itemprop="datePublished" datetime="2015-06-14T08:46:29Z">@ 2015-06-14T08:46:29Z</time></div><div><textarea name="code" aria-label="code you want to submit"></textarea><code itemprop="articleBody" class="required invalid"><?php $h1 = md5('240610708'); $h2 = md5('aabg7XSs'); var_dump($h1, $h2, $h1 == $h2);</code></div><div><select class="valid" name="version" id="version" data-values='{"8.3.":12,"8.2.":24,"8.1.":30,"8.0.":[30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,3,2,1,0],"7.4.":[33,32,30,29,28,27,26,25,24,23,22,21,20,19,18,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0],"7.3.":33,"7.2.":34,"7.1.":33,"7.0.":33,"5.6.":40,"5.5.":38,"5.4.":45,"5.3.":29,"5.2.":17,"5.1.":6,"5.0.":5,"4.4.":9,"4.3.":11,"git.":["master_jit","master"],"rfc.":["property-hooks"]}'></select></div><input type="submit" value="eval();" title="shortcut: ctrl+enter" /></form><noscript><div class="alert warning"><h2>Enable javascript to submit</h2><p>You have javascript disabled. You will not be able to edit any code.</p></div></noscript><ul id="tabs"><li itemprop="articleSection" class="active"><a href="/OL7ik">Output</a></li><li><a href="/OL7ik/perf">Performance</a></li><li><a href="/OL7ik/vld">VLD</a></li><li><a href="/OL7ik/refs">References</a></li><li><a href="/OL7ik/rfc">Branches</a></li></ul><div id="tab" itemprop="articleBody"><a id="output"></a><dl><dt id="v4.3.0">Output for <span title="released 2002-12-27">4.3.0</span> - <span title="released 2005-03-31">4.3.11</span>, <span title="released 2005-07-11">4.4.0</span> - <span title="released 2008-08-07">4.4.9</span>, <span title="released 2004-07-13">5.0.0</span> - <span title="released 2005-09-05">5.0.5</span>, <span title="released 2005-11-24">5.1.0</span> - <span title="released 2006-08-24">5.1.6</span>, <span title="released 2006-11-02">5.2.0</span> - <span title="released 2011-01-06">5.2.17</span>, <span title="released 2009-06-30">5.3.0</span> - <span title="released 2014-08-14">5.3.29</span>, <span title="released 2012-03-01">5.4.0</span> - <span title="released 2015-09-03">5.4.45</span>, <span title="released 2013-06-20">5.5.0</span> - <span title="released 2016-07-21">5.5.38</span>, <span title="released 2014-08-28">5.6.0</span> - <span title="released 2019-01-10">5.6.40</span>, <span title="released 2015-12-03">7.0.0</span> - <span title="released 2018-12-06">7.0.33</span>, <span title="released 2016-12-01">7.1.0</span> - <span title="released 2019-10-24">7.1.33</span>, <span title="released 2017-11-30">7.2.0</span> - <span title="released 2020-08-06">7.2.33</span>, <span title="released 2018-12-06">7.3.0</span> - <span title="released 2021-11-18">7.3.33</span>, <span title="released 2019-11-28">7.4.0</span> - <span title="released 2022-11-03">7.4.33</span>, <span title="released 2020-11-26">8.0.0</span> - <span title="released 2023-08-03">8.0.30</span>, <span title="released 2021-11-25">8.1.0</span> - <span title="released 2024-09-26">8.1.30</span>, <span title="released 2022-12-08">8.2.0</span> - <span title="released 2024-09-26">8.2.24</span>, <span title="released 2023-11-23">8.3.0</span> - <span title="released 2024-09-26">8.3.12</span></dt><dd>string(32) "0e462097431906509019562988736854" string(32) "0e087386482136013740957780965295" bool(true) </dd></dl></div></div><hr /><div id="prefs">preferences:<input type="checkbox" id="darkMode" /><label for="darkMode">dark mode</label><input type="checkbox" id="livePreview" /><label for="livePreview">live preview</label></div><b>69.1</b> ms | <b>410</b> KiB | <b>5</b> Q<script src="/s/my.js" async></script><script src="/ext/diff.js" async></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/ace.js" integrity="sha384-/HiYf7uts/FC/PC50yfG3bXnxyMdlMFQpgaXPNOqiTJkQIbiBeth3J86SYJowDdK" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/ext-language_tools.js" integrity="sha384-pjdIm81c7GuHpSIwd3CpO3BgZx2B+hNtSvqcFnk7DCwPdEmf0xBCZX5i7jMj/ib6" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/mode-php.js" integrity="sha384-EO1oIq3Wru7Pa4jrHft9hrjz2SKGcYx1J/BteienRTZbIRvIWRADNyaNMCV4AmNN" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/theme-chrome.js" integrity="sha384-uOlVPZfQXFZofTCU/B1H8M3c6hww7F3VOufsGRLzlK4l9blvVqfJeONjYJM5+tnb" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/gh/ajaxorg/ace-builds@1.23.0/src-min-noconflict/theme-chaos.js" integrity="sha384-mfoITkRp/u4qWConw/ovtCjvymPkNZiOj9csanbxBv8rdPa/v7wiZdnwF8i+M3UE" crossorigin="anonymous"></script></body></html> |
Так как результатом умножения любого числа на “0” всегда будет “0”, то любые два хэша будут равны между собой если:
1) они начинаются с произвольного количества “0”
2) за нолями следует символ “0”
3) после символа “e” следуют только числа.
Говоря языком регекспов — ^[0]+e[0-9]+$
Теперь небольшая проекция на реальную ситуацию из жизни.
Есть сайт, в котором авторизация пользователей реализована таким образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php /* many-many useful code */ $currUser = getFromDatabase( 'users', [ 'login' => $_GET['login']; ]); // получение данных о пользователе из базы данных if($currUser == 'NOT_FOUND') return 'Пользователь или пароль не верны'; if(md5($_GET['password']) == $currUser->password) { return ["Добро пожаловать {$currUser->username}", $currUser]; } else { return ['Пользователь или пароль не верны', 0]; } |
Теперь если у пользователя Васи пароль от аккаунта “240610708”. То, за Васю можно войти и с помощью пароля “aabg7XSs”, и с “QNKCDZO”, и даже с “NOOPCJF”.
Причем данная проблема не зависит от типа используемой функции. Буде это даже sha256 там тоже присутствуют хэши, которые удовлетворяют обозначеным выше условиям. Но вот загвоздка, натолкнуться на такой хэш довольно проблематично. Другое дело если мы его сгенерируем сами.
Система сброса с поста админа пароля.
Рассмотрим такое явление, как восстановление забытого пароля. Довольно часто оно реализовано таким способом:
1) Человек нажимает кнопку сброса пароля http://some-useless-forum.ru/recovery.php?action=recstart
2) Вводит свое имя пользователя/e-mail
3) Получает на почту ссылку для восстановления пароля, вида http://some-useless-forum.ru/recovery.php?action=newpass&id=666&hash=E9C2F4EA8015A084CE9CF83A3C65B51D
4) Переходит по ней
5) Система разрешает установить пользователю новый пароль
6) Sex & Fun
Теперь посмотрим, что будет, если этот процесс реализован примерно таким кодом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php /* code and code again */ switch($action) { case 'recstart': $findedUser = findUserInDb( 'users', ['email' => $_GET['email']] ); // ищем юзера в таблице if($findedUser === 1) { $recCode = md5(generateStringForRecovery(10)); // если находим, генерируем код для сброса пароля saveRecCodeInDb([ 'userId' => $findedUser->id, 'hash' => $recCode ]); // сохраняем код в базу emailRecoverySend( $findedUser->email, $recCode ); // отправляем письмо с кодом } else { echo 'Пользователь с таким адресом электронной почты не найден.'; } break; case 'newpass': $findedUser = findUserInDbByID( 'users', ['id' => $_GET['id']] ); // ищем юзера с id в таблице if($findedUser === 1) { if($_GET['hash'] == $findedUser->hash) { showFormForSetNewPass(); } else { echo 'Введенный код восстановления пароля неверен.'; } } else { echo 'Ссылка восстановления пароля недействительна.'; } break; } |
При таком подходе, где использется нестрогого сравнение хэшей, мы можем сбросить пароль любого пользователя, зная только адрес его электронной почты.
Для этого мы можем написать скрипт, который будет:
1) Отправлять форму восстановления пароля с нужным на email’ом.
2) Переходить по ссылке для сброса, используя в качестве кода 0.
3) Проверять: появилась ли форма для ввода нового пароля. Если нет, то переходить к 1 пункту. И так по кругу, пока не получим форму для ввода нового пароля.
Это работает таким образом: раз за разом генерируется новый хэш для сброса пароля и когда этот хэш совпадает с условиями, которые я описал выше, то достаточно сравнить его с “0” и результат сравнения будет истиной. Конечно, чем длиннее хэш, тем результат получения нужного стремится к нулю.
Такая уязвимость была обнаружена в одной из старых версий Simple Machines Forum, об этом еще писал Raz0r в своем блоге http://raz0r.name/vulnerabilities/simple-machines-forum/.
Заключение.
Вот и все мысли по данному вопросу. В блоге WhiteHat Security есть очень хорошая статья на английском языке по данному вопросу — https://blog.whitehatsec.com/magic-hashes/
Я лишь приложу сюда таблицу с паролями, которые равны 0.
HASH TYPE | HASH LENGTH | “MAGIC” NUMBER / STRING | MAGIC HASH | FOUND BY |
---|---|---|---|---|
md2 | 32 | 505144726 | 0e015339760548602306096794382326 | WhiteHat Security, Inc. |
md4 | 32 | 48291204 | 0e266546927425668450445617970135 | WhiteHat Security, Inc. |
md5 | 32 | 240610708 | 0e462097431906509019562988736854 | Michal Spacek |
sha1 | 40 | 10932435112 | 0e07766915004133176347055865026311692244 | Independently found by Michael A. Cleverly & Michele Spagnuolo & Rogdham |
ripemd128 | 32 | 315655854 | 0e251331818775808475952406672980 | WhiteHat Security, Inc. |
ripemd160 | 40 | 20583002034 | 00e1839085851394356611454660337505469745 | Michael A Cleverly |
tiger128,3 | 32 | 265022640 | 0e908730200858058999593322639865 | WhiteHat Security, Inc. |
tiger160,3 | 40 | 13181623570 | 00e4706040169225543861400227305532507173 | Michele Spagnuolo |
tiger192,3 | 48 | – | – | – |
tiger128,4 | 32 | 479763000 | 00e05651056780370631793326323796 | WhiteHat Security, Inc. |
tiger160,4 | 40 | 62241955574 | 0e69173478833895223726165786906905141502 | Michele Spagnuolo |
adler32 | 8 | FR | 00e00099 | WhiteHat Security, Inc. |
crc32 | 8 | 2332 | 0e684322 | WhiteHat Security, Inc. |
crc32b | 8 | 6586 | 0e817678 | WhiteHat Security, Inc. |
fnv132 | 8 | 2186 | 0e591528 | WhiteHat Security, Inc. |
fnv164 | 16 | 8338000 | 0e73845709713699 | WhiteHat Security, Inc. |
joaat | 8 | 8409 | 0e074025 | WhiteHat Security, Inc. |
haval128,3 | 32 | 809793630 | 00e38549671092424173928143648452 | WhiteHat Security, Inc. |
haval160,3 | 40 | 18159983163 | 0e01697014920826425936632356870426876167 | Independently found by Michael Cleverly & Michele Spagnuolo |
haval192,3 | 48 | 48892056947 | 0e4868841162506296635201967091461310754872302741 | Michael A. Cleverly |
haval128,4 | 32 | 71437579 | 0e316321729023182394301371028665 | WhiteHat Security, Inc. |
haval160,4 | 40 | 12368878794 | 0e34042599806027333661050958199580964722 | Michele Spagnuolo |
haval128,5 | 32 | 115528287 | 0e495317064156922585933029613272 | WhiteHat Security, Inc. |
haval160,5 | 40 | 33902688231 | 00e2521569708250889666329543741175098562 | Michele Spagnuolo |
haval192,5 | 48 | 52888640556 | 0e9108479697641294204710754930487725109982883677 | Michele Spagnuolo |
Так же для тех кто пишет код, советую внимательно прочитать мануалы на сайте PHP. В двух словах — приучайте себя использовать тождественное равенство ===.
http://php.net/manual/ru/language.operators.comparison.php
http://php.net/manual/ru/types.comparisons.php
http://php.net/manual/ru/language.types.string.php
http://php.net/manual/ru/language.types.float.php
http://php.net/manual/ru/language.types.integer.php
Еще немного информации по теме:
http://turbochaos.blogspot.com.au/2013/08/exploiting-exotic-bugs-php-type-juggling.html