The Z80 Adventure Part III

In my last post on this topic, I discussed improvements to my Z80 computer, which allowed the use of peripherals from within the Z80 OS. I recently rebuilt this computer, to allow for a bit more extensibility (and eventually, LED debugging).

Conceptually, this is similar to the last iteration, with an ATMega32A acting as a custom I/O port to the Z80, it’s gateway to the outside world. The address bus accessible to the ATMega has been reduced to 8 bits – the upper 4 bits weren’t being used, except for debugging (and we can debug with LED’s and a manual clock input).

To add wifi and disk support, I used the ESP-01 module: this acts as a WiFi bridge, so you can connect to it via netcat. It also supports a series of specially formatted (but human readable, for debugging) UART commands, which allow disk access:

The actual protocol is fairly simple:

  • !xx!yy!zz\r\n:
    • xx is set to 0xFF for read operations
    • yy is set to the low byte of the address bus.
    • zz is the data bus
    • This will wait for one byte – if it’s a “write-only” operation, like selecting the disk number, the byte will be treated as an “ack” and ignored. If it’s a read operation, like reading a byte from disk, the byte will be placed on the data bus (or routed as the ATMega sees fit).
  • !!! means an actual “!” is being printed over UART.

To correctly support replies, a change had to be made to the way the ATMega handled UART input. Previously, when the ATMega was simply bridging for the Z80, an asynchronous interrupt-based UART was fine – this was the way the Z80’s BASIC rom BIOS expected input. Here, we need to temporarily disable interrupts every time we want to wait for a response from the ESP-01 as part of a I/O operation, otherwise, your interrupt routine will consume your input:

char async_getchar()
	char tempByte;
	while(!(UCSRA & (1 << RXC)));
	tempByte = UDR;

Given the static nature of the Z80, all this occurs in one clock cycle – the clock is simply held, while the ATMega waits for a reply from the ESP module.

Finally, to connect to this system, we need to disable line buffering (stty -icanon; nc 23) before we use netcat, for characters to be sent correctly to the CP/M OS:

With this in place, the next step is to implement a working CP/M disk structure – but this can be fully implemented on the ESP side (which is, incidentally, a lot easier to program). I’m setting aside this project temporarily, to spend my time elsewhere. The code can be found on Github as usual.

Posted in Bards, Computers, Jesting | Leave a comment

Notes on RF Retroreflectors

Over the past few weeks, I’ve been spending some time learning about RF retroreflectors. The goal of this is to improve my understanding of the theory and application of RF in general.

An RF retroreflector is a device which takes a target signal, and when illuminated by a continuous wave of RF energy, amplitude modulates the wave as it’s reflected back:

The primary advantage of this device is that it doesn’t need power, and doesn’t “transmit” unless it’s actively illuminated.

Three primary resources exist for playing with RF Retroreflectors.

  • GBBPR2’s Youtubes, here
  • Mike Ossmann’s work, here
  • The Wakabayashi paper, here

All three are worth reviewing, and the entirety of GBBPR’s internet contributes are well worth watching. If you’re still out there, I hope you’re carrying out your good work still.

The concept of a RF retroreflector is simple: a piece of wire is used as a passive reflecting antenna, and a MOSFET controls it’s capacitance by connecting and disconnecting it to a ground plane. The device is trivial, and can be made as follows:

The MOSFET is flexible: I used a BSS138, but a standard 2N7000 works too. Select this based on the rise time, corresponding to the source signal you want to exfiltrate. A finished device looks like this:

The antenna can be any length, but a quarter-wavelength monopole is recommended from experimentation. More on this below.

We can use gnuradio to generate the illuminator wave, as follows:

Theoretically, the antenna should best modulate at it’s resonant frequency. In practice, we can observe a very wide frequency envelope in which we can successfully recover signal (subject to noise – I’m waiting for some nice log-periodic antennas to ship). Here is a 10khz square wave reflected at approximately 2.41 GHz:

And the same, at 2.47:

Through expeirmentation, the impact of frequency is eclipsed by the impact of illuminator strength – no wonder the NSA used a dedicated unit, all praise to the unblinking eye watching us all.

Recovering the target signal can be done with a simple moving average and a threshold filter:

To provide a reference for relative amplitude, here’s the same code running, with the retroreflector disabled:

Nevertheless, this is useless unless we can recover actual logical data. My initial attempt with a knock-off Arduino failed for reasons unknown, so I made a new PIC firmware to constantly transmit a stream of the character 0xAA (for timing clarity) over UART in a loop. To begin with, let’s confirm that we can “see” the signal:

This waveform can be downsampled and pushed out to file, all in GNURadio (it’s possible to stream it to a custom Python block, but it means your Python block needs to implement a USART receiver – example code for the streaming is in the Github below).

You can download the source code here. Have fun!

Posted in Bards, Computers, Jesting | Leave a comment

Writeups – LowDeep, Kaboom (Insomnihack Teaser)

This weekend, I participated for a few hours in the Insomnihack Teaser CTF. Due to poor time management (specifically, my inability to correctly convert UTC time), I was only able to play for a little while, but I solved two challenges.

The writeups are presented below.


Lowdeep was presented as a web challenge, and was a nice warmup challenge for my renewed efforts this year:

A simple command injection reveals the presence of the print-flag binary, and strings gets the flag:

What a classic.


Kaboom was presented as a Windows executable. You can download the original here.

Upon initial investigation, this was a UPX packed executable, so I ran upx -d. Searching around the executable only revealed a troll flag:

Given the size of the executable, I was initially convinced that a hidden “unlock” function had been secreted somewhere in the application, perhaps hidden behind the facade of a standard library call. Unfortunately, searching for this was fruitless: it did not exist in the executable, and was not in the memory.

The other possibility I considered was that the UPX packer was not unpacking the flag correctly. Manual inspection of the packed executable revealed a clue – that there appeared to be two different packed flags. Firstly, the decoy flag:

Then, an actual flag:

Going through the UPX packer implementation (in hindsight, bindiff would have helped here), we could see the following code:

This simply overwrites the “correct” key with the troll key, so we never see the correct key unpacked.

A stronger internet wizard than me might have implemented a UPX unpacker stub and unpacked the correct key, but with my limited powers, I proceeded down the route of simply overwriting a chunk of the executable with the correct key.

Depending on how this is done, this can cause the UPX unpacker to experience a fault, but as long as this is after the key is packed into memory, it doesn’t matter:

Thankyou to the Insomnihack team for putting together yet another great CTF – this event has consistently been enlightening and fun. I look forward to solving the other challenges I downloaded.

A special mention should be made of the thoughtfully put together welcome challenge, which includes the following hilarious line:

I wonder how many people simply ran this without looking 🙂

Posted in Bards, Computers, Jesting | 2 Comments

Thoughts on 2019 / 2020

As we sit on the cusp of a new year, it is appropriate that we consider the year just gone, and the path ahead. In 2016, I began a push to use deliberate practice to improve my own skills in things that I was interested in. Since then, much has been accomplished:

  • I’ve gotten somewhat better at exploitation, mostly through practice. I’m not at the point where I can reliably search for and weaponize remote exploits in unknown IoT firmware in a given time-frame, but this is a goal for 2020.
  • I’ve gotten better at regular people “hardware hacking”, primarily because the increase from zero to anything is “a lot”. I’m able to identify attack paths into a device, and bypass some countermeasures. I can identify and use common debugging interfaces, I’ve some experience in writing payloads for MIPS/ARM (and know enough to Google the rest).
  • I’ve gotten better at actual hardware hacking. I understand the theory of side channel and fault injection attacks, have experience doing this with commodity and custom hardware, and have my own toolchains for experimenting with this tooling.
  • I’ve gotten somewhat better at digital hardware design. I can use COTS components to implement basic hardware design – the other day, I thought about a laser microphone, tried to implement one with ESP8266 (it didn’t work), and made a fake ADC out of a PIC microcontroller. You can see the result here.

I am rather proud of my small menagerie of gadgets I’ve made over the past year – but more so of the fact that I now know enough to imagine a concept, evaluate it’s viability and get on with making it, without needing someone to copy off:

The biggest challenge at this point is where to find those dark orange bakelite prototyping boards that are “soft” to cut, not like the new ones from Jaycar that crumble when you cut them.

Not everything has been sunshine and roses – as with anything, there are inevitable setbacks:

  • Side channel analysis of SIM cards, with the goal of obtaining cryptographic secrets, was somewhat unsuccessful. I suspect this is down to countermeasures implemented in the SIM card itself, but it’s difficult to confirm this as I can’t call up my provider and ask for source.
    • On the bright side, attacking a production system led to several major steps forward in trace preprocessing and alignment – I can’t complain too much about this.
  • I still suck at heap exploitation. With most forms of exploitation, I can visualise the process in my head, but once a heap allocator gets involved, there’s still a process of “trial and error” to make sure I’ve got the offsets right, and I’m predicting the behaviour of the heap allocator correctly. I have no idea how to exploit heap structures on modern systems.
  • have no idea how to uncover and weaponize a browser exploit (remotely triggerable via watering hole). I have some experience using JS payloads to attack web apps, but I don’t know how to move from a browser to a desktop (or more specifically, to an Android device).
  • have no experience at fabricating high-frequency circuits. I want to be able to make my own PCIe interfaces and NAND Flash interposer boads, but I haven’t committed time and resources to this – my fault.
  • distinctly lack education in electronics theory. In the age of search engines, this isn’t necessarily a downside per se, but often I find myself following rabbit-holes of “why is a dipole antenna the way it is”. That said, I taught myself all I know of electronics, so this is fixable.

As I tread further and further into the less-explored hinterlands of hardware security, it is increasingly difficult to maintain focus. Between the incessant demands of day-to-day life, and the general lack of fellow Internet Explorers in Australia, it is a challenge to remain committed to reaching the goals above; it’s worth having a think about what I’m going to do for the next five or so years to make myself learn faster.

Nevertheless, in an effort to make next year’s shitposting a little easier, my new goals for 2020 are as follows:

  • I want to rebuild my skillset with software. This involves doing things like Hack the Box, CTF’s and simply creating exploits for existing software – my subscription fee for HTB needs to be worthwhile.
  • I want to practice building high-frequency circuits. By the end of 2020, I want to have built at least one FPGA board (similar to the playstation modchip boards), acting as a custom PCIe interface.
  • I want to learn emissions security. Attacks such as TEMPEST have always been of interest, and I want to know enough to independently implement TEMPEST (both passive and active) against a simple signal by the end of 2020, as well as a few other key attacks. This links to the goal above.
  • I want to practice “universal backdoors” against Android. I want to be able to desolder a BGA NAND Flash chip, insert a backdoor (e.g. editing fstab), and replace it on the device. This vastly improves my ability to gain an initial foothold on completely closed systems.

I should also mention the part that my work at UNSW plays: as some of you know, I teach web application security, which isn’t my area of focus – but this is truly an opportunity I’ve failed to capitalize on. 2020 presents a renewed opportunity to truly take ownership of the course and reset it – I look forward to teaching an actually good course with consistent content quality, and then using this as a launchpad to further pursue my core interests by working with academically-minded folks I otherwise would not have contact with.

To top everything off, I can’t help but feel an all-consuming sense of desperation: I’m not getting any younger, but I’m far off from achieving what others have achieved (take a look at Yifan Lu’s work with the PS Vita, windytan’s work on HDMI side channeling, the successes so far on extracting SIM secrets – the examples are endless). Humanity has always been a few bright flames amidst a sea of flickering sparks, and few things fill me with bitter contempt like the thought of settling into a white picket fence life.

As we look forward into the new year, let us archive our accomplishments, grit our teeth and steel our resolve for the challenges ahead.

Posted in Bards, Jesting | Leave a comment

