## Net 0

In this level we are presented with an integer and we have to reply the server with a little endian version of the integer. We use python and the struct module to do the conversion for us:

from socket import *
from struct import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(("localhost", 2999))
challange = s.recv(1024)
start = challange.find("'") + 1
end = challange.find("'", start)
num = int(challange[start:end])
print "Challange: " + str(num)
li = pack("<I", num)
s.send(li)
print(s.recv(1024))
s.close()


And the result:

[email protected]:~$python net0.py Challange: 637794649 Thank you sir/madam  ## Net 1 In this level we are presented with an integer in little endian representation and we have to send back se ASCII representation. The following script can do that: from socket import * from struct import * s = socket(AF_INET, SOCK_STREAM) s.connect(("localhost", 2998)) wanted = s.recv(1024) challange = str(unpack("<I", wanted)) print("Received: " + str(challange)) s.send(challange) print(s.recv(1024)) s.close()  And the result: [email protected]:~$ python net1.py
you correctly sent the data


## Net 2

In this level we are presented with 4 integers in little endian representation and we have to sum them and send back the little endian representation. The following script can do that:

from socket import *
from struct import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(("localhost", 2997))

sum = 0
for i in range(4):
n = s.recv(1024)
num = int(unpack("<I", n))
sum += num
print("Sum: " + str(sum))
sum = pack("<I", sum)
s.send(str(sum))

print(s.recv(1024))
s.close()


The output:

[email protected]:~$python net2.py Received: 1586317571 Received: 1593370836 Received: 1661924573 Received: 1044911132 Sum: 5886524112 net2.py:14: DeprecationWarning: struct integer overflow masking is deprecated sum = pack("<I", sum) you added them correctly  It seems that the integer overflow masking is deprecated so we better do it our selves: from socket import * from struct import * s = socket(AF_INET, SOCK_STREAM) s.connect(("localhost", 2997)) sum = 0 for i in range(4): n = s.recv(1024) num = int(unpack("<I", n)) print("Received: " + str(num)) sum += num print("Sum: " + str(sum)) sum &= 0xffffffff sum = pack("<I", sum) s.send(str(sum)) print(s.recv(1024)) s.close()  and no warning this time: [email protected]:~$ python net2.py
Sum: 5176475099


## Net 3

In this level we are given the following code:

#include "../common/common.c"

#define NAME "net3"
#define UID 996
#define GID 996
#define PORT 2996

/*
* Extract a null terminated string from the buffer
*/

int get_string(char **result, unsigned char *buffer, u_int16_t len)
{
unsigned char byte;

byte = *buffer;

if(byte > len) errx(1, "badly formed packet");
*result = malloc(byte);
strcpy(*result, buffer + 1);

return byte + 1;
}

/*
*/

int login(unsigned char *buffer, u_int16_t len)
{
int deduct;
int success;

if(len < 3) errx(1, "invalid login packet length");

deduct = get_string(&resource, buffer, len);

success = 0;
success |= strcmp(resource, "net3");

free(resource);

return ! success;
}

void send_string(int fd, unsigned char byte, char *string)
{
struct iovec v;
u_int16_t len;
int expected;

len = ntohs(1 + strlen(string));

v.iov_base = &len;
v.iov_len = sizeof(len);

v.iov_base = &byte;
v.iov_len = 1;

v.iov_base = string;
v.iov_len = strlen(string);

expected = sizeof(len) + 1 + strlen(string);

if(writev(fd, v, 3) != expected) errx(1, "failed to write correct amount of bytes");

}

void run(int fd)
{
u_int16_t len;
unsigned char *buffer;
int loggedin;

while(1) {
len = ntohs(len);
buffer = malloc(len);

if(! buffer) errx(1, "malloc failure for %d bytes", len);

switch(buffer) {
case 23:
loggedin = login(buffer + 1, len - 1);
send_string(fd, 33, loggedin ? "successful" : "failed");
break;

default:
send_string(fd, 58, "what you talkin about willis?");
break;
}
}
}

int main(int argc, char **argv, char **envp)
{
int fd;

/* 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(fd);
}


The program is reading a value from the network (len) and convert it from network byte order (bin endian) to host byte order (little endian) and then uses malloc to reserve that length in the heap

Then it reads again from the network the number of bytes specified in the length value and into the heap chunk we just reserved.

Then it reads the first byte and if it is 23 (0x17) then it calls the login function with the rest of the string read from the network

The login function scans the string for three values: net3, awesomesauce and password Each of these strings need to be preceded of a byte indicating its size (including the null byte) and followed by a NULL byte.

Solution:

from socket import *
from struct import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(("localhost", 2996))

print "length: " + str(llength)

# Send the login length as unsigned short (H) and network byte order (!)
s.send(pack("!H", llength))

[email protected]:~\$ python net3.py