Didier Stevens

Thursday 22 January 2015

Converting PEiD Signatures To YARA Rules

Filed under: Forensics,Malware,My Software — Didier Stevens @ 0:56

I converted Jim Clausing’s PEiD rules to YARA rules so that I can use them to detect executable code in suspect Microsoft Office Documents with my oledump tool.

Of course, I wrote a program to do this automatically: peid-userdb-to-yara-rules.py

This program converts PEiD signatures to YARA rules. These signatures are typically found in file userdb.txt. Since PEiD signature names don’t need to be unique, and can contain characters that are not allowed in YARA rules, the name of the YARA rule is prefixed with PEiD_ and a running counter, and non-alphanumeric characters are converted to underscores (_).
Signatures that can not be parsed are ignored.

Here is an example:
PEiD signature:

 [!EP (ExE Pack) V1.0 -> Elite Coding Group]
 signature = 60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10
 ep_only = true

Generated YARA rule:

 rule PEiD_00001__EP__ExE_Pack__V1_0____Elite_Coding_Group_
 {
     meta:
         description = "[!EP (ExE Pack) V1.0 -> Elite Coding Group]"
         ep_only = "true"
     strings:
         $a = {60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10}
     condition:
         $a
 }

PEiD signatures have an ep_only property that can be true or false. This property specifies if the signature has to be found at the PE file’s entry point (true) or can be found anywhere (false).
This program will convert all signatures, regardless of the value of the ep_only property. Use option -e to convert only rules with ep_only property equal to true or false.

Option -p generates rules that use YARA’s pe module. If a signature has ep_only property equal to true, then the YARA rule’s condition becomes $a at pe.entry_point instead of just $a.

Example:

 import "pe"

 rule PEiD_00001__EP__ExE_Pack__V1_0____Elite_Coding_Group_
 {
     meta:
         description = "[!EP (ExE Pack) V1.0 -> Elite Coding Group]"
         ep_only = "true"
     strings:
         $a = {60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10}
     condition:
         $a at pe.entry_point
 }

Specific signatures can be excluded with option -x. This option takes a file that contains signatures to ignore (signatures like 60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10, not names like [!EP (ExE Pack) V1.0 -> Elite Coding Group]).

Download my YARA Rules.

peid-userdb-to-yara-rules_V0_0_1.zip (https)
MD5: D5B9B6FA7EC50A107A70419D30FEC9ED
SHA256: F8A12B5522B92AE7E3EDF11ACFAEEA7FDCC7FBDA8DC827D288A2D92B2B2CA5E2

Tuesday 20 January 2015

YARA Rule: Detecting JPEG Exif With eval()

Filed under: Forensics,Malware — Didier Stevens @ 20:39

My first release of 2015 was a new YARA rule to detect JPEG images with an eval() function inside their Exif data.

Such images are not new, but I needed an example to develop a complex YARA rule:

