简体   繁体   中英

Hacking Challenge - locating vulnerability in the code

My Friend recently completed a hacking challenge and sent it to me (binary and source). I wanted to ask here before I asked him for tips as I want to do it myself :)

I've been going through it but I am struggling to find the vulnerability.

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

static void usage(const char *argv0) {
    printf("Build your own string!\n");
    printf("\n");
    printf("Usage:\n");
    printf("  %s length command...\n", argv0);
    printf("\n");
    printf("Each command consist of a single character followed by it's index.\n");
    printf("\n");
    printf("Example:\n");
    printf("  %s 11 h0 e1 l2 l3 o4 w6 o7 r8 l9 d10\n", argv0);
    exit(1);
}

int main(int argc, char **argv) {
    char *buffer;
    unsigned short buffersize, i, index, length;

    if (argc < 2) usage(argv[0]);

    length = atoi(argv[1]);
    if (length <= 0) {
            fprintf(stderr, "bad length\n");
            return 1;
    }

    buffersize = length + 1;
    buffer = alloca(buffersize);
    memset(buffer, ' ', buffersize);
    buffer[buffersize - 1] = 0;

    for (i = 2; i < argc; i++) {
            if (strlen(argv[i]) < 2) {
                    fprintf(stderr, "bad command \"%s\"\n", argv[i]);
                    return 1;
            }

            index = atoi(argv[i] + 1);
            if (index >= length) {
                    fprintf(stderr, "bad index in command \"%s\"\n", argv[i]);
                    return 1;
            }

            buffer[index] = argv[i][0];
    }

    printf("%s\n", buffer);
    return 0;
}

I think the vulnerability lies within the short int, and the use of alloca.

Entering ./app 65535 65535 can cause a segfault but I can't actually override anything since buffer will only ever be set to max 65535 or it loops around. This makes me think I can't override the EIP to inject shellcode.

Can anyone help me with where to look at?

Thanks!

Actually, the vulnerability lies in the fact that you can store a character at any offset in the buffer allocated with alloca , but the test is done on length rather than size . passing arguments of 65535 and a1 invokes undefined behavior: size as value 0 because of arithmetic wraparound if unsigned short has 16 bits.

You can try passing a first argument of 65535 and subsequent arguments with increasing offsets, that will poke values beyond the end of buffer , possibly overwriting the return address of main and causing a crash:

myprog 65535 a3 a7 a15 a19 a23 a27 a31 a35 a39 a43 a47 a51 a55 a59 a63 ...

Depending on the actual local variable layout, the required offset may be larger than 17 , but should be smaller than 80 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM