This forensics challenge was the easiest one in this CTF

We were given the same 2 AD1 files as evidences for the 4 forensics challs. It is a pretty uncommon file type, let’s use FTK Imager on Windows.

Investigation

After extracting all the files using FTK Imager, we have access to 3 main Windows Folders : Programs, Users and Riot Games.

After searching a bit, we notice a Riot Vanguard folder in Programs that contains logs. The name is a bit too similar to the title of the challenge for it to be a coincidence.

Vanguard is the anti-cheat system used by Riot for Valorant.

The logs seem to be encrypted.

Vanguard Logs Decryptor

After searching for a bit, I was able to find a Vanguard Logs Decryptor written in python. https://www.unknowncheats.me/forum/anti-cheat-bypass/488665-vanguard-log-decryptor.html

After customizing it for a bit in order to decrypt all the logs and write the decrypted data in a new file, here is the script:

import struct
import sys
import glob, os
    
def rc4(data, key):
    S = [i for i in range(256)]
    j = 0
    out = []
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]
    i = j = 0
    for char in data:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        out.append(char ^ S[(S[i] + S[j]) % 256])
    return bytearray(out)
    
    
KEYMASK = [0xB1, 0x54, 0x45, 0x57, 0xA7, 0xC4, 0x64, 0x2E,
            0x98, 0xD8, 0xB1, 0x1A, 0x0B, 0xAA, 0xD8, 0x8E,
            0x7F, 0x1E, 0x5B, 0x8D, 0x08, 0x67, 0x96, 0xCB,
            0xAA, 0x11, 0x50, 0x84, 0x17, 0x46, 0xA3, 0x30]
    
loglist = []
os.chdir("./")
for file in glob.glob("*.log"):
    loglist.append(file)
BIGOUTPUT = open("output/big.txt","w")
for f in loglist:
    OUTPUT = open("output/"+f+"_dec.log","w")
    DATA = open(f, 'rb').read()
    DATA = DATA[4:]
    REAL_KEY = [DATA[i] ^ KEYMASK[i] for i in range(32)]
    DATA = DATA[32:]
    while len(DATA) > 0:
        BLOCK_LEN = struct.unpack('<L', DATA[:4])[0]
        DATA = DATA[4:]
        OUTPUT.write(rc4(DATA[:BLOCK_LEN], REAL_KEY).decode('utf-16'))
        BIGOUTPUT.write(rc4(DATA[:BLOCK_LEN], REAL_KEY).decode('utf-16'))
        DATA = DATA[BLOCK_LEN:]
    OUTPUT.close()
BIGOUTPUT.close()

We find the flag by searching for the vsctf string in the output file big.txt.

Flag

vsctf{0h_w0W!_v4Ngu4rd_l0Gs_d3CrYpt3D_sHh!!_d0Nt_T3Ll_3vErd0X_>:(}