0

I'm pentesting a system (call it X) which uses an internal secret key. Due to weaknesses in the crypto, I can determine:

  1. The SHA1 hash of the key (stored as a checksum)
  2. With high probability, the value of any byte of the key
  3. The len of the key
  4. That the key consists only of printable ASCII chars

#2 is probabilistic, not perfect. That is, if the key would be secretkey! I might predict szcretyey!.

I'd like to use my prediction as a base, and use John EXTERNAL mode or hashcat rules to progressively modify it, replacing zero bytes, then one byte, then two bytes, each time with a printable ASCII char, until the SHA1 hash matches.

How can I do this?

*Note: I've already confirmed that the key does not appear in dictionaries or wordlists, and is too long to be cracked incrementally.


Update:

The rule would be something like:

N = 0
modify N chars
N++
SRobertJames
  • 245
  • 1
  • 7
  • 1
    You can leak the key bytes several thousand times and group them by frequency, So the first byte might be 80% s, 10% t, 1% a. Which should give you likely character combinations. Add to the fact that it appears to be a humanly generated key your brain should be able to filter these further. – wireghoul Feb 02 '22 at 22:15

1 Answers1

2

In hashcat, there are two broad approaches (and the second is probably better for your use case):

First, you can do this with rules. For the first couple of levels, you can start to do this with multiple calls of a rule ("stacked" rule) file, each line of which simply overwrites (o) a single character in a single position with another character (o0a, o0b, o0c, and then o1a, o1b, o1c, etc.) The rules file should also contain the no-op "passthrough" directive : - so that stacking the rules file multiple times (-r file -r file etc) will get you one replacement, two replacements, etc.

But the challenge with this method is that the number of possibilities goes up quite quickly - (94*wl)^x, where wl is the word length in characters, and x is the number of changed characters. Even just replacing a single character in your example 10-character string is 940 possibilities. The first character or two aren't hard for a fast hash like SHA1, but you'll reach a feasibility limit pretty quickly:

940^1 = 940
940^2 = 883600
940^3 = 883600830584000

In practice, only a few million rules will fit within most GPUs' memory. So really, only the first two levels are likely feasible for most software and platforms.

Second, you can do this with masks. Since you have high probability, another approach would be hold most of the string constant while varying the rest. You could do this with a file containing multiple masks, of the following form for a single character:

?aecretkey!
s?acretkey!
se?aretkey!
sec?aetkey!
secr?atkey!
secre?akey!
secret?aey!
secretk?ay!
secretke?a!
secretkey?a

... and this approach for two characters:

?a?acretkey!
?ae?aretkey!
?aec?aetkey!
?aecr?atkey!
?aecre?akey!
?aecret?aey!
?aecretk?ay!
?aecretke?a!
?aecretkey?a

... etc., rotating through all two-character replacements, then all three-character replacements, etc.

If the second (mask) approach is feasible for your use case, it is definitely more efficient - each mask is attacked separately, and has low memory requirements.

Royce Williams
  • 9,128
  • 1
  • 31
  • 55