03-05-2022, 12:01 AM

Fart-box asked to describe the algorithm so I figured I'd take a few minutes and outline the algo to determine the multiplier (like for nvg589 and nvg599)

First things first, the key at least as those for nvg589 and nvg599 is base 37 (heptatrigesimal), with a charset of abcdefghijkmnpqrstuvwxyz23456789#%+=? This is all described by MrFancyPants and implemented in PSKracker by Soxrok2212, see the default router keyspace thread here on hashcat.

key = integer * multiplier

The password converts into the key (long integer). This key is the product of an integer and the multiplier. If the multiplier is an integer then you can use the Euclidean method to determine the greatest common denominator. So far so good, but what if the multiplier is a real number (with a fraction)? The response surface is jagged so you cannot fit it, it needs at least 7 decimal places to get the last character of the password correct, so brute forcing the multiplier is out. I always ended up with one more unknown than equations to go the linear algebra route.

My happy thought was I should drop my fascination with the multiplier and instead brute force the integer. You can use the first key and a guessed integer to determine a multiplier. Then use a second key, divide by that same multiplier to recover the integer belonging to the 2nd key. If that value is in fact an integer you have discovered a multiplier! If it isn't an integer than the first integer was wrong and thus the multiplier was wrong.

for integer1 = 1 to Very_Large_Number

multiplier = key1/integer1;

integer2 = key2/multiplier;

if is_integer(integer2) then print "BINGO"

endfor

Obviously you have to define integer2 as a float. The critical function here is is_integer. It needs to flag x.9999 as well as x.0001 as close enough to an integer with a defined precision. I'll leave that to the reader to implement.

Of course using multiple keys vs each other makes it robust against typos. Lastly, you will also recover more than the greatest common denominator, because key = (integer1 * 6) * (multiplier/6) and a host of other small integers (that cancel each other out). So it requires a bit of sorting out, but you'll quickly spot the ones that belong together.

Let's do an example for the 5268AC.

password 9yw9mx6sj3wt turns into key1=1353921430411399943 (assuming the first digit is base8 not base37)

password 9u7ke7kz7r9w turns into key2=1335782341279950921

So you are merrily scanning integers until you hit integer1=1940033061 (in C++ you can scan billions in minutes single threaded)

multiplier = key1/integer1; = 1353921430411399943/1940033061 = 697885751.345657064037

then you do

integer2 = key2/multiplier; = 1335782341279950921/697885751.345657064037 = 1914041573.000032

1914041573.000032 is pretty close to an actually integer so perhaps 697885751.345657064037 is the multiplier.

Might as well verify say against password 39bh23v3qpf6 (key3=234888871301781004)

key3/multiplier= 336572097.72354 *sad trombone* that's not an integer at all!

There many more ways to turn a password into a key including changing the charset around, so I'll let the reader experiment with those! May be they are more creative than I and strike gold!

First things first, the key at least as those for nvg589 and nvg599 is base 37 (heptatrigesimal), with a charset of abcdefghijkmnpqrstuvwxyz23456789#%+=? This is all described by MrFancyPants and implemented in PSKracker by Soxrok2212, see the default router keyspace thread here on hashcat.

key = integer * multiplier

The password converts into the key (long integer). This key is the product of an integer and the multiplier. If the multiplier is an integer then you can use the Euclidean method to determine the greatest common denominator. So far so good, but what if the multiplier is a real number (with a fraction)? The response surface is jagged so you cannot fit it, it needs at least 7 decimal places to get the last character of the password correct, so brute forcing the multiplier is out. I always ended up with one more unknown than equations to go the linear algebra route.

My happy thought was I should drop my fascination with the multiplier and instead brute force the integer. You can use the first key and a guessed integer to determine a multiplier. Then use a second key, divide by that same multiplier to recover the integer belonging to the 2nd key. If that value is in fact an integer you have discovered a multiplier! If it isn't an integer than the first integer was wrong and thus the multiplier was wrong.

for integer1 = 1 to Very_Large_Number

multiplier = key1/integer1;

integer2 = key2/multiplier;

if is_integer(integer2) then print "BINGO"

endfor

Obviously you have to define integer2 as a float. The critical function here is is_integer. It needs to flag x.9999 as well as x.0001 as close enough to an integer with a defined precision. I'll leave that to the reader to implement.

Of course using multiple keys vs each other makes it robust against typos. Lastly, you will also recover more than the greatest common denominator, because key = (integer1 * 6) * (multiplier/6) and a host of other small integers (that cancel each other out). So it requires a bit of sorting out, but you'll quickly spot the ones that belong together.

Let's do an example for the 5268AC.

password 9yw9mx6sj3wt turns into key1=1353921430411399943 (assuming the first digit is base8 not base37)

password 9u7ke7kz7r9w turns into key2=1335782341279950921

So you are merrily scanning integers until you hit integer1=1940033061 (in C++ you can scan billions in minutes single threaded)

multiplier = key1/integer1; = 1353921430411399943/1940033061 = 697885751.345657064037

then you do

integer2 = key2/multiplier; = 1335782341279950921/697885751.345657064037 = 1914041573.000032

1914041573.000032 is pretty close to an actually integer so perhaps 697885751.345657064037 is the multiplier.

Might as well verify say against password 39bh23v3qpf6 (key3=234888871301781004)

key3/multiplier= 336572097.72354 *sad trombone* that's not an integer at all!

There many more ways to turn a password into a key including changing the charset around, so I'll let the reader experiment with those! May be they are more creative than I and strike gold!