September 19, 2026
Mastering Business Logic Vulnerabilities — PortSwigger All Labs Walkthrough
# Lab 1: Excessive Trust in Client-Side Controls
By Bhanvararam choudhary
13 min read
# Lab 1: Excessive Trust in Client-Side Controls
…………………………………………………………………………………………………
Concept: The server trusts the price value supplied by the client instead of validating the actual product price.
Reproduce / Steps
- Login with
wiener:peterand add the Lightweight l33t leather jacket to the cart. - In Burp → Proxy → HTTP history, find:
POST /cart - Send it to Repeater. The request contains:
productId=1&redir=PRODUCT&quantity=1&price=1337
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*x50FCRocJB1lC-CTl_oEfA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*x50FCRocJB1lC-CTl_oEfA.png 1x">
<img src="/img/medium/700/1*x50FCRocJB1lC-CTl_oEfA.png" alt="None" width="922" height="733" loading="lazy" data-zoom-src="/img/medium/4000/1*x50FCRocJB1lC-CTl_oEfA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*VEvf0g0IUVvxSA7iJo227A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*VEvf0g0IUVvxSA7iJo227A.png 1x">
<img src="/img/medium/700/1*VEvf0g0IUVvxSA7iJo227A.png" alt="None" width="1107" height="847" loading="lazy" data-zoom-src="/img/medium/4000/1*VEvf0g0IUVvxSA7iJo227A.png" class="prose-image"/>
</picture>
4.Change the client-controlled `price` to an amount below your store credit, for example
productId=1&redir=PRODUCT&quantity=1&price=1
5. Send the request and refresh the cart. The jacket price becomes **$1**.
6. Place the order.
### Result
The jacket originally costs **$1337**, but the server accepts the manipulated client-side price and allows the purchase for **$1**.
**Root cause:** Excessive trust in client-side controls. The server should fetch and validate the product price server-side instead of trusting the `price` parameter supplied by the client.
**Flag/Result:** Lab solved — _Lightweight l33t leather jacket purchased for $1._
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*2tJnO2kp6KgLI47dnHQErA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*2tJnO2kp6KgLI47dnHQErA.png 1x">
<img src="/img/medium/700/1*2tJnO2kp6KgLI47dnHQErA.png" alt="None" width="1481" height="1046" loading="lazy" data-zoom-src="/img/medium/4000/1*2tJnO2kp6KgLI47dnHQErA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*8uOUpj1Ft_nZhgovZTfC0A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*8uOUpj1Ft_nZhgovZTfC0A.png 1x">
<img src="/img/medium/700/1*8uOUpj1Ft_nZhgovZTfC0A.png" alt="None" width="1822" height="792" loading="lazy" data-zoom-src="/img/medium/4000/1*8uOUpj1Ft_nZhgovZTfC0A.png" class="prose-image"/>
</picture>
```bash
# Lab2: High-level Logic Vulnerability
**Logic:** The application accepts a negative `quantity` value. This allows us to create a negative-priced cart item and use it to reduce the total cost of the leather jacket.
### Reproduce
1. Login with `wiener:peter` and add a cheap product to the cart.
2. In Burp, capture the `POST /cart` request and modify:
```http
quantity=-1productId=1&redir=PRODUCT&quantity=1&price=1337
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*x50FCRocJB1lC-CTl_oEfA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*x50FCRocJB1lC-CTl_oEfA.png 1x">
<img src="/img/medium/700/1*x50FCRocJB1lC-CTl_oEfA.png" alt="None" width="922" height="733" loading="lazy" data-zoom-src="/img/medium/4000/1*x50FCRocJB1lC-CTl_oEfA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*VEvf0g0IUVvxSA7iJo227A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*VEvf0g0IUVvxSA7iJo227A.png 1x">
<img src="/img/medium/700/1*VEvf0g0IUVvxSA7iJo227A.png" alt="None" width="1107" height="847" loading="lazy" data-zoom-src="/img/medium/4000/1*VEvf0g0IUVvxSA7iJo227A.png" class="prose-image"/>
</picture>
4.Change the client-controlled `price` to an amount below your store credit, for example
productId=1&redir=PRODUCT&quantity=1&price=1
5. Send the request and refresh the cart. The jacket price becomes **$1**.
6. Place the order.
### Result
The jacket originally costs **$1337**, but the server accepts the manipulated client-side price and allows the purchase for **$1**.
**Root cause:** Excessive trust in client-side controls. The server should fetch and validate the product price server-side instead of trusting the `price` parameter supplied by the client.
**Flag/Result:** Lab solved — _Lightweight l33t leather jacket purchased for $1._
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*2tJnO2kp6KgLI47dnHQErA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*2tJnO2kp6KgLI47dnHQErA.png 1x">
<img src="/img/medium/700/1*2tJnO2kp6KgLI47dnHQErA.png" alt="None" width="1481" height="1046" loading="lazy" data-zoom-src="/img/medium/4000/1*2tJnO2kp6KgLI47dnHQErA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*8uOUpj1Ft_nZhgovZTfC0A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*8uOUpj1Ft_nZhgovZTfC0A.png 1x">
<img src="/img/medium/700/1*8uOUpj1Ft_nZhgovZTfC0A.png" alt="None" width="1822" height="792" loading="lazy" data-zoom-src="/img/medium/4000/1*8uOUpj1Ft_nZhgovZTfC0A.png" class="prose-image"/>
</picture>
```bash
# Lab2: High-level Logic Vulnerability
**Logic:** The application accepts a negative `quantity` value. This allows us to create a negative-priced cart item and use it to reduce the total cost of the leather jacket.
### Reproduce
1. Login with `wiener:peter` and add a cheap product to the cart.
2. In Burp, capture the `POST /cart` request and modify:
```http
quantity=-1- Send the request repeatedly until the cheap product has a negative quantity.
- Add the Lightweight l33t leather jacket normally with:
quantity=1
- Use a suitable negative quantity for the cheap product so that the final cart total becomes less than your available store credit.
- Place the order.
Example
Leather jacket = $1337 × 1
Com-Tool = $99.10 × -14
--------------------------------
Total = $11.60Leather jacket = $1337 × 1
Com-Tool = $99.10 × -14
--------------------------------
Total = $11.60(The exact total/quantity can vary depending on the products and values used.)
Why it works
The server fails to enforce the business rule:
quantity must be positivequantity must be positiveInstead, it accepts negative quantities and calculates them normally:
price × negative quantity = negative amountprice × negative quantity = negative amountThis negative amount offsets the jacket's price, allowing the attacker to purchase an expensive item with insufficient store credit.
Result: Leather jacket purchased → Lab Solved ✅
=============================================
LAB 3 : Inconsistent Security Controls (PortSwigger Web Security Academy) LEVEL: Apprentice (Logic Flaw)
VULNERABILITY KYA HAI? Application email verification me inconsistency rakhti hai. Registration ke waqt email verify hota hai, lekin jab user apna email change karta hai, toh app bina verify kiye maan leti hai ki user company employee hai. Bas isi flaw ka fayda uthana hai.
STEP-BY-STEP WRITEUP:
Step 1: Admin Panel Dhundho
- Burp Suite open karo. Target > Site map me jao.
- Lab domain par right-click karke Engagement tools > Discover content select karo.
- "Session is not running" par click karke content discovery start karo.
- Thodi der me /admin path mil jayega. (Ya direct URL me /admin daal ke try karo).
Step 2: Error Message Dekho
- /admin par browse karo. Access nahi milega, lekin error message batayega ki sirf "DontWannaCry" users ko access hai.
Step 3: Registration Karo
- Account registration page par jao. Wahan likha hoga ki DontWannaCry employees apna company email use karein.
- Ek arbitrary email se register karo: anything@your-email-id.web-security-academy.net (Apna email domain nikalne ke liye "Email client" button par click karo).
- Email client me jaakar confirmation link par click karke registration complete karo.
Step 4: Email Change Karo (Yahi Hai Asli Trick)
- Apne naye account se login karo aur "My account" page par jao.
- Wahan "Update email" ka option hoga. Apna email change karke anything@dontwannacry.com kar do.
- NOTE: Yahan app koi verification nahi maangegi. Bas save ho jayega.
Step 5: Admin Panel Access Karo aur Carlos Ko Delete Karo
- Ab aapko admin panel ka access mil jayega. Home page par ya direct /admin URL par jao.
- Wahan users ki list dikhegi. carlos ke aage "Delete" button par click kar do.
- "User deleted successfully!" message aayega aur lab SOLVED ho jayega.
==============================================================
=============================================
LAB 4 : Flawed enforcement of business rules (PortSwigger Web Security Academy) LEVEL: Apprentice (Logic Flaw / Business Logic)
VULNERABILITY KYA HAI? Application ka coupon validation logic flawed hai. Server sirf yeh check karta hai ki pichla applied coupon same tha ya nahi (consecutive check). Lekin wo yeh verify nahi karta ki coupon pehle bhi use ho chuka hai (absolute check). Isliye do alag-alag coupons ko alternate karke baar-baar apply kiya ja sakta hai, jisse unlimited discount milta hai aur order total $0 ho jata hai.
STEP-BY-STEP WRITEUP:
Step 1: Login karo wiener:peter se.
Step 2: Home page par coupon code NEWCUST5 dikhega, usko note karo.
Step 3: Page ke bottom par newsletter signup karo. Wahan se dusra coupon SIGNUP30 milega.
Step 4: "Lightweight l33t leather jacket" ko apne cart me add karo.
Step 5: Checkout page par coupons apply karo. Yeh sequence follow karo:
— Pehle NEWCUST5 lagao. (Accept hoga)
— Phir SIGNUP30 lagao. (Accept hoga)
— Ab wapas NEWCUST5 lagao. (Yeh bhi accept hoga kyunki pichla SIGNUP30 tha)
— Phir SIGNUP30 lagao. (Yeh bhi accept hoga)
Step 6: Isi tarah alternate karte raho (NEWCUST5 -> SIGNUP30 -> NEWCUST5 -> SIGNUP30…) jab tak order total tumhare store credit ($100) se kam ya $0 na ho jaye.
Step 7: Jab total $0 ho jaye, toh "Place Order" button dabao. Lab SOLVED! 🎉
SUMMARY:
"Same coupon ko lagatar dobara mat lagao. NEWCUST5 aur SIGNUP30 ko alternate karke lagao. App sirf pichle coupon se compare karti hai, isliye dono coupons baar-baar lag jayenge aur price $0 ho jayegi."
===============================================================
Lab 5 : Low-level Logic Flaw
- Concept:* Integer overflow caused by repeatedly adding a valid quantity. The application uses a 32-bit signed integer for the cart total, so when the value exceeds
2,147,483,647, it wraps around into the negative range.
Reproduce
-
Login with:
wiener:peter -
Add the Lightweight "l33t" Leather Jacket to the cart.
-
In Burp → Proxy → HTTP history, find the
POST /cartrequest and send it to Intruder. -
Set the jacket quantity to:
quantity=99
5. In Intruder:
- Payload type: **Null payloads**
- Generate exactly **323 payloads**
- Resource Pool → **Maximum concurrent requests = 1**
6. Start the attack. Each request adds 99 jackets:
323 × 99 = 31,977
7. After the attack, use Burp Repeater and send one more request:
quantity=47
8. Final jacket quantity:
31,977 + 47 + 99 = 32,123
- The extra `99` is the initial jacket-add request that was already in the cart.
- The jacket price is stored in cents:
- `$1337.00 = 133,700 cents`
Therefore:
133,700 × 32,123
= 4,294,845,100 cents
9. A signed 32-bit integer can store only up to:
2,147,483,647
The calculation overflows and wraps around:
4,294,845,100–4,294,967,296
= -122,196 cents
= -$1,221.96
10. Now add another product to bring the negative total back between `$0` and your `$100` store credit.
In this lab:
Real Life Photoshopping = $49.12
Quantity = 26
Calculation:
$49.12 × 26 = $1,277.12
- $1,221.96 + $1,277.12
= $55.16
11. Final cart:
Leather Jacket × 32,123
Real Life Photoshopping × 26
Final total = $55.16
Store credit = $100
12. Place the order.
### Result
The expensive leather jacket was purchased for an unintended effective price of **$55.16**, and the lab was solved.
### Root Cause
The application fails to safely handle integer overflow. Repeated valid inputs make the cumulative value exceed the maximum 32-bit signed integer, causing the value to wrap into a negative number and allowing the attacker to manipulate the final purchase price.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*H2P-cTnmRVk8jkGSvQbd-A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*H2P-cTnmRVk8jkGSvQbd-A.png 1x">
<img src="/img/medium/700/1*H2P-cTnmRVk8jkGSvQbd-A.png" alt="None" width="1470" height="1041" loading="lazy" data-zoom-src="/img/medium/4000/1*H2P-cTnmRVk8jkGSvQbd-A.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*4OZbtgG4_CmB2yKkrahENQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*4OZbtgG4_CmB2yKkrahENQ.png 1x">
<img src="/img/medium/700/1*4OZbtgG4_CmB2yKkrahENQ.png" alt="None" width="1742" height="840" loading="lazy" data-zoom-src="/img/medium/4000/1*4OZbtgG4_CmB2yKkrahENQ.png" class="prose-image"/>
</picture>
===============================================================
### # Lab 6: Inconsistent Handling of Exceptional Input
**Logic:** The application handles the email address differently in different parts of the system. The email client uses the full address, but the application truncates the stored email to **255 characters**. By placing `[@dontwannacry](http://twitter.com/dontwannacry).com` exactly at the end of those 255 characters, we can make the application treat our account as a DontWannaCry employee.
### Reproduce
1. Use Burp → **Target → Site map** and discover `/admin`.
2. Open `/admin`. Access is denied, but the message reveals that **DontWannaCry users** can access it.
3. Open the registration page and notice that employees are required to use a `[@dontwannacry](http://twitter.com/dontwannacry).com` email.
4. Open the lab's **Email client** and note your unique exploit-server domain:
```text
exploit-0a5800c60355d252816fd308010100f8.exploit-server.net
5.First, register with a very long normal email address:
- `[200+ characters]@exploit-0a5800c60355d252816fd308010100f8.exploit-server.net`
- Verify the account from the email client and check **My account**. The email is truncated to **255 characters**.
- Now exploit this truncation. Register using:
- `[238 a's]@dontwannacry.com.exploit-0a5800c60355d252816fd308010100f8.exploit-server.net`
- Here:
- `238 × "a" + @dontwannacry.com (17 characters) = 255 characters`
- Therefore the final `m` of `.com` is character **#255**.
- The full email still reaches the exploit-server email client because the part after dontwannacry.com is a valid subdomain of your exploit-server domain.
- Open the confirmation email and click the registration link.
- Log in to the newly created account and open **My account**. The stored email is truncated at 255 characters, so it now effectively ends with:
- `@dontwannacry.com`
- Open `/admin`. You now have administrator access.
- Click **Delete** next to `carlos`.
### Why it works
The same email is processed differently:
Full email:
[aaaa…aaaa@dontwannacry.com.exploit-server.net](mailto:aaaa...aaaa@dontwannacry.com.exploit-server.net)
↓
Email server → receives full address ✅
Application/database:
↓
Truncates to 255 characters
↓
[aaaa…aaaa@dontwannacry.com](mailto:aaaa...aaaa@dontwannacry.com)
↓
Application considers it a company email ✅
**Root cause:** Inconsistent input handling between the email-delivery system and the application's 255-character storage/authorization logic.
**Result:** Admin access obtained → `carlos` deleted → **LAB SOLVED ✅**
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*BIHfxmA0-vui-49BjxuXsA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*BIHfxmA0-vui-49BjxuXsA.png 1x">
<img src="/img/medium/700/1*BIHfxmA0-vui-49BjxuXsA.png" alt="None" width="1731" height="1048" loading="lazy" data-zoom-src="/img/medium/4000/1*BIHfxmA0-vui-49BjxuXsA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*L2_GpKQ11HS62cmliF61xA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*L2_GpKQ11HS62cmliF61xA.png 1x">
<img src="/img/medium/700/1*L2_GpKQ11HS62cmliF61xA.png" alt="None" width="1741" height="982" loading="lazy" data-zoom-src="/img/medium/4000/1*L2_GpKQ11HS62cmliF61xA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*LUTpPwCufrWRdY6l5Gzlkw.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*LUTpPwCufrWRdY6l5Gzlkw.png 1x">
<img src="/img/medium/700/1*LUTpPwCufrWRdY6l5Gzlkw.png" alt="None" width="1886" height="815" loading="lazy" data-zoom-src="/img/medium/4000/1*LUTpPwCufrWRdY6l5Gzlkw.png" class="prose-image"/>
</picture>
==============================================================================================================================
### =============================================
LAB 7 : Weak Isolation on Dual-Use Endpoint (PortSwigger Web Security Academy)
LEVEL: Practitioner (Logic Flaw / IDOR)
=============================================
VULNERABILITY KYA HAI?
Application ek hi endpoint (`/my-account/change-password`) ko multiple roles ke liye use kar rahi hai (isliye "dual-use").
Logic flaw do jagah hai:
1. Server mandatory parameter (`**current-password**`) ki presence ko verify nahi karta. Agar hum isse request se poori tarah delete kar dein, toh server bina current password verify kiye password change kar deta hai.
2. `username` parameter ko manipulate karke hum kisi bhi user (jaise `administrator`) ka password change kar sakte hain.
STEP-BY-STEP WRITEUP:
Step 1: Login karo `wiener:peter` se aur "My account" page par jao. Password change karo aur Burp Suite me request intercept karo (`POST /my-account/change-password`).
Step 2: Request ko Burp Repeater me bhejo. Notice karo ki parameters kuch is tarah hain:
`username=wiener¤t-password=…&new-password-1=…&new-password-2=…`
Step 3: Ab do changes karo:
- `current-password` parameter ko poori tarah delete kar do (sirf value nahi, poora `current-password=…` uda do).
- `username` parameter ki value `wiener` se change karke `administrator` kar do.
Step 4: Request send karo. Server successfully administrator ka password change kar dega (bina current password verify kiye).
Step 5: Logout karo aur `administrator` ke naye password se login karo.
Step 6: `/admin` panel par jao aur `carlos` ko delete kar do. Lab SOLVED!
===============================================================
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*NkAqlzbXRA5haPyrp9eWPg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*NkAqlzbXRA5haPyrp9eWPg.png 1x">
<img src="/img/medium/700/1*NkAqlzbXRA5haPyrp9eWPg.png" alt="None" width="1133" height="842" loading="lazy" data-zoom-src="/img/medium/4000/1*NkAqlzbXRA5haPyrp9eWPg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*Pu8OFZGIkMIIpSY2H0PH7w.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*Pu8OFZGIkMIIpSY2H0PH7w.png 1x">
<img src="/img/medium/700/1*Pu8OFZGIkMIIpSY2H0PH7w.png" alt="None" width="1793" height="1078" loading="lazy" data-zoom-src="/img/medium/4000/1*Pu8OFZGIkMIIpSY2H0PH7w.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*yIethVxcuL_woJr4t8Khrg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*yIethVxcuL_woJr4t8Khrg.png 1x">
<img src="/img/medium/700/1*yIethVxcuL_woJr4t8Khrg.png" alt="None" width="1752" height="1002" loading="lazy" data-zoom-src="/img/medium/4000/1*yIethVxcuL_woJr4t8Khrg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*Velz5xRvrTsfvhyUPv88NA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*Velz5xRvrTsfvhyUPv88NA.png 1x">
<img src="/img/medium/700/1*Velz5xRvrTsfvhyUPv88NA.png" alt="None" width="1683" height="947" loading="lazy" data-zoom-src="/img/medium/4000/1*Velz5xRvrTsfvhyUPv88NA.png" class="prose-image"/>
</picture>
===============================================================
### =============================================
LAB 8 : Insufficient Workflow Validation (PortSwigger Web Security Academy)
LEVEL: Practitioner (Logic Flaw / Forced Browsing)
=============================================
VULNERABILITY KYA HAI?
Application purchasing workflow ki sequence par andha bharosa karti hai.
Developer ne socha ki user hamesha:
1. Cart me item daalega -> 2. Checkout (POST) karega -> 3. Order Confirmation (GET) par jayega.
Lekin `/cart/order-confirmation` endpoint par server yeh check NAHI karta ki:
- User ne checkout step complete kiya tha ya nahi?
- User ke paas kitne paise hain?
Isliye hum Checkout step (jahan paisa katta hai) ko skip karke seedha Order Confirmation URL hit kar dete hain. Server maan leta hai ki order ho gaya, aur bina paise kaate item de deta hai.
STEP-BY-STEP WRITEUP:
Step 1: Setup & Login
- Burp Suite open karo aur Proxy ON rakho.
- Lab me `wiener:peter` se login karo.
Step 2: Normal Purchase Karo (Flaw Dhundhne Ke Liye)
- Store se koi bhi sasta item khareedo jo tumhare store credit me aa jaye.
- Checkout karo. Burp ke "Proxy > HTTP History" me jao.
- Wahan do requests dhundho:
1. `POST /cart/checkout` (Yeh paisa katta hai)
2. `GET /cart/order-confirmation?order-confirmation=true` (Yeh sirf confirmation page hai)
- Is GET request par right-click karke "Send to Repeater" karo.
Step 3: Expensive Item Cart Me Daalo
- Store par wapas jao aur "Lightweight l33t leather jacket" ko cart me add karo.
- CHECKOUT MAT KARO! Bas cart me add karke chhod do.
Step 4: Repeater Se Direct Order Confirm Karo
- Burp Suite ke Repeater tab me jao.
- Tumhari saved `GET /cart/order-confirmation?order-confirmation=true` request ready hogi.
- Bas "Send" button dabao.
Step 5: Result Dekho
- Order confirm ho jayega bina paise kaate.
- Jacket tumhare paas aa jayegi.
- Lab SOLVED! 🎉
EK LINE ME SUMMARY:
"Checkout ka POST request skip karo aur seedha Order Confirmation ka GET request bhej do. Server bina validation ke order confirm kar dega aur paisa nahi katega."
===============================================================
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*gB9wJwix5VFlvNe1sSS4ew.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*gB9wJwix5VFlvNe1sSS4ew.png 1x">
<img src="/img/medium/700/1*gB9wJwix5VFlvNe1sSS4ew.png" alt="None" width="1163" height="816" loading="lazy" data-zoom-src="/img/medium/4000/1*gB9wJwix5VFlvNe1sSS4ew.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*kx456ueGg-rGpCiuJy4rcQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*kx456ueGg-rGpCiuJy4rcQ.png 1x">
<img src="/img/medium/700/1*kx456ueGg-rGpCiuJy4rcQ.png" alt="None" width="1622" height="1043" loading="lazy" data-zoom-src="/img/medium/4000/1*kx456ueGg-rGpCiuJy4rcQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*wCvF7K7bm8YDPf0Qq3kTQw.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*wCvF7K7bm8YDPf0Qq3kTQw.png 1x">
<img src="/img/medium/700/1*wCvF7K7bm8YDPf0Qq3kTQw.png" alt="None" width="1086" height="816" loading="lazy" data-zoom-src="/img/medium/4000/1*wCvF7K7bm8YDPf0Qq3kTQw.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*PY6d9mSXj2u92ED-apHJoQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*PY6d9mSXj2u92ED-apHJoQ.png 1x">
<img src="/img/medium/700/1*PY6d9mSXj2u92ED-apHJoQ.png" alt="None" width="1722" height="1061" loading="lazy" data-zoom-src="/img/medium/4000/1*PY6d9mSXj2u92ED-apHJoQ.png" class="prose-image"/>
</picture>
===============================================================
### =============================================
LAB 9 : Authentication bypass via flawed state machine
LEVEL: Practitioner (Logic Flaw / State Machine Bypass)
=============================================
🧠 LOGIC (Vulnerability Explained)
The application uses a multi-step login process:
1. Login (POST /login) -> 2. Select Role (GET /role-selector) -> 3. Home Page.
The server assumes every user will stop at Step 2 and select a role (like "User").
However, the backend has a flaw: if a user skips role selection, the session variable remains uninitialized. The server then defaults to the highest privilege level (Administrator) instead of defaulting to a standard User.
By intercepting and dropping the role-selection request, we break the state machine and gain admin access.
🛠️ STEP-BY-STEP SOLUTION
Step 1: Normal Login
Log in with `wiener:peter`. Notice that after login, you are forced to a "Role Selector" page to choose your role.
Step 2: Admin Path Discovery
Try to browse directly to `/admin` from the role selector page. You will get an "Access Denied" error.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*Jc4PIOhh5_jaKOmU-ovxCQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*Jc4PIOhh5_jaKOmU-ovxCQ.png 1x">
<img src="/img/medium/700/1*Jc4PIOhh5_jaKOmU-ovxCQ.png" alt="None" width="1780" height="1028" loading="lazy" data-zoom-src="/img/medium/4000/1*Jc4PIOhh5_jaKOmU-ovxCQ.png" class="prose-image"/>
</picture>
Step 3: Setup the Attack
- Log out and go back to the login page.
- Turn ON Burp Suite Intercept (Proxy > Intercept > Intercept is on).
- Log in again with `wiener:peter`.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*-vGmJ9I7FRi5efQUa5kPfQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*-vGmJ9I7FRi5efQUa5kPfQ.png 1x">
<img src="/img/medium/700/1*-vGmJ9I7FRi5efQUa5kPfQ.png" alt="None" width="1162" height="873" loading="lazy" data-zoom-src="/img/medium/4000/1*-vGmJ9I7FRi5efQUa5kPfQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*6Nj6fTNsjo8YGY37p-2xWQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*6Nj6fTNsjo8YGY37p-2xWQ.png 1x">
<img src="/img/medium/700/1*6Nj6fTNsjo8YGY37p-2xWQ.png" alt="None" width="1396" height="878" loading="lazy" data-zoom-src="/img/medium/4000/1*6Nj6fTNsjo8YGY37p-2xWQ.png" class="prose-image"/>
</picture>
Step 4: The Exploit (Drop the Request)
- Burp will capture the first request: `POST /login`. Forward it.
- Burp will capture the next request: `GET /role-selector`. **DROP this request entirely.**
- Now, manually change the URL in your browser to `/admin` (or the lab's home page).
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*MGCOHAbIj0ckKXQybfGNPQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*MGCOHAbIj0ckKXQybfGNPQ.png 1x">
<img src="/img/medium/700/1*MGCOHAbIj0ckKXQybfGNPQ.png" alt="None" width="1851" height="1072" loading="lazy" data-zoom-src="/img/medium/4000/1*MGCOHAbIj0ckKXQybfGNPQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*ecvX1lI1nOJ1P70-o4wLGQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*ecvX1lI1nOJ1P70-o4wLGQ.png 1x">
<img src="/img/medium/700/1*ecvX1lI1nOJ1P70-o4wLGQ.png" alt="None" width="1282" height="867" loading="lazy" data-zoom-src="/img/medium/4000/1*ecvX1lI1nOJ1P70-o4wLGQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*UvLI73I774JmrQ-xtssI3w.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*UvLI73I774JmrQ-xtssI3w.png 1x">
<img src="/img/medium/700/1*UvLI73I774JmrQ-xtssI3w.png" alt="None" width="1832" height="1077" loading="lazy" data-zoom-src="/img/medium/4000/1*UvLI73I774JmrQ-xtssI3w.png" class="prose-image"/>
</picture>
Step 5: Delete Carlos
Because you skipped the role selector, the server defaults your role to Administrator. The `/admin` panel will open successfully. Click "Delete" next to `carlos` to solve the lab.
📝 SUMMARY
"Skip the role selection step during login by dropping the `GET /role-selector` request in Burp. The server will default your role to Administrator due to a flawed state machine, allowing you to access `/admin` and delete carlos."
===============================================================
### =============================================
LAB 10 : Infinite money logic flaw (PortSwigger Web Security Academy)
LEVEL: Practitioner (Logic Flaw / Business Logic)
=============================================
🧠 VULNERABILITY LOGIC
The application has a flawed purchasing workflow. It allows users to purchase a $10 gift card using the `SIGNUP30` coupon (30% discount).
The gift card costs $7 (after discount) but can be redeemed for its full value of $10.
This results in a net profit of $3 per transaction. By automating this process, an attacker can generate infinite store credit and purchase high-value items like the "Lightweight l33t leather jacket" ($1337).
### 🛠️ STEP-BY-STEP EXPLOITATION
### **Step 1: Manual Verification**
1. Log in with `wiener:peter` and sign up for the newsletter to get the `SIGNUP30` coupon.
2. Add a $10 gift card to your cart, apply the coupon, and checkout.
3. Copy the gift card code from the order confirmation page and redeem it in "My Account".
4. Notice that your store credit increases by $3. (Lab Reset recommended here to start with $100 clean credit).
### *Step 2: Burp Macro Configuration**
1. Capture the following 5 requests in Burp Proxy history:
— `POST /cart`
— `POST /cart/coupon`
— `POST /cart/checkout`
— `GET /cart/order-confirmation?order-confirmed=true`
— `POST /gift-card`
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*PvhxGYcelbDGxrSk4Y_xHg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*PvhxGYcelbDGxrSk4Y_xHg.png 1x">
<img src="/img/medium/700/1*PvhxGYcelbDGxrSk4Y_xHg.png" alt="None" width="1398" height="893" loading="lazy" data-zoom-src="/img/medium/4000/1*PvhxGYcelbDGxrSk4Y_xHg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*pd8QnbIi1MAW1-tx-YSoBw.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*pd8QnbIi1MAW1-tx-YSoBw.png 1x">
<img src="/img/medium/700/1*pd8QnbIi1MAW1-tx-YSoBw.png" alt="None" width="1397" height="898" loading="lazy" data-zoom-src="/img/medium/4000/1*pd8QnbIi1MAW1-tx-YSoBw.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*yw5bCsQ-efev4PtEIRSU9A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*yw5bCsQ-efev4PtEIRSU9A.png 1x">
<img src="/img/medium/700/1*yw5bCsQ-efev4PtEIRSU9A.png" alt="None" width="1435" height="898" loading="lazy" data-zoom-src="/img/medium/4000/1*yw5bCsQ-efev4PtEIRSU9A.png" class="prose-image"/>
</picture>
2. Go to **Settings > Sessions > Session handling rules > Add**. Set Scope to "Include all URLs".
3. Under Rule actions, select **Run a macro**. Add the 5 requests in the exact order above.
4. In the Macro Editor, configure `GET /cart/order-confirmation` to extract the `gift-card` custom parameter from the response.
5. Configure `POST /gift-card` to derive the `gift-card` parameter from the prior response.
6. Click **Test macro** to ensure it returns a 302 status code for the final request.
- *Step 3: Automation with Burp Intruder**
1. Send `GET /my-account` to Burp Intruder (Sniper attack).
2. In Payloads, select **Null payloads** and generate **412 payloads**.
*(Math: $1337 target — $100 initial credit = $1237 needed. $1237 / $3 profit = ~412 requests).*
3. In the **Resource Pool**, create a new pool with **Maximum concurrent requests = 1**.
*(Crucial: This prevents race conditions and ensures the gift card code matches correctly).*
4. Start the attack.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*87amRQoUphV-5XYvp4dFkQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*87amRQoUphV-5XYvp4dFkQ.png 1x">
<img src="/img/medium/700/1*87amRQoUphV-5XYvp4dFkQ.png" alt="None" width="1436" height="881" loading="lazy" data-zoom-src="/img/medium/4000/1*87amRQoUphV-5XYvp4dFkQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*UUZWkbqJqMNQrJYJv7T6Cg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*UUZWkbqJqMNQrJYJv7T6Cg.png 1x">
<img src="/img/medium/700/1*UUZWkbqJqMNQrJYJv7T6Cg.png" alt="None" width="1431" height="892" loading="lazy" data-zoom-src="/img/medium/4000/1*UUZWkbqJqMNQrJYJv7T6Cg.png" class="prose-image"/>
</picture>
- *Step 4: Purchase the Target Item**
1. Once the attack completes, your store credit will exceed $1337.
2. Add the "Lightweight l33t leather jacket" to your cart and place the order. Lab SOLVED!
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*obraDDcbybSdGEG2pf-BXA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*obraDDcbybSdGEG2pf-BXA.png 1x">
<img src="/img/medium/700/1*obraDDcbybSdGEG2pf-BXA.png" alt="None" width="1428" height="898" loading="lazy" data-zoom-src="/img/medium/4000/1*obraDDcbybSdGEG2pf-BXA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*qeEwQ4U6d68S64EfIzKbFg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*qeEwQ4U6d68S64EfIzKbFg.png 1x">
<img src="/img/medium/700/1*qeEwQ4U6d68S64EfIzKbFg.png" alt="None" width="1895" height="1067" loading="lazy" data-zoom-src="/img/medium/4000/1*qeEwQ4U6d68S64EfIzKbFg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*5IY-mIKZONPBc_VJAFVk_w.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*5IY-mIKZONPBc_VJAFVk_w.png 1x">
<img src="/img/medium/700/1*5IY-mIKZONPBc_VJAFVk_w.png" alt="None" width="1402" height="872" loading="lazy" data-zoom-src="/img/medium/4000/1*5IY-mIKZONPBc_VJAFVk_w.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*vcJADfh2zc4QgvG7Wj2Bmg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*vcJADfh2zc4QgvG7Wj2Bmg.png 1x">
<img src="/img/medium/700/1*vcJADfh2zc4QgvG7Wj2Bmg.png" alt="None" width="1783" height="1062" loading="lazy" data-zoom-src="/img/medium/4000/1*vcJADfh2zc4QgvG7Wj2Bmg.png" class="prose-image"/>
</picture>
📝 SUMMARY
"Exploit the price discrepancy between discounted gift card purchases and their full redemption value. Automate the workflow using Burp Macros and Intruder to generate infinite store credit."
===============================================================
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*BV2jGa5KSmdqDGAmomOOdA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*BV2jGa5KSmdqDGAmomOOdA.png 1x">
<img src="/img/medium/700/1*BV2jGa5KSmdqDGAmomOOdA.png" alt="None" width="1798" height="1062" loading="lazy" data-zoom-src="/img/medium/4000/1*BV2jGa5KSmdqDGAmomOOdA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*QT4UXA4vG8QHKyWX9E-KNA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*QT4UXA4vG8QHKyWX9E-KNA.png 1x">
<img src="/img/medium/700/1*QT4UXA4vG8QHKyWX9E-KNA.png" alt="None" width="1843" height="1075" loading="lazy" data-zoom-src="/img/medium/4000/1*QT4UXA4vG8QHKyWX9E-KNA.png" class="prose-image"/>
</picture>quantity=99
5. In Intruder:
- Payload type: **Null payloads**
- Generate exactly **323 payloads**
- Resource Pool → **Maximum concurrent requests = 1**
6. Start the attack. Each request adds 99 jackets:
323 × 99 = 31,977
7. After the attack, use Burp Repeater and send one more request:
quantity=47
8. Final jacket quantity:
31,977 + 47 + 99 = 32,123
- The extra `99` is the initial jacket-add request that was already in the cart.
- The jacket price is stored in cents:
- `$1337.00 = 133,700 cents`
Therefore:
133,700 × 32,123
= 4,294,845,100 cents
9. A signed 32-bit integer can store only up to:
2,147,483,647
The calculation overflows and wraps around:
4,294,845,100–4,294,967,296
= -122,196 cents
= -$1,221.96
10. Now add another product to bring the negative total back between `$0` and your `$100` store credit.
In this lab:
Real Life Photoshopping = $49.12
Quantity = 26
Calculation:
$49.12 × 26 = $1,277.12
- $1,221.96 + $1,277.12
= $55.16
11. Final cart:
Leather Jacket × 32,123
Real Life Photoshopping × 26
Final total = $55.16
Store credit = $100
12. Place the order.
### Result
The expensive leather jacket was purchased for an unintended effective price of **$55.16**, and the lab was solved.
### Root Cause
The application fails to safely handle integer overflow. Repeated valid inputs make the cumulative value exceed the maximum 32-bit signed integer, causing the value to wrap into a negative number and allowing the attacker to manipulate the final purchase price.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*H2P-cTnmRVk8jkGSvQbd-A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*H2P-cTnmRVk8jkGSvQbd-A.png 1x">
<img src="/img/medium/700/1*H2P-cTnmRVk8jkGSvQbd-A.png" alt="None" width="1470" height="1041" loading="lazy" data-zoom-src="/img/medium/4000/1*H2P-cTnmRVk8jkGSvQbd-A.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*4OZbtgG4_CmB2yKkrahENQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*4OZbtgG4_CmB2yKkrahENQ.png 1x">
<img src="/img/medium/700/1*4OZbtgG4_CmB2yKkrahENQ.png" alt="None" width="1742" height="840" loading="lazy" data-zoom-src="/img/medium/4000/1*4OZbtgG4_CmB2yKkrahENQ.png" class="prose-image"/>
</picture>
===============================================================
### # Lab 6: Inconsistent Handling of Exceptional Input
**Logic:** The application handles the email address differently in different parts of the system. The email client uses the full address, but the application truncates the stored email to **255 characters**. By placing `[@dontwannacry](http://twitter.com/dontwannacry).com` exactly at the end of those 255 characters, we can make the application treat our account as a DontWannaCry employee.
### Reproduce
1. Use Burp → **Target → Site map** and discover `/admin`.
2. Open `/admin`. Access is denied, but the message reveals that **DontWannaCry users** can access it.
3. Open the registration page and notice that employees are required to use a `[@dontwannacry](http://twitter.com/dontwannacry).com` email.
4. Open the lab's **Email client** and note your unique exploit-server domain:
```text
exploit-0a5800c60355d252816fd308010100f8.exploit-server.net
5.First, register with a very long normal email address:
- `[200+ characters]@exploit-0a5800c60355d252816fd308010100f8.exploit-server.net`
- Verify the account from the email client and check **My account**. The email is truncated to **255 characters**.
- Now exploit this truncation. Register using:
- `[238 a's]@dontwannacry.com.exploit-0a5800c60355d252816fd308010100f8.exploit-server.net`
- Here:
- `238 × "a" + @dontwannacry.com (17 characters) = 255 characters`
- Therefore the final `m` of `.com` is character **#255**.
- The full email still reaches the exploit-server email client because the part after dontwannacry.com is a valid subdomain of your exploit-server domain.
- Open the confirmation email and click the registration link.
- Log in to the newly created account and open **My account**. The stored email is truncated at 255 characters, so it now effectively ends with:
- `@dontwannacry.com`
- Open `/admin`. You now have administrator access.
- Click **Delete** next to `carlos`.
### Why it works
The same email is processed differently:
Full email:
[aaaa…aaaa@dontwannacry.com.exploit-server.net](mailto:aaaa...aaaa@dontwannacry.com.exploit-server.net)
↓
Email server → receives full address ✅
Application/database:
↓
Truncates to 255 characters
↓
[aaaa…aaaa@dontwannacry.com](mailto:aaaa...aaaa@dontwannacry.com)
↓
Application considers it a company email ✅
**Root cause:** Inconsistent input handling between the email-delivery system and the application's 255-character storage/authorization logic.
**Result:** Admin access obtained → `carlos` deleted → **LAB SOLVED ✅**
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*BIHfxmA0-vui-49BjxuXsA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*BIHfxmA0-vui-49BjxuXsA.png 1x">
<img src="/img/medium/700/1*BIHfxmA0-vui-49BjxuXsA.png" alt="None" width="1731" height="1048" loading="lazy" data-zoom-src="/img/medium/4000/1*BIHfxmA0-vui-49BjxuXsA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*L2_GpKQ11HS62cmliF61xA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*L2_GpKQ11HS62cmliF61xA.png 1x">
<img src="/img/medium/700/1*L2_GpKQ11HS62cmliF61xA.png" alt="None" width="1741" height="982" loading="lazy" data-zoom-src="/img/medium/4000/1*L2_GpKQ11HS62cmliF61xA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*LUTpPwCufrWRdY6l5Gzlkw.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*LUTpPwCufrWRdY6l5Gzlkw.png 1x">
<img src="/img/medium/700/1*LUTpPwCufrWRdY6l5Gzlkw.png" alt="None" width="1886" height="815" loading="lazy" data-zoom-src="/img/medium/4000/1*LUTpPwCufrWRdY6l5Gzlkw.png" class="prose-image"/>
</picture>
==============================================================================================================================
### =============================================
LAB 7 : Weak Isolation on Dual-Use Endpoint (PortSwigger Web Security Academy)
LEVEL: Practitioner (Logic Flaw / IDOR)
=============================================
VULNERABILITY KYA HAI?
Application ek hi endpoint (`/my-account/change-password`) ko multiple roles ke liye use kar rahi hai (isliye "dual-use").
Logic flaw do jagah hai:
1. Server mandatory parameter (`**current-password**`) ki presence ko verify nahi karta. Agar hum isse request se poori tarah delete kar dein, toh server bina current password verify kiye password change kar deta hai.
2. `username` parameter ko manipulate karke hum kisi bhi user (jaise `administrator`) ka password change kar sakte hain.
STEP-BY-STEP WRITEUP:
Step 1: Login karo `wiener:peter` se aur "My account" page par jao. Password change karo aur Burp Suite me request intercept karo (`POST /my-account/change-password`).
Step 2: Request ko Burp Repeater me bhejo. Notice karo ki parameters kuch is tarah hain:
`username=wiener¤t-password=…&new-password-1=…&new-password-2=…`
Step 3: Ab do changes karo:
- `current-password` parameter ko poori tarah delete kar do (sirf value nahi, poora `current-password=…` uda do).
- `username` parameter ki value `wiener` se change karke `administrator` kar do.
Step 4: Request send karo. Server successfully administrator ka password change kar dega (bina current password verify kiye).
Step 5: Logout karo aur `administrator` ke naye password se login karo.
Step 6: `/admin` panel par jao aur `carlos` ko delete kar do. Lab SOLVED!
===============================================================
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*NkAqlzbXRA5haPyrp9eWPg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*NkAqlzbXRA5haPyrp9eWPg.png 1x">
<img src="/img/medium/700/1*NkAqlzbXRA5haPyrp9eWPg.png" alt="None" width="1133" height="842" loading="lazy" data-zoom-src="/img/medium/4000/1*NkAqlzbXRA5haPyrp9eWPg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*Pu8OFZGIkMIIpSY2H0PH7w.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*Pu8OFZGIkMIIpSY2H0PH7w.png 1x">
<img src="/img/medium/700/1*Pu8OFZGIkMIIpSY2H0PH7w.png" alt="None" width="1793" height="1078" loading="lazy" data-zoom-src="/img/medium/4000/1*Pu8OFZGIkMIIpSY2H0PH7w.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*yIethVxcuL_woJr4t8Khrg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*yIethVxcuL_woJr4t8Khrg.png 1x">
<img src="/img/medium/700/1*yIethVxcuL_woJr4t8Khrg.png" alt="None" width="1752" height="1002" loading="lazy" data-zoom-src="/img/medium/4000/1*yIethVxcuL_woJr4t8Khrg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*Velz5xRvrTsfvhyUPv88NA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*Velz5xRvrTsfvhyUPv88NA.png 1x">
<img src="/img/medium/700/1*Velz5xRvrTsfvhyUPv88NA.png" alt="None" width="1683" height="947" loading="lazy" data-zoom-src="/img/medium/4000/1*Velz5xRvrTsfvhyUPv88NA.png" class="prose-image"/>
</picture>
===============================================================
### =============================================
LAB 8 : Insufficient Workflow Validation (PortSwigger Web Security Academy)
LEVEL: Practitioner (Logic Flaw / Forced Browsing)
=============================================
VULNERABILITY KYA HAI?
Application purchasing workflow ki sequence par andha bharosa karti hai.
Developer ne socha ki user hamesha:
1. Cart me item daalega -> 2. Checkout (POST) karega -> 3. Order Confirmation (GET) par jayega.
Lekin `/cart/order-confirmation` endpoint par server yeh check NAHI karta ki:
- User ne checkout step complete kiya tha ya nahi?
- User ke paas kitne paise hain?
Isliye hum Checkout step (jahan paisa katta hai) ko skip karke seedha Order Confirmation URL hit kar dete hain. Server maan leta hai ki order ho gaya, aur bina paise kaate item de deta hai.
STEP-BY-STEP WRITEUP:
Step 1: Setup & Login
- Burp Suite open karo aur Proxy ON rakho.
- Lab me `wiener:peter` se login karo.
Step 2: Normal Purchase Karo (Flaw Dhundhne Ke Liye)
- Store se koi bhi sasta item khareedo jo tumhare store credit me aa jaye.
- Checkout karo. Burp ke "Proxy > HTTP History" me jao.
- Wahan do requests dhundho:
1. `POST /cart/checkout` (Yeh paisa katta hai)
2. `GET /cart/order-confirmation?order-confirmation=true` (Yeh sirf confirmation page hai)
- Is GET request par right-click karke "Send to Repeater" karo.
Step 3: Expensive Item Cart Me Daalo
- Store par wapas jao aur "Lightweight l33t leather jacket" ko cart me add karo.
- CHECKOUT MAT KARO! Bas cart me add karke chhod do.
Step 4: Repeater Se Direct Order Confirm Karo
- Burp Suite ke Repeater tab me jao.
- Tumhari saved `GET /cart/order-confirmation?order-confirmation=true` request ready hogi.
- Bas "Send" button dabao.
Step 5: Result Dekho
- Order confirm ho jayega bina paise kaate.
- Jacket tumhare paas aa jayegi.
- Lab SOLVED! 🎉
EK LINE ME SUMMARY:
"Checkout ka POST request skip karo aur seedha Order Confirmation ka GET request bhej do. Server bina validation ke order confirm kar dega aur paisa nahi katega."
===============================================================
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*gB9wJwix5VFlvNe1sSS4ew.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*gB9wJwix5VFlvNe1sSS4ew.png 1x">
<img src="/img/medium/700/1*gB9wJwix5VFlvNe1sSS4ew.png" alt="None" width="1163" height="816" loading="lazy" data-zoom-src="/img/medium/4000/1*gB9wJwix5VFlvNe1sSS4ew.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*kx456ueGg-rGpCiuJy4rcQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*kx456ueGg-rGpCiuJy4rcQ.png 1x">
<img src="/img/medium/700/1*kx456ueGg-rGpCiuJy4rcQ.png" alt="None" width="1622" height="1043" loading="lazy" data-zoom-src="/img/medium/4000/1*kx456ueGg-rGpCiuJy4rcQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*wCvF7K7bm8YDPf0Qq3kTQw.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*wCvF7K7bm8YDPf0Qq3kTQw.png 1x">
<img src="/img/medium/700/1*wCvF7K7bm8YDPf0Qq3kTQw.png" alt="None" width="1086" height="816" loading="lazy" data-zoom-src="/img/medium/4000/1*wCvF7K7bm8YDPf0Qq3kTQw.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*PY6d9mSXj2u92ED-apHJoQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*PY6d9mSXj2u92ED-apHJoQ.png 1x">
<img src="/img/medium/700/1*PY6d9mSXj2u92ED-apHJoQ.png" alt="None" width="1722" height="1061" loading="lazy" data-zoom-src="/img/medium/4000/1*PY6d9mSXj2u92ED-apHJoQ.png" class="prose-image"/>
</picture>
===============================================================
### =============================================
LAB 9 : Authentication bypass via flawed state machine
LEVEL: Practitioner (Logic Flaw / State Machine Bypass)
=============================================
🧠 LOGIC (Vulnerability Explained)
The application uses a multi-step login process:
1. Login (POST /login) -> 2. Select Role (GET /role-selector) -> 3. Home Page.
The server assumes every user will stop at Step 2 and select a role (like "User").
However, the backend has a flaw: if a user skips role selection, the session variable remains uninitialized. The server then defaults to the highest privilege level (Administrator) instead of defaulting to a standard User.
By intercepting and dropping the role-selection request, we break the state machine and gain admin access.
🛠️ STEP-BY-STEP SOLUTION
Step 1: Normal Login
Log in with `wiener:peter`. Notice that after login, you are forced to a "Role Selector" page to choose your role.
Step 2: Admin Path Discovery
Try to browse directly to `/admin` from the role selector page. You will get an "Access Denied" error.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*Jc4PIOhh5_jaKOmU-ovxCQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*Jc4PIOhh5_jaKOmU-ovxCQ.png 1x">
<img src="/img/medium/700/1*Jc4PIOhh5_jaKOmU-ovxCQ.png" alt="None" width="1780" height="1028" loading="lazy" data-zoom-src="/img/medium/4000/1*Jc4PIOhh5_jaKOmU-ovxCQ.png" class="prose-image"/>
</picture>
Step 3: Setup the Attack
- Log out and go back to the login page.
- Turn ON Burp Suite Intercept (Proxy > Intercept > Intercept is on).
- Log in again with `wiener:peter`.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*-vGmJ9I7FRi5efQUa5kPfQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*-vGmJ9I7FRi5efQUa5kPfQ.png 1x">
<img src="/img/medium/700/1*-vGmJ9I7FRi5efQUa5kPfQ.png" alt="None" width="1162" height="873" loading="lazy" data-zoom-src="/img/medium/4000/1*-vGmJ9I7FRi5efQUa5kPfQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*6Nj6fTNsjo8YGY37p-2xWQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*6Nj6fTNsjo8YGY37p-2xWQ.png 1x">
<img src="/img/medium/700/1*6Nj6fTNsjo8YGY37p-2xWQ.png" alt="None" width="1396" height="878" loading="lazy" data-zoom-src="/img/medium/4000/1*6Nj6fTNsjo8YGY37p-2xWQ.png" class="prose-image"/>
</picture>
Step 4: The Exploit (Drop the Request)
- Burp will capture the first request: `POST /login`. Forward it.
- Burp will capture the next request: `GET /role-selector`. **DROP this request entirely.**
- Now, manually change the URL in your browser to `/admin` (or the lab's home page).
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*MGCOHAbIj0ckKXQybfGNPQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*MGCOHAbIj0ckKXQybfGNPQ.png 1x">
<img src="/img/medium/700/1*MGCOHAbIj0ckKXQybfGNPQ.png" alt="None" width="1851" height="1072" loading="lazy" data-zoom-src="/img/medium/4000/1*MGCOHAbIj0ckKXQybfGNPQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*ecvX1lI1nOJ1P70-o4wLGQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*ecvX1lI1nOJ1P70-o4wLGQ.png 1x">
<img src="/img/medium/700/1*ecvX1lI1nOJ1P70-o4wLGQ.png" alt="None" width="1282" height="867" loading="lazy" data-zoom-src="/img/medium/4000/1*ecvX1lI1nOJ1P70-o4wLGQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*UvLI73I774JmrQ-xtssI3w.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*UvLI73I774JmrQ-xtssI3w.png 1x">
<img src="/img/medium/700/1*UvLI73I774JmrQ-xtssI3w.png" alt="None" width="1832" height="1077" loading="lazy" data-zoom-src="/img/medium/4000/1*UvLI73I774JmrQ-xtssI3w.png" class="prose-image"/>
</picture>
Step 5: Delete Carlos
Because you skipped the role selector, the server defaults your role to Administrator. The `/admin` panel will open successfully. Click "Delete" next to `carlos` to solve the lab.
📝 SUMMARY
"Skip the role selection step during login by dropping the `GET /role-selector` request in Burp. The server will default your role to Administrator due to a flawed state machine, allowing you to access `/admin` and delete carlos."
===============================================================
### =============================================
LAB 10 : Infinite money logic flaw (PortSwigger Web Security Academy)
LEVEL: Practitioner (Logic Flaw / Business Logic)
=============================================
🧠 VULNERABILITY LOGIC
The application has a flawed purchasing workflow. It allows users to purchase a $10 gift card using the `SIGNUP30` coupon (30% discount).
The gift card costs $7 (after discount) but can be redeemed for its full value of $10.
This results in a net profit of $3 per transaction. By automating this process, an attacker can generate infinite store credit and purchase high-value items like the "Lightweight l33t leather jacket" ($1337).
### 🛠️ STEP-BY-STEP EXPLOITATION
### **Step 1: Manual Verification**
1. Log in with `wiener:peter` and sign up for the newsletter to get the `SIGNUP30` coupon.
2. Add a $10 gift card to your cart, apply the coupon, and checkout.
3. Copy the gift card code from the order confirmation page and redeem it in "My Account".
4. Notice that your store credit increases by $3. (Lab Reset recommended here to start with $100 clean credit).
### *Step 2: Burp Macro Configuration**
1. Capture the following 5 requests in Burp Proxy history:
— `POST /cart`
— `POST /cart/coupon`
— `POST /cart/checkout`
— `GET /cart/order-confirmation?order-confirmed=true`
— `POST /gift-card`
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*PvhxGYcelbDGxrSk4Y_xHg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*PvhxGYcelbDGxrSk4Y_xHg.png 1x">
<img src="/img/medium/700/1*PvhxGYcelbDGxrSk4Y_xHg.png" alt="None" width="1398" height="893" loading="lazy" data-zoom-src="/img/medium/4000/1*PvhxGYcelbDGxrSk4Y_xHg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*pd8QnbIi1MAW1-tx-YSoBw.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*pd8QnbIi1MAW1-tx-YSoBw.png 1x">
<img src="/img/medium/700/1*pd8QnbIi1MAW1-tx-YSoBw.png" alt="None" width="1397" height="898" loading="lazy" data-zoom-src="/img/medium/4000/1*pd8QnbIi1MAW1-tx-YSoBw.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*yw5bCsQ-efev4PtEIRSU9A.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*yw5bCsQ-efev4PtEIRSU9A.png 1x">
<img src="/img/medium/700/1*yw5bCsQ-efev4PtEIRSU9A.png" alt="None" width="1435" height="898" loading="lazy" data-zoom-src="/img/medium/4000/1*yw5bCsQ-efev4PtEIRSU9A.png" class="prose-image"/>
</picture>
2. Go to **Settings > Sessions > Session handling rules > Add**. Set Scope to "Include all URLs".
3. Under Rule actions, select **Run a macro**. Add the 5 requests in the exact order above.
4. In the Macro Editor, configure `GET /cart/order-confirmation` to extract the `gift-card` custom parameter from the response.
5. Configure `POST /gift-card` to derive the `gift-card` parameter from the prior response.
6. Click **Test macro** to ensure it returns a 302 status code for the final request.
- *Step 3: Automation with Burp Intruder**
1. Send `GET /my-account` to Burp Intruder (Sniper attack).
2. In Payloads, select **Null payloads** and generate **412 payloads**.
*(Math: $1337 target — $100 initial credit = $1237 needed. $1237 / $3 profit = ~412 requests).*
3. In the **Resource Pool**, create a new pool with **Maximum concurrent requests = 1**.
*(Crucial: This prevents race conditions and ensures the gift card code matches correctly).*
4. Start the attack.
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*87amRQoUphV-5XYvp4dFkQ.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*87amRQoUphV-5XYvp4dFkQ.png 1x">
<img src="/img/medium/700/1*87amRQoUphV-5XYvp4dFkQ.png" alt="None" width="1436" height="881" loading="lazy" data-zoom-src="/img/medium/4000/1*87amRQoUphV-5XYvp4dFkQ.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*UUZWkbqJqMNQrJYJv7T6Cg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*UUZWkbqJqMNQrJYJv7T6Cg.png 1x">
<img src="/img/medium/700/1*UUZWkbqJqMNQrJYJv7T6Cg.png" alt="None" width="1431" height="892" loading="lazy" data-zoom-src="/img/medium/4000/1*UUZWkbqJqMNQrJYJv7T6Cg.png" class="prose-image"/>
</picture>
- *Step 4: Purchase the Target Item**
1. Once the attack completes, your store credit will exceed $1337.
2. Add the "Lightweight l33t leather jacket" to your cart and place the order. Lab SOLVED!
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*obraDDcbybSdGEG2pf-BXA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*obraDDcbybSdGEG2pf-BXA.png 1x">
<img src="/img/medium/700/1*obraDDcbybSdGEG2pf-BXA.png" alt="None" width="1428" height="898" loading="lazy" data-zoom-src="/img/medium/4000/1*obraDDcbybSdGEG2pf-BXA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*qeEwQ4U6d68S64EfIzKbFg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*qeEwQ4U6d68S64EfIzKbFg.png 1x">
<img src="/img/medium/700/1*qeEwQ4U6d68S64EfIzKbFg.png" alt="None" width="1895" height="1067" loading="lazy" data-zoom-src="/img/medium/4000/1*qeEwQ4U6d68S64EfIzKbFg.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*5IY-mIKZONPBc_VJAFVk_w.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*5IY-mIKZONPBc_VJAFVk_w.png 1x">
<img src="/img/medium/700/1*5IY-mIKZONPBc_VJAFVk_w.png" alt="None" width="1402" height="872" loading="lazy" data-zoom-src="/img/medium/4000/1*5IY-mIKZONPBc_VJAFVk_w.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*vcJADfh2zc4QgvG7Wj2Bmg.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*vcJADfh2zc4QgvG7Wj2Bmg.png 1x">
<img src="/img/medium/700/1*vcJADfh2zc4QgvG7Wj2Bmg.png" alt="None" width="1783" height="1062" loading="lazy" data-zoom-src="/img/medium/4000/1*vcJADfh2zc4QgvG7Wj2Bmg.png" class="prose-image"/>
</picture>
📝 SUMMARY
"Exploit the price discrepancy between discounted gift card purchases and their full redemption value. Automate the workflow using Burp Macros and Intruder to generate infinite store credit."
===============================================================
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*BV2jGa5KSmdqDGAmomOOdA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*BV2jGa5KSmdqDGAmomOOdA.png 1x">
<img src="/img/medium/700/1*BV2jGa5KSmdqDGAmomOOdA.png" alt="None" width="1798" height="1062" loading="lazy" data-zoom-src="/img/medium/4000/1*BV2jGa5KSmdqDGAmomOOdA.png" class="prose-image"/>
</picture>
<picture>
<source media="(max-width: 768px)" srcset="/img/medium/700/1*QT4UXA4vG8QHKyWX9E-KNA.png 1x">
<source media="(min-width: 769px)" srcset="/img/medium/2000/1*QT4UXA4vG8QHKyWX9E-KNA.png 1x">
<img src="/img/medium/700/1*QT4UXA4vG8QHKyWX9E-KNA.png" alt="None" width="1843" height="1075" loading="lazy" data-zoom-src="/img/medium/4000/1*QT4UXA4vG8QHKyWX9E-KNA.png" class="prose-image"/>
</picture>