Showing posts with label retro. Show all posts
Showing posts with label retro. Show all posts

2024-09-07

Cracking an old ZIP file to help open source the ANC's "Operation Vula" secret crypto code

It's not often that you find yourself staring at code that few people have ever seen, code that was an important part in bringing down the apartheid system in South Africa, and code that was used for secure communication using one-time pads smuggled into South Africa by a flight attendant on floppy disks. But I found myself doing that one morning recently after having helped decrypt a 30 year old PKZIP file whose password had long been forgotten.

Some time ago I became interested in the secure communications used by the ANC as part of Operation Vula in the late 1980s. Operation Vula was the infiltration of ANC leaders (and materiel) into South Africa to set up an underground network bringing together the various elements of ANC activism operating inside the country. 

The operation needed secure communications to be successful and these were established using 8-bit computers, DTMF tones, acoustic couplers and a variety of other equipment for exchanging one-time pad encrypted messages using programs written in PowerBASIC.

I won't go into the detail of how this worked as Tim Jenkin, the person primarily responsible for the encryption system, has now open sourced the original code, and which can be found here. Tim's write up on the encryption system can be found here. I thoroughly recommend reading it for the details.

The code hadn't been open sourced before for one simple reason: on leaving the UK for South Africa in 1991 he had zipped up all the source code and set a password on it. In the intervening years he'd simply forgotten the password! So, when I emailed him to ask if it had been open sourced he replied:

I still have the Vula source code but unfortunately most of it I can't access because when I left the UK in 1991 to return to South Africa, I zipped up all the files with a password. I was able to decode and extract one of the files but it was a very early version of the software. The rest I couldn't extract because I forgot the password. When I got back to SA there was no need to access the code. I thought I would never forget the password but when I tried to decode it a few years later, I couldn't remember it.

If you could find out how to decode zipped files that would release the software, which I would be more than happy to share. I have made a few attempts to crack the code but so far have been unsuccessful.

I readily agreed and he sent me two files: ALLBAS.ZIP and CODMAY93.ZIP. These were both created with an early version of PKZIP and had passwords set on them. Luckily, there is a known plain text attack against the ZipCrypto scheme used in that era's ZIP format. And an open source implementation of the attack called bkcrack.

So, it was a "simple matter" of predicting 12 bytes of plain text at a known location inside the ZIP file. Here's a sample of what's inside the ZIP file:

$ bkcrack -L ALLBAS.ZIP | head -n 20

bkcrack 1.7.0 - 2024-05-26
Archive: ALLBAS.ZIP
Index Encryption Compression CRC32    Uncompressed  Packed size Name
----- ---------- ----------- -------- ------------ ------------ ----------------
    0 ZipCrypto  Shrink      b0f86b1d          163          117 A1PSW.BAS
    1 ZipCrypto  Shrink      8fa662d4          163          118 A2PSW.BAS
    2 ZipCrypto  Shrink      0c5a7295          163          119 A3PSW.BAS
    3 ZipCrypto  Shrink      49907f86          179          125 A4PSW.BAS
    4 ZipCrypto  Shrink      3d20eb7a          163          120 A5PSW.BAS
    5 ZipCrypto  Shrink      f8b558f0          136          128 BIOS.INC
    6 ZipCrypto  Implode     799074ed          377          278 CHKERR.INC
    7 ZipCrypto  Implode     c44ea0a5        17906         5401 CODSUBS.INC
    8 ZipCrypto  Implode     7bd7e23d        27287         8297 COMAID.BAS
    9 ZipCrypto  Implode     03dc63da         2109         1001 COMKEY.BAS
   10 ZipCrypto  Store       3500d320         2372         2384 CONFIG.TIM
   11 ZipCrypto  Shrink      35a85089          147          111 CONPSW.BAS
   12 ZipCrypto  Implode     55be75ce         2094          825 DOS.INC
   13 ZipCrypto  Shrink      3387d043          134          127 DOSVER.INC
   14 ZipCrypto  Implode     28a32efa         1304          535 DOSX.INC
   15 ZipCrypto  Implode     6578a66c         3196          966 EDDY.BAS

