$ cat writeup.md…
$ cat writeup.md…
hackthebox
Task: Generate all valid PINs from a template with wildcards and constraints (no adjacent duplicates). Solution: Backtracking algorithm with look-ahead optimization to prune invalid branches early.
After gaining access to CygnusCorp's internal network, you've uncovered a critical system locked behind a numeric PIN. The catch? Only partial digits are visible, leaving you to piece together the rest. With your mission progressing, every second counts. You can't afford to waste time blindly guessing. Can you use the partial information at hand to orchestrate an educated brute force attack and break into the system before you're caught?
*The task is a classic combination generation problem with constraints:
* symbol means we need to iterate through all possible digits 0-9The service works via HTTP API:
/runcode and language fieldsUsing the backtracking algorithm:
def solve(template): n = len(template) results = [] def backtrack(pos, current): if pos == n: results.append("".join(current)) return if template[pos] != "*": # Fixed digit digit = template[pos] # Check that it doesn't match the previous one if pos == 0 or current[pos-1] != digit: current.append(digit) backtrack(pos + 1, current) current.pop() else: # Wildcard - iterate through all digits for d in "0123456789": # Check: doesn't match the previous one if pos == 0 or current[pos-1] != d: # Look-ahead: if next position is fixed and equals d, skip if pos + 1 < n and template[pos + 1] != "*" and template[pos + 1] == d: continue current.append(d) backtrack(pos + 1, current) current.pop() backtrack(0, []) return sorted(results) template = input().strip() result = solve(template) for pin in result: print(pin)
Input: *23
Algorithm:
* - iterate 0-9, but skip 2 (next fixed position = 2)2 - fixed3 - fixedOutput:
023
123
323
423
523
623
723
823
923
import requests code = ''' def solve(template): n = len(template) results = [] def backtrack(pos, current): if pos == n: results.append("".join(current)) return if template[pos] != "*": digit = template[pos] if pos == 0 or current[pos-1] != digit: current.append(digit) backtrack(pos + 1, current) current.pop() else: for d in "0123456789": if pos == 0 or current[pos-1] != d: if pos + 1 < n and template[pos + 1] != "*" and template[pos + 1] == d: continue current.append(d) backtrack(pos + 1, current) current.pop() backtrack(0, []) return sorted(results) template = input().strip() result = solve(template) for pin in result: print(pin) ''' response = requests.post( "http://83.136.251.11:56814/run", json={"code": code, "language": "python"} ) print(response.text)
Use this technique when:
Itertools + filtering: Generate all combinations via itertools.product, then filter out invalid ones. Less efficient but simpler to implement.
Dynamic programming: Can count the number of valid PINs without generating them, if only statistics are needed.
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar