{"id":1990,"date":"2016-04-03T15:29:24","date_gmt":"2016-04-03T13:29:24","guid":{"rendered":"https:\/\/www.asafety.fr\/?p=1990"},"modified":"2016-07-25T00:34:27","modified_gmt":"2016-07-24T22:34:27","slug":"ctf-ndh-2016-quals-write-up-cryptography-toil33t","status":"publish","type":"post","link":"https:\/\/www.asafety.fr\/en\/cryptologie\/ctf-ndh-2016-quals-write-up-cryptography-toil33t\/","title":{"rendered":"[CTF NDH 2016 Quals] Write-Up \u2013 Cryptography : Toil33t"},"content":{"rendered":"<p><\/p>\n<p style=\"text-align: center;\"><strong>Write-up of the challenge \u201cCryptography\u00a0\u2013 Toil33t\u201d of Nuit du\u00a0Hack 2016 CTF qualifications.<\/strong><\/p>\n<p>The weekend of 04\/01\/2016 is pre-qualification for the <strong><a href=\"https:\/\/nuitduhack.com\/fr\/\" target=\"_blank\">Nuit du Hack 2016<\/a><\/strong>\u00a0as a <strong>Jeopardy CTF<\/strong>. Having had the opportunity and the time to participate with some colleagues and friends, here\u2019s a write-up resolution of the challenges which we could participate.<\/p>\n<ul>\n<li>Category: <strong>Cryptography<\/strong><\/li>\n<li>Name: <strong>Toil33t<\/strong><\/li>\n<li>Description : <em>Hey ! I really want to buy a toil33t, however it is not available yet! \ud83d\ude41 Can you access to the administrative page and take one for me?<\/em><\/li>\n<li>URL : http:\/\/toil33t.quals.nuitduhack.com<\/li>\n<li>Points :\u00a0<strong>400<\/strong><\/li>\n<\/ul>\n<p>This cryptographic challenge concretely illustrates the &#8220;cut and paste attack &#8221; on the cipher AES-ECB. The idea is to manipulate the blocks of encrypted data (cut &amp; paste) to forge a different encrypted data with\u00a0our expectations.<\/p>\n<p>When we\u00a0go to the URL of the challenge, we are invited to register us:<\/p>\n<div id=\"attachment_1991\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/01-3.png\" rel=\"attachment wp-att-1991\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1991\" class=\"size-medium wp-image-1991\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/01-3-300x157.png\" alt=\"Main page\" width=\"300\" height=\"157\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/01-3-300x157.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/01-3-768x402.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/01-3-1024x537.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/01-3.png 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1991\" class=\"wp-caption-text\">Main page<\/p><\/div>\n<p>No control over the field values are applied, inscribe us with a login, password and email with the same value &#8220;x&#8221;:<\/p>\n<div id=\"attachment_1993\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/03-3.png\" rel=\"attachment wp-att-1993\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1993\" class=\"wp-image-1993 size-medium\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/03-3-300x268.png\" alt=\"Register with &quot;x&quot;\" width=\"300\" height=\"268\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/03-3-300x268.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/03-3-768x687.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/03-3.png 802w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1993\" class=\"wp-caption-text\">Register with &#8220;x&#8221;<\/p><\/div>\n<p>Your registration is successful, now observed in the various requests the presence of a session cookie:<\/p>\n<pre>session=e7a0bb1bd4f4473106e24b374ac5fa5a799a5dc4824d8f51e2a78524b1020705a6eaf0fe5db99c6755c21f277aff95020ea7708a8f28694887deb53b8ecd855b1fe1ccac92e372290593e12777d8260f;<\/pre>\n<p>In addition, AJAX GET request is made from the home page to &#8220;\/session,&#8221; to see if ads\u00a0are to be displayed on the main page. This simple GET request (with the session cookie) returns JSON in the following format:<\/p>\n<pre>{\r\n \"email\": \"x\", \r\n \"is_admin\": false, \r\n \"show_ad\": false, \r\n \"username\": \"x\"\r\n}<\/pre>\n<p>Interesting the field\u00a0&#8220;is_admin&#8221; to &#8220;false&#8221;. We have to change this value\u00a0to &#8220;true&#8221; to reach the admin page. Currently an attempt to access this page responds:<\/p>\n<div id=\"attachment_1992\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/02-3.png\" rel=\"attachment wp-att-1992\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1992\" class=\"size-medium wp-image-1992\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/02-3-300x65.png\" alt=\"Admin page error\" width=\"300\" height=\"65\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/02-3-300x65.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/02-3-768x166.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/02-3.png 985w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1992\" class=\"wp-caption-text\">Admin page error<\/p><\/div>\n<p>The challenge home page informs that the exchanges are &#8220;secure&#8221; via Rijndael + 256ROT13, we can deduce that the value of the session cookie is calculated as:<\/p>\n<pre>session_cookie = 256ROT13 ( AES_ECB ( json ) )<\/pre>\n<p>JSON data is encoded to form the session cookie. Re-inscribe us in just modifying a parameter, the email = &#8220;z&#8221;:<\/p>\n<div id=\"attachment_1994\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/04-2.png\" rel=\"attachment wp-att-1994\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1994\" class=\"size-medium wp-image-1994\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/04-2-300x269.png\" alt=\"Email updated\" width=\"300\" height=\"269\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/04-2-300x269.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/04-2-768x688.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/04-2.png 794w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1994\" class=\"wp-caption-text\">Email updated<\/p><\/div>\n<p>New JSON data :<\/p>\n<pre>{\r\n \"email\": \"z\", \r\n \"is_admin\": false, \r\n \"show_ad\": false, \r\n \"username\": \"x\"\r\n}<\/pre>\n<p>New session cookie :<\/p>\n<pre>session=e7a0bb1bd4f4473106e24b374ac5fa5a799a5dc4824d8f51e2a78524b1020705a6eaf0fe5db99c6755c21f277aff95020ea7708a8f28694887deb53b8ecd855bf1c9c8bf9c982612c9b86320a36e61d0;<\/pre>\n<p>Comparing both session cookies from the\u00a0two accounts (x \/ x \/ x and x \/ x \/ z), we see that only the last block is different, and the block size of the AES-ECB is 16:<\/p>\n<pre>(x \/ x \/ x)\r\ne7a0bb1bd4f4473106e24b374ac5fa5a 799a5dc4824d8f51e2a78524b1020705 a6eaf0fe5db99c6755c21f277aff9502 0ea7708a8f28694887deb53b8ecd855b 1fe1ccac92e372290593e12777d8260f\r\n(x \/ x \/ z)\r\ne7a0bb1bd4f4473106e24b374ac5fa5a 799a5dc4824d8f51e2a78524b1020705 a6eaf0fe5db99c6755c21f277aff9502 0ea7708a8f28694887deb53b8ecd855b f1c9c8bf9c982612c9b86320a36e61d0<\/pre>\n<p>We conclude that the encrypted data meets JSON syntax similar to:<\/p>\n<pre>session_cookie = 256ROT13 ( AES_ECB ( '{\"username\": \"x\", \"show_ad\": false, \"is_admin\": false, \"email\": \"x\"}' ) )<\/pre>\n<p>By distributing equal size to the JSON data from their respective block, we deduce:<\/p>\n<pre>e7a0bb1bd4f4473106e24b374ac5fa5a [{\"username\": \"x\"] (1a)\r\n799a5dc4824d8f51e2a78524b1020705 [, \"show_ad\": fal] (2a)\r\na6eaf0fe5db99c6755c21f277aff9502 [se, \"is_admin\": ] (3a)\r\n0ea7708a8f28694887deb53b8ecd855b [false, \"email\": ] (4a)\r\n1fe1ccac92e372290593e12777d8260f [\"x\"}]             (5a)<\/pre>\n<p>The idea will now be playing on the value of the &#8220;username&#8221; with registration, in order to forge a line containing only &#8220;true,&#8221; to follow up the line &#8220;3a&#8221;. So &#8220;is_admin: true&#8221; will be forged.<\/p>\n<p>By registering with a &#8220;username&#8221; equal to:<\/p>\n<pre>username = [xxtrue,           ]<\/pre>\n<p>We gain the session cookie :<\/p>\n<pre>9d287ba085f621f4d11632215d255584e3264500a02a33efe37921dbd92324aa5d998eabd9fd50d71639ffd19fadaeb23164706a5409b80800d7b98a576d11546cb3b01c5a57390325c7f6a18a4183c2340e00870031efaef32faae48f1dacc3<\/pre>\n<p>Distribution :<\/p>\n<pre>9d287ba085f621f4d11632215d255584 [{\"username\": \"xx] (1b)\r\ne3264500a02a33efe37921dbd92324aa [true,           ] (2b)\r\n5d998eabd9fd50d71639ffd19fadaeb2 [\", \"show_ad\": fa] (3b)\r\n3164706a5409b80800d7b98a576d1154 [lse, \"is_admin\":] (4b)\r\n6cb3b01c5a57390325c7f6a18a4183c2 [ false, \"email\":] (5b)\r\n340e00870031efaef32faae48f1dacc3 [ \"x\"}]            (6b)<\/pre>\n<p>The line &#8220;2b&#8221; perfectly matches our expectations.<\/p>\n<p>We must now forge a suitable block for email:<\/p>\n<pre>username =\u00a0[xxxxxxxxxx]<\/pre>\n<p>Cookie :<\/p>\n<pre>9d287ba085f621f4d11632215d255584853ce76be7095f7a6006aade6d87574f3758e2604a11b75246b4f7fd9d14df598ac9ee8270fdde8d052e27be7d93dd3a5e3e792d648734eb774d0263b4a5b30b<\/pre>\n<p>Distribution\u00a0:<\/p>\n<pre>9d287ba085f621f4d11632215d255584 [{\"username\": \"xx] (1c)\r\n853ce76be7095f7a6006aade6d87574f [xxxxxxxx\", \"show] (2c)\r\n3758e2604a11b75246b4f7fd9d14df59 [_ad\": false, \"is] (3c)\r\n8ac9ee8270fdde8d052e27be7d93dd3a [_admin\": false, ] (4c)\r\n5e3e792d648734eb774d0263b4a5b30b [\"email\": \"x\"}]    (5c)<\/pre>\n<p>We have now all the &#8220;material&#8221; to forge an administration cookie from valid blocks and to obtain our desired JSON:<\/p>\n<pre>{\"username\": \"x\", \"show_ad\": false, \"is_admin\": true, \"email\": \"x\"}<\/pre>\n<p>A block is independent of the previous block, they are interchangeable as the decrypted data translated in JSON is with a\u00a0valid syntax (cut and paste attack). It therefore takes the blocks that are of interest for previous requests to forge one you want, the 256ROT13 is obvious\u00a0(<strong>1a, 2a, 3a, 2b and 5c<\/strong>) :<\/p>\n<pre>e7a0bb1bd4f4473106e24b374ac5fa5a [{\"username\": \"x\"] (1a)\r\n799a5dc4824d8f51e2a78524b1020705 [, \"show_ad\": fal] (2a)\r\na6eaf0fe5db99c6755c21f277aff9502 [se, \"is_admin\": ] (3a)\r\ne3264500a02a33efe37921dbd92324aa [true,           ] (2b)\r\n5e3e792d648734eb774d0263b4a5b30b [\"email\": \"x\"}]    (5c)<\/pre>\n<p>Test of\u00a0our new cookie on the page &#8220;\/session&#8221; to see how it is decoded:<\/p>\n<pre>e7a0bb1bd4f4473106e24b374ac5fa5a799a5dc4824d8f51e2a78524b1020705a6eaf0fe5db99c6755c21f277aff9502e3264500a02a33efe37921dbd92324aa5e3e792d648734eb774d0263b4a5b30b<\/pre>\n<div id=\"attachment_1995\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/05-1.png\" rel=\"attachment wp-att-1995\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1995\" class=\"size-medium wp-image-1995\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/05-1-300x58.png\" alt=\"JSON valide is_admin true\" width=\"300\" height=\"58\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/05-1-300x58.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/05-1-768x147.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/05-1-1024x196.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/05-1.png 1601w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1995\" class=\"wp-caption-text\">JSON valide is_admin true<\/p><\/div>\n<p>Bingo! Just visit the admin page with the new cookie value:<\/p>\n<div id=\"attachment_1996\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/06-1.png\" rel=\"attachment wp-att-1996\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1996\" class=\"size-medium wp-image-1996\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/06-1-300x88.png\" alt=\"Admin page\" width=\"300\" height=\"88\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/06-1-300x88.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/06-1.png 721w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1996\" class=\"wp-caption-text\">Admin page<\/p><\/div>\n<p>Flag :\u00a0<strong>NDH{22cf96f723f08382606119fe574953b9}<\/strong><\/p>\n<p>Greeting to\u00a0<a href=\"http:\/\/www.information-security.fr\/\" target=\"_blank\">nj8<\/a>, <a href=\"http:\/\/0xbadcoded.com\/\" target=\"_blank\">St0rn<\/a>, <a href=\"http:\/\/www.georgestaupin.com\/\" target=\"_blank\">Emiya<\/a>, Mido, downg(r)ade,\u00a0Ryuk@n and\u00a0rikelm, \ud83d\ude09\u00a0\/\/ Gr3etZ<\/p>\n<p><strong>Sources &amp; ressources :<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/nuitduhack.com\/fr\/\" target=\"_blank\">NDH 2016<\/a><\/li>\n<li><a href=\"http:\/\/grocid.net\/2016\/04\/03\/nuit-du-hack-toil33t-aes-ecb-challenge\/\" target=\"_blank\">Grocid.net write-up<\/a><\/li>\n<\/ul>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Write-up of the challenge \u201cCryptography\u00a0\u2013 Toil33t\u201d of Nuit du\u00a0Hack 2016 CTF qualifications. The weekend of 04\/01\/2016 is pre-qualification for the [&hellip;]<\/p>\n","protected":false},"author":1337,"featured_media":1963,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58,57,56,524,523,526,527],"tags":[473,474,476,469,475,459],"class_list":["post-1990","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cryptanalyse","category-cryptographie","category-cryptologie","category-ctf","category-events","category-ndh","category-ndh2k16","tag-aes-ecb","tag-cryptography","tag-cut-and-paste-attack","tag-jeopardy","tag-rot13","tag-write-up"],"_links":{"self":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/posts\/1990","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/users\/1337"}],"replies":[{"embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/comments?post=1990"}],"version-history":[{"count":6,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/posts\/1990\/revisions"}],"predecessor-version":[{"id":2002,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/posts\/1990\/revisions\/2002"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/media\/1963"}],"wp:attachment":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/media?parent=1990"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/categories?post=1990"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/tags?post=1990"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}