[CTF] WU - SHIT I GOT TO GO!
CTF InterCampus Ynov 2024
Difficulty Level : Insane
Challenge Category : Malware
Description :
During routine system maintenance, I accidentally executed this suspicious program. Shortly after, I discovered that all my files had been encrypted. Can you extract the script responsible for the encryption.
Can you analyze the script and recover the flag.
DISCLAIMER !!!! REAL MALWARE BE CAREFUL !!!
Challenge Overview
You are provided with a PowerPoint file containing embedded macros. At first glance, opening the file does not reveal any noticeable activity. However, upon closer inspection, the macros reveal the presence of three modules, each containing distinct PowerShell scripts.
The scripts implement an RSA encryption scheme involving the following variables:
- e: The public exponent
- d: The private exponent
- Z: A value related to the RSA modulus (n).
A crucial hint is discovered within the macros, indicating that d and Z together encode information about the prime factors P and Q of n. These primes are critical for understanding and breaking the RSA encryption.
Challenge Objective
To solve the challenge, you must reverse-engineer the RSA process and brute-force a missing factor k in the equation:
n = (k * e * d - 1) + Z - 1
Where:
- n: RSA modulus
- e: Public exponent
- d: Private exponent
- Z: Value derived from the prime factors (P and Q)
- k: An unknown integer factor to be brute-forced.
The goal is to determine the missing factor k, which enables the reconstruction of n and, consequently, the RSA private key.


Tools and Techniques
- Macro Analysis: Tools like
oletools
orVBA Editor
to extract and analyze the PowerShell scripts embedded in the macros. - Brute-Forcing k: A Python or PowerShell script to iterate over potential k values and solve the equation.
- Libraries : pycryptodome & tqdm
Python Script for Brute-Forcing k
from Crypto.Util.number import *
from tqdm import *
Z = 23708477623422123989911840509603682236427243837909957142649477995756613551417771108814520918899394732450559929795498438009915928437053853511525438092891944
e = 65537
d = 17409852817563021737163902989212279100735120175418641008244781705876293551110148109904232413623854677476746990875790644057589605168375455792794919949833451395040211778229858312334988138987353959934801123972615827275654741061592388665207758027411963916915266233226516186035198670053990698284286950107833088273
ct = 112569996888684048707974554874760082093999450193432783850566443882311920857206710400131003272094451780670160584517262126075672560570102442431915552711774933491099227555584450258514686020607237282307281443480739470228480229923701086866291637098549717882217161302754466078414381717166307312901131329539364669836
for k in trange(1, e):
n = ((e * d - 1) // k) + Z - 1
flag = long_to_bytes(pow(ct, d, n))
if b"FLAG" in flag:
print(flag)
break
