Protostar 0x08 - Net0

Prev: 0x07 - Stack7
Next: 0x09 - Net1

After completing the first 8 Stack levels, I will be doing the remainder out of order, starting now with the Net series.


The source code here defines a "run" function, then serves it indefinitely via some custom functions on port 2999 which is defined at the top of the file as a constant. If we enter the "ps" command to show current processes and search for "net0," we find that it is already running:


$ ps aux | grep net0
999   1700  0.0  0.0  1532  276 ?      Ss  14:28  0:00 /opt/protostar/bin/net0
user  2666  0.0  0.0  3300  732 pts/0  S+  19:26  0:00 grep net0


Additionally, we can call netstat with "-l" to show all currently listening sockets. If we scan it, we find net0's port - 2999 - is listening:


$ netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address  Foreign Address  State
tcp        0      0 *:60591        *:*              LISTEN
tcp        0      0 *:sunrpc       *:*              LISTEN
...
tcp        0      0 *:2999         *:*              LISTEN


So, looks like it's already awaiting our input. If we check the source code for the "run" function, we can see our objective: first, "run" generates a random number via the "random" function. Then, it prints a string requesting that we send back the value of that function in as "a little endian 32bit int." Finally, "fread" reads whatever we send via stdin into a buffer titled "i" and then compares it to the random integer, and gives us feedback accordingly.

Let's now create a "net0.py" file and begin crafting our solution. Note that you can continue working with the VM, or you can work on your local machine for these "net" exercises with the VM running in the background as you will still be able to communicate through the socket regardless. I'll proceed with using the VM, but keep in mind that this uses Python version 2.6.6:


$ python --version
Python 2.6.6 


If you opt to use your local machine which likely has a newer version of Python and other packages, keep in mind that some things will differ: namely, the "print" and "struct.pack" functions which may need some "int()" and "str()" conversions before being able to execute the code as I've written it below.

In our file, we'll first want to import socket and use this package to connect with net0 using port 2999. The code below is standard Python TCP communication client code, so familiarize yourself with the basics if this is new for you.


import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2999))

request = s.recv(1024)
print request 


We first define the type of socket, and then connect to it. We can use localhost as the IP in "s.connect" as we are on the VM, but if you are not, you will need to enter the IP here (enter "/sbin/ifconfig" to obtain the IP of the VM - look for "inet addr"). Then, we receive a response of up to 1024 bytes, define it as "request," and print it.

If we run the program now, this is what we see (where "XXXX" is a random integer):


$ python net0.py
Please send 'XXXX' as a little endian 32bit int 


Great - our code is working as intended thus far. Now, how to send it back as little endian 32bit int? Well, we know from previous levels that "struct.pack" can accomplish this, so let's import the "struct" package and pass in the integer using "input()." Alternatively, we could get clever with Python and search the "request" string for the number contained with the apostrophes, but this should suffice. After the "struct.pack" conversion, we will send this value, and then call "recv" once more to receive and then print our feedback. Here's our final Python code:


import socket, struct

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2999))

request = s.recv(1024)
print request

response = struct.pack("<I", input())
print "Sending back: " + response
s.send(response)

feedback = s.recv(1024)
print feedback 


If we run it, here's what happens:


$ python net0.py
Please send '869932294' as a little endian 32bit int
869932294
Sending back: 3
Thank you sir/madam 


We get the request from the "net0" server, we type the integer back to it (or rather, back to our program which then converts and sends it), our program prints what we send to it (which typically looks like nonsense as "print" is unable to properly print the binary data we are sending), and then it thanks us for sending the correct value!

Prev: 0x07 - Stack7
Next: 0x09 - Net1