Write-up for: https://exploit.education/phoenix/net-zero/.
This challenge serves as an intro to network programming and the obstacles you need to overcome in the context of exploit development, such as endianness and encoding.
The first step is to observe the behavior of the program by connecting to it. We can do this using
user@phoenix-amd64:~$ nc 127.0.0.1 64000 Welcome to phoenix/net-zero, brought to you by https://exploit.education Please send '266126999' as a little endian, 32bit integer. 266126999 Close - you sent 825636402 instead user@phoenix-amd64:~$ nc 127.0.0.1 64000 Welcome to phoenix/net-zero, brought to you by https://exploit.education Please send '2539383473' as a little endian, 32bit integer. AAAA Close - you sent 1094795585 instead
There are two things to observe here.
- The number we are supposed to send is randomized
- The number is not parsed from a string but our input is directly interpreted as a 32-bit integer (AAAA = 0x41414141 = 1094795585)
Now we know what we need to implement:
- Connect to the socket
- Read two lines
- Parse the required number from the second line
- Send the number as a little-endian integer
- Read the result line
And here’s the implementation in Python:
import struct import socket HOST = "127.0.0.1" PORT = 64000 def read_line_from_sock(socket): buf = "" while True: b = s.recv(1) if b == b'\n': break buf += b.decode("ascii") return buf with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) print(read_line_from_sock(s)) query = read_line_from_sock(s) print(query) num_to_send = str(query).split().split("'") s.sendall(struct.pack('<I', int(num_to_send))) print(read_line_from_sock(s))
struct.pack to convert the number into a little-endian byte array. Let’s see it in action:
user@phoenix-amd64:~$ python3 net0.py Welcome to phoenix/net-zero, brought to you by https://exploit.education Please send '3232984659' as a little endian, 32bit integer. You have successfully passed this level, well done!