Anyone who spent a bit of time archiving software distributed on floppies probably knows this situation: There’s only one disk set of a given software release known to exist, and it’s not clean. That is, it’s been previously used to install the software and the installer scribbled something on the floppies, like the user’s name or a serial number.
Restoring the disks to a virgin state is desirable, but that’s easier said than done. There are easy cases like the OS/2 installation boot floppy: The installer creates a file named INSTALL.LOG and writes a couple of things to it, but does not modify any existing files. Such behavior is relatively harmless because the additional file can be simply ignored, or all traces of it can be thoroughly erased.
LAN Manager 2.1 and 2.2 is in a different category. The setup program “burns in” the user name, modifying a file on one of the installation disks. That is far more difficult to undo because an existing file’s timestamp is changed and the contents modified. Restoring original content is rather difficult because it’s not at all obvious what it had originally been. Although having just one “clean” set of LAN Manager disks helps.
LAN Manager 2.1 Licensing
In LAN Manager 2.1, Microsoft implemented a new licensing scheme which relied on overwriting a special block of data in the file called SERVICES\NETSVINI.EXE. This is the “root” service without which LAN Manager can not run. The data block serves two purposes: Copy protection and license management.
The copy protection is very lightweight and only consists of “burning in” the user name and installation date into the executable. Licensing is much stricter and limits the number of connections to a server. Microsoft sold 10-user license packs ($995) which increased the server’s capacity; these could be purchased and installed multiple times through the ADDPAK utility. Microsoft also sold unlimited upgrades ($5,495) which removed the connection limit entirely, or rather set it to 1,000 users.
I primarily focused on the user registration in my analysis. When the LAN Manager setup is first run, it asks for the user name and writes it to the NETSVINI.EXE file on the OS/2 Workstation disk. This file is copied to all installed machines. On a subsequent install, setup no longer asks for the user name and just uses the existing information.
The user name is scrambled such that it cannot be easily found in the NETSVINI.EXE file. Modifying it is naturally even harder.
Analyzing the LAN Manager setup utility revealed that Microsoft pulled out the big gun for this—DES encryption. Note that LAN Manager 2.0 already used DES for calculating password hashes and optionally encrypting traffic.
On the OS/2-based server and workstations, DES encryption/decryption API was implemented in a kernel component and accessed through an IOCTL in order to make snooping more difficult. This was of course not available to the setup utility, therefore LAN Manager’s SETUP.EXE has its own DES implementation.
From a modern perspective, the use of DES for encrypting the user name is a waste of time. Why? Because LAN Manager uses a single hardcoded key for it. The use of DES serves only to obfuscate, something which could be achieved through much simpler means. Once you fish out the key out of the SETUP.EXE executable, the user registration data has nowhere to hide.
Well, almost. Even after I had the encrypted data and the key, it still took me quite a while to decrypt it using a standard DES implementation. Although DES is outdated, it is real crypto… which means that if you get a single bit of the key wrong, the result will be complete garbage.
The troublemaker turned out to be the format of the DES key. The standard DES algorithm uses 56-bit keys, but these are usually supplied as a 64-bit key where the low bit of each byte is ignored.
Given how LAN Manager turns passwords more or less directly into DES keys, Microsoft did not want to toss out the low bit of each byte, so that “PasswdB” would not be equivalent to “PasswdC”. Instead, Microsoft packed the DES key into 7 bytes (56 bits); before feeding the key to the DES algorithm, LAN Manager inserts one dummy bit for each 7 bits of the input, thus obtaining a 64-bit key for DES.
What this means is that when the DES key hardcoded in the LAN Manager setup is used with a standard DES implementation, it will produce garbage. It has to be first spaced out and have dummy parity bits inserted. Once that’s done, a standard DES implementation (e.g. the one in the Python Crypto module) works just fine.
Data Structure Details
The above mentioned data structure is stored in NETSVINI.EXE. It has a header with a ‘LMPI’ signature—perhaps that stands for LAN Manager Product Information? The format is roughly as follows:
Offset | Size | Contents |
---|---|---|
0 | 4 | ‘LMPI’ signature |
4 | 2 | Unknown, zero |
6 | 4 | ‘LMPI’ signature |
10 | 24 | Product/serial |
34 | 36 | User name |
70 | 4 | Installation timestamp |
74 | 2 | Number of additional licenses |
76 | ?? | Additional licenses |
This structure has at least three users: The SETUP.EXE utility, the ADDPAK.EXE utility, and NETSVINI.EXE itself. As far as I can tell, SETUP only touches the user name and timestamp. ADDPAK updates the additional licenses. NETSVINI uses the product/serial and additional licenses to calculate the licensed connection limit.
The field I named “product/serial” looks about like this: ‘096-045v210-xxxxxxxx’; that is literally ‘xxxxxxxx’. I suspect the original idea was to put the LAN Manager serial number in there, but Microsoft appears to have decided against it and left a sequence of ‘x’ characters in place of the serial number. The middle part (‘045v210’) is significant because it determines the LAN Manager version and the maximum user limit.
If additional licenses are installed through the ADDPAK utility, those will be stored after the encrypted user name and timestamp. The additional licenses do include a complete serial number. That was an inevitable requirement, because otherwise users could install additional 10-user licenses several times. The serial number was a way of preventing that.
Lies and Half-Truths
Microsoft published KB article Q77358 which describes the how Additional User Paks are installed. As far as I can tell, the description might perhaps fit LAN Manager 2.0. It definitely does not apply to LAN Manager 2.1/2.2. I have one LAN Manager 2.1 unlimited user AddPak and it most certainly does not create ADDPAK.SER, but rather installs the additional license into NETSVINI.EXE, as described above.
While I cannot test it, I am almost certain that additional 10-user licenses are installed in exactly the same manner on LAN Manager 2.1/2.2, by modifying NETSVINI.EXE, rather than creating or modifying a separate ADDPAK.SER file.
As an aside, LAN Manager 2.1/2.2 can also be installed as a peer server/workstation. In that case, NETSVINI.EXE is not used, and a separate NETPSINI.EXE (PS for Peer Server) is used instead. NETPSINI.EXE does not include the ‘LMPI’ data block, the installer does not ask for user name, and the connection limit cannot be changed.
Examining Registration Data
I slapped together a simple Python utility which lets one view the registration information in LAN Manager. It looks for the LMPI header and can be used on NETSVINI.EXE or on a (raw) floppy image containing NETSVINI.EXE (which, unlike other files on the installation disks, is not compressed for obvious reasons).
The utility requires the Crypto module. If not already in place, this can be typically installed with ‘pip install pycryptodome’ or equivalent, depending on the host OS.
Here’s an example output from running lmcrypt.py against NETSVINI.EXE from LAN Manager 2.1 and upgraded to unlimited connection through ADDPAK:
LMPI signature found at file offset 0xbef6 Product ID: 096-045v210-xxxxxxxx Registered to: OS/2 Museum Timestamp: 1638040400 (2021-11-27 19:13:20) Number of AddPaks: 1 AddPak serial: 096-244v210-72201277
See the Python source code for details. Note that the implementation is based on guesswork and may be inaccurate. Modifying the registration data is intentionally left as an exercise to the reader.
When I was a teenager, I was loaned the latest hotness of Microsoft Office – version 4.3 – which happily installed – but all About screens insisted it was registered to someone at Kone Cranes. Examining .INI files revealed nothing, so I decided to take a look at the original install disks.
Turns out those early versions of Office did something like this – it was more like the LM2.0 method than 2.1 though. I seem to recall (so I could be completely wrong!) it edited an NE file on Disk 1 (the giveaway being the different date stamp on said file), implanting the registration information into the resource section of said file.
So, taking, a chance, I pulled out a hex editor, identified the same part of the resource section of WINWORD.EXE, and copy-pasted it into the modified file. One could say I was pretty chuffed with myself when I re-ran Office Setup, and it asked me for my name and company. π
Interesting. Word 6.0c definitely puts the registration information in an .INI file on the installation floppy (somehow scrambled, didn’t try to figure out how). On the installed system, it’s almost certainly stored in SETUP.STF, possibly somewhere else. The executables don’t have modified timestamps but I haven’t checked their contents.
Windows 95 put it on disk 2 which is a DMF disk
“There are easy cases like the OS/2 installation boot floppy: The installer creates a file named INSTALL.LOG and writes a couple of things to it, but does not modify any existing files.”
Though nowhere near the extremes that LANMAN goes through, nevertheless I seem to recall that there is at least one release of OS/2 — the 2.1 FullPak “Upgrade Edition” (and possibly 2.0 Upgrade as well; haven’t checked that one) — that *does* modify existing files on Disk 1. As I recall, the very first time you run the installer, it runs an upgrade eligibility check by looking at files on your hard disk. If it deems you eligible, I believe it modifies one of the binaries (can’t remember which one, or whether it was an EXE or DLL…will have to trawl through Usenet archives again to remind myself!) to neutralize the eligibility check so that it never re-runs it for subsequent installations.
At that point, as I recall, the files on the modified Upgrade Edition Diskette 1 are then bit-for-bit identical to those on the regular Diskette 1. So it’s actually kind of the opposite of the LanMan and Office experiences described above: the self-modification REMOVES copy-protection-esque mechanisms! And one could argue that it actually makes the disk contents more valuable than they were originally since it just “converted” itself from an Upgrade Edition to a non-Upgrade copy, so very few people likely actually care that the original bits were lost in the process.
I’m also pretty sure that for CD-ROM releases of OS/2 2.1 FullPak Upgrade, the included CD was in no way different from the one that shipped in the regular 2.1 box (down to the IBM FRU / P/N). Which also meant that the disk image for Diskette 1 included on the CD was already the non-Upgrade version. So if you wanted to bypass the eligibility check (which was easy enough to satisfy on its own, really…), you could simply overwrite the contents of the Diskette 1 that shipped in your box with that of the image file from the CD.
I guess the hardcoded key is why it is not subject to export restrictions, right?
βDES encryption/decryption API was implemented in a kernel component and accessed through an IOCTL in order to make snooping more difficult.β
I wonder if it is also to make hardware acceleration easier.
It would have, although I don’t think there was any hardware support available. Couldn’t find any mentions of it at least.
I would think so, although I don’t know if export restrictions were the reason for doing it the way Microsoft did. It’s a possibility.
Thinking about, projects like Samba would not work well if DES source code could not be exported in 1999, right? I wonder if the problems with exporting DES source code was why the export restrictions were lifted so quickly.
Re export – not sure how Samba did but in general the solution is simply to develop the encryption part of the code outside of the area that imposes an embargo on other parts of the world.
Also SMB has fallbacks to lower encryption levels. IIRC this was one of the reasons for various safety problems during the years.
Yes, developing the crypto outside of the US gets around the embargo because then no one in the US is exporting.
Falling back won’t get you far. The old DES based LANMan authentication is very old.
Of course, I am talking about when the export restrictions were raised from 40-bit to 56-bit
Windows 3.1 is somewhere in between – it modifies the file SETUP.INI, usually on Disk 3 or 4. However, all that stuff is ignored completely when installing it from something other than floppies.
Merry Christmas!
Thanks Jason, and likewise!
Cue everyone’s feeds churning…
Happy holidays everyone (in as far as observed) π
Cue everyone’s feeds churning… </Scrooge mode>
Happy holidays everyone (in as far as observed) π
At the time NT4 SP4 were just released that introduced NTLMv2 which is based on HMAC-MD5, but..