🚩 CTF Writeup: Activation Challenge
📋 Informasi Challenge
- Kategori:
Reverse Engineering- Tingkat Kesulitan:
Medium- Format File:
PE32 .NET Executable- Nama File:
aktivasi.exe- Platform: FGTE CTF
- Objective: Temukan username dan license yang valid.
1. Reconnaissance & Initial Analysis
1.1 Eksekusi Awal Program
Pertama-tama, saya menjalankan binary untuk memahami perilakunya:
$ chmod +x ./aktivasi.exe
$ ./aktivasi.exe
> aktivasi v1.0
> Usage: aktivasi.exe <username> <license>
Temuan Awal:
- Program memerlukan 2 argumen:
usernamedanlicense. - Aplikasi command-line sederhana.
1.2 Testing dengan Input Random
$ ./aktivasi.exe RANI salt_part_1_from_cre
> aktivasi v1.0
> Invalid license.
Analisis: Program memvalidasi username dan license. Pesan "Invalid license" menunjukkan bahwa mungkin username sudah benar (atau belum divalidasi), namun license salah.
2. Identifikasi Tipe Binary
Menggunakan command file untuk melihat arsitektur:
$ file aktivasi.exe
aktivasi.exe: PE32 executable for MS Windows 4.00 (console), Intel i386 Mono/.Net assembly, 4 sections
Implikasi:
- Mono/.Net assembly: KUNCI PENTING. Ini adalah aplikasi .NET.
- Kita bisa menggunakan ILSpy atau dnSpy untuk melakukan Decompile (mendapatkan source code asli), bukan sekadar Disassemble.
3. String Analysis
Ekstraksi string untuk mencari petunjuk awal:
$ strings aktivasi.exe | grep -i "salt\|flag\|license\|key" | head -10
saltChunks
license
set_KeySize
set_Key
GetSalt
ExpectedLicense
DeriveKeyFromLicense
Analisis String:
ExpectedLicense: Kemungkinan fungsi validasi utama.DeriveKeyFromLicense: Mengindikasikan license digunakan untuk membuat kunci (KDF).saltChunks: Array yang menyimpan potongan-potongan salt.
4. Decompilation dengan ILSpy
Karena ini file .NET, saya menggunakan ilspycmd untuk mendapatkan kode sumbernya.
ilspycmd aktivasi.exe > source.cs
Berikut adalah hasil decompile yang telah dibersihkan:
🔻 Klik untuk melihat Solver Code
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ActivatorApp;
internal class Program
{
// [DATA HARDCODED]
private static readonly string[] userChunks = new string[1] { "UkFOSQ==" };
private static readonly string[] saltChunks = new string[4] {
"c2FsdF9w", "YXJ0XzFf", "ZnJvbV9j", "cmU="
};
// Encrypted Blob (Flag) - 64 Bytes
private static readonly byte[] encryptedBlob = new byte[64] { ... };
// [FUNGSI UTAMA]
private static string GetEmbeddedUsername() { ... }
private static byte[] GetSalt() { ... }
// Core Logic
private static string ExpectedLicense(string username) { ... }
private static byte[] DeriveKeyFromLicense(string license) { ... }
private static string DecryptBlob(byte[] key) { ... }
private static void Main(string[] args) {
// Logic validasi argumen ada di sini
}
}
5. Analisis Source Code
5.1 Static Data Extraction
Dari kode di atas, kita bisa mendekode data penting:
A. Username
"UkFOSQ=="
- Decode:
Base64("UkFOSQ==")→RANI
B. Salt
"c2FsdF9w" + "YXJ0XzFf" + "ZnJvbV9j" + "cmU="
- Gabungan:
c2FsdF9wYXJ0XzFfZnJvbV9jcmU= - Decode:
salt_part_1_from_cre
6. Reverse Engineering Algoritma
Mari kita bedah fungsi kriptografinya.
A. Pembuatan License (ExpectedLicense)
Algoritma validasi license adalah sebagai berikut:
- Ambil Salt (
salt_part_1_from_cre). - Hitung HMAC-SHA256 dari
username("RANI") menggunakan keySalt. - Ambil 8 Byte pertama dari hash.
- Konversi ke Hex String (Uppercase).
Simulasi Manual:
Key = "salt_part_1_from_cre"
Message = "RANI"
HMAC = HMAC-SHA256(Key, Message)
Result = 0905E413DDF6D48B... (panjang)
License = 0905E413DDF6D48B (16 char pertama)
B. Derivasi Kunci AES (DeriveKeyFromLicense)
Setelah license valid, kunci enkripsi dibuat dengan cara:
- Gabungkan string:
License + Base64(Salt). - Hash menggunakan SHA256.
- Ambil 16 Byte pertama sebagai AES-128 Key.
C. Dekripsi Flag (DecryptBlob)
- Ambil 16 byte pertama dari
encryptedBlobsebagai IV. - Sisanya adalah Ciphertext.
- Dekripsi menggunakan AES-128-CBC (PKCS7 Padding).
7. Implementasi Solver Script
Saya membuat script Python untuk menghitung license dan mendekripsi flag secara otomatis.
🔻 Klik untuk melihat Solver.py
#!/usr/bin/env python3
"""
CTF Solver: Activation Challenge
Author: rwx4m
"""
import hmac
import hashlib
import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
# 1. SETUP DATA
USER_B64 = "UkFOSQ=="
SALT_CHUNKS = ["c2FsdF9w", "YXJ0XzFf", "ZnJvbV9j", "cmU="]
ENCRYPTED_BLOB = bytes([
167, 164, 179, 68, 122, 43, 220, 205, 221, 237,
252, 140, 94, 60, 228, 168, 158, 24, 12, 211,
42, 196, 123, 129, 112, 31, 108, 142, 85, 169,
138, 71, 23, 244, 193, 140, 102, 155, 201, 244,
183, 5, 176, 49, 163, 24, 215, 196, 212, 215,
159, 80, 85, 221, 12, 234, 16, 7, 169, 163,
172, 218, 85, 246
])
# 2. DECODE STATIC DATA
username = base64.b64decode(USER_B64).decode('utf-8')
salt_b64 = "".join(SALT_CHUNKS)
salt = base64.b64decode(salt_b64)
print(f"[+] Username : {username}")
print(f"[+] Salt : {salt.decode('utf-8')}")
# 3. GENERATE LICENSE (HMAC-SHA256)
hmac_obj = hmac.new(salt, username.encode('utf-8'), hashlib.sha256)
hmac_digest = hmac_obj.digest()
license_key = "".join([f"{b:02X}" for b in hmac_digest[:8]])
print(f"[+] License : {license_key}")
# 4. DERIVE AES KEY
# Logic: SHA256(License + Base64Salt) -> Take 16 bytes
combined = license_key + salt_b64
key_hash = hashlib.sha256(combined.encode('utf-8')).digest()
aes_key = key_hash[:16]
print(f"[+] AES Key : {aes_key.hex()}")
# 5. DECRYPT FLAG (AES-CBC)
iv = ENCRYPTED_BLOB[:16]
ciphertext = ENCRYPTED_BLOB[16:]
cipher = Cipher(algorithms.AES(aes_key), modes.CBC(iv), backend=default_backend())
decryptor = cipher.decryptor()
plaintext_padded = decryptor.update(ciphertext) + decryptor.finalize()
# Remove PKCS7 Padding manually for display
padding_len = plaintext_padded[-1]
flag = plaintext_padded[:-padding_len].decode('utf-8')
print(f"\n[SUCCESS] FLAG: {flag}")
Hasil Eksekusi Solver
🔻 Klik untuk melihat Output Solver
[+] Username : RANI
[+] Salt : salt_part_1_from_cre
[+] License : 0905E413DDF6D48B
[+] AES Key : ab5ca2c49a6e6f4425eb73d97f603242
[SUCCESS] FLAG: FGTE{REDACTED_FOR_SECURITY}
8. Verifikasi Akhir
Untuk memastikan temuan benar, saya jalankan binary asli dengan kredensial yang didapat.
$ ./aktivasi.exe RANI 0905E413DDF6D48B
aktivasi v1.0
Activation OK. Here is your secret:
FGTE{REDACTED_FOR_SECURITY}
9. Key Takeaways:
- .NET is Open Book: Aplikasi .NET tanpa obfuscation sangat mudah dibaca source code-nya.
- Hardcoded Secrets: Memecah string salt (
saltChunks) tidak menambah keamanan signifikan. - Kriptografi: Implementasi teknis benar, namun lemah di manajemen kunci (key derivation dari data statis).