August 2, 2026
𧨠Writing Custom Exploits: From Vulnerability Discovery to Working PoC
A custom exploit is code you write yourself to demonstrate that a vulnerability is actually exploitable.

By ATNO For Cybersecurity | Hacking
5 min read
Not a Metasploit module someone else wrote. Not a public PoC you downloaded. Something you built from scratch because:
- The vulnerability is new and no public exploit exists
- The existing exploit doesn't work on this specific version or configuration
- You need to prove real-world impact in a pentest report
- You're doing bug bounty and want to show maximum severity
This is the skill that separates good security people from great ones.
πΊοΈ The Journey - Start to Finish
Here's the full picture before we go deep:
Phase What You're Doing Discovery Finding something that looks wrong Analysis Understanding WHY it's wrong Weaponization Making it do something useful PoC Clean, reproducible demonstration
Most beginners spend 90% of their time on discovery and then have no idea what to do next. This post flips that.
π Phase 1: Vulnerability Discovery
Before you write a single line of exploit code, you need to find something worth exploiting.
The mindset shift:
Stop looking for vulnerabilities. Start looking for unexpected behavior.
- What happens when you send a negative number where a positive is expected?
- What happens when a field accepts 10,000 characters instead of 10?
- What happens when you send JSON where the app expects a string?
- What happens when you access resource ID 1 while logged in as user 2?
"Every bug is an assumption the developer made that turned out to be wrong."
Where most people find bugs:
- Input fields that pass data directly to backend processes
- API endpoints that trust client-supplied values
- File upload features (type, size, content all three)
- Authentication flows with multiple steps (what if you skip step 2?)
- Error messages that reveal internal information
A real example:
Imagine a password reset flow: you enter your email, get a 6-digit code, enter it, reset your password.
The assumption: you need the correct code.
The question: does the server actually validate it server-side, or is it just a check in JavaScript?
That question, asked at the right moment, has led to account takeover bugs worth $10,000+ in bug bounty programs.
𧬠Phase 2: Understanding the Vulnerability
Found something weird? Good. Now slow down.
This is where most people rush and it shows in their reports. Before writing any exploit code, you need to understand:
What is actually happening technically?
- Is this a logic flaw (the code does the wrong thing by design)?
- Is this an injection issue (user input reaches a sensitive function)?
- Is this a memory issue (buffer overflow, use-after-free)?
- Is this an access control failure (missing authorization check)?
Why does it happen?
Not "the app doesn't validate input." Specifically WHY the developer made this mistake. Understanding the root cause tells you:
- How far the impact actually reaches
- Whether similar bugs exist elsewhere in the same codebase
- How to write a proper exploit vs. a fragile one-time hack
A quick way to categorize what you found:
- You can read data you shouldn't β Information Disclosure
- You can modify data you shouldn't β Broken Access Control
- You can execute commands you shouldn't β Code Execution
- You can bypass a security check β Authentication/Authorization Bypass
The category determines the next steps.
βοΈ Phase 3: Building the Exploit
Okay. You know what's broken and why. Now let's make it do something.
Start with the simplest possible test:
Don't start with a fancy exploit. Start with the most basic version of the vulnerability that you can reproduce reliably.
For a SQL injection:
import requests
url = "<https://target.com/search>"
payload = "' OR '1'='1"
response = requests.get(url, params={"q": payload})
print(response.status_code)
print(response.text[:500])import requests
url = "<https://target.com/search>"
payload = "' OR '1'='1"
response = requests.get(url, params={"q": payload})
print(response.status_code)
print(response.text[:500])That's it. Does it behave differently? Good. Now you have a foundation.
Build up one step at a time:
- Step 1: Confirm the behavior is reproducible
- Step 2: Confirm it's server-side (not a client-side quirk)
- Step 3: Understand the output you're getting
- Step 4: Expand the impact (read more data, escalate privileges, etc.)
The tools that actually help here:
- Burp Suite Repeater for HTTP-based bugs (send, modify, resend fast)
- Python requests library for scripting custom payloads
- curl for quick one-off tests directly in terminal
- Wireshark if you need to see exactly what's going over the wire
"Your first working payload won't be clean. That's fine. Clean comes later. Working comes first."
π§ͺ A Real Walkthrough - IDOR to Account Takeover
Here's a realistic example of how this plays out end to end.
Discovery:
You're testing a web app. After logging in, your profile is at:
GET /api/user/profile?id=1042GET /api/user/profile?id=1042You change 1042 to 1041.
You get back someone else's profile data.
Analysis:
- This is an IDOR (Insecure Direct Object Reference)
- The server is not checking if the logged-in user owns resource
1041 - Every user ID is probably exploitable, not just adjacent ones
Weaponization:
You write a script that loops through IDs and collects profile data:
import requests
session_cookie = "your_session_cookie_here"
headers = {"Cookie": f"session={session_cookie}"}
for user_id in range(1000, 1100):
response = requests.get(
f"<https://target.com/api/user/profile?id={user_id}>",
headers=headers
)
if response.status_code == 200:
data = response.json()
print(f"ID {user_id}: {data.get('email')} - {data.get('name')}")import requests
session_cookie = "your_session_cookie_here"
headers = {"Cookie": f"session={session_cookie}"}
for user_id in range(1000, 1100):
response = requests.get(
f"<https://target.com/api/user/profile?id={user_id}>",
headers=headers
)
if response.status_code == 200:
data = response.json()
print(f"ID {user_id}: {data.get('email')} - {data.get('name')}")The PoC:
Now you have a reproducible script that proves:
- The vulnerability exists
- It affects all users, not just one
- Real sensitive data (emails, names) is exposed
- Any authenticated user can access any other user's data
That is a high-severity finding. That is what a working PoC looks like.
π Phase 4: Writing the PoC Properly
A PoC is not just "code that works." It's documentation.
Your PoC should include:
- A clear description of the vulnerability in one sentence
- Exact steps to reproduce from scratch
- The expected behavior (what should happen)
- The actual behavior (what does happen)
- Proof: screenshots, output, or response data
- Impact: what can an attacker actually do with this?
The structure that works:
VULNERABILITY: IDOR in user profile endpoint
SEVERITY: High
AFFECTED ENDPOINT: GET /api/user/profile?id=
STEPS TO REPRODUCE:
1. Log in as any user
2. Navigate to /api/user/profile?id=YOUR_USER_ID
3. Change the id parameter to any other integer
4. Observe that you receive another user's profile data
EXPECTED: 403 Forbidden or only your own data
ACTUAL: Full profile data of the target user
IMPACT: Any authenticated user can access the personal
data of every other user in the system.
PROOF OF CONCEPT: [attached script output]VULNERABILITY: IDOR in user profile endpoint
SEVERITY: High
AFFECTED ENDPOINT: GET /api/user/profile?id=
STEPS TO REPRODUCE:
1. Log in as any user
2. Navigate to /api/user/profile?id=YOUR_USER_ID
3. Change the id parameter to any other integer
4. Observe that you receive another user's profile data
EXPECTED: 403 Forbidden or only your own data
ACTUAL: Full profile data of the target user
IMPACT: Any authenticated user can access the personal
data of every other user in the system.
PROOF OF CONCEPT: [attached script output]The one thing most people skip:
Showing the impact clearly. "You can access other users' data" is weaker than "I ran the attached script against IDs 1000β1100 and retrieved 87 unique email addresses, full names, and phone numbers in under 30 seconds."
Numbers make impact real.
π« What to Avoid
A few things that make PoCs weak or get them dismissed:
- Untestable steps: "Exploit the SQL injection to get admin access" β how exactly?
- Screenshots of tool output you don't understand: If you can't explain every line, don't include it
- Overstating impact: If you found an IDOR on a public field that's already visible, that's not a high-severity finding
- Missing reproduction steps: If the report can't be reproduced by the person reading it, it gets closed as "insufficient information"
- Skipping the fix section: A good PoC always includes what the developer should change
π‘ The Skill You're Actually Building
Writing exploits isn't really about the code.
It's about being able to:
- Think like someone who built the system (to understand the assumptions)
- Think like someone trying to break the system (to find the gaps)
- Think like someone who needs to fix the system (to communicate clearly)
That combination technical depth plus clear communication is rarer than you'd think.
The people who get paid the most in security are usually not the best hackers. They're the best at explaining what they found and why it matters.
The PoC is where both things come together. π