Protostar exploits Net2

Introduction

Protostar exploits are a cool bunch of ctf type exercises that focus on Linux  binary exploits that progressively get harder. A ISO containing the OS and challenges can be downloaded.

The website with all information and downloads is at https://exploit-exercises.com/protostar/

Challenge

Test run

net2 is a network daemon that listens on port 2997. The iso image automatically starts the daemon for you. If we list the running processes you should see it.

root@protostar:/home/user# ps ax |grep net2
 1662 ? Ss 0:00 /opt/protostar/bin/net2
28632 pts/1 S+ 0:00 grep net2
root@protostar:/home/user# netstat -nap|grep net2
tcp 0 0 0.0.0.0:2997 0.0.0.0:* LISTEN 1662/net2 
localhost.localdomain [127.0.0.1] 2997 (?) open
eO?t?`?7FBH?
AAAA 
sorry, try again. invalid
 sent 5, rcvd 42

Exploit

We need to connect to the network daemon, read four random numbers sent to us, reverse byte order them and send back the sum of all the numbers in little endian order. Success will be indicated with the message ‘you added them correctly’.

#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();
}

I found that scripting my challenge helped me have greater control over reading the challenge integer values and converting to little endian ready for sending back to the server as raw bytes.

Here is my script https://github.com/muttiopenbts/protostar/blob/master/protostar-net2.py

"""
This code is for protostar net2 challange.
Will connect to net2 network daemon, read 4 integers reverse byte order, add them up, reverse order total and send back to server.
"""
import socket
import sys
import re
import struct

try:
 #create an AF_INET, STREAM socket (TCP)
 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
 print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
 sys.exit()

print 'Socket Created'

host = sys.argv[1]
port = sys.argv[2]

try:
 remote_ip = socket.gethostbyname( host )

except socket.gaierror:
 #could not resolve
 print 'Hostname could not be resolved. Exiting'
 sys.exit()

print 'Ip address of ' + host + ' is ' + remote_ip

#Connect to remote server
s.connect((remote_ip, int(port)))
s.settimeout(2) #Raise exception if no data received after 2 seconds, Use this timeout to begin processing data received from server.

print 'Socket Connected to ' + host + ' on ip ' + remote_ip

recv_array = []
total = 0

try:
 #Now receive data
 while True:
 recv = s.recv(4096)
 recv_array.append(recv)
 print "Received: %s" %recv

except socket.timeout:
 print("Timeout. Server has finished sending data. Time to add up all the values.")
 for bytes in recv_array:
 hexval = bytes.encode('hex')
 integer = struct.unpack("<L", bytes)[0] #L=unsigned long 4 bytes, < little endian and unpacked to integer
 total += integer
 print "Received bytes %s converted little endian %s which resulted in an integer %s" %(hexval, hex(integer), integer)
 rev_bytes = struct.pack("<L", total)#reverse bytes received for little endian
 print "Total up the integers %s, reverse byte order from %s to %s and send" %(total, hex(total), rev_bytes.encode('hex'))
 print "Sending challenge to server"
 s.sendall(rev_bytes)

 recv = s.recv(4096)
 print recv
except socket.error:
 #Send failed
 print 'Send failed'
 sys.exit()

print 'Done.'

Testing the script

user@protostar:~$ python protostar-net2.py localhost 2997
Socket Created
Ip address of localhost is 127.0.0.1
Socket Connected to localhost on ip 127.0.0.1
Received: ??`
Received: Du3
Received: Y?Bj
Received: Pm
Timeout. Server has finished sending data. Time to add up all the values.
Received bytes ba926004 converted little endian 0x46092ba which resulted in an integer 73437882
Received bytes 44750033 converted little endian 0x33007544 which resulted in an integer 855668036
Received bytes 59f1426a converted little endian 0x6a42f159 which resulted in an integer 1782772057
Received bytes 50166d1f converted little endian 0x1f6d1650 which resulted in an integer 527242832
Total up the integers 3239120807, reverse byte order from 0xc1110fa7L to a70f11c1 and send
Sending challenge to server
you added them correctly
Done.

The script reads four integers from the network socket, reverse byte orders each one, totals up the values, reverse orders the total and send back to the server.

Thank you

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s