- Published on
CodeFestCTF'25 - Forensics - Password Recovery
- Authors
- Name
- Muhammad Haris
- @ArcusTen
Challenge Description

Solution
The provided binary passgen
generates a password based on current time:

Binary disassembly:
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
int i; // [rsp+Ch] [rbp-64h]
char v6[16]; // [rsp+10h] [rbp-60h] BYREF
char v7[72]; // [rsp+20h] [rbp-50h] BYREF
unsigned __int64 v8; // [rsp+68h] [rbp-8h]
v8 = __readfsqword(0x28u);
banner(argc, argv, envp);
strcpy(v7, "abcdefghijklmnoqprstuvwyzxABCDEFGHIJKLMNOQPRSTUYWVZX0123456789");
v3 = time(0LL);
srand(v3);
for ( i = 0; i <= 14; ++i )
v6[i] = v7[rand() % 62];
v6[15] = 0;
printf("[*] HERE IS YOUR SECURELY GENERATED PASSWORD: %s\n", v6);
return 0;
}
Here we can see that the password is generated using the srand
function. The seed for the srand
function is the current time.
v3 = time(0LL);
srand(v3);
If you dont know, srand
function generates same result for same seed which means if we generate 2 password at the same time (like 20:55.13
), we will get the same password.

So in thoery, 86,400
passwords can be generated in a day.
What if we bruteforce the password by generating the password for each second of Jan 26, 2019 (republic day india 2019) and try to extract the zip file using that?
This script bruteforce all passwords starting from 00:00:00 and up till 23:59:59 (date: 26th Jan 2019) and tries to extract the zip file using the generated password.
import os
import ctypes
import zipfile
from datetime import datetime, timedelta
from pwn import log
libc = ctypes.CDLL('/lib/x86_64-linux-gnu/libc.so.6')
def c_srand(seed):
libc.srand(seed)
def c_rand():
return libc.rand()
def genPassword(seed_time):
c_srand(int(seed_time))
charset = "abcdefghijklmnoqprstuvwyzxABCDEFGHIJKLMNOQPRSTUYWVZX0123456789"
password = ''
for _ in range(15):
index = c_rand() % len(charset)
password += charset[index]
log.info(f"Generated password: {password}")
return password
def bruteForceZIP(zipPath):
print(f"[INFO] Starting brute force on ZIP file '{zipPath}'")
start_time = datetime(2019, 1, 26, 0, 0, 0)
end_time = datetime(2019, 1, 26, 23, 59, 59)
current_time = start_time
with open('generated_passwords.txt', 'w') as password_file:
while current_time <= end_time:
password = genPassword(current_time.timestamp())
password_file.write(password + '\n')
try:
with zipfile.ZipFile(zipPath, 'r') as zf:
zf.extractall(pwd=password.encode('utf-8'))
'''Checking size of flag to see if original flag is retrieved'''
if os.path.exists('flag.txt'):
flag_size = os.path.getsize('flag.txt')
if flag_size > 0:
log.success(f"Password found:- {password}")
log.success(f"Time used:- {current_time}")
log.success(f"Flag retrieved successfully ({flag_size} bytes).")
return password
else:
log.warn(f"Password failed: `flag.txt` is empty.")
else:
log.warn(f"Password failed: `flag.txt` not created.")
except (RuntimeError, zipfile.BadZipFile) as e:
log.warn(f"Exception occurred: {e}")
current_time += timedelta(seconds=1)
print("[ERROR] No password found.")
return None
if __name__ == '__main__':
zipPath = 'encrypted.zip'
if os.path.exists(zipPath):
bruteForceZIP(zipPath)
else:
log.warn(f"'{zipPath}' help :(")
Flag:
