Tag Archive : forensic

/ forensic

So there was a seminar and workshop, a week ago. Not a big one, limited to at least 30 people. DracOs is invited to give a workshop, and I was one of the speaker. The presentation I brought is about memory forensics. This is an introduction and we were discussing certain basic of memory forensic there. I got two slots, the seminar in the morning and the workshop in the afternoon.

For workshop we were talking about Volatility framework for analysis and some tools for dumping memory in Windows. We also had handson material. We were not analyzing some random sample of memory dump, but we were analyzing a memory dump of host which infected by malware.

As always, you are free to read and spread it.

For the Seminar, you can grab it here.

 

For the workshop, you can grab it here.

Digital Forensics : Ann’s Aurora

December 11, 2015 | Labs, Writeups | No Comments

Ann’s Aurora is a digital forensic challenge created by SANS Digital Forensics & Incident Response (DIFT). This problem is released as a public challenge for communities. The problem can be considered as network forensic released as per 2011 with not so complicated difficulty. The challenge can be seen on this link.

This article will discuss about solution for Ann’s Aurora case.

All steps performed here has been tested on following environment:

  1. Windows 8.1 64-bit
  2. Linux Slackware 14.1 64-bit
  3. Sans Institute Forensics Toolkit (SIFT) Linux version 3.0

And tools used here is:

  1. Wireshark

Most of screenshot taken here are result of test performed on machine [1], however we have ensure that all steps are applicable to machine [2] and [3].

Incident Description

Ann Dercover want to steal secret recipe from SaucyCorp. She then tailing lead developer Vick Timmes and investigate how to access SaucyCorp server. Ann know Vick login with his laptop computer (IP 10.10.10.70) and do VPN connection to SaucyCorp.

Ann then use 0-day exploit for Internet Explorer and attack with Client-Side Spear Phising Attack to fool Vick Timmes browser.

List of Goals

Basically, this case has following foals:

  1. Know full URI of web request done by Vick Timmes.
  2. Know content of 1300-element wide array labeled as COMMENT which is response from Ann.
  3. Know second HTTP request done by Vick
    • Requested file name
    • MD5 hash value of requested file name
  4. Know time of TCP session establishment on port 4444
  5. Know time of TCP session closed on port 4444
  6. Know type and MD5 hash value of packet 17 from server.
  7. To Analyze Vick’s computer behavior when trying to establish connection to server on port 4445 after disconnected from port 4444.
    • How fast TCP Initial Sequence Number does changed.
    • How fast IP ID does changed.
    • How fast source port does changed.
  8. Know time of connection to port 4445 successfully established.
  9. Know MD5 hash value of data sent on port 4445 by server.
  10. Know time of TCP closed on port 4445.

These goals is summary of questions / goals proposed by the challenge, which can be seen on following link.

Evidences

The only evidence we have is a pcap formatted file “evidence06.pcap”. This file is records of all activities in network at incident time. The evidence can be downloaded freely on this link. To download it, you have to login to member area, which you can register there free.

Analysis

Preliminaries

File evidence06.pcap has MD5 hash: efac05c50c0ae92bf0818e98763920bd

Following screenshot prove it. This value should be similar to value written on challenge page.

uas_1

Know we want to know some general information about it.

  1. How many IP address involved?
  2. How many pair of (source,destination) port involved?

This means to grab raw estimation about scope of analysis.

For first goal, we use tshark which is command line version of wireshark. Our attention go to source and destination address recorded on this file.

Sender addresses can be extracted by:

tshark –r evidence06.pcap –T fields –e ip.src | sort | uniq

Which has following result:

uas_2

It should be clear that there are two unique address as sender address on this file:

  • 10.10.10.10
  • 10.10.10.70 (Vick Timmes)

We guess that 10.10.10.10 is Ann Dercover machine.

Destination addresses can be extracted by:

tshark –r evidence06.pcap –T fields –e ip.dst | sort | uniq

Which has following result:

uas_3

It is clear that the addresses which involved as destination address are:

  • 10.10.10.10 (probably Ann Dercover)
  • 10.10.10.70 (Vick Timmes)
  • 10.10.10.255

Address 10.10.10.10 and 10.10.10.70 exists on both side, we then make a hypothesis that both machine has direct communication each other. While address 10.10.10.255 only appear on destination side. We guess that this address is server of SaucyCorp server which is targeted by Ann Dercover.

Next we want to know pair of port used for data exchange. There are two type of transfer protocols: TCP and UDP.

tshark –r evidence06.pcap –T fields –e tcp.port | sort | uniq

Following is the result:

uas_4

And UDP port pairs:

tshark –r evidence06.pcap –T fields –e tcp.port | sort | uniq

With following result:

uas_5

Note that all pairs are not representing established connection. We know that one connection might use different pair on runtime which is quite common.

Attack Vector used by Ann is Microsoft Internet Explorer “Aurora” Memory Corruption. This exploit is indexed as MS10-002 pada bulletin Microsoft Security (https://technet.microsoft.com/library/security/ms10-002) or CVE-2010-0249 on Common Vulnerabilities and Exposures (http://www.cvedetails.com/cve/2010-0249).

Basically, this exploit attack browser Internet Explorer by the way Internet Explorer handle deleted objects. This exploit first create massive-size temporary garbage data. Next when the data is deleted, exploit will point to that memory location and attack can plan malware there. In this case, the payload used is Trojan Hydraq.

Goal I Solution (Full URI)

Seeing first packet we can get full URI as following:

uas_6

uas_1a

In other words, URI accessed by Vick is: http://10.10.10.10:8080/index.php

First packet is a part of HTTP request to get index page. Response to this request is packet indexed as packet 2 to packet 6 and also packet 8, which are subject to Goal 2.

Goal II Solution (Response String)

Second packet is an ACK message of first HTTP request, while the response text are given as packet 3 to packet 6 and also packet 8. Five of them are pieces of HTML file which is content of index page.

To get all of those fragments, we should track every packet involved. Right click on the first packet and use “Follow TCP Stream”. Make sure we use “Raw” option. The message is plaintext, so we can copy the content directly.

The content of that file can be seen on this link.

To ease analysis, we can do identifier substitution. Identifier substitution can be done without alter the script logic. The modification can be seen on this link.

In this part, we wan to know what the content of 1300 object array are. This can be done by source code analysis which refer to simplified and deobfuscated code.

The code will execute function “func2(event)” when the page is loaded for first time. Function func2() will then create a time which will execute func3 on next 50 milliseconds. This means, func3() will be executed, whatever it is. While func1() only executed once when executing func2(). Based on our knowledge that attack vector used is CVE-2010-0249, we know that func1() is responsible to generate massive-size temporary object which later be deleted.

About 1300 object created on array var2. Data on this array is a unicode-escaped string. The string is:

\u0c0f\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d
\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d

Or can be interpreted as following strings:

ఏ఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍఍

This massive object is used to flood the system and create perfect condition to execute the exploit, see further on (http://www.symantec.com/connect/blogs/trojanhydraq-incident-analysis-aurora-0-day-exploit).

Goal III Solution (Second HTTP Request)

Second HTTP request is done to obtain http://10.10.10.70:8080/ index.phpmfKSxSANkeTeNrah.gif

It is a GIF file on iframe which is automatically downloaded by browser. Request to this file is pointed by packet 9. While the response itself is on packet 11.

The requested file is a GIF file which can be seen by the signature in header as following:

uas_8

Right click on “Compuserve GIF, Version: GIF89a” in packet content and choose “Export Selected Packet Bytes”. Save it as GIF.

Our MD5 value calculation give us df3e567d6f16d040326c7a0ea29a4f41.

uas_9

Goal IV Solution ( Opening TCP Session Port 4444 )

To know time of connection establishment, we need to build basic understanding:

  • Destination IP address is 10.10.10.10
  • Destination port is 4444

Thus, we can set rule on Wireshark as following:

ip.dst==10.10.10.10 && tcp.dstport==4444

Knowing TCP three-way handshake, we know that connection is established when TCP handshake finished. It is marked by ACK message from initiator (one who want to connect). In this case, 10.10.10.70 to 10.10.10.10.

Inspection will lead us to packet 13 and 15. Packet 13 is a SYN message to start TCP handshake and packet 15 is ACK acknowledge and finish TCP handshake. Beyond this point, TCP session has been established.

Packet 15 is on 1.3 seconds offset relative to first packet seen on this file. It means the connection is opened on 1.3.

Goal V Solution ( Closing TCP Session Port 4444 )

To know time of connection closed, we need to build basic understanding:

  • Destination IP address is 10.10.10.10
  • Destination port is 4444

Thus, we can set rule on Wireshark as following:

(ip.dst==10.10.10.10 && tcp.dstport==4444) || (ip.dst==10.10.10.70 && tcp.srcport==4444)

Knowing TCP four-way handshake to close connection, we got idea about how TCP connection closed. It is marked by ACK from initiatior. However, we cannot point yet who become initiator, whether 10.10.10.10 or 10.10.10.70 both have possibilities. Therefore we need to look it on two conditions.

Inspection will lead us to pair packet 1563, 1565 and 1562,1564. Packet 1562 and packet 1563 are packet [FIN,ACK] where packet 1562 is sent first from 10.10.10.10 to 10.10.10.70.Therefore we can conclude that the server has initiative to end the connection after it finish transmitting. ACK packet is sent by 10.10.10.10 on packet 1564 to state end of connection.

Packet 1564 is on 87.6 second, which means the connection ended on 87.6

Goal VI Solution( Sent File Type )

Inspected packet is packet 17. We need to check header of the payload and search for some signatures.

uas_7

Here, we see that MZ is a signature for PE32 executable file. We then have confidence after see string “This program cannot be run in DOS mode” which is backward compatibility offered by Microsoft to ensure program is still recognized by older Windows but not for running purpose.

Therefore, the file sent is a Windows executable or PE32.

To do extraction, we need to collect fragments by using “Follow TCP Stream” on packet 17. Click “Save As” to store it, let say as “suspect1.exe”

MD5 checksum can be computed by following: b385b7cf73ba0e75b20e4fdb310717c2

uas_10

Goal VII Solution ( Vick’s Computer Behavior )

For this goal, we need to use following understanding

  • Destination IP address is 10.10.10.10
  • Destination port is 4445

Thus, we can set rule on Wireshark as following:

(ip.dst==10.10.10.10 && tcp.dstport==4445) || (ip.dst==10.10.10.70 && tcp.srcport==4445)

By previous goal (goal VI), we know that connection to port 4444 is closed on packet 1564, 87.6 second. Therefore we focus our attention to packet after 1564, which are 1566 and 1656 (when 10.10.10.10 send RST notification and 10.10.10.70 send SYN back).

1. Initial Sequence Number

Initial Sequence Number is a unique 32-bit embedded to any new connection on TCP-based connection. ISN value expected to be random. Sequence number is the 4th octet on TCP header.

On packet 1566, ISN is 26. Here is the table of first 5 ISN number:

Initial Sequence Number # Packet Entry
26 1557 (6 entries)
27 1568 (6 entries)
28 1574 (6 entries)
29 1580 (6 entries)
30 1586 (6 entries)

 

In this pattern we get conclusion that ISN changing is done for every three packets. This is based on knowledge that the entries are actually pair of request-response.

2. IP ID

IP ID or Internet Protocol Identification is 16-bit number used to identify fragment groups from IP datagram. IP ID is the 4th octet of IP header.

On packet 1566, IP ID is 553. Here is table of first 10 IP ID seen:

IP Identification # Packet Entry
553 1566 ( 2 entries)
554 1568 ( 2 entries)
555 1570 ( 2 entries)
556 1572 ( 2 entries)
557 1574 ( 2 entries)
558 1576 ( 2 entries)
559 1578 ( 2 entries)
560 1580 ( 2 entries)
561 1582 ( 2 entries)
562 1584 ( 2 entries)

 

By this pattern, we can conclude that IP ID is changing for every packet sent. This is based on knowledge that the entries are actually pair of request-response.

Note: IP header in this file is referred to IPv4 header.

3. Source Port

Source Port is 16-bit number used identify port for sending packet. This number is the 0-th octet on TCP header.

Packet 1566 has Source Port 1041. Here we present table of 4 first Source Port seen:

Source Port # Packet Entry
1041 1533 (35 entries, 12 seconds)
1042 1568 (30 entries, 12 seconds)
1043 1598 (30 entries, 11 seconds)
1044 1628 (30 entries, ~ seconds)

 

In this pattern, we can conclude that Source Port is changing in interval between 10 and 15 seconds from previous port usage.

Goal VIII Solution ( Opening TCP Session Port 4445)

For this goal, we need to use following understanding

  • Destination IP address is 10.10.10.10
  • Destination port is 4445

Thus, we can set rule on Wireshark as following:

(ip.dst==10.10.10.10 && tcp.dstport==4445) || (ip.dst==10.10.10.70 && tcp.srcport==4445)

From goal VII we get that connection establishment are tried until packet 1656 [SYN]. In packet 1657 we see that 10.10.10.10:445 gives response [SYN,ACK] signaling that TCP three-way handshake is on the way.

TCP three-way handshake for port 4445 is finished on packet 1657 when 10.10.10.70 send packet ACK so connection is established on packet 1657.

Packet 1567 happen on 123.7 which means the connection is open on 123.7.

Goal IX Solution ( MD5 Hash of Executable File )

Ann (10.10.10.10) has initiative to send executable file to Vick (10.10.10.70), seen from packet 1659 which is [PSH,ACK] message. The message itself is sent from packet 1660. Using “Follow TCP Stream” on packet 1660, we can see whole data exchange. However the data itself is defected with following message: “[1436350345 bytes missing in capture file]”

Save the PE32 data as suspect2.exe and click “Save As”. Open up suspect2.exe using editor capable of viewing hex number (however hexeditor is recommended). Delete the first 42 bytes so we have MZ signature.

MD5 calculation gives us efbf686f09de864bd0058dab650ac34a as result of checksum.

uas_11

Goal X Solution (Closing TCP Session Port 4445)

For this goal, we need to use following understanding

  • Destination IP address is 10.10.10.10
  • Destination port is 4445

Thus, we can set rule on Wireshark as following:

(ip.dst==10.10.10.10 && tcp.dstport==4445) || (ip.dst==10.10.10.70 && tcp.srcport==4445)

Knowing TCP four-way handshake, we know that connection closed when TCP handshake is over. It is marked by ACK from initiator. However, we don’t know for sure yet who the initiator is.

Inspection lead us to pair packet 2552, 2554 and 2551,2553. Packet 2552 and packet 2553 are packet [FIN,ACK] where packet 2552 is sent first from 10.10.10.70 to 10.10.10.10. Therefore we can get conclusion that client has initiative to end the connection after server finish sending the data. Packet ACK is sent by 10.10.10.70 on entry 2554, present us to fact that connection is ended.

Packet 2554 happen on 198.4 which means the connection is closed roughly at 198.4 seconds relative to first of packet.

Conclusion

Ann Dercover has done break-in activity and has been proved planting malware to Vick Timmes.

To know what data stolen are, further investigation is needed.


Satria Ady Pradana
I3510030
School of Electrical Engineering & Informatics
Institut Teknologi Bandung

Creating Disk Image

December 11, 2015 | Article | No Comments

I remember creating one or two challenges for local forensic competition in my community. Ideally the image should be created from live hard drive or SD card. However, I’m not in condition to do that. The constraint I have is to create image as small as possible so we can distribute it across any media. Therefore I create a “disk image” by myself.

In this article we will use:

  1. Slackware64 14.1
  2. dd
  3. fdisk

We will create a small disk image, 50MB in size. It can be an image of a single partition, or even we can make it as if it was an image of a disk. Let’s say we will create “partition.img” and “disk.img”

Creating a Blank Image

The disk image is exactly a single file. It is a storage containing the complete contents and structure representing a data storage or device, such as hard drive, tape drive, optical disc, or USB flash drive. Creating a disk image is usually done by creating complete sector-by-sector copy of the source medium. Thereby perfect replicating the structure and contents of a storage device.

In our case, however, we are not copying real disk. We create it, literally. What we will do is creating an empty file with sufficient size before we do something to it.

If you have experience with Virtual Machine and ever creating disk image for particular VM (for example, VirtualBox VDI), you should know that it is slightly different thing. Yes, it is still a disk image, but we have extra metadata and various thing over it.

Now, to create our blank disk image of size 50MB, we invoke following command:

dd if=/dev/zero of=disk.img bs=512 count=97656

The dd utility is used with following argument:

  • if=/dev/zero, we specify the input is /dev/zero. This is a special node in Linux which generate a zero every time it is read.
  • of=disk.img, we specify the output will be a file named disk.img.
  • bs=512, we set the block size to 512 byte. Actually you can set the zie to any convenient number. Anything will do but I choose this number.
  • count=97656, we specify how many block we will write. So, in our case, we will have 97656 blocks or 97656 x512 byte = 49999872 bytes or around 50MB. I got the number by calculating 50*1000*1000/512.

Creating the partition.img is in similar manner.

Single Partitioned Disk Image

Having partition.img, we are ready to format the image into certain partition. I want an EXT4 format, so i use following command:

mkfs.ext4 partition.img

The command will take partition.img and format the partition with to EXT4 file system.

In general, we are attempting to imitate a partition. Later we can mount the partition by:

mount -o loop partition.img /mnt/partition

Now you can mount the partition and copy files tot he /mnt/partition and they will be written to our image file.

Multiple Partitioned Disk Image

In this section we will create a disk image with multiple partitions. In other words, we are trying to imitate the real disk.

The procedure is basically similar, but the image file must first be partitioned. So, more work involved here.

As in our case, we will create two partitions. First partition will occupy 10MB. The rest will be allocated to second partition.

fdisk disk.img

The fdisk utility is interactive program and quite clear. You just need to choose right option and enter right number for start and end of partition. Before you proceed, make sure you print current condition (using option p). Fdisk will display how many heads, sectors, and cylinders it recognized. It also print out the size of sector.

Here is what specification we need:

Partition 1:
primary partition
First sector = 2048
Last sector = 22527

Partition 2:
primary partition
First sector = 22528
Last sector = 97655

If you see the number 97655 and wonder it might have something to do with the count=97656 argument to dd, you are sharp! It is truly last sector of our disk image.

Now the formatting would be bit complicated. In short, we have to make a loop back device to point a partition inside our disk image and then do formatting.

losetup /dev/loop0 disk.img -o 2048
losetup /dev/loop1 disk.img -o 22528

mkfs.ext4 /dev/loop0
mkfs.ext4 /dev/loop1

To mount our disk image, you can follow this article: Mounting Partition from Raw Disk Image on Linux

For you who are not patient enough, here’s how we mont both partitions:

mount -o loop,offset=1048576 disk.img /mnt/disk1

mount -o loop,offset=11534336 disk.img /mnt/disk2

Mounting Partition from Raw Disk Image on Linux

December 11, 2015 | Article | No Comments

In Linux/Unix or perhaps in every computer system, a term mounting is defined as attaching additional filesystem to the currently accessible filesystem of a computer. As we know, a filesystem is hierarchy of directories (also referred to as a directory tree) that is used to organize files on a computer or storage media.

We might familiar or maybe remember how to mount a partition well. But that’s when the partition is inside a storage media or physical medium. What if the partition we want to access is in form of disk image? Here, we will discuss it.

In this article I use:

  1. Slackware64 14.0
  2. dumped image from 4GB SD-card, using dd

The Theory

Disk Image

A disk image is a single file or storage device containing the complete contents and structure representing a data storage medium or device, such as hard drive, tape drive, floppy disk, optical disc, or USB flash drive. A disk image is usually created by creating a complete sector-by-sector copy of the source medium and thereby perfect replicating the structure and contents of a storage device.

In Linux, we can create disk image using dd utility. Assuming we want to create disk image of a SD-card which is recognized as /dev/sdb as MyDiskImage.img:

dd if=/dev/sdb of=MyDiskImage.img

Partition and Partition Table

As said, disk image is perfect copy of a storage media. Therefore we got very same bit of partition and partition table. Nothing is modified, unless you alter it. Therefore, we can still read the partition table like what we do on physical storage medium.

We can use fdisk to see the partition table of a disk image:

fdisk MyDiskImage.img

Loopback Device

We know that Linux and Unix list all recognized device as device nodes. They are treated like ordinary file and stored on /dev, like /dev/sda for first SCSI storage device we have. However, not many of us know some pseudo-devices on this directory. One of them is loop device /dev/loop*.

This is special node that we will use for mounting an image.

How to Mount

There are some steps we have to do so we can mount a partition inside of disk image.

Know the Offset

We have to know where is the offset of partition. Clearly we need to know where the partition start and where the partition end. Although, we only need the offset of beginning of the partition. To do that, we can use fdisk to peek on partition table. For example:

fdisk MyDiskImage.img

Here’s how my partition looks like.

Disk MyDiskImage.img: 691 MB, 691798016 bytes
255 heads, 63 sectors/track, 84 cylinders, total 1351168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0002c262

                         Device Boot      Start         End      Blocks   Id  System
2013-09-25-wheezy-raspbian.img1            8192      122879       57344    c  W95 FAT32 (LBA)
2013-09-25-wheezy-raspbian.img2          122880     5785599     2831360   83  Linux

What we want to know is the offset, which is in byte-level. However fdisk tell us about sectors. Fortunately we can convert the offset in sector to bytes by multiplying it with the size of sector. In our case, one sector is 512 bytes.

Let say we want to mount partition 2, which is ext4. We calculate the offset for this partition.

122880 * 512 = 62914560

Save this value.

Mount It!

The actual mounting. Mounting process is similar when we mount normal partition. However, this time we use loopback device and use one argument we never use before, “offset”. Basically, offset tell mount utility to skip the data on particular to offset.

Here how we do:

mount -o loop,offset=62914560 MyDiskImage.img /mnt/mount_point

Here we mount partition 2, which is located on 62914560 bytes after the beginning of the file. The partition should be mounted to our mount point (/mnt/mount_point). Unless you have an unknown filesystem, this command shouldn’t be fail.

Social media & sharing icons powered by UltimatelySocial