December 30, 2013

Another look at a cross-platform DDoS botnet

I learned from a recent "Malware Must Die" post about a Linux malware sample that is associated with DNS amplification attacks.  As mentioned in the MMD post, several researchers have posted on this, or similar malware.  Since I'm particularly interested in Linux malware, especially if it has a DDoS component, I thought I'd also take a look.

I was able to get the malware to execute on my Linux sandbox and connect to the C&C.  While I've yet to see any DDoS related activity, I did pcap the C2 comms and snap an image for Volatility analysis.  Links to the pcap and memory image can be found at the bottom of this post. 

The malware was downloaded from hxxp://198.2. [.] 192.204:22/disknyp
The MD5 hash value of the sample I obtained is 260533ebd353c3075c9dddf7784e86f9
The C2 is located at 190.115.20.27:59870

Referencing the supplied pcap, the compromised host connected to the C2 at 18:46 EST. Upon connection to the C2, the compromised host sends information about the current Linux kernel, in this case, "Linux 2.6.32-33-generic-pae"

bot sending kernel info to C2

It's interesting to note that the bot's C2 communications is via a persistent connection.  Unlike typical HTTP bot check-in traffic, this bot maintains a connection to the remote host on port 59870.  Since this is all one huge session, if you attempt "Follow TCP stream" in Wireshark, it will take a bit of time to present the output.

The C2 then sends 4 bytes,  "0x04 0x00 0x00 0x00" upon which the bot sends back 27 bytes of all 0x00.

At 21:13, the C2 sends 75 bytes of hex: 

Initial 75 byte sequence from C2 to bot

Approx. every thirty seconds, the C2 sends a new 75 byte sequence to the bot, for example:

01:00:00:00:43:00:00:00:00:fd:05:00:00:00:00:00:00:01:00:00:00:01:00:00:00:80:d4:07:c6:9c:50:00:01:00:00:00:00:00:00:00:1e:00:00:00:00:04:00:00:00:04:00:00:10:27:60:ea:ac:f5:a5:8f:ac:f5:a5:8f:00:00:00:00:00:d4:07:c6:9c:50:00

01:00:00:00:43:00:00:00:00:fe:05:00:00:00:00:00:00:01:00:00:00:01:00:00:00:80:d4:07:c7:d4:50:00:01:00:00:00:00:00:00:00:1e:00:00:00:00:04:00:00:00:04:00:00:10:27:60:ea:ac:f5:a5:8f:ac:f5:a5:8f:00:00:00:00:00:d4:07:c7:d4:50:00

01:00:00:00:43:00:00:00:00:ff:05:00:00:00:00:00:00:01:00:00:00:01:00:00:00:80:d4:07:c6:9b:50:00:01:00:00:00:00:00:00:00:1e:00:00:00:00:04:00:00:00:04:00:00:10:27:60:ea:ac:f5:a5:8f:ac:f5:a5:8f:00:00:00:00:00:d4:07:c6:9b:50:00

Byte offset decimal 09 appears to be a counter, incrementing by one each time on each sequence from the C2.  The contents at decimal offset 28 and and 71 initially vary between 0xC6 and 0xC7.  This continues until 22:06 EST when the pattern changes and varied values are seen:

01:00:00:00:43:00:00:00:00:1d:06:00:00:00:00:00:00:01:00:00:00:01:00:00:00:80:73:ee:ed:f5:58:1b:01:00:00:00:00:00:00:00:0c:00:00:00:00:04:00:00:00:04:00:00:10:27:60:ea:ac:f5:a5:8f:ac:f5:a5:8f:00:00:00:00:00:73:ee:ed:f5:58:1b

01:00:00:00:43:00:00:00:00:1e:06:00:00:00:00:00:00:01:00:00:00:01:00:00:00:80:7a:e0:22:c7:58:1b:01:00:00:00:00:00:00:00:0c:00:00:00:00:04:00:00:00:04:00:00:10:27:60:ea:ac:f5:a5:8f:ac:f5:a5:8f:00:00:00:00:00:7a:e0:22:c7:58:1b

