So far, these Net challenges in Protostar have been pretty easy. This challenge, Net 2 got a small bit tougher.
We are given the following code:
#include "../common/common.c"
#define NAME "net2"
#define UID 997
#define GID 997
#define PORT 2997
void run()
{
unsigned int quad[4];
int i;
unsigned int result, wanted;
result = 0;
for(i = 0; i < 4; i++) {
quad[i] = random();
result += quad[i];
if(write(0, &(quad[i]), sizeof(result)) != sizeof(result)) {
errx(1, ":(\n");
}
}
if(read(0, &wanted, sizeof(result)) != sizeof(result)) {
errx(1, ":<\n");
}
if(result == wanted) {
printf("you added them correctly\n");
} else {
printf("sorry, try again. invalid\n");
}
}
int main(int argc, char **argv, char **envp)
{
int fd;
char *username;
/* Run the process as a daemon */
background_process(NAME, UID, GID);
/* Wait for socket activity and return */
fd = serve_forever(PORT);
/* Set the client socket to STDIN, STDOUT, and STDERR */
set_io(fd);
/* Don't do this :> */
srandom(time(NULL));
run();
}
From this code, we can see a daemon is listening on port 2997. It is going to output 4 random unsigned integers in little-endian format. It then will expect the sum of all 4 of those integers to be returned in little-endian format.
I was able to solve this with the following code:
#!/usr/bin/env python
# Protostar Net 2
# http://exploit-exercises.com/protostar/net2
# Matt Andreko
# twitter: @mandreko
# contact: matt [at] mattandreko.com
from socket import *
from struct import *
from optparse import OptionParser
def main(host, port):
s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
sum = 0
# Loop over the 4 unsigned integers being read in, and them to "sum"
for x in range(4):
data = s.recv(4)
little_endian = int(unpack("<I", data)[0])
print "[*] integer " + str(x) + ": " + str(little_endian)
sum += little_endian
print "[*] Sum: " + str(sum)
# Handle integer overflow by doing a logical AND with 0xffffffff
sum &= 0xffffffff
# Convert the sum back to little-endian, to send back over the wire
sum_packed = pack("<I", sum)
s.send(sum_packed)
print s.recv(1024)
s.close()
if __name__ == "__main__":
parser = OptionParser("usage: %prog [options]")
parser.add_option("-H", "--host", dest="hostname", default="127.0.0.1",
type="string", help="Target to run against")
parser.add_option("-p", "--port", dest="portnum", default=2997,
type="int", help="Target port")
(options, args) = parser.parse_args()
main(options.hostname, options.portnum)
When I run that code, I get the following output:
C:\Protostar>net2.py -H 192.168.1.132 [] integer 0: 1724850170 [] integer 1: 692469090 [] integer 2: 630776982 [] integer 3: 1691529294 [*] Sum: 4739625536 you added them correctly