Didier Stevens

Wednesday 22 July 2015

“Analysing Malicious Documents” Training At 44CON London

Filed under: Announcement,Didier Stevens Labs,Forensics,My Software — Didier Stevens @ 0:00

I’m teaching a 2-day class “Analysing Malicious Documents” at 44CON London.

Here is my promo video:

Monday 20 July 2015

If You Have A Problem Running My Tools

Filed under: My Software — Didier Stevens @ 0:00

If you get an error running one of my tools, first make sure you have the latest version. Many tools have a dedicated page, but even more tools have no dedicated page but a few blogposts. Check “My Software” list for the latest versions.

Most of my tools are written in Python or C.

Almost all of my Python tools are written for Python 2 and not Python 3. My PDF tools pdfid and pdf-parser are an exception: they are designed to run with Python 2 and Python 3.

If you get a syntax error running one of my Python tools, then it’s most likely that you are using Python 3 with a tool written for Python 2. Remove Python 3 and install Python 2.

Most of my tools use only build-in Python modules, you don’t need to install extra modules. Some tools that require extra modules will print a warning when you run them without the extra module installed. My tools that support Yara rules require the Yara module, but you will only get a warning for a missing Yara module if you use Yara rules.  You can use the tool without the Yara module as long as you don’t use Yara rules.

I develop my tools on Python 2. My few Python tools written for Python 2 and Python 3 are also developed on Python 2, but only tested on Python 3.

My tools written in C are developed with Borland C++ or Visual Studio 2013.

The tools compiled with Borland C++ don’t require a C runtime to be installed.

The tools compiled with Visual Studio 2013 come in several versions:

  • You have 32-bit and 64-bit versions. If the filename contains x86, then it is a 32-bit tool, if the filename contains x64, then it is a 64-bit tool. 64-bit executables don’t run on 32-bit Windows.
  • You have versions with the C runtime included and versions without. If the filename contains crt, then the C runtime was linked into the executable. If you get an error running executables without crt in the filename, then you are missing the C runtime on your Windows machine. Install the Visual C++ Redistributable Packages for Visual Studio 2013 (remark that there are 32-bit and 64-bit version of the C runtime).
  • Versions with elev in the filename will elevate automatically when you run them.


Monday 13 July 2015

Extracting Dyre Configuration From A Process Dump

Filed under: Forensics,My Software,Reverse Engineering — Didier Stevens @ 0:00

There are a couple of scripts and programs available on the Internet to extract the configuration of the Dyre banking malware from a memory dump. What I’m showing here is a method using a generic regular expression tool I developed (re-search).

Here is the Dyre configuration extracted from the strings found inside the memory dump:


I want to produce a list of the domains found as first item in an <litem> element. re-search is a bit like grep -o, it doesn’t select lines but it selects matches of the provided regular expression. Here I’m looking for tag <litem>:


By default, re-search will process text files line-by-line, like grep. But since the process memory dump is not a text file but a binary file, it’s best not to try to process it line-by-line, but process it in one go. This is done with option -f (fullread).

Next I’m extending my regular expression to include the newline characters following <litem>:


And now I extend it with the domain (remark that the Dyre configuration supports asterisks (*) in the domain names):


If you include a group () in your regular expression, re-search will only output the matched group, and not the complete regex match. So by surrounding the regex for the domain with parentheses, I extract the domains:


This gives me 1632 domains, but many domains appear more than once in the list. I use option -u (unique) to produce a list of unique domain names (683 domains):


Producing a sorted list of domain names is not simple when they have subdomains:


That’s why I have a tool to sort domains by tld first, then domain, then subdomain, …

re-search_V0_0_1.zip (https)
MD5: 5700D814CE5DD5B47F9C09CD819256BD
SHA256: 8CCF0117444A2F28BAEA6281200805A07445E9A061D301CC385965F3D0E8B1AF

Sunday 5 July 2015

base64dump.py Version 0.0.1

Filed under: My Software — Didier Stevens @ 14:54

A new tool, a new video:

base64dump_V0_0_1.zip (https)
MD5: 350C12F677E08030E0DD95339AC3604D
SHA256: 1F8156B43C8B52B7E5620B7A8CD19CFB48F42972E8625994603DDA47E07C9B35

Friday 26 June 2015

Update: oledump.py Version 0.0.17 – ExitCode

Filed under: My Software,Update — Didier Stevens @ 9:44

Here is a new version of oledump with a couple of bugfixes and a new feature: ExitCode.

The ExitCode of the Python program running oledump.py is 0, except if the analyzed file contains macros, then it is 1. You can’t use options if you want the ExitCode.

Thanks Philippe for the idea.

oledump_V0_0_17.zip (https)
MD5: 5AF76C638AA300F6703C6913F80C061F
SHA256: A04DDE83621770BCD96D622C7B57C424E109949FD5EE2523987F30A34FD319E1

Tuesday 16 June 2015

Metasploit Meterpreter Reverse HTTPS Snort Rule

Filed under: Networking — Didier Stevens @ 22:00

Emerging Threats and Snort released my Snort rule to detect Metasploit Meterpreter Reverse HTTPS traffic.

More details about the rule in an upcoming blogpost.

Tuesday 9 June 2015


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

pcap-rename.py is a program to rename pcap files with a timestamp of the first packet in the pcap file.

The first argument is a template of the new filename. Use %% as a placeholder for the timestamp. Don’t forget the .pcap extension.

The next arguments are the pcap files to be renamed.
You can provide one or more pcap files, use wildcards (*.pcap) and use @file.
@file: file is a text file containing filenames. Each file listed in the text file is processed.

Example to rename pcap files:
pcap-rename.py server-%%.pcap *.pcap

Renamed: capture1.pcap -> server-20140416-184037-926493.pcap
Renamed: capture2.pcap -> server-20140417-114252-700036.pcap
Renamed: capture3.pcap -> server-20140419-052202-911011.pcap
Renamed: capture4.pcap -> server-20140424-065625-868672.pcap

Use option -n to view the result without actually renaming the pcap files.

This program does not support .pcapng files (yet).

pcap-rename_V0_0_1.zip (https)
MD5: 5F844411E178909970BC21349A629438
SHA256: AB706DB3470A915A3031EC248B8DAF83C08F42DBF6AC2EACB1A2DB2493B0AEEE

Thursday 4 June 2015

Regular Expressions With Comments

Filed under: My Software — Didier Stevens @ 20:01

Many flavors of regular expressions support comments now. You can make your regular expression a bit more readable by adding comments. Like in programming languages, where a comment does not change the behavior of the program, a regular expression comment does not change the behavior of the regular expression.

A regular expression comment is written like this: (?#comment) where comment can be any text, as long it is not ).

Here is an example of a regular expression for a simple email address: [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}

And here is the same regular expression with a comment (bold): [A-Z0-9._%+-]+@(?#domain)[A-Z0-9.-]+\.[A-Z]{2,6}

Why am I posting this? Because I’m using this in my new Snort rules I’m blogging about soon.

Monday 18 May 2015

Howto: Install Wireshark Dissectors

Filed under: My Software,Wireshark — Didier Stevens @ 0:00

I teach a Wireshark class at Brucon 2015.

If you want to use my Wireshark dissectors like TCP Flag dissector, but don’t know how to install a Wireshark dissector, then watch this video howto:

Monday 11 May 2015

Detecting Network Traffic from Metasploit’s Meterpreter Reverse HTTP Module

Filed under: Networking — Didier Stevens @ 5:52

I teach a Wireshark class at Brucon 2015.

I took a closer look at Metasploit’s Meterpreter network traffic when reverse http mode is used.

The Meterpreter client will make regular HTTP requests to the Metasploit server to check if it has commands ready to be executed. This is how a request looks like:



The client sends an HTTP POST request with a 4-byte payload: RECV. The URI has the following pattern: 4 or 5 alphanumeric characters, an underscore and 16 alphanumeric characters. The 16 alphanumeric characters are chosen at random, and the 4 or 5 alphanumeric characters are some kind of checksum.

I checked Meteasploit’s source code: these characteristics of Meterpreter’s Reverse HTTP protocol are hardcoded.

What is not hardcoded, but parametrized with a variable, is the User Agent String. By default, it is “Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)”, but it is an option that can be changed.

I’ve tested the detection of Metasploit Meterpreter traffic with this User Agent String in several environments, and never encountered a false positive. You might think that “Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)” is quite common as a User Agent String, but it is not. “MSIE 6.1″ is pretty rare (according to Wikipedia, there is no Internet Explorer version 6.1), and “Windows NT” without version number is also rare. Combined, I’ve never seen this User Agent String except for Metasploit Meterpreter traffic. The only User Agent String seen in-the-wild that comes close to this one is “Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)”. But I suggest that you check your environment for this Metasploit User Agent String if you want to be sure no false positives will be generated in your environment.