01:00:00:00:43:00:00:00:00:1f:06:00:00:00:00:00:00:01:00:00:00:01:00:00:00:80:0e:11:5f:4a:58:1b:01:00:00:00:00:00:00:00:0c:00:00:00:00:04:00:00:00:04:00:00:10:27:60:ea:ac:f5:a5:8f:ac:f5:a5:8f:00:00:00:00:00:0e:11:5f:4a:58:1b

01:00:00:00:43:00:00:00:00:20:06:00:00:00:00:00:00:01:00:00:00:01:00:00:00:80:3d:84:e6:15:5b:1b:01:00:00:00:00:00:00:00:0c:00:00:00:00:04:00:00:00:04:00:00:10:27:60:ea:ac:f5:a5:8f:ac:f5:a5:8f:00:00:00:00:00:3d:84:e6:15:5b:1b

The bot's replies again replies with a 27 byte sequence, however decimal offset 19 now has a value that will vary between 0 and 2.

00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01:00:00:00:00:00:00:00
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:02:00:00:00:00:00:00:00
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00


Volatility

Some basic Volatility analysis of the memory image yields the following:

linux_pslist
linux_pslist
The 'disknyp' process started at 23:45 UTC with PID 1241.  Ran with user privs and no child processes were noted.



linux_lsof -p1241
linux_lsof for PID 1241
Process 'disknyp', PID 1241 has /dev/null open as well as socket:[6931]



linux_proc_maps
linux_proc_maps for PID 1241
Note that /tmp/disknyp is the path where 'disknyp' was originally executed.  Dumping the two segments at '/usr/tmp' produces two files, 'task.1241.0x8048000.vma' and 'task.1241.0x8168000.vma'.   
Running 'file' on the segments shows:
task.1241.0x8048000.vma: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
Dumping strings for that segment shows:

section of 'strings' output for PID 1241 segment 0x8048000
We note the string "fake.cfg" that was mentioned in other posts related to this malware.  Attempting to find the file in the original /tmp directory:


linux_find_file for 'fake.cfg'

linux_yarascan
Let's use the 'yarascan' plugin to see if there are any other references to 'fake.cfg' in this image.

searching for other references to 'fake.cfg' using the linux_yarascan plugin
We see that the string 'fake.cfg' is only found in PID 1241, 'disknyp'.  Again using the 'linux_find_file' plugin, we can dump the contents of 'fake.cfg' located at inode 0xed9dc088. 

Contents of 'fake.cfg'
Final Thoughts

This appears to be some Proof of Concept or "testing" malware.  There are several aspects to this sample that make me wonder if it was just put out there to see how quickly it would be detected and analyzed.
  • Analysis of the original file as downloaded from hxxp://198.2. [.] 192.204:22/disknyp that it is statically linked, not stripped.
  • The C2 communications is somewhat noisy.  Maintaining a persistent connection with checkins every few seconds is not very stealthy.
  • No attempt to hide the process.  In hours of running this, I didn't see any child processes or variance in the process on the local host.
  • 'fake.cfg' is created in the malware's working directory. 'fake.cfg' really?
  • As I mentioned earlier in the post, I have yet to see any DoS related traffic from this sample.  I'm also not aware of DoS activity being seen by other researchers.  If anyone has learned otherwise, I'd love to hear from you!

December 17, 2013

A Forensic Overview of a Linux perlbot

It's fairly old news that exploit attempts against PHP, ColdFusion, and Content Management Systems are quite common these days.  Most of these attempts target old vulnerabilities, hoping to hit enough neglected servers to make it worthwhile.   In some cases, a particular exploit may succeed against a high value server, leading to some pretty significant data leakage.  In others, the attacker is going for volume, where they can make use of a large number of compromised hosts. 

