Writeup – El33t Articles Hub (Pragyan CTF)

This weekend, I participated in Pragyan CTF. In the time allocated, I solved a few challenges – unfortunately, most of them are not worth writing about, in that they are very similar to previous writeups.

I will present a writeup for one of the web challenges below.

El33t Articles Hub

This was a web challenge, with the challenge text as follows:

On visiting the website, we are taken to the following web page:

Viewing the source code gives us an interesting clue: that a dynamic favico is being generated:

A bit of guesswork reveals that this is vulnerable to a path traversal bug, and a little bit of exploration later reveals the source code for index.php, and more importantly, helpers.php:

Some fiddling with the path on the webserver later, gives us the flag:

Thanks to the Pragyan organisers for putting together this event – unfortunately, it quickly became apparent that this event was not ready for deployment, and some of the challenges had undergone insufficient playtesting. Also, the entire “Misc” category disappearing while the CTF was on is pretty much never a good sign.

Interestingly, someone in my university class asked last week, “is every website this vulnerable”. Funnily enough, the answer is no, but almost that it doesn’t matter – enough things are vulnerable that the problem shifts from a pure technology one to an intelligence one, towards keeping an eye on what’s vulnerable, and keeping tabs on what’s “interesting” – and this leads down a path of philosophical discussions all on it’s own.

Better luck next time – see you all in N1CTF next weekend.

Posted in Bards, Computers, Jesting | Leave a comment

Reversing the e3372 – Completing the Compromise (P711-HILINK Remix)

In my last post, I began detailing the reverse engineering of the Huawei e3372 device. This is a new version of the device, using the P711-HILINK firmware (fingerprinted through a memory dump, I can’t see any visible indicator on the board). Throughout the week, I learned a bit about the Android booting process, and was able to complete the compromise, to get a root shell.

This is clearly a changed firmware from a similar device I acquired last year – on initially UART’ing into the device, no console is presented, and the UART distribution (the L/V/M thing) doesn’t work. Instead, we are presented with an endless scroll of something about “IN drvStartModeGetFlag”.

I began my investigation by pausing the boot process to before the Android kernel had booted, and editing boot arguments:

Unfortunately, this did nothing (nor did init=/bin/sh, removing rdinit, single-user mode and all the trickery I could conceive).

My next approach was to investigate the userland process (suspected userland – investigated via a memory dump from 0xc0000000) which was causing the message loop. The “IN drvStartModeGetFlag” string was from libplatform.so (found through extracting a firmware blob) – specifically, we have a good guess that this code path is from drvStartModeGet (at 0x469C). We can easily nop out of this check:

This exits the crashed process, bringing us to the familiar authconsole interface:

From here, we patch the same 2 authconsole checks as we did to the e5573 to get the EUAP> prompt, and from there, a privileged shell.

I would like to thank the engineering team at Huawei for making this challenge not too easy that I didn’t learn anything, but not too hard that it is impossible. With this approach, we have a way of shelling this device which does not require abusing the update functionality / boot pin trick.

I look forward to seeing you all in Pragyan CTF this weekend.

Posted in Bards, Computers, Jesting | Leave a comment

Notes (rambling) on the E3372 / DIY Supply Adapter for JLink

Over the last few days, I found an old Huawei E3372 device. In the past, I have had limited success compromising this device, but had not been able to independently achieve OS-level access (a shell).

I poked and prodded at this device, and after being still unsuccessful, I figured it would be a good time to desolder the NAND Flash chip to acquire device firmware. Misfortune struck, as (what I assume to be) damage from desoldering rendered the chip unusable, and I was unable to retrieve any meaningful image from it.

With the hot air gun already switched on and whatever toxic desoldering fumes already saturating my room, I pressed on and desoldered everything else for fun. Moments later, bittersweet triumph:

JTAG pads for this device did exist, underneath the SIM card reader. I suspect this was a space-saving measure from Huawei, but this turned out to be a cunning troll: if you wanted to unlock the device via JTAG, you’d need to desolder the SIM card reader and put it back when you were done (or replace it, if the plastic had warped during hot-air desoldering).

I went to the Optus store and purchased a new e3372 device, and wired it up.

The only thing I really needed was some manner of reference voltage for the JLink, to avoid damaging the circuitry. I knew from past experience that this device operated at approximately 1.8V – it didn’t need to be exact, but I should avoid raising voltage levels to 5V.

Initially, I attempted to use the same technique as other Huawei devices, “borrowing” a voltage reference from some other pin. Unfortunately, on this device, it turned out to be unstable – once I connected the “target reference pin”, the voltage reference would drop to zero.

