-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Key Generation Knowledge Base / Forum #3
Comments
The check is exactly the same as in XP, only parameters are different:
for Retail keys,
for OEM keys. As far as I know, these parameters are the same for all editions except betas. (Upgrade keys differ from normal keys by the lower bit of Product Key.) |
Woah, that's amazing! Thank you! Also, how did you calculate |
No. MSKey4in1 knows nothing about Win98, and mskey.exe from the second comment just prints some hardcoded keys for Win98 (and some of them are not even valid, using '1' or 'A'). In fact, I have implemented and run Pollard's rho for these points and curve, but I don't want to share the code. |
I don't remember getting any garbage keys from the mskey.exe I sent. Why would you not want to share the code? It would be helpful, especially that you seem to know what you're talking about. |
Acquiring the private key and the order of the curve isn't sufficient but necessary to the generation process. Surely, though, the generation algorithm itself is different. Besides, I don't expect the Raw Product Key format to be the same either in Windows 98. Addressing the OP's question, you clearly must have extracted the pubkey from the pIDgen.dll, which you also should have the code for. That would be excellent learning material! |
well, mskey.exe has 47 keys in "Windows 98 OEM" group and maybe five of them are not valid win98 keys, and "Full"/"Upgrade" groups are much smaller and fully correct, so it does take some luck (misfortune?) to get one
Yet, it is literally the same except that different behaviour for ChannelID has only appeared in XP, so one does not need to worry about setting a "correct" BBB (in terms of README.md). Even the BINK resources have the same format, except that pidgen.dll was 16-bit back then, so finding the blob in the file is different - but once one finds the blob, its structure is the same (already with 32-bit fields). Rewind to 1995. Windows 95 has just been released, product keys have no cryptographic protection, and that is sort of bad. Elliptic-curve cryptography is either a thing from frontiers of science or some lunatic math depending on your point of view. Given a problem of protecting product keys that should nevertheless be reasonably short, Microsoft Research develops a cryptographic scheme that we all know. For 1995, it makes some sense. Fast-forward three years. Windows 98 incorporates the new scheme of cryptographically-signed product keys. Nobody cares because everyone just uses the same key. MS takes it as a sign that the scheme is good; everything else (Office/WinME/Win2k) uses the same scheme, only concrete numbers are changed (a key from win98 shouldn't be valid for win2k). Fast-forward another three years. XP introduces WPA, nobody wants to share keys anymore (okay, that is not exactly true, but it is true enough to make a pressure to find alternate ways; and "Devil's Own" VL key was banned after all), so people actually try to make keygens. Moore's law is good, ECC slowly expands its usage and becomes better known. The scheme is still cryptographically secure in the sense that nobody knows better-than-generic-blackbox-attacks, but suddenly it turns out that the parameters are just too small, and the generic attacks are within the reach, and even in two different ways. (One way is what this repository does: blackbox discrete logarithm for n-bit groups uses O(2^(n/2)) operations, it is not too much for n=55. Another way uses the fact that the check field is 28-bit, so a random key with a correct ChannelId has probability 2^(-28) to pass the check; just keep checking random keys until one of them passes, that requires 2^28 checks per key on average - I think computers from 2001 could do that in maybe several hours per key.) MS has noticed the keygens, but it is hard to totally redesign a cryptographic scheme on a short notice. For 2003 Server (and XP64 which is essentially 2003 Server with repainted wallpapers), they raised parameters as much as they could (and also introduced 10-bit server-auth field at expense of ChannelId that is encoded in more complicated way), which may have stopped keygenners for some time, but not forever. In Vista, the product keys are finally checked in entirely different way, it marks the end of this story. (I have not seen any discussion on how Vista does this.) (And in Win8, MS has entirely dropped client-side crypto checks for product keys, leaving only 10-bit CRC to prevent typos and hoping for server-side checks during activation.) But before that, everything used one of two variations (XP vs 2003Server) of the same scheme where the only things that differ are concrete numbers to plug in. |
That's a nice bit of history and explanation, I appreciate the in-depth look. However, why couldn't you want to release the code so that we can all generate keys for all editions? It would greatly improve the field and preservation ease, not having to rely on keys posted all over the place and having everything documented and easily accessible is always a plus. |
Could you elaborate on the server-auth (prefix) field and how it's related to the ChannelID? What exactly do you mean by more complicated encoding? I searched enough, but I couldn't find the Product ID <-> Raw Product Key relation for Server 2003, so it's still kind of a mystery. You very likely know much more. But most importantly, Server 2003 seems to be oblivious to the prefix (that server-auth field). I tested the code with that field generated with RNG and it works about half of the times, given the high bits are set. At first, I thought it was a SHA prefix, but if it actually serves a real purpose other than being salt, it might explain why the generation fails sometimes.
Vista abandoned the initial activation mechanism, it uses SLP 2.0 exclusively, which is rather easy to crack. People moved on from using keygens to instead emulating ACPI SLIC tables to trick Windows into thinking its activated. // Are there any papers/resources you could suggest on this particular topic, asides from the known MSKey 4-in-1 ReadMe? The code would MARGINALLY help too. You don't have to share it, but if you did it really would help everyone with understanding how to approach this task. Any help is appreciated! |
That's the point. The client never checks this field. That field exists so that MS servers (mainly activation servers, maybe update center servers) can distinguish between a true key and a generated one: if there is no code in the OS, then nobody can reverse-engineer how the field is checked, so any keygen can not do better than a random guess. On the other hand, if you don't care about MS servers, this field doesn't matter at all. XP keys don't have this field. In the initial release of XP, activation servers happily proceeded with anything that the OS itself accepted. First keygens have shown the weakness. Then, MS presumably has built a database of MS-generated keys - maybe only new ones starting from some moment? - and made activation servers contact this database; this closed the weakness, but presumably MS wasn't too happy - maybe maintaining such a database is a pain? - and decided to implement other measures.
You don't check the return value of
Patent US7512232: https://patents.google.com/patent/US7512232B2/en . XP keys have bitfields 1+30+28+55 for UpgradeOnly+SerialNumber+r+s, where SerialNumber is later split as |
That's what MSKey 4-in-1 stated, and that's exactly why I rerun the generator function if it returns an invalid point. Thanks for clarifying! I'm rather new to cryptography, so my intuition failed me when I thought squares should appear more often than not.
I guess I just didn't get what you meant by "encoding". A rather credible source I found today explained everything. It makes much, much more sense now. MSKey 4in1 Readme is just completely wrong. But that's what I assumed anyway. The final thing I don't entirely understand is how the signature scalar cap affects the discrete logarithm computation time despite the 512-bit curve parameters. It's relatively tangent to key generation, but it might help if you do know that as well. |
Speaking of that source you found, I've been trying to find the ECDLP software program they're talking about but the link seems to be dead and the wayback machine only archived the 404 page 🤦 Might this help? https://github.com/stefan2904/ecdlp-pollard |
Generic algorithms for discrete logarithm are bound by the order of the group in question. (And there are no specific algorithms for a random elliptic curve.) As an extreme example, consider a group of order 3, i.e. generated by a point Scalar cap must be close to the group order. If you just follow the standard signing, the resulting values will be capped by the group order. If you are willing to repeat a few times and take the minimum, then you can get a better bound (and MS does this, the limit for XP-style keys being 2^55 and the order somewhere between 2^55 and 2^56), but you can't get too far without astronomical number of retries. Number of all points on an elliptic curve modulo |
So I did extract the curve constants from the BINK of Windows 98, calculated order of the base point and the private key. Here's what I got:
I did not bother extracting the second BINK, but this proves your calculated data is correct.
The algorithm seems to be different. I plugged all my calculated Windows 98 values into the XP generator function (I even tried the inverse of the Private Key), but it did not work at all. The algorithm must have been different on Windows 98, I don't have any explanation to such behavior otherwise. P. S. I also tried the Server 2003 algorithm with calculated values for Windows XP x64. That failed as well. Update (fixed)It appears that my Windows 98 version required values from the second BINK, it worked with OEM values. |
Wow. You managed to get the ECDLP solver then... kudos. I didn't achieve it myself. Massive props! Now for the next steps, will you add all the XP/Server 2003 editions into the keygen? |
My friend nephacks did. It's pretty dang hard to find, so I uploaded the software to my website. You can download it here.
I would probably go for a generalization at this point. The BINK extraction and the order of the point isn't that big of a deal. I could probably implement that myself. The only actual problem at this point is that I don't have the discrete logarithm solution code. And more importantly, if I find one - it's VERY important to parallelize that task, which requires extra work and knowledge. |
Per my understanding of the situation, don't we already have all the pieces? E,g: with the ECDLP software, don't we already get the order and the private key? Isn't that enough to finish the keygen for all editions? As for the parallelization issue, is it really necessary? There are a total of 7 editions and 17 .pubs in XP.
|
Did you use a Program to extract that or you extract it yourself. I would like to get the code if it is a program |
Hey everyone wanted to jump in here with a few of my findings: Steps I took:
I also took a stab at modifying the sage script to input the ks2 files and output the job file for Mr. HAANDI's ECDLP Solver v0.2a (can be downloaded from https://dl.malwarewatch.org/software/advanced/ecc-research-tools/ ) If you download all of the above you will have 24 BINKs to play with and find k and n values. Then it is just a matter of matching up the BINK with a specific iso. Let me know if there are other file names I should look at or other iso directories! |
Is there a equivelent of PID on Office or other MS Products? |
MSKey 4-in-1 generates Office 2003 keys. That means the algorithm must be very similar if not identical. |
Appreciate it, man! These findings are in fact extremely helpful. I'll make sure to compile everything we found and learned into the README.md As an exercise, you may try finding pIDgen's and BINK's inside Windows ME / Windows 2000 / Office 97 / Office 2000 / Office 2003 image files. The image files listed in their respective order:
|
Look into BINKReader.py file in this repository, I wrote it in Python. |
An interesting thought, will it be able to generate keys for Neptune, Whistler or Longhorn Builds given their PIDGENs? |
The second-generation elliptic curve license validation mechanism has been present ever since Windows 98 and hasn't been changed until Server 2003. So that's a firm yes from me. |
Hello from HN! Wasn't expecting stuff like this to be cutting-edge, but I guess you're the first to both put in the effort and do it in public. I'd like to help if I can. My interest in old editions of Windows is for software preservation of PC-exclusive games. Not my project, but a sister project under the umbrella of TASVideos is PCem, specifically scripting the Windows installation process in libTAS+PCem so that machine images can be reproduced without distributing copyrighted material. A big problem for us at the moment is Windows 98 keys, which are easily found online but we're keen to avoid the ire and lawyers of Big Tech. I have some experience in C/C++, systems programming (on Linux), and reverse engineering, and I have a limited understanding of EC encryption from uni. My most relevant expertise would probably be in reproducibility, due to my knowledge of the Nix ecosystem. If you'd prefer to discuss over IM, I'm |
Which file contains the BINK on Windows 98 SE and ME? |
|
How to extract BINK from Win98 and WinME's |
I don't have this pidgen, but maybe try to look for a BINK header in the dll with a hex editor? You should see Then, the BINK file should start 0x10 bytes before this value, with a size of 0x170 bytes. |
Thanks, it was easy to find it with a hex editor by searching for that sequence and by also looking at a BINK hex "structure" from an XP version extracted with Resource Hacker. |
I loaded the 16 bit ones in ghidra and copied the hex strings of those resources into a hex editor and saved it |
Which files contains the BINK of Office (and also Office XP)? There doesn't seem to be a |
office 2000 has |
Let me post my findings: What doesn't: More detailed: Win 98 SE Memphis Win ME beta Win XP Whistler BINK ID00.ks2 Win 98 SE BINK1 ID02 Win Me BINK1 ID1C Win 2000 Pro SP3 BINK ID12.ks2 Win 2000 Datacenter BINK ID0A.ks2 Win XP Home SP3 BINK ID2A.ks2 Win XP Pro SP3 BINK ID2C.ks2 Win XP Pro SP3 VL BINK ID2E.ks2 Win XP POSReady 2009 Product ID 620 BINK ID0D |
I generated an interesting key for Longhorn 4074: Supposedly, this key has an "infinite" evaluation period (pid 105): {
"index": 7,
"bink": "00000074",
"pid_range": [
105,
105
],
"type": "Evaluation",
"days_to_activate": 0,
"days_evaluation": 2147483647
} I set the date a year forward and I can still login, but I have no idea if this is because of the key or not. |
How do you generate LH keys? |
I will PR support for x64/Longhorn/Server key generation to Neo-Desktop/WindowsXPKg once @Endermanch finishes refactoring. For the impatient, here is my testing Jupyter notebook: https://gist.github.com/WitherOrNot/e2f1f4a6b17a7ffcd7e2426c75bc2278 You will need an installation of SageMath to use it. |
Thanks. I would like to know is k and n value Found by the solver app? We can extract the other value but not these. |
For the record, none of these keys are unsolvable They may take up to about 20 minutes But if there are any that are more intensive, version 0.3a of the solver is GPU/CUDA assisted |
v0.3a CUDA is not usable, its CUDA SDK is too old for modern GPUs... |
Read the README file. |
unrelated and off topic: @WitherOrNot: I went ahead and sent you a signed email regarding communication outside of GitHub |
Thanks! Just sent my response |
This is correct, Server 2003 R2 x86 worked in ~5-10 minutes with ECDLP Solver v0.2a on a 5600x with PBO on, to be honest I saw
in the readme and didn't even try. I will try more "unsolvable" from above and will edit my comment |
For what its worth, |
I can't prove it but I'm the author of Back in 2002 there was a Slashdot article about a Windows XP keygen by TheBlueList. Someone posted a base64 encoded .zip of the .exe if you want to try it out (good old days when a keygen can fit in a comment and not removed as spam). It was slow so I figured it was using some kind of brute force. I eventually reversed the keygen (found the IDA .idb created Aug 2003). I was studying elliptic curves at that time so it was nice to find ECC in the XP product key. The signature verification was not something familiar, it probably took a week before I found it by chance in the Handbook of Applied Cryptography as the Schnorr signature. At that time they did not know the private key, thus the brute force approach. It was done by fixing a random signature then trying different PID values until the 28-bit hash matched. At this point I had a clone of TheBlueList keygen using my own ECC library and GMP. The private key seemed feasible to solve given the small order of the subgroup. The basic (non-parallel) Pollard's rho algorithm is simpler than the keygen, just 114 SLOC excluding the ECC library. The group order was found on my home PC; the private key on an internet cafe where I left the program running and got the result the next day (sorry). My keygen was updated to use the private key for signing instead of bruteforcing the hash. I sat on this for ~3 years until around 2006 when I first discussed my work on the AntiWPA forum. The old forum is gone but some of it got archived. That was the first time I became aware of MSKey4in1. My 2003 keygen was based on the README (I probably copied the EC parameters/private key from the .exe). I got in contact with cw2k who suggested to upload the XP and 2003 keygen sources on AntiWPA. I rewrote it to use OpenSSL instead of my ECC library. cw2k was also working on the beta version of Vista's pidgenx.dll but it was obfuscated. Speculation from PDB strings suggest the algorithm is a pairing-based short signature, confirmed here. If you read this thread, apologies for the unreadable code that looks like compiler optimizations. |
It would be pretty useful to know how Windows 98 (and all its editions) verifies its product keys. At first glance, it seems to be a pretty similar system to XP's. 98 seems to be an outlier in the retro Windows scene, as nobody has come up with a generator yet, whereas XP has this one and the versions before 98 use a simple algorithm with many GitHub repos implementing it, some in creative ways.
The text was updated successfully, but these errors were encountered: