Didier Stevens

Wednesday 23 August 2017

Wireshark: Follow Streams

Filed under: Networking,Wireshark — Didier Stevens @ 0:00

Following streams (like TCP connections) in Wireshark provides a different view on network traffic: in stead of individual packets, one can see data flowing between client & server.

There is a difference between following a TCP stream and an HTTP stream. For example, if the data downloaded from the webserver is gzip compressed, following the TCP stream will display the compressed data, while following the HTTP stream will display the decompressed data.

I illustrate this in the following video:

Sunday 30 July 2017

Quickpost: Trying Out JA3

Filed under: Networking,Quickpost — Didier Stevens @ 21:19

I tried out JA3 (a Python program to fingerprint TLS clients) with a 1GB pcap file from my server. It was fast (less than 1 minute), but I had to add some error handling to skip packets it would crash on.

I did not identify a lot of client HELLO packets with the JSON fingerprint database: around 5%.


Quickpost info

Monday 7 September 2015

Wireshark Wifi and Lua Training – Brucon 2015

Filed under: Didier Stevens Labs,Networking,WiFi — Didier Stevens @ 0:00

I teach a 2 day training “Wireshark Wifi and Lua Training” at Brucon. More details here.

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

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 => https://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

Wednesday 6 May 2015

Update: NAFT Version 0.0.9

Filed under: Forensics,My Software,Networking,Update — Didier Stevens @ 13:55

This update to NAFT adds support for YARA. YARA rules can be used to search through the heap, like this:

naft-icd.py -y IOS_canary.yara –decoders decoder_xor1 heap r870-core

Address      Bytes     Prev     Next Ref     PrevF    NextF Alloc PC  what
83AB9498 0000004100 83AB9444 83ABA4CC 001  -------- -------- 80B5CC7C  8253709C
 YARA rule: IOS_canary

Rule IOS_canary.yara searches for a canary value inside the blocks.

rule IOS_canary
        $canary = {FD 01 10 DF}

NAFT_V0_0_9.zip (https)
MD5: FEBBDB892D631275A95A0FEA59F8519F
SHA256: 95F42F109623F2BA6D8A9FFB013CBB0B5E995F02E5EB35F8E83A62B8CA8B86D0

Friday 17 April 2015

MS15-034 Detection: Some Observations

Filed under: Networking,Vulnerabilities — Didier Stevens @ 9:15

Several detection rules (SNORT, F5, …) are being published these days to detect exploitation of vulnerability MS15-034.

If you are making or modifying such detection rules, I want to share some observations with you.

MS15-034 can be exploited with a GET request with a specially crafted Range header.

Here is the example we’ll use: Range: bytes=2-18446744073709551615

Referring to RFC 2616 section 14.35.1, you can see that this is not the only way to specify a range. Here is the BNF:

ranges-specifier = byte-ranges-specifier
byte-ranges-specifier = bytes-unit “=” byte-range-set
byte-range-set  = 1#( byte-range-spec | suffix-byte-range-spec )
byte-range-spec = first-byte-pos “-” [last-byte-pos]
first-byte-pos  = 1*DIGIT
last-byte-pos   = 1*DIGIT

suffix-byte-range-spec = “-” suffix-length
suffix-length = 1*DIGIT

First of all, whitespace is allowed. So Range: bytes = 2 – 18446744073709551615 is valid (and also caused a BSOD on my test machine).

Second, numbers can have leading zeroes. So Range: bytes=2-018446744073709551615 is valid (and also caused a BSOD on my test machine).

Third, multiple ranges are allowed. So Range: bytes=2-3,4-18446744073709551615 is valid (this did not cause a BSOD on my test machine).

If you are using rules that don’t detect these cases properly, then attackers can easily evade detection. One space character could be all it takes to evade detection. If the rule looks for string “-18446744073709551615”, then using string “- 18446744073709551615” in the attack (extra space character added) will evade detection.

Monday 15 December 2014


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.

Monday 12 May 2014

Video: “Packet Class: Wireshark – Lua Protocol Dissectors”

Filed under: Networking,Wireshark — Didier Stevens @ 21:02

In this video, I’m trying to give you an idea of what you can expect in my “Packet Class: Wireshark” training when we will cover protocol dissectors written in Lua.

Next Page »

Blog at WordPress.com.