flag = '' for s in strings: ascii_str = bytes.fromhex(s.decode()).decode()[::-1] flag += ascii_str
print(flag)
p.interactive()
Maltigriti (62 solves / 352 points)
I just submitted my third bug report to Maltirgiti (a competitor of Intigriti), and it was again closed as a duplicate! Can you figure out what is going on and get me my well deserved swag pack? Author: c0nrad - Sloppy Joe Pirates maltigriti.ctf.intigriti.io 1337
This was my favorite chall I solved recently. <3
Analysis
The C source code was provided. From what I’ve seen, the code is well written, so I’ll share it in full.
voidedit_user(struct User *user) { if (user != 0 && user->bio != NULL) { printf("Your current bio is: %s\n", user->bio); printf("Enter your new bio> "); fgets(user->bio, user->bio_length, stdin); } else { puts("You don't have a bio yet!"); printf("How long is your bio> ");
scanf("%d", &user->bio_length); getchar();
user->bio = malloc(user->bio_length); printf("Enter your new bio> ");
intcalculate_balance(struct Report *report, struct User *user) { int balance = 0;
while (report != NULL) { if (report->status == STATUS_ACCEPTED && report->user == user) { balance += report->bounty; } report = report->next; } printf("Your balance is: %d\n", balance); return balance; }
voidbuy_swag_pack(struct Report *report, struct User *user) { if (calculate_balance(report, user) >= 1337) { puts("You have enough money to buy a swag pack!"); puts("With great swag comes great responsibility."); puts("Here is your swag pack: flag{redacted_redacted}"); exit(0); } else { puts("You don't have enough money to buy a swag pack!"); puts("Keep submitting bug reports and maybe you'll get there one day!"); puts(":evil_grin:"); } }
struct User *register_user() { structUser *user =malloc(sizeof(struct User));
printf("Enter your name> "); fgets(user->name, 32, stdin);
printf("Enter your password> "); fgets(user->password, 32, stdin);
if (firstReport != NULL) { // get last report structReport *scanner = firstReport; while (scanner->next != NULL) { scanner = scanner->next; } scanner->next = report; } else { firstReport = report; }
report->user = user;
printf("Enter your report title> "); fgets(report->title, 32, stdin);
printf("Please enter the content of your report> "); fgets(report->body, 128, stdin);
// Automatically mark the status as duplicate so we don't have to pay anyone :evil_grin: report->status = STATUS_DUPLICATE; report->bounty = 0;
puts("Thank you for submitting your bug report!"); puts("Unfortunately our records indicate that this bug has already been submitted!"); puts("Report will be closed and marked as duplicate."); puts("Hope you didn't spend too much time on it! ( ͡° ͜ʖ ͡°) ");
The condition of getting flag is in the buy_swag_pack function. I need to reconstruct report->status and report->status to get the flag.
The vulnerability is that only user->bio is freed in the logout function.
1 2 3 4 5 6 7 8
voidlogout(struct User *user) { if (user != NULL) { memset(user->name, 0, 32); memset(user->password, 0, 32); memset(user->bio, 0, user->bio_length); free(user->bio); // <-- here } }
Since bio->length can be specified in the register_user function, it can be set to be the same as the size of the report object. This means that you can freely configure the report object using UAF.