pikachu靶场实战
暴力破解
基于表单的暴力破解
随便填用户名和密码之后用burp抓包,用常用字典直接爆破即可。
字典推荐:fuzzDicts
- 爆破结果:
将响应包按长度排序,由此可知:用户名为admin(不区分大小写),密码为123456
验证码绕过(on server)
- 先填入正确的用户名、密码和验证码进行重放攻击测试
经测试发现,该验证码虽在后端验证,但不能抗重放攻击。
于是可以用正确的验证码的包来进行用户名和密码的爆破。
同样地,用户名为admin(不区分大小写),密码为123456
验证码绕过(client)
- 第一种方法可以按照上面绕过服务器端验证的方法绕过
- 第二种方法:
由于是在客户端验证的,所以尝试将请求中的验证码参数部分去掉然后进行重放,发现依然可以登陆成功。
于是选择使用删掉验证码字段的请求包进行用户名和密码的爆破。
token防爆破
- 抓包发现请求包中增加了token参数,用来防爆破,repeater进行重放发现无法成功登录。
- 经测试发现,需要在第n次爆破的时候,使用第n-1次返回包中携带的token,才能通过验证。
- 选择鱼叉模式进行密码爆破
- 第一个参数是密码,用字典即可
因为token都是一次性的,线程需要调成1。 - 第二个参数需要用到Grep-Extract模块
点击add
下面的框没有包的话点一下refetch response
这时候只要选中token的值,左上角就会标记好它在包中的位置,点击ok
回到payload设置界面进行设置。
第二个参数选择recursive grep模式,在下面这个框里粘贴repeater里获取的新的token
- 爆破结果:
这里感觉第一个token填什么都可以,且固定会牺牲掉第一个密码字段中填入的第一个payload,也就是第一个密码字段的payload也是随便填。
同样地,爆破出密码为123456
XSS
反射型XSS(get)
先随意提交一段字符观察url的变化,可以看到是在messgae字段进行XSS的。
于是直接进行XSS
这里仅用弹出1来实验,实战中多为利用XSS获取cookie。
反射型XSS(POST)
- 直接无脑POST实现
- burp抓包实现
注意这里要将payload进行url编码才有效果。
存储型XSS
先随便输点什么测试一下功能点。
可以看到传统的存在存储型XSS的留言板功能(刷新之后还会存在的留言列表)。
-
直接在留言板中插入payload
<script>alert(document.cookie)</script>
-
结果如图:
-
数据库中也是可以看到的
DOM型XSS
F12查看源码,发现前端js,闭合掉进行XSS即可。
'><img src="#" onmouseover="alert(document.cookie)">
' onclick="alert(document.cookie)">
onclick是点击下方的蓝色触发xss,onmouseover是鼠标放到蓝字上就会触发xss
DOM型XSS-X
同样地F12找到前端JS的源码
payload同上,只不过要多点一下,之后才能触发。
XSS之盲打
XSS盲打不是攻击类型,而是一个攻击场景。
我们先不管别的,先插一段xss代码再说,<script>alert('xss')</script>
,我们只看到一句,没有别的了。
提交后我们输入的内容不会在前对输出,而是提交到了后台,可能管理员会去看。如果我们输入一个JS代码,管理员登录后台管理界面,如果后台把我们的内容输出,那后台管理员可能遭受到我们的XSS攻击。
在数据库中可以看到已经写入了数据库。
于是登录管理员后台管理界面查看,发现受到了XSS攻击。
XSS之过滤
实际中的系统,或多或少都会做一些安全措施,但是这些安全措施也能方法、逻辑不严谨,可以被绕过。
转换思路:
-
前端限制绕过,直接抓包重放,或者修改html前端代码。比如反射型XSS(get)中限制输入20个字符。
-
大小写,比如
<SCRIPT>aLeRT(111)</sCRIpt>
。后台可能用正则表达式匹配,如果正则里面只匹配小写,那就可能被绕过。 -
双写(拼凑),
<scri<script>pt>alert(111)</scri</script>pt>
。后台可能把<script>
标签去掉换,但可能只去掉一次。 -
注释干扰,
<scri<!--test-->pt>alert(111)</sc<!--test-->ript>
。加上注释后可能可以绕过后台过滤机制。
我们在pikachu上,尝试用大小写混合的方式看看能否绕过:<SCRIPT>alert(document.cookie)</sCRIpt>
,发现后端只对小写的script进行过滤。
当然,由于它只过滤小写的script标签,那么换一种payload也是可以绕过的。
<img src=x onerror=alert(document.cookie)>
XSS之htmlspecialchars
- htmlspecialchars()是PHP里面把预定义的字符转换为HTML实体的函数。
预定义的字符是
-
& 成为 &
-
" 成为 "
-
' 成为 '
-
< 成为 <
-
成为 >
可用引号类型
-
ENT_COMPAT:默认,仅编码双引号
-
ENT_QUOTES:编码双引号和单引号
-
ENT_NOQUOTES:不编码任何引号
我们看下源代码,这个可以对特殊字符进行编码,即预定义的字符是 & " ' < > 这五个,转化为 &#xxx的形式。虽然使用了htmlspecialchars进行处理,但是htmlspecialchars默认形式不对单引号处理。
我们可以构造一下Payload,我们在Payload前添加一个单引号用于闭合 href 中的单引号:' onmouseover='alert(document.cookie)'
XSS之href输出
查看一下源代码
这个页面会接收我们的输入的message,然后判断我们输入的网址,如果输入的不是百度会对我们输入的内容用 htmlspecialchars() 进行处理。
这个函数转义单引号、双引号和左右尖括号。然后输出到 a 标签的 href 属性中,在 a 标签的href属性中,可以用javascript协议来执行JS
构造payload:javascript:alert(document.cookie)
然后点击下方的蓝字触发即可。
XSS之js输出
老规矩查看一下源码
发现会把输入的内容嵌到script内部,于是考虑可以先闭合script标签然后再进行XSS。
payload:</script><img src=x onerror=alert(document.cookie)>)
CSRF
CSRF(get)
随便登录一个账户然后选择修改个人信息并抓包。
然后即可根据包中数据构造钓鱼链接,发给受害者,在他保持登录状态的情况下,会将对应字段的信息改成攻击者设置好的内容。
http://x.x.x.x/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=test&phonenum=test&add=test&email=test@test.com&submit=submit
- 受害者点击后效果如图:
CSRF(post)
同样地,先登录。
修改个人信息,然后抓包。
URL不再显示修改参数,所以无法再使用上述办法(即通过URL来伪造请求)进行修改
但是抓包可以知道本页面中有的标签以及name,方便后面构造表单时使用
然后用burp生成CSRF poc
然后稍加修改
让受害者访问该页面,即可在受害者保持登陆的情况下,将个人信息修改为攻击者设置好的内容。
CSRF Token
同样我们重新登录一下。
首先我们了解一下什么是Token?每次请求,都增加一个随机码(需要够随机,不容易被伪造),后台每次对这个随机码进行验证。这个随机码就是Token。
然后我们看一下Pikachu平台的CSRF(token)页面,我们可以看到服务器返回的修改页面源码中有一个hiden的token
在文件token_get_edit.php中,我们也可以看到服务端会生成token:
在对应文件inc/function.php可以看到token的生成方式:
这里我们就要分析一下这个token的作用了。按照前面csrf get的方法,攻击者会伪造一个GET URL去让用户点击。但用户正常提供GET请求时,会把服务器返回的token填入和提交,而攻击者伪造URL时除非前期抓包获取到这个返回的token,否则他是不会知道这个token的。所以攻击者无法构造GET URL。同理,对于POST方法也是一样。
所以,使用token是一个很好的防御CSRF攻击的方法。
SQL-Inject
数字型注入(post)
- 如图所示,order by 递增到3的时候出现报错,则证明数据表一共有两列。
- 测试注入点
- 爆破当前数据库名以及mysql的版本
- 获取数据库名
由此可以继续获取表名、列名和数据。
其实用sqlmap直接跑也是可以的。
字符型注入(get)
- 在得知是get 字符型注入后,直接在url中加入payload进行注入点测试。
- 获取当前数据库名以及mysql版本
- 获取所有数据库名
- 获取当前数据库所有表名
- 以member数据表为例,获取其所有列名
- 查询各个列的具体数据
搜索型注入
xx型注入
查看后端代码,多除了括号,我们还是进行闭合。
- payload
') or 1=1 #
,查看结果。
insert/update注入
注册用户名处 或者 修改个人信息处:
- payload
weiss' or updatexml(1,concat(0x7e,database()),0) or '
delete注入
先任意提交,例如123
删除,抓包/pikachu-master/vul/sqli/sqli_del.php?id=59
59之后添加or updatexml(1,concat(0x7e,datebase()),0)
用加号连接:id=60+or+updatexml(1,concat(0x7e,datebase()),0)
http header注入
-
User-Agent:'or updatexml (1,concat(0x7e,datebase()),0) or '
-
Cookie:ant[uname]=admin'or updatexml (1,concat(0x7e,datebase()),0) or ';
盲注
boolean
-
手工注入:
name=lucy' and length(database())=7-- -
判断数据库的长度是7,查看burpsuite响应的render
实为pikachu,正好7位 -
sqlmap直接跑:
python sqlmap.py -u "http://x.x.x.x/pikachu/vul/sqli/sqli_blind_b.php?name=1&submit=查询" --dbs
time
- payload:
kobe' and if((substr(database(),1,1))='p',sleep(5),null)#
根据响应时间来判断是否正确。 - sqlmap:
python sqlmap.py -u "http://x.x.x.x/pikachu/vul/sqli/sqli_blind_b.php?name=1&submit=查询" --dbs
宽字节注入
- 首先用
name=1%df' union select 1,2#
判断注入位置和有无回显 - 之后就按照正常注入流程即可,原理是利用GBK绕过前端对单引号添加的转义符。
PHP反序列化
- payload
O:1:"s":1:{s:4:"test";s:31:"<script>alert('weiss')</script>";}
- 结果:
XXE
- payload
<?xml version = "1.0"?>
<!DOCTYPE note [ <!ENTITY hacker "xxe"> ]>
<name>&hacker;</name>
- 结果:
URL重定向
SSRF
SSRF(curl)
SSRF(file_get_content)
参考资料:pikachu靶场通关