Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

A Novel Technique for SQL Injection in PDO’s Prepared Statements- 1710

Adam Kues - SearchlightPosted 8 Days Ago
  • PHP contains a library for prepared statements with PDO and contains prepared statements. In most languages, this is sufficient for preventing SQL injection. However, PDO in PHP isn't a true prepared statement. PDO attempts to do the escaping itself instead of binding the information, like many other languages do, which requires their own custom SQL parser.
  • There's a great quote that sums up the whole challenge: "if we can trick the PDO parser into parsing our input as a bound parameter where it shouldn’t, we can get an SQLi in a situation that would otherwise be impossible." They created this as a CTF challenge that contains a potential injection point within a column name; this is because column names cannot be bound. So, the parameter should be escaped adequately with backticks, but this isn't enough!
  • The parser contains a nice specification for how it parses the data. The type ANYNOEOF is defined as [\001-\377]. When adding a null byte and a question mark - ?\0 - it will see this as a SPECIAL and note a literal now. Naturally, this error occurs because it's trying to bind two things in the query. However, adding a comment - code>?#\0 - can easily remediate this problem. So, are we done? Nope! Still some more trickery for this to work.
  • Now, the first parameterized item in the query is used with OUR question mark and has to have a value. The substitution turns this into 'x'#\0, where the x is a controllable parameter and the parameterization adds the single quotes around the query because it thinks it's a string. There's another issue now: a null byte cannot be in a comment. The problem can be solved by adding a semicolon between the comment and nullbyte to make it a new line. With the stolen parameter x`;# and the same column name, this problem is solved.
  • The column 'x does not exist, though. What now? PDO still thinks that our injection point is in a string! Placing a \ as the first character in the string causes some MAJOR havoc. It will escape the single quote to allow for a context escape. The column name \?#\0 and the stolen parameter with x` FROM... allows us to create a legitimate query to perform SQL injection. Neat!
  • Older versions of PHP are much more susceptible to these types of attacks. This is because the lack of usage of backticks allowed for any injection of a question mark or semicolon, leading to SQL injection. There are numerous other ways to exploit this by creating a desync between the parameterization data. Overall, a pretty slick blog post on a fun SQL injection technique.