Browsing around, I found a supply adapter available for purchase, which would allow me to set the voltage which the JLink operated at, without a target reference:

Browsing through the documentation available on the Segger website, this looked like a simple voltage regulator on a breakout board. I dug through my massive box of miscellaneous crap, and lo and behold, an open pack of LM317T voltage regulators. I couldn’t remember buying them or using them, but I wondered if I could replicate the functionality of the supply adapter using one of these.

In a nutshell, a voltage regulator can give you a fixed, adjustable output from a variable input. On paper, it looks like this:

R1 and R2 get adjusted to determine which output you want. Our input is the 5V target supply pin on the JLink itself; our output is, naturally, the VTRef pin.

In practice, it looks a little something like this:

To enable the voltage regulator, start JLink, and enter the “power on” command. The target voltage should then jump to approximately 1.8V, which is about what we need to interface with the target, saving me approximately $104 (granted, my version doesn’t come with the power indicator LED, but I’m sure I’ll live without):

Unfortunately, our adventure is not yet over. The “authconsole” bin, which I found in previous adventures (see the notes around the E5572), did not seem to start automatically on this device, nor did I get the option to set the serial console mode with L/V/M/K/etc. Instead, I got some wierd error message (while the device did seem functional): my hypothesis is that this is either a new firmware revision (preloaded onto the device), or some hardware damage may have forced the device into a new state without console access.

Fortunately, the weekend is only half over…

Posted in Bards, Computers, Jesting | Leave a comment

Writeup – Flag Checker 2, Mario Mystery, Envy (Xiomara CTF)

This weekend, I participated in the Xiomara CTF, which has just concluded at the time of writing. I will present some (relatively short) writeups for this CTF below.

Flag Checker 2

This challenge was a web challenge which can be solved locally. The challenge files can be downloaded here.

On opening the HTML file, we are prompted for a password (the flag), which is evaluated with some obfuscated JavaScript. The point value of the challenge did not seem to correspond with the effort of manually de-obfuscating the JS, so I looked for a side channel. I quickly found one, when prettifying main.js:

Here, there is an obfuscated alert() call. On testing in the JS console, this reveals the “You got the correct flag” message. Occam’s razor says that one of the two operands to “!==” is the flag, and a quick test proves us right, and scoring us some easy points:

Mario Mystery

This challenge was presented as an APK, which you can download here.

Initial reverse engineering didn’t reveal anything, and the clue said something about the key being server-side: so my first port of call was the classes.dex file. I put it through dex2jar and jd-gui, which revealed my first clue:

Still, I had no API key. Going through the Java code, I find that the string is loaded from a resource, and MD5’ed:

We can use apktool (apktool d Xiomara_2k18.apk) to extract all the resources from the APK. Browsing through res/values, we find a key:

From here, it is simple enough to MD5 the key, call the API endpoint and grab our flag:


This challenge was presented as a Linux binary, which you can download here.

Upon initial reverse engineering, we don’t see a whole lot – the psuedocode seems to indicate that we’re strcmp’ing two uninitialized variables, some string alluding to a buffer overflow and something indicating fancy binary exploitation (“Try again, you got 0x%08x”).

In the end, all of these turned out to be cunning trolls – the flag was in an unreferenced variable, above the “src” and “s2” strings referenced by the main function:

Thanks to the organisers for putting together this CTF – it was a pleasure to play in, the challenges remained online for the duration of the challenge and there was some good variety without it turning into blind guessing games. See you all in Pragyan CTF (the best part of all of this for me is seeing the same CTF’s come back around, one year on) next weekend.

Posted in Bards, Computers, Jesting | Leave a comment

Late Writeup – flea_attack (Harekaze)

This weekend, me and 0x4a47 attempted the flea_attack challenge from Harekaze CTF, but we were unable to solve it in the time allocated. Still, this was a good lesson in modern heap exploitation, and therefore, I think it’s worth writing up.

At the end of this post, I will disclose the exploit-in-progress at the time the CTF ended, as well as two modified exploits, one of which “works” (but both prove the concept).


This challenge was presented as a 64-bit Linux binary, which you can download here: flea_attack. The flow of the application is as follows:

  • Open /home/flea_attack/flag, drop this into 0x204080
  • Read a comment, of 0x60 (via original_fgets: 95 characters) in length into 0x204000.
  • Present the user with a menu, allowing:
    • Adding a note (_malloc)
    • Removing a note (_free)

Based on the challenge title and the way the add and remove functions were structured as malloc and free primitives, we figured this would be a heap challenge.

My initial, naive approach was to attempt your standard unlink macro corruption, but inspecting memory, I noticed that this challenge required a different approach:

As you can see, there is no fd/bk pointer to overwrite to exploit unlink with, just a size. Furthermore, there’s not really any “overwrite” per se: while we entirely control a chunk, there’s no way provided for us to actually write outside an allocated chunk.

The madness of GLIBC

This is due to the glibc’s heap implementation, which is much, much more complicated than glibc. In glibc, memory allocations are stored in “bins”, in which memory blobs of a single size can be stored one chunk after another / as efficiently as possible by glibc. For example, if I request a malloc of 2 bytes, malloc is likely to return me a chunk of 16 bytes (the smallest chunk size), as part of a bin (as per the behaviour above).

Each chunk allocation looks like this:

When I free a chunk, two things happen:

  • Perform some sanity checking around the chunk I want to free – it’s structures must be valid. Look here for more information.
  • The chunk’s “fd” ptr is zeroed. This indicates the memory is ready for re-use.
  • The chunk address is added to a “freelist”, which operates like a FIFO stack. If I want to allocate 2 bytes, glibc will traverse it’s freelist, to determine if there’s a chunk of memory it can re-use. If not, it will allocate me a new chunk.

When I allocate memory to a previously freed chunk (from the freelist):

  • If the “fd” ptr is zeroed, return a pointer here and let the user write.
  • If the “fd” ptr is not zeroed, return a pointer here and let the user write, but next time you allocate memory, follow the pointer to get the next free chunk.

Note that none of this is magic: glibc malloc simply relies on some flimsy-ass local structures to determine if you’ve got a valid chunk and what that looks like so it’s entirely possible to forge heap allocations for yourself, which was my approach.

Forging a chunk

We can then forge two chunks with a single malloc call: if we allocate a large chunk of memory, we can write a smaller chunk header inside it, creating a second “fake allocation”. This second allocation can then be freed, writing it’s location to the free list.

Now, when we reallocate a chunk of the same size, glibc will fetch our fake block from the freelist – if the fd pointer happens to be written at this point, glibc will fuck up the next allocation, pointing it to whatever we filled fd with.

We can attempt this to overwrite the flag directly. Firstly, we forge a fake heap chunk:

Our fake heap chunk is at 0x7bb260 (with malloc returning 0x7bb270). Note that it’s size is 0x20 (the 1 is a flag, indicating the previous chunk is in use).

Now, we allocate memory of size < 20, and we should overwrite this with no error:

Note that 0x7bb270 is now replaced by our userdata. Where is our pointer, I wonder?

There it is! The error indicates that glibc tried to give us memory from that location, but it doesn’t have a valid header. Fair enough, it’s the flag, and there’s nothing before it: that’s not a valid header.

Our flag is stored at 0x204080, but we’re only able to write until 0x204060 (based on the original_fgets function). Still, if I’m able to allocate memory in the 0x204000 to 0x204060 range, this should be good enough: I can size this allocation to cover until the flag (by writing 95 bytes into the comment: normally, original_fgets will add 0x0a after your comment, but will fail at doing so if you write as many characters as it allows, giving us a clean fastbin length.

So, we modify our exploit as follows:

  • In the initial comment, forge a chunk at 0x204056 (by sending 94 “A”‘s followed by one character of length). Let the size of this chunk be X.
  • Make an allocation of size >X. Let this be allocation A
  • Within allocation A, forge a second chunk of size X. Let this be allocation B.
  • Free B (on the freelist)
  • Free A.
  • Make an allocation of size >X, re-using A. During this allocation, recreate B, with a fd pointer aiming at 0x204056.
  • Make an allocation of size X, re-using B, and storing B’s “fd” pointer as the next free chunk.
  • Make a second allocation of size B. This will allocate memory at 0x204066 (taking into account headers), letting is write and leak memory from there (by filling it with enough characters such that it reaches the flag at 0x204080).

While we did not finish this exercise in time, you can find the original script we arrived at at the conclusion of the CTF here.

A working script which demonstrates the concept above is here. Note when you make the second allocation of size <0x20, you get an address within the comment section, demonstrating the attack is possible. Tweak the field size to leak the flag. Here’s the script in action, allocating an address within the comment section:

I also followed someone else’ writeup, which talked about exploiting this through a double free. This is also doable, and the script for that is here. Note that when double freeing, you can’t free the same chunk twice in a row: thus the extraneous free operation.

If only there were more hours in the day…

Posted in Bards, Computers, Jesting | Leave a comment