Description
We give you the PowerShell transformation script and the output file. Can you reverse it to find the input?
Setup
Download the PowerShell script and the output file.
wget <url>/script.ps1wget <url>/output.txtSolution
Walk me through it- Step 1Read the script to understand the transformationOpen script.ps1. It reads an input file as UTF-8, verifies each block of 6 characters consists of only '0' and '1', generates a list of pseudo-random seeds (one per block), then for each block calls a scramble function and XORs the result cumulatively, writing each cumulative XOR to output.txt. The output.txt has 264 lines.bash
cat script.ps1Learn more
The transformation has three stages:
- The input is 264 blocks of 6 binary digits (ones and zeros).
- Each block is scrambled using a seeded random number generator (the seed sequence is deterministic given the block count).
- Results are XORed cumulatively and written to output.txt.
To reverse it, undo the cumulative XOR first (XOR adjacent lines), then unscramble each block, then interpret each 6-bit block as a binary digit.
- Step 2Reverse the cumulative XORThe script accumulates XOR results across blocks. The first line of output is the XOR of block 0 alone. The second line is that XOR block 1. To undo, XOR each line with the previous line to isolate individual block results. Write a PowerShell (or Python) script that reproduces the same seed sequence and unscramble function.bash
# Reproduce the seed generation (copy from script.ps1): # RandomGen generates the same seed list given blocks.count = 264 # Run the unscramble logic in PowerShell: pwsh -File reverse.ps1Learn more
The seed sequence is deterministic: copy the
RandomGenfunction directly from script.ps1 withblocks.count = 264. The unscramble function is the inverse of scramble: where scramble replaces one binary character with a longer pattern, unscramble maps those patterns back to0or1. - Step 3Interpret the unscrambled blocks as binary and convert to ASCIIAfter reversing, each line has two 6-character blocks. The block with more '1' bits encodes a 1; the block with fewer '1' bits encodes a 0. Collect all bits and decode as 8-bit binary to ASCII. Use Python to do this final step.python
python3 << 'EOF' # Read the unscrambled blocks output from the PowerShell reverse step with open("unscrambled.txt") as f: lines = f.read().splitlines() bits = "" for line in lines: parts = line.split() # The block with more 1s encodes bit 1 g0, g1 = parts[0], parts[1] if g0.count("1") > g1.count("1"): bits += "1" else: bits += "0" # Decode 8 bits at a time to ASCII flag = "" for i in range(0, len(bits), 8): byte = bits[i:i+8] if len(byte) == 8: flag += chr(int(byte, 2)) print(flag) EOFLearn more
The encoding uses two variants of each binary digit: a pattern with more ones represents 1, and a pattern with fewer ones represents 0. This is a simple majority-vote encoding. After collecting all bits, reading them as 8-bit binary integers and converting to ASCII reveals the flag (printed multiple times in the output because of the cumulative structure).
Flag
picoCTF{...}
Reverse the cumulative XOR, unscramble each block using the same seed sequence, decode the bit encoding (more 1s = bit 1), then convert 8-bit groups to ASCII.