Search code examples
cbuffer-overflowshellcode

Treat input as hex values


I am trying to learn how to create shellcode and I need to input a whole bunch of hex codes. However, when I give give my program an input with hex codes, the hex codes are treated as normal ASCII chars and the backslash is simply just stripped.

Example:

./a.out "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x35\x85\x04\x08"

In this scenario, the hex codes (\x35\x85\x04\x08) is treated as individual characters - i.e. x=0x75 etc.

The way my program handles input is similar to the following:

int authentication(char *pass){
  char password_buffer[16];
  strcpy(password_buffer, pass);
  return 1;
}

int main(int argc, char *argv[]){
   if(authentication(argv[1])){
      //access
   }
  return 1;
}

A dump from memory after strcpy():

0xbffff260: 0x41414141  0x41414141  0x41414141  0x41414141
0xbffff270: 0x78353378  0x30783538  0x38307834  0x08048400

As you can see, at address 0xbffff270 the memory value is 0x78353378, which corresponds to x35x and thus the three first letters in the hex-code input. I would like these four bytes to be 0x08048535.

How do I format my input to do this?


Solution

  • You could use shell printf function like this:

    ./a.out "$(printf "AAAAA\x08\x32\x20\xfa\x10\x16")"
    

    Hex values will be converted to "binary".


    This part is perhaps only adding clutter, and I can and might remove it:

    Else you could also do a quick conversion inside your program, to make it easier to use across platforms and systems. A crude sample. (This takes a string and converts any hex sequences where they are presented as \xNN, and in addition prints a hex dump at completion):

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    /*
     * Hex Dump
     * */
    static void txt(unsigned char *buf, int len) 
    {
            int i;
            fprintf(stdout, "  ");
            for (i = 0; i < len; ++i) {
                    fprintf(stdout,
                            "%c",
                            isprint(buf[i]) ?
                            buf[i] :
                            '.'
                    );
            }
    }
    
    static void xxd(unsigned char *buf, int len) 
    {
            int i, j;
    
            for (i = 0; i < len; ) {
                    if (!(i % 16)) {
                            fprintf(stdout,
                                    "%s%03x: ",
                                    i ? "\n" : "",
                                    i
                            );
                    }
                    fprintf(stdout, "%02x ", buf[i]);
                    if (!(++i % 16))
                            txt(&buf[i - 16], 16);
            }
            if ((i % 16)) {
                    for (j = i; j % 16; ++j)
                            fprintf(stdout, "   ");
                    txt(&buf[i - (i % 16)], i % 16);
            }
            fprintf(stdout, "\n");
    }
    
    /*
     * Hex char to value.
     * */
    static unsigned hexval(char c)
    {
        if (c >= '0' && c <= '9')
            return c - '0';
        if (c >= 'a' && c <= 'f')
            return c - 'a' + 10;
        if (c >= 'A' && c <= 'F')
            return c - 'A' + 10;
        return ~0;
    }
    /*
     * Convert all hex sequences.
     * */
    int str2bin(char *data, unsigned char **buf_ptr) 
    {
            int len, converted = 0;
            unsigned int val;
            unsigned char *buf;
    
            buf = malloc(strlen(data) + 1);
            *buf_ptr = buf;
    
            for (; *data; ) {
                    /* If next char is not backslash copy it and continue */
                    if (*data != '\\') {
                            *buf++ = *data++;
                            continue;
                    }
                    /* If we have anything else then x or X after, return error. */
                    if (data[1] != 'x' && data[1] != 'X')
                            return -1;
                    val = (hexval(data[2]) << 4) | hexval(data[3]);
                    /* If not valid hex, return error. */
                    if (val & ~0xff)
                            return -1;
                    *buf++ = val;
                    data += 4;
                    /* Keep track of converted numbers, "for fun". */
                    ++converted; 
            }
            len = buf - *buf_ptr;
    
            fprintf(stderr, "%d hex values converted.\n", converted);
    
            return len;
    }
    
    int main(int argc, char *argv[])
    {
            int len;
            unsigned char *buf = NULL;
            if (argc < 2) {
                    fprintf(stderr, "Missing argument.\n");
                    return 1;
            }
    
            if ((len = str2bin(argv[1], &buf)) < 0) {
                    fprintf(stderr, "Bad input.\n");
                    return 2;
            }
    
            xxd(buf, len);
    
            free(buf);
    
        return 0;
    }
    

    Giving you something like this:

    $ ./hexin "Hello\x20\x44\x65\x08\x01\x00\x00\xf7\xdf\x00\x02Bye"
    11 hex values converted.
    000: 48 65 6c 6c 6f 20 44 65 08 01 00 00 f7 df 00 02   Hello De........
    010: 42 79 65                                          Bye