Prove You Are (Not) a Robot
Prove You Are (Not) a Robot
Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-04-04 | Status: Solved Techniques: arithmetic_expression_solver, base64_task_decoding, websocket_automation
Summary
Task: a Uvicorn-served page delegated the real logic to a websocket that issued base64-encoded arithmetic challenges. Solution: automate the websocket flow, decode each expression, compute the answer, and loop through 50 rounds until the server returned the flag.
Prove You Are (Not) a Robot — Hackerlab
Description
Original task name: «Я не робот! Докажи, что ты (не) робот!»
Target: http://62.173.140.174:16011/
The page itself was only a thin frontend. JavaScript immediately opened a websocket connection and the real challenge was a sequence of server-issued arithmetic tasks that had to be solved automatically.
Analysis
Initial recon showed an HTTP page served by Uvicorn and a client-side websocket connection to:
text read-only • copy allowedws://62.173.140.174:16011/ws
After connecting, the server sent messages such as:
text read-only • copy allowed[*] Solve: eCA9IDE2MSAqIDg3Ng==
The string after Solve: was base64. Decoding it produced an expression like:
text read-only • copy allowedx = 161 * 876
Sending the correct result returned the next challenge together with a progress counter (1/50 through 49/50). After 50 correct answers, the websocket returned the flag directly. So this was not a browser interaction problem; it was a simple websocket automation task.
Solution
- Open the main page and inspect the JavaScript.
- Connect directly to
ws://62.173.140.174:16011/ws. - Extract the base64 blob from each
Solve:message. - Decode it and parse the arithmetic expression.
- Support
+,-, and*. - Send each computed result back on the same websocket until the flag appears.
python read-only • copy allowed#!/usr/bin/env python3 import asyncio import base64 import re import websockets HOST = "ws://62.173.140.174:16011/ws" FLAG_RE = re.compile(r"CODEBY\{[^}]+\}") TASK_RE = re.compile(r"Solve:\s*([A-Za-z0-9+/=]+)") EXPR_RE = re.compile(r"x\s*=\s*(-?\d+)\s*([+\-*])\s*(-?\d+)") def solve_expr(encoded: str) -> str: decoded = base64.b64decode(encoded).decode() m = EXPR_RE.fullmatch(decoded.strip()) if not m: raise ValueError(f"Unexpected task: {decoded!r}") a, op, b = m.groups() a, b = int(a), int(b) if op == "+": return str(a + b) if op == "-": return str(a - b) if op == "*": return str(a * b) raise ValueError(f"Unsupported operator: {op}") async def main() -> None: async with websockets.connect(HOST) as ws: while True: message = await ws.recv() print(message) flag = FLAG_RE.search(message) if flag: print(f"\nFLAG: {flag.group(0)}") return m = TASK_RE.search(message) if not m: continue await ws.send(solve_expr(m.group(1))) if __name__ == "__main__": asyncio.run(main())