I am working on creating a security based CTF application in Django. The current exercise I am building is a blind time-based sql injection. As Django does not appear to support stacked queries through Model.raw()
, I imported the mysql-connector-python which does support stacked queries using the cursor.execute(query, multi=True)
.
However, when attempting to use sleep(X)
in the stacked query, the sleep statement won't execute. The following is one example:
view:
query = f"select sleep(2); select 1;"
mydb = mysql.connector.connect(
host="localhost",
user="****",
password="****",
database="****"
)
cursor = mydb.cursor()
cursor.execute(query, multi=True)
return HttpResponse(f"query: {cursor}")
sqli script:
url = f"http://127.0.0.1:8080/books/book/?q=1"
start = time.perf_counter()
response = requests.get(f'{url}')
end = time.perf_counter()
print(response.text)
print(f'response time: {end-start}')
This will return the following:
query: MySQLCursor: select sleep(2); select 1;
response time: 0.005476321006426588
However, if dropping multi=True and running a single query, it the sleep will work just fine.
view:
query = f"select sleep(2);"
mydb = mysql.connector.connect(
host="localhost",
user="****",
password="****",
database="****"
)
cursor = mydb.cursor()
cursor.execute(query)
return HttpResponse(f"query: {cursor}")
sqli script:
url = f"http://127.0.0.1:8080/books/book/?q=1"
start = time.perf_counter()
response = requests.get(f'{url}')
end = time.perf_counter()
print(response.text)
print(f'response time: {end-start}')
This will return the following:
query: MySQLCursor: select sleep(2);
response time: 2.010241993004456
Note that I have tried using do sleep(X)
and it also will not execute. This is also a simplistic example as the real meat of the exercise is to read a file (such as /etc/passwd) and use the blind time-based response to pull the data back from a temp table one char at a time.
The query select sleep(2); select 1;
works just fine in MySQL console and workbench so it should not be an issue with the query itself.
The URL for the execute docs: https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
I have been searching for MySQL documentation as well as questions about stacked queries but can't find anything that makes use of the sleep command.
Thank you all for any help in advance!
The linked documentation says:
If
multi
is set toTrue
,execute()
... returns an iterator that enables processing the result of each statement.
To see sleep(2)
work, traverse the iterator: list(cursor.execute(query, multi=True))
.