Write-up of the challenge “office-program”
This challenge is part of the “Binary exploitation” category and earns 100 points.
Goal of the challenge
The objective of this challenge is to feed the program a certain number that will eventually be less than zero.
Program structure
int32_t main(int32_t argc, char** argv, char** envp){ setvbuf(__TMC_END__, nullptr, 2, 0); srand(time(nullptr)); puts("Welcome to the Office Program");
while (true) { puts("\nSelect an action:"); puts("0 - Exit (like leaving the office at 5 PM)"); puts("1 - Print favourite excel column"); puts("2 - Call Rebecca from front desk"); puts("3 - Get secret sauce (only for finance)"); printf("Enter your choice: "); int32_t var_c; __isoc99_scanf("%d", &var_c); important_work_or_attend_a_meeting();
if (var_c == 3) break;
if (var_c < 0) { puts("\nInput out of range. You confused the system"); var_c = -(var_c); }
var_c += 5;
if (var_c >= 0) { var_c = 0;
if (var_c) { puts("\nClocking out... Goodbye!"); return 0; }
if (var_c == 1) puts("\nDon't forget the TPS reports. Also, the printer is jammed again."); else if (var_c != 2) puts("\nThe CEO wants to talk to you"); else puts("\nAdjusting the CRT monitor's brightness..."); } else { puts("\nInput out of range. You confused the system"); print_flag(); }
if (rand() % 3) { if (rand() % 3 != 1) puts("\nUnexpected error, please insert disk"); else puts("\nRandom action: Rewinding a cassette tape with a pencil..."); } else puts("\nRandom action: Faxing a memo to nowhere..."); }
puts("\nThe Office Program is not able to process the number 3"); important_work_or_attend_a_meeting(); puts("\nExiting now..."); exit(0); /* no return */}Security breach
Not doing any checks for integer overflow if (var_c >= 0).
Solution
So my solution was to send the MAX_UNIT for signed integer which is 2**31 or 2147483648 to understand how we got here we need to look at the program’s flow:
-
The menu choice var_c is read as a signed 32 bit integer
-
If input is negative, it’s negated: var_c = -(var_c)
-
Then var_c += 5 is executed
-
If var_c >= 0, normal menu processing happens
-
If var_c < 0, print_flag() is called
So when we send 2147483648, this happens:
-
When negated:
-(-2147483648)tries to compute 2147483648 -
This overflows because 2147483648 > INT_MAX (2147483647)
-
Signed overflow wraps to
-2147483648again -
Then += 5 makes it
-2147483643(still negative) -
Since
var_c < 0,print_flag()executes