Didier Stevens

Sunday 31 January 2021

New Tool: pdftool.py

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

pdftool.py is a new tool I developed. This version has only one command: iu (incremental updates).

With this command, one can check if a PDF has incremental updates, and then select different versions of this PDF with incremental updates.

A PDF with incremental updates, is a PDF that has been modified by appending changes to the document at the end of the PDF file, without modifying the original content.

Here is a video explaining incremental updates and the use of my tool.

I reference 2 blog posts in the video: “Solving a Little PDF Puzzle” and “Shoulder Surfing a Malicious PDF Author“.

pdftool_V0_0_1.zip (https)
MD5: ED2BBE886008C737CC06E22F4F0FE8A1
SHA256: 401E88FBFAEC4382A50FE59430D04FE6111F9911958AB09BA7530C26043FDA87

Thursday 28 January 2021

Update: XORSelection.1sc Version 6.0

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

I released an update to my 010 Editor script XORSelection.1sc.

010 is a binary editor with a scripting engine. XORSelection.1sc is a script I wrote years ago, that will XOR-encode a (partial) file open in the editor.

The first version just accepted a printable, arbitrary-length string as XOR-key. Later versions accepted an hexadecimal key too, and introduced various options.

With version 6.0, I add support for a dynamic XOR-key. That is a key that changes while it is being used. It can change, one byte at-a-time, before or after each XOR operation at byte-level is executed.

Hence option cb means change before, and ca means change after. Watch this video to understand exactly how the key changes (if you want to skip the part explaining my script XORSelection, you can jump directly to the dynamic XOR-key explanation).


I made this update to my XORSelection script, because I had to “manually” decode a Cobalt Strike beacon that was XOR-encoded with a changing XOR key (it is part of a WebLogic server attack). Later I included this decoding in my Cobalt Strike beacon analysis tool 1768.py.

The decoding shellcode is in the first 62 bytes (0x3E) of the file:

After the shellcode comes the XOR-key, the size and the beacon:

We can decode the beacon size, that is XOR-encoded with key 0x3F0882FB, as follows. First we select the bytes to be decoded:

Then we launch 010 Editor script XORSelection.1sc:

Provide the XOR key (prefix 0x is to indicate that the key is provide as hexadecimal byte values):

And then, after pressing OK, the bytes that contain the beacon size are decoded by XOR-ing them with the provided key:

This beacon size (bytes 00 14 04 00) is a little-endian, 32-bit integer: 0x041400.

To decode the beacon, we select the encoded beacon and launch script XORSelection.1sc again:

This time, we need to provide an option to change the XOR-decoding process. We press OK without entering a value, this will make the next prompt appear, where we can provide options:

The option we need to use to decode this Cobalt Strike beacon, is cb: change before.

In the next prompt, we can provide the XOR-key:

And we end up with the decoded beacon (you can see parts of the PE file that is the beacon):

Remark that you can enter “h” at the option prompt, to get a help screen:

I made this video explaining how to use this new option, and also explaining how the XOR key is changed exactly when using option change before (cb) or change after (ca).

If you want to skip the part explaining my script XORSelection, you can jump directly to the dynamic XOR-key explanation.

XORSelection_V6_0.zip (https)
MD5: C1872C275B59E236906D38B2302F3F4B
SHA256: 1970A506299878FAC2DDD193F9CE230FD717854AC1C85554610DDD95E04DE9E9


Sunday 24 January 2021

Update: strings.py Version 0.0.7

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

This new version brings an update to the Pascal feature of strings.py, my tool to extract strings from arbitrary files.

I had to analyze compiled Lua code (compiled with Lua 5.2): Lua 5.2 byte code stores strings like C strings and Pascal strings.

The strings are terminated by a NULL byte, like C strings, and they are prefixed with a length counter, like Pascal strings. Since the length includes the NULL byte, my strings.py tool didn’t match compiled Lua 5.2 strings:

I need to subtract 1 from the counter, so that it matches the length of the string without NULL byte. This can now be done as follows:


strings_V0_0_7.zip (https)
MD5: 2533BF3E7CBD5526718CDE5E150039D2
SHA256: FFBE686A2E41B22858023898580419806A789349D408C24EF25E8BEBCD33A418

Saturday 23 January 2021

Update: re-search.py Version 0.0.15

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

This is a new version of my tool to search with regular expression, adds a -F (–filter) option to filter search results.

re-search_V0_0_15.zip (https)
MD5: E68D42F9F943335961C12BED7AD459A7
SHA256: 47F837C198CC3033B9C07086EA4FD0484BC40CE850723B4F6A849FB237D9A7E0

Friday 22 January 2021

Update: re-search.py Version 0.0.14

Filed under: My Software,Update — Didier Stevens @ 21:34

This is a new version of my tool to search with regular expression, that adds a new regular expression to the embedded dictionary: detection of domain names that end with a valid TLD:

