← Back to list

Decryptify (CTF) | TryHackMe | PART 1

PART 1: Recon and Initial Entry

RABABE AZIL · 2026-04-13 15:58 · 1 claps · 4.7 min read
#tryhackme #ctf #web-enumeration #hacking
Open on Medium ↗
Wiki topics: 🔒 · Cybersecurity

Decryptify (CTF) | TryHackMe | PART 1

PART 1: Recon and Initial Entry

Scope

Target: <IP Address>

Reconnaissance mindset

Start by treating the target like a standard Linux web box. The goal here is not just to list ports, but to understand attack surface types.

A quick full port scan with service detection and default scripts is enough to map the first layer of the system.

nmap -sC -sV -T4 <IP Address>
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
1337/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Login - Decryptify
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

This revealed that ports 22 and 1337 were open

What to pay attention to

  • SSH is present, but usually not the first entry point
  • A non-standard HTTP port is exposed (1337), which often indicates a custom web app
  • Web service versions can hint at known misconfigurations or outdated behavior

At this stage, the important takeaway is: focus on the web service first, not SSH

Web enumeration

Once a web server is identified, the next step is to map hidden content.

Use directory brute forcing to uncover:

  • hidden endpoints
  • backup files
  • API endpoints
  • admin panels
gobuster dir -u http://<IP Address>:1337/ -w <wordlist>

What you should be looking for

Rather than just collecting paths, categorize them:

  • authentication-related pages (login, dashboard)
  • debugging or logging endpoints
  • API or JavaScript files

In this case, interesting findings include:

  • a login interface
  • a logs directory
  • a JavaScript file exposed publicly

At this point, a key idea should form:

If logs are exposed, the application may be leaking internal state or sensitive workflow data.

JavaScript analysis

When a JS file like api.js is discovered, do not skim it.

Instead, treat it like client-side source code that may contain:

  • hidden endpoints
  • hardcoded secrets
  • obfuscation layers

Handling obfuscated JavaScript

If the code is unreadable:

  • Beautify it first
  • Then identify patterns:
  • arrays used as lookup tables
  • wrapper functions like decoders
  • numeric or hex-based indexing

A common trick is a function that maps numbers to hidden strings.

Hint for progression

Ask yourself:

What happens if I manually test the decoder function with different numeric inputs?

This often leads to hidden credentials or API keys.

Once the logic is understood, you may recover a secret used for authentication into another endpoint (in this case, /api.php).

Hidden functionality discovery

// Token generation example
function calculate_seed_value($email, $constant_value) {
    $email_length = strlen($email);
    $email_hex = hexdec(substr($email, 0, 8));
    $seed_value = hexdec($email_length + $constant_value + $email_hex);

    return $seed_value;
}
     $seed_value = calculate_seed_value($email, $constant_value);
     mt_srand($seed_value);
     $random = mt_rand();
     $invite_code = base64_encode($random);

After gaining access to a restricted API page, look for:

  • code snippets
  • backend logic leaks
  • token generation functions

Here, the interesting part is an invite code generator.

Instead of trying to immediately break it, analyze its structure:

Key observation

The token depends on:

  • email length
  • part of the email string
  • a constant value
  • PHP’s random number generator seed

Important learning point

If a token is deterministic:

Any missing parameter becomes a reverse-engineering target.

So the challenge becomes:

  • We know the input email
  • We know the output token
  • We are missing one variable
<?php

function calculate_seed_value($email, $constant_value) {
    $email_length = strlen($email);
    $email_hex = hexdec(substr($email, 0, 8));

    $seed_raw = $email_length + $constant_value + $email_hex;

    // same behavior as original code
    $seed_value = hexdec((string)$seed_raw);

    return $seed_value;
}

function generate_random_from_constant($email, $constant_value) {
    $seed = calculate_seed_value($email, $constant_value);

    mt_srand($seed);
    return mt_rand();
}

function find_constant_value($email, $invite_code, $max_range = 1000000) {
    // decode invite code
    $target_random = (int) base64_decode($invite_code);

    $email_length = strlen($email);
    $email_hex = hexdec(substr($email, 0, 8));

    for ($constant = 0; $constant <= $max_range; $constant++) {

        $seed_raw = $email_length + $constant + $email_hex;
        $seed = hexdec((string)$seed_raw);

        mt_srand($seed);
        $rand = mt_rand();

        if ($rand === $target_random) {
            return $constant;
        }
    }

    return null;
}

/*
Example usage
*/

$email = ""; 
$invite_code = "";

$constant = find_constant_value($email, $invite_code, 1000000);

if ($constant !== null) {
    echo "Found constant value: " . $constant . PHP_EOL;
} else {
    echo "No constant found in range." . PHP_EOL;
}

Log analysis

Now shift attention to exposed logs.

Logs often reveal:

  • real user actions
  • system behavior over time
  • Repeated API patterns

Here, the logs show:

  • Invite codes are being generated
  • account creation and deletion events
  • different email usage patterns

Key insight

If multiple users go through the same process:

Their token generation likely follows the same formula with only minor variable changes.

This is your bridge to reverse engineering.

HINT: Try using the PHP script provided above.

Reverse engineering the invite system

At this stage, you already have:

  • algorithm logic (from API leak)
  • one known email
  • One known invite code (99999)

Now the problem becomes:

Find the missing constant that makes the system reproduce the known output.

How to think about it

Instead of brute forcing immediately:

  1. Recreate the formula locally
  2. Confirm how PHP casts and converts values
  3. Verify randomness seed behavior
  4. Then attempt constrained brute force

Important hint

The mistake many people make here is ignoring type conversion issues in PHP:

  • strings vs integers
  • hex conversion behavior
  • casting before hashing

These subtle differences often determine whether brute force works or fails.

Solving strategy

When brute forcing:

  • Start with a small range first (sanity check)
  • Confirm your reproduction matches the expected output
  • Then scale the search space

If done correctly, the missing constant can be recovered.

Final step: token generation

Once the missing constant is identified, the rest becomes straightforward:

  • plug values back into the formula
  • generate the same deterministic random output
  • encode it as required

At this point, you can generate valid invite codes for new emails and gain access to the next user account.

Key takeaway from Part 1

This challenge is less about exploitation and more about:

  • Understanding exposed logic
  • reconstructing hidden parameters
  • validating assumptions through small tests

If you can reliably reverse deterministic systems like this, you are already thinking like a web attacker.


메타데이터
post_id
0a1bd3faebbe
slug
decryptify-ctf-tryhackme-part-1-0a1bd3faebbe
url
https://medium.com/@azilrababe/decryptify-ctf-tryhackme-part-1-0a1bd3faebbe
canonical_url
https://medium.com/@azilrababe/decryptify-ctf-tryhackme-part-1-0a1bd3faebbe
author_url
https://medium.com/@azilrababe
status
ok
fetched_at
2026-07-26 02:36:47