Category: Reverse Engineering


How-to: Reversing and debugging ISAPI modules

Recently, I had the privilege to write a detailed analysis of CVE-2023-34362, which is series of several vulnerabilities in the MOVEit file transfer application that lead to remote code execution. One of the several vulnerabilities involved an ISAPI module - specifically, the MoveITISAPI.dll ISAPI extension. One of the many vulnerabilities that comprised the MOVEit RCE was a header-injection issue, where the ISAPI application parsed headers differently than the .net application. This point is going to dig into how to analyze and reverse engineer an ISAPI-based service!

This wasn’t the first time in the recent past I’d had to work on something written as an ISAPI module, and each time I feel like I have to start over and remember how it’s supposed to work. This time, I thought I’d combine my hastily-scrawled notes with some Googling, and try to write something that I (and others) can use in the future. As such, this will be a quick intro to ISAPI applications from the angle that matters to me - how to reverse engineer and debug them!

I want to preface this with: I’m not a Windows developer, and I’ve never run an IIS server on purpose. That means that I am approaching this with brute-force ignorance! I don’t have a lot of background context nor do I know the correct terminology for a lot of this stuff. Instead, I’m going to treat these are typical DLLs from typical applications, and approach them as such.

Continue reading

Fork off: Three ways to deal with forking processes

Have you ever tested a Linux application that forks into multiple processes? Isn’t it a pain? Whether you’re debugging, trying to see a process crash, or trying to write an exploit, it can be super duper annoying!

In a few days, I’m giving a talk at NorthSec in Montreal. I asked some co-workers to review my slides, and they commented that I have some neat techniques to deal with forking, so I thought I’d share a couple!

Spoiler alert: The last one is the best, so you can just skip to that. :)

Continue reading

Reverse engineering tricks: identifying opaque network protocols

Lately, I’ve been reverse engineering a reasonably complex network protocol, and I ran into a mystery - while the protocol is generally an unencrypted binary protocol, one of the messages was large and random. In an otherwise unencrypted protocol, why is one of the messages unreadable? It took me a few hours to accomplish what should have been a couple minutes of effort, and I wanted to share the trick I ultimately used!

I’m going to be intentionally vague on the software, and even modify a few things to make it harder to identify; I’ll probably publish a lot more on my work blog once I’m finished this project!

Continue reading

GDB Tricks: Tricking the Application into Generating Test Data

While reverse engineering a Linux binary, I ran into a fairly common situation: I wanted to understand how a decompression function works, but I didn’t have compressed data to test with. In this blog, I’ll look at how to we can manipulate the instruction pointer in the GNU debugger (gdb) to trick the software into generating test data for us!

I posted this on Mastodon awhile back, but I cleaned it up and expanded it a bit to make it a full blog post.

Continue reading

BSidesSF CTF 2021 Author writeup: log-em-all, a Pokemon-style collection game [video]

This is a video walkthrough of Log ‘em All, a difficult Hacking / Reverse Engineering challenge based on a classic bug in Pokemon Red. You can view the video below, or directly on Youtube.

I’ve never done a video-based writeup before, so I’d love feedback!

Continue reading

BSidesSF CTF 2021 Author writeup: glitter-printer, a buffer underflow where you modify the actual code

Hi Everybody!

This is going to be a challenge-author writeup for the Glitter Printer challenge from BSides San Francisco 2021.

First, a bit of history: the original idea I had behind Glitter Printer was to make a video game challenge involving cartridge-swap, where I’d write a handful of simple video games in 100% x86 code with no imports or anything (like an old fashioned cartridge game), and the player could swap between them without memory being re-initialized. Folks used to do this sorta thing on NES, and maybe I’ll use it in a future challenge, but I decided to make this a bit simpler.

While experimenting with writing libraries without libc, I realized just how much work it was going to be to write a bunch of games, and decided to simplify. My next ide was to write a “driver” type thing, where a blob of code is loaded into +RWX memory and the player could go wild on it. The the name Glitter Printer came across my radar, I don’t even remember why, and that gave me the idea to do an LPR server.

That’s quite the background!

Continue reading

BSidesSF CTF 2021 Author writeup: secure-asset-manager, a reversing challenge similar to Battle.net bot dev

Hi Everybody!

This is going to be a challenge-author writeup for the Secure Asset Manager challenge from BSides San Francisco 2021.

It’s designed to be a sort of “server management software”. I sort of chose that theme to play off the Solarwinds thing, the theme wasn’t super linked to the challenge.

The challenge was to analyze and reverse engineer a piece of client-side software that “checks in” with a server. For the check-in, the client is required to “validate” itself. The server sends a random “challenge” - which is actually a block of randomized x86 code - and that code used to checksum active memory to prevent tampering. If anybody reading this worked on bots for the original Starcraft (and other Battle.net games), this might seem familiar! It’s based on Battle.net’s CheckRevision code.

Continue reading

BSidesSF CTF 2021 Author writeup: Reverseme and Reverseme2 – simpler reverse engineering challenges

This is going to be a writeup for the Reverseme challenges (reverseme and reverseme2 from BSides San Francisco 2021.

Both parts are reasonably simple reverse engineering challenges. I provide the compiled binaries to the player (you can find those in the respective distfiles/ folders), and you have to figure out what to do with them.

Both challenges use the same basic code as the runme challenges, where you send shellcode that is executed. Only in this case, the shellcode must be modified or “encoded” in some way first!

Continue reading

BSidesSF CTF: Hard reversing challenge: Chameleon

For my third and final blog post about the BSidesSF CTF, I wanted to cover the solution to Chameleon. Chameleon is loosely based on a KringleCon challenge I wrote (video guide), which is loosely based on a real-world penetration test from a long time ago. Except that Chameleon is much, much harder than either.

Continue reading

BSidesSF CTF: Easy to hard Rust reversing challenges

As mentioned in a previous post, I was honoured to once again help run BSidesSF CTF!

This is going to be a quick writeup for three challenges: config-me, rusty1, and rusty2. All three are reversing challenges written in Rust, although the actual amount of reversing required is low for the first two.

Continue reading

In BSidesSF CTF, calc.exe exploits you! (Author writeup of launchcode)

Hey everybody,

In addition to genius, whose writeup I already posted, my other favourite challenge I wrote for BSidesSF CTF was called launchcode. This will be my third and final writeup for BSidesSF CTF for 2019, but you can see all the challenges and solutions on our Github releases page.

This post will be more about how I developed this, since the solution is fairly straight forward once you know how it’s implemented.

Continue reading

BSidesSF CTF author writeup: genius

Hey all,

This is going to be an author’s writeup of the BSidesSF 2019 CTF challenge: genius!

genius is probably my favourite challenge from the year, and I’m thrilled that it was solved by 6 teams! It was inspired by a few other challenges I wrote in the past, including Nibbler. You can grab the sourcecode, solution, and everything needed to run it yourself on our Github release!

It is actually implemented as a pair of programs: loader and genius. I only provide the binaries to the players, so it’s up to the player to reverse engineer them. Fortunately, for this writeup, we’ll have source to reference as needed!

Continue reading

Technical Rundown of WebExec

This is a technical rundown of a vulnerability that we’ve dubbed “WebExec”. The summary is: a flaw in WebEx’s WebexUpdateService allows anyone with a login to the Windows system where WebEx is installed to run SYSTEM-level code remotely. That’s right: this client-side application that doesn’t listen on any ports is actually vulnerable to remote code execution! A local or domain account will work, making this a powerful way to pivot through networks until it’s patched.

High level details and FAQ at https://webexec.org! Below is a technical writeup of how we found the bug and how it works.

Continue reading

GitS 2015: Huffy (huffman-encoded shellcode)

Welcome to my fourth and final writeup from Ghost in the Shellcode 2015! This one is about the one and only reversing level, called “huffy”, that was released right near the end.

Unfortunately, while I thought I was solving it a half hour before the game ended, I had messed up some timezones and was finishing it a half hour after the game ended. So I didn’t do the final exploitation step.

At any rate, I solved the hard part, so I’ll go over the solution!

Continue reading

Defcon Quals writeup for byhd (reversing a Huffman Tree)

This is my writeup for byhd, a 2-point challenge from the Defcon Qualifier CTF. You can get the files, including my annotated assembly file, here. This is my second (and final) writeup for the Defcon Qualifiers, you can find the writeup for shitsco here.

This was a reverse engineering challenge where code would be constructed based on your input, then executed. You had to figure out the exact right input to generate a payload that would give you access to the server (so, in a way, there was some exploitation involved).

Up till now, cnot from PlaidCTF has probably been my favourite hardcore reversing level, but I think this level has taken over. It was super fun!

Continue reading

PlaidCTF writeup for Pwn-275 – Kappa (type confusion vuln)

Hey folks,

This is my last writeup for PlaidCTF! You can get a list of all my writeups here. Kappa is a 275-point pwnable level called Kappa, and the goal is to capture a bunch of Pokemon and make them battle each other!

Ultimately, this issue came down to a type-confusion bug that let us read memory and call arbitrary locations. Let’s see why!

Continue reading

PlaidCTF writeup for Pwn-200 (a simple overflow bug)

I know what you’re thinking of: what’s with all the Web levels!?

Well, I was saving the exploitation levels for last! This post will be about Pwnable-200 (ezhp), and the next one will be Pwnable-275 (kappa). You can get the binary for ezhp here, and I highly recommend poking at this if you’re interested in exploitation—it’s actually one of the easiest exploitation levels you’ll find!

Continue reading

Ghost in the Shellcode: fuzzy (Pwnage 301)

Hey folks,

It’s a little bit late coming, but this is my writeup for the Fuzzy level from the Ghost in the Shellcode 2014 CTF! I kept putting off writing this, to the point where it became hard to just sit down and do it. But I really wanted to finish before PlaidCTF 2014, which is this weekend so here we are! You can see my other two writeups here (TI-1337) and here (gitsmsg).

Like my other writeups, this is a “pwnage” level, and required the user to own a remote server. Unfortunately, because of my slowness, they’re no longer running the server, but you can get a copy of the binary at my github page and run it yourself. It’s a 64-bit Linux ELF executable. It didn’t have ASLR, and DEP would have been

Continue reading

Ghost in the Shellcode: gitsmsg (Pwnage 299)

“It’s Saturday night; I have no date, a 2L bottle of Shasta, and my all-rush mix tape. Let’s rock!”

…that’s what I said before I started gitsmsg. I then entered “Rush” into Pandora, and listened to a mix of Rush, Kansas, Queen, Billy Idol, and other 80’s rock for the entire level. True story.

Anyway, let’s get on with it! Not too long ago I posted my writeup for the 100-level “Pwnage” challenge from Ghost in the Shellcode. Now, it’s time to get a little more advanced and talk about the 299-level challenge: gitsmsg. Solved by only 11 teams, this was considerably more challenging.

As before, you can obtain the binary, my annotated IDA database, and exploit code on my Github page

Continue reading

Ghost in the Shellcode: TI-1337 (Pwnable 100)

Hey everybody,

This past weekend was Shmoocon, and you know what that means—Ghost in the Shellcode!

Most years I go to Shmoocon, but this year I couldn’t attend, so I did the next best thing: competed in Ghost in the Shellcode! This year, our rag-tag band of misfits—that is, the team who purposely decided not to ever decide on a team name, mainly to avoid getting competitive—managed to get 20th place out of at least 300 scoring teams!

I personally solved three levels: TI-1337, gitsmsg, and fuzzy. This is the first of three writeups, for the easiest of the three: TI-1337—solved by 44 teams.

You can download the binary, as well as the exploit, the IDA Pro files, and everything else worth keeping that I generated, from my Github repository.

Continue reading

In-depth malware: Unpacking the ‘lcmw’ Trojan

Hey folks,

Happy New Year, and welcome to 2014!

On a recent trip to Tyson’s Corner, VA, I had some time to kill, so I took a careful look at a malware sample that a friend of mine sent to me some time ago, which I believe he originally got off somebody else’s hosed system. The plan was for me to investigate it, and I promised him I would; it just took awhile!

Anyways, the sample has a few layers of packing, and I thought it’d be fun/interesting to show you how to unwrap the entire thing to obtain the final payload. I am not going to discuss the payload itself in this post, largely because I haven’t spent much time reversing it. Perhaps in the future I’ll dig a little deeper, but for now we’ll focus on the packing.

I called this sample “lcmw”. It stood for something interesting, but I don’t really remember what—I may have been drinking when I named it. :)

Continue reading

ropasaurusrex: a primer on return-oriented programming

One of the worst feelings when playing a capture-the-flag challenge is the hindsight problem. You spend a few hours on a level—nothing like the amount of time I spent on cnot, not by a fraction—and realize that it was actually pretty easy. But also a brainfuck. That’s what ROP’s all about, after all!

Anyway, even though I spent a lot of time working on the wrong solution (specifically, I didn’t think to bypass ASLR for quite awhile), the process we took of completing the level first without, then with ASLR, is actually a good way to show it, so I’ll take the same route on this post.

Before I say anything else, I have to thank HikingPete for being my wingman on this one. Thanks to him, we solved this puzzle much more quickly and, for a short time, were in 3rd place worldwide!

Continue reading

Epic “cnot” Writeup (highest value level from PlaidCTF)

When I was at Shmoocon, I saw a talk about how to write an effective capture-the-flag contest. One of their suggestions was to have a tar-pit challenge that would waste all the time of the best player, by giving him a complicated challenge he won’t be able to resist. In my opinion, in PlaidCTF, I suspected that “cnot” was that challenge. And I was the sucker, even though I knew it all the way…

(It turns out, after reviewing writeups of other challenges, that most of the challenges were like this; even so, I’m proud to have been sucked in!)

If you want a writeup where you can learn something, I plan to post a writeup for “Ropasaurus” in the next day or two. If you want a writeup about me being tortured as I fought through inconceivable horrors to finish a level and capture the bloody flag, read on! This level wasn’t a lot of learning, just brute-force persistence.

Continue reading

Battle.net authentication misconceptions

Hey everybody,

There have been a lot of discussion and misconceptions about Battle.net’s authentication lately. Having done a lot of work on the Battle.net protocol, I wanted to lay some to rest.

The first thing to understand is that, at least at the time I was working on this, there were three different login methods (this is before they combined the Web logins with Battle.net logins - I can’t speak on those). The three methods are:

  1. CHAT protocol - deprecated a long, long time ago
  2. Old Login System (OLS) - used by Diablo, Warcraft 2 BNE, Starcraft, and Diablo II
  3. New Login System (NLS) - used by Warcraft 3, World of Warcraft, and in some fashion by newer games. Also supported - but unused - by Diablo II

I’ll describe, in detail, how each of these work. The summary is, though, that at no point does a game client ever send a plaintext password to the server. The closest is the SHA1 of the password, which is used for account creation in old games. For more information, read on!

Continue reading

Remote control manager FAIL

Hey guys,

Today, I thought it’d be fun to take a good look at a serious flaw in some computer-management software. Basically, the software is designed for remotely controlling systems on networks (for installing updates or whatever). As far as I know, this vulnerability is currently unpatched; there are allegedly mitigations, but you have to pay to see them! (A note to vendors - making us pay for your patches or mitigation notes only makes your customers less secure. Please stop doing that!)

This research was done in the course of my work at Tenable Network Security on the Reverse Engineering team. It’s an awesome team to work on, and we’re always hiring (for this team and others)! If you’re interested and you have mad reverse engineering skillz, or any kind of infosec skillz, get in touch with me privately! (rbowes-at-tenable-dot-com if you’re interested in applying)

Continue reading

A deeper look at ms11-058

Hey everybody,

Two weeks ago today, Microsoft released a bunch of bulletins for Patch Tuesday. One of them - ms11-058 - was rated critical and potentially exploitable. However, according to Microsoft, this is a simple integer overflow, leading to a huge memcpy leading to a DoS and nothing more. I disagree.

Although I didn’t find a way to exploit this vulnerability, there’s more to this vulnerability than meets the eye - it’s fairly complicated, and there are a number of places that I suspect an experienced exploit developer might find a way to take control.

In this post, I’m going to go over step by step how I reverse engineered this patch, figured out how this could be attacked, and why I don’t believe the vulnerability is as simple as the reports seem to indicate.

Oh, and before I forget, the Nessus Security Scanner from Tenable Network Security (my employer) has both remote and local checks for this vulnerability, so if you want to check your network go run Nessus now!

Continue reading

Locks that can re-key themselves?

Hey everybody,

As I’m sure you all know, I normally post about IT security here. But, once in awhile, I like to take a look at physical security, even if it’s just in jest.

Well, this time it isn’t in jest. I was at Rona last week buying a lead/asbestos/mold-rated respirator (don’t ask!), when I took a walk down the lock aisle. I’m tired of all my practice locks and was thinking of picking up something interesting. Then I saw it: a lock that advertised that it could re-key itself to any key. Woah! I had to play with it.

Now, maybe I’m an idiot (in fact, my best friends would swear it). But I hadn’t ever heard of a lock that can do that before! So I did the obvious thing: I bought it, took it apart, figured out how it worked, then took pictures of everything.

Continue reading

Watch out for exim!

Hey everybody,

Most of you have probably heard of the exim vulnerability this week. It has potential to be a nasty one, and my brain is stuffed with its inner workings right now so I want to post before I explode!

First off, if you’re concerned that you might have vulnerable hosts, I wrote a plugin for Nessus to help you find them (I’m not sure if it’s in the ProfessionalFeed yet - if it isn’t, it will be soon). There’s no Nmap script yet, but my sources tell me that it’s in progress (keep an eye on my Twitter account for updates on that).

Continue reading

Taking apart the Energizer trojan – Part 4: writing a probe

Now that we know what we need to send and receive, and how it’s encoded, let’s generate the actual packet. Then, once we’re sure it’s working, we’ll convert it into an Nmap probe! In most of this section, I assume you’re running Linux, Mac, or some other operating system with a built-in compiler and useful tools (gcc, hexdump, etc). If you’re on Windows, you’ll probably just have to follow along until I generate the probe.

Continue reading

Taking apart the Energizer trojan – Part 3: disassembling

In Part 2: runtime analysis, we discovered some important addresses in the Energizer Trojan – specifically, the addresses that make the call to recv() data. Be sure to read that section before reading this one.

Now that we have some starting addresses, we can move on to a disassembler and look at what the code’s actually doing. Fortunately, the author made no attempt to disguise the code or pack or or anything like that, so a simple disassembler is all we need to examine the code.

A word of warning: this is the longest, most complicated section. But stick with it, by the end we’ll know exactly how the Trojan ticks!

Continue reading

Taking apart the Energizer trojan – Part 2: runtime analysis

In Part 1: setup, we infected the system with the Trojan. It should still be running on the victim machine. If you haven’t read that section, I strongly recommend you go back and read it.

Now that we’ve infected a test machine, the goal of this step is to experiment a little with the debugger and learn a little about the Energizer Trojan. This can all be discovered with a simple disassembler, but I find it more fun to take apart a live sample. All we’re going to do is add a breakpoint at the recv() function and see where it’s called from.

This step is going to require Debugging Tools for Windows. If you haven’t installed it already, install it on the victim machine.

Continue reading

Taking apart the Energizer trojan – Part 1: setup

Hey all,

As most of you know, a Trojan was recently discovered in the software for Energizer’s USB battery charger. Following its release, I wrote an Nmap probe to detect the Trojan and HDMoore wrote a Metasploit module to exploit it.

I mentioned in my last post that it was a nice sample to study and learn from. The author made absolutely no attempt to conceal its purpose, once installed, besides a weak XOR encoding for communication. Some conspiracy theorists even think this may have been legitimate management software gone wrong – and who knows, really? In any case, I offered to write a tutorial on how I wrote the Nmap probe, and had a lot of positive feedback, so here it is!

Just be sure to take this for what it is. This is not intended to show any new methods or techniques or anything like that. It’s a reverse engineering guide targeted, as much as I could, for people who’ve never opened IDA or Windbg in their lives. I’d love to hear your comments!

Continue reading