re-search_V0_0_14.zip (https)
MD5: 53CDB34174E6EFE211872D6BC64533CC
SHA256: 3F55E6EA7272BFC780E159BA886932F96DC055CF533B0B3C3A5CCBAF0229682E

Tuesday 19 January 2021

Video: Maldoc Analysis With CyberChef

Filed under: maldoc,Malware,video — Didier Stevens @ 0:00

In this video, I show how to analyze a .doc malicious document using CyberChef only. This is possible, because the payload is a very long string that can be extracted without having to parse the structure of the .doc file with a tool like oledump.py.

I pasted the recipe on pastebin here.

Monday 18 January 2021

Update: Python Templates Version 0.0.4

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

Here is a bug fix version for my Python template (binary files).

I use these templates as a starting point for new tools or for quick development of ad-hoc tools.

python-templates_V0_0_4.zip (https)
MD5: 0ED3B69594A5BCD5069391177A6C1F79
SHA256: 15DBE4FD16F19FEBF4CB9381E4D59A1B7ECC11C43B48AE96FADD75FC53BB189F

Sunday 17 January 2021

Update: count.py Version 0.3.0

Filed under: My Software,Update — Didier Stevens @ 11:06

This is a Python 3 update for my count.py tool, a tool to count items.

count_v0_3_0.zip (https)
MD5: 52B9E424640983892FAD7734D0388860
SHA256: 4ED5A3FD913E6953A4635AB93F015BEDE08DF3448125DD95E1EFCB47A320D0D5

Monday 11 January 2021

Decrypting TLS Streams With Wireshark: Part 3

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

Say that you have to share a decrypted TLS stream, like the stream we decrypted in part 1.

You did a forensic investigation, and you need to included the decrypted TLS stream in your findings. Or you are troubleshooting an issue, and need need to share the decrypted TLS stream with a vendor.

I’m sure you don’t want to share the web server’s private key with a vendor (remember, in part 1, we used a web server’s private key to decrypt a TLS stream, while in part 2 we used a client’s SSLKEYLOGFILE).

If you would have the necessary secrets in a SSLKEYLOGFILE, you would be able to share that. Because those keys only apply to that particular TLS stream, they are useless for other TLS streams.

Such a file with secrets can be generated by Wireshark, when you have the capture file open together with the server’s private key file.

I use option “Export TLS Session Keys”:

The content of the file that was created (tls.keys) looks very similar to the SSLKEYLOGFILE we generated in part 2:

A small difference here, is that the RSA secret includes the master key in stead of the pre-master key.

This file can now be shared (together with the capture file) with third parties, without revealing the web server’s private key. They can then use it like explained in part 2.


To make life easier for the recipients of your capture file with secrets file, you can also merge both files together: embedding the secrets into the pcapng file. This way, they don’t have to configure secrets files in Wireshark, just opening the pcapng file is sufficient for the TLS traffic to be decrypted.

This embedding can be done with editcap’s –embed–secrets option:

The type of secret we want to inject is TLS. The tls.keys file (or the SSLKEYLOGFILE files from part 2) is injected like this into pcapng file capture-1.pcapng:

“c:\Program Files\Wireshark\editcap.exe” –inject-secrets tls,export.keys capture-1.pcapng capture-1-with-keys.pcapng

The resulting file, capture-1-with-keys.pcapng can then be opened in any instance of Wireshark, and the TLS traffic will be decrypted automatically, without having to change the configuration for the TLS protocol:

Embedding secrets is only possible with the pcapng format, because that format has a record type specific for secrets:

This is not possible with the older pcap format.

You can also created a pcap file with only the traffic you want to share, and nothing more. Use a display filter to select the traffic you want to share, and then export the specified packets:

And then you can open this filtered capture file, and generate TLS keys only for the traffic you want to share.


A typical Wireshark installation comes with a command-line version too: tshark. tshark uses the same settings as Wireshark. Thus if you defined a secrets file to decrypt TLS in Wireshark, tshark will also be able to do the decryption (-Y http is a display filter for http):

While if nothing is configured to do the decryption in Wireshark, tshark won’t be able to decrypt:

A final tip I want to share: starting with Python 3.8, python supports SSLKEYLOGFILE too (it uses a version of openssl that supports this).


Previous blog posts:

Decrypting TLS Streams With Wireshark: Part 1

Decrypting TLS Streams With Wireshark: Part 2

Sunday 10 January 2021

Update: oledump.py Version 0.0.58

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

This new version of oledump.py adds an overview of indicators to the end of the man page (-m) and adds simple password cracking to plugin_biff for Excel 95 files.

oledump_V0_0_58.zip (https)
MD5: 46CACE8791487EC18FAC250B6F5ECC7F
SHA256: 241E182CE5E1CC8B6EB612CF1EC09418BE263529501B6C54C5E683B88A3C5ABB

Next Page »

Blog at WordPress.com.