This blog post will be a sum-up for Net 0, Net 1, Net 2 and Net 3 challenges of exploit-exercises’ Protostar wargame.
In the first challenge we have to read a random integer’s decimal representation off the network and send it back. We parse the received data, we convert into an integer value and send it back.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define RPORT 2999
#define BUF_SIZE 255
#define RHOST “192.168.23.5”int main (int argc, char **argv)
{
int sd, wanted;
char buf[BUF_SIZE];
char *ptr;
struct sockaddr_in target;/* Prepare structures and socket */
memset (&target, 0, sizeof (target));
target.sin_family = AF_INET;
target.sin_port = htons (RPORT);
if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
{
printf(“inet_pton()”);
return -1;
}
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
printf(“socket()”);
return -1;
}/* Connect to the target host */
if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
{
printf(“connect()”);
return -1;
}
/* Read the message */
if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
{
printf(“recv()”);
return -1;
}
printf ("%s\n", buf);/* Extract the value */
ptr = (char *) buf + 14;
while ((*ptr++ != ‘\’’) && (ptr < buf + BUF_SIZE));wanted = atoi (buf + 13);
/* Send it back in little endian */
if (send (sd, &wanted, sizeof (wanted), 0) != sizeof (wanted))
{
printf(“send()”);
return -1;
}memset (buf, 0, BUF_SIZE);
if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
{
printf(“recv()”);
return -1;
}
printf ("%s\n", buf);return 0;
}
kroosec@doj:~/protostar$ ./a.out
Please send ‘217873919’ as a little endian 32bit intThank you sir/madam
The second challenge is mostly the inverse of the first. We read an integer over
the network and send back its decimal representation.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define RPORT 2998
#define BUF_SIZE 255
#define RHOST “192.168.23.5”int main (int argc, char **argv)
{
int sd;
char buf[BUF_SIZE];
char tmp[BUF_SIZE];
char *ptr;
struct sockaddr_in target;/* Prepare structures and socket */
memset (&target, 0, sizeof (target));
target.sin_family = AF_INET;
target.sin_port = htons (RPORT);
if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
{
printf(“inet_pton()”);
return -1;
}
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
printf(“socket()”);
return -1;
}/* Connect to the target host */
if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
{
printf(“connect()”);
return -1;
}
/* Read the message */
if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
{
printf(“recv()”);
return -1;
}memset (tmp, 0, BUF_SIZE);
sprintf (tmp, “%d”, *(int *)buf);if (send (sd, tmp, strlen (tmp), 0) != strlen (tmp))
{
printf(“send()”);
return -1;
}memset (buf, 0, BUF_SIZE);
if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
{
printf(“recv()”);
return -1;
}
printf ("%s\n", buf);return 0;
}kroosec@doj:~/protostar$ ./a.out
you correctly sent the data
The third challenge is about sending back the sum 4 unsigned integers received
over the wire.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define RPORT 2997
#define BUF_SIZE 255
#define RHOST “192.168.23.5”int main (int argc, char **argv)
{
unsigned int sd, wanted, i;
char buf[BUF_SIZE];
struct sockaddr_in target;/* Prepare structures and socket */
memset (&target, 0, sizeof (target));
target.sin_family = AF_INET;
target.sin_port = htons (RPORT);
if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
{
printf(“inet_pton()”);
return -1;
}
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
printf(“socket()”);
return -1;
}/* Connect to the target host */
if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
{
printf(“connect()”);
return -1;
}wanted = 0;
/* Read 4 unsigned integers and sum them up. */
for (i = 0; i < 4; i++)
{
if (recv (sd, buf, sizeof (int), 0) == -1)
{
printf(“recv()”);
return -1;
}
wanted += *(int *) buf;
}if (send (sd, &wanted, sizeof (int), 0) != sizeof (int))
{
printf(“send()”);
return -1;
}memset (buf, 0, BUF_SIZE);
if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
{
printf(“recv()”);
return -1;
}
printf ("%s\n", buf);return 0;
}
kroosec@doj:~/protostar$ ./a.out
you added them correctly
The last challenge of the networking category emulates a networking protocol. It starts by reading the total length of the data on 2 bytes which will be 31. Following is 23 on one byte, which signifies login command. After that the resource net3, the username awesomesauce and the password each terminated with a null byte and prepended with its length (+1 for null byte).
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define RPORT 2996
#define BUF_SIZE 500
#define RHOST “192.168.23.5”int main (int argc, char **argv)
{
int sd;
char buf[BUF_SIZE];
struct sockaddr_in target;/* Prepare structures and socket */
memset (&target, 0, sizeof (target));
target.sin_family = AF_INET;
target.sin_port = htons (RPORT);
if (inet_pton (AF_INET, RHOST, &target.sin_addr.s_addr) != 1)
{
printf(“inet_pton()”);
return -1;
}
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
printf(“socket()”);
return -1;
}/* Connect to the target host */
if (connect (sd, (struct sockaddr *) &target, sizeof (target)))
{
printf(“connect()”);
return -1;
}/* Prepend with payload size == 31 */
if (send (sd, “\x00\x1f”, 2, 0) != 2)
{
printf(“send()”);
return -1;
}/* Start with 23 */
if (send (sd, “\x17”, 1, 0) != 1)
{
printf(“send()”);
return -1;
}/* resource */
if (send (sd, “\x05net3\x00”, 6, 0) != 6)
{
printf(“send()”);
return -1;
}/* login */
if (send (sd, “\x0d"“awesomesauce\x00”, 14, 0) != 14)
{
printf(“send()”);
return -1;
}/* password */
if (send (sd, “\x09password\x00”, 10, 0) != 10)
{
printf(“send()”);
return -1;
}memset (buf, 0, BUF_SIZE);
if (recv (sd, buf, BUF_SIZE - 1, 0) == -1)
{
printf(“recv()”);
return -1;
}
printf ("%s\n”, buf+2);return 0;
}
kroosec@doj:~/protostar$ ./a.out
!successful
And that is it with the Networking challenges of Protostar.