boginw / zyxel-vmg8825-keygen

A key generator for Zyxel VMG8825-T50
GNU General Public License v2.0
17 stars 6 forks source link

Is old algorithm admin zyxel password correct? #5

Open drsn00ker opened 1 year ago

drsn00ker commented 1 year ago

Has this been confirmed that the emulator actually gives the correct admin password for the router?

I've got the qemu-arm-static running in debug mode while monitoring in IDA64. Just completed the old zyxel admin algo (param 1) and get the same answer that shows up on the emulator. However, it is nothing like the other zyxel algos that makes me wonder if Maximus (author of the emulator) made an error in the implementation. Specifically the salt after the first MD5....

Apologies, Matlab is my preferred languange, but my code is below. You can see the salt is "inputKeyAccoundPassword" follow by a byte vector instead of ASCII hex of the digest. That inputKey comes outa nowhere.... (well from the function call upstream)

I'll play with the other modes tomorrow!

`function password=old_admin_zyxel_password(sn);

digest1=hasher(sn,'MD5');

input_string2=['inputKeyAccount_Password' digest1]; %digest is byte vector here; digest2=hasher(input_string2,'MD5');

base=int32(digest2(1))*256+int32(digest2(2)); %default base is 48206 base_binary=fliplr(dec2bin(base,16)); % convert to binary and flip lowest significant bit the left side for default: 0111001000111101

%disp(char(mod(new_md5_hash(1:16),26)+97))

key2=''; for i=1:16, if base_binary(i)=='1', c=mod(digest2(i),26)+65; %modulo 26 if the bit is a 1 else c=mod(digest2(i),10)+48; % modulo 10 if the bit is a 0 end key2=[key2 char(c)]; end

bad_chars='125690IOSZ'; % negroni from Zykgen. filler='3478ABCDEFGHJKLMNPQRTUVWXY'; filler_mod=26; % length(charset)

for position=1:16, letter=key2(position); bad_position=find(bad_chars==letter); %get position of bad letter in the haystack

if not(isempty(bad_position)) % found an unwanted letter, time to replace
    new_letter=filler(1+mod(base+bad_position(1)-1,filler_mod));  % bad_position(1) in case there is more than one entry in the haystack
    key2(position)=new_letter; %overwrite with allowed letter
end

end password=key2(1:8); `

drsn00ker commented 1 year ago

Just confirmed in the python version, that the digest2 is already correct. So the difference between my matlab version and your python code is actually after the hashes. It's in the conversion of the 2nd hash into the password string. You must be sooo close. Just a little bug in there somewhere....

drsn00ker commented 1 year ago

Figured it out. In functions/GenKeyBySerialNumConfigLengthOld.py line 31 should be: strAsInt = (md5Result[0] << 8) + md5Result[1]

drsn00ker commented 1 year ago

Serial numbers that start with S19 and newer use a different algo for the new admin passwords that's based on method2 and method3 with a change in the character substitution afterwards. I'm sure you can figure those out so you'll have green check marks all down your dashboard!

redhatperl123 commented 1 year ago

@drsn00ker I am trying to get password for my device which has serial S210Z3xxxxxxx However, the keygen does not seem to generate correct password. Any pointer on how to generate Supervisor for that serial?

drsn00ker commented 1 year ago

Did you try the keygen on openwrt: https://openwrt.org/toh/zyxel/nr7101 It's the complete version. This github repository hasn't been completed yet. You might have to edit out the sed pipe in the bash script.

redhatperl123 commented 1 year ago

Did you try the keygen on openwrt: https://openwrt.org/toh/zyxel/nr7101 It's the complete version. This github repository hasn't been completed yet. You might have to edit out the sed pipe in the bash script.

I have tried it but the generated password did not work on my device. Any help would be greatly appreciated!

drsn00ker commented 1 year ago

If you do it correctly, you should get 12 different passwords. Did you try all 12?

redhatperl123 commented 1 year ago

If you do it correctly, you should get 12 different passwords. Did you try all 12?

Yes, I removed the piped command for old algorithm and tried all 12, but unfortunately none of them worked.

drsn00ker commented 1 year ago

Well, you can either wait for somebody to post some new algorithm, or you can dump the nand, find the /etc/shadow and run hashcat to crack it. But the password is probably 10 char, ?u?l?d so that would take years to crack.

But my OP question stands, not sure if the algo is implemented correctly.... You could play around with the salt. It might gave you a password that does work! I'd try plain "AccoundPassword" as the salt. I'd also try the hex-string of the digest, before and after the salt, instead of the byte-vector. Make sure you implement the correction in line 31!

