Meowww
chal.jpghack10{flag_here}1. Challenge Overview
The objective of this challenge is to discover a hidden payload hidden within a seemingly innocent image file (chal.jpg). According to the prompt, incident response personnel suspected attacker activity and malware delivery embedded in the image, pointing towards malicious command execution (which is eventually confirmed to be a PowerShell stage). We need to analyze the image, detect the steganography application used, extract the concealed data, and decode the payload to uncover the flag.
2. Initial Reconnaissance
We started the investigation by observing the file type and running basic forensics tools like file and exiftool to check for embedded metadata and trailing data.
1$ ls -la \&\& file chal.jpg \&\& exiftool chal.jpg2total 2683-rw-rw-r-- 1 nopalinto nopalinto 261423 Mar 27 10:01 chal.jpg4chal.jpg: JPEG image data, JFIF standard 1.02, resolution (DPI), density 72x72, segment length 16, baseline, precision 8, 1600x1598, components 35ExifTool Version Number : 13.506File Name : chal.jpg7Directory : .8File Size : 261 kB9File Type : JPEG10[...]11Image Size : 1600x1598Since the standard magic bytes were straightforward and the EOF marker ff d9 was at the expected offset, we proceeded to test for conventional steganography applications. Attempting to use steghide with a blank password yielded no results:
1$ steghide info chal.jpg -p ''2"chal.jpg":3 format: jpeg4 capacity: 16.0 KB5steghide: could not extract any data with that passphrase!3. Analysis / Forensics Path
Because steghide reported it "could not extract any data with that passphrase" instead of a flat "no steganographic data", there was an implication that steganographic content existed but was password-protected. I utilized stegseek along with the rockyou.txt wordlist to brute-force the password.
I manually downloaded and extracted the stegseek binary since system permission restrictions prevented normal installations:
1$ ./stegseek_bin/usr/local/bin/stegseek chal.jpg /usr/share/wordlists/rockyou.txt2StegSeek 0.6 - https://github.com/RickdeJager/StegSeek3[i] Found passphrase: "hidden"4[i] Original filename: "chal.ps1".5[i] Extracting to "chal.jpg.out".The extracted file naturally matched the implied threat actor lore—a PowerShell script payload (chal.ps1). Reading the extracted payload, we found heavily obfuscated PowerShell code using Base64 encoding wrapped in a Deflate stream.
1$ cat chal.jpg.out23(nEW-objECt SYstem.iO.COMPreSsIon.deFlaTEStREAm( [IO.mEmORYstreAM][coNVERt]::FROMBAse64sTRING( 'UzF19/UJV7BVUMpITM42NKguMCg3LopPMU42SDGuVQIA') ,[io.COmPREssioN.coMpreSSioNmODE]::DeCoMpReSS)| %{ nEW-objECt sYStEm.Io.StREAMrEADeR($_,[TeXT.encodiNG]::AsCii)} |%{ $_.READTOENd()})| \& ( $eNV:cOmSPEc[4,15,25]-JOin'')4. Exploitation / Recovery
The nested payload is structured around [Convert]::FromBase64String and feeds into System.IO.Compression.DeflateStream to decompress the next stage of the malware. To intercept and recover the exact payload without blindly detonating it on a Windows execution environment, we can simply recreate the inflation routine safely in Python.
Solver Python Script:
We use Python's built-in base64 and zlib libraries (using -zlib.MAX_WBITS to handle raw inflate/deflate streams correctly lacking standard header bytes).
1import base642import zlib3# The raw payload recovered from the extracted chal.ps1 PowerShell script4payload_b64 = 'UzF19/UJV7BVUMpITM42NKguMCg3LopPMU42SDGuVQIA'5# Decode Base64 string to raw bytes6compressed_bytes = base64.b64decode(payload_b64)7# Decompress using zlib with negative WBITS for raw Deflate streams8decompressed_stage = zlib.decompress(compressed_bytes, -zlib.MAX_WBITS)9# Output the hidden flag assigned to the variable10print("Recovered Payload:")11print(decompressed_stage.decode('utf-8'))Executing this one-liner equivalent recovers the plaintext directly into the terminal, revealing the variable name and the assigned flag.
1$ python3 -c "import base64, zlib; print(zlib.decompress(base64.b64decode('UzF19/UJV7BVUMpITM42NKguMCg3LopPMU42SDGuVQIA'), -zlib.MAX_WBITS))"23b'$5GMLW = "hack10{p0w3r_d3c0d3}"'5. Flag
6. Summary of Approach & Key Takeaways
Initial Recon: Verified the file was a valid standard image and checked strings/metadata. Steghide prompt hinted at password protection.
Brute-Force Extraction: Adopted an offline-attack tool (stegseek) against steghide steganography, quickly compromising the protection using the rockyou.txt wordlist (password: "hidden").
Payload Identification: Assessed the extracted stream as an intermediate and obfuscated PowerShell script relying on a compressed Base64 blob.
Offline Decryption: Defanged the shell payload safely by utilizing a fast python solver script to inverse the Zlib structure -WBITS parameter, recovering the raw flag inside the memory variable.
Takeaway: Never skip basic toolchain checks! Brute-forcing standard Steghide password vectors against benign-appearing images is an essential triage step in forensic and incident response scenarios. Safe unpacking techniques using languages like Python prevent analysts from running malicious payload logic on test environments blindly.