Vue中的Xss構造
阿新 • • 發佈:2021-04-01
首發tools:https://www.t00ls.net/thread-59512-1-1.html
##儲存型XSS
最近做測試的時候碰到了一個前端頁面使用了Vue框架的專案
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/518c8db4-3068-497a-8cd6-48b1faaa4170.png)
在測試XSS漏洞的過程中通過儲存構造的Payload後發現頁面顯示不正常,這讓我覺得肯定有戲
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/4941578.png)
事不宜遲,翻看JS原始碼發現一個名為project_name屬性的值被構造的單引號閉合了,導致語句出錯。可以看到它在這裡例項了一個Vue構造器,在el 屬性中使用id選擇器將該例項指向了頁面上id 為 mainbody的div元素。
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/0ef8b33a-be5d-4e57-abbf-d8a6ffb38447.png)
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/f29fb036-3207-477c-9666-5fcfc009277f.png)
可控點為project_name屬性的值,這個屬性是用來渲染編輯框內容的,既然這裡直接將惡意語句輸出在了js裡,那麼我們就不用考慮頁面的渲染問題了,直接在資料屬性data區構造一個任意屬性,在賦值屬性時執行我們的alert()函式進行彈窗,構造Payload,
```javascript
',x:alert(/xss/),//
```
儲存Payload
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/9128eafd-31b2-4ce1-bedf-2a21f1bf1d11.png)
成功彈窗
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/6410187.png)
下面來分析一下payload,`'`用於閉合前面的屬性值,`,`分割屬性,構造一個`x`屬性,執行彈窗函式alert(),`//`註釋掉後面的單引號防止報錯停止執行
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/e8036a45-168d-45a9-96bc-5b6f1ac18321.png)
##反射型XSS
我們再來看另一個反射型XSS,這次的觸發點位於這三個欄目頁面中,可控點是getDefectTree方法內的axios請求引數jid,該方法位於Vue繫結的方法methods中。這裡也使用了單引號賦值屬性,而該系統後端轉義了雙引號沒有轉義單引號導致此處被閉合。
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/d9e41229-d6cc-4b36-a15d-6fb21d8043ab.png)
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/17db908b-34d7-4818-ad97-18c38254e703.png)
追蹤呼叫過程發現是某個按鈕點選事件
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/2d4953b0-54af-4a1c-afba-c49bad45fe52.png)
![1597372266667](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/1597372266667.png)
那麼現在想要讓他自動執行的話有兩個思路,一個是在Vue內構造,一個是閉合Vue
####Vue內構造
先來看看Vue內構造,在Vue元件的生命週期中有這幾個鉤子函式
```
beforecreate: 一般使用場景是在加 loading事件 的時候
created :處於loading結束後,還做一些初始化,實現函式自執行(data資料已經初始化,但是DOM結構渲染完成,元件沒有載入)
beforemount:處於元件建立完成,但未開始執行操作
mounted :處於發起後端請求,獲取資料,配合路由鉤子執行操作(DOM渲染完成,元件掛載完成 )
beforeupdate、updated:處於資料更新的前後
beforeDestroy:當前元件還在的時候,想刪除元件
destroyed:當前元件已被銷燬,清空相關內容
```
**我們可以構造一個方法,然後構造生命週期鉤子函式,利用指定的生命週期函式在例項載入前後自動執行繫結的方法。**可利用的鉤子函式為`created` 和`mounted`。這裡就選擇created作為Payload,構造Payload
```javascript
new Vue({
el: "#mainbody",
data: {},
created(){
this.test()
},
methods: {
test(){
alert(1)
}
}
})
```
**可以看到在例項Vue時,在created鉤子函式中執行了我們構造的test方法成功彈窗,test方法記憶體在惡意程式碼。**
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/f714fae6-9399-4b52-9037-99559cbf385e.png)
接下來直接將觸發點處小段程式碼精簡後Copy到控制檯進行構造,這樣對括號的閉合有幫助,因為有閉合提示。
```javascript
new Vue({
el: "#mainbody",
data: {},
methods: {
getDefectTree(func){
axios.get("", {
params: {
jid: '11',//可控點
}
})
.then(function (response) {
})
}
}
})
```
首先要閉合params引數,構造`'}`,
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/430e0417-ca3c-4fb6-bc1c-ab508a7b705d.png)
然後閉合axios,構造`'}})`
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/f778285a-7476-46cf-8239-c4f0fd54b49d.png)
因為這個函式沒有自動執行,所有我們還需要跳出這個函式和methods方法區,構造`'}})}}`
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/e24f1d02-4a26-400f-8371-a23e086b9b3c.png)
跳出方法區後就可以構造生命週期鉤子函數了,構造`'}})}},created(){this.test()}`
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/94f0bdee-e1ce-4640-9945-846c062fff92.png)
這時前面已經處理完了,我們現在開始閉合後面的括號,後面的按照閉合點前到methods的寫法炮製一番即可,構造`'}})}},created (){this.test()},methods: {go(){axios.get("", {params: {//`,記得註釋掉最後的單引號
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/8215a2ae-fcea-42cc-a3fa-27a5e820d086.png)
沒有報錯,離成功又進了一步,下面在構造的methods中新建一個方法test,將彈窗程式碼置於其中即可,構造`'}})}},created (){this.test()},methods: {test(){alert(/test/)},go(){axios.get("", {params: {//`
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/fe2035fd-eabf-4df7-ae1a-7e6a19cee7ef.png)
get,下面就將Payload複製到url進行測試,
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/286d2edb-f710-4cb7-b62d-19c954183a6a.png)
可以看到成功彈框,這裡其實還有一種方法就是構造一個數據區,這樣也能觸發而且簡短一點,Payload`'}})}},data:{x:alert(/test/)},methods: {go(){axios.get("", {params: {//`
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/ca02b6f0-2ccc-4d96-9443-bef5575f70b5.png)
####閉合Vue
閉合Vue的話只需要考慮前面一個花括號,一個圓括號,後面部分new 一個Vue例項和前面保持一致即可。Payload:`'}})}}});alert(1);new Vue({methods: {go(){axios.get("", {params: {//`
![img](https://aysec.oss-cn-shenzhen.aliyuncs.com/blog/Vue-xss/760866c4-6a94-485c-8f56-021360b8bc77.png)