Monday, August 26, 2013

JackCR ISSA 2013 Netwars Challange - Answers

ISSA 2013 Netwars Challange

Response by @BryanNolen


@JackCR recently posted the ISSA 2013 Netwars challenge on his blog []

I have already provided a quick write up on getting the memory image from it working [], so now let's dive into the actual forensics.

Challenge Background

Participants were invited to download and boot an ISO file containing a Live CD version of Security Onion which had been customised for the event.

One the desktop were 3 data files and the challange questions.

Network Capture     issa-2013-challenge.pcap
Disk Image              issa-2013-challenge.sda1.dd
Memory Capture     vmss.core

There were 25 questions to be answered, and though the course of this post I will provide my answers as well as details as to how I came to my conclusions.

Rather than using the supplied analysis environment, I have opted to extract the evidence files over to a seperate VMDK volume which I can then mount on normal analysis systems.

Baselining the Evidence Provided

Using the files command, we can easily determine the basic formats of the the evidence provided:

issa-2013-challenge.pcap:                     tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)
issa-2013-challenge.sda1.dd:                  Linux rev 1.0 ext3 filesystem data, UUID=bc8f66b6-48cb-4dfa-a554-cb91b9b83dd7 (large files)
vmss.core:                                    ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from 'GuestVM'

Based on this we can make the following assumptions

We have a partition image, rather that a whole disk image, and that the partition is ext3 formatted.
The memory dump is in 32bit ELF format which rules out a dump from VirtualBox (which uses ELF64 format instead)
We need to convert the memory dump to be able to process it in volatility
We are dealing with Intel archetecture and not some weird ARM/MACH/SPARC system

A Word of Warning

Please note in this post I will use /path/to/image/ to represent the full path to where I hve mounted my evidence VMDK. You will need to change this to match your system if you want to replicate what I have done.

Answering the Questions

1. What time did the attack begin?
Based on the datestamp given in the first 200 OK header, the initial recon began at Fri, 08 Feb 2013 22:47:07 GMT. Looking in the packet capture, there was also ICMP ping activity 2 minutes before this.

This is co-related with the apache logs showing the initial HEAD request at 08/Feb/2013:17:47:07 -0500 with the same user agent as observed on the wire.


Connection: Keep-Alive
User-Agent: Mozilla/5.00 (Nikto/2.1.5) (Evasions:None) (Test:Port Check)


HTTP/1.1 200 OK
Date: Fri, 08 Feb 2013 22:47:07 GMT
Server: Apache/2.2.12 (Ubuntu)
X-Powered-By: PHP/5.2.10-2ubuntu6
Set-Cookie: 5d3dc44c722468d70ab42839bbac9eb6=9ae4e1bd64c90d2202cdc7b0638b479a; path=/
Expires: Mon, 1 Jan 2001 00:00:00 GMT
Last-Modified: Fri, 08 Feb 2013 22:47:07 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

2. What was the initial indicator?
Request for "HEAD /" followed by "GET /" wuth a user agent matching a know scanning tool.

3. What tool was used to scan the webserver?
Nikto 2.1.5 as disclosed in the User Agent presented to the web server during recon.

User-Agent: Mozilla/5.00 (Nikto/2.1.5) (Evasions:None) (Test:Port Check)

4. What application was exploited to compromise the webserver?
The attacker targeted the content management system (Joomla 1.5), specifically the tiny_mce plugin. - - [08/Feb/2013:18:33:42 -0500] "GET /plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/upload.php?type=file&folder= HTTP/1.1" 200 3055 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" - - [08/Feb/2013:18:33:42 -0500] "POST /plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/upload_file.php?folder=/images/stories/&type=file&feid=&obfuscate=3bc6aeeecd3d028411bb8a479e93c359&sessidpass= HTTP/1.1" 200 283 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" - - [08/Feb/2013:18:33:42 -0500] "GET /plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/upload_process.php?folder=/images/stories/&type=file&feid=&filetotal=1 HTTP/1.1" 302 737 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" - - [08/Feb/2013:18:33:42 -0500] "POST /plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/edit.php?type=file&folder= HTTP/1.1" 200 8283 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"

5. What was the ip address of the attacker that compromised the webserver?

6. Were there any additional ip addresses used in the attack? If so, what are they?
One additional IP address was observed,

7. What file was initially placed on the machine by the attacker

8. What directory was it located in?
From the apache webroot /images/stories/ which maps to /var/www/images/stories

9. What allowed the upload of that file?
Exploit in the tiny_mce plugin for Joomla 1.5

10. What was the first operating system command executed by the attacker?
Bonus - the attacker launched a perl based backconnect shell to port 4444 that was base64 encoded in ogfcmxaiaexofkdozkvz.php

11. How did the attacker attempt to escalate privileges?
By using a exploit in the way PAM reads /etc/motd executed though a custom script located on the attackers server at "" and downloaded to the target server via a wget command executed in the backconnect session.

12. What was the timestamp that privilege escalation was attempted?
Fri, 08 Feb 2013 23:37:49 UTC

13. Is the machine still at risk for this method of privilege escalation? Why?
Yes, the exploit relies on a vulnrability in PAM, which was not patched at the time of attack.

14. What files were placed on the webserver by the attacker?

15. How was the attacker able to place each file on the machine?
ogfcmxaiaexofkdozkvz.php was uploaded via the aforementioned Joomla exploit.
timeserver.bash and webstat.txt / webstat.php were retrieved from the attackers machine via wget, executed through the backconnect shell
linux-rootkit.tar.gz was uploaded via the webshell

16. What additional tool was placed on the machine that gave the attacker direct access?
webstat.php - a full featured PHP webshell.

17. How did the attacker access this tool?
By accessing it through their web browser.

18. What did the attacker take from the webserver?
Dumps of the MySQL databases

19: What are the md5 hashes of all the files taken?
6b9caaac96c3e3f34d09a8288dba874a    dump_172.16.150.20_Joomla_08-02-2013-18-46-37.sql
c38154a80b3ab96272d576b550d5cd63  dump_172.16.150.20_mysql_08-02-2013-18-47-33.sql

20. What directory was created by the attacker?

21. What are the contents of this directory?

22. Was the attacker able to successfully execute the tool in this directory? How do you know?
At this stage it does not appear so. The output from the the tool appears to be how to use instructions. Looking at the packet capture the command was never executed with the correct password ("fabrika" based on the .c file)


Sistem yetki unitesi

Kullanim: /var/tmp/.www/linux-rootkit/kontrol <password>


System power unit

Use: /var/tmp/.www/linux-rootkit/kontrol <password>

23. What was the exact netstat command that was executed at Fri Feb 08 2013 18:53:37? What ports were listening based on the output from that command?
netstat -nap

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0*               LISTEN      -
tcp        0      0    *               LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0      ESTABLISHED -
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Path
unix  2      [ ACC ]     STREAM     LISTENING     2390     -                   @/com/ubuntu/upstart
unix  2      [ ]         DGRAM                    2447     -                   @/org/kernel/udev/udevd
unix  5      [ ]         DGRAM                    3473     -                   /dev/log
unix  2      [ ACC ]     STREAM     LISTENING     3790     -                   /var/run/mysqld/mysqld.sock
unix  2      [ ]         DGRAM                    5354     -
unix  2      [ ]         DGRAM                    3783     -
unix  2      [ ]         DGRAM                    3615     -
unix  3      [ ]         DGRAM                    2479     -
unix  3      [ ]         DGRAM                    2478     -
unix  3      [ ]         STREAM     CONNECTED     2444     -                   @/com/ubuntu/upstart
unix  3      [ ]         STREAM     CONNECTED     2441     -

24. How was the attacker able to gain access to the database credentials?
Read the contents of /var/www/configuration.php via web shell.

25. List the points of remediation that need to occur as a result of the analysis performed.

  • Upgrade system from Ubuntu 9.10 to 13.04.
  • Update Joomla
  • Disable/Delete unneeded modules
  • Reset ALL credientials (user and database)
  • Install Web Firewall (mod_security, cloudflare etc.)
  • Change permissions on web folders so they are NOT writable by the apache account unless absolutly needed.

Friday, August 23, 2013

JackCR ISSA 2013 Netwars Challange - Memory Issues

ISSA 2013 Netwars Challange - Getting the memory image to work.


