{"id":4707,"date":"2021-01-15T13:04:29","date_gmt":"2021-01-15T11:04:29","guid":{"rendered":"https:\/\/www.laurentmarot.fr\/wordpress\/?p=4707"},"modified":"2021-01-15T15:02:31","modified_gmt":"2021-01-15T13:02:31","slug":"playing-with-bcrypt-and-joomla","status":"publish","type":"post","link":"https:\/\/www.laurentmarot.fr\/wordpress\/?p=4707","title":{"rendered":"Playing with bcrypt and Joomla"},"content":{"rendered":"<p>Juste pour poser l\u00e0 quelques d\u00e9tails sur le stockage s\u00e9curis\u00e9 des mots de passe dans Joomla (cms php tr\u00e8s courant).<\/p>\n<p>Bref un truc avec lequel on joue un peu en TP, mais qui est aussi parfois bien utile quand on a perdu le mot de passe de l&rsquo;unique compte d&rsquo;administration du site (n&rsquo;est-ce pas la Mairie de N&#8230;.?, vieille mission Alliacom en 2010).<\/p>\n<p>Si je jette un \u0153il sur le contenu de ma table des utilisateurs Joomla, j&rsquo;aper\u00e7ois ce genre de cha\u00eenes de caract\u00e8res dans les champs password :<\/p>\n<p>$2y$10$OL0ibA8TKT.287zm4HPkYuKI\/5CH0X1bMe9PyxPRjOxjeCSC\/FOwm<\/p>\n<p>On notera par ailleurs qu 2 utilisateurs avec le m\u00eame mot de passe pr\u00e9senteront un hash diff\u00e9rent, bref on est loin du pauvre MD5 sans sel utilis\u00e9 il y a quelques ann\u00e9es par Joomla.<\/p>\n<p>On reconna\u00eet un hash <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bcrypt\" target=\"_blank\" rel=\"noopener\">bcrypt<\/a> par la pr\u00e9sence en d\u00e9but de cha\u00eene de\u00a0 $2y dans &lsquo;$2y$10$&rsquo;, le $10 est le co\u00fbt algorithmique, autrement dit 2<sup>10<\/sup> = 1 024 it\u00e9rations.<\/p>\n<p>Les 22 caract\u00e8res suivants constituent le sel al\u00e9atoire. Les caract\u00e8res qui compl\u00e8tent la cha\u00eene composent le mot de passe hasch\u00e9. Comme un petit sch\u00e9ma vaut mieux qu&rsquo;un long discours :<\/p>\n<div id=\"attachment_4714\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capture-du-2021-01-15-13-24-08.png\" rel=\"lightbox[4707]\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4714\" class=\"size-medium wp-image-4714\" src=\"https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capture-du-2021-01-15-13-24-08-300x141.png\" alt=\"brcypt\" width=\"300\" height=\"141\" srcset=\"https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capture-du-2021-01-15-13-24-08-300x141.png 300w, https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capture-du-2021-01-15-13-24-08.png 716w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-4714\" class=\"wp-caption-text\">brcypt selon <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bcr\" target=\"_blank\" rel=\"noopener\">wikipedia<\/a><\/p><\/div>\n<p>Pour plus de d\u00e9tails (tout public) sur bcrypt\u00a0 : <b><a href=\"https:\/\/www.bcrypt.fr\/questions\" target=\"_blank\" rel=\"nofollow noopener\">https:\/\/www.bcrypt.fr\/questions<\/a><\/b><\/p>\n<p>Et pour aller plus loin dans la compr\u00e9hension : <a href=\"https:\/\/auth0.com\/blog\/hashing-in-action-understanding-bcrypt\/\" target=\"_blank\" rel=\"noopener\">https:\/\/auth0.com\/blog\/hashing-in-action-understanding-bcrypt\/<\/a><\/p>\n<p>Et enfin pour faire quelques tests en ligne : <b><a href=\"https:\/\/bcrypt-generator.com\/\" target=\"_blank\" rel=\"nofollow noopener\">https:\/\/bcrypt-generator.com\/<\/a><\/b><\/p>\n<p>La fonction crypt en php, fonctionne donc comme cela :<\/p>\n<div class=\"bbcode_container\">\n<pre class=\"bbcode_code\">crypt($motdepasse, '$2y$10$'.randombytes(22));<\/pre>\n<div id=\"attachment_4710\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capturebcrypte.png\" rel=\"lightbox[4707]\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4710\" class=\"size-medium wp-image-4710\" src=\"https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capturebcrypte-300x72.png\" alt=\"playing with bcrypt and Joomla\" width=\"300\" height=\"72\" srcset=\"https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capturebcrypte-300x72.png 300w, https:\/\/www.laurentmarot.fr\/wordpress\/wp-content\/uploads\/2021\/01\/Capturebcrypte.png 745w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-4710\" class=\"wp-caption-text\">playing with bcrypt and Joomla<\/p><\/div>\n<\/div>\n<p><a href=\"http:\/\/micmap.org\/php-by-example\/manual\/fr\/function.crypt.html\" target=\"_blank\" rel=\"nofollow noopener\">http:\/\/micmap.org\/php-by-example\/man&#8230;ion.crypt.html<\/a><\/p>\n<p>Exemple : <em>password<\/em> (tr\u00e8s mauvaise id\u00e9e de mot de passe)<\/p>\n<div class=\"bbcode_container\">\n<pre class=\"bbcode_code\">$2y$10$.prE1BkZ87aPNnsKMTOSxe9pv8TQIhfBb2HZpSnBPfh.LeHgnaLD2<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Cette fonction est par exemple utilis\u00e9e dans Joomla la classe\/m\u00e9thdoe <b>JUserHelper::hashPassword<\/b> pour Joomla. Apr\u00e8s \u00e9tude, il est ainsi relativement simple de cr\u00e9er un fichier joomla-password-hash.php et de le placer \u00e0 la racine de son site.<\/p>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC1\" class=\"blob-code blob-code-inner js-file-line\"><span class=\"pl-ent\">&lt;?php<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC2\" class=\"blob-code blob-code-inner js-file-line\"><span class=\"pl-en\">define<\/span>(<span class=\"pl-s\">&lsquo;_JEXEC&rsquo;<\/span>, <span class=\"pl-c1\">1<\/span>);<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC3\" class=\"blob-code blob-code-inner js-file-line\"><span class=\"pl-en\">define<\/span>(<span class=\"pl-s\">&lsquo;JPATH_BASE&rsquo;<\/span>, <span class=\"pl-en\">dirname<\/span>(__FILE__));<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC4\" class=\"blob-code blob-code-inner js-file-line\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC5\" class=\"blob-code blob-code-inner js-file-line\"><span class=\"pl-k\">require_once<\/span>(<span class=\"pl-c1\">JPATH_BASE<\/span> . <span class=\"pl-s\">&lsquo;\/includes\/defines.php&rsquo;<\/span>);<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC6\" class=\"blob-code blob-code-inner js-file-line\"><span class=\"pl-k\">require_once<\/span>(<span class=\"pl-c1\">JPATH_BASE<\/span> . <span class=\"pl-s\">&lsquo;\/includes\/framework.php&rsquo;<\/span>);<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC7\" class=\"blob-code blob-code-inner js-file-line\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\" data-paste-markdown-skip=\"\">\n<tbody>\n<tr>\n<td id=\"file-joomla-password-hash-php-LC8\" class=\"blob-code blob-code-inner js-file-line\"><span class=\"pl-k\">echo<\/span> <span class=\"pl-s\">\u00ab\u00a0&lt;strong&gt;Password: &lt;\/strong&gt;\u00a0\u00bb<\/span> . <span class=\"pl-v\">JUserHelper<\/span>::<span class=\"pl-en\">hashPassword<\/span>(<span class=\"pl-s\">&lsquo;password&rsquo;<\/span>);<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a href=\"https:\/\/gist.github.com\/AdamMadrzejewski\/5ce3ac3afa1114a71b92\" target=\"_blank\" rel=\"nofollow noopener\"><span class=\"pl-ent\">?&gt;<\/span><\/a><br \/>\n<a href=\"https:\/\/api.joomla.org\/cms-3\/classes\/JUserHelper.html\" target=\"_blank\" rel=\"nofollow noopener\">https:\/\/api.joomla.org\/cms-3\/classes\/JUserHelper.html<\/a><\/p>\n<p>En r\u00e9sum\u00e9, le nombre d&rsquo;it\u00e9rations implique un calcul plus long et plus fastidieux pour les scripts de hacks et m\u00eame si la base de donn\u00e9es \u00e9tait pirat\u00e9e, cela me semble un peu plus difficile de retrouver le mot de passe&#8230; comme ce fut le cas l&rsquo;ann\u00e9e derni\u00e8re pour dailymotion (ce service de video utilisent bcrypt \u00e9galement) : <a href=\"https:\/\/www.information-security.fr\/hack-dailymotion-une-fuite-de-85-millions-didentifiants\/\" target=\"_blank\" rel=\"nofollow noopener\">https:\/\/www.information-security.fr\/&#8230;didentifiants\/<\/a><\/p>\n<p>L&rsquo;impl\u00e9mentation d bcrypt a donn\u00e9 un peu plus de s\u00e9curit\u00e9 \u00e0 Joomla, cela n\u2019emp\u00eache pas d&rsquo;imposer un minimum de caract\u00e8res, m\u00e9lange min\/maj, caract\u00e8res sp\u00e9ciaux aux mots de passe pour fonctionner un peu plus efficacement. Il faut \u00e9viter par exemple que les utilisateurs utilisent uniquement leur date d&rsquo;anniversaire pour le mot de passe &#8230; (chercher \u00ab\u00a0paradoxe des anniversaires\u00a0\u00bb dans un moteur de recherche si vous aimez les probabilit\u00e9s )&#8230;<\/p>\n<p>De plus, il y a aujourd&rsquo;hui un march\u00e9 de solutions compl\u00e9mentaires \u00e0 conna\u00eetre : MFA, double authentification (google authenticator et d\u00e9riv\u00e9), sans mot de passe comme launchkey.com, par sms avec accountkit de facebook&#8230;<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Juste pour poser l\u00e0 quelques d\u00e9tails sur le stockage s\u00e9curis\u00e9 des mots de passe dans Joomla (cms php tr\u00e8s courant). Bref un truc avec lequel on joue un peu en TP, mais qui est aussi parfois bien utile quand on a perdu le mot de passe de l&rsquo;unique compte d&rsquo;administration du site (n&rsquo;est-ce pas la [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,39],"tags":[],"_links":{"self":[{"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/4707"}],"collection":[{"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4707"}],"version-history":[{"count":11,"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/4707\/revisions"}],"predecessor-version":[{"id":4720,"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/4707\/revisions\/4720"}],"wp:attachment":[{"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4707"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4707"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.laurentmarot.fr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4707"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}