Tim had some unencrypted .BAS files lying around but they were different versions than those in the file and trying the bkcrack attack using them (after running them through original PKZIP in DOSBox) was unsuccessful and I decided to apply some brain power before attempting further attacks.

ALLBAS.ZIP contained a number of files that were uncompressed, because they were already binary and not worth compressing. These files are marked as Store:

$ bkcrack -L ALLBAS.ZIP | grep Store
   10 ZipCrypto  Store       3500d320         2372         2384 CONFIG.TIM
   23 ZipCrypto  Store       14a285ac            2           14 KEYCOD.EXE
   25 ZipCrypto  Store       d6343ce1         4767         4779 KEYONE.ZIP
   26 ZipCrypto  Store       650778b7         6523         6535 KEYTHREE.ZIP
   30 ZipCrypto  Store       12a711cd        58172        58184 OLDCOD.ZIP
   41 ZipCrypto  Store       00000000            0           12 TAPCOD.EXE
   44 ZipCrypto  Store       55000714        12716        12728 TECOD5.ZIP
   45 ZipCrypto  Store       f4f4366c         9230         9242 TECOD6.ZIP

Files that are Store'd are fruitful for plaintext prediction because they have not undergone compression and there's no need to have the original file to compress in order to obtain plaintext. Focussing on the ZIP files, since the ZIP files start with a PK header, seemed like a good place to find predictable plaintext at a known position. Here are the fields in the standard PK header at the very start of a ZIP file:


A viable attack appeared to be to predict the name of the first file in the archive. If the file name was at least 8 characters (which seemed pretty easy since at least four characters were used for .BAS, .INC etc.) then at least 12 characters of plaintext would be available when the file name size (offset 0x1A, 0x1B) and the length of the extra field (which appeared to be 0x00, 0x00 in all the ZIPs Tim sent) was added.

In the worst case, it would be possible to bruteforce the potential names of files given that they all appear to be uppercase/number combinations with a maximum length of eight characters plus extension. But that turned out not to be necessary.

Happily, Tim had a different version of OLDCOD.ZIP (one of the ZIP files inside ALLBAS.ZIP) and was able to tell me that the first file in it was COMKEY.BAS. So, I whipped up a quick Perl program to create the necessary plaintext in that hope that the OLDCOD.ZIP inside ALLBAS.ZIP did start with COMKEY.BAS:

$ cat maken.pl
use strict;
use warnings;

my $outfile = "hexname-$$.txt";

while (<>) {
    chomp;
    my $bas = $_;
    print("$bas / $outfile\n");
    my $n = sprintf("%c\x00\x00\x00$bas",length($bas));
    open G, ">$outfile";
    print G $n;
    close G;
    system("bkcrack -C ALLBAS.ZIP -c OLDCOD.ZIP -p $outfile -o 26 -j 8");
}

23 minutes later bkcrack spit out the key to the ALLBAS.ZIP file and was able to decrypt it. The same key worked for CODMAY93.ZIP also.

$ time echo "COMKEY.BAS" | perl maken.pl

COMKEY.BAS / hexname-41227.txt

bkcrack 1.7.0 - 2024-05-26

[07:49:38] Z reduction using 6 bytes of known plaintext

100.0 % (6 / 6)

[07:49:38] Attack on 925073 Z values at index 33

Keys: 98e0f009 48a0b11a c70f8499

80.6 % (745571 / 925073) 

Found a solution. Stopping.

You may resume the attack with the option: --continue-attack 745571

[18:13:49] Keys

98e0f009 48a0b11a c70f8499


real 23m4.371s

user 162m3.520s

sys 0m37.752s

bkcrack does the decryption once the key has been found:

$ bkcrack -C ALLBAS.ZIP -k 98e0f009 48a0b11a c70f8499 -D ALLBAS-DECRYPTED.ZIP

bkcrack 1.7.0 - 2024-05-26

[07:52:22] Writing decrypted archive ALLBAS-DECRYPTED.ZIP

100.0 % (81 / 81)

$ bkcrack -C CODMAY93.ZIP -k 98e0f009 48a0b11a c70f8499 -D CODMAY93-DECRYPTED.ZIP

bkcrack 1.7.0 - 2024-05-26

