macOS Thread Injection via Task port

AWS hacklemeyi sıfırdan kahraman olmak için öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'ı desteklemenin diğer yolları:

Kod

1. İş Parçacığı Kaçırma

İlk olarak, uzak görevden bir iş parçacığı listesi elde etmek için task_threads() işlevi çağrılır. Bir iş parçacığı kaçırma için bir iş parçacığı seçilir. Bu yaklaşım, thread_create_running()'i engelleyen yeni önlem nedeniyle yeni bir uzak iş parçacığı oluşturmanın yasak olduğu geleneksel kod enjeksiyon yöntemlerinden farklılık gösterir.

İş parçacığı kontrol etmek için thread_suspend() çağrılır ve iş parçacığının yürütmesi durdurulur.

Uzak iş parçacığı üzerinde izin verilen tek işlemler, iş parçacığını durdurmak ve başlatmak, kayıt değerlerini alıp değiştirmek içindir. Uzak işlev çağrıları, kayıtları x0 ile x7 arasındaki argümanlar olarak ayarlayarak, pc'yi hedeflenen işlevi hedeflemek üzere yapılandırarak ve iş parçacığını etkinleştirerek başlatılır. İş parçacığının dönüşten sonra çökmemesini sağlamak için dönüşün tespit edilmesi gerekmektedir.

Bir strateji, iş parçacığı için bir istisna işleyici kaydetmek için thread_set_exception_ports() kullanarak uzak iş parçacığı için bir istisna işleyici kaydetmektir. Bu, işlev çağrısından önce lr kaydını geçersiz bir adres olarak ayarlar. Bu, işlev yürütmesinden sonra bir istisna tetikler ve bir mesajı istisna bağlantı noktasına gönderir, iş parçacığının durumu incelenerek dönüş değeri kurtarılır. Alternatif olarak, Ian Beer'ın triple_fetch saldırısından benimsenen bir yöntemde, lr sonsuz bir döngüye ayarlanır. Ardından iş parçacığının kayıtları sürekli olarak izlenir ve pc'nin o talimatı işaret ettiği kontrol edilir.

2. İletişim için Mach bağlantı noktaları

Sonraki aşama, uzak iş parçacığıyla iletişimi kolaylaştırmak için Mach bağlantı noktaları oluşturmaktır. Bu bağlantı noktaları, görevler arasında keyfi gönderme ve alma haklarının aktarılmasında önemli rol oynar.

İki yönlü iletişim için, biri yerel ve diğeri uzak görevde olmak üzere iki Mach alma hakkı oluşturulur. Ardından, her bağlantı noktası için bir gönderme hakkı karşıt göreve aktarılır, mesaj alışverişi yapılmasını sağlar.

Yerel bağlantı noktasına odaklanılarak, alma hakkı yerel görev tarafından tutulur. Bağlantı noktası mach_port_allocate() ile oluşturulur. Zorluk, bu bağlantı noktasına bir gönderme hakkını uzak göreve aktarmaktadır.

Bir strateji, thread_set_special_port()'u kullanarak yerel bağlantı noktasına bir gönderme hakkını uzak iş parçacığının THREAD_KERNEL_PORT'una yerleştirmektir. Ardından, uzak iş parçacığına mach_thread_self() çağrısı yapması talimatı verilir ve gönderme hakkını alması sağlanır.

Uzak bağlantı noktası için işlem temelde tersine çevrilir. Uzak iş parçacığına, mach_port_allocate()'in dönüş mekanizması nedeniyle uygun olmadığı için mach_reply_port() kullanarak bir Mach bağlantı noktası oluşturması talimatı verilir. Bağlantı noktası oluşturulduktan sonra, uzak iş parçacığında mach_port_insert_right() çağrılır ve bir gönderme hakkı oluşturulur. Bu hak daha sonra thread_set_special_port() kullanılarak çekirdeğe saklanır. Yerel görevde, uzak iş parçacığı üzerinde thread_get_special_port() kullanılarak, uzak görevde yeni oluşturulan Mach bağlantı noktasına bir gönderme hakkı elde edilir.

