← Back to Writeups
CUSTOMMediumWeb

Snitch (Снитч)

XESXOR9/10/20263 min read
#web#custom#medium#custom-shuffle-algorithm-rever#javascript-deobfuscation#string-constant-extraction-fro

Snitch (Снитч)

Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2025-12-20 | Status: Solved Techniques: Custom shuffle algorithm reverse engineering, JavaScript deobfuscation, String constant extraction from obfuscated arrays

Summary

Task: Web page with obfuscated JavaScript and a flying snitch distraction. Solution: Analyzed deobfuscation function ISd() and extracted flag from string array in browser console.

Snitch (Снитч) — hackerlab.pro

Description

Непонятный код? Может действовать прямолинейно? (Unclear code? Maybe act straightforwardly?)

URL: http://62.173.140.174:16048

Analysis

Initial Inspection

The page displays a "Snitch" (like the Golden Snitch from Harry Potter) — a flying button with a 🎯 emoji that moves around the screen. The obvious goal is to catch the snitch, but this is a distraction.

Hint in the Description

The phrase "act straightforwardly" hints that instead of trying to click on the flying button, you should directly analyze the page source code. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Obfuscated JavaScript

The page source contains heavily obfuscated JavaScript:

javascript
var _$_9efc = ["...", "...", ...]; // Array of encrypted strings

function ISd(s, n) {
    // Deobfuscation function
    var arr = s.split('');
    for (var i = arr.length - 1; i > 0; i--) {
        var j = (i * n) % (i + 1);
        var temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    return arr.join('').split('|');
}

Deobfuscation Algorithm

The ISd() function works as follows:

  1. Takes an encrypted string s and a seed number n
  2. Splits the string into a character array
  3. In reverse order (from end to beginning) performs swap operations
  4. Swap position is calculated as j = (i * n) % (i + 1)
  5. The result is split by the | delimiter into an array of strings ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Flag Extraction

After deobfuscation, the _$_9efc array contains all string constants used in the code. The flag is located in one of the elements of this array.

Solution

Method 1: Browser Console

Open DevTools (F12) and execute in the console:

javascript
// Find the string array
console.log(_$_9efc);

// Or find the element containing CODEBY
_$_9efc.forEach((item, index) => {
    if (item.includes('CODEBY')) {
        console.log(`Index ${index}: ${item}`);
    }
});

Method 2: Manual Deobfuscation

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

python
#!/usr/bin/env python3
"""
Deobfuscation of JavaScript code from the Snitch page
"""

def deobfuscate(s: str, n: int) -> list:
    """
    Reverse of the ISd() function from obfuscated JS
    """
    arr = list(s)
    
    # Reverse pass with swap operations
    for i in range(len(arr) - 1, 0, -1):
        j = (i * n) % (i + 1)
        arr[i], arr[j] = arr[j], arr[i]
    
    # Split by delimiter
    return ''.join(arr).split('|')

# Encrypted string from source code
encrypted = "..." # Copy from source
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Seed from function call
seed = 123  # Find in code

result = deobfuscate(encrypted, seed)

# Search for flag
for i, item in enumerate(result):
    if 'CODEBY' in item or 'flag' in item.lower():
        print(f"[{i}] {item}")

Result

The flag is located at index 12 of the _$_9efc array:

CODEBY{REDACTED}

Notes

Typical JS Obfuscation Patterns

  1. String Array Rotation — strings are stored in an array and retrieved by index
  2. Character Shuffle — characters are shuffled and restored by a function
  3. Hex/Unicode Encoding — strings are encoded in hex or unicode escape sequences
  4. Control Flow Flattening — logic is broken into switch-case statements ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Deobfuscation Tools

  • de4js — online deobfuscator
  • JStillery — static analysis
  • Browser DevTools — execute code in the page context
  • Synchrony — deobfuscation for obfuscator.io

Distraction Technique

The flying snitch is a classic example of a "rabbit hole" in CTF. Instead of trying to catch it (which is technically possible via JS), the correct approach is to analyze the code directly. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