1 of 9

Week 2

2 of 9

Last week’s challenge

  • Simple SQL injection!
  • Need to authenticate
  • Username must be admin:

if request.form["username"] == “admin”:

return render_template("flag.html", flag=get_flag())

else:

return "Well, you logged in, but you aren't an admin."

  • SQL query must therefore be injected via password
  • The system checks that at least one record in the database matches
  • How can this check be bypassed?

3 of 9

Last week’s challenge

SELECT * FROM users WHERE username='admin' AND password='%s'

  • A couple methods:
    • Utilize the closing quotation mark in the exploit to generate an always-true clause:

SELECT * FROM users WHERE username='%s' AND password='' OR '1'='1'

    • Ignore the closing quotation mark by terminating the line:

SELECT * FROM users WHERE username='%s' AND password='' OR 1--'

4 of 9

This Week

  • What if we want to leak information from the database, but said information is never printed?
  • What if all we can observe is a boolean condition: success or failure?
  • Think of last week’s challenge, but instead, the flag is the admin password.

5 of 9

“The substr(X,Y,Z) function returns a substring of input string X that begins with the Y-th character and which is Z characters long . . . The left-most character of X is number 1.”

For example:

SELECT * FROM posts WHERE substr(title, 4, 3) = ‘bar’

Would match a post entitled “Foobar”

6 of 9

Blind SQL injection

  • In so-called “blind” SQL injection, a single bit of data can be leaked through each request: typically in the form of either a success or a failure.
  • Therefore, we’re not going to leak the flag in one shot. Instead, multiple request will need to be used.
  • In the most trivial case, we can iterate over the flag and use substr to check each character against a “guess” character.
  • But this method would be very slow: assuming 26 + 26 + 10 + 2 possible characters and a flag length of 20, this would require 64 * 20 = 1280 requests.
  • Over the internet, 1280 requests is a lot. While certainly doable, it would take a while (~20 minutes).

7 of 9

Blind SQL injection

  • Can we do better?
  • From an information-theoretic perspective, we should be able to leak a bit in each request, and there are only 160 bits . . .

  • (Hint: Yes. I’ll leave you to figure out exactly how, but here’s one more thing you might need:)

8 of 9

“The unicode(X) function returns the numeric unicode code point corresponding to the first character of the string X.”

For example:

SELECT * FROM posts WHERE unicode(title) < 66

Would match a post entitled “A story” because the unicode codepoint for “A” is 65.

9 of 9

This week

  • Solve non-visible