But like I said, the User Agent String is an option, and can be easily changed by the Metasploit operator. That’s why I also developed a method to detect Metasploit Meterpreter Reverse HTTP traffic looking for its hardcoded characteristics: a POST request with RECV payload to a recognizable URI.

Here is the Snort rule:

# Snort rules by Didier Stevens (http://DidierStevens.com)
# 2015/05/01 - 2015/05/10
# Thanks to Nathan Fowler for helping out with performance optimization
# I start numbering my rules at SID 1618000
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit Meterpreter"; flow:to_server,established; content:"RECV"; http_client_body; depth:4; fast_pattern; isdataat:!0,relative; urilen:23<>24,norm; content:"POST"; pcre:"/^\/[a-z0-9]{4,5}_[a-z0-9]{16}\/$/Ui"; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/05/11/detecting-network-traffic-from-metasploits-meterpreter-reverse-http-module/; sid:1618008; rev:1;)

This Snort rule looks for traffic from your internal network to the outside. You need to change the rule if you want to detect internal-only traffic.

Here is an example of an alert:

[**] [1:1618008:1] Metasploit Meterpreter [**]
[Classification: A Network Trojan was detected] [Priority: 1] 
05/11-22:26:31.236007 ->
TCP TTL:64 TOS:0x0 ID:21177 IpLen:20 DgmLen:212 DF
***A**** Seq: 0x1B677291  Ack: 0x861008DD  Win: 0x7680  TcpLen: 20
[Xref => http://blog.didierstevens.com/2015/05/11/detecting-network-traffic-from-metasploits-meterpreter-reverse-http-module/]

Based on the Metasploit User Agent Strings I published a couple of months ago, I made these Snort rules:

# Snort rules by Didier Stevens (http://DidierStevens.com)
# 2015/04/30
# I start numbering my rules at SID 1618000
#alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/4.0 (compatible\; MSIE 6.0\; Windows NT 5.1)|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618000; rev:1;)
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/4.0 (compatible\; MSIE 6.1\; Windows NT)|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618001; rev:1;)
#alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/4.0 (compatible\; MSIE 7.0\; Windows NT 6.0)|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618002; rev:1;)
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/4.0 (compatible\; MSIE 7.0\; Windows NT 6.0\; Trident/4.0\; SIMBAR={7DB0F6DE-8DE7-4841-9084-28FA914B0F2E}\; SLCC1\; .N|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618003; rev:1;)
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/4.0 (compatible\; Metasploit RSPEC)|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618004; rev:1;)
#alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/5.0 (Windows\; U\; Windows NT 5.1\; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/ Safari/525.13|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618005; rev:1;)
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/5.0 (compatible\; Googlebot/2.1\; +http://www.google.com/bot.html)|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618006; rev:1;)
#alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"Metasploit User Agent String"; flow:to_server,established; content:"User-Agent|3a| Mozilla/5.0 (compatible\; MSIE 10.0\; Windows NT 6.1\; Trident/6.0)|0d 0a|"; http_header; classtype:trojan-activity; reference:url,blog.didierstevens.com/2015/03/16/quickpost-metasploit-user-agent-strings/; sid:1618007; rev:1;)

Remark that I commented-out the Snort rules that I expect to generate too many false positives. But it’s best that you check what User Agent Strings are common in your environment, before you deploy and uncomment these rules.

Update: these rules are designed for an environment where egress traffic has to go to an HTTP port. If your environment allows all destination ports (like Metasploit’s default 4444 port), then replace $HTTP_PORTS by any in the rules you deploy. Thanks @securitygen for the remark.

snort-rules-V0_0_1.zip (https)
MD5: 526AAC1CE1E8576633498223DFA07E3D
SHA256: 7694E4E884E12068BC2A32714D3B0C48060B12C80E4093AFB6B1563E2EDA5E8D

Next Page »

The Rubric Theme. Blog at WordPress.com.


Get every new post delivered to your Inbox.

Join 312 other followers