Recent posts

HITCON CTF Quals 2017 - Seccomp

ELF x64 reversing challenge.

1. The main function

It is a small program. This program hides its core logic inside the seccomp syscall filter rule, and requires us to figure out the correct syscall arguments.

The filter rules stored at 0x201020 can be easily decoded using seccomp-tools. I have used bpftools for the decoding purpose, but outputs from seccomp-tools are more human-readable.

Read more

HITCON CTF Quals 2017 - Impeccable Artifact

Linux ELF pwnable challenge.

完美無瑕 ~Impeccable Artifact~
Overwhelmingly consummate protection

제목은 우리말로 “완전무결” 정도 되겠다. PIE가 걸린 x64 ELF 바이너리와 바이너리를 주었다.

1. Sandbox

프로그램이 실행되면 우선 아래와 같은 seccomp 시스템 콜 필터가 걸린다.

Read more

Building custom kernel

Use VM when you practice, just in case.

1. Download kernel

Download from
For example,

sudo apt-get install -y wget xz-utils
tar xf linux-4.9.28.tar.xz

2. Make your modification

Patch the files, add code, … etc.

3. Config

Copy current setting.

sudo cat /boot/config-`uname -r` > .config
make olddefconfig

4. Build

make -j4
make -j4 modules

5. Install

sudo make modules_install
sudo make install

Files will be written to /boot directory.

6. Reboot

Reboot the computer. If anything goes wrong, reboot again and select original kernel.

(Optional) Change default boot kernel

See here

Codegate 2017 finals - BMP

BMP is a Windows pwnable task.


1. Reversing

This program opens a BMP image and extracts LSB of each pixel. Then they are saved as another BMP image (*_out.bmp). The image can be opened by either “File > Open” menu or command line argument.

The main logic looks like this:

Read more

Codegate 2017 quals - meow

Linux ELF binary and a service port is given. So I assume it’s a pwnable task.

1. First look

This binary receives 10 byte input and checks its MD5 hash. If the check passes, the string is used to decrypt two data blobs. Then two decrypted blobs are mmaped to fixed addresses 0x12000 and 0x14000 with RWE permission. Then at the end of the program, we can ‘call’ the code at 0x12000 just like a function.

Since finding preimage of the MD5 hash is hopeless, our goal is now finding the 10 byte key that makes the decoded blob plausible. To do that, we had to analyze the decryption function 0xD1D. But I felt I will definitely make mistake during understanding it. So my teammate took another way.

2. Simplifying the decryption routine

The decryption seemed to be composed of simple XORs. So we used angr to derive the symbolic relation between input and output.

First load the binary in angr.

import angr
proj = angr.Project('./meow')

Read more