I recently noticed a PHP exploit attempt coming from several HK and CN IP addresses, so I allowed the exploit on my honeypot and documented the results. The resulting activity was very reminiscent of the the early botnet days, with IRC Command and Control, as well as the use of the compromised host as a scanning tool.  
I thought it might be interesting to show this example of a successful PHP exploit against a linux server, what it does, and how you might go about some basic analysis. I'll conclude by showing how some basic memory forensics can be performed on this type of incident using Volatility. 

In this example, the remote attacker attempts the following PHP exploit:

PHP exploit attempt against CVE-2012-1823

This exploit attempt is against an old vulnerability (CVE-2012-1823) which allows a remote attacker to inject arbitrary code via command line options within the HTTP query string.
When decoded, the attack string is:


Decoded PHP exploit string

The rest of the HTTP POST reveals the attempted commands to be executed if the exploit was successful:

Attempted command injection string

This string of commands instructs the compromised server to do the following:
  • Change working directory to /var/tmp
  • Remove any file named "a.pdf" from that directory
  • Download file "a.pdf" from a domain under the attacker's control and save it to /var/tmp. The "a.pdf" file is actually a perl script, which is given a "pdf" file extension.
  • Execute the perl script "a.pdf"
  • Finally, delete the perl script, "a.pdf"
To ensure downloading success of the remote script, the attacker repeats these instructions using 'curl', 'fetch', and 'lwp-get'.

Network packet capture reveals the overall activity of the injected script.  Upon execution, the script sleeps for awhile, then connects to the IRC C2 on 'vafel.pexit.cu.cc', port 45129.

Perl script connecting to remote IRC server on vafel.pexit.cu.cc

A short time later, the compromised host is instructed to fetch another script, "ins_h.sh" this time from m1.pexit.cu.cc
Compromised server instructed to download bash script 'ins_h.sh'
The contents of the "ins_h.sh" script shows among other things, the attacker creating hidden directories on the linux server, fetching source code of another tool (h.c), compiling it, and modifying the crontab.
Not long after this, a fair amount of assorted files were downloaded to the compromised host.  Among these include mining software, development libraries, and compiling tools. Also downloaded were a large collection of linux local privilege escalation exploits. 

After the attacker had the box configured the way he wanted it, activity related to Bitcoin and Primecoin mining soon began.   Of particular note was the use of the Stratum Mining Protocol connecting to a pool server on 37.251.139.161.

Bitcoin Stratum mining protocol traffic

Most servers that are injected with these various scripts are then used for a variety of tasks, including DDoS, vulnerability scanning, and exploiting.  The mining of virtual currency is now often seen running in the background during the attacker's "downtime".  The Internet Storm Center recently posted an entry, "The case of Minerd", which discusses the increasing use of compromised servers being used to mine virtual currency.  

Volatility

Let's now do a bit of memory forensics on the RAM image of this particular compromised host.  We'll use Volatility version 2.3.1 which has the ability to analyze Linux images.  In order to do this, you'll have to supply the appropriate Linux profile.  Creating a profile is very easy, but it needs to be done for the appropriate distribution and kernel in use.  I'd recommend bookmarking Ken Pryor's Github site, where Ken is building a repository of Linux Volatility profiles.

The system under analysis is an Ubuntu 10.04 server, with kernel version 2.6.32-33-generic-pae.
We'll first take a look at the active processes on the system via the 'linux_pslist' plugin.

'linux_pslist' output

Note the timestamps for PID 1517 (httpds) and PID 27157 (rsyslogd) are much later than those processes listed above it.  Since the earlier processes and their relative timestamps resemble a Linux startup routine, the two later processes are of interest.   Note also that these processes show a User ID and Group ID of 1002, which Ubuntu allocates to a user account.

The Volatility plugin, 'linux_psaux' behaves similar to the Linux command 'ps aux', so it is able to show  the command line arguments used at process invocation.  Running this against our image shows:

'linux_psaux' output

