docker run -d -p 3111:3111 --restart always --name ctf-ascii-rev joshbeck2024/ctf-ascii-rev
The ASCII codes are reversed.
ASCII 108 is presented as 801
Competitors have to reverse each number and convert to chr()
import socket
import time
HOST = '127.0.0.1'
PORT = 3111
def solve_challenge(challenge_str):
"""
Reverses the challenge transformation.
Input: "401 101 801 801 111" (example)
Output: "hello"
"""
try:
parts = challenge_str.split()
original_chars = []
for part in parts:
# Reverse the number string back to original ascii decimal string
ascii_str = part[::-1]
# Convert to int
ascii_val = int(ascii_str)
# Convert to char
char = chr(ascii_val)
original_chars.append(char)
return "".join(original_chars)
except Exception as e:
print(f"Error solving challenge '{challenge_str}': {e}")
return None
def main():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
print(f"Connected to {HOST}:{PORT}")
buffer = ""
while True:
data = s.recv(4096).decode()
if not data:
break
print(data, end='')
buffer += data
if "Round" in buffer and ":" in buffer:
# Extract the challenge part
lines = buffer.split('\\n')
# Look for the last line that contains "Round"
challenge_line = None
for line in lines:
if "Round" in line and ":" in line:
challenge_line = line
if challenge_line:
# Format: "Round X/100: <challenge_string>"
parts = challenge_line.split(': ')
if len(parts) >= 2:
challenge = parts[1].strip()
# Solve it
solution = solve_challenge(challenge)
if solution:
print(f"Solving: {solution}")
s.sendall(f"{solution}\\n".encode())
# Clear buffer to avoid re-processing same round (though server sends chunks)
# Actually, we should just process what we receive.
# A simple way for this specific protocol is to react to the prompt.
buffer = ""
if "Flag-" in buffer:
print("\\n\\n*** CONGRATS! ***")
break
except Exception as e:
print(f"Connection failed: {e}")
finally:
s.close()
if __name__ == "__main__":
main()