A hackers blog: application security, reverse engineering, math, python, CTF, exploits, ...

2016 DEFCON OpenCTF - Tyro ROP2 (pwnable)

August 24, 2016

Tyro ROP2 was the second in a series of pwnable challenge from OpenCTF this year. Each challenge in the series emphasized a different technique - this exploit uses mprotect to bypass a non-executable (NX) stack.

2016 Legitbs Defcon Quals - Feedme (32-bit ROP exploit with stack canary bypass)

May 25, 2016

FEED ME! Sure, how about these delicious ROP chains? The first step in this challenge was overcoming the stack canary and then we build a ROP chain that used system calls to open and read the flag. I included a PoC exploit and detailed commentary to help explain the process and concepts. Enjoy!

2015 Defcon Open CTF - Sigil of Darkness (64-bit exploit writeup)

August 8, 2015

Here is a writeup for the Open CTF's Sigil of Darkness pwnable challenge. This was a 64-bit exploit challenge where the payload was restricted to 16 bytes.

ROP your way out of python jail

2014 Plaid CTF - nightmares pwnables 375

April 16, 2014

Thank you PPP for another awesome year of Plaid CTF! Nothing captures my attention like a good Python jail, especially when you have to ROP your way out. ;)

Runasm - a simple tool for testing shellcode

August 8, 2013

When developing exploits, or writing stand-alone assembly in general, we want to test it with an isolated wrapper before introducing the complexities of the actual exploit. The usual method for doing this is either to link the object file into an ELF binary or to export the byte-code and paste it into a simple C file that jumps to it. While nothing is wrong with either of these methods, neither is particularly elegant. Here is my solution: mmap the assembled shellcode file to a new page in memory, mark it as executable, and jump to it. Here is the code - enjoy!

Here is how to use the tool:

gcc runasm.c -o runasm 
nasm helloworld.s
runasm helloworld

int main(int argc, char *argv[]) {
    int fdin = 0;
    off_t size;
    void (*shellcode)() = NULL; // shellcode is a pointer to a function that has no arguments

    /* open the input file */
    fdin = open(argv[1], O_RDONLY);
    if (fdin < 0) {
        fprintf(stderr, "Error opening %s for reading\n", argv[1]);
        return 1;

    /* find size of input file */
    size = lseek(fdin, 0, SEEK_END);
    if (size <= 0) {
        fprintf(stderr, "File (fd == %x) size error: %x\n", fdin, (unsigned int)size);
        return 1;
    lseek(fdin, 0, SEEK_SET);

    /* mmap the file to a new page and make it executable */
    shellcode = mmap(NULL, (int)size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE, fdin, 0);

    if (shellcode == MAP_FAILED) {
        fprintf(stderr, "Failed to mmap %x bytes at %p\n", (int)size, shellcode);

    /* jmp to the shellcode */
    return 0;

Legitbs CTF Quals - Reverse Engineering 1 writeup

June 17, 2013

The new organizers of the Defcon CTF tournament (LegitBS) definitely raised the exploitation bar this year. There were a lot of ARM and AMD64 binaries. Here is a writeup for the first reverse engineering (gnireegne lol) challenge which involved an ELF 32-bit binary and core file. (Spoiler: GDB process record and reply for the win).

Plaid CTF 2013 - Crypto 250 - Giga (RSA) Writeup

May 16, 2013

Recently our Neg9 crew participated in the Plaid CTF - a particularly high quality competition. It seemed that even the easiest binaries where compiled with a non-executable stack, ASLR was enabled, and many were 64-bit. We had a great time, thank you PPP for hosting! Two of my favorite challenges were Ropasaurusrex and Giga. Here is a writeup for Giga which was an RSA encryption service with a broken Random Number Generator (RNG). Get ready for some math!

Toorcon Seattle Talk - Blackmamba

June 18, 2011

Blackmamba is a new Python library I wrote to accelerate the process of building fast, concurrent brute force and discovery tools using Epoll and Coroutines. For more information see the following resources: