363 words
2 minutes
office-program

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#

chall.c
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 -2147483648 again

  • Then += 5 makes it -2147483643 (still negative)

  • Since var_c < 0, print_flag() executes

office-program
https://fuwari.vercel.app/posts/office-program/office-program/
Author
a.b.h.a
Published at
2025-11-11
License
CC BY-NC-SA 4.0