In this video, I show how to get started with my tools and a WannaCry sample.
Tools: pecheck.py, zipdump.py, strings.py
Sample: 84c82835a5d21bbcf75a61706d8ab549
In this video, I show how to get started with my tools and a WannaCry sample.
Tools: pecheck.py, zipdump.py, strings.py
Sample: 84c82835a5d21bbcf75a61706d8ab549
Added handling of zlib errors when performing a dictionary attack.
zipdump_v0_0_8.zip (https)
MD5: 51B971B57800D126B2067DC53303355A
SHA256: 095EE6000E99B9193C830B8BA11139907CB9445FD7D94D81E3F97A8B458D5D16
After adding support for password lists in zipdump, I decided to add an internal password list to zipdump, based on John’s public domain password list.
This internal password list (a few thousand passwords) can be used by providing filename . (a single dot) to options -P and –passwordfilestop.
zipdump_v0_0_7.zip (https)
MD5: 7B3D165B68B4E66D7EFCF54B25E08115
SHA256: DC794679CFDEA57AC532E11BC338F6823EECC26A36CB844B29EF15F93B6BA1C1
This new version of re-search.py has a build-in regular expression for bitcoin addresses, together with a Python function to validate the address.
re-search_V0_0_7.zip (https)
MD5: 38EBBC6B45476AA2FB03DC9604D2F7EE
SHA256: 7BE3B986126C3E40A886A66A08EA360EEE01A29F064F2D3235A1311C4FB4E45E
When I used my re-search.py tool to extract Bitcoin addresses from the latest WCry samples, I found a small bug. This version is a bugfix (bug introduced in version 0.0.4).
re-search_V0_0_5.zip (https)
MD5: A03CBBA9F2C5900A368BC064D3CC3D00
SHA256: 940B12CA8E3ADCC0266BC788B5A7AE2C830115BDB9FC04C3A7A178FDD7D44F02
We had to crack a password protected ZIP file, to discover that just few hours later, we would fly to Dubai for our NVISO team building event.
This inspired me to update my zipdump.py tool. This tool can handle password protected ZIP files. Using default password “infected”, or a password that can be provided with option -p.
In this new version, you can provide a list of password in a text file using option -P. Turns out that this simple dictionary attack just using Python is surprisingly quick (at least to me): 8000 passwords per second on an average machine.
zipdump_v0_0_6.zip (https)
MD5: B605DEABFC5458488B6487B1E9104085
SHA256: DDC2CE94D250CBDE62AD1EBE650654E4A50C51F97CADF412B16A553242819772
A good friend asked me how to decompress a gzip compressed file, stored inside a McAfee quarantine file. On Linux, it’s simple, using the punbup.py tool. Like this:
punbup.py -f quarantine.bup | gzip -d
Option -f dumps the first file in the quarantine file to the pipe of gzip, which decompresses the file and dumps it to stdout.
On Windows, where you have no gzip (unless you use Cygwin or a similar solution), you can use my translate.py tool.
translate has 2 modes of operation: translate byte per byte, or translate the complete byte sequence in one go.
By default, translate operates in byte per byte mode. To operate on the complete byte sequence, you use option -f. The translation expression (a Python expression) needs to be a lambda function when you use option -f. It receives the complete byte sequence as argument, and must return the translated byte sequence. So we need to use the gzip Python module for decompression, and the StringIO Python module to operate in memory (and not with files). This is the lambda function (argument b is the byte sequence, e.g. the quarantined file):
lambda b: gzip.GzipFile(”, ‘r’, fileobj=StringIO(b)).read()
As translate does not import the gzip Python module (it does import the StringIO Python module however), we need to import it using option -e:
-e -“import gzip”
The complete command is:
punbup.py -f quarantine.bup | translate.py -e “import gzip” -f “lambda b: gzip.GzipFile(”, ‘r’, fileobj=StringIO(b)).read()”
More than 5 years ago, I worked out a technique to drop any file on a machine which has removable storage disabled. The technique used a Teensy to simulate a keyboard and type out a pure ASCII PDF to notepad. The PDF, containing an embedded executable, can then be saved and opened with a PDF reader to extract the embedded file.
I recently re-visited this technique with my Bash Bunny (it can also be done with a Rubber Ducky):
First I create a pure ASCII PDF file with an embedded executable using my make-pdf-embedded.py tool:
make-pdf-embedded.py -f fi80 -t -n Dialog42.exe.txt Dialog42.exe Dialog42.pdf
Option -f select the filters to use: f to deflate (zlib compress) and i80 to use hexadecimal lines of 80 characters to encode the compressed executable file in pure ASCII.
Option -t for pure text.
Option -n to choose the name used in the PDF document for the embedded file (files with extension .exe can not be extracted with Adobe Reader).
And then I create a Ducky Script script from the PDF with my python-per-line.py tool:
python-per-line.py "Duckify({})" -o payload.duck Dialog42.pdf
The payload.duck file can then be installed on my Bash Bunny, referenced from a payload.txt bash script like this:
#!/bin/bash ATTACKMODE HID QUACK SET_LANGUAGE be QUACK GUI r QUACK DELAY 500 QUACK STRING notepad.exe QUACK ENTER QUACK DELAY 1000 QUACK switch1/payload.duck
Here is a video showing my Bash Bunny dropping this PDF file:
I often have to make changes to text files by processing each line, and prefer to do that with Python. This is why I wrote this tool about a year ago, and publish it now in preparation of a blog post on Bash Bunny.
The man page:
Usage: python-per-line.py [options] expression [[@]file ...]
Program to evaluate a Python expression for each line in the provided text file(s)
Arguments:
@file: process each file listed in the text file specified
wildcards are supported
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, --man Print manual
-o OUTPUT, --output=OUTPUT
Output to file
-s SCRIPT, --script=SCRIPT
Script with definitions to include
Manual:
This program reads lines from the given file(s) or standard input, and
then evaluates the provided Python expression on each line of text and
outputs the result of the Python expression.
The Python expression needs to use {} to represent the content of each
line. Before evaluation, {} is replaced by the content of each line
surrounded by single quotes.
The value of the evaluated expression is outputed as a single line,
except when the Pythion expression returns a list. In that case, each
element of the list is outputed on a single line.
Example:
Content test.txt:
Line 1
Line 2
Line 3
Command:
python-per-line.py "'copy ' + {}" test.txt
Output:
copy Line 1
copy Line 2
copy Line 3
This program contains a predefined Python function to help with the
generation of Rubber Ducky scripts: Duckify.
Example:
Content test.txt:
Line 1
Line 2
Line 3
Command:
python-per-line.py "Duckify({})" test.txt
Output:
STRING Line 1
ENTER
STRING Line 2
ENTER
STRING Line 3
ENTER
The lines are written to standard output, except when option -o is
used. When option -o is used, the lines are written to the file
specified by option -o.
An extra Python script (for example with custom definitions) can be
loaded using option -s.
python-per-line_V0_0_1.zip (https)
MD5: B7C1146D44D6B3F8B04C571E8C205191
SHA256: 6D7931B33F8A1D81539E892897D301145A63502A181B2B89A01466D599D53787
This version has one new option: -G or –grepall.
re-search_V0_0_4.zip (https)
MD5: 965C484CC5BF447B390BA4E176698972
SHA256: D2F3A52F7590CD38E796B6F6209FC87A1BD6451F1787010557FA39E25AFDBC2F