[07:58:31] Writing decrypted archive CODMAY93-DECRYPTED.ZIP

100.0 % (40 / 40)


And with that the long encrypted source code used to help set up secure communications for the ANC was available!


Had that failed I was going to attack one of the other ZIP files using the same attack (before resorting to bruteforceing file names). I'd guessed that TECOD5.ZIP was probably a ZIP of just the file TECOD.BAS (or maybe TECOD5.BAS) based on the compressed size of TECOD.BAS in ALLBAS.ZIP). Turns out I wouldn't have had to wait 23 minutes if I'd started there:


$ time echo "TECOD5.BAS" | perl maken.pl

TECOD5.BAS / hexname-41544.txt

bkcrack 1.7.0 - 2024-05-26

[18:14:51] Z reduction using 6 bytes of known plaintext

100.0 % (6 / 6)

[18:14:51] Attack on 880113 Z values at index 33

Keys: 98e0f009 48a0b11a c70f8499

2.4 % (20737 / 880113)

Found a solution. Stopping.

You may resume the attack with the option: --continue-attack 20737

[18:15:29] Keys

98e0f009 48a0b11a c70f8499


real 0m38.152s

user 4m35.318s

sys 0m0.897s


The known plaintext attack against ZipCrypto works quickly with the right plaintext. If you ever have to do something similar it's worth spending time thinking about the plaintext. In particular, files that are Store'd in the ZIP file are useful to examine since they are uncompressed and it may be easier to predict their contents (rather than having to find an original file and compress it to match what's stored in the ZIP).


Running the code


I compiled two of the programs and ran them using DOSBox. The first, RANDOM.BAS, was used to create disks of random numbers to be used as a one time pad, the other, TECOD.BAS, was used to encrypt and decrypt messages sent via email. The code I compiled and the generated executables can be found here.


Compilation is simply running the PowerBASIC compiler as follows:


C:\>EXE\PBC TECOD.BAS PowerBASIC Compiler Version 3.00b Copyright (c) 1989-1993 by Robert S. Zale Spectra Publishing, Sunnyvale, CA, USA C:\TECOD.BAS 2575 statements, 2329 lines Compile time: 00:12.0 Compilation speed: 12600 stmts/minute 45984 bytes code, 4880 bytes data, 2048 bytes stack Segments(1): 46k C:\>EXE\PBC RANDOM.BAS PowerBASIC Compiler Version 3.00b Copyright (c) 1989-1993 by Robert S. Zale Spectra Publishing, Sunnyvale, CA, USA C:\RANDOM.BAS 2194 statements, 1940 lines Compile time: 00:10.1 Compilation speed: 12600 stmts/minute 33328 bytes code, 4704 bytes data, 3072 bytes stack Segments(1): 34k C:\>


The first step is to create random data on disk to be used as a one time pad. RANDOM.EXE uses three different randomness generating algorithms (one based on a random key you type in yourself).



Encryption and decryption is done through TECOD.EXE which is password protected. 


Although the password is embedded in the program and quite simple Tim Jenkin did obfuscate it as follows:

DIM PW$(PL)
PW$(9)=CHR$(66):PW$(4)=CHR$(66):PW$(1)=CHR$(84):PW$(5)=CHR$(79):PW$(2) = CHR$(73)
PW$(3)=CHR$(77):PW$(6)=CHR$(66):PW$(8)=CHR$(77):PW$(10)=CHR$(79):PW$(7)=CHR$(73)

In this particular version of the program that makes the password TIMBOBIMBO which when entered takes you to the main menu. Note that each version of these programs being sent to different members of the ANC had different passwords.

If you're interested in running these programs yourself, the manual is here.

Here are three short videos showing the creation of random data in RANDATA.1 for the key using RANDOM.EXE, followed by encrypting a message stored in PLAIN.TXT on a RAM disk (all crypto operations were meant to happen on a RAM disk) and turning it into PLAIN.BIN (and the reverse).

Creating random data to be used as an encryption key



Encrypting a file


Here the programs (TECOD.EXE/TECOD.CNF) are on a floppy disk in A:, the data disk (containing the key file created above) are in B: and there's a RAM disk on R:. To get this to work the RANDATA.1 file created in the step above needs to be renamed to SNUM. 



Decrypting a file


Here the programs (TECOD.EXE/TECOD.CNF) are on a floppy disk in A:, the data disk (containing the key file created above) are in B: and there's a RAM disk on R:. The RANDATA.1 needs to be called RNUM on B:. 


There are lots of interesting details of how these programs work that deserve another longer blog post when I have time. Or a detailed study by someone else. For example, the key material is destroyed after use, the RANDOM.EXE program has multiple ways of making randomness and code to check the distribution of the random bytes created. There's an emphasis on using the RAM disk for all cryptographic operations. 

2024-06-15

Acorn Computer Systems catalogue circa 1983

I unearthed a catalogue that I'd picked up in around 1983 of Acorn Computer Systems. This catalogue overlaps the BBC Micro era (which was released in 1981) as it goes up to the final Acorn System 5 (released in 1983).

The Acorn Computer Systems were based on the Eurocard format for PCBs that can be mounted in a standard chassis.


The Eurocard format meant that you could design a system for your needs, including handling Prestel/Teletext.


And, of course, you could add RAM.


A complete scan of the catalogue is available here as a PDF.

2023-12-19

Complete restoration of an IBM "Butterfly" ThinkPad 701c

Just over a year ago there was a discussion on Hacker News about the IBM ThinkPad 701c (the one with the lovely folding "butterfly" keyboard). In particular, it was a discussion about the incredible web site 701c.org which gives very, very detailed instructions on how to dismantle, restore and preserve those lovely machines.

In the discussion a chap said: "I have two in non-working condition, pretty beat up. If I can make someone really happy and they want to restore them, feel free to send me an email. I wanted to do it myself for the last 10 years it so but realistically know I won’t. I’m based in NL." And I figured, he's not too far from me, maybe I could get them and create one restored machine from them.

A year later my fully restored (and memory upgraded!) IBM ThinkPad 701c is finished. Here it is:

It was a long journey to get here. I've written before about the painstaking operation to repair a damaged ribbon cable for the pointer. 

This blog post is a deeper dive into going from these two machines (see below for representative pictures of the mess they were in) to the picture above. Everything I know about restoring this machine came from the 701c.org website and a couple of emails with its creator. Without him this would not have happened. Thank you!




As you can see everything is a mess. The batteries have leaked and damaged the cases, screws are missing, parts are warped, covers are missing, the rubberized paint has become a sticky mess. But at least one of the keyboards seems to be OK (but see above about the ribbon cable!).



One of the machines would actually power on with nothing on the display. The other was totally dead. Time to dismantle the two and see what's salvageable.

Dismantling 

The 701c.org site and the IBM manual and video it links to have detailed instructions on how to take these machines apart. As I took them apart case pieces that had been soaked in battery goo just broke away in my hands. So taking them apart was a slow and delicate operation. Here are some internal pictures during that process.


One of the machines was an IBM ThinkPad 701cs (which has a less capable screen than the 701c). In addition, the screen frame just cracked apart as I was removing it. But it did have a working modem:


Both machines had extensive damage from the batteries having leaked:



The state of the batteries once I had managed to remove them from the cases:



This battery goo had damaged one bottom case to the point that it was crumbling in my hands. Luckily, the other case had survived:


Between the two machines I had enough pieces to make a single machine. The major case parts were there (they "just" needed stripping and repainting) and I had a complete set of screws as well. The screws matter because some of them are T1 torx screws (not something you want to mislay). 

Before trying to see if I could get the machine to boot into anything I first needed to clean up the battery mess.

Cleaning up battery leakage

As you can see above the batteries had leaked inside the laptops and made a mess. Via a very slow process of using 90% isopropyl alcohol (IPA) and a sharp tool and a toothbrush all that material was removed and with a multimeter I was able to verify that all the connections were good and there were no shorts.

In the end the terminals ended up looking something like this:


You can see how the metal has been damaged but luckily the connectors are still intact. I also washed all the circuit boards with 90% IPA and replaced the old Kapton tape. Since I was going to end up building a frankenmachine I stuck coloured stickers on parts. Throughout the photos you'll see little red and green stickers indicating which original machine the parts came from.


Why no screen?

One question that got immediately answered on dismantling the machines was "Why does one machine power on but have a blank screen?". Answer: because someone has completely removed the screen connector. I suspect one machine might have been used as a source of parts at some point.


Happily the other machine had a cable and so I was able to take multiple parts from different computers and create something that starts.

Finding a combination of parts that work

On first boot the frankenmachine complained about three things: memory, date and time and CMOS.


All of those things are actually symptoms of the same thing: the CMOS battery is dead and has lost settings and the machine has lost its way. But it's a simple fix! Hitting ESC allowed me to run diagnostics on the machine:


It had a lot to complain about but was bootable and even managed to get into Windows 95 (for a while). It would subsequently crash because there was a problem with the machine not knowing how much RAM it had (8MB!).

Fixing the CMOS battery

To stabilize the machine it was essential to replace the CMOS battery. It's pretty simple fix (see the 701c.org page for details).

Old battery before removal:


New battery installed:


(It was also around this time that I did the delicate ribbon cable repair for the keyboard) With the new CMOS battery in place the machine was no longer complaining about CMOS troubles.


And a run through the configuration utility and the machine was 100% stable and usable. Which brought me on to the most painful part of the operation: stripping the paint off the case. At was at this point that I began to question ever having started this project.

A total pain: stripping and repainting

Once again the 701c.org site will really take you through the process, but it's a lot of work. I couldn't get the same stripper and paint as I'm in Europe so I ended up using Tamiya TS-6 Matt Black Spray Matt and Tamiya TS-80 Flat Clear Spray Matt for the case. I stripped it using BRUTUS graffiti and paint remover.

I highly recommend having a pack of different grades of sandpaper and plastic razor blades.

Rubberized paint bubbling from the graffiti remover.


Scraping off rubberized and dissolved paint using a plastic razor blade.


Time for sanding after scraping and graffiti remover seems to have done its job.


Masking before spraying.


Mid-spraying. I put on three coats of the black paint.


Left to dry for at least 48 hours.


Once painted and dried the case needed the decals re-applied. But along the way there were little touchups like re-chroming and recolouring the IBM logo for the lid.


And repairing the cover for the memory slot by gluing in place a little piece of plastic to replace the broken latch. And so on and so on.

Decals

I bought a pack of decals from 701c.org and there make a huge difference. You just have to apply them very carefully. If you're old enough to have used Letraset you'll be fine here. But work slowly and carefully.


Final reassembly

On both machines the metal that connects the keyboard to the bottom case had broken off. Once the battery leaks and swells it applies pressure to this joint and destroys it. Here I glued it back into place with epoxy and carefully melted what little plastic dots I could to hold it into place.


The screen can be reassembled as a single unit.


You'll notice here a PCMCIA Ethernet adapter in place. I bought from eBay a complete set of accessories: docking station, cables, floppy disk drive and this PCMCIA card.


There are a whole load of small but important things that have to be done in re-assembly: glue the speaker back in place, reinsert the battery lock and its tiny spring, insert the spring and cover for the power button, don't break anything. But you can follow the 701c.org disassembly instructions in reverse.

A final boot test before final reassembly. Just complaining about the lack of keyboard.


Once fully reassembled I had a fully working Windows 95 machine. 



But who can resist an upgrade?

A memory upgrade

The machine came with 8MB of RAM but is upgradable to 40MB. Happily, it's possible to buy the needed 32MB SODIMM on eBay. Just a simple matter of slipping it into the slot on the motherboard that's accessible from the back.

The SODIMM in place.


Yes, 40MB!

What's next?

Well, I haven't replaced the sleep battery (apparently, there's a company in Hungary that makes a replacement but they won't ship outsider Hungary). And I can live without the sleep memory mode and I actually disabled hibernate in the BIOS.

And I haven't replaced the main battery. I have all the parts but need access to a large 3D printer to print the case. One day.

And the machine doesn't have access to the Internet with this version of Windows 95. It has a helpful file called Internet.Txt that tells you what the Internet is! But it does have a modem and PCMCIA Ethernet so should be doable.

But, I'm ready. 

So with this machine I'm ready.


So ready for 1995.

(If you really like retro computing I have a whole web site just for that: Two Stop Bits).