In the documented picoCTF 2022 Buffer Overflow 1 binary, the worked offset from the input buffer to saved EIP is 44 bytes. The example payload is 44 padding bytes followed by the little-endian address of win(), 0x080491f6. Those values belong to that specific 32-bit binary; measure the offset and find the function address in your own challenge artifact before using them.
What the challenge is asking you to do
The 2022 challenge source shown in the CTFtime writeup declares a 32-byte local buffer and reads into it with gets(), which does not enforce a destination size. It also defines win(), which reads flag.txt and prints its contents. The intended control-flow change is to supply input that overwrites the saved return address so the vulnerable function returns to win().
As an Amazon Associate I earn from qualifying purchases.
This is a ret2win exercise: you are not injecting new code. You are redirecting execution to a function already present in the program. picoCTF’s 2018 educational outcomes PDF describes buffer-overflow exploitation and return-address control as learning goals, and also identifies GDB debugging and mitigations such as canaries, ASLR, and NX as relevant topics. That document explains the educational context; it does not confirm whether this particular challenge is currently available.
Recommended Free Tools
Confirm the binary and find its target values
Do not start by assuming the buffer size, offset, architecture, or address from an online payload. They are properties of the exact executable and its build. Inspect the challenge source or binary, identify the input function and the intended target function, then measure how far the input buffer is from the saved instruction pointer.
#1 Best Overall
- Identify the artifact: confirm that you have the 2022 Buffer Overflow 1 binary, rather than a similarly named challenge from another year.
- Check architecture and protections: the cited 2022 example is i386 (32-bit), with no stack canary, NX disabled, and no PIE. Your supplied binary may differ.
- Locate the functions: find the vulnerable input path and
win()in the source, symbols, or disassembly. - Measure the offset: use a debugger such as GDB to determine the distance from the start of the input buffer to the saved return address. The declared buffer length alone does not establish that distance; saved frame data and compiler layout matter.
- Encode the target address: use the target architecture’s byte order. For the cited 32-bit little-endian binary, the example address is represented as four bytes, least significant byte first.
Build the 2022 example payload
In the specific 32-bit binary documented by CTFtime, the buffer starts at 0xffffd050 and saved EIP is at 0xffffd07c, a difference of 44 bytes. The writeup identifies win() at 0x080491f6 (also printed as 0x80491f6). Therefore, the demonstrated payload structure is:
[44 padding bytes] + [win() address in 32-bit little-endian form]
For example, using pwntools, the structure can be expressed as b'A' * 44 + p32(0x080491f6). This is an illustration of the documented binary, not a universal solve string. Use the measured offset and address from your own copy, and confirm that the payload reaches the intended function under the same execution conditions.
Verify locally before using a challenge service
- Run the exact local binary under GDB. Use a controlled input and confirm where execution stops when the function returns. The goal is to verify that the saved return address is overwritten at the offset you measured.
- Test the ret2win payload locally. Check that execution reaches
win(), rather than crashing earlier or returning somewhere unexpected. If it does not, revisit the offset, architecture, byte order, and function address. - Account for the local flag-file behavior. The cited writeup reports a fallback message when
flag.txtis unavailable. A local run may therefore reachwin()successfully without displaying a competition flag; that output alone does not prove the control-flow redirect failed. - Only then use the authorized challenge instance. The cited example does not establish a current remote endpoint or service status. Use the endpoint and instructions supplied by the challenge platform, and do not treat an old address or service as current.
Why the 2019 “Overflow 1” payload is different
A separate picoCTF 2019 Overflow 1 writeup documents a different program: it has a 64-byte buffer, calls the target function flag(), and derives a 76-byte offset (0x48 bytes from the buffer to EBP plus four bytes for saved EBP). Its function address and payload are not interchangeable with the 2022 Buffer Overflow 1 example. Compare the year, architecture, buffer layout, measured offset, target function, and protections in the exact artifact you are solving. [c003] The cited 2022 writeup supports the 2022 values described above; the 2019 details are identified in the challenge materials as a separate edition and should not be used to derive the 2022 payload.
Quick Recap
Best Value
Rank #4
Rank #3
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




