第一关:暴力破解
1.1基于表单的暴力破解
首先打开burp suite拦截,然后在随意输入账号密码,
可在burpsuite上抓到皮卡丘的包,可以看到刚才输入的账号密码
我们选择放包,然后看到提示“用户名或密码不存在”,说明刚刚随便输入的账号密码是错的(废话)
这怎么办呢,可以看到右上角有提示,我们点开发现三个账号密码,其中肯定有一个是正确的,当然我们可以一个一个地试。但是数量多的话我们就不好试了。把这三个记下来,下面用到。
再次随便输入账号密码,拦截抓包
发送
攻击类型选择集束炸弹
添加要攻击的位置,即账户和密码位置
第一个负载集对应账户,添加输入上面提示给的三个账户,第二个负载对应密码,
添加三个密码
然后开始攻击,返回长度与其他不一样的一组即为正确的账号密码
1.2验证码绕过(on server)
随意输入账号密码,输入正确的验证码,登录。然后提示账号密码不存在,验证码改变。
打开burp suite拦截,再次随机输入账号密码和正确的验证码,burp查看数据包
把数据包发送给重发器,修改数据包中的验证码,然后发送,在右边响应栏可以看到,验证码输入错误的提示,说明后台会对验证码进行验证。
点击右上角有个小提示告诉我们验证码一直有效
关闭burp拦截,返回平台重新随机输入账号密码和正确的验证码,burp拦截抓包
把数据包发送给重发器,点击发送,右侧响应栏提示账号密码不存在。
然后我们修改账号密码,验证码不动,再发送,还是提示账号密码不存在。但是却不提示验证码错误。说明我们修改账号密码登录,验证码不过期,可以重复使用。
把数据包发送给测试器,因为验证码不会改变,我们输入的验证码又是正确的,所以我们只要设置账号密码两个攻击变量
两个攻击载荷分别添加字典,开始攻击
返回长度不同的就是正确的账号密码。
1.3验证码绕过(on client)
首先随机输入用户名密码和正确的验证码,burp拦截抓包
把数据包发送给重发器,修改验证码,然后发送过去,发现响应栏只提示用户名和密码错误,却没有说验证码错误,是不是说明后台根本没有检验发送过来的验证码,或者说验证码根本没有发送到后台。
我们看一下右上角的提示
打开码源,发现这个验证码是JavaScript前端随机生成的,每点击一次就随机生成一个验证码,
并且验证码的检验也是由前端来检验的,后台没有检验这个验证码。
那就好办了,我们只需要随机输入账号密码,输入正确的验证码,然后只需要对发送到后台的数据包中的账号密码进行字典攻击就可以了。后面的操作跟1.1一样。
第二关:Cross-Site Scripting
2.1反射型xss(get)
输入特殊字符,查看源码,发现被原封不动的输出,说明没有对输入的内容进行过滤处理
我们尝试输入script语句:
<script>alert('xss')</script>
发现不能完整输入,输入长度被限制了。
F12打开码源,搜索length,修改长度,原来的是20,我们修改大一点,200。
返回,继续输入script语句提交,弹出xss窗口,刷新就消失,这就是反射型xss,也就是一次性的
这个xss是以get方式提交,也就是体现在url中
用burp拦截也能看到
2.2反射型(post)
登录
输入script语句,并用burp拦截才能发现,在url中没有体现。GET方式的XSS漏洞更加容易被利用, 一般利用的方式是将带有跨站脚本的URL伪装后发送给目标,而POST方式由于是以表单方式提交,无法直接使用URL方式进行攻击
2.3存储型xss
这是一个留言板,我们输入什么信息,下面的留言列表就会永久存储该信息,没有对输入的内容进行过滤处理,包括特殊符号。
那我们尝试输入上面用到的Javascrip语句:
<script>alert('xss')</script>
把scrip语句留言到留言板后,该语句就会被执行,弹出窗口,并且刷新后或者退出重新访问还是会弹出。
打开页面源码查看,我们写入的代码已经变成了页面的JavaScript脚本了,每次访问该页面都会运行脚本。也就是说我们可以利用这个漏洞写入恶意代码,每当用户访问该留言页面时,恶意代码将会被执行。
存储型xss与反射型差不多,区别就是一个是永久存储,一个是一次性的。
2.4DOM型xss
先随便输入,点击,出现一个类似a标签的东西。
打开源码查看,这个意思就是说当我们在这个标签里面输入一个字符串之后
就会把这个字符串通过dom方法 通过字符串拼接的方式拼接到a标签的herf属性中
这个a标签会被写道id=dom的div标签里面
<a href='"+str+"'>what do you see?</a>
复制源码 做对应的分析 构造闭合
<a href='"+str+"'>what do you see?</a>
Str我们输入的内容
我们可以把输入部分删除
<a href='#’οnclick=”alert(1111)”>'>what do you see?</a>
在个这个地方把前面的a标签闭合掉
随便输入一个字符串 单引号 用一个conclik弹一个窗 然后闭合a标签
#'οnclick="alert(1111)">
这就是我们构造的payload
经过我们前面的分析 知道
通过dom的方式获取到我们的输入 在输出到div里面
我构造闭合后,并没有弹窗出现
换了另一条js语句,点击a标签,弹出窗口
2.5DOM型xss-x
与上面差不多
2.6xss之盲打
随便输入内容提交后内容消失,点击提示,需要我们登录后台
根据所给提示,登录到后台,发现我们刚才随意输入的内容发送到了后台存起来的
写入恶意弹窗代码,提交
再次登录后台,一登陆就出现弹窗,管理员被攻击到。这种情况就是xss盲打,对攻击者来说只是尝试的输入,并不知道后台是否被输出,只是尝试的输入跨站脚本。管理员被攻击到,攻击者成功。这种危害比较大,如果在前端输入一段盗取cookie的脚本,管理员一登陆,管理员的cookie就会被获取。攻击者就可以伪装管理员登陆后台,后台的权限就大了。
2.7xss之过滤
直接输入特殊字符,发现没有过滤处理
然后我们直接输入弹窗语句
提交后发现,我们的语句被吞掉了,应该是设置了过滤把我们的<scrip...都过滤了
我们来验证一下,输入<scrip>,提交,确实被吞掉了
查看源码,所以可以确定的是它对标签<scrip>进行了过滤
接下来,我们试试大小写混用,看看是不是还被过滤
看来它只是对小写进行简单的过滤,用大写就可以绕过了
我们也可以用img标签
<img src=x onerror="alert('xss')">
2.8xss之htmlspecialchars
关于htmlspecialchars()函数:
htmlspecialchars()是PHP里面把预定义的字符转换为HTML实体的函数
预定义的字符是:
& 成为 &
" 成为 "
' 成为 '
< 成为 <
> 成为 >
可用引号类型
ENT_COMPAT:默认,仅编码双引号
ENT_QUOTES:编码双引号和单引号
ENT_NOQUOTES:不编码任何引号
查看php源码,htmlspecialchars默认不对 ' 处理
构造闭合:
' onclick='alert(111)'
2.9xss之href输出
输入payload
Javascript:alert(111),
查看页内源码
点击a标签,弹出窗口
查看php源码,
这个页面会接收我们的输入的message,然后判断我们输入的网址,如果输入的不是百度的网址会对我们输入的内容用 htmlspecialchars()函数 进行处理
这个函数转义单引号、双引号和左右尖括号
然后输出到 a 标签的 href 属性中,在 a 标签的href属性中,可以用javascript协议来执行JS
如果要对 href 做处理,一般有两个逻辑:
输入的时候只允许 http 或 https 开头的协议,才允许输出
其次再进行htmlspecialchars处理
2.10xss之js输出
根据提示,我们输入tmac,然后查看页内源码,发现它会把我们的输入放到JS中,然后对这个变量进行判断,然后再输出
我们可以构造一个闭合,先用一个单引号和</script>闭合掉页面中的<script>,然后再插入自己的JS代码
输入我们构造的payload
'</script><script>alert('xss')</script>
对比上面的图,<script>提前被我们闭合了,然后插入我们自己的script代码
第三关:CSRF
3.1CSRF(get)
CSRF全称为跨站请求伪造(Cross-site request forgery),是一种网络攻击方式,在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。也被称为 one-click attack 或者 session riding。
首先,随便登录一个用户
登录成功页面,点击修改个人信息
进入修改 信息页面后,这里我修改了电话号码
提交后
重新返回修改信息页面,编辑信息后提交,打开burp拦截抓包
看上面的url可见,修改用户信息的时候,是不带任何不可预测的认证信息的,我们并没有看到CSRF的token,说明并没有防CSRF的措施,那么,这里应该是可以被利用的。
我们url复制下来
GET /vul/csrf/csrfget/csrf_get_edit.php?sex=%E7%94%B7&phonenum=1111&add=nba+lakes&email=kobe%40pikachu.com&submit=submit HTTP/1.1
把url中电话号码修改成2222
GET /vul/csrf/csrfget/csrf_get_edit.php?sex=%E7%94%B7&phonenum=2222&add=nba+lakes&email=kobe%40pikachu.com&submit=submit HTTP/1.1
然后访问修改后的url
可以看到,电话号码已经变成了我们修改的号码
在实际中,攻击者只要注册一个新的号,登录修改信息后,就可以获取到这个链接,只需修改链接的内容,在受害者在登录状态下,把伪造后的链接发送给受害者,引诱其点击(比如发送到他邮箱或者发送信息),即可完成攻击,相当于受害者以他自己的身份,修改了他自己的信息
3.2CSRF(post)
同样的操作,登录修改信息,抓包
我们发现它的提交方式为post
所有参数在请求体中提交,我们就不能通过伪造URL的方式进行攻击
是不是不能进行攻击了呢?
其实不是,我们可以自己搭建一个站点
诱导受害者点击链接,那么就会以受害者身份向后台用post请求提交修改信息
我们可以在抓到的包中右键
它会给我们自己生成一个脚本
然后我们修改信息,点击下面“用浏览器测试”,会生成一段链接
将链接复制到浏览器访问,信息修改成功
其实我们也可以在本地写一个html文件,原理一样,都是让用户来访问我们写的脚本,以达到以post请求向后台修改信息的请求。
3.2CSRF Token
token验证原理
CSRF的主要问题是敏感操作的链接容易被伪造
每次请求,都增加一个随机码(需要够随机,不容易伪造),后台每次对随机码进行验证
网页接受从后台发过来的token,类型不可见。将其一并提交给后台进行验证。每次刷新,后台发送过来的token都不一样,起到了防止伪造的作用。
同样拦截抓包,发现这一关比前面的多了一个token参数
看一下后台源码,修改用户信息时,服务器会比较url中的token字段和session中的token字段,如果相同才能修改用户信息。
修改完用户信息之后,会用set_token()函数生成新的token,将其返回到html表单中并隐藏起来,以便下次用户修改信息时代入url
所以攻击者无法伪造
第四关:SQL-Inject
4.1数字型注入(post)
随便选一个数查询,发现url中没有以get方式传参,那应该是以post方式传参,返回的是两个数据,一个名字,一个邮箱地址。所以我们判断SQL语句应该是:
select 字段1,字段2 from 表名 where id=1
我们打开burp suite抓包,果然是以post方式提交
发送数据给重发器,构造payload:
id =1 or 1=1
发送后,在右边的Render可以看到爆出了全部的数据
4.2字符型注入(get)
随便输入一个名字,如allen,就出现以下内容。返回了两个信息,并且url中有我们输入的字符进行传参,所以猜测后台的sql语句为:
select 字段1,字段2 from 表名 where name='(我们输入的名字)'
所以我们构造payload:
' or 1=1 #
前面的引号把语句前面的引号闭合,后面的#号把语句后面的引号注释掉
手工测试:基于union联合查询的信息获取( select )
首先在输入框中输入 1' ,提交后出现以下报错。说明可能存在sql注入漏洞。
为了验证,我们输入永真式:
1' or 1 =1 #
结果爆出全部信息
接着我们检测一下它的查询字段有几个,根据上面的回显信息,我们猜测是查询的是两个字段,输入
1' order by 2#
出现以下信息
把2改成3再试试
1' order by 3#
出现报错信息,说明查询字段是两个,回显也是两个
这时候我们就可以用union联合查询:
1' union select user(),database()#
得到用户名:root@localhost,数据库名:pikachu
改一下语句还可以查询数据库版本:
1' union select user(),version()#
通过information_ schema手工测试爆出数据库
MYSQL小知识补充: information_ schema
在mysql中,自带的information_schema这个表里面存放了大量的重要信息。具体如下:
如果存在注入点的话,可以直接尝试对该数据库进行访问,从而获取更多的信息。
比如:
SCHEMATA表:提供了当前mysq|实例中所有数据库的信息。是show databases的结果取之此表。
TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema ,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
通过上面,我们得到了数据库名为:pikachu,我们还要通过information_schema获取到pikachu这个数据库里有哪些表:
1' union select table_schema,table_name from information_schema.tables where table_schema = 'pikachu'#
爆出了pikachu数据库下的四个表,httpinfo,member,users,xssblind
注意到有个表users,应该是用来存放用户信息的。
继续爆出来
1' union select table_name,column_name from information_schema.columns where table_name = 'users'#
注意到有一列username,一列passeord,应该就是用户名和密码
继续把用户名的密码爆出来
1' union select username,password from users #
得到三个用户名和密码,密码看长度应该是MD5加密,解密即可得到密码
4.3搜索型注入
输入一个字母a,返回了两条内容。判断后台sql语句为:
select * from 表名 where name like '%a%'
所以我们一样构造payload:
' or 1=1 #
4.4xx型注入
尝试构造闭合,没有成功
查看一下后台源码,原来是要加括号进行闭合
构造payload:
') or 1=1 #
4.5"insert/update"注入
在MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息。select/insert/update/delete都可以使用报错来获取信息。
背景条件:
后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端。
首先先注册,用户名输入:
aaa' or updatexml(1,concat(0x7e,database()),0) or '
密码随意输入
直接爆出数据库名,想要爆出表名,列名,用户账号密码等只要把payload修改就可以得到下想要的信息了
update类型:
先注册一个账号,用这个账号登录,然后点击修改个人信息(如果登录了发现信息没有显示不出来
在这里我们本地打开这个路径,找到第报错行,把MYSQL_ASSOC改成MYSQLI_ASSOC,保存文件,刷新网页。就可以啦。
同样的操作输入payload即可爆出信息
4.6"delete"注入
随便输入留言信息
点击删除,然后用burp suite抓包,右键发送给repeater(重发器),修改数据,把id后面改成以下payload,
1 or updatexml(1,concat(0x7e,database()),0)
然后选中,右键转换选择(convert selection),url编码,然后发送数据,即可在右侧render看到信息
4.7"http header"注入
什么是Http Header注入
有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)
或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等等。
会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑,则可能会导致基于http header的SQL Inject漏洞。
先正常登录
然后用burp suite抓包
发送给repeater,修改Agent=1',出现报错,判断有SQL注入
修改成我们的payload:
1' or updatexml(1,concat(0x7e,database()),0) or '
发送
4.8盲注(base on boolian)
什么是盲注?
在有些情况下,后台使用了错误消息屏蔽方法(比如@ )屏蔽了报错
此时无法在根据报错信息来进行注入的判断。
这种情况下的注入,称为“盲注"
根据表现形式的不同,盲注又分为based boolean和based time两种类型
基于boolean的盲注主要表现症状:
0.没有报错信息
不管是正确的输入,还是错误的输入,都只显示两种情况(我们可以认为是0或者1)
在正确的输入下,输入and 1= 1/and 1= 2发现可以判断
我们用burp suite抓包
首先判断注入类型,
发送给repeater,修改url,记得每次修改url时,有特殊符号都要进行url编码,不然不符合url的格式输入kobe,显示正常
输入kobe',显示不正常
然后输入 kobe'#,构造闭合,显示不正常,说明是字符型
输入payload:
kobe' and 1=1#
发现正常
修改payload
kobe' and 1=2#
发现不正常
我们就可以利用这些正常和不正常的返回来判断猜测
例如:
我们前面就知道数据库名叫pikachu,长度是7,那么我们可以来验证一下,输入payload
kobe'and length(database())=8#
返回不正常
修改一下payload
kobe'and length(database())=7#
返回正常,验证了我们数据库名字长度确实是7位
假如我们现在不知道数据库的名字,我们可以进行尝试判断,第一个字母是a
输入payload
kobe' and left(database(),1)='a'#
返回不正常
我们继续尝试字母b,c,d....,直到p返回正常,说明数据库名字第一个字母是p,思路就是这样子,不断猜测得到需要的信息
4.9盲注(base on time)
无论输入什么,返回显示都是没有区别的,这样子我们就没法通过返回显示来判断了
输入payload
kobe' and sleep(5)#
画面返回信息延迟了五秒,可以判断我们的语句被执行了,存在注入
接下来输入payload:
kobe' and if(length(database())=7, sleep(1),5)#
意思就是判断数据库名字长度是不是7,正确了秒回,不正确则延迟5 秒返回。
同理,接下来就是判断数据库名
kobe' and if((select substr(database(),1,1))='p',sleep(1),5)#
判断数据库内表的个数
kobe' and if((select count(table_name) from information_schema.tables where table_schema=database())=5,sleep(1),5)#
4.10宽字节注入
1)宽字节注入指的是 mysql 数据库在使用宽字节(GBK)编码时,会认为两个 字符是一个汉字(前一个 ascii 码要大于 128(比如%df),才到汉字的范围),而且当我们输入单引号时,mysql 会调用转义函数,将单引号变为’,其中\的十 六进制是%5c,mysql 的 GBK 编码,会认为%df%5c 是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击。
2)测试宽字节注入,和联合注入是一样的只是在内容后面添加%df即可,通过在内容输入处输入内容,然后修改。