So the process named 'httpds', with PID 1517 was started with "/usr/bin/httpd" and process 'rsyslogd', with PID 27157 was invoked with command line arguments "-B -c".  We'll note to check 'httpd' in /usr/bin if we obtain a disk image of the compromised server.  Researching the 'rsyslogd' command, we learn that "-B" is not a valid option, so this process remains suspicious. 

While the pslist command finds running processes by walking the linked list of Linux task_struct-> tasks, the  'linux_pidhashtable' command walks the hashtable, which hashed by process identifier (pid).  This may help in finding hidden processes.

'linux_pidhashtable' output

Note the four additional  'rsyslogd' processes discovered by the 'linux_pidhashtable' plugin.

In cases like this, it's always a good practice to check the server's networking information.  Volatility has a number of networking plugins that will help identify remote connections and the processes that initiated them.  For example, the 'linux_netstat' plugin behaves just like the Linux 'netstat'  command, and will list active network connections, as well as listening sockets.  In this case, we see suspicious processes, PID 1517, and PID 27157 as the processes associated with established network connections to remote IP addresses.  
  
'linux_netstat' output

It's also a good idea to run the 'linux_route_cache' plugin, to display the routing table cache.  This may reveal any old connections that may not be seen via the 'linux_netstat' plugin.

'linux_route_cache' output

Now that we've established PIDs 1517 and 27157 as suspicious processes,  let's get a list of all the open files and paths associated with each.  Similar to using 'lsof' on a live, running Linux system, we'll use the Volatility plugin 'linux_lsof' here.  

'linux_lsof' output for PID 1517
'linux_lsof' output for PID 27157

Note that both PID 1517 and 27157 have two open files in common.  One is socket: [7916], and the other is the httpd.pid file in the hidden directory "/tmp/.ICE-unix/-log/".

Another useful Volatility plugin is 'linux_proc_maps'. This plugin will display the details of process memory, including shared libraries.  Details include the start and end location, inode and flag for each section.  This is very valuable information to be gleaned from memory during a forensic investigation.  For example, on PID 1517 we get the following:

'linux_proc_maps' output for PID 1517

We see the same hidden directory mentioned earlier, but now referring to filename 'httpds'.  The inode for this file is seen as 405961.  The 'linux_proc_maps' plugin has an output switch that allows for the dumping of the listed segments.  However to recover the complete, intact file, we need to recover it from the page cache, which holds in memory all the pages pertaining to a file.   We can do this via the 'linux_find_file' plugin.  This plugin will find the address to the file's inode, then allow you to dump the cached file contents from memory.  So for the 'httpds' file at inode 405961:

python vol.py -f /home/abc/pexit.vmem --profile=LinuxUbuntu1004_pae32-33x86 linux_find_file -F "/tmp/.ICE-unix/-log/httpds"

'linux_find_file' output for 'httpds' file

We then use the 'linux_find_file' plugin with the -O option, passing the address of the inode in order to extract the file.  After extraction, we can run 'strings' on it and see contents of significance:

'strings' of recovered 'httpds' file from hidden directory
These are just a few examples of how Volatility can assist in your forensic analysis of a compromised host.  A good deal of what is gleaned from Volatility can then be correlated to the disk image examination.  
I've posted the Linux memory image for this perlbot at the bottom of this post. Be sure to get the Linux profile, "Ubuntu1004_pae32-33.zip" from Ken Pryor's site.  You'll need it to run Volatility against this image. 

I hope this post shed some light on one example of a successful PHP exploit and the resulting script injection.  Besides ensuring that Internet facing servers are properly patched and hardened, knowing how to quickly track such a compromise should be part of best practices.  Across my honeypots, I'll see dozens of these a day, including Linux ELF files, perlbots, and vintage shells.   

While these injected perl and shell scripts are typically considered the patio gnats of the Internet, more annoying than anything else, they do have the potential to cause considerable harm. 

Memory image of pexit perlbot