{"id":2111,"date":"2016-07-04T23:54:00","date_gmt":"2016-07-04T21:54:00","guid":{"rendered":"https:\/\/www.asafety.fr\/?p=2111"},"modified":"2016-07-25T00:33:41","modified_gmt":"2016-07-24T22:33:41","slug":"wargame-ndh-2016-write-up-web-sticky-sticky","status":"publish","type":"post","link":"https:\/\/www.asafety.fr\/en\/vuln-exploit-poc\/wargame-ndh-2016-write-up-web-sticky-sticky\/","title":{"rendered":"[WARGAME NDH 2016] Write-Up &#8211; Web: Sticky! Sticky!"},"content":{"rendered":"<p><\/p>\n<p style=\"text-align: center;\"><strong>Write-up of the challenge &#8220;Web &#8211; Sticky! Sticky! &#8221; <strong>of Nuit du\u00a0Hack 2016\u00a0Wargame<\/strong><\/strong><\/p>\n<p>The weekend of 02-03 july 2016\u00a0is the WARGAME of the\u00a0<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>Web<\/strong><\/li>\n<li>Name:\u00a0<strong>Sticky! Sticky!<\/strong><\/li>\n<li>Description :\u00a0<em>HEY! Welcome back!<\/em>\n<ul>\n<li>Hint 1 : <em>check all the cookies!!!<\/em><\/li>\n<li>Hint 2 : <em>resolution is in base32<\/em><\/li>\n<\/ul>\n<\/li>\n<li>URL :\u00a0http:\/\/sticky.wargame.ndh<\/li>\n<li>Points : <b>250<\/b><\/li>\n<\/ul>\n<p>Given the name of the challenge, &#8220;sticky&#8221;, we doubt that a notion of cookie and &#8220;persistence&#8221; will come into play &#8230;<\/p>\n<p>By going to the URL of the challenge, we were invited to enter a user name:<\/p>\n<div id=\"attachment_2113\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen02.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2113\" class=\"size-medium wp-image-2113\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen02-300x60.png\" alt=\"Sticky-Sticky login page\" width=\"300\" height=\"60\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen02-300x60.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen02-768x154.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen02-1024x206.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen02.png 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2113\" class=\"wp-caption-text\">Sticky-Sticky login page<\/p><\/div>\n<p>Once a login was entered\u00a0a simple page &#8220;Welcome back&#8221; was displayed with the login reflected:<\/p>\n<div id=\"attachment_2114\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen01.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2114\" class=\"size-medium wp-image-2114\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen01-300x44.png\" alt=\"Sticky-Sticky connected\" width=\"300\" height=\"44\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen01-300x44.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen01-768x112.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen01-1024x149.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen01.png 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2114\" class=\"wp-caption-text\">Sticky-Sticky connected<\/p><\/div>\n<p>By observing in more detail requests, we have a cookie set:<\/p>\n<pre>GET \/index.php HTTP\/1.1\r\nHost: sticky.wargame.ndh\r\nUser-Agent: Mozilla\/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko\/20100101 Firefox\/47.0\r\nAccept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8\r\nAccept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nCookie: user_id=553241; validator=validator.wargame.ndh; resolution=\"YCUAACI=\"\r\nConnection: close<\/pre>\n<ul>\n<li><strong>user_id<\/strong> : the identifier of the user (generated server-side)<\/li>\n<li><strong>validator<\/strong> : a private hostname of &#8220;validation&#8221;<\/li>\n<li><strong>resolution<\/strong> : \u00a0a value encoded in base64? (after obtaining the second &#8220;hint&#8221; of the challenge it&#8217;s Base32&#8230;).<\/li>\n<\/ul>\n<p>By testing various encoding \/ decoding base64 value for &#8220;resolution&#8221;, no relevant information is disclosed, but\u00a0interesting errors (also visible after multiple query execution):<\/p>\n<div id=\"attachment_2115\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen04.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2115\" class=\"size-medium wp-image-2115\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen04-300x164.png\" alt=\"DNS resolution error\" width=\"300\" height=\"164\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen04-300x164.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen04-768x420.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen04-1024x560.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen04.png 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2115\" class=\"wp-caption-text\">DNS resolution error<\/p><\/div>\n<p>In case you change the value of the cookie &#8220;validator&#8221;, we get an error attempting to hijack:<\/p>\n<div id=\"attachment_2116\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen03.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2116\" class=\"size-medium wp-image-2116\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen03-300x164.png\" alt=\"Hijack validator\" width=\"300\" height=\"164\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/screen03-300x164.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen03-768x420.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen03-1024x560.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/screen03.png 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2116\" class=\"wp-caption-text\">Hijack validator<\/p><\/div>\n<p>Testing was continued by trying to inject a payload through the login. A small persistent XSS is here, but nothing exploitable:<\/p>\n<div id=\"attachment_2117\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky005.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2117\" class=\"size-medium wp-image-2117\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky005-300x208.png\" alt=\"XSS in Sticky! Sticky!\" width=\"300\" height=\"208\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky005-300x208.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky005-768x533.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky005.png 897w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2117\" class=\"wp-caption-text\">XSS in Sticky! Sticky!<\/p><\/div>\n<p>The presence of this XSS, stored server side (although responses appeared behind a load balancer), allowed a malicious troll to inject a false-flag that has baffled more than one ^^! Good game \ud83d\ude09 !<\/p>\n<p>Based on previous errors and hints, we deduce several things:<\/p>\n<ul>\n<li>The frontend is a simple connection of web application and reflection of a login<\/li>\n<li>Login (and privileges) appear checked with an inaccessible third-party server &#8220;validator.wargame.ndh&#8221; defined via cookie.<\/li>\n<li>We can change the\u00a0&#8220;user_id&#8221; via cookies. Set to &#8220;1&#8221; it\u00a0displays a &#8220;Welcome admin!&#8221;<\/li>\n<li>The host of validation &#8220;validator.wargame.ndh&#8221; seems listening on port &#8220;8888&#8221; as shown in the previous error message<\/li>\n<li>When altering the encoded value &#8220;resolution&#8221; through cookies there is\u00a0an error related to the host DNS resolution of &#8220;validator.wargame.com&#8221;.<\/li>\n<\/ul>\n<p>Trying to query the server &#8220;sticky.wargame.ndh&#8221; on port 8888 itself:<\/p>\n<pre>GET \/ HTTP\/1.1\r\nHost: sticky.wargame.ndh:8888\r\nUser-Agent: Mozilla\/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko\/20100101 Firefox\/47.0\r\nAccept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8\r\nAccept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nCookie: user_id=553241; validator=validator.wargame.ndh; resolution=\"YCUAACI=\"\r\nConnection: close<\/pre>\n<p>Response:<\/p>\n<pre>HTTP\/1.1 200 OK\r\nServer: nginx\/1.6.2\r\nDate: Sun, 03 Jul 2016 01:32:06 GMT\r\nContent-Type: text\/plain; charset=utf-8\r\nConnection: close\r\nContent-Length: 25\r\n\r\n{\"admin\": 0, \"name\": \"0\"}<\/pre>\n<p style=\"text-align: center;\"><strong>Solving the challenge requires definitely close this answer with an &#8220;admin: 1&#8221;!<\/strong><\/p>\n<p>We focus more on the value of the cookie &#8220;resolution&#8221;, which, following the issuance of the second &#8220;hint&#8221;, is in\u00a0Base32:<\/p>\n<ul>\n<li>Default value : <strong>YCUAACI=<\/strong><\/li>\n<li>Base32 to Hex :\u00a0<strong>C0A80009<\/strong><\/li>\n<li>ASCII : <strong>[192][168][0][9]<\/strong><\/li>\n<\/ul>\n<p>It is an IP that is encoded in the &#8220;resolution&#8221; cookie!<\/p>\n<p>A request sent to the application with the cookie generates the following:<\/p>\n<ul>\n<li>The web server queries the name server (NS) whose IP is Base32 encoded, transmitted in the &#8220;resolution&#8221; cookie. Default: 192.168.0.9.<\/li>\n<li>The server requests\u00a0the NS for the corresponding IP to the specified domain in the cookie &#8220;validator&#8221;: &#8220;What is the corresponding IP of validator.wargame.ndh domain?&#8221;<\/li>\n<li>The corresponding IP is queried on port 8888 to validate the user name. This web server returns JSON like:<\/li>\n<\/ul>\n<pre>{\"admin\": 0, \"name\": \"admin\"}<\/pre>\n<div id=\"attachment_2133\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/archi01.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2133\" class=\"size-medium wp-image-2133\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/archi01-300x179.png\" alt=\"Sticky! Stycky normal behavior\" width=\"300\" height=\"179\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/archi01-300x179.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/archi01-768x457.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/archi01-1024x610.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/archi01.png 1075w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2133\" class=\"wp-caption-text\">Sticky! Stycky normal behavior<\/p><\/div>\n<p>On the client side, we have to take the role of the\u00a0name server (NS), the validation server and force a JSON response\u00a0with:<\/p>\n<pre>{\"admin\": 1, \"name\": \"admin\"}<\/pre>\n<p>My computer, connected to the Wargame network of the NDH, has the\u00a0IP: <strong>172.16.16.250<\/strong>, or in hexadecimal: <strong>AC1010FA<\/strong> and therefore Base32: <strong>VQIBB6Q=<\/strong> (<a href=\"http:\/\/tomeko.net\/online_tools\/base32.php?lang=en\" target=\"_blank\">converter available here<\/a>).<\/p>\n<p>The new value of the cookie &#8220;resolution&#8221; will be <strong>VQIBB6Q=<\/strong>. The web server will seek to resolve the host name in &#8220;validator&#8221; of the NS that will ultimately my machine : 172.16.16.250.<\/p>\n<p>I must therefore turn my post as a DNS server :<\/p>\n<pre>apt-get install dnsmasq\r\necho validator.wargame.ndh 172.16.16.250 &gt;&gt; \/etc\/hosts\r\n\/etc\/init.d\/dnsmasq start<\/pre>\n<p>Done !<\/p>\n<p>Now the DNS resolution of the host &#8220;validator.wargame.ndh&#8221; is made by my computer, and point to my computer itself. It only remains to deploy\u00a0a small web server on port 8888 that will return the JSON &#8220;admin:1&#8221;:<\/p>\n<pre>mkdir sticky\r\ncd sticky\r\nvi 1 # {\"admin\":1,\"name\":\"admin\"}\r\npython -m SimpleHTTPServer 8888<\/pre>\n<p>Our web server is running on port 8888, and a &#8220;1&#8221; file delivers the appropriate JSON to become admin.<\/p>\n<p>It only remains to realize the last request to &#8220;sticky.wargame.ndh&#8221;, with the cookie:<\/p>\n<ul>\n<li><strong>user_id=1<\/strong> : admin user id<\/li>\n<li><strong>validator=validator.wargame.ndh<\/strong> : which will be solved by our own name server<\/li>\n<li><strong>resolution=VQIBB6Q=<\/strong> : IP Base 32 of our name server<\/li>\n<\/ul>\n<div id=\"attachment_2122\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky006.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2122\" class=\"size-medium wp-image-2122\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky006-300x164.png\" alt=\"Stikcy flag\" width=\"300\" height=\"164\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky006-300x164.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky006-768x420.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky006-1024x560.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/stcky006.png 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2122\" class=\"wp-caption-text\">Stikcy flag<\/p><\/div>\n<p>Bingo ! Flag :\u00a0<strong>ndh2k16_e5f3eb90c4438c1a062125e3f74c2b41<\/strong><\/p>\n<div id=\"attachment_2134\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/archi02.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2134\" class=\"size-medium wp-image-2134\" src=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/archi02-300x130.png\" alt=\"Sticky! Sticky! PWN !\" width=\"300\" height=\"130\" srcset=\"https:\/\/www.asafety.fr\/wp-content\/uploads\/archi02-300x130.png 300w, https:\/\/www.asafety.fr\/wp-content\/uploads\/archi02-768x334.png 768w, https:\/\/www.asafety.fr\/wp-content\/uploads\/archi02-1024x445.png 1024w, https:\/\/www.asafety.fr\/wp-content\/uploads\/archi02.png 1068w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2134\" class=\"wp-caption-text\">Sticky! Sticky! PWN !<\/p><\/div>\n<p>Thank you to all the team of the NDH2K16 for this event and for the whole organization!<\/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, downgrade,\u00a0Ryuk@n and\u00a0rikelm, ?\u00a0\/\/ Gr3etZ<\/p>\n<p><strong>Sources &amp; resources :<\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/tomeko.net\/online_tools\/base32.php?lang=en\" target=\"_blank\">Base32 to HEX to ASCII decoder<\/a><\/li>\n<li><a href=\"https:\/\/nuitduhack.com\/fr\/\" target=\"_blank\">NDH 2016<\/a><\/li>\n<\/ul>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Write-up of the challenge &#8220;Web &#8211; Sticky! Sticky! &#8221; of Nuit du\u00a0Hack 2016\u00a0Wargame The weekend of 02-03 july 2016\u00a0is the [&hellip;]<\/p>\n","protected":false},"author":1337,"featured_media":2112,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[524,523,526,527,165,14,525],"tags":[418,469,493,495,494],"class_list":["post-2111","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ctf","category-events","category-ndh","category-ndh2k16","category-os","category-vuln-exploit-poc","category-wargame","tag-cookie","tag-jeopardy","tag-sticky","tag-validator","tag-web"],"_links":{"self":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/posts\/2111","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=2111"}],"version-history":[{"count":15,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/posts\/2111\/revisions"}],"predecessor-version":[{"id":2135,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/posts\/2111\/revisions\/2135"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/media\/2112"}],"wp:attachment":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/media?parent=2111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/categories?post=2111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/tags?post=2111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}