Hack This Site - Complete Solution
Challenge Goal: Learn how to hack this site by analyzing obfuscated JavaScript code, finding authentication credentials, bypassing client-side access controls, and capturing the flag.
Step 1: Understanding the Challenge
When you open the challenge, you see a login form for a vault system called "SecureVault". The form asks for a username and password. If you try random credentials, you'll see an error message: "Invalid credentials. Access denied."
The key insight here is that this is a client-side application - all the HTML, CSS, and JavaScript are loaded in your browser. This means the authentication logic must be somewhere in the JavaScript code.
Why client-side authentication is problematic:
When authentication happens in the browser (client-side), the code that validates credentials must be sent to the user's computer. Even if the code is obfuscated or minified, an attacker can:
• View the complete source code
• Deobfuscate or reverse engineer it
• Extract hardcoded credentials
• Bypass authentication by calling functions directly with found credentials
• Access restricted functionality by understanding the code logic
Step 2: Opening Browser Developer Tools
To analyze the JavaScript code, you'll need to use your browser's developer tools. These built-in tools allow you to inspect HTML, view JavaScript source code, set breakpoints, and debug web applications.
Opening Developer Tools:
Chrome/Edge:
• Press F12, or
• Press Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (Mac), or
• Right-click anywhere on the page and select "Inspect"
Firefox:
• Press F12, or
• Press Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (Mac), or
• Right-click and select "Inspect Element"
Safari:
• First enable developer menu: Preferences > Advanced > Show Develop menu
• Press Cmd+Option+I, or
• Select Develop > Show Web Inspector
Once open, you'll see several tabs: Elements, Console, Sources, Network, etc. We'll primarily use the Sources tab (Chrome/Edge) or Debugger tab (Firefox).
Step 3: Locating the JavaScript Code
Now we need to find where the JavaScript code is located in the page.
Finding the JavaScript:
1. Click on the Sources tab (Chrome/Edge) or Debugger tab (Firefox)
2. In the left panel, you'll see a file tree showing all resources loaded by the page
3. Click on index.html (or the current page name)
4. Scroll down to the bottom of the HTML file
You'll see a <script> tag containing JavaScript code. This code looks scrambled and difficult to read - this is obfuscated JavaScript using hex-encoded strings.
What is obfuscation?
Obfuscation is the process of making code intentionally difficult to understand while maintaining its functionality. In this challenge, the obfuscation uses:
• Hex-encoded strings (\x67\x65\x74... instead of "get...")
• Meaningless variable names (_0x4d2f, _0x2e5b, _0x8f3c)
• Character code encoding for the flag
• Complex function structures
Step 4: Analyzing the Obfuscated Code Structure
Let's examine what we can see in the obfuscated code:
Observable patterns in the code:
1. Hex-encoded strings:
You'll see strings like '\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64'
These are hexadecimal representations of text (this one is "getElementById")
2. Configuration object:
An object like var _0x2e5b={...} that stores important values
Look for keys like '\x75\x73\x65\x72' and '\x70\x61\x73\x73' ("user" and "pass")
3. Authentication state variable:
A variable like var _0x8f3c=null that tracks authentication status
4. Logic functions:
Functions like validateAccess(), grantAccess(), showError(), and retrieveFlag() contain the actual program logic
Step 5: Deobfuscating Hex-Encoded Strings
The easiest way to understand the obfuscated code is to decode the hex-encoded strings:
Method 1: Using Browser Console (Quick)
1. Open the Console tab in Developer Tools
2. Type a hex string to decode it:
'\x61\x64\x6d\x69\x6e' and press Enter
3. The console will display: "admin"
Try these to reveal important values:
• '\x75\x73\x65\x72' → "user"
• '\x70\x61\x73\x73' → "pass"
• '\x61\x64\x6d\x69\x6e' → "admin"
• '\x37\x66\x33\x61\x39\x63\x32\x65\x31\x62\x35\x64\x38\x66\x34\x61' → "7f3a9c2e1b5d8f4a"
Method 2: Manual Hex Decoding
Each \xNN represents a hexadecimal ASCII value:
• \x61 = 97 decimal = 'a'
• \x64 = 100 decimal = 'd'
• \x6d = 109 decimal = 'm'
• \x69 = 105 decimal = 'i'
• \x6e = 110 decimal = 'n'
Together: "admin"
Method 3: Using Browser Debugger
1. In the Sources/Debugger tab, find the validateAccess() function
2. Click on the line number to set a breakpoint
3. Enter any credentials in the form and click "Access Vault"
4. The code will pause at your breakpoint
5. Hover over variables to see their decoded values
6. Inspect the _0x2e5b object to see stored credentials
Step 6: Finding the Credentials
By examining the code structure and decoding hex strings, you'll discover the authentication logic:
The authentication logic (conceptual view):function validateAccess() {
    var username = document.getElementById('username').value;
    var password = document.getElementById('password').value;
    
    if (username.toLowerCase() == 'admin' && password == '7f3a9c2e1b5d8f4a') {
        // Store authentication state
        authState = password;
        grantAccess(username, password);
    } else {
        showError();
    }
}Credentials found:• Username: 
admin (case-insensitive)
• Password: 
7f3a9c2e1b5d8f4a (case-sensitive)
The code checks if the entered username (converted to lowercase) equals 'admin' and the password exactly matches '7f3a9c2e1b5d8f4a'. If both conditions are true, it stores the authentication state and calls 
grantAccess() with the credentials.
 Step 7: Accessing the Restricted Area (Primary Method)
Now that you have the valid credentials, you can authenticate normally:
Logging in through the form:
1. Return to the challenge page (or refresh if needed)
2. Enter the username: admin
3. Enter the password: 7f3a9c2e1b5d8f4a
4. Click "Access Vault"
The login form will disappear, and you'll see the restricted area appear with a success message: "Access Granted - Welcome to the restricted vault area."
The flag will be displayed in a cyan-colored box in UUID format.
Step 8: Understanding the Authentication Flow
After successful authentication, here's what happens internally:
The grantAccess() function flow:
1. Hides the login form:
document.getElementById('loginArea').style.display = 'none';
2. Shows the restricted area:
document.getElementById('restrictedArea').style.display = 'block';
3. Retrieves and displays the flag:
var flag = retrieveFlag(username, password);
document.getElementById('flagContainer').innerHTML = flag;
Notice that grantAccess() now requires both username and password parameters, and passes them to retrieveFlag() for validation.
Step 9: Analyzing the Flag Retrieval Mechanism
The retrieveFlag() function has built-in security to prevent easy bypasses:
The retrieveFlag() function (conceptual view):function retrieveFlag(username, password) {
    // Check authentication state and password
    if (!authState || password != storedPassword) {
        return 'Access Denied';
    }
    
    // Decode the flag from character codes
    var encoded = '102,52,97,52,100,101,97,56,45,99,51,100,53,45,52,100,48,55,45,56,50,52,100,45,50,52,97,97,50,97,48,100,102,56,101,101';
    return encoded.split(',').map(function(code) {
        return String.fromCharCode(parseInt(code, 10));
    }).join('');
}Key security features:1. 
Authentication state check: The function verifies that authentication has occurred by checking the authState variable
2. 
Password validation: The provided password must match the stored password
3. 
Returns "Access Denied": If validation fails, no flag is returned
4. 
Character code encoding: The flag is stored as comma-separated ASCII values
How the flag is decoded:• Splits the comma-separated string into an array of numbers
• Converts each number to an integer with 
parseInt(code, 10)• Converts each integer to its character with 
String.fromCharCode()• Joins all characters to form the complete flag
 Step 10: Alternative Bypass Methods (Require Credentials)
Even with security measures, you can still bypass the normal flow - but you MUST have the credentials first:
Method 1: Direct grantAccess() call1. Open the Console tab in Developer Tools
2. Type: 
grantAccess('admin', '7f3a9c2e1b5d8f4a')3. Press Enter
4. The restricted area appears with the flag
This bypasses the form validation but still requires knowing the correct credentials.
Method 2: Direct retrieveFlag() call1. First, set the authentication state:
_0x8f3c = '7f3a9c2e1b5d8f4a' (variable name may differ)
2. Then call retrieveFlag with credentials:
retrieveFlag('admin', '7f3a9c2e1b5d8f4a')3. The flag will be displayed in the console
This also requires knowing the credentials and the authentication state variable name.
Method 3: Decode character codes manuallyOnce you find the encoded flag string in the code:
'102,52,97,52,100,101,97,56,45,99,51,100,53,45,52,100,48,55,45,56,50,52,100,45,50,52,97,97,50,97,48,100,102,56,101,101'In the Console, run:
'102,52,97,52,100,101,97,56,45,99,51,100,53,45,52,100,48,55,45,56,50,52,100,45,50,52,97,97,50,97,48,100,102,56,101,101'.split(',').map(c => String.fromCharCode(parseInt(c, 10))).join('')The decoded flag will appear directly.
Method 4: Use an online ASCII decoder1. Find the encoded string in the source code
2. Copy: 
102,52,97,52,100,101,97,56,45,99,51,100,53,45,52,100,48,55,45,56,50,52,100,45,50,52,97,97,50,97,48,100,102,56,101,1013. Go to an ASCII converter like 
https://www.rapidtables.com/convert/number/ascii-to-text.html4. Convert each number (102 → f, 52 → 4, 97 → a, etc.)
5. Combine the characters to get the complete flag
Why these bypasses still require effort:• You must analyze the obfuscated code
• You must decode hex strings to find credentials
• You must understand the code structure
• You still learn the intended lessons about client-side security
 Step 11: Retrieving the Final Flag
After successfully authenticating (or using one of the bypass methods), the flag will be displayed:
The flag appears in a cyan-colored box in the restricted area in UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). This is your answer - submit this complete UUID as the flag.
Key Security Lessons
Why Client-Side Authentication Fails
- Code is visible: All JavaScript sent to the browser can be viewed and analyzed
- Credentials are exposed: Hardcoded credentials in client-side code are always discoverable
- Logic can be bypassed: Attackers can call functions directly with found credentials
- Obfuscation is not security: Obfuscated code can be deobfuscated, debugged, or reverse engineered
- No server validation: Without server-side checks, client-side controls provide no real security
- State can be manipulated: Client-side authentication state can be modified in the console
Proper Authentication Practices
- Server-side validation: Always validate credentials on the server, never in the browser
- Never trust the client: Assume all client-side code and data can be modified
- Use secure protocols: Implement proper authentication (OAuth, JWT with server validation, sessions)
- No hardcoded secrets: Never embed passwords, API keys, or flags in client code
- Session management: Use secure, server-side session tokens with HttpOnly cookies
- Proper architecture: Authentication and authorization must happen on the backend
Tools and Techniques Summary
Essential tools for JavaScript analysis:
• Browser Developer Tools: Built-in debugging and inspection (F12)
• Console: Execute JavaScript, call functions, inspect variables, decode hex strings
• Debugger: Set breakpoints, step through code, watch variables in real-time
• Hex decoders: Browser console or online tools to decode \xNN strings
• ASCII converters: Convert character codes to text
• Online deobfuscators: deobfuscate.io, de4js (for more complex obfuscation)
Key techniques learned:
• JavaScript hex-encoding and deobfuscation
• Using browser DevTools for code analysis
• Understanding obfuscation patterns and techniques
• Extracting hardcoded credentials from client-side code
• Bypassing client-side authentication controls
• Decoding encoded data (character codes to strings)
• Direct function invocation via browser console
• Manipulating application state through the console
Real-World Applications
This type of vulnerability is commonly found in:
- Administrative panels: Internal tools with weak authentication that should have server-side validation
- Single-page applications: SPAs that implement auth logic incorrectly in JavaScript
- Mobile app web views: Hybrid apps using web technologies without proper backend security
- API key exposure: Hardcoded API keys, tokens, or secrets in frontend code
- Premium feature unlocks: Client-side checks for paid features that can be bypassed
- Development/staging environments: Forgotten debug code or hardcoded credentials in production
- Embedded systems: IoT devices with web interfaces and client-side authentication
Bug bounty programs regularly reward findings of hardcoded credentials, exposed API keys, and client-side authentication bypasses. Typical bounty amounts range from $500 to $5,000 depending on severity and impact. Understanding these vulnerabilities is essential for both offensive security testing and defensive secure development.
Prevention and Mitigation
For developers and security teams:
1. Move authentication to the backend: All credential validation must happen on the server
2. Use secure session management: Implement proper session tokens, not client-side state
3. Never hardcode credentials: Use environment variables and secure configuration management
4. Implement proper access control: Server-side checks for every restricted resource
5. Use HTTPS: Encrypt all communication between client and server
6. Audit client-side code: Regularly review frontend code for exposed secrets
7. Security testing: Include client-side security in penetration testing scope
8. Code review: Check for hardcoded secrets before deployment
9. Monitor for leaked secrets: Use tools to scan for exposed credentials in code
Congratulations! You've successfully analyzed obfuscated JavaScript code, decoded hex-encoded strings, extracted hardcoded credentials, understood authentication state management, bypassed client-side authentication, and retrieved the flag. You've learned why client-side security controls are ineffective and how to properly implement authentication in web applications. This knowledge is directly applicable to penetration testing, bug bounty hunting, and secure application development.