qangr Examples

2025-01-12

Quick Info

There are 2 required arguments for qangr, a good address and binary.

qangr -g 0x1337 chall

A good address would look something like a "Key Correct!" in a CrackMe or Binary.

Most CrackMe's or CTF Binaries will also output something like "Key Incorrect" if the key doesn't match the condition, this your bad address.

qangr -g 0x1337 -b 0x892e2 chall

If the binary is PIE enabled, use -B to specify a base address. You can also use -B auto to automatically determine a base address. If you forget to specify a base address and PIE is enabled, qangr will warn you.

qangr -g 0x1337 -b 0x892e2 -B auto chall

These will be the options of most use when using qangr to quickly pwn a CrackMe. Let's try pwning some challenges!

Example 1

Our first challenge is from CSDCTF.

Challenge Info

Fig.1

Decompiled it looks like this.

Challenge Decompiled

Fig.2 Binary Ninja

It looks pretty complex to reverse, qangr can buzz through it easy though.

00400247 syscall(sys_write {1}, fd: 1, buf: "Correct! The flag is: csd{", count: 0x1b)

This would be our good address as it says we are correct and we want to get to that.

time qangr -g 0x400247 ctf/re/practice-challs/mecrack2
[*] Exploring ts (this) 💔...
[*] Solution found: b'\xfa\xac\x01\xab\rGG\xf9'
qangr -g 0x400247 ctf/re/practice-challs/mecrack2  2.18s user 0.26s system 109% cpu 2.226 total
echo '\xfa\xac\x01\xab\rGG\xf9' | ctf/re/practice-challs/mecrack2
Enter the password: Correct! The flag is: csd{Cr4CkI35}

Nice, it found the solution and we got the flag! Reversing that manually would have been a challenge but the angr framework's incredible binary analysis and qangr's simplicity made it easy. Let's try another one!

Example 2

This challenge is from 247CTF.

Challenge Info

Fig.1

The title gives us a not so subtle hint towards using angr.

Challenge Decompiled

Fig.2 Binary Ninja

The function is massive and Binja doesn't even want to analyze it but we know we want to get to the flag function, so that will be our good address.

qangr -g 0x8048596 ~/ctf/re/practice-challs/angr-y_binary --binary-info
INFO     | 2025-01-12 15:40:50,314 | pwnlib.elf.elf | '/home/vipin/ctf/re/practice-challs/angr-y_binary'
Arch:       i386-32-little
RELRO:      Partial RELRO
Stack:      Canary found
NX:         NX enabled
PIE:        No PIE (0x8048000)
Stripped:   No
ELF('/home/vipin/ctf/re/practice-challs/angr-y_binary')
[*] Exploring ts (this) 💔...
WARNING  | 2025-01-12 15:40:50,506 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing register with an unspecified value. This could indicate unwanted behavior.
WARNING  | 2025-01-12 15:40:50,507 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING  | 2025-01-12 15:40:50,507 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING  | 2025-01-12 15:40:50,507 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING  | 2025-01-12 15:40:50,507 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING  | 2025-01-12 15:40:50,507 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x86286f1 (__libc_csu_init+0x1 in angr-y_binary (0x86286f1))
[*] Solution found: b'wgIdWOS6Df9sCzAfiK\x00\x00'
nc b7738e66a7b03881.247ctf.com 50405
Enter a valid password:
wgIdWOS6Df9sCzAfiK\x00\x00
247CTF{a3bbb9d2e648841d99e1cf4535a92945}

Example 3

This is another challenge from 247CTF but this time we need to crack a license key checker.

Challenge Info

Fig.1

Let's decompile the binary.

Challenge Decompiled

Fig.2 Binary Ninja

Our good address will be the win() function and our bad address will be the "Invalid Product Key!".

We will also use Depth First Search and since the binary is PIE enabled, we will also use -B auto.

time qangr -g 0x143f -b 0x144d -B AUTO --DFS ~/ctf/re/practice-challs/flag_keygen
[*] Exploring ts (this) 💔...
[*] Solution found: b'BMMLFZMZZZL@MPPULC@@UYQ@MNWMHHOM\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
./qangr.py -g 0x143f -b 0x144d -B AUTO --DFS   120.42s user 1.55s system 100% cpu 2:01.59 total
nc 86e9406c4b786e8b.247ctf.com 50252
Enter a valid product key to gain access to the flag:
BMMLFZMZZZL@MPPULC@@UYQ@MNWMHHOM
Valid product key!
247CTF{fb88b9fe80e969e73a27541f62d6f89c}

I’d say qangr is a quick and efficient tool for solving simple reverse engineering challenges. However, for more complex challenges, scripting with angr is a better approach.

For any work-related inquiries, please email me at vipin@vipin.xyz. If you want to chat with me, feel free to drop me a message on Discord