Showing posts with label cable modem. Show all posts
Showing posts with label cable modem. Show all posts

Monday, September 12, 2016

LuaBot: Malware targeting cable modems

During mid-2015 I disclosed some vulnerabilities affecting multiple ARRIS cable modems. I wrote a blogpost about ARRIS' nested backdoor and detailed some of my cable modem research during the 2015 edition from NullByte Security Conference.

CERT/CC released the Vulnerability Note VU#419568 and it got lots of media coverage. I did not provide any POC's during that time because I was pretty sure that those vulnerabilities were easily wormable... And guess what? Someone is actively exploiting those devices since May/2016.

The malware targets Puma 5 (ARM/Big Endian) cable modems, including the ARRIS TG862 family. The infection happens in multiple stages and the dropper is very similar to many common worm that targets embedded devices from multiple architectures. The final stage is an ARMEB version from the LuaBot Malware.


The ARMEL version from the LuaBot Malware was dissected on a blogpost from Malware Must Die, but this specific ARMEB was still unknown/undetected for the time being. The malware was initially sent to VirusTotal on 2016-05-26 and it still has a 0/0 detection rate.



Cable Modem Security and ARRIS Backdoors

Before we go any further, if you want to learn about cable modem security, grab the slides from my talk "Hacking Cable Modems: The Later Years". The talk covers many aspects of the technology used to manage cable modems, how the data is protected, how the ISPs upgrade the firmwares and so on.


Pay special attention to the slide #86:


I received some reports that malware creators are remotely exploiting those devices in order to dump the modem's configuration and steal private certificates. Some users also reported that those certificates are being sold for bitcoin to modem cloners all around the world. The report from Malware Must Die! also points that the LuaBot is being used for flooding/DDoS attacks.


Exploit and Initial Infection

Luabot malware is part of a bigger botnet targeting embedded devices from multiple architectures. After verifying some infected systems, I noticed that most cable modems were compromised by a command injection in the restricted CLI accessible via the ARRIS Password of The Day Backdoor.

Telnet honeypots like the one from nothink.org have been logging these exploit attempts for some time. They are logging many attempts to bruteforce the username "system" and the password "ping ; sh", but they're, in fact, commands used to escape from the restricted ARRIS telnet shell.


The initial dropper is created by echoing shell commands to the terminal to create a standard ARM ELF.


I have cross compiled and uploaded a few debugging tools to my cross-utils repository, including gdbserver, strace and tcpdump. I also happen to have a vulnerable ARRIS TG862 so I can perform dynamic analysis in a controlled environment.

If you run the dropper using strace to monitor the network syscalls, you can see the initial connection attempt:

./strace -v -s 9999 -e poll,select,connect,recvfrom,sendto -o network.txt ./mw/drop
connect(6, {sa_family=AF_INET, sin_port=htons(4446), sin_addr=inet_addr("46.148.18.122")}, 16) = -1 ENODEV (No such device)

The command is a simple download and exec ARMEB shellcode. The malicious IP 46.148.18.122 is known for bruteforcing SSH servers and trying to exploit Linksys router command injections in the wild. After downloading the second stage malware, the script will echo the following string:
echo -e 61\\\\\\x30ck3r

This pattern is particularly interesting because it is quite similar to the one reported by ProtectWise while Observing Large-Scale Router Exploit Attempts:
cmd=cd /var/tmp && echo -ne \\x3610cker > 610cker.txt && cat 610cker.txt

The second stage binary ".nttpd" (MD5 c867d00e4ed65a4ae91ee65ee00271c7) performs some internal checks and creates iptables rules allowing remote access from very specific subnets and blocking external access to ports 8080, 80, 433, 23 and 22:


These rules block external exploit attempts to ARRIS services/backdoors, restricting access to networks controlled by the attacker.

After setting up the rules, two additional binaries were transferred/started by the attacker. The first one, .sox.rslv (889100a188a42369fd93e7010f7c654b) is a simple DNS query tool based on udns 0.4.



The other binary, .sox (4b8c0ec8b36c6bf679b3afcc6f54442a), sets the device's DNS servers to 8.8.8.8 and 8.8.4.4 and provides multiple tunneling functionalities including SOCKS/proxy, DNS and IPv6.



Parts of the code resembles some shadowsocks-libev functionalities and there's an interesting reference to the whrq[.]net domain, which seems to be used as a dnscrypt gateway:



All these binaries are used as auxiliary tools for the LuaBot's final stage, arm_puma5 (061b03f8911c41ad18f417223840bce0), which seems to be selectively installed on vulnerable cable modems.

UPDATE: According to this interview with the supposed malware author, "reversers usually get it wrong and say there’s some modules for my bot, but those actually are other bots, some routers are infected with several bots at once. My bot never had any binary modules and always is one big elf file and sometimes only small <1kb size dropper"


Final Stage: LuaBot

The malware's final stage is a 716KB ARMEB ELF binary, statically linked, stripped and compiled using the same Puma5 toolchain as the one I made available on my cross-utils repository.


If we use strace to perform a dynamic analysis we can see the greetings from the bot's author and the creation of a mutex (bbot_mutex_202613). Then the bot will start listening on port 11833 (TCP) and will try to contact the command and control server at  80.87.205.92.


In order to understand how the malware works, let's mix some manual and dynamic analysis. Time to analyse the binary using IDA Pro and...

Reversing stripped binaries

The binaries are stripped and IDA Pro's F.L.I.R.T. didn't recognize standard function calls for our ARMEB binary. Instead of spending hours manually reviewing the code, we can use @matalaz's diaphora diffing plugin to port all the symbols.

First, we need to export the symbols from uClibC's Puma5 toolchain. Download the prebuilt toolchain here and open the library "armeb-linux\ti-puma5\lib\libuClibc-0.9.29.so" using IDA Pro. Choose File/Script File (Alt+F7), load diaphora.py, select a location to Export IDA Database to SQLite, mark "Export only non-IDA generated functions" and hit OK.

When it finishes, close the current IDA database and open the binary arm_puma5. Rerun the diaphora.py script and now choose a SQLite database to diff against:


After a while, it will show various tabs with all the unmatched functions in both databases, as well as the "Best", "Partial" and "Unreliable" matches tabs.

Browse the "Best matches" tab, right click on the list and select "Import *all* functions" and choose not to relaunch the diffing process when it finishes. Now head to the "Partial matches" tab, delete everything with a low ratio (I removed everything below 0.8), right click in the list and select "Import all data for sub_* function":


The IDA strings window display lots of information related to the Lua scripting language. For this reason, I also cross-compiled Lua to ARMEB, loaded the "lua" binary into IDA Pro and repeated the diffing process with diaphora:


We're almost done now. If you google for some debug messages present on the code, you can find a deleted Pastebin that was cached by Google.



I downloaded the C code (evsocketlib.c), created some dummy structs for everything that wasn't included there and cross-compiled it to ARMEB too. And now what? Diffing again =)



Reversing the malware is way more legible now. There's builtin Lua interpreter and some native code related to event sockets. The list of the botnet commands is stored at 0x8274: bot_daemonize, rsa_verify, sha1, fork, exec, wait_pid, pipe, evsocket, ed25519, dnsparser, struct, lpeg, evserver, evtimer and lfs:


The bot starts by setting up the Lua environment, unpacks the code and then forks, waiting for instructions from the Command and Control server. The malware author packed the lua source code as a GZIP blob, making the entire reversing job easier for us, as we don't have to deal with Lua Bytecode.


The blob at 0xA40B8 contains a standard GZ header with the last modified timestamp from 2016-04-18 17:35:34:


Another easy way to unpack the lua code is to attach the binary to your favorite debugger (gef, of course) and dump the process memory (heap).

First, copy gdbserver to the cable modem, run the malware (arm_puma5) and attach the debugger to the corresponding PID:
./gdbserver --multi localhost:12345 --attach 1058


Then, start gef/GDB and attach it to the running server:
gdb-multiarch -q
set architecture arm
set endian big
set follow-fork-mode child
gef-remote 192.168.100.1:12345


Lastly, list the memory regions and dump the heap:
vmmap
dump memory arm_puma5-heap.mem 0x000c3000 0x000df000


That's it, now you have the full source code from the LuaBot:


The LuaBot source code is composed of several modules:


The bot settings, including the DNS recurser and the CnC settings are hardcoded:


The code is really well documented and it includes proxy checking functions and a masscan log parser:


