{"id":735,"date":"2017-08-28T23:39:57","date_gmt":"2017-08-29T07:39:57","guid":{"rendered":"https:\/\/www.pnfsoftware.com\/blog\/?p=735"},"modified":"2018-12-19T13:34:52","modified_gmt":"2018-12-19T21:34:52","slug":"firmware-exploitation-with-jeb-part-3-reversing-the-smartrgs-sr505n","status":"publish","type":"post","link":"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-3-reversing-the-smartrgs-sr505n\/","title":{"rendered":"Firmware exploitation with JEB part 3: Reversing the SmartRG\u2019s sr505n"},"content":{"rendered":"<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">For the final blog post of this series (<a href=\"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-1\/\">part 1<\/a> , <a href=\"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-2\/\">part 2<\/a>), let\u2019s reverse a real router firmware. First off, no 0days or security sensitive information will be disclosed in this blogpost but if you have a contact at SmartRG, let us know.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">To be able to reverse easily and test my findings, I wanted a MIPS router that was still used, that had a public firmware update that I could dig into and that was relatively cheap. I begun with the ZyXel NBG6716 by downloading the firmware update from their website and bought one on Amazon. Sadly, I received the wrong model so I decided to try another approach.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">Interestingly enough, the router I personally own met all my criterias and some locals were selling it cheaply on the internet which allowed me to not brick my own device. Here is where the <a href=\"https:\/\/www.smartrg.com\/sr505n\">sr505n<\/a> comes into play. I encourage to follow this blog post by looking at the firmware update while reading, and <\/span><a href=\"https:\/\/help.teksavvy.com\/hc\/en-us\/articles\/200673910-SmartRG-505N-Firmware-Upgrade\"><span style=\"font-weight: 400;\">here<\/span><\/a><span style=\"font-weight: 400;\"> is where you can download it. <\/span><\/p>\n<h1><span style=\"font-weight: 400;\">Static analysis<\/span><\/h1>\n<h2><span style=\"font-weight: 400;\">Extraction and file system<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The `file` command tells us that the firmware update is plain data but let\u2019s see what binwalk thinks of that:<\/span><\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nbinwalk CA_PBCA_2.5.0.14_698450e_sr505n_cfe_fs_kernel \r\n\r\nDECIMAL       HEXADECIMAL     DESCRIPTION\r\n--------------------------------------------------------------------------------\r\n0             0x0             Broadcom 96345 firmware header, header size: 256, firmware version: &quot;68&quot;, board id: &quot;63168MBV_17AZZ&quot;, ~CRC32 header checksum: 0x64494342, ~CRC32 data checksum: 0xACF56C90\r\n14308         0x37E4          LZMA compressed data, properties: 0x6D, dictionary size: 4194304 bytes, uncompressed size: 230336 bytes\r\n61648         0xF0D0          Squashfs filesystem, little endian, non-standard signature, version 4.0, compression:gzip, size: 6672344 bytes, 1060 inodes, blocksize: 65536 bytes, created: 2017-05-31 18:49:24\r\n&#x5B;...]\r\n<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">Let\u2019s rerun binwalk with the `-e` switch to extract the squashfs file system and begin reversing the firmware binaries. One thing to note here is that squashfs is read-only but we can still write on other file systems that are mounted as we can see here:<\/span><\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# mount\r\nrootfs on \/ type rootfs (rw)\r\n\/dev\/root on \/ type squashfs (ro,relatime)\r\nproc on \/proc type proc (rw,relatime)\r\ntmpfs on \/var type tmpfs (rw,relatime,size=420k)\r\ntmpfs on \/mnt type tmpfs (rw,relatime,size=16k)\r\nsysfs on \/sys type sysfs (rw,relatime)\r\n<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">We have the usual file system structure so let\u2019s head to \/bin, \/sbin. A good portion of the binaries are linked to busybox but the majority are real ELF binaries. Interestingly, there is a \/lib\/private directory where proprietary libraries seem to be stored as we can confirm from proprietary binaries linked against those. <\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Binaries<\/span><\/h2>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">At first, I saw myself flooded with binaries to reverse, some with helpful names and some not. I had the idea to create a simple plugin to kick-start the research (whether it\u2019s for vulnerability research, malware analysis or other reverse engineering tasks) by listing some user-selected function names (or sub-strings of names) and creating a list of which binaries call those and where they are called. Let\u2019s see an example:<\/span><\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/e8de7b5912f9a2f32848c31f9d2d02fb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/e8de7b5912f9a2f32848c31f9d2d02fb.png\" alt=\"\" width=\"217\" height=\"481\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">I chose memory sensitive functions as well as networking functions to identify binaries that dealt with user input (possibly without requiring authentication). For example, the `smd` binary is the service manager daemon and caCaptivePortal has the functionalities its name implies.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">If you want to use that plugin here is the <\/span><a href=\"https:\/\/github.com\/pnfsoftware\/jeb2-samplecode\/tree\/master\/src\/com\/pnf\/pommePlugin\"><span style=\"font-weight: 400;\">repo<\/span><\/a><span style=\"font-weight: 400;\">. You\u2019ll need to copy the `functionList.json` or create one in ${JEB_HOME}\/bin\/cl\/ for it to work properly. Specify the functions that interest you and add all the artifacts you want to search from.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">There are some other things that you will quickly notice if you analyze the firmware too. Each user has a simple and hardcoded password but I can confirm ISPs seem to change those (but for simple and hardcoded ones as well in my experience). I grabbed the latest firmware I could find and there might be newer ones but some software need updating as the \/tmp\/bootupmessages file reveals:<\/span><\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# cat tmp\/bootupmessages \r\n&lt;5&gt;Linux version 2.6.30 (root@cpebuild.smartrg.local) (gcc version 4.4.2 (Buildroot 2010.02-git) ) #1 SMP PREEMPT Mon May 18 13:51:47 PDT 2015\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">You will also see some interesting memory management functions made in-house if you analyze the binary:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/696d7b052e55c7b77929ed06a84f7482.png\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Go grab a copy of our <\/span><a href=\"https:\/\/www.pnfsoftware.com\/jeb\/demo\"><span style=\"font-weight: 400;\">trial<\/span><\/a><span style=\"font-weight: 400;\">, reverse some binaries and share your findings with us!<\/span><\/p>\n<h1><span style=\"font-weight: 400;\">Dynamic Analysis<\/span><\/h1>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">One thing that will help you along the way is to be able to upload binaries to the device to run them. The way I did it was to set up a web server on my computer and `wget` the statically-linked binaries in \/var or \/tmp (as \/var is a tmpfs as well, there are not much differences between the two). I took one trick from this <\/span><a href=\"https:\/\/www.youtube.com\/watch?v=KZWGD9fWIcM\"><span style=\"font-weight: 400;\">great presentation<\/span><\/a><span style=\"font-weight: 400;\"> which mentioned that you can upload your own busybox binary to break out of the limits imposed by the default busybox binary inside the firmware. For example, the `netstat` utility (that was not part of one of the original BusyBox applets) can become useful when you want to assess the possible attack vectors.<\/span><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n# .\/busybox-mips netstat -tunlp\r\nActive Internet connections (only servers)\r\nProto Recv-Q Send-Q Local Address Foreign Address State PID\/Program name\r\ntcp 0 0 0.0.0.0:44401 0.0.0.0:* LISTEN 259\/smd\r\ntcp 0 0 0.0.0.0:30103 0.0.0.0:* LISTEN 1031\/caCaptivePorta\r\ntcp 0 0 0.0.0.0:5431 0.0.0.0:* LISTEN 1240\/upnp\r\ntcp 0 0 127.0.0.1:5916 0.0.0.0:* LISTEN 799\/acsd\r\ntcp 0 0 :::80 :::* LISTEN 259\/smd\r\ntcp 0 0 :::21 :::* LISTEN 259\/smd\r\ntcp 0 0 :::30005 :::* LISTEN 259\/smd\r\ntcp 0 0 :::22 :::* LISTEN 259\/smd\r\ntcp 0 0 :::23 :::* LISTEN 259\/smd\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">One \u00a0other thing you\u2019ll like to have is a statically-linked gdbserver. You can found one <\/span><a href=\"https:\/\/github.com\/rapid7\/embedded-tools\/tree\/master\/binaries\/gdbserver\"><span style=\"font-weight: 400;\">online<\/span><\/a><span style=\"font-weight: 400;\"> or build a newer one with <\/span><a href=\"https:\/\/buildroot.org\/downloads\/\"><span style=\"font-weight: 400;\">buildroot<\/span><\/a><span style=\"font-weight: 400;\"> and connect to it from JEB, for example.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">QEMU <\/span><\/h2>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">You can of course emulate the binaries as I did for the DVRF challenges but I found it hard to recreate the whole environment with running daemons. Be sure to have the exact same behaviour as the real device&#8217;s with all the required files created on boot. <\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Further analysis<\/span><\/h2>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">I did find what seems to be UART pinout and wanted to play with that as well (OpenOCD might become useful for later analysis). More binaries and shared libraries need to be checked and even ARM devices will become interesting since we released the alpha version of the ARM decompiler in the latest update.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">And that was the tips and tools I wanted to share! If you want to see MIPS memory corruption, head over to the <\/span><a href=\"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-2\/\"><span style=\"font-weight: 400;\">previous blogposts<\/span><\/a><span style=\"font-weight: 400;\"> for more.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For the final blog post of this series (part 1 , part 2), let\u2019s reverse a real router firmware. First off, no 0days or security sensitive information will be disclosed in this blogpost but if you have a contact at SmartRG, let us know. To be able to reverse easily and test my findings, I &hellip; <a href=\"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-3-reversing-the-smartrgs-sr505n\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Firmware exploitation with JEB part 3: Reversing the SmartRG\u2019s sr505n<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,13],"tags":[],"class_list":["post-735","post","type-post","status-publish","format-standard","hentry","category-jeb2","category-native-code"],"_links":{"self":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=735"}],"version-history":[{"count":0,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/735\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}