Description
Hmm, SGX is hard. Can you try to recreate the algorithm? Analyze the provided files to understand the encryption and recover the flag.
Setup
Download the provided files (enclave binary, encrypted data, or source).
wget https://mercury.picoctf.net/static/.../fault1.tar.gz && tar xvf fault1.tar.gzSolution
Walk me through itset $rip = $rip + N or jump *addr) used here to simulate a fault.- Step 1Identify the fault-injection modeThis challenge simulates instruction skipping: there is a check inside the enclave that, in a real attack, would be bypassed by glitching power or clock at the exact moment the conditional executes. You reproduce that by jumping past the check in GDB.bash
ls -la fault1/bashgrep -nE 'verify|check|fault|skip' fault1/*.c fault1/*.py 2>/dev/nullLearn more
Fault-injection taxonomy:
- Bit-flip: attacker corrupts a single memory bit (rowhammer, cosmic ray simulation). Useful against key bytes or jump targets.
- Voltage/clock glitch: drop the CPU's supply voltage or clock for a few nanoseconds, causing one ALU operation to produce a wrong result. Common against signature-verify chains (
cmpreturns equal even when the buffers differ). - Instruction skip: the same glitch tuned more aggressively makes the CPU treat the next instruction as a NOP. Bypasses access-control checks like
if (!authenticated) return -1;.
CTF challenges almost always simulate instruction skip because it's the cleanest to reason about: you find the check in the disassembly and step past it in GDB.
- Step 2Examine the provided filesList and read the extracted files. Look for the encryption algorithm implementation - it may be in a C source file, a compiled enclave binary, or accompanying Python script.bash
ls -labashfile *bashcat *.py 2>/dev/nullbashcat *.c 2>/dev/nullbashstrings *.so 2>/dev/null | grep -v lib | head -30Learn more
Intel SGX (Software Guard Extensions) creates encrypted, isolated execution environments called enclaves. Code and data inside an enclave are protected from the operating system, hypervisor, and other processes - even the system owner cannot read enclave memory. SGX is used for trusted computing, DRM, and secure key storage.
In this CTF context, the challenge simulates an SGX-like scenario where an algorithm runs inside a protected environment. You are given the algorithm's description or implementation and asked to either reproduce it, reverse it, or find a weakness in it.
- Step 3Analyze and implement the algorithmRead the algorithm implementation carefully. Identify the transformation applied to the flag, then implement the inverse in Python to decrypt the provided ciphertext.python
python3 - <<'EOF' # Implement the algorithm found in the provided files # and reverse it to recover the flag ciphertext = bytes.fromhex('PASTE_CIPHERTEXT_HERE') # Example: XOR-based custom cipher key = b'PASTE_KEY_OR_DERIVE_IT_HERE' flag = bytes(c ^ key[i % len(key)] for i, c in enumerate(ciphertext)) print(flag.decode('ascii', errors='replace')) EOFLearn more
Three reversal patterns by algorithm shape.
- Self-inverse (XOR-only). If the cipher is
c = p XOR k, run the exact same operation oncto recoverp. This is true for any byte-wise XOR scheme regardless of howkis generated, because(p XOR k) XOR k = p. - Invertible bijection. If the cipher is a sequence of operations like
add k,multiply by m mod 256,permute bytes- apply the inverses in reverse order:unpermute,multiply by m^(-1) mod 256,subtract k. The inverse ofm mod 256exists iffgcd(m, 256) = 1- i.e.,mis odd. - Known-plaintext key recovery. If the algorithm is
c[i] = p[i] XOR k[i % keylen]and you know any plaintext bytes, recover the corresponding key bytes viak[i % keylen] = p[i] XOR c[i]. The flag prefixpicoCTF{is 8 known bytes - enough to recover an 8-byte key directly.
Worked example. Suppose the algorithm is
c[i] = (p[i] * 17 + k[i mod 4]) mod 256with keyk = [3, 7, 11, 13]. Inverse:17 mod 256 has inverse 241 (since 17*241 = 4097 = 16*256 + 1) For each i: p[i] = ((c[i] - k[i mod 4]) * 241) mod 256 Verify: encrypt p='A' (65) with k[0]=3: c = (65*17 + 3) mod 256 = 1108 mod 256 = 84 Decrypt: p = ((84 - 3) * 241) mod 256 = 19521 mod 256 = 65 ✓Why "security through enclave" is not security. Intel SGX hides code from the OS, but the binary on disk is still readable. Reverse-engineering the enclave (Ghidra, IDA, even
strings) usually exposes the algorithm. SGX defends only against "cold" OS-level attackers, not against anyone who can analyze the binary - so any cryptographic strength must come from the algorithm itself, not from the wrapper. - Self-inverse (XOR-only). If the cipher is
- Step 4Skip the check in GDB to simulate the faultFind the conditional jump that gates the flag print in the disassembly, break right before it, and either skip past the check with set $rip or jump straight to the success branch.bash
gdb -q ./fault1bash(gdb) disas check_password # locate the je/jne after cmpbash(gdb) break *0x401234 # address of the conditional jumpbash(gdb) runbash(gdb) set $rip = $rip + 2 # skip a 2-byte je instructionbash# or jump to the success branch directly:bash(gdb) jump *0x40128abash(gdb) continueLearn more
Both primitives, when to use each.
set $rip = $rip + Nadvances the instruction pointer by exactlyNbytes - good when you want to skip a single short instruction (a 2-byteje, a 6-bytecall) without disturbing surrounding state.jump *addrteleports execution to a specific address; use it when you've identified the start of the success branch and want to leap past several instructions at once.Use
x/i $ripafter the move to confirm you landed on a sane instruction. Landing mid-instruction produces immediate undefined behavior.
Flag
picoCTF{...}
The challenge simulates an instruction-skip fault - jump past the verify branch in GDB and the enclave hands over the flag.