Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri, 17 Oct 2014 21:40:04 +0200
From: Frank Dittrich <>
Subject: Some format ssh and ssh-ng issues/questions

Sorry, for the rather long message.
I just wanted to ask a few simple questions, but while I started to
investigate a little bit, I just couldn't stop.

According to doc/README.ssh, both formats (ssh and ssh-ng) support
cracking passwords of ssh private key files.
But for some reason, their corresponding converters, ssh2john and, produce different hashes.
None of these 2 formats can process the other format's hashes.

Why is this necessary? Can't both formats use the same canonical hash
Does extract some information from the private key file
which ssh2john ignores?
Or does ssh2john extract more information from the private key file
(When I ran ssh2john and on the same input file, the hash
representation generated by ssh2john is longer than the one.)

While the ssh format does not emit false positives, sshng does.
Why that? If sshng currently produces just a view false positives, it
should be able to easily process the complete logic for those
candidates, without a significant drop in the c/s rate.
If ssh-ng can't do that, because doesn't extract all the
required information from the key file, isn't that an indication that
ssh-ng needs to be fixed?

Now let's compare the performance.
I used --markov instead of --incremental, because --incremental has much
more overhead in the first few seconds, compared to longer runs.

(bleeding-jumbo)run $ time ./john --format=ssh-ng --markov sshng.hash1
--session=sshng-1 --max-run-time=30
Loaded 1 password hash (SSH-ng [RSA/DSA 32/64])
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
MKV start (stats=$JOHN/stats, lvl=200 len=12 pwd=259356431)
0g 0:00:00:10 18.62% (ETA: 19:10:03) 0g/s 4421Kp/s 4421Kc/s 4421KC/s
Session stopped (max run-time reached)

real    0m30.065s
user    1m57.601s
sys    0m0.040s
(bleeding-jumbo)run $ time ./john --format=ssh --markov ssh.hash1
--session=ssh-1 --max-run-time=30
Loaded 1 password hash (SSH [RSA/DSA 32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
MKV start (stats=$JOHN/stats, lvl=200 len=12 pwd=259356431)
0g 0:00:00:30 35.29% (ETA: 19:11:00) 0g/s 3051Kp/s 3051Kc/s 3051KC/s
Session stopped (max run-time reached)

real    0m30.111s
user    1m59.679s
sys    0m0.093s

Apparently, ssh-ng needs additional 20 seconds before the real cracking
starts, because the status line reports just 10 seconds of run time.
So, you'd need some longer sessions, before ssh-ng with the reported c/s
rate of 4421K catches up with ssh (reported c/s rate 3051K).

(bleeding-jumbo)run $ time ./john --test=1 --format=ssh-ng
Will run 4 OpenMP threads
Benchmarking: SSH-ng [RSA/DSA 32/64]... (4xOMP) DONE
Raw:    2178K c/s real, 546005 c/s virtual

real    0m20.171s
user    1m18.144s
sys    0m0.006s
(bleeding-jumbo)run $ time ./john --test=1 --format=ssh  
Will run 4 OpenMP threads
Benchmarking: SSH (one 2048-bit RSA and one 1024-bit DSA key) [RSA/DSA
32/64]... (4xOMP) DONE
Raw:    179960 c/s real, 45553 c/s virtual

real    0m1.113s
user    0m4.100s
sys    0m0.004s

For --test, we also have about 19 seconds overhead for --format=ssh-ng.
And while --format=ssh has very specific output about what's being
tested ("one 2048-bit RSA and one 1024-bit DSA key"), this is not the
case for --format=ssh-ng.

Let's check the format tests.
Because the hashes are quite long, I just print the passwords here:

(bleeding-jumbo)run $ ./john --list=format-tests --format=ssh-ng|cut -f 4
(bleeding-jumbo)run $ ./john --list=format-tests --format=ssh|cut -f 4

So, there are 5 tests for --format=ssh, and 7 for --format=ssh-ng.

These passwords are used for both ssh and ssh-ng tests:

This one is only used for ssh:

And these are only used for ssh-ng:

I have no idea whether or not the tests with shared passwords really
match each other, what hash types they are, and what about those tests
with different passwords.

To test the individual hashes, I commented out all tests but one per
format, and compared the results.
For ssh I got:
test   c/s
1    93440
2    3855K
3    3260K
4    3231K
5    3499K

For ssh-ng (which has the cipher type as part of the hash), I got
test   c/s cipher
1    5225K 1
2    1380K 0
3    5205K 1
4    5222K 1
5    5221K 1
6    1379K 0
7    7.7   2

Yes, that's right, the last test (cipher 2) has a c/s rate of just 7.7!

(bleeding-jumbo)run $ time ./john --test=10 --format=ssh-ng
Will run 4 OpenMP threads
Benchmarking: SSH-ng [RSA/DSA 32/64]... (4xOMP) DONE
Raw:    7.7 c/s real, 1.9 c/s virtual

real    1m57.608s
user    7m22.915s
sys    0m0.008s

(bleeding-jumbo)run $ time ./john --test=0 --format=ssh-ng
Will run 4 OpenMP threads
Testing: SSH-ng [RSA/DSA 32/64]... (4xOMP) PASS

real    1m57.952s
user    7m22.938s
sys    0m0.016s

This also explains the 20 seconds extra time in my --markov tests!

Wouldn't it be a good idea to only test this particular cipher 2 hash in
DEBUG builds?
Could there be some bug causing this low c/s rate? Should this cipher 2
be a completely separate format?
(Mixing cipher 2 hashes with other in one session would be a desaster.
And currently, ssh-ng doens't even support tunable cost reporting, ssh
(I would be willing to provide a patch, but currently I know too little
about these formats.)

Apparently, cipher 2 has been added (just to ssh-ng) with this commit:
commit da8f1dfcc35e41c52ff28428e9ffd6f65e34eafd
Author: Spiros Fraganastasis <>
Date:   Thu Sep 25 20:05:03 2014 +0300

    add support for new openssh key format

How to I generate such a private key?

Cipher 0 and cipher 1 don't mean the type of the private key, either.
Because, when I create 2 key files, one with
$ ssh-keygen -t rsa
and the other with
$ ssh-keygen -t dsa
then ./ converts both files into hashes with cipher type 1.

According to, these are the ciphers encoded with 0, 1, 2:
        'AES-128-CBC': {'cipher': AES, 'keysize': 16, 'blocksize': 16,
'mode': AES.MODE_CBC},
        'DES-EDE3-CBC': {'cipher': DES3, 'keysize': 24, 'blocksize': 8,
'mode': DES3.MODE_CBC},
        'AES-256-CBC': {'cipher': AES, 'keysize': 32, 'blocksize': 16,
'mode': AES.MODE_CBC},

For the DSA key, I get about 3750K c/s for ssh and 4420K c/s for ssh-ng.
For the RSA key, I get about 3200K c/s for ssh and 4400K c/s for ssh-ng.
So, what impacts the c/s rate in which way? The key length? The key type
Apparently, the cipher does (at least for cipher 2).

And finally, since "man ssh-keygen" also mentions -t ecdsa for protocol
version 2, I also generated a key file for -t ecdsa.

(bleeding-jumbo)run $ file test-ecdsa
test-ecdsa: PEM EC private key
(bleeding-jumbo)run $ ./ test-ecdsa
test-ecdsa is not a valid private key file
(bleeding-jumbo)run $ ./ssh2john test-ecdsa
*** Error in `./ssh2john': double free or corruption (fasttop):
0x00000000023a3620 ***
======= Backtrace: =========
======= Memory map: ========
Aborted (core dumped)

(bleeding-jumbo)run $ cat test-ecdsa
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,3ED634BF5F4CD542DC28576FC0241978


So, while just doesn't recognize this file as a valid
private key file, ssh2john just crashes.
May be escda isn't important enough to be supported, but at least
ssh2john shouldn't crash.


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.