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 via nc saturn.picoctf.net 60781 and submit two large positive values that overflow when added.
wget https://artifacts.picoctf.net/c/456/flag.c && cat flag.cpython3 - <<'PY'
print(2147483647)
print(2147483647)
PY | nc saturn.picoctf.net 60781Solution
- Step 1Understand the constraintBecause 32-bit signed addition wraps, adding two maximum ints produces a negative result. This satisfies the inequality check.
Learn more
Integer overflowoccurs when an arithmetic operation produces a result outside the range representable by the integer type. A 32-bit signed integer can hold 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 doesn't 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. This is the bug the challenge exploits. - Step 2Submit the overflow pairSend 2147483647 twice (or any pair that sums beyond INT_MAX). The service interprets the overflow and prints the flag.
Learn 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 2,147,483,647 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. Notable examples include:
- The Ariane 5 rocket crash (1996) - a 64-bit float was cast to a 16-bit integer, overflowing and causing the guidance system to shut down
- Android's libpng vulnerability (2015) - integer overflow led to a heap buffer overflow exploitable via malicious PNG files
- Many game 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.
Flag
picoCTF{Tw0_Sum_Integer_Bu773R_0v3rf...8bd}
Any pair causing signed overflow works; using INT_MAX keeps the math simple.