Didier Stevens

Monday 24 April 2017

Bash Bunny PDF Dropper

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

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:

Sunday 23 April 2017

New Tool: python-per-line

Filed under: My Software — Didier Stevens @ 10:42

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

Monday 10 April 2017

Update: re-search.py Version 0.0.4

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

This version has one new option: -G or –grepall.

re-search_V0_0_4.zip (https)
MD5: 965C484CC5BF447B390BA4E176698972
SHA256: D2F3A52F7590CD38E796B6F6209FC87A1BD6451F1787010557FA39E25AFDBC2F

Saturday 8 April 2017

Quickpost: Infinite Control For Bash Bunny

Filed under: Bash Bunny,Hardware,My Software,Quickpost — Didier Stevens @ 11:25

I already used a Teensy to send a CONTROL keypress every 10 seconds. This came in handy to keep machines from going to sleep or auto-locking.

Today I wrote a script for my Bash Bunny to do the same.

Warning: if you use this, make sure you unplug the Bash Bunny before you start typing on the computer. Otherwise the CONTROL keypresses will interfere with your typing, potentially ending up in unwanted commands like CTRL-Q: Quit


#!/bin/bash
# Title:         Infinite Control
# Author:        Didier Stevens (https://DidierStevens.com)
# Version:       0.0.1 2017/04/08
#
# Hit the CONTROL key every 10 seconds in an infinite loop,
# while blinking the red LED with every keypress.
#
# Can be used to prevent a machine from sleeping or auto-locking.
#
# WARNING: Do not type on the machine's keyboard while this script
#          is running, or your keystrokes might become commands,
#          for example CTRL-Q: Quit
#
# Red ...............Hitting CONTROL key
# Red Blinking.......Wow! We broke out of the infinite while loop!

ATTACKMODE HID

# infinite while loop
while true
do
  LED R
  QUACK CTRL
  LED
  sleep 10
done

# this code will never be reached
LED R 100

Quickpost info


Tuesday 7 March 2017

Update: oledump.py Version 0.0.27

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

This new version of oledump.py adds some extra features for YARA rule scanning.

oledump.py declares 2 external variables that can be used in your YARA rules.

External variable streamname is a string with the stream name, as printed in oledump’s report.

External variable VBA is a boolean that is set to true when the data to scan is VBA source code. Previous versions of oledump would scan the raw stream content with YARA, but this new version also decompresses all streams with VBA macros, and concatenates them together to scan them after all streams have been scanned.

Example of a rule using external variable VBA:

rule VBA_Autorun
{
    strings:
        $a = "AutoExec" nocase fullword
        $b = "AutoOpen" nocase fullword
        $c = "DocumentOpen" nocase fullword
        $d = "AutoExit" nocase fullword
        $e = "AutoClose" nocase fullword
        $f = "Document_Close" nocase fullword
        $g = "DocumentBeforeClose" nocase fullword
        $h = "Document_Open" nocase fullword
        $i = "Document_BeforeClose" nocase fullword
        $j = "Auto_Open" nocase fullword
        $k = "Workbook_Open" nocase fullword
        $l = "Workbook_Activate" nocase fullword
        $m = "Auto_Close" nocase fullword
        $n = "Workbook_Close" nocase fullword
    condition:
        VBA and any of ($*)
}

The condition of this rule is true when external variable VBA is true and when at least one of the strings are found:

20170306-184258

This rule is included in a new set of YARA rules I included with oledump.py: vba.yara.

I made a video to illustrate this:

And there is also a new plugin: plugin_str_sub. It tries to de-obfuscate strings with padded characters:

oledump_V0_0_27.zip (https)
MD5: A6C6728E20AE46A4FECC5F3976AF33BF
SHA256: 54FE550D5102A0E9428F6BD9B5170B50797EDA2076601634519CDBB574004A3C

Monday 6 March 2017

Update: cut-bytes.py Version 0.0.5

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

I just updated the manual of this version, to explain here documents.

cut-bytes_V0_0_5.zip (https)
MD5: B20B9758D50C846CD0E0AEB9E0B15101
SHA256: B12D1E1C510ED4CC820C5D2F62897DF71E567B0D3B23AC36653236D30104157F

Sunday 5 March 2017

New Tool: sets.py

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

It’s a tool I started years ago, and I’m releasing it now.

sets.py allows you to perform operations on sets: union, intersection, subtraction and exclusive or. A set is a list of lines in a file, or a stream of bytes in a file.

I demo the tool in this video:

sets_V0_0_1.zip (https)
MD5: DF0AE1EF67B4BA04750A39EF7FAEE09C
SHA256: A5FF61610AD67CA0638E53A10DD083612C2F5BF42218DD2393AFD20035E89B9F

Update: re-search.py Version 0.0.3

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

A very small update to re-search.py: I added a regular expression for strings to the library:

20170303-224430

re-search_V0_0_3.zip (https)
MD5: 6C4F59C4BA5DAC1D16D3E09D1E333FD0
SHA256: BFB019F1350F7D63FB3704322F62894A4B17D8EE03CC186156F2A97045E47F58

Tuesday 28 February 2017

Password History Analysis

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

When cracking Active Directory passwords as I explained in this series of blog posts, you can also crack the password history.

The program I’m releasing now will make a report of users who “recycle” their previous passwords by using a common string.

Example:

 

20170227-220004

The man page:

Usage: password-history-analysis.py [options] [[@]file ...]
Program to analyze password history

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 SEPARATOR, --separator=SEPARATOR
                        Separator used in the password files (default :)
  -l, --lowercase       Convert usernames to lowercase
  -n, --nonmatching     Print lines that do not match a password entry
  -L LENGTH, --length=LENGTH
                        Minimum length common string

Manual:

This program analyzes files with password history, and reports
statistics on common strings (prefix, suffix, infix) of passwords per
user.
The minimum lenght of a common string is 3 characters by default. Use
option -L to change the minimum length of the common string.


Example of input file (passwords.txt):
user01:HASH:azerty-
user01_history0:HASH:azerty0
user01_history1:HASH:azerty1
user01_history2:HASH:azerty2
user01_history3:HASH:azerty3
user01_history4:HASH:azerty4
user01_history5:HASH:azerty5
user01_history6:HASH:azerty6
user01_history7:HASH:azerty7
user01_history8:HASH:azerty8
user01_history9:HASH:azerty9
user01_history10:HASH:azerty10
user01_history11:HASH:azerty11
user01_history12:HASH:azerty12
user01_history13:HASH:azerty13
user01_history14:HASH:azerty14
user01_history15:HASH:azerty15
user01_history16:HASH:azerty16
user01_history17:HASH:azerty17
user01_history18:HASH:azerty18
user01_history19:HASH:azerty19
user01_history20:HASH:azerty20
user01_history21:HASH:azerty21
user01_history22:HASH:azerty22
user02:HASH:99Monkey
user02_history0:HASH:00Monkey
user02_history1:HASH:01Monkey
user02_history2:HASH:02Monkey
user02_history3:HASH:03Monkey
user02_history4:HASH:04Monkey
user02_history5:HASH:05Monkey
user02_history6:HASH:06Monkey
user02_history7:HASH:07Monkey
user02_history8:HASH:08Monkey
user02_history9:HASH:09Monkey
user02_history10:HASH:10Monkey
user02_history11:HASH:11Monkey
user02_history12:HASH:12Monkey
user02_history13:HASH:13Monkey
user02_history14:HASH:14Monkey
user02_history15:HASH:15Monkey
user02_history16:HASH:16Monkey
user02_history17:HASH:17Monkey
user02_history18:HASH:18Monkey
user02_history19:HASH:19Monkey
user02_history20:HASH:20Monkey
user02_history21:HASH:21Monkey
user02_history22:HASH:22Monkey
user03:HASH:SomethingElse
user03_history0:HASH:Password0
user03_history1:HASH:Password1
user03_history2:HASH:Password2
user03_history3:HASH:Password3
user03_history4:HASH:Password4
user03_history5:HASH:Password5
user03_history6:HASH:Password6
user03_history7:HASH:Password7
user03_history8:HASH:Password8
user03_history9:HASH:Password9
user03_history10:HASH:Password10
user03_history11:HASH:Azerty$1

Usage example:
password-history-analysis.py passwords.txt

Output:
user01:24:24:100.00:azerty
user02:24:24:100.00:Monkey
user03:13:11:84.62:Password

The first field is the username.
The second field is the number of passwords for the given username.
The third field is the largest number of passwords for the given
username with the same prefix or suffix.
The fourth field is the percentage of third and second field.
The fifth field is the password's common string.

The report can be written to file with option -o.
Use option -l to convert usernames to lowercase.

Option -n will not produce a report, but output all lines that do not
match a password entry. Use this to detect entries not handled by this
program.

The separator (for input and output) is :, and can be changed with
option -s.


password-history-analysis_v0_0_1.zip (https)
MD5: 2ED7FB5E6968B25AEBF623754E5513B0
SHA256: DA75A8E2C92DCD31FB3C05732C660C3996EAEBADFA198535C051DC02AE94805B

Sunday 26 February 2017

Update: translate.py Version 2.4.0

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

I added a feature similar to “here files” to translate.py. It’s something I already did in xor-kpa.py.

In stead of using an input filename, the content can also be passed in the argument. To achieve this, precede the text with character #.
If the text to pass via the argument contains control characters or non-printable characters, hexadecimal (#h#) or base64 (#b#) can be used.

Example:
translate.py #h#89B5B4AEFDB4AEFDBCFDAEB8BEAFB8A9FC “byte ^0xDD”
Output:
This is a secret!

translate_v2_4_0.zip (https)
MD5: B33830C68D8A8A7534AF178243658E70
SHA256: A01AB10FCE42664869C4E31DB1AB2E1E0237172D0AE9685549A09BF866D7F885

Next Page »

Blog at WordPress.com.