前幾天看了兩篇文章,覺得很不錯,寫一筆,就當筆記記錄。
第一篇文章:https://jinone.github.io/bugbounty-dom-xss/
作者寫了自己透過自動化挖dom xss,差不多賺了3w刀左右。他分享了一些不錯的漏洞案例。這裡很感謝作者,無私分享思路出來,也給大家有了喝口湯的機會。
中國需要多一些這樣的熱愛分享的白帽子,一方面是推動安全測試水位,另一方面是帶來更多的思路給他人。看這篇文章,給了我一些啟發。在相當內卷的今天,選擇適合自己的漏洞挖掘賽道很重要。就像不是人人都適合挖rce,一個道理。
第一篇文章的細節點:
訪問:
https://example.com/xsspath'%22?xssparam%27%22=xssvalue%27%22#xsshash'%22
結論:
location.search 會對'"編碼 location.hash 不會對'編碼 location.pathnme 不會對'編碼 location.href hash和pathname中的'不會被編碼 包含search,hash和pathname { 這三個可以跳出單引號 location.href location.hash location.pathname }
因為作者文章中提到有自動化挖掘。這裡就調研了下市面上的工具,記錄下:
透過檢視作者寫的文章,以及自己對dom xss的理解,簡單寫下半動化的粗略思路
dom xss半自動化簡單思路:
{
n個source
n個sink
如果有某個source和某個sink同時存在
疑似dom xss,命中
}
只檢索applocation/javascript和text/html
關於dom xss的探測,多疑似,那麼誤報率就會很高。
缺陷很明顯,需要儘可能的收集javascript和javscipt庫的source和sink,吃經驗,吃規律,需要熟悉一定的規律。
工具1:Dom Invader 可以用於檢測dom xss和postMessage xss
檢測postmessage+dom xss配置如下:
和寫dom xss的作者聊過一些,這款工具,檢測dom xss很不錯
關於這個外掛的學習教程:
https://www.youtube.com/watch?v=Wd2R47czzO0&t=156s https://portswigger.net/blog/introducing-dom-
這裡簡單提一嘴,burpsuite很多外掛,挖洞使用很方便,有空的話,我講下burpsuite上一些很好的輔助挖洞神器。
這個工具我就一筆帶過,他不是本文的重點,本文的重點是另一個工具:
重點檢測工具:semgrep
semgrep? what?
A fast, open-source, static analysis tool for profoundly improving software security and reliability.
一種快速、開源、靜態分析工具,可顯著提高軟體的安全性和可靠性。
我認為它就是grep命令的升級版,更加的強大。
優勢:
1.支援本地,命令列執行,很方便 2.支援線上網站上建立和匯入/新增規則
3.支援批次檢測,無需對程式碼進行編譯
什麼場景下使用他們?
1.大量的程式碼,進行安全缺陷審查 2.漏洞挖掘,web程式碼審計 3.支援純文字程式碼識別和汙點跟蹤 4.src/眾測 部分程式碼需要
5.發現某個漏洞特徵,使用semgrep事半功倍
安裝:
三種安裝方式 # Using Homebrew $ brew upgrade semgrep # Using pip $ python3 -m pip install --upgrade semgrep # Using Docker $ docker pull returntocorp/semgrep:latest
這裡我使用的是第二種,pip安裝。
referer: https://github.com/returntocorp/semgrep
semgrep基礎使用:
1.命令列cl使用
semgrep --pattern '127.$A.$B.$C' --lang generic /etc/hosts #lang 是指定某種型別 參考:https://semgrep.dev/docs/supported-languages/ 很詳細
參考:https://semgrep.dev/docs/getting-started/
—pattern是一種匹配模式。但是更推薦的是匯入yaml,對某段程式碼/某個專案進行執行漏洞規則檔案:
漏洞yaml規則庫大全 用於學習編寫規則:
https://github.com/returntocorp/semgrep-rules https://semgrep.dev/playground/new?editorMode=advanced
涉及到的語言眾多
汙點跟蹤 這個適合漏洞挖掘,半自動化:
汙點跟蹤演示教程:https://semgrep.dev/docs/writing-rules/data-flow/taint-mode/
使用汙點跟蹤半動化檢測dom xss:
rules:
- id: domxss-insertAdjacentHTML
languages:
- javascript
- typescript
message: Found dangerous HTML output
mode: taint
pattern-sources:
- pattern: document.location.href
- pattern: document.location
- pattern: window.location
- pattern: window.location.href
pattern-sinks:
- pattern: $X.insertAdjacentHTML(...)
- pattern: $X.innerHTML(...)
- pattern: $X.innerHTML = ...
severity: WARNING
不想聊規則細節,我說下這段yaml哪裡來的。
參考:https://netsec.expert/posts/automating-dom-xss/
一定要看,這篇文章作者是谷歌的一位安全工程師,這是他寫的規則。
他還寫了一個輔助工具,用於爬蟲網站上的js:https://github.com/the-xentropy/dump-scripts/blob/main/dump-scripts.py
然後呼叫semgrep批次檢測script目錄裡的js。
這個規則,會漏掉很多dom xss,這裡簡單調研了下,source和sink非常多,這裡只總結了一些常見的,整合了前面的幾位作者的思路和官方規則:
總結了下用於檢測js open redirect_url和其他型別的dom xss規則:
rules:
- id: dom_xss
message: dom_xss
metadata:
cwe:
- "dom_xss"
owasp:
- A03:2021 - Injection
asvs:
section: V5 Validation, Sanitization and Encoding
control_id: 5.2.4 Dynamic Code Execution Features
control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing
version: "4"
category: security
technology:
- browser
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
confidence: LOW
references:
- https://owasp.org/Top10/A03_2021-Injection
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- javascript
- typescript
severity: WARNING
mode: taint
pattern-sources:
- patterns:
- pattern-inside: |
url.split('...')
- patterns:
- pattern-inside: |
getURLParameter('...')
- patterns:
- pattern-inside: |
$PROPS.get('...')
- patterns:
- pattern-inside: |
getUrlParameter('...')
- patterns:
- pattern-inside: |
GetQueryString('...')
- patterns:
- pattern-inside: |
$PROPS.get('...')
- patterns:
- pattern-inside: |
$PROPS.split("...")
- patterns:
- pattern-either:
- pattern-inside: >
$PROP = new URLSearchParams($WINDOW. ...
.location.search).get('...')
...
- pattern-inside: |
$PROP = new URLSearchParams(location.search).get('...')
...
- pattern-inside: >
$PROP = new URLSearchParams($WINDOW. ...
.location.hash.substring(1)).get('...')
...
- pattern-inside: >
$PROP = new
URLSearchParams(location.hash.substring(1)).get('...')
...
- pattern-inside: |
$PROP = window.location.search.substr(1).match(...)
...
- pattern: $PROP
- patterns:
- pattern-either:
- pattern-inside: |
$PROPS = new URLSearchParams($WINDOW. ... .location.search)
...
- pattern-inside: |
$PROPS = new URLSearchParams(location.search)
...
- pattern-inside: >
$PROPS = new URLSearchParams($WINDOW. ...
.location.hash.substring(1))
...
- pattern-inside: |
$PROPS = new URLSearchParams(location.hash.substring(1))
...
- pattern: $PROPS.get('...')
- patterns:
- pattern-either:
- pattern-inside: |
$PROPS = new URL($WINDOW. ... .location.href)
...
- pattern-inside: |
$PROPS = new URL(location.href)
...
- pattern: $PROPS.searchParams.get('...')
- patterns:
- pattern-either:
- pattern-inside: >
$PROPS = new URL($WINDOW. ...
.location.href).searchParams.get('...')
...
- pattern-inside: |
$PROPS = new URL(location.href).searchParams.get('...')
...
- pattern: $PROPS
pattern-sinks:
- patterns:
- pattern-either:
- pattern: $WINDOW. ... .location.href = $SINK
- pattern: $WINDOW. ... .location = $SINK
- pattern: location.href = $SINK
- pattern: $THIS. ... .location.href = $SINK
- pattern: $THIS. ... .location.replace($SINK)
- pattern: $WINDOW. ... .replace($SINK)
- pattern: $PROPS.replace($SINK)
- pattern: $X.insertAdjacentHTML($SINK)
- pattern: $X.innerHTML($SINK)
- pattern: $X.innerHTML = $SINK
- pattern: $X.innerHTML += $SINK
- pattern: $X.prepend($SINK)
- pattern: $X.prepend("..."+$SINK)
- pattern: $X.append($SINK)
- pattern: $X.append("..."+$SINK)
- pattern: $X.before($SINK)
- pattern: $X.before("..."+$SINK)
- pattern: $X.after($SINK)
- pattern: $X.after("..."+$SINK)
- pattern: $X.html($SINK)
- pattern: $X.html("..."+$SINK)
- metavariable-pattern:
patterns:
- pattern-not: |
"..." + $VALUE
- pattern-not: |
`...${$VALUE}`
metavariable: $SINK
如何實戰利用?
使用一個漏洞規則批次檢測多個專案:
使用多個規則檢測多個專案:
semgrep -c rules/ jstest/*
對於semgrep,我並不陌生。早在今年log4j2漏洞剛爆發的時候,我們團隊內部就使用了semgrep編寫log4j2規則去批次檢測,效果很好。
工具很強大,寫好匹配規則即可。語言都是次要的,主要是要多收集source和sink。剩下的就是套娃~~