boginw commented 1 year ago

Figured it out. In functions/GenKeyBySerialNumConfigLengthOld.py line 31 should be: strAsInt = (md5Result[0] << 8) + md5Result[1]

That's fantastic! I will look it over later, but you are welcome to submit a PR so you can get some credit

spinalgr1990 commented 1 year ago

I am trying

python ./main.py S220Y33149988

drsn00ker commented 1 year ago

@boginw I don't need any credit. You did all the hard work! Besides, I'd have to study how to actually do a pull request. Never done one before...

spinalgr1990 commented 1 year ago

I made a new working script : Zyxel Root Password.zip

drsn00ker commented 1 year ago

@spinalgr1990 You should do the other supervisor and admin passwords as well!

Also looks like you've left in all the compiler added math that isn't necessary. Like (((round3[i] % 10) * 0x1000000) >> 0x18) + asChar('0') is just round3[i] % 10 + 48; "var" always ends up being zero, so you can just ignore that as well.

Manu99it commented 1 year ago

it seems that zyxel has since changed the algo. Newer routers with S21/S22+ don't have 1234 as default admin password, the admin password is the same as wifi password. And the script here or the complete algorithm in openwrt don't work anymore. (yes I tried all the 12 passwords). If anyone has found some way to still obtain the root password on these newer devices would be awesome

Aljutor commented 11 months ago

I can confirm that with S22 serial, non of 12 passwords works. It seems we need another dump for a newer firmware.

drsn00ker commented 11 months ago

None of the newer firmware seems to have the correct keygen included anymore... Just a place-holder algorithm.

spinalgr1990 commented 10 months ago

https://www.onlinegdb.com/XR_spa_we

drsn00ker commented 10 months ago

Well done! You always learn a lot implementing your own version of the same algorithm... You will learn even more if you convert it to a different language as you have to figure out the mathematics!

suprruser44 commented 2 months ago

any news for solution for S22 serials?

drsn00ker commented 2 months ago

A couple of local users with new Zyxel models managed to extract the file system from their respective routers. We already knew that the posted firmware on Zyxels website contain a place-holder algorithm, rather than the real one. With the files extracted from the physical routers we can also confirm that the same place holder algorithm is present on the router, again not the one used to generate the passwords. That leaves trying variations of the known algorithms in the hopes of getting lucky. I tried a bunch, but with hashes (MD5 and SHA256) you can be one bit away from the jackpot and not know it. So I'll invite anyone to try. The known zyxel algos are posted here with their model numbers. https://forum.hashkiller.io/index.php?threads/default-wpa-keyspace-work-in-progress.36607/post-343456 They are all in python, study them, and make some variations, may be you get lucky!

From looking at the statistics of the characters used for the new model (S22+), it matches the probabilities of the Zykgen 'm' May be they changed the salt ("PSK_ra0"), may be they changed the hash from SHA256 to something else. That's my best guess. So start there.

Manu99it commented 2 months ago

any news for solution for S22 serials?

In some s21/s22 serial devices you can still obtain the root password in this way if you have FTP access (in LTE5398-M904 for sure):

  1. Set up FTP in web GUI
  2. Access FTP as admin user and download zcfg_config.json
  3. Open it and copy the encrypted password under the root user (not the default password, that's the same that you can calculate with the emulator)
  4. Set up a fake DDNS in web GUI
  5. Download the backup file
  6. Open the backup file and replace the encrypted password under DynamicDNS with our encrypted password of root user copied before
  7. Now save and restore the file from webgui. Go to ddns settings and just read the password: it's clear

Reference

suprruser44 commented 2 months ago

any news for solution for S22 serials?

In some s21/s22 serial devices you can still obtain the root password in this way if you have FTP access (in LTE5398-M904 for sure):

  1. Set up FTP in web GUI
  2. Access FTP as admin user and download zcfg_config.json
  3. Open it and copy the encrypted password under the root user (not the default password, that's the same that you can calculate with the emulator)
  4. Set up a fake DDNS in web GUI
  5. Download the backup file
  6. Open the backup file and replace the encrypted password under DynamicDNS with our encrypted password of root user copied before
  7. Now save and restore the file from webgui. Go to ddns settings and just read the password: it's clear

Reference

When i access ftp,I find the two folders,but are empty ,no zcfg_config.json file

Manu99it commented 2 months ago

When i access ftp,I find the two folders,but are empty ,no zcfg_config.json file

Then probably it was patched on your model