Description
The bank's challenge asks for two positive integers that satisfy n1 > n1 + n2 or n2 > n1 + n2. Triggering 32-bit integer overflow is the intended exploit.
Setup
Review the provided source to confirm the comparison uses signed 32-bit ints.
Connect to the service and submit two large positive values that overflow when added.
wget https://artifacts.picoctf.net/c/456/flag.cprintf '2147483647\n2147483647\n' | nc saturn.picoctf.net 60781Solution
Walk me through it- Step 1Confirm the int width with objdumpDisassemble the binary and grep for the comparison; a signed 32-bit int check appears as cmp against 0x7fffffff (INT_MAX). That confirms the wrap-around at exactly 2^31 - 1.bash
objdump -d ./flag | grep -E 'cmp.*0x7fffffff' -B2 -A2Learn more
Integer overflow occurs when an arithmetic operation produces a result outside the range representable by the integer type. A 32-bit signed integer holds values from -2,147,483,648 to 2,147,483,647 (INT_MIN to INT_MAX). When you add 2,147,483,647 + 2,147,483,647, the mathematical result (4,294,967,294) exceeds INT_MAX, so it wraps around to -2 in two's complement arithmetic.
Two's complement is the near-universal representation of signed integers in hardware. In two's complement, addition and subtraction work identically for signed and unsigned numbers at the bit level; the CPU does not distinguish. Overflow just means the carry bit is discarded, and the result is interpreted as a signed value. For 32 bits:
0x7FFFFFFF + 0x7FFFFFFF = 0xFFFFFFFE = -2when read as signed.The condition
n1 > n1 + n2is logically impossible for positive integers in math. But in C with 32-bit signed ints, if the sum wraps to a negative number, a positiven1is indeed greater than the negative sum. The disassembly check anchors that intuition; if you seecmp eax, 0x7fffffffin the comparison's neighborhood, you are looking at a signed 32-bit int and the wrap point is exactly where you expect it. - Step 2Submit the overflow pairPipe two INT_MAX values into the service. The sum wraps to a negative number, the bogus inequality holds, and the flag prints.bash
printf '2147483647\n2147483647\n' | nc saturn.picoctf.net 60781Learn more
INT_MAX (2,147,483,647 = 2^31 - 1) is the maximum value for a 32-bit signed integer. Any pair of positive integers whose sum exceeds INT_MAX will overflow and produce a negative (or unexpectedly small) result. Using INT_MAX twice is the cleanest choice because it maximally overflows, but values like 1,200,000,000 + 1,000,000,000 would also work.
Real-world impact of integer overflow is serious and well-documented:
- CVE-2018-10933 (libssh): integer-handling bug let attackers bypass authentication entirely.
- CVE-2022-37454 (XKCP/SHA-3): integer overflow in the official Keccak/SHA-3 implementation triggered a buffer overflow exploitable in any consumer of the library.
- The Ariane 5 rocket crash (1996): a 64-bit float was cast to a 16-bit integer, overflowing and shutting down the guidance system. Old, but still the canonical example of why width conversions matter.
- Game economy exploits: item counts and gold values stored as 32-bit ints that wrap around when maximized.
In C, signed integer overflow is formally undefined behavior; the compiler is allowed to assume it never happens and optimize accordingly, which can introduce security vulnerabilities even when the developer expects wrap-around behavior. Unsigned integers, by contrast, are defined to wrap. Languages like Rust and Swift trap on overflow by default in debug builds. For more on the disassembly workflow used here, see Buffer Overflow Binary Exploitation in CTF.
Flag
picoCTF{Tw0_Sum_Integer_Bu773R_0v3rf...8bd}
Any pair causing signed overflow works; using INT_MAX keeps the math simple.