As an attempt to revive my blog a bit, here is some fun with ancient looking code taken from the series Stranger Things. Although the story takes place in the '80s and is not technical, there is a short scene in episode 8 of the latest season (currently season 2) where the character Bob hacks the door access system of a secretive governmental laboratory to allow them to regain control after a blackout.
At first, it has to be noted that this likely is no real code (running on the pictured computer). A strong indicator for this can be seen in the first image of this article: if you look close, you can see that the text overflows the right monitor bezel which is probably because the source code was added in post-production. But nevertheless there are a lot of interesting aspects of the displayed code and it's a fun exercise to analyze it. Of course, I'm not the first person trying to analyze this code. I've stumbled upon a German blog post which also describes the hack of the door lock system. The blog post also links to a Reddit thread on /r/geek where this code is discussed (Spoiler Alert: I've also posted some of the following contents there). I'm trying to summarize these two sources and add further insight.
A close look to the sticker on the right side of the bezel clearly shows the letters IBM, so it is some kind of computer manufactured by IBM. An even closer look (like really close) shows something like a model number beneath IBM’s logo. With a bit of trial and error, Wikipedia and the power of search engines I found the pictured computer: It's an IBM 3180 Display Station terminal. This means that the computer very likely is connected to some kind of mainframe and only is the terminal operating another larger machine. Unfortunately, this makes it harder to find out what kind of computing system this should be, but the following chapters will take a closer look nevertheless.
Throwing the image into good old Photoshop and twiddling with some settings to enhance and rectify the source image reveals this closeup of the code:
For convenience I've transcribed the code true to the original:
10 DIM FourDigitPassword INTEGER 20 FOR i = 0 TO 9 30 FOR j = 0 TO 9 40 FOR k = 0 TO 9 50 FOR l = 0 TO 9 60 FourDigitPassword = getFourDigits (i,j,k,l) 70 IF checkPasswordMatch(FourDigitPassword) = TRUE THEN 80 GOTO 140 90 END 100 NEXT l 110 NEXT k 120 NEXT j 130 NEXT i 140 PRINT FourDigitPassword 150 END
So the first thing to notice from the code are the numbers at the start of each line. The only programming language I know of, which uses this kind of structure, is BASIC and the other sources seem to affirm this strongly. Also, the use of BASIC perfectly fits into the time the series takes place. As a side note: You probably notice that the lines numbers jump in steps of ten. This is because BASIC heavily relies on
GOTO statements with line numbers instead of labels for program control (for example in line 80).
But there are also some things which seem off:
The code is shown with lower and upper case letters (also known as CamelCase or PascalCase) to increase readability. While using lower and uppercase letters is common for most – if not all – modern programming languages, this likely was not possible for computers back in the '80s, simply because the fonts back then only supported upper case letters which is probably also the case for this terminal.
Another thing to notice is the indentation: While this also is common for modern code, this was not common for BASIC code back then. Even for modern code, this indentation style would be a bit weird, as it uses an irregular number of whitespace characters for each level. Modern code would use multiples of a constant for each indentation level, e.g. 4 spaces for the first level, 8 for the second, 16 for the third and so on. The code shown in the screenshot seems to use 4, 5, then two times 6 and finally 8 characters for each subsequent level.
Another outstanding fact about the code is the use of subroutines or rather functions. The code calls two function:
getFourDigits (line 60) and
checkPasswordMatch (line 70). For modern programming languages this is also nothing special, but again to BASIC this is rather uncommon.
So we analyzed how the code looks like, but what does it actually do? Of course, this can be inferred from watching the episode (Spoiler Alert): It somehow obtains the access code to regain control over automatic door locks after a power outage. To achieve this, the code performs a so-called brute force attack on the four-digit password prompt which basically means that all possible combinations are tried until the right one is found.
Starting in the first line, the code initializes a variable called
FourDigitPassword which will hold an integer. The name of the variable gives away its purpose: It will hold the final password to access the system.
To get this password, there are four nested loops which each count from 0 to 9. Each loop stores the value of the current iteration in a variable (
In the body of the innermost loop, these variables then get passed to the function
getFourDigits (line 60). From the shown code it is not clear what this function does, but it is very likely that it assembles the digits from each loop to a single four digit number and returns it. This number is then stored in the variable
FourDigitPassword which was previously initialized in line 10.
The next three lines (70, 80, 90) are the core of the code: Here another unknown function
checkPasswordMatch gets called with the
FourDigitPassword as the parameter. It is quite obvious that this function returns a boolean value as it is used in an
IF statement. This function likely tries the generated password against the security system and returns
TRUE if it succeeds or
FALSE otherwise. If the password matches, the body of the
IF statement gets executed which makes the code jump to line 140 to print out the found password and the last line (150) will then simply end the program. If the password does not match, this jump will not happen, but instead, the innermost loop will increment its variable
l by one and the digits will be assembled again and also checked against the system. If the innermost loop reaches 9, the parent loop will increment its variable and so on. This simply represents counting from 0000 to 9999 while checking each iteration against the security system.
This code is totally fine, but it could be done without the four nested loops, which will get cumbersome if the password has more digits. Therefore a simpler solution is to use one loop to cycle through all numbers and prepend leading zeros to fit the digits. Another solution is suggested in the Reddit thread mentioned at the beginning of this article:
FOR X = 10000 TO 19999: FourDigitPassword = RIGHT$(STR$(X),4)
"Each iteration is yielding the 4 least significant digits. It’s simpler than a bunch of nested loops and yields the same result. First iteration would give “0000”, then “0001” and on to “9999”" Remark: "If he limited the upper number to 9999 any number less than 1000 would have less than 3 digits in it. Instead he starts at 10000 to achieve a constant four digits."
Compiling and running the code
Now that we know what programming language this is supposed to be and what the code is supposed to do, it would be nice to actually run it. The problem is, that there is a huge amount of dialects and other variants of BASIC. As seen in the previous chapters, there are quite a few hints given by the syntax and maybe the age also helps. Of course, Wikipedia has a list of BASIC dialects, but it's huge and comparing the features would be very cumbersome. So the question is: Which BASIC is used in the film? I tried to look at some of them: PC-BASIC, BASICA, (IBM) Cassette BASIC while looking for criteria like
DIM being used for variable declaration with data type given (line 10) and functions (line 60 and 70) – without success.
Unfortunately, I did not find a historic version of BASIC which matched these criteria, so I tried to find a fairly recent BASIC dialect which can be installed on a modern system. FreeBASIC seems to be quite popular and has all the required features. There was one little surprise, though: FreeBASIC seems to have no interactive interpreter but compiles the source code to a native binary. This is also fine, so I put the untouched source code transcribed from the screenshot into a text file and fired up the compiler.
Of course, the code did not compile. There were a lot of deprecation errors which could be fixed easily by adding the suggested parameter
-lang deprecated. After that, there was a small issue with the variable declaration in line 10: FreeBASIC requires an
AS between the variable name and its type. The compiler also complains about an expected
END IF in line 10 instead of the
END. These issues were very easy to fix.
Next came the undeclared functions
checkPasswordMatch(). The episode does not show more code than seen in the screenshot, therefore the code must be pulled out of thin air. Luckily these functions have pretty descriptive names and their usage also implies how they should behave roughly. With the help of the FreeBASIC documentation and some examples, I was able to implement these functions consisting of a header file and a file containing the implementations.
My header file (
strangerthings-api.bi) looks like this:
DECLARE FUNCTION getFourDigits (k AS INTEGER, h AS INTEGER, da AS INTEGER, n AS INTEGER) AS INTEGER DECLARE FUNCTION checkPasswordMatch (p AS INTEGER) AS BOOLEAN
And the implementation of those functions was implemented as follows (
FUNCTION getFourDigits (k AS INTEGER, h AS INTEGER, da AS INTEGER, n AS INTEGER) AS INTEGER RETURN k * 1000 + h * 100 + da * 10 + n END FUNCTION FUNCTION checkPasswordMatch (password AS INTEGER) AS BOOLEAN RETURN password = 1337 END FUNCTION
Compiling the modified code from the screenshot together with the implementation of the missing functions now successfully compiles! And even better: The produced binary also works and is able to "brute force" the password.
If you want to reproduce this little experiment, here are the steps I took. Note that I've used Alpine Linux in a virtual machine as the compiler for FreeBASIC, unfortunately, is not available for macOS. For other Linux distributions, the commands will differ a bit (e.g.
apt-get install instead of
apk add and the steps to fix some libraries also might not be necessary).
Download the FreeBASIC compiler:
wget "https://sourceforge.net/projects/fbc/files/Binaries - Linux/FreeBASIC-1.05.0-linux-x86_64.tar.gz"
Extract the tarball:
tar xvf FreeBASIC-1.05.0-linux-x86_64.tar.gz
Install the binaries to
./install.sh -i /usr/local
For Alpine Linux some dependencies to run the compiler are missing and need to be installed manually:
apk add ncurses ncurses5-libs ncurses-dev
Alpine Linux uses musl libc instead of the GNU C library (glibc), but FreeBASIC expects the latter to be installed. Luckily a symlink from the missing library to musl libc seems to work:
ln -s /lib64/ld-musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
Also, another dependency for FreeBASIC seems to be missing which also can be solved by another symlink to libncurses:
ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
Finally, the compiler can be used to create our program used in the Stranger Things episode:
fbc -lang deprecated strangerthings.bas strangerthings-api.bas
Although the code shown is obviously not flawless (as outlined), it actually is pretty close to a real BASIC program and even runs with very minimal modifications (and additions of missing parts) - at least in a modern version of BASIC. This level of detail in a series where programming and technology are of no big importance is very laudable because it adjusts the ridiculous picture of programming and hacking in most other Hollywood productions. I hope other productions will follow this attitude and add this level of detail to computing-related props. If you found this article interesting (or not) and would like to comment on it or found some mistakes (typos/grammar/content) feel free to contact me.