Oleg
Oleg
Platform: duckerz | Category: Forensics | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-09 | Status: Solved Techniques: utf16le_string_search, zipcrypto_known_plaintext_attack, mask_bruteforce
Summary
Task: recover the password for a protected GovSec ZIP using a VMware memory dump and the encrypted archive contents. Solution: treat the UTF-16LE flag-like string in memory as a stale decoy, recover ZipCrypto keys with bkcrack known plaintext, then brute-force only the changed suffix behind the stable prefix.
Oleg — duckerz
Description
The challenge provided two important artifacts: a VMware memory dump Oleg-GovSec.vmem and a password-protected archive Oleg/GovSec.zip. The goal was to recover the real archive password, which was also the flag.
Recon
The first useful observation was that this was not just a memory-forensics task. The archive itself mattered because it used legacy ZipCrypto, which is vulnerable to known-plaintext attacks.
Relevant files:
Oleg-GovSec.vmemOleg/GovSec.zip
Initial string searches through the dump quickly produced something that looked extremely convincing: a full DUCKERZ{...} value stored as UTF-16LE.
False Lead / Decoy
Searching the memory dump revealed this flag-like UTF-16LE string:
text read-only • copy allowedDUCKERZ{REDACTEDEKxuj0atl2D}
It matched the challenge theme perfectly and looked like the shared archive password mentioned in the scenario. However, testing it against the archive failed. This was the key turning point: the memory dump contained an old or stale password-like value, not the current one.
The important lesson is that a believable string found in memory is not automatically the live credential. Here the dump gave a stable prefix, but the suffix had changed.
ZipCrypto Recovery
Because GovSec.zip used legacy ZipCrypto, the better route was to recover the internal stream-cipher state with a known-plaintext attack. A good plaintext target was monitor.bat, using the decrypted file recovered from the archive contents.
bash read-only • copy allowedbkcrack -C "Oleg/GovSec.zip" -c monitor.bat -p govsec_decrypted/monitor.bat
Recovered ZipCrypto keys:
0eb36c3810584367983d6808
Once these keys were known, the task was no longer “guess the whole password”. It became “recover the real password that matches the already recovered ZipCrypto state”.
Final Password Recovery
The stale memory string was still useful because almost all of it looked stable. Instead of brute-forcing a full flag, it was enough to keep the fixed prefix and search only the unknown suffix with a mask.
bash read-only • copy allowedbkcrack -k 0eb36c38 10584367 983d6808 -m 'DUCKERZ{REDACTED?a?a?a?a?a?a?a?a?a}' -j 8
This quickly recovered the real password:
text read-only • copy allowedDUCKERZ{REDACTED}
Verification:
bash read-only • copy allowed7z t -p'DUCKERZ{REDACTED}' 'Oleg/GovSec.zip'
Expected result:
text read-only • copy allowedEverything is Ok
Minimal Reproduction Script
python read-only • copy allowed#!/usr/bin/env python3 import subprocess zip_path = "Oleg/GovSec.zip" known_plaintext = "govsec_decrypted/monitor.bat" keys = ["0eb36c38", "10584367", "983d6808"] mask = "DUCKERZ{REDACTED?a?a?a?a?a?a?a?a?a}" subprocess.run([ "bkcrack", "-C", zip_path, "-c", "monitor.bat", "-p", known_plaintext, ], check=False) subprocess.run([ "bkcrack", "-k", *keys, "-m", mask, "-j", "8", ], check=False)