Skip to content
All modules
CoreModule 11 of 27120 minutes

Injection: SQL and everything after it

One bug class, five parsers. Break out of a SQL string, a shell argument, an XML document, a NoSQL query and an LDAP filter, and read the response for confirmation.

Assumes10. Web recon and attack surface

By the end you can

  • Confirm an injection point with a detection payload before attempting exploitation
  • Move from a broken quote to a UNION select, and from a blind boolean to an extracted string
  • Recognise NoSQL, LDAP, XPath and CRLF injection from the sink rather than from the payload
  • Turn an XXE into a file read, and know which parsers stopped allowing that
  • Chain a command injection into an out-of-band confirmation when nothing is echoed back
  • Explain why every one of these is the same bug: data crossing into a parser as code

1. Read

2. Use the tools

In the order they come up while solving. Read what each one does, or go straight to the workspace tab that runs it.

3. Try one now

Generated in your browser and checked in your browser. No account, nothing to download, and a fresh one whenever you want another.

4. Practise on the real thing

Real picoCTF challenges that use these techniques, easiest first. 23 match in total - see the full index.

Common mistakes

The wrong turns this topic reliably produces. Written as the mistake rather than the rule, because the rule is easy to agree with and easy to walk straight past.

  • Pasting a long exploit payload first. A single quote and a timing payload tell you whether there is a bug at all, and the response to them tells you which parser you are in.
  • Concluding 'not vulnerable' from an unchanged page. Blind and second-order injections change nothing visible; time and out-of-band channels are the detector.
  • Escaping quotes and calling it fixed. Numeric contexts, identifiers, ORDER BY clauses and LIKE patterns all inject without a quote.
  • Treating the error message as the whole oracle. Once an application swallows errors the extraction still runs over a boolean, a delay or a DNS lookup, and a student who has only seen the verbose case stops at the first generic 500.
  • Sending a payload the transport mangles. A + in a form body is a space, a # truncates the query string, and a comment sequence that worked in a database console fails over HTTP for reasons that have nothing to do with the injection.

Checkpoint

Extract one row from a database through a blind boolean injection and state, per character, which comparison confirmed it - then do the same extraction through a time-based channel.

Teaching note

Teach the sink, not the payload list. A student who can name the parser on the other side derives the escape sequence; a student with a payload list is stuck the first time the challenge uses MSSQL instead of MySQL.

Go deeper

The lessons above are written to get you through a challenge. These go after the subject instead. Each one opens our notes on that chapter - what it argues, what to take from it and where it stops - so this is somewhere to read now rather than a book to buy first. Nothing here is affiliate-linked or sold by us.

Every book the curriculum cites has a page in the library.