Bot author is seeding random with /dev/urandom (crypgtographers rejoice):


LuaBot integrates an embedded JavaScript engine and executes scripts signed with the author's RSA key:


Meterpreter is so 2000's, the V7 JavaScript interpreter is named shiterpreter:


There's a catchy function named checkanus.penetrate_sucuri, on what seems to be some sort of bypass for Sucuri's Denial of Service (DDoS) Protection:



LuaBot has its own lua resolver function for DNS queries:


Most of the bot capabilities are in line with the ones described on the Malware Must Die! blogpost. It's interesting to note that the IPs from the CnC server and iptables rules don't overlap, probably because they're using different environments for different bot families (or they were simply updated).

I did not analise the remote botnet structure, but the modular approach and the interoperability of the malware indicates that there's a professional and ongoing effort.


Conclusion

The analysed malware doesn't have any persistence mechanism to survive reboots. It wouldn't try to reflash the firmware or modify volatile partitions (NVRAM for example), but the first stage payload restricts remote access to the device using custom iptables rules.

This is a quite interesting approach because they can quickly masscan the Internet and block external access to those IoT devices and selectively infect them using the final stage payloads.

On 2015, when I initially reported about the ARRIS backdoors, there were over 600.000 vulnerable ARRIS devices exposed on the Internet and 490.000 of them had telnet services enabled:
If we perform the same query nowadays (September/2016) we can see that the number of exposed devices was reduced to approximately 35.000:
I know that the media coverage and the security bulletins contributed to that, but I wonder how much of those devices were infected and had external access restricted by some sort of malware...

The high number of Linux devices with Internet-facing administrative interfaces, the use of proprietary Backdoors, the lack of firmware updates and the ease to craft IoT exploits make them easy targets for online criminals.

IoT botnets are becoming a thing: manufacturers have to start building secure and reliable products, ISPs need to start shipping updated devices/firmwares and the final user has to keep his home devices patched/secured.

We need to find better ways to detect, block and contain this new trend. Approaches like the one from SENRIO can help ISPs and Enterprises to have a better visibility of their IoT ecosystems. Large scale firmware analysis can also contribute and provide a better understanding of the security issues for those devices.


Indicators of Compromise (IOCs)

LuaBot ARMEB Binaries:
  • drop (5deb17c660de9d449675ab32048756ed)
  • .nttpd (c867d00e4ed65a4ae91ee65ee00271c7)
  • .sox (4b8c0ec8b36c6bf679b3afcc6f54442a)
  • .sox.rslv (889100a188a42369fd93e7010f7c654b)
  • .arm_puma5 (061b03f8911c41ad18f417223840bce0)

GCC Toolchains:
  • GCC: (Buildroot 2015.02-git-00879-g9ff11e0) 4.8.4
  • GCC: (GNU) 4.2.0 TI-Puma5 20100224

Dropper and CnC IPs:
  • 46.148.18.122
  • 80.87.205.92

IP Ranges whitelisted by the Attacker:
  • 46.148.18.0/24
  • 185.56.30.0/24
  • 217.79.182.0/24
  • 85.114.135.0/24
  • 95.213.143.0/24
  • 185.53.8.0/24

Thursday, November 19, 2015

ARRIS Cable Modem has a Backdoor in the Backdoor

A couple of months ago, some friends invited me to give a talk at NullByte Security Conference. I started to study about some embedded device junk hacking hot topics and decided to talk about cable modem security. Braden Thomas keynoted at Infiltrate 2015 discussing about Practical Attacks on DOCSIS so, yeah, cable modem hacking is still mainstream.

On November 21st I'll be at Salvador speaking on "Hacking cable modems: The Later Years". It's not a talk about theft of service and getting free Internet access. I'll focus on the security of the cable modems, the technology used to manage them, how the data is protected and how the ISPs upgrade the firmwares. Spoiler Alert: everything's really really bad.


Securing cable modems is more difficult than other embedded devices because, on most cases, you can’t choose your own device/firmware and software updates are almost entirely controlled by your ISP.

While researching on the subject, I found a previously undisclosed backdoor on ARRIS cable modems, affecting many of their devices including TG862A, TG862G, DG860A. As of this writing, Shodan searches indicate that the backdoor affects over 600.000 externally accessible hosts and the vendor did not state whether it's going to fix it yet.