Unlike @JackCR's previous challenges, this one is 1. from a Linux server, and 2. does not have a memory component. Well, that is not entirely accurate, there is a memory dump but it is not usable because of the way that vmss2core produces a file that is not useful for linux memory forensics. Long story short, Volatility can now read vmem (VMWare memory) and vmss (VMWare Snapshot) natively - don't use vmss2core anymore!

That said, there is a way to extract the memory image so that you can process it in volatility... once you have also created a profile!

A Word of Warning

Please note in this post I will use /path/to/image/ to represent the full path to where I hve mounted my evidence VMDK. You will need to change this to match your system if you want to replicate what I have done.

Converting the Memory Dump

After a quick bit of google-fu I was able to find a page [] that described a process for extracting the memory image in RAW from the ELF64 format used by VirtualBox, and acting on the hunch that the ELF32 format would be functionally similar decided to try it out.

$ readelf --program-headers vmss.core

Elf file type is CORE (Core file)
Entry point 0x0
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  NOTE           0x000074 0x00000000 0x00000000 0x00144 0x00000     0
  LOAD           0x001000 0x00000000 0x00000000 0x20000000 0x20000000 RWE

The line that we care about is LOAD. Based on this output we now know out RAW data is 0x20000000 long and begins at offset 0x001000. After a little bit of hex-dec conversion we can then use dd to export this section

$ dd if=vmss.core bs=4096 skip=1 count=131072 of=memdump.bin
131072+0 records in
131072+0 records out
536870912 bytes (537 MB) copied, 9.01116 s, 59.6 MB/s

Now we have our memory dump, we now need to determine what profile we need and to generate it as need. Luckily we have a partition image that should hopefully have the /boot and /usr/src/linux-headers-* directories on it, which we need to create the specific profile for this system

# mkdir /media/temp
# mount -t ext3 -o ro /path/to/image/issa-2013-challenge.sda1.dd /media/temp
# cd /media/temp
# ls
bin  boot  cdrom  dev  etc  home  initrd.img  lib  lost+found  media  mnt  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var  vmlinuz

Looking good :)

# cat etc/*-release

Not so good, this is an OLD version of Ubuntu :(

# ls boot usr/src
abi-2.6.31-14-generic-pae     grub                              memtest86+.bin                    vmcoreinfo-2.6.31-14-generic-pae
config-2.6.31-14-generic-pae  initrd.img-2.6.31-14-generic-pae  vmlinuz-2.6.31-14-generic-pae

linux-headers-2.6.31-14  linux-headers-2.6.31-14-generic-pae

Excellent, we have what we need to compile a custom profile anyway. Step 1 - get the and kernel headers from the target system. You can also get them from the distribution repository, but it is better to get them from the target itself for maximum compatability.

# mkdir /path/to/image/temp
# cp -r usr/src/linux* /path/to/image/temp/
# mkdir /path/to/image/temp/boot
# cp boot/ /path/to/image/temp/boot/

Now we change the the location we have volatility sources downloaded and compile the profile based on our new paths
These directions are based on the current SVN version as of 2013-08-23 and assume you have pre-installed dwarfdump (see [])

# cd /path/to/image/volatility-read-only/tools/linux/
# make -C /path/to/image/temp/linux-headers-2.6.31-14-generic-pae CONFIG_DEBUG_INFO=y M=/path/to/image/volatility-read-only/tools/linux/ modules
# dwarfdump -di module.ko > module.dwarf
# make -C /path/to/image/temp/linux-headers-2.6.31-14-generic-pae CONFIG_DEBUG_INFO=y M=/path/to/image/volatility-read-only/tools/linux/ clean
# cp module.dwarf /path/to/image/temp/
# cd /path/to/image/temp/
# zip module.dwarf boot/
# mkdir /path/to/image/temp/plugins
# cp /path/to/image/temp/plugins/

And now for the moment of truth, does this profile load?

# cd /path/to/image/volatility-read-only
# python --plugins=/path/to/image/temp/plugins --info | grep Ubu
Volatile Systems Volatility Framework 2.3_beta
LinuxUbuntu910x86 - A Profile for Linux Ubuntu910 x86

Looking good so far....

# python --plugins=/path/to/image/temp/plugins -f /path/to/image/memdump.bin --profile=LinuxUbuntu910x86 linux_ifconfig
Volatile Systems Volatility Framework 2.3_beta
Interface        IP Address           MAC Address        Promiscous Mode
---------------- -------------------- ------------------ ---------------
lo                 00:00:00:00:00:00  False         
eth0           00:0c:29:7d:72:4b  False  


Thursday, May 30, 2013

Wireless comms for the Arduino, done properly :)

After some r&d it turns out that 433mhz is great for your garage door, but not so much if you want reliable comms over distances of 1.5km or greater. For that, we need the big guns, and the best on the consumer market that does not require a license is XBee from Digi.

On the left is a Stalker from SeeedStudios (described in an earlier post) but with the addition of the Bees Shield which has 2 separate XBee sockets meaning no additional cabling is required to link your gps/sensing bee with your comms bee :)

On the right is another XBee that has been paired with the remote unit and is linked to the pc so the telemetry can be read and processed (think moving maps *grin*)

More to follow.


Saturday, March 2, 2013

Wireless Comms for Arduino on the cheep

This is just a teaser :)
TX/RX Setup
Quick notes:

  • 433Mhz modules from Jaycar (low power, ~AUD$10 per module, should do 150 meters@2000 baud)
  • VirtualWire API for over the air packet handling
  • Custom message chunking (VirtualWire has a small limit on number of bytes per transmission, which is a pain for GPS and timestamp messaging which easily exceed this, especially with a preamble)

Monday, February 4, 2013

Adventures with Arduino

For no reason other than they are cool I have been playing around with an Arduino UNO and a Seeedstudio Stalker. Both of these devices are really easy to use and fairly cheep.

UNO w/ LCD Shield
The UNO is a base level arduino model and runs at 5v supplied by a barrel jack connector or via USB. The USB is also connected to an integrated USB USART allowing the same connector to be used for programming and power, as well as being connected to the hardware serial connectors on the micro for I/O.

Conversely, the Stalker runs at 3.3v but only accepts power from a LiPo battery (JST) connector or via the programming header connection. There is also a JST connector for a solar panel to allow the unit to trickle charge the battery for remote sensing apps. In order to program the unit you need an external USART - the UsartSBee is ideal for this as it has all the required connections (tx,rx,dtr,vcc & gnd.)

The other massive difference is that the Stalker has an integrated header for connection an XBee module in addition to the usual ardunio rev 3 layout headers. Oh, it also has a real time clock and mini-sd card reader on board, meaning you don't need extra shields or break outs for those modules. The disadvantage is that those pins are hardwired to the micro making a number of shields incompatible.
Stalker w/GPSBee

In this shot you can see the GPSBee connected to the Stalker, power via the programming header though the UsartSBee's regulated supply, and finally Software Serial connection back to the UNO for debugging. The Software Serial is needed as the hardware serial connections on the Stallker are hardwired to the programming header AND the XBee socket, meaning you can be talking to one or the other, but not both, which complicates debugging in the field.

Eventually, my goal is to use the Stalker as a standalone datalogging unit, a function for which it is ideal because of the RTC & SD integration. Next steps are designing a custom sensor shield and working out a decent way to get the data from it up to 500M away wirelessly :)


Tuesday, January 29, 2013

Forensic Challanges & Future Plans

Some time ago (back in distant 2012) an open challenge was posted on twitter:

My response to this was posted on dropbox. In upcoming posts I will be covering some of the techniques used as well as finally addressing some of those unanswered questions I left dangling in my analysis:

* Use of the ChopShop gh0st_decode module to extract the commands used (Appendix A) as
well as the files themselves.
* Use of the mftparser command for volatility to extract the bat files from the $DATA
segments in RAM
* Reconstruction of command line activity over a PSEXEC session from memory

One other thing that was useful from this exercise was accurately reconstructing the IP addresses in use on the device being examined. For this I created a plugin for Volatility to do just that.

You can download the alpha release from dropbox. In a future post I will deconstruct how it works and ways to extend it.

The report, plugin, and other bits and pieces are now on my GitHub repo.


Blog Reboot

Well, after putting it off for years I have finally decided to re-launch this blog. Hopefully with more content than 1 now deleted post and a "welcome" posting :)