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/classifier-read.py with the “–gui” argument to use this, code is in keyboards/ui.py.

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

Writeups – Elecduino, python_jail (NCTF)

This weekend, I participated in NCTF. This was a beginner CTF, and it was good both as a morale boost, particularly as other research wades into unexplored territory, as well as a refresher on basic skill. It is always a delight to taste a few fleeting moments of focus, against the lifeless static of life.

For completeness, I will present some of the challenges solved below:


This challenge was presented as a link to a Tinkercad project. The Tinkercad website presents a particularly chaotic Arduino Uno setup:

I’m not really sure what this is intended to do, but the code gives away the game – this is some manner of bit-banging on port 12, 10 and 4. We can create a C stub, replacing the GPIO activations with printfs, depending on the pin number activated.

This quickly bears fruit, revealing a short binary-encoded flag:

A little bit of wrangling with the flag format later, and the flag is ours.


This challenge was presented as a host/port combination. On connecting, we are presented with the source code to a challenge:

This is a reasonably “light” jail (but a refreshingly Python3 one): only a few keywords are blocked. We can easily escape this, with the following payload:

To break this down a bit, we first use the Python “__builtins__” global (and for future reference, if __builtins__ is destroyed, try reload(__builtins__). __builtins__ doesn’t allow us to directly subscript a member, but we do this with __dir__, allowing us to get the exec function.

Once this is done, we exec a small secondary payload to import os, and then run shell commands – all the while taking care to avoid the blacklisted keywords in the challenge, giving us the flag.

Thankyou to the NCTF team for organising this event, I benefited from it. Condolences on the unexpected downtime halfway, and best wishes on any future events you organize. See you all in the Pwn2Win CTF next weekend.

Posted in Bards, Computers, Jesting | Leave a comment

Preliminary Notes on Electromagnetic Keylogging

This is my keylogger. There are very few like it – this one is mine.

Over the past few weeks (and on and off before that), I have done some work on electromagnetic keylogging – this has met with some success. This post will document my progress so far, and collate some thoughts on future work in this area. All the code can be downloaded at my Github – due to the extreme work-in-progress nature of this project, I recommend you review the available branches before experimenting (or get in touch and let’s work together!)


To explain this keylogger’s operation, we must look into the actual operation of a keyboard. A modern keyboard is comprised primarily of two sheets of flexible plastic, with conductive traces printed on them. The traces on the two sheets of plastic intersect at locations corresponding to the physical keys – when a key is pressed, a contact is made between the two plastic sheets, allowing a conductive path to form between a row and a column of the scan matrix.

A microcontroller scans the matrix by setting each pin in a column to high for a period of time, and monitoring the voltage of each of the rows:

(credit: http://www.pykett.org.uk/picscannermidi.htm)

Viewed through another lens, a microcontroller activates one of num_columns antennas intermittently, signalling that it is scanning. Previously, Martin Vuagnoux and Sylvain Pasini exploited this property to determine the presence of keystrokes via delays in the scan cycle caused by the microcontroller buffering a USB packet or creating a PS2 message (not sure of the name of these). In my experimentation, I was unable to reliably observe this delay, but I was able to (visually!) observe the difference in magnitude of leaked energy – this was enough to perform imperfect keylogging on a target with training data (and presumably, without).


To measure and correlate my attacks, I built some simple magnetic pickups – these were simply lengths of wire on a cardboard plate, with some aluminum foil noise shielding on one side (there is insufficient testing to determine how effective this shielding is), as follows:

Some manual analysis was performed to determine the trigger threshold, sample rate and sample count for a keystroke, and some signal processing was done to align the measured signals – from there, two primary paths of correlation became apparent:

  • In circumstances where a high current flowed between the column and the row (creating a large magnetic spike), I could isolate only the single spike corresponding to a single row-column scan event, and correlate the magnetic field generated against test data.
  • In circumstances where not enough current flowed to reliably trigger on a single column-row pair, it appears possible to continuously capture signal, align the captured signals in a known way and correlate that against training data.

In some cases, feature extraction and signal processing techniques can be used to clean up the captured signal to reduce background noise: though I found when capturing single row-column scan events, I had to be careful to avoid information loss. Continuous visualization with matplotlib helped here.

A further improvement was to increase the fidelity of the information I captured, using two coils instead of one. Triggering was still done on a single coil (this was reliable enough on a test keyboard), but correlation was performed on both channels of data. This was enough to correctly capture words – though with any such approach, particularly under the time-limited sampling constraint of typing, the results are imperfect, but a limited test case (continuous recapturing of training data is continuously a pain in the fucking ass) shows promise:

The arrays above represent the “key guess”, and a weighted sum of correlation coefficients of scan events vs training data (“correct” hits with >0.9 correlation are weighted more heavily).

Observe further the below two two-channel signal plots representing a full scan cycle, the first with the “J” key held down during capture:

And a second, without:

The difference is already as clear as day, and is consistent across samples, some trivial signal analysis can clean up the traces and do the necessary correlation to identify the key.

A “Combined Arms” Approach

In truth, the core of this project is not in the electromagnetic pickup – the principle of signal correlation should be applicable to almost any side channel, with some interpretation where appropriate. Most empowering perhaps is the potential to use different inputs to solve the detection vs identification problem referred to by John Monaco in his work, “SoK: Keylogging Side Channels“.

Particularly in cases where a keypress does not generate a significant enough event to trigger off alone, a secondary channel, such as sound or vibration picked up via a smartphone, could allow us to reduce the amount of data we need to sample. Alternatively, a “SAD Match” trigger (as per the ChipWhisperer) could feasibly be used, though greatly increasing the cost of the equipment required for the attack, ChipWhisperer or no.

I am also keen on investigating the potential interpretation of this signal in the frequency domain – if I am able to reduce the effective sample rate (currently sampling at ~125MSPS, requiring the use of an oscilloscope at the very least), perhaps by using higher-frequency harmonics, it may be possible to greatly reduce the cost of this attack. Most importantly, I am keen to explore the fundamental relationship between the fundamental frequency and it’s harmonics in a way that it may be applicable to other “loud” electromagnetic leakage sources.

I am excited by the progress made in this project, and as my understanding of the theory behind this class of attack improves, the vast horizons opening up ahead; a warm reminder of the heady days of my youth, learning for the first time that impacting a user’s view of a web application was known as “cross-site scripting”. If you are interested in working together on this, please do leave a note – I am most keen to keep exploring this area.

Posted in Bards, Computers, Jesting | Leave a comment