ARRIS Backdoors

ARRIS SOHO-grade cable modems contain an undocumented library (libarris_password.so) that acts as a backdoor, allowing privileged logins using a custom password.

The following files load the backdoor library on ARRIS TG862A Firmware TS0705125D_031115_MODEL_862_GW (released on 2015):

/usr/sbin/arris_init
/usr/sbin/dimclient
/usr/sbin/docsis_mac_manager
/usr/sbin/ggncs
/usr/sbin/gw_api
/usr/sbin/mini_cli
/usr/sbin/pacm_snmp_agent
/usr/sbin/snmp_agent_cm
/usr/www/cgi-bin/adv_pwd_cgi
/usr/www/cgi-bin/tech_support_cgi

ARRIS password of the day is a remote backdoor known since 2009. It uses a DES encoded seed (set by the ISP using the arrisCmDoc30AccessClientSeed MIB) to generate a daily backdoor password. The default seed is MPSJKMDHAI and guess what - many ISPs won't bother changing it at all.

The backdoor account can be used to enable Telnet and SSH remotely via the hidden HTTP Administrative interface "http://192.168.100.1/cgi-bin/tech_support_cgi" or via custom SNMP MIBs.



The default password for the SSH user 'root' is 'arris'. When you access the telnet session or authenticate over SSH, the system spawns the 'mini_cli' shell asking for the backdoor password.


When you log using the password of the day, you are redirected to a restricted technician shell ('/usr/sbin/cli')

Restricted shells are ;restricted

In order to understand how the backdoor works, I built an Puma5 toolchain (ARMEB) and cross compiled some useful tools like strace, tcpdump and gdbserver. I hosted them on my Github, get them here:

https://github.com/bmaia/cross-utils/tree/master/armeb

While analyzing the backdoor library and the restricted shells, I found an interesting code on the authentication check:



Yes, they put a backdoor in the backdoor (Joel from Dlink is sure to be envy). The undocumented backdoor password is based on the last five digits from the modem's serial number. You get a full busybox shell when you log on the Telnet/SSH session using these passwords.

The vendor asked not to disclose details about the password generation algorithm. I'm really relieved knowing that those awful guys from Metasploit won't be able to reverse this in a timely manner.


Vulnerability, Disclosure and Marketing

Of course, we need a logo so the media can report about this with fancy graphs as well as vendors could distribute customized t-shits at Blackhat.

What I like most about lcamtuf is how visionary he is. While people were still writing dumb fuzzers, he wrote AFL performed a detailed Technical analysis of Qualys' GHOST. Based on his analysis, I hired a couple of marketing specialists to find out the best way to disclose the ARRIS backdoor.

What do we have here?

- Multiple backdoors allowing full remote access to ARRIS Cable modems
- An access key that is generated based on the Cable modem's serial number

After a thoughtful analysis, the marketing committee advised w00tsec members to write a Keygen. In order to write a Keygen, we need a leet ascii art and a cool chiptune. The chosen font was ROYAFNT1.TDF, from the legendary artist Roy/SAC and the chiptune is Toilet Story 5, by Ghidorah.



Here's the POC (make sure you turn the sound on):




Conclusion

I reported these flaws to CERT/CC on 2015-09-13 but we didn't receive much feedback from the vendor. CERT/CC was very helpful and responsive (10/10 would disclose again!). I was asked not to release the POCs immediately so I'm going to wait for the vendor to "fix" the issue.


CERT/CC set a disclosure policy of 45 days long ago. They waited for more than 65 days for them to "fix" it but ARRIS didn't remove the backdoors in a timely manner. Someone needs to update the Responsible Disclosure RFC and include a note describing that vendors shall lose disclosure points whenever they plant a backdoor on the device (ARRIS modems have a third backdoor too, check the ConsoleCowboys Blog).

I'm pretty sure bad guys had been exploiting flaws on these devices for some time (just search for ARRIS DNS on Twitter, for example). We need more people bypassing EULAs and reversing end-user software and firmware. If you haven't heard about the Firmware.RE, check them right now. A broader view on firmwares is not only beneficial, but necessary to discover new vulnerabilities and backdoors, correlating different device families and showing how vulnerabilities reappear across different products.

To all the vendors out there, I would like to finish this post by quoting @daveitel:



Monday, November 11, 2013

Unpacking Firmware Images from Cable Modems

Hacking Cable modems used to be very popular during the early 2000’s. People like DerEngel and Isabella from TCNiSO carried lots of research on the topic and talks from bitemytaco (R.I.P) and BlakeSelf during DEFCON 16 and DEFCON 18 covered lots of information on the subject.

Securing cable modems is more difficult than other embedded devices because, on most cases, you can’t choose your own device/firmware and software updates are almost entirely controlled by your ISP. Most cable modems offer a limited administrative interface and management commands are sent using SNMP.

Cable Modem Firmware

There are basically three types of firmware images for cable modems:

- Signed and compresed (PKCS#7 & binary)
- Compressed binary images
- RAM dump images (uncompressed & raw)

You can dump your own firmware image using JTAG or sniffing the connection during upgrades, for example. I’m a big fan of binwalk and I always wondered why it doesn't unpack firmwares from popular Broadcom based cable modems so I decided to research on this.

Unpacking the Firmware

For this analysis I’ll use Cisco DPC3925, which is a very common DOCSIS 3.0 modem here in Brazil. Cisco DPC3925 has a BCM3380 chipset, 16MB Flash x 64MB DRAM memory configuration.


The compressed firmware image has around 4MB. Using strings against the file didn't help much and binwalk v1.2.1 (without any additional parameters) did not recognize it.


We can gather lots of useful information from the vendor’s page: user guides, datasheets, licensing information and open source disclaimer for the product. There are no sources available on Cisco's home, but the Copyright Notices section states that the product uses LZMA SDK 4.21.


So we know that the firmware is probably packed using LZMA but we still need to figure out how to unpack it. Binwalk -i displays results marked as invalid during the scan and we might get some clue:


The LZMA header is not well documented. There are some good resources on lzma-purejs Github and you can also check binwalk's magic file signatures (devttys0 already did all the hard work for us).

  Offset Size  Description
    0     1    lc, lp and pb in encoded form
    1     4    dictSize (little endian)
    5     8    uncompressed size (little endian)

The Bootloader in the beggining of the flash contains the necessary information to boot the firmware image. On the top of the firmware there's always an extractor which decompress the firmware into DRAM.

Offset 0x677 is a good candidate because it's located in the beginning of the file and it seems to have a valid header. 5D 00 00 00 01 indicates a LZMA compression level of -8 and the next 64 bits should be the data's uncompressed size (in little endian).


The 64 bits following the header (00 20 20 0E 3A 28 AB EF) is clearly not a valid uncompressed size (2898643604054482944 bytes). It represents the actual compressed data, making binwalk and 7zr unable to extract it.

What we need to do here is append a few extra bytes to the header so our regular 7zr binary can recognize and extract the data. We don't know the uncompressed size for the firmware yet: the good news is that we can append and specify a big value here, allowing 7zr utility to unpack it (although complaining that the EOF was reached too early). Let's specify 268435456 bytes (256MB), convert it to little endian (00 00 00 10 00 00 00 00) and append it to the original LZMA header. The new header should be something like ... 5D 00 00 00 01 00 00 00 10 00 00 00 00 00 20 20 ...

I took the opportunity to have a look on binwalk's API and wrote a simple lzma-unpacker.py:

This code will be obsolete in a couple of days because I'm pretty sure Binwalk incorporate this (a plugin maybe?)


The data was extracted successfully and contains 21982740 bytes. If we replace the uncompressed size on the LZMA header with the correct value in Little Endian (14 6E 4F 01 00 00 00 00), the 7zr tool would not complain about the file integrity.


Most Broadcom cable modems are packed this way, including the ones manufactured by different vendors. The script was fully tested and works fine for the following models:

  - Cisco DPC3925, DPC2434
  - Motorola SB5100, SB5101, SVG6582, SVG1202
  - Thomson ACG905, DCM425, DHG534, DHG544, DWG850, DWG874
  - Webstar DPC2203

Firmware Analysis

Now that you successfully unpacked the firmware, here's a couple of cool things you should do:

- Find default passwords


- Find backdoors



- Pentest the Web Application




- Fingerprint your device and submit to NMAP

- Find similar devices using scans.io dataset

- Mail HD Moore a copy of the firmware and wait for the CVE Spam