Didier Stevens

Tuesday 6 June 2017

Update: xor-kpa.py Version 0.0.5

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

Some small changes to my XOR known plaintext attack tool (xor-kpa), which will be detailed in an ISC Diary entry.

xor-kpa_V0_0_5.zip (https)
MD5: 023D8E3725E0EF7CEC449085AA96BB3A
SHA256: 7517DD44AFBFA11122FD940D76878482F50B7A2A2BCD1D7A2AF030F6CAC4F4E3

Friday 12 May 2017

Quickpost: ZIP Password Cracking With John The Ripper

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

Here is how to crack a ZIP password with John the Ripper on Windows:

First you generate the hash with zip2john:

Then you run john:

In this example, I use a specific pot file (the cracked password list).

 


Quickpost info


Friday 3 March 2017

Practice ntds.dit File Part 9: Extracting Password History Hashes

Filed under: Encryption — Didier Stevens @ 0:00

I released a tool to analyze password history.

To extract password history from ntds.dit with ntdsxtract/dsusers.py, use option –passwordhistory.

To extract password history from ntds.dit with secretsdump.py, use option -history.

20170302-224914

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 27 November 2016

Update: xor-kpa.py Version 0.0.4

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

This new version of xor-kpa adds the option -x to encode/decode, and also prints the hexadecimal value of the found keys.

xor-kpa_V0_0_4.zip (https)
MD5: FCE75B6125104D8AFC56A67B65FF75C0
SHA256: 3DCCA479D4C8CAC9B248B24F799184A69D0F10403593CB002248DD35CCE60FD4

Tuesday 22 November 2016

Simple Ciphers: cipher-tool.py

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

When I left my last position, my friends and colleagues with whom I’ve worked for years gave me a little challenge: a PDF with a hidden ciphertext. At first I had to use Excel to decipher the ciphertext, but later I wrote a small Python tool to help me.

The simple ciphers supported by this tool are XOR, ROT, Vigenère and subtract (I added that last one because it was used in a maldoc). You can use the man page (option -m) to learn more.

cipher-tool_V0_0_1.zip (https)
MD5: B7D44090A76F66D7194D0A0D890E2CEB
SHA256: 1E8E1F112595FC08C3C20A06D172C21DDE6375EC8651A8DE6EF57B938F3E67E8

Monday 22 August 2016

Update: xor-kpa.py Version 0.0.3 With Man Page

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

This new version has a man page now (option -m):

Usage: xor-kpa.py [options] filename-plaintext [filename-ciphertext]
XOR known-plaintext attack

Predefined plaintext:
 dos: This program cannot be run in DOS mode

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
  -n, --name            Use predefined plaintext
  -e EXTRA, --extra=EXTRA
                        Minimum number of extras
  -d, --decode          Decode the ciphertext

Manual:

xor-kpa performs a known-plaintext attack (KPA) on an XOR-encoded file. Take a
file with content "This is a secret message, do not share!". This file is XOR-
encoded like this: the key is ABC, the first byte of the file is XORed with A,
the second byte of the file is XORed with B, the third byte of the file is
XORed with C, the fourth byte of the file is XORed with A, the fifth byte of
the file is XORed with B, ...
If you know part of the plaintext of this file, and that plaintext is longer
than the key, then xor-kpa can recover the key.

xor-kpa tries to recover the key as follows. xor-kpa encodes the encoded file
with the provided plaintext: if you XOR-encode an XOR-encoded file
(ciphertext) again with its plaintext, then the result is the keystream (the
key repeated): ABCABCABC... xor-kpa detects such keystreams and extracts the
key.

Example:
 xor-kpa.py "#secret message" encoded.txt
Output:
 Key:       ABC
 Extra:     11
 Keystream: BCABCABCABCABC

In this example, we assume that the plaintext contains "secret message". xor-
kpa finds one keystream: BCABCABCABCABC. From this keystream, xor-kpa extracts
the key: ABC.
Extra is the number of extra charecters in the keystream: the keystream is 14
characters longh, the key is 3 characters long, so extra is 14 - 3 = 11. It is
a measure for the probability that the recovered key is the actual key. The
longer it is, the better.
In this case, because the ciphertext is a small file, xor-kpa found only one
keystream. But for larger files or small plaintext, it will identify more than
one potential keystream.

Example:
 xor-kpa.py #secret encoded.txt
Output:
 Key:       ABC
 Extra:     3
 Keystream: BCABCA

 Key:       'KUW^'
 Extra:     1
 Keystream: '^KUW^'

 Key:       'S@E'
 Extra:     1
 Keystream: 'S@ES'

In this example, xor-kpa has identified 3 potential keys. The potential keys
are sorted by descending extra-value. So the most promising keys are listed
first.
Keystreams with an extra value of 1 (1 extra character) rarely contain the
correct key.
Option -e (--extra) allows us to reduce the amount of displayed potential keys
by specifying the minimum value for extras.

Example:
 xor-kpa.py -e 2 #secret encoded.txt
Output:
 Key:       ABC
 Extra:     3
 Keystream: BCABCA

With option -e 2 we specify that the keystream must at least have 2 extras.
That's why the keystreams with 1 extra are not listed.

xor-kpa can also decode the ciphertext file with the recovered key (the key
with the highest extra value). Use option -d (--decode) to do this:

Example:
 xor-kpa.py -d #secret encoded.txt
Output:
 This is a secret message, do not share!

