N
Back to writeup archive
Hack@10 International Capture The Flag Pre-Eliminary Round 2026

Proton X1337

APK decompilation, hidden C2 reconstruction, and server-side flag retrieval.

Reverse EngineeringMarkdown + PDFMediumsolved2 minread·534words
route
/TryN3rr0r/writeups/hack10-pre-eliminary-2026/proton-x1337
archive index
7 / 15
read mode
parsed markdown
Writeup loaded.

Proton X1337

challenge brief
target profile, scoring, and execution stack
verified solve
target
ProtonX1337.apk
category
Reverse Engineering
points
500
difficulty
Medium
flag format
HACK10{flag_here}
tools used
fileunzipstringsgrepapktoolcurlweb browser
final flag
HACK10{j3mpu7_s3r74_0W4SP_C7F}
reveal and copy from section 5

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.

PDF evidence frame 01

2. Initial Reconnaissance

File Type Identification

bash3 lines
1$ file ProtonX1337.apk23ProtonX1337.apk: Zip archive data, at least v0.0 to extract, compression method=store

APK Structure Analysis

bash10 lines
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

bash4 lines
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/
PDF evidence frame 02

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

bash11 lines
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 directory

Locating the backdoorC2 Function

bash4 lines
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.smali

Analyzing 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:

smali8 lines
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 v5

Extracting the Actual C2 URL

In LiveLiterals$MainActivityKt.smali, the string constants are defined:

smali4 lines
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

PDF evidence frame 03

4. Exploitation / Recovery

Fetching the C2 Server

With the C2 URL identified, we fetch the page content:

bash1 lines
1$ curl -s "https://appsecmy.com/pages/liga-ctf-2026" | tail -20

The page returns a LIGA CTF 2026 promotional webpage. However, examining the raw HTML source reveals an HTML comment containing the flag:

bash3 lines
1$ curl -s "https://appsecmy.com/pages/liga-ctf-2026" | grep -i "HACK10"23    <!-- HACK10{j3mpu7_s3r74_0W4SP_C7F} -->
PDF evidence frame 04

Complete Analysis Script

python46 lines
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

captured flag
HACK10{j3mpu7_s3r74_0W4SP_C7F}

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

ToolPurpose
fileFile type identification
unzipAPK extraction
stringsString extraction from binaries
grepPattern searching
apktoolAPK decompilation to Smali
curlHTTP requests to C2 server