Assignment: SUBTERFUGE

Changelog:

Your Task

  1. Download the target executable program dumbledore.exe. (This is a different program than for the OVER assignment.) Your job is to exploit a buffer overflow using pointer subterfuge.

    Your goal is to construct a program input such that the program’s output ends with:

    Congratulations, YOUR NAME.
    I recommend that you get an A on this assignment.
    

    You will supply an attack program like attack.py and then we will something like:

    python3 attack.py > input.txt
    ./dumbledore.exe < input.txt
    

    or a similar program named attack.c or attack.cc or attack.py2 (which we will run differently, as in the OVER assignment).

    Unlike the OVER assignment, we will not disable address randomization or attempt to normalize the location of the stack pointer. Although we will not disable ASLR system-wide, the program’s code uses hard-coded addresses, so it must be loaded at a fixed address. The address of the heap and libraries will, however be randomized.

Important about what the vulnerable program does

  1. The vulnerable code uses structs declared like:

    struct StudentInfo {
        char name[SOME SIZE];
        struct Assignment *current_assignment;
    };
    

    and then runs code that looks like:

    printf("Your name: ");
    gets(info->name);
    printf("Your submission: ");
    gets(info->current_assignment->submission);
    

    (where info is a struct StudentInfo*, and submission is a char array in the struct Assignment struct).

  2. Rather than writing shellcode, you will be able to use arc injection to run a “PrintSuccessAndExit” function included in the program.

Hints

  1. The gets(info->name) call can overwrite info->current_assignment. Your goal is to take advantatge of overwriting this pointer in order to overwrite something more important.

  2. You will need to figure out where in the current_assignment struct submission is.

  3. You should examine out what the program does after accepting input in order to find a function pointer that you can overwrite.

  4. The executable does not fully enable RELRO (relocation read-only)

  5. This list of useful GDB commands may be helpful.

  6. As part of a buffer-overflow avoidance feature, the compiler manages to add a check on the first gets call the vulnerable code makes. But this check happens to only verify that the gets call remains in bounds of the object allocated on the heap, not of the string field within that object.

  7. I recommend verifying that your attack input looks correct in a hex editor if you have problems.

Writing binary data with Python 3

  1. By default Python 3 expects to output strings as UTF-8 or something similar, in which you can’t easily include arbitrary bytes.

  2. You should avoid using strings and instead use bytes or bytearray objects.

  3. To output binary data to stdout, use something like sys.stdout.buffer.write(some_bytes). (See “note” in documentation here.) (You won’t be able to use print because it needs to convert its arguments to strings first.)