xor-kpa takes one or two arguments. The first argument is a file containing
the plaintext, the second argument is a file containing the ciphertext.
xor-kpa can also read the ciphertext from stdin (for example via a pipe), in
that case the second argument is omitted.
The files can also be ZIP files containing one file (optionally password-
protected with 'infected'), in that case xor-kpa will decompress the content
of the ZIP file and use it.

In stead of putting the plaintext or the ciphertext in a file, it can also be
passed in the argument. To achieve this, precede the text with character #
(this is what we have done in all the examples up till now).
If the text to pass via the argument contains control characters or non-
printable characters, hexadecimal (#h#) or base64 (#b#) can be used.

Example:
 xor-kpa.py -d #h#736563726574 encoded.txt
Output:
 This is a secret message, do not share!

Example:
 xor-kpa.py -d #b#c2VjcmV0 encoded.txt
Output:
 This is a secret message, do not share!

Finally, the plaintext can be selected from a predefined list. For the moment,
the only text in the predefined list is 'This program cannot be run in DOS
mode', identified by the keyword dos. Use option -n (--name) to use predefined
plaintext.

Example:
 xor-kpa.py -n dos malware.vir



xor-kpa_V0_0_3.zip (https)
MD5: 228B9DE1D3005F75190113369A91E1D4
SHA256: A30C20668BA0939DD936BB2706AEC636E5260EFB0B0F16F4770F9B1B59E780A9

Monday 15 August 2016

Video: mimikatz: Golden Ticket + DCSync

Filed under: Encryption — Didier Stevens @ 0:00

I also have a video for my mimikatz: Golden Ticket + DCSync blog post.

Friday 12 August 2016

mimikatz: Golden Ticket + DCSync

Filed under: Encryption — Didier Stevens @ 8:04

This blog post aims to provide a bit more information about what Benjamin Delpy wrote in this tweet:

20160805-092138

For this demo I run mimikatz as a least privilege, local user on a Windows workstation that is a member of my demo domain. The first step is to generate and use a golden ticket to obtain domain admin rights. The second step is to use dcsync to retrieve hashes from the domain controller.

As a freshly logged-on local user, I have no tickets:

20160805-090019

Then I create a golden ticket for the domain admin:

20160805-090730

20160805-090713

And I use it:

20160805-090827

Now my least privilege, local user is impersonating the domain administrator:

20160805-090904

Then I retrieve the hashes for user user01 from the domain control via the DRSR protocol:

20160805-091005

Compare the LM and NTLM hashes with the hashes in this blogpost: they are the same.

All the arguments (krbtgt, domain, domain admin username, domain SID) needed for the kerberos::golden command can be extracted from the ntds.dit file we obtained. More info on alternative methods to obtain the arguments can be found here.

@gentilkiwi told me that the domain admin username and RID can also be faked, as long that it is part of the domain admins group. It will work for about 20 minutes without checks.

If we don’t have the necessary rights (for example domain admin) to query a DC with DRSR, we get an error 5 (access denied):

20160805-090342

You also get this error when the krbtgt NTLM hash has changed. Command ptt will seem to succeed however:

20160805-121604

Remember that unless the password for user krbtgt is changed (which is not a standard practice), the krbtgt NTLM hash never changes. So even very old copies of ntds.dit can be used to recover hashes as described in this method.

The ticket is stored on file using asn1:

20160805-100151

Benjamin has a YARA rule (mimikatz_kirbi_ticket) to detect such tickets:

20160805-101142

Unfortunately, the mimikatz I use (version 2.1) uses another asn1 encoder and the rule no longer works.

Until Benjamin makes a more generic rule, you can use this updated rule:

rule mimikatz_kirbi_ticket
{
	meta:
		description		= "KiRBi ticket for mimikatz"
		author			= "Benjamin DELPY (gentilkiwi); Didier Stevens"

	strings:
		$asn1			= { 76 82 ?? ?? 30 82 ?? ?? a0 03 02 01 05 a1 03 02 01 16 }
		$asn1_84		= { 76 84 ?? ?? ?? ?? 30 84 ?? ?? ?? ?? a0 84 00 00 00 03 02 01 05 a1 84 00 00 00 03 02 01 16 }

	condition:
		$asn1 at 0 or $asn1_84 at 0
}

This ticket file is created on disk because I use kerberos::golden’s option /ticket:, but if I use option /ptt, the ticket is immediately passed, and not written to disk.

@gentilkiwi also told me that if you impersonate a domain controller account for kerberos::dcsync, then no events are logged.

Monday 8 August 2016

Howto CreateCertGUI: Create Your Own Certificate On Windows (OpenSSL Library)

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

I created a program with a graphical user interface to create a simple certificate. This program uses the OpenSSL library. Extract the program from the zip file (below) and run it:

20160807-232138

You don’t have to install any dependencies, everything is linked into the program.

If you need more help, here is a video:

Download:

CreateCertGUI_V1_0_0_1.zip (https)
MD5: F5400736E7E38F30D35A02FEB6D99651
SHA256: 82D59AC494FEF1A8B219C591717359712C19E8845D02A457017045A9A4C3D989

And if you are interested, here is the source code:

CreateCertGUI_source_V1_0_0_1.zip (https)
MD5: 790CA083407032434A8DA1FF8AC1E512
SHA256: B15BB8A3504EF56D1C6C84CA181FFB6E5A73956EC79757C62B87B520C136AA2D

Next Page »

Blog at WordPress.com.