0

The goal is to call the function foo in the following program:

struct object {
    unsigned char buf[36];
    void (*fp)();
};

void baz(struct object * obj, unsigned int num) {
    for (int i = 0; i < num; i++) {
        unsigned int x;
        scanf("%d", &x);
        if (x == 0) break;
        obj->buf[i] = x & 0x000000ff;
    }
}

void foo() { // target
}

void bar() {
}

int main() {
    setvbuf(stdin,  NULL, _IONBF, 0); 
    setvbuf(stdout, NULL, _IONBF, 0); 
    setvbuf(stderr, NULL, _IONBF, 0);

    struct object * obj = malloc(sizeof(struct object));
    memset(obj->buf, 0, 36);
    obj->fp = &bar;

    int num;
    scanf("%d", &num);
    if (num > 36) {
        num = 0;
    } else {
        baz(obj, num);
    }

    for (int i = 0; i < num; i++) {
        printf("%d. \t", i + 1);
        for (int j = 0; j < obj->buf[i]; j++) {
            printf("*");
        }
        puts("");
    }

    obj->fp();
    free(obj);
}

My thoughts were to modify fp in obj (which is called at the end) such that it points to foo instead of bar. By entering a negative number for num such that it becomes a large positive number when casted to unsigned int in baz, this should allow the modification of fp by overflowing buf in obj. However, this would require the address of foo which changes every time the program is run.

I would appreciate any ideas or hints to solve this problem.

EDIT: This is a homework question.

wayne
  • 1
  • 1
  • 2
    Is this a homework question? –  Apr 01 '20 at 10:27
  • Yes, so it would be good if I can get some hints instead of the full answer. – wayne Apr 01 '20 at 11:49
  • Alright, then please [edit] your question to clarify that it is for homework. Did your professor mention anything about ASLR? (E.g. you should disable it, your're not allowed to disable it, etc.) –  Apr 01 '20 at 11:59
  • Edited. I didn't hear anything about ASLR. I'm supposed to connect to a server (which executes this program) and provide input for scanf. – wayne Apr 01 '20 at 12:13
  • Then it might be that that server is configured "correctly" already. Have you tried checking how foo() and bar() are placed relatively to each other? –  Apr 01 '20 at 12:34
  • @MechMK1 I tested locally and found that &foo + 0x37 = &bar on every run (although the addresses themselves change). – wayne Apr 01 '20 at 13:14
  • @MechMK1 ASLR wouldn't randomize locally defined functions, it would be PIE that does this, which can't be turned off unless you recompile the executable. – multithr3at3d Apr 01 '20 at 13:55
  • @multithr3at3d You're probably right. i don't know too much about binary exploitation –  Apr 01 '20 at 13:58
  • See which call instruction are used for call fp (relative E8 or absolute FF) – Billy Apr 01 '20 at 13:27
  • If it is not compiled for debugging, there is no way - the function is unused and gets optimized away. – Aganju Apr 03 '20 at 01:51

0 Answers0