rule JPEG_EXIF_Contains_eval
{
    meta:
        author = "Didier Stevens (https://DidierStevens.com)"
        description = "Detect eval function inside JPG EXIF header (http://blog.sucuri.net/2013/07/malware-hidden-inside-jpg-exif-headers.html)"
        method = "Detect JPEG file and EXIF header ($a) and eval function ($b) inside EXIF data"
    strings:
        $a = {FF E1 ?? ?? 45 78 69 66 00}
        $b = /\Weval\s*\(/
    condition:
        uint16be(0x00) == 0xFFD8 and $a and $b in (@a + 0x12 .. @a + 0x02 + uint16be(@a + 0x02) - 0x06)
}

Here is an example of such an image:

20150120-204954

The YARA rule has 3 conditions that must be satisfied:

  1. JPEG magic header FFD8, tested with: uint16be(0x00) == 0xFFD8
  2. Exif structure: FF E1 ?? ?? 45 78 69 66 00
  3. eval function inside Exif data, tested with a regular expression: \Weval\s*\(

Condition 1 is straightforward: the file must start with FFD8. I’m using test uint16be(0x00) == 0xFFD8 instead of searching for {FF D8} at 0x00. FF D8 is a short string, searching for {FF D8} can cause performance problems (you’ll get a warning from YARA when it compiles rules with such short strings).

Condition 2 checks for the presence of the Exif data header. Bytes 3 and 4 (?? ??) encode the length of the Exif Data.

Condition 3 checks for the presence of the eval function. To reduce the number of false positives that would occur when searching for string eval, we use a regular expression that matches string eval, possibly followed by whitespace characters (\s*), and an opening parenthesis: \(. And we don’t want letters or numbers before the string eval (we don’t want to match a string like deval), eval must be the start of a word. To achieve this with regular expressions, you use a word boundary: \b. So our regular expression would be \beval\s*\(. Unfortunately, YARA’s regular expression engine does not support word boundaries, so I had to come up with something else. I match any character that is not alphanumeric: \W. Be warned that there is a small difference between \W and \b. \b also matches the beginning of a string (like $), while \W has to match a character. So the regular expression I use is \Weval\s*\(.

The eval function must also be found inside the Exif data. We don’t want to trigger on the eval function if it is found somewhere else in the image. That’s where YARA’s in ( .. ) syntax comes in.

The first 18 bytes of the Exif structure are various headers which we ignore, so our eval function $b must start at @a + 0x12 or further.

The total size of the Exif structure is given by expression 0x02 + uint16be(@a + 0x02). We add this to the start of the Exif header (@a): @a + 0x02 + uint16be(@a + 0x02). And finally, we have to subtract the size of the string matched by the regular expression. Unfortunately, YARA has no function to calculate this length. So we will use the minimum length our regular expression can match: 6 characters. So our eval function $b must start no further than @a + 0x02 + uint16be(@a + 0x02) – 0x06. Putting all this together gives: $b in (@a + 0x12 .. @a + 0x02 + uint16be(@a + 0x02) – 0x06)

FYI: Victor told me that he plans to add a string length function to YARA, so our condition will then become: $b in (@a + 0x12 .. @a + 0x02 + uint16be(@a + 0x02) – &b)

You can find all my YARA rules here: YARA Rules.

Wednesday 17 December 2014

Introducing oledump.py

Filed under: Forensics,Malware,My Software — Didier Stevens @ 0:07

If you follow my video blog, you’ve seen my oledump videos and downloaded the preview version. Here is the “official” release.

oledump.py is a program to analyze OLE files (Compound File Binary Format). These files contain streams of data. oledump allows you to analyze these streams.

Many applications use this file format, the best known is MS Office. .doc, .xls, .ppt, … are OLE files (docx, xlsx, … is the new file format: XML insize ZIP).

Run oledump on an .xls file and it will show you the streams:

20141216-223150

The letter M next to stream 7, 8, 9 and 10 indicate that the stream contains VBA macros.

You can select a stream to dump its content:

20141216-223233

The source code of VBA macros is compressed when stored inside a stream. Use option -v to decompress the VBA macros:

20141216-223705

You can write plugins (in Python) to analyze streams. I developed 3 plugins. Plugin plugin_http_heuristics.py uses a couple of tricks to extract URLs from malicious, obfuscated VBA macros, like this:

20141216-224228

You might have noticed that the file analyzed in the above screenshot is a zip file. Like many of my analysis programs, oledump.py can analyze a file inside a (password protected) zip file. This allows you to store your malware samples in password protected zip files (password infected), and then analyze them without having to extract them.

If you install the YARA Python module, you can scan the streams with YARA rules:

20141216-224952

And if you suspect that the content of a stream is encoded, for example with XOR, you can try to brute-force the XOR key with a simple decoder I provide (or you can develop your own decoder in Python):

20141216-225911

This program requires Python module OleFileIO_PL: http://www.decalage.info/python/olefileio

oledump_V0_0_3.zip (https)
MD5: 9D5AA950C9BFDB16D63D394D622C6767
SHA256: 44D8C675881245D3336D6AB6F9D7DAF152B14D7313A77CB8F84A71B62E619A70

Tuesday 16 December 2014

YARA Rules

Filed under: Forensics,Malware — Didier Stevens @ 0:00

Here are some YARA rules I developed.

contains_pe_file will find embedded PE files.

maldoc is a set of rules derived from Frank Boldewin’s OfficeMalScanner signatures, that I also use in my XORSearch program. Their goal is to find shellcode embedded in documents.

20141215-160602

yara-rules-V0.0.1.zip (https)
MD5: 4D869BD838E662E050BBFCB0B89732E4
SHA256: 0CA778EAD97FF43CF7961E3C17A88B77E8782D082CE170FC779543D67B58FC72

Monday 15 December 2014

router-forensics.net

Filed under: Forensics,Networking — Didier Stevens @ 10:20

Together with Xavier Mertens I proposed a Brucon 5×5 project. Our project was accepted, and we bought 23 Cisco routers to teach memory forensics on network devices.

21 routers are used for workshops, and 2 routers are online.

If you want to practice memory forensics with real Cisco IOS devices, go to http://router-forensics.net.

Tuesday 25 November 2014

Update: find-file-in-file.py Version 0.0.4

Filed under: Forensics,My Software,Update — Didier Stevens @ 22:05

Here is the version I talked about in my Bitcoin virus posts.

It also has an embedded man page (use option –man).

find-file-in-file_v0_0_4.zip (https)
MD5: CD381616158BD233D94B368554B824C6
SHA256: FD5C4E3EC99371754E58B93D3D96CBA7A86C230C47FC9C27C9B871ED8BFB9149

Man page:

Usage: find-file-in-file.py [options] file-contained file-containing […]
Find if a file is present in another file

Arguments:
file-containing can be a single file, several files, and/or @file
@file: run the command on each file listed in the text file specified
wildcards are supported
batch mode is enabled when more than one file is specified

Source code put in the public domain by Didier Stevens, no Copyright
Use at your own risk

https://DidierStevens.com

Options:
–version             show program’s version number and exit
-h, –help            show this help message and exit
-m MINIMUM, –minimum=MINIMUM
Minimum length of byte-sequence to find (default 10)
-o, –overlap         Found sequences may overlap
-v, –verbose         Be verbose in batch mode
-p, –partial         Perform partial search of contained file
-O OUTPUT, –output=OUTPUT
Output to file
-b RANGEBEGIN, –rangebegin=RANGEBEGIN
Select the beginning of the contained file (by default
byte 0)
-e RANGEEND, –rangeend=RANGEEND
Select the end of the contained file (by default last
byte)
-x, –hexdump         Hexdump of found bytes
-q, –quiet           Do not output to standard output
–man                 Print manual

Manual:

find-file-in-file is a program to test if one file (the contained
file) can be found inside another file (the containing file).

Here is an example.
We have a file called contained-1.txt with the following content:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
and have a file called containing-1.txt with the following content:
0000ABCDEFGHIJKLM1111NOPQRSTUVWXYZ2222

When we execute the following command:
find-file-in-file.py contained-1.txt containing-1.txt

We get this output:
0x00000004 0x0000000d (50%)
0x00000015 0x0000000d (50%)
Finished

This means that the file contained-1.txt was completely found inside
file containing-1.txt At position 0x00000004 we found a first part
(0x0000000d bytes) and at position 0x00000015 we found a second part
(0x0000000d bytes).

We can use option hexdump (-x) to see which bytes were found:
find-file-in-file.py -x contained-1.txt containing-1.txt
0x00000004 0x0000000d (50%)
41 42 43 44 45 46 47 48 49 4a 4b 4c 4d
0x00000015 0x0000000d (50%)
4e 4f 50 51 52 53 54 55 56 57 58 59 5a
Finished

The containing file may contain the contained file in an arbitrary
order, like file containing-2.txt:
0000NOPQRSTUVWXYZ1111ABCDEFGHIJKLM2222

Example:
find-file-in-file.py -x contained-1.txt containing-2.txt
0x00000015 0x0000000d (50%)
41 42 43 44 45 46 47 48 49 4a 4b 4c 4d
0x00000004 0x0000000d (50%)
4e 4f 50 51 52 53 54 55 56 57 58 59 5a
Finished

The containing file does not need to contain the complete contained
file, like file containing-3.txt:
0000ABCDEFGHIJKLM1111

Example:
find-file-in-file.py -x contained-1.txt containing-3.txt
0x00000004 0x0000000d (50%)
41 42 43 44 45 46 47 48 49 4a 4b 4c 4d
Remaining 13 (50%)

The message “Remaining 13 (50%)” means that the last 13 bytes of the
contained file were not found in the containing file (that’s 50% of
the contained file).

If the contained file starts with a byte sequence not present in the
containing file, nothing will be found. Example with file
contained-2.txt:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

Nothing is found:
find-file-in-file.py -x contained-2.txt containing-1.txt
Remaining 36 (100%)

If you know how long that initial byte sequence is, you can skip it.
Use option rangebegin (-b) to specify the position in the contained
file from where you want to start searching.
Example:

find-file-in-file.py -x -b 10 contained-2.txt containing-1.txt
0x00000004 0x0000000d (50%)
41 42 43 44 45 46 47 48 49 4a 4b 4c 4d
0x00000015 0x0000000d (50%)
4e 4f 50 51 52 53 54 55 56 57 58 59 5a
Finished

If you want to skip bytes at the end of the contained file, use option
rangeend (-e).

If you don’t know how long that initial byte sequence is, you can
instruct find-file-in-file to “brute-force” it. With option partial
(-p), one byte at a time will be removed from the beginning of the
contained file until a match is found.
Example:

find-file-in-file.py -x -p contained-2.txt containing-1.txt
File: containing-1.txt (partial 0x0a)
0x00000004 0x0000000d (50%)
41 42 43 44 45 46 47 48 49 4a 4b 4c 4d
0x00000015 0x0000000d (50%)
4e 4f 50 51 52 53 54 55 56 57 58 59 5a
Finished

“(partial 0x0a)” tells you that the first 10 bytes of the contained
file were skipped before a match was found.

There are some other options:
-m minimum: find-file-in-file will search for byte sequences of 10
bytes long minimum. If you want to change this minimum, use option -m
minimum.
-o overlap: find-file-in-file will not let byte sequences overlap. Use
option -o overlap to remove this restriction.
-v verbose: be verbose in batch mode (more than one containing file).
-O output: besides writing output to stdout, write the output also to
the given file.
-q quiet: do not output to stdout.

Thursday 24 July 2014

Stoned Bitcoin: My Analysis Tools

Filed under: Encryption,Forensics,Malware,My Software — Didier Stevens @ 0:00

The most interesting thing about Stoned Bitcoin for me, was to work out a method to find these Bitcoin transactions.

When this was mentioned on Twitter, I did a string search through the Bitcoin blockchain for string STONED: no hits.

Some time later I used my find-file-in-file tool. I got a copy of the Stoned Virus (md5 74A6DBB7A60915FE2111E580ACDEEAB7) and searched through the blockchain: again, no hits.

Although this means the blockchain doesn’t contain the start bytes of the Stoned Virus, it could still contain other parts of the virus. So I randomly selected a sequence of bytes from the virus, and used my tool again: I got a hit!

The command: find-file-in-file.py -s 0xFC 74A6DBB7A60915FE2111E580ACDEEAB7.vir blk00129.dat

The output:

0171c33d 00000010 (6%)
Remaining 244 (93%)

These are the bytes I found: 07 00 BA 80 00 CD 13 EB 49 90 B9 03 00 BA 00 01

How to find the transaction containing this byte sequence? A Bitcoin transaction (binary form) starts with a version number (unsigned 32 bit integer, little-endian), this number is currently 1. The ID of a transaction is the SHA-256 hash of the SHA-256 hash of all the bytes in the transaction, and this reversed and expressed in hexadecimal notation. Armed with this information, I was able to find the transaction: f09904aaa4fa4a8ec7da06f5e3d318a9b6a218e1a215f9307416fbbadf5a1c8e.

Finally, I updated my find-file-in-file tool so that I could do partial searches (and a couple of other features), and I wrote a Python script to parse and search the Bitcoin blockchain.

This is what you can do with the new version of find-file-in-file:

20140723-234257

Option partial allows you to search for parts of the file.

Option hexdump does a hexdump of the found bytes.

And options rangebegin and rangeend allow you to limit what you are searching for by specifying the range to search for. This is necessary for the Stoned Virus, because it ends with a sequence of 0x00 bytes, and such sequences are certainly not specific to the Stoned Virus, but omni-present in the blockchain.

Soon I will release these tools.

Monday 30 June 2014

Update: Stoned Bitcoin

Filed under: Encryption,Forensics,Malware,Update — Didier Stevens @ 0:04

kurt wismer pointed me to this post on pastebin after he read my Stoned Bitcoin blogpost. The author of this pastebin post works out a method to spam the Bitcoin blockchain to cause anti-virus (false) positives.

I scanned through all the Bitcoin transactions (until 24/06/2014) for the addresses listed in this pastebin post (the addresses represent antivirus signatures for 400+ malwares).

All these “malicious” Bitcoin addresses, designed to generate anti-virus false positives,  have been exclusively used in the 8 Bitcoin transactions I mentioned in my previous post.

The pastebin entry was posted on 2014/04/02 19:01:08 UTC.

And here are the 8 transactions with the UTC timestamp of the block in which they appear:

Block: 2014/04/03 23:12:48
Transaction: edb83f04e68bfe78bbfe7ce80d33e85acb9335c96ead5712517b8c70d1f27b38
Block: 2014/04/04 01:10:45
Transaction: 7e49504c7cecea7ea95d78ff14687878ba581a21dc0772805d2925c617514129
Block: 2014/04/04 01:43:25
Transaction: f65895220f04aa0084d9abae938d3f517893e3afbffe25fc9e7073e02331b9ed
Block: 2014/04/04 02:58:13
Transaction: 8a445d12f225a21d36bb78da747efd2e74861fcd033757da572c0434d423acd1
Block: 2014/04/04 04:32:24
Transaction: fcf5cf9893a142897598edfc753bd6162e3638e138fc2feaf4a3477c0cfb65eb
Block: 2014/04/04 04:32:24
Transaction: 2814673f0952b936d578d73197bfd371cefbd73c6294bab16de1575a4c3f6e80
Block: 2014/04/04 09:36:29
Transaction: f09904aaa4fa4a8ec7da06f5e3d318a9b6a218e1a215f9307416fbbadf5a1c8e
Block: 2014/04/04 09:36:29
Transaction: 5dbb9df056c36457228a841d6cc98ac90967bc88411c95372d3c2d92c18060f8

So it took a bit more than 24 hours before someone spammed the Bitcoin blockchain with these transactions designed to trigger false positives.

Monday 23 June 2014

Stoned Bitcoin

Filed under: Encryption,Forensics,Malware — Didier Stevens @ 20:29

There are reports of anti-virus false positive detections of Bitcoin files. More precisely for the old Stoned computer virus.

I found the smoking gun! These reports should not be dismissed as hoaxes.

I’ve identified 2 Bitcoin transactions that contain byte sequences found in the Stoned computer virus. Here they are:

Both transactions appear in blocks dated 2014-04-04.

The first transaction has byte sequences of the Stoned computer virus in the address of transaction outputs 1, 2, 3 and 4:

Txout 1:
 value: 1
 txOutScriptLength: 25
 txOutScript: 'OP_DUP OP_HASH160 0700ba8000cd13eb4990b90300ba000100000000 OP_EQUALVERIFY OP_CHECKSIG'
 Stoned virus byte sequence:     0700ba8000cd13eb4990b90300ba0001
Txout 2:
 value: 1
 txOutScriptLength: 25
 txOutScript: 'OP_DUP OP_HASH160 b8010333dbb10133d29c00000000000000000000 OP_EQUALVERIFY OP_CHECKSIG'
 Stoned virus byte sequence:     b8010333dbb10133d29c
Txout 3:
 value: 1
 txOutScriptLength: 25
 txOutScript: 'OP_DUP OP_HASH160 750e33c08ed8a03f04a8017503e8070000000000 OP_EQUALVERIFY OP_CHECKSIG'
 Stoned virus byte sequence:     750e33c08ed8a03f04a8017503e80700
Txout 4:
 value: 1
 txOutScriptLength: 25
 txOutScript: 'OP_DUP OP_HASH160 b8010333dbb10133d29c00000000000000000000 OP_EQUALVERIFY OP_CHECKSIG'
 Stoned virus byte sequence:     b8010333dbb10133d29c

I’ve submitted this transaction to VirusTotal: 16 detections. I also submitted the block containing this transaction: 5 detections.

The second transaction has a byte sequence of the Stoned computer virus in the address of transaction output 43:

Txout 43:
 value: 10
 txOutScriptLength: 25
 txOutScript: 'OP_DUP OP_HASH160 0400b801020e07bb000233c98bd1419c00000000 OP_EQUALVERIFY OP_CHECKSIG'
 Stoned virus byte sequence:     0400b801020e07bb000233c98bd1419c

I’ve submitted this transaction to VirusTotal: 14 detections. I also submitted the block containing this transaction: 4 detections.

This is a likely explanation why there were “Stoned Virus” anti-virus alerts for Bitcoin blockchain files reported in the news.

Stuffing messages in the address of the output(s) of a transaction is a well known method to insert messages in the Bitcoin blockchain. The drawback is that the Bitcoins send to these addresses are irrevocably lost, because these addresses have no (known) private key. That is why only very small amounts will be transferred (1 and 10 Satoshis in these transactions). The message is limited to 20 bytes (the size of the raw address used in the output).

But I believe that all output addresses in these transactions (except for the last output) are byte sequences found in malware.

When I run ClamAV’s sigtool on these transactions (with a recent database), a lot of signatures are found:

VIRUS NAME: Gen.600;MATCH: ** YES ** (1 match at offset: 1321)
VIRUS NAME: Gen.696;MATCH: ** YES ** (1 match at offset: 1356)
VIRUS NAME: Gen.801;MATCH: ** YES ** (1 match at offset: 1798)
VIRUS NAME: Stoned.1;MATCH: ** YES ** (1 match at offset: 200)
VIRUS NAME: Stoned.2;MATCH: ** YES ** (1 match at offset: 266)
VIRUS NAME: Syslock.1;MATCH: ** YES ** (1 match at offset: 369)
VIRUS NAME: Syslock.2;MATCH: ** YES ** (2 matches at offsets: 404 368)
VIRUS NAME: Ten-Bytes;MATCH: ** YES ** (1 match at offset: 606)
VIRUS NAME: Terminator.1;MATCH: ** YES ** (1 match at offset: 642)
VIRUS NAME: Terror.1;MATCH: ** YES ** (1 match at offset: 675)
VIRUS NAME: Terror.2;MATCH: ** YES ** (1 match at offset: 709)
VIRUS NAME: Terror.4;MATCH: ** YES ** (1 match at offset: 744)
VIRUS NAME: Terror;MATCH: ** YES ** (1 match at offset: 810)
VIRUS NAME: Tiny-163.A;MATCH: ** YES ** (1 match at offset: 845)
VIRUS NAME: Tiny-163.C;MATCH: ** YES ** (1 match at offset: 879)
VIRUS NAME: Tiny-A;MATCH: ** YES ** (1 match at offset: 912)
VIRUS NAME: Tori-1;MATCH: ** YES ** (1 match at offset: 1014)
VIRUS NAME: Tree;MATCH: ** YES ** (1 match at offset: 1050)
VIRUS NAME: TUQ.RPVS;MATCH: ** YES ** (1 match at offset: 538)
VIRUS NAME: USSR-1049.A;MATCH: ** YES ** (1 match at offset: 1083)
VIRUS NAME: USSR-2144.B;MATCH: ** YES ** (1 match at offset: 1117)
VIRUS NAME: USSR-3103;MATCH: ** YES ** (1 match at offset: 1152)
VIRUS NAME: USSR-311.B;MATCH: ** YES ** (1 match at offset: 1184)
VIRUS NAME: USSR-311.D;MATCH: ** YES ** (1 match at offset: 1219)
VIRUS NAME: USSR-311.E;MATCH: ** YES ** (1 match at offset: 1252)
VIRUS NAME: USSR-516.B;MATCH: ** YES ** (1 match at offset: 1287)
VIRUS NAME: USSR-601;MATCH: ** YES ** (1 match at offset: 1320)
VIRUS NAME: USSR-707.B;MATCH: ** YES ** (1 match at offset: 1390)
VIRUS NAME: USSR-707.C;MATCH: ** YES ** (1 match at offset: 1422)
VIRUS NAME: USSR-711.C;MATCH: ** YES ** (1 match at offset: 1458)
VIRUS NAME: USSR-830;MATCH: ** YES ** (1 match at offset: 1490)
VIRUS NAME: USSR-948.B;MATCH: ** YES ** (1 match at offset: 1525)
VIRUS NAME: V1244;MATCH: ** YES ** (1 match at offset: 1661)
VIRUS NAME: V191;MATCH: ** YES ** (1 match at offset: 1697)
VIRUS NAME: V-1L;MATCH: ** YES ** (1 match at offset: 1594)
VIRUS NAME: V200.B;MATCH: ** YES ** (1 match at offset: 1729)
VIRUS NAME: Vacsina.2;MATCH: ** YES ** (1 match at offset: 1900)
VIRUS NAME: Vacsina.3;MATCH: ** YES ** (1 match at offset: 1934)
VIRUS NAME: Vacsina.4;MATCH: ** YES ** (1 match at offset: 1966)
VIRUS NAME: VCS (Clam);MATCH: ** YES ** (1 match at offset: 1830)
VIRUS NAME: VHP-361.A;MATCH: ** YES ** (1 match at offset: 1864)
VIRUS NAME: Vienna-1028;MATCH: ** YES ** (1 match at offset: 2172)
VIRUS NAME: Vienna.1;MATCH: ** YES ** (2 matches at offsets: 2068 2034)
VIRUS NAME: Vienna.1-1;MATCH: ** YES ** (1 match at offset: 2068)
VIRUS NAME: Vienna.2;MATCH: ** YES ** (1 match at offset: 2102)
VIRUS NAME: Vienna-62.B;MATCH: ** YES ** (1 match at offset: 2205)
VIRUS NAME: Vienna.7;MATCH: ** YES ** (1 match at offset: 2137)
VIRUS NAME: TinyFamily2;MATCH: ** YES ** (1 match at offset: 946)
VIRUS NAME: TinyFamily3;MATCH: ** YES ** (1 match at offset: 980)

VIRUS NAME: Italian.1;MATCH: ** YES ** (1 match at offset: 231)
VIRUS NAME: Italian-Generic;MATCH: ** YES ** (1 match at offset: 266)
VIRUS NAME: Jerusalem.1;MATCH: ** YES ** (1 match at offset: 301)
VIRUS NAME: Jerusalem-1361;MATCH: ** YES ** (1 match at offset: 469)
VIRUS NAME: Jerusalem.2.Nemesis;MATCH: ** YES ** (2 matches at offsets: 1592 334)
VIRUS NAME: Jerusalem.5;MATCH: ** YES ** (1 match at offset: 368)
VIRUS NAME: Jerusalem.7;MATCH: ** YES ** (1 match at offset: 403)
VIRUS NAME: Jerusalem.9;MATCH: ** YES ** (1 match at offset: 436)
VIRUS NAME: Jerusalem-Family.1;MATCH: ** YES ** (1 match at offset: 504)
VIRUS NAME: Jerusalem-USA;MATCH: ** YES ** (1 match at offset: 572)
VIRUS NAME: Kharkov-1024;MATCH: ** YES ** (1 match at offset: 605)
VIRUS NAME: Label.1;MATCH: ** YES ** (1 match at offset: 674)
VIRUS NAME: Label.2;MATCH: ** YES ** (1 match at offset: 707)
VIRUS NAME: Leech.1;MATCH: ** YES ** (1 match at offset: 741)
VIRUS NAME: Leprosy.1;MATCH: ** YES ** (1 match at offset: 777)
VIRUS NAME: Leprosy.2;MATCH: ** YES ** (1 match at offset: 809)
VIRUS NAME: Leprosy.4;MATCH: ** YES ** (1 match at offset: 843)
VIRUS NAME: Leprosy-A;MATCH: ** YES ** (1 match at offset: 879)
VIRUS NAME: LOL;MATCH: ** YES ** (1 match at offset: 641)
VIRUS NAME: Lozinsky.2;MATCH: ** YES ** (1 match at offset: 913)
VIRUS NAME: Macho;MATCH: ** YES ** (1 match at offset: 1015)
VIRUS NAME: Minnow;MATCH: ** YES ** (1 match at offset: 1081)
VIRUS NAME: Mirror.1;MATCH: ** YES ** (1 match at offset: 1117)
VIRUS NAME: Mis-Speller;MATCH: ** YES ** (1 match at offset: 1149)
VIRUS NAME: MIX1;MATCH: ** YES ** (1 match at offset: 1217)
VIRUS NAME: MIX1-B;MATCH: ** YES ** (1 match at offset: 1251)
VIRUS NAME: Mixer-1A;MATCH: ** YES ** (1 match at offset: 1319)
VIRUS NAME: Mixer-1B;MATCH: ** YES ** (1 match at offset: 1354)
VIRUS NAME: Mix-I;MATCH: ** YES ** (1 match at offset: 1286)
VIRUS NAME: MLTI.1;MATCH: ** YES ** (1 match at offset: 945)
VIRUS NAME: MLTI.2;MATCH: ** YES ** (1 match at offset: 981)
VIRUS NAME: Mummy;MATCH: ** YES ** (1 match at offset: 1422)
VIRUS NAME: New-COM.1;MATCH: ** YES ** (1 match at offset: 1659)
VIRUS NAME: Nomenclatura.2;MATCH: ** YES ** (1 match at offset: 1693)
VIRUS NAME: Nothing;MATCH: ** YES ** (1 match at offset: 1729)
VIRUS NAME: NPox-1;MATCH: ** YES ** (1 match at offset: 1491)
VIRUS NAME: NV-71;MATCH: ** YES ** (1 match at offset: 1525)
VIRUS NAME: Ontario.3;MATCH: ** YES ** (1 match at offset: 1932)
VIRUS NAME: Orion-263;MATCH: ** YES ** (1 match at offset: 1966)
VIRUS NAME: Oropax.1;MATCH: ** YES ** (1 match at offset: 2001)
VIRUS NAME: Oropax.2;MATCH: ** YES ** (1 match at offset: 2035)
VIRUS NAME: OV;MATCH: ** YES ** (1 match at offset: 1762)
VIRUS NAME: PC-Bandit;MATCH: ** YES ** (1 match at offset: 2067)
VIRUS NAME: PRSC1024;MATCH: ** YES ** (1 match at offset: 2203)
VIRUS NAME: Boot.OneHalf;MATCH: ** YES ** (1 match at offset: 1898)
VIRUS NAME: Jerusalem-PuertoExe;MATCH: ** YES ** (1 match at offset: 537)
VIRUS NAME: Mistake.TypoBoot;MATCH: ** YES ** (1 match at offset: 1183)
VIRUS NAME: MtE.mem.2-staticsig;MATCH: ** YES ** (1 match at offset: 1387)
VIRUS NAME: MutationEng-NE;MATCH: ** YES ** (1 match at offset: 1455)
VIRUS NAME: OldYankee.1;MATCH: ** YES ** (1 match at offset: 1796)
VIRUS NAME: OldYankee.2;MATCH: ** YES ** (1 match at offset: 1829)
VIRUS NAME: OldYankee.3;MATCH: ** YES ** (1 match at offset: 1863)
VIRUS NAME: Stoned-B;MATCH: ** YES ** (1 match at offset: 1625)
VIRUS NAME: Nado.Lover.602-1;MATCH: ** YES ** (1 match at offset: 1557)

My conclusion: these transactions are a deliberate attempt to generate as much false positive anti-virus detections as possible on systems that store Bitcoin transactions on disk. Virus signatures were stuffed in the address of the outputs of these transactions.

And I don’t think the attempt was limited to these 2 transactions. Around the same time, I find other transactions were the output addresses also ends with null bytes:

Hash: edb83f04e68bfe78bbfe7ce80d33e85acb9335c96ead5712517b8c70d1f27b38
Hash: 7e49504c7cecea7ea95d78ff14687878ba581a21dc0772805d2925c617514129
Hash: f65895220f04aa0084d9abae938d3f517893e3afbffe25fc9e7073e02331b9ed
Hash: 8a445d12f225a21d36bb78da747efd2e74861fcd033757da572c0434d423acd1
Hash: 2814673f0952b936d578d73197bfd371cefbd73c6294bab16de1575a4c3f6e80
Hash: 5dbb9df056c36457228a841d6cc98ac90967bc88411c95372d3c2d92c18060f8

You can also look at the input addresses of these transactions to find other, similar transactions:

 

I plan to discuss the methods and tools I used to find and analyze these transactions in an upcoming blog post.

Thursday 27 March 2014

Recorded “Network Device Forensics” Talk

Filed under: Forensics,My Software,Networking — Didier Stevens @ 0:27

I recorded my “Network Device Forensics” talk.

Supporting media:

Next Page »

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 251 other followers