Effective Electromagnetic Keyboard Side-Channel on a (kinda) Budget

Update: a primitive GUI is now available to help remove the last false positives from signal matching. To use this, execute keyboards/ with the “–gui” argument to use this, code is in keyboards/

This week, I made good progress on electromagnetic keylogging (in particular, distinguishing keystrokes from a high-current-leakage keyboard). Just as the traveller may miss the forest for the trees, so I was blinded by my own mistaken interpretation of the data at hand – depending on key, a series of unique peaks is identifiable *after* the initial strong electromagnetic leakage pulse signifying a closed circuit within the scan matrix.

I will not yet claim to remotely understand the physics behind what I presume is the decay of the magnetic field over time (and by extension, the way this phenomena translates into measured electrical signal over time) – but it is  enough to know the behavior exists, and how to apply it to recovering keystroke data.


It is immediately apparent that the “unknown” signals of “0.npy” and “2.npy” are basically time-shifted versions of “p” – however, the initial pulse (the trigger) must be exempted for this to work. This is uniquely the case for every letter of the target keyboard I have tested thus far, forming an electromagnetic signature for each key, independent of position information from the scan matrix.

From here, the bulk of the work is in signal processing. I know little of the subject, but my stumbling about in Python has gotten a somewhat viable solution, as follows:

  • Firstly, extract the peaks from each signal. This is an inherently fuzzy problem, so we approximate by extracting signals from the 99.95 percentile. We only accept peaks which are a minimum distance apart (the maximum point in the proximity of an  identified peak). A set of this is saved as training data.
  • We perform an equivalent extraction against each identified key pulse in the “unknown” signal.
  • For each pairing of unknown signal and training data, we cull the longer signal to match the shorter signal, by discarding signal points of lowest absolute value. The assumption is that these peaks are swallowed by noise.
  • We “match” a key when the following conditions are met:
    • The position of the spikes is within a tolerance limit
    • The correlation coefficient of the values of both trace-peak sets is within a tolerance limit
    • The difference of absolute value of each equivalent peak-pair is within a tolerance limit (perhaps this and the time-position of each spike could be converted to a distance, and the entire thing fed to something starting with import tensorflow :P)

Of this, the peak extraction was the most finicky to get right – I ended up playing with a number of approaches before I landed on the current one, which seems fairly resistant to noise:

While imperfect (though I am semi-competent at Python, I am no data scientist), this generates extremely strong matches with relatively low false-positive and low false-negative rates. An improvement over previous matching efforts is that we can now generate true-negatives, where a sample simply matches nothing in our training dataset.

Still, p<unknown>ssw<unknown>rd really doesn’t leave too much to the imagination – and due to our ability to measure our certainty, for the instances where we’re unsure, we can lay the traces on top of one another like tracing paper and manually determine the best match. We can also improve this by saving all matches for a given unknown signal, and sieving a wordlist for common passwords / using language features to improve our signal matching.

During the investigation, I also explored whether unique frequency components were present in the decaying magnetic field, but I am currently unable to use a frequency-based interpretation to perform reliable matching. Observe, a matching signal overlaid on the correct training data in the frequency domain (via a power spectral density estimate using scipy.signal.welch):

Now, observe the same, though with an unmatched training data set:

This isn’t to rule out a frequency-based side-channel, simply that I don’t know how to do it – I am eager to explore other interpretations of the same data!

It is crucial to note that while conceptually reliable, this attack is severely affected by electromagnetic noise: a typist working by the light of the aurora should be all but immune to this. To successfully correlate training data, we must ensure there are no noise sources which can either cause extraneous peak detection, or missing peaks. Preferrably, training should be done with the same noise background as actual signal capture.

This attack is quite cheap to carry out, requiring only a readily available off-the-shelf USB oscilloscope (PicoScope 2206B) and two loops of thin wire. Best of all, due to per-keystroke triggering, no external storage is required for the attack. All the code required for the attack is available on Github – and sample data is available here. Enjoy!

Posted in Bards, Computers, Jesting | Leave a comment