Description
Best Hacker's Shoppe! You start with 40 coins but the flag costs 100. Find a way to get more coins.
Setup
Connect via netcat to interact with the shop.
nc mercury.picoctf.net 42159Solution
Walk me through it- Step 1Use a negative quantity to gain coinsFrom the main menu, select option 1 (Buy). Items are numbered from 0 - choose item 0 (the cheapest). When prompted for quantity, try -1 first to confirm the bug: if your balance increases, the validation is missing. Then enter -99 to overshoot 100 coins. Avoid extremely large negatives (e.g., -2,000,000,000) which can trigger a different integer-overflow path; -99 is safely within int range.
Learn more
This is a classic integer sign validation bug. The shop computes your new balance as:
balance = balance - (price * quantity). With a negative quantity, the subtraction becomes an addition. This class of bug has caused real-world financial exploits in video games and occasionally in production payment systems where quantity fields lack server-side non-negativity checks.Why this vulnerability exists: Developers often validate that a quantity is a number, but forget to validate that it is a positive number. Input validation must cover both type (is it an integer?) and range (is it within acceptable bounds?). The fix is a single server-side check:
if quantity <= 0: return error. Client-side validation alone is never sufficient - an attacker can bypass it by sending a crafted request directly withcurlor a proxy like Burp Suite.Related vulnerability - integer overflow: A different but related bug occurs when a very large positive quantity causes the product
price * quantityto overflow a fixed-width integer, wrapping around to a negative value. In C with signed 32-bit integers, multiplying 1000 * 2200000 overflows and produces a negative number. This negative cost then gets subtracted from the balance, again adding instead of deducting. Both vulnerabilities stem from failing to validate arithmetic results before applying them.Real-world impact: In 2013, a flight booking platform bug allowed users to purchase tickets with a negative number of passengers, generating a refund larger than the original ticket price. Similar issues have appeared in cryptocurrency exchange order books where negative trade quantities were accepted. These bugs are consistently listed in the OWASP Top 10 under "Insecure Design" - business logic that does not account for adversarial inputs.
- Step 2Buy the flag and decode the outputNow select option 1 again and buy item 2 (Fruitful Flag). The shop outputs the flag as a list of decimal ASCII values. Use Python to convert each number to its corresponding character. The separator is usually a comma; if commas don't split cleanly, try newlines as the fallback.python
python3 -c "print(''.join([chr(x) for x in [112,105,99,111,67,84,70,123,98,52,100,95,98,114,111,103,114,97,109,109,101,114,95,55,57,55,98,50,57,50,99,125]]))"bash# Fallback if the values are newline-separated rather than comma-separated:pythonpython3 -c "import sys; print(''.join(chr(int(x)) for x in sys.stdin.read().splitlines() if x.strip()))" < flag_output.txtLearn more
The flag is output as decimal ASCII code points separated by spaces.
chr(x)converts an integer to the corresponding Unicode/ASCII character. Joining the characters gives the flag string. This encoding is trivially reversible - it provides no obfuscation, but is a common pattern for flag delivery in binary/remote challenges.ASCII encoding basics: ASCII maps the integers 0 to 127 to characters. Printable characters start at 32 (space). Uppercase letters are 65 to 90, lowercase 97 to 122, digits 48 to 57. Knowing a few anchor points lets you mentally decode short sequences: 112 = 'p', 105 = 'i', 99 = 'c', 111 = 'o' - which immediately spells "pico," confirming the flag format. This quick check is useful for verifying you have the right values before running the full decode.
Flag
picoCTF{...}
The shop never validates that quantity > 0 - supplying a negative quantity causes the balance to increase instead of decrease.