Bu adımların tamamlanması, Mach bağlantı noktalarının kurulmasını sağlar ve iki yönlü iletişim için temel oluşturur.

3. Temel Bellek Okuma/Yazma İşlemleri

Bu bölümde, temel bellek okuma ve yazma işlemlerini sağlamak için yürütme ilkelinin kullanılmasına odaklanılır. Bu ilk adımlar, uzak işlem üzerinde daha fazla kontrol sağlamak için önemlidir, ancak bu aşamadaki ilkel işlemler pek çok amaç için hizmet etmeyecektir. Yakında, bunlar daha gelişmiş sürümlere yükseltilecektir.

Yürütme İlkelini Kullanarak Bellek Okuma ve Yazma

Bellek okuma işlemi için, aşağıdaki yapıya benzeyen işlevler kullanılır:

uint64_t read_func(uint64_t *address) {
return *address;
}

Ve belleğe yazmak için, bu yapıya benzer işlevler kullanılır:

void write_func(uint64_t *address, uint64_t value) {
*address = value;
}

Bu işlevler, verilen derleme talimatlarına karşılık gelir:

_read_func:
ldr x0, [x0]
ret
_write_func:
str x1, [x0]
ret

Uygun Fonksiyonları Belirleme

Ortak kütüphanelerin taranması, bu işlemler için uygun adayları ortaya çıkardı:

  1. Bellek Okuma: Objective-C çalışma zamanı kütüphanesinden property_getName() fonksiyonu, bellek okuma için uygun bir fonksiyon olarak belirlenmiştir. Aşağıda fonksiyonun taslağı bulunmaktadır:

const char *property_getName(objc_property_t prop) {
return prop->name;
}

Bu işlev, read_func gibi davranarak objc_property_t'nin ilk alanını döndürerek etkili bir şekilde çalışır.

  1. Belleğe Yazma: Belleğe yazma için önceden oluşturulmuş bir işlev bulmak daha zorlu olabilir. Bununla birlikte, libxpc'deki _xpc_int64_set_value() işlevi aşağıdaki derlemesiyle uygun bir adaydır:

__xpc_int64_set_value:
str x1, [x0, #0x18]
ret

Belirli bir adreste 64 bitlik bir yazma işlemi gerçekleştirmek için, uzaktan çağrı aşağıdaki gibi yapılandırılır:

_xpc_int64_set_value(address - 0x18, value)

Bu temel yapılar oluşturulduktan sonra, uzak işlemi kontrol etmek için önemli bir adım olan paylaşılan belleğin oluşturulması için sahne hazırlanır.

4. Paylaşılan Bellek Kurulumu

Amaç, yerel ve uzak görevler arasında paylaşılan bellek oluşturmaktır. Bu, veri transferini basitleştirir ve çoklu argümanlara sahip işlevlerin çağrılmasını kolaylaştırır. Yaklaşım, libxpc ve onun OS_xpc_shmem nesne türünü kullanmayı içerir. Bu nesne türü, Mach bellek girişlerine dayanır.

İşlem Genel Bakışı:

  1. Bellek Tahsisi:

  • Paylaşım için belleği mach_vm_allocate() kullanarak tahsis edin.

  • Ayrılan bellek bölgesi için bir OS_xpc_shmem nesnesi oluşturmak için xpc_shmem_create() kullanın. Bu işlev, Mach bellek girişinin oluşturulmasını yönetecek ve Mach gönderme hakkını OS_xpc_shmem nesnesinin 0x18 ofsetinde depolayacaktır.

  1. Uzak İşlemde Paylaşılan Bellek Oluşturma:

  • Uzak işlemde OS_xpc_shmem nesnesi için bellek tahsis edin ve bunu uzaktan malloc() çağrısıyla yapın.

  • Yerel OS_xpc_shmem nesnesinin içeriğini uzak işleme kopyalayın. Ancak, bu ilk kopyada 0x18 ofsetinde yanlış Mach bellek girişi adları olacaktır.

  1. Mach Bellek Girişini Düzeltme:

  • Uzak göreve Mach bellek girişi için bir gönderme hakkı eklemek için thread_set_special_port() yöntemini kullanın.

  • Uzak bellek girişinin adıyla 0x18 ofsetindeki Mach bellek girişi alanını düzeltmek için üzerine yazın.

  1. Paylaşılan Bellek Kurulumunu Tamamlama:

  • Uzaktaki OS_xpc_shmem nesnesini doğrulayın.

  • Uzaktan xpc_shmem_remote() çağrısıyla paylaşılan bellek eşlemesini oluşturun.

Bu adımları takip ederek, yerel ve uzak görevler arasında paylaşılan bellek verimli bir şekilde kurulacak ve basit veri transferleri ve çoklu argüman gerektiren işlevlerin yürütülmesi mümkün olacaktır.

Ek Kod Parçacıkları

Bellek tahsisi ve paylaşılan bellek nesnesi oluşturmak için:

mach_vm_allocate();
xpc_shmem_create();

Uzak işlemde paylaşılan bellek nesnesi oluşturmak ve düzeltmek için:

malloc(); // for allocating memory remotely
thread_set_special_port(); // for inserting send right

Mach bağlantı noktalarının ve bellek giriş adlarının ayrıntılarını doğru bir şekilde ele alarak paylaşılan belleğin düzgün çalışmasını sağlamak önemlidir.

5. Tam Kontrol Elde Etme

Paylaşılan belleği başarıyla kurduktan ve keyfi yürütme yeteneklerini elde ettikten sonra, hedef süreç üzerinde tam kontrol elde etmiş oluruz. Bu kontrolü sağlayan temel işlevler şunlardır:

  1. Keyfi Bellek İşlemleri:

  • Paylaşılan bölgeden veri kopyalamak için memcpy() işlevini çağırarak keyfi bellek okumaları gerçekleştirin.

  • Paylaşılan bölgeye veri aktarmak için memcpy() kullanarak keyfi bellek yazmaları gerçekleştirin.

  1. Birden Fazla Argümanı Olan Fonksiyon Çağrılarını Yönetme:

  • 8'den fazla argüman gerektiren fonksiyonlar için, ek argümanları çağırma kuralına uygun olarak yığına yerleştirin.

  1. Mach Bağlantı Noktası Aktarımı:

  • Daha önceden kurulan bağlantı noktaları aracılığıyla Mach mesajları ile Mach bağlantı noktalarını görevler arasında aktarın.

  1. Dosya Tanımlayıcı Aktarımı:

  • Ian Beer tarafından triple_fetchte vurgulanan bir teknik olan dosya tanımlayıcılarını işlemler arasında aktarın.

Bu kapsamlı kontrol, hedef süreçle etkileşim için ayrıntılı bir uygulama ve kullanıcı dostu bir API sağlayan threadexec kütüphanesinde yer almaktadır.

Önemli Düşünceler:

  • Sistem kararlılığını ve veri bütünlüğünü korumak için bellek okuma/yazma işlemleri için memcpy() işlevini doğru bir şekilde kullanın.

  • Mach bağlantı noktalarını veya dosya tanımlayıcılarını aktarırken, sızıntıları veya istenmeyen erişimleri önlemek için uygun protokollere uyun ve kaynakları sorumlu bir şekilde yönetin.

Bu yönergeleri takip ederek ve threadexec kütüphanesini kullanarak, hedef süreç üzerinde tam kontrol sağlayarak süreçleri ayrıntılı bir şekilde yönetebilir ve etkileşimde bulunabilirsiniz.

Referanslar

AWS hacklemeyi sıfırdan kahraman olmak için htARTE (HackTricks AWS Red Team Expert) ile öğrenin!

HackTricks'i desteklemenin diğer yolları:

Last updated