philsmd/7z2hashcat

7z archive that fails with JtR as well as hashcat

magnumripper opened this issue · 7 comments

See openwall/john#2532

We got a sample from a user that doesn't crack in JtR. I tried it with hashcat and that too fails. Problem could be with 7z2hashcat or with the crackers (or both).

The correct password for test.7z is 1234 but NOTE that the content of test.7z is allegedly malicious

This works just fine:

$ 7z t test.7z 

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,8 CPUs x64)

Scanning the drive for archives:
1 file, 541480 bytes (529 KiB)

Testing archive: test.7z

Enter password (will not be echoed):
--
Path = test.7z
Type = 7z
Physical Size = 541480
Headers Size = 248
Method = LZMA2:26 7zAES
Solid = +
Blocks = 1

Everything is Ok

Files: 2
Size:       837861
Compressed: 541480

@philsmd I emailed you the link to the sample

Hey magnumripper,

I've investigated this problem now a little bit and analyzed the file...
I didn't find any problem with 7z2hashcat... but I noticed that whenever we do not perform the early skip (aes cbc padding attack), that everything seems to be correct and the "hash" was cracked correctly.

This is kind of strange and I didn't come across such a situation beforehand.

Looking at the code, whenever we skip this https://github.com/hashcat/hashcat/blob/b924901bb0a434b14f44dd9ab413f048255ca4d4/src/interface.c#L14749-L14754 early skip test, the hash is correctly cracked.

In other words, in case of the "correct" padding all out[0]-out[3] should be zero, but they are not!

I've also investigated if some lengths could be wrong, but it doesn't seem to be the case (furthermore, if it would be wrong the CRC32 code wouldn't match).

I also tried to see if a non-default (non-zero) padding was used to encrypt with AES-CBC... but it doesn't seem to be a standard one.

Hopefully I will find some more time later to investigate which padding was used etc (or if there are/could be other problems that I didn't look into yet).

In the meantime, maybe you can confirm that without the early skips (AES CBC padding attack), it cracks also with jtr?!
Thanks

@philsmd @magnumripper

After disabling the padding check(s), JtR jumbo is able to crack this hash just fine.

So perhaps some very new version of 7z doesn't pad correctly on purpose, in order to make it harder for us? Or maybe it's just a bug in some obscure archiver. Anyway it's pretty bad news because the padding early-reject is very good for us.

yeah

In my opinion this doesn't seem to be a problem with 7z2hashcat... but rather a problem which the crackers (hashcat + jtr) should address... I also believe that we do not really know whenever the padding was standard or not (neither does 7z2hashcat have this info, nor do we know that before the full aes decrypt... :()

As said, I have a couple of test .7z files but didn't come across this case beforehand... you could be right, that this .7z file was created by a different tool (maybe even a tool where the remaining padding just comes from non-cleanely intitialized memory or some random data on purpose)... or a special option used together with the 7z tool.

As you can see, it is very difficult to say without being able to reproduce this "problem" (if we just could somehow generate such archives would be a good start), or if someone provides more details on how this .7z file was created.

I'm not sure if I can do more than that for now... the only thing that comes to my mind would be to add an option to the crackers to disable the early reject test... but that could also cost a little bit and I would say that we should avoid this without the confirmation that we know some tools/options that generate .7z files like this one.

Yeah I also thought about adding a generic "no early reject" option to JtR. Anyway, this is not a problem with 7z2hashcat so I'm closing this for now. Thanks for all input!

For the record, this is the last AES block after decryption:

2c000000 fe070000 10908c02 00000000

Padding size "should" be 12, but only the last 4 bytes are zero. Unpack size is 148 (CRC length 147) so the AES data is 160 bytes. The "fe070000 10908c02" should be zeros for all we knew.

I dropped the padding checks in JtR (as long as we have complete data for CRC and so on) and performance wasn't hurt too much.