Proton X1337
1. Challenge Overview
We are provided with an Android APK file ProtonX1337.apk. According to the challenge description:
> "This file seems normal and safe. But it is actually maliciously, secretly transmitting data to a C2. Identify the server, and find the flag."
The objective is to reverse engineer the APK, identify the Command \& Control (C2) server URL that the malicious app communicates with, and retrieve the flag from that server.
2. Initial Reconnaissance
File Type Identification
1$ file ProtonX1337.apk23ProtonX1337.apk: Zip archive data, at least v0.0 to extract, compression method=storeAPK Structure Analysis
1$ unzip -l ProtonX1337.apk | head -502Archive: ProtonX1337.apk3 Length Date Time Name4--------- ---------- ----- ----5 29116 1981-01-01 01:01 classes2.dex6 56 1981-01-01 01:01 META-INF/com/android/build/gradle/app-metadata.properties7 12928 1981-01-01 01:01 classes4.dex8 22228 1981-01-01 01:01 classes3.dex9 1738 1981-01-01 01:01 DebugProbesKt.bin10...The APK contains multiple DEX files (classes.dex through classes5.dex), indicating a Kotlin/Android Compose application.
String Analysis on DEX Files
1$ strings apk_extracted/classes*.dex | grep -iE "(http|https|url|c2|server|flag|hack10|HACK)" | head -502SESSION_TOKEN=HACK10{n0t_A_Fl4g}3backdoorC24https://appsecmy.com/Key findings:
A decoy flag: SESSION_TOKEN=HACK10{n0t_A_Fl4g} (this is NOT the real flag!)
A backdoorC2 function exists in the code
A potential C2 URL: https://appsecmy.com/
3. Analysis / Forensics Path
APK Decompilation with apktool
1$ apktool d ProtonX1337.apk -o apktool_output -f2I: Decoding values */* XMLs...3I: Baksmaling classes.dex...4I: Baksmaling classes2.dex...5I: Baksmaling classes4.dex...6I: Baksmaling classes3.dex...7I: Baksmaling classes5.dex...8I: Copying assets and libs...9I: Copying unknown files...10I: Copying original files...11I: Copying META-INF/services directoryLocating the backdoorC2 Function
1$ find apktool_output -name "*.smali" | xargs grep -l "backdoorC2" 2>/dev/null2apktool_output/smali_classes3/com/example/protonx1337/MainActivity.smali3apktool_output/smali_classes3/com/example/protonx1337/MainActivity$backdoorC2$1.smali4apktool_output/smali_classes3/com/example/protonx1337/LiveLiterals$MainActivityKt.smaliAnalyzing the C2 URL Construction
The backdoorC2 function in MainActivity$backdoorC2$1.smali constructs the C2 URL by concatenating two strings (d1 and d2) retrieved from LiveLiterals$MainActivityKt:
1.line 702sget-object v4, Lcom/example/protonx1337/LiveLiterals$MainActivityKt;->INSTANCE:Lcom/example/protonx1337/LiveLiterals$MainActivityKt;3invoke-virtual {v4}, Lcom/example/protonx1337/LiveLiterals$MainActivityKt;->String$val-d1$try$fun-$anonymous$$arg-5$call-thread$fun-backdoorC2$class-MainActivity()Ljava/lang/String;4move-result-object v45.line 716sget-object v5, Lcom/example/protonx1337/LiveLiterals$MainActivityKt;->INSTANCE:Lcom/example/protonx1337/LiveLiterals$MainActivityKt;7invoke-virtual {v5}, Lcom/example/protonx1337/LiveLiterals$MainActivityKt;->String$val-d2$try$fun-$anonymous$$arg-5$call-thread$fun-backdoorC2$class-MainActivity()Ljava/lang/String;8move-result-object v5Extracting the Actual C2 URL
In LiveLiterals$MainActivityKt.smali, the string constants are defined:
1const-string v0, "https://appsecmy.com/"2sput-object v0, Lcom/example/protonx1337/LiveLiterals$MainActivityKt;->String$val-d1$try$fun-$anonymous$$arg-5$call-thread$fun-backdoorC2$class-MainActivity:Ljava/lang/String;3const-string v0, "pages/liga-ctf-2026"4sput-object v0, Lcom/example/protonx1337/LiveLiterals$MainActivityKt;->String$val-d2$try$fun-$anonymous$$arg-5$call-thread$fun-backdoorC2$class-MainActivity:Ljava/lang/String;Full C2 URL: https://appsecmy.com/pages/liga-ctf-2026
4. Exploitation / Recovery
Fetching the C2 Server
With the C2 URL identified, we fetch the page content:
1$ curl -s "https://appsecmy.com/pages/liga-ctf-2026" | tail -20The page returns a LIGA CTF 2026 promotional webpage. However, examining the raw HTML source reveals an HTML comment containing the flag:
1$ curl -s "https://appsecmy.com/pages/liga-ctf-2026" | grep -i "HACK10"23 <!-- HACK10{j3mpu7_s3r74_0W4SP_C7F} -->Complete Analysis Script
1#!/usr/bin/env python32"""3Proton X1337 CTF Challenge Solver4Category: Reverse Engineering5"""6import subprocess7import re8import os9def main():10 apk_file = "ProtonX1337.apk"11 print("[*] Step 1: Extracting APK contents...")12 os.makedirs("apk_extracted", exist_ok=True)13 subprocess.run(["unzip", "-o", apk_file, "-d", "apk_extracted/"], 14 capture_output=True)15 print("[*] Step 2: Searching for C2 indicators in DEX files...")16 result = subprocess.run(17 "strings apk_extracted/classes*.dex | grep -iE '(http|backdoor|c2)'",18 shell=True, capture_output=True, text=True19 )20 print(result.stdout)21 print("[*] Step 3: Decompiling with apktool...")22 subprocess.run(["apktool", "d", apk_file, "-o", "apktool_output", "-f"],23 capture_output=True)24 print("[*] Step 4: Extracting C2 URL from LiveLiterals smali...")25 with open("apktool_output/smali_classes3/com/example/protonx1337/"26 "LiveLiterals$MainActivityKt.smali", "r") as f:27 content = f.read()28 # Extract d1 (base URL)29 d1_match = re.search(r'const-string v0, "(https://[^"]+)".*String\\$val-d1', 30 content, re.DOTALL)31 d1 = d1_match.group(1) if d1_match else ""32 # Extract d2 (path)33 d2_match = re.search(r'const-string v0, "([^"]+)".*String\\$val-d2', 34 content, re.DOTALL)35 d2 = d2_match.group(1) if d2_match else ""36 c2_url = d1 + d237 print(f"[+] C2 URL Found: {c2_url}")38 print("[*] Step 5: Fetching flag from C2 server...")39 result = subprocess.run(["curl", "-s", c2_url], capture_output=True, text=True)40 flag_match = re.search(r'HACK10{[^}]+}', result.stdout)41 if flag_match:42 print(f"\\n[+] FLAG CAPTURED: {flag_match.group(0)}")43 else:44 print("[-] Flag not found in response")45if __name__ == "__main__":46 main()5. Flag
6. Summary of Approach & Key Takeaways
Step-by-Step Methodology
File Identification: Confirmed the file is a valid Android APK (ZIP archive containing DEX files)
String Extraction: Used strings on DEX files to identify suspicious strings:
Found a decoy flag HACK10{n0t_A_Fl4g} (trap for quick-solvers)
Discovered backdoorC2 function reference
Located partial C2 URL https://appsecmy.com/
APK Decompilation: Used apktool to convert DEX to Smali bytecode for detailed analysis
Smali Analysis: Traced the backdoorC2 function to understand URL construction:
The app uses Kotlin's LiveLiterals for storing string constants
C2 URL is split into two parts (d1 and d2) and concatenated at runtime
C2 URL Reconstruction: Combined the extracted strings:
d1 = "https://appsecmy.com/"
d2 = "pages/liga-ctf-2026"
Full URL: https://appsecmy.com/pages/liga-ctf-2026
Flag Retrieval: Fetched the C2 endpoint and found the flag hidden in an HTML comment
Key Takeaways
Beware of Decoy Flags: The HACK10{n0t_A_Fl4g} was intentionally placed to mislead solvers who don't fully analyze the code
Kotlin LiveLiterals: Modern Android apps using Jetpack Compose may store string constants in LiveLiterals classes for hot-reload functionality during development
Split URL Construction: Malware often splits malicious URLs into multiple parts to evade static analysis and string-based detection
HTML Comments: Flags or sensitive information can be hidden in HTML comments - always view raw source code
Static Analysis is Sufficient: This challenge didn't require dynamic analysis (emulation/debugging) - careful static analysis of smali code revealed all necessary information
Tools Summary
| Tool | Purpose |
|---|---|
file | File type identification |
unzip | APK extraction |
strings | String extraction from binaries |
grep | Pattern searching |
apktool | APK decompilation to Smali |
curl | HTTP requests to C2 server |