Follow us on twitter

Donate Bitcoins

About

This level introduces the concept that memory can be accessed outside of its allocated region, how the stack variables are laid out, and that modifying outside of the allocated memory can modify program execution.

This level is at /opt/protostar/bin/net3

Source code

  1#include "../common/common.c"
  2
  3#define NAME "net3"
  4#define UID 996
  5#define GID 996
  6#define PORT 2996
  7
  8/*
  9 * Extract a null terminated string from the buffer 
 10 */
 11
 12int get_string(char **result, unsigned char *buffer, u_int16_t len)
 13{
 14  unsigned char byte;
 15
 16  byte = *buffer;
 17
 18  if(byte > len) errx(1, "badly formed packet");
 19  *result = malloc(byte);
 20  strcpy(*result, buffer + 1);
 21
 22  return byte + 1;
 23}
 24
 25/*
 26 * Check to see if we can log into the host
 27 */
 28
 29int login(unsigned char *buffer, u_int16_t len)
 30{
 31  char *resource, *username, *password;
 32  int deduct;
 33  int success;
 34
 35  if(len < 3) errx(1, "invalid login packet length");
 36
 37  resource = username = password = NULL;
 38
 39  deduct = get_string(&resource, buffer, len);
 40  deduct += get_string(&username, buffer+deduct, len-deduct);
 41  deduct += get_string(&password, buffer+deduct, len-deduct);
 42
 43  success = 0;
 44  success |= strcmp(resource, "net3");
 45  success |= strcmp(username, "awesomesauce");
 46  success |= strcmp(password, "password");
 47
 48  free(resource);
 49  free(username);
 50  free(password);
 51
 52  return ! success;
 53}
 54
 55void send_string(int fd, unsigned char byte, char *string)
 56{
 57  struct iovec v[3];
 58  u_int16_t len;
 59  int expected;
 60
 61  len = ntohs(1 + strlen(string));
 62
 63  v[0].iov_base = &len;
 64  v[0].iov_len = sizeof(len);
 65  
 66  v[1].iov_base = &byte;
 67  v[1].iov_len = 1;
 68
 69  v[2].iov_base = string;
 70  v[2].iov_len = strlen(string);
 71
 72  expected = sizeof(len) + 1 + strlen(string);
 73
 74  if(writev(fd, v, 3) != expected) errx(1, "failed to write correct amount of bytes");
 75  
 76}
 77
 78void run(int fd)
 79{
 80  u_int16_t len;
 81  unsigned char *buffer;
 82  int loggedin;
 83
 84  while(1) {
 85    nread(fd, &len, sizeof(len));
 86    len = ntohs(len);
 87    buffer = malloc(len);
 88
 89    if(! buffer) errx(1, "malloc failure for %d bytes", len);
 90
 91    nread(fd, buffer, len);
 92
 93    switch(buffer[0]) {
 94      case 23: 
 95        loggedin = login(buffer + 1, len - 1);
 96        send_string(fd, 33, loggedin ? "successful" : "failed");
 97        break;
 98      
 99      default:
100        send_string(fd, 58, "what you talkin about willis?");
101        break;
102    }
103  }
104}
105
106int main(int argc, char **argv, char **envp)
107{
108  int fd;
109  char *username;
110
111  /* Run the process as a daemon */
112  background_process(NAME, UID, GID);  
113  
114  /* Wait for socket activity and return */
115  fd = serve_forever(PORT);
116
117  /* Set the client socket to STDIN, STDOUT, and STDERR */
118  set_io(fd);
119
120  /* Don't do this :> */
121  srandom(time(NULL));
122
123  run(fd);
124}

Discussion