Merhabalar Değerli Forum Üyeleri,
Blue olarak PoC tarafına da artık el atacağız, dolayısıyla bu konuyu hem üyelere bir örnek olması hem de teknik perspektif sunmak adına hazırlıyorum.
Poc nedir ne değildir, neden pocye ihtiyaç duyarız, security ortamlarında simülasyonlar yeterli değil mi, bunlara yönelik güvenlik ürünlerinde kural geliştirilemez mi vesaire gibi konuların DETAYLI cevaplarını ilerleyen konularda işleyeceğiz fakat buradan da yorum tarafında sorabilirsiniz tartışırız, sorularınıza cevap veririm. Zaten geliştirilen projeler bu sorularınıza gerekli cevap niteliğinde olacaktır, eğitim şeklinde de sizlere sunacağız yakında.

Konu "GitHub - andreisss/Remote-DLL-Injection-with-Timer-based-Shellcode-Execution: Remote DLL Injection with Timer-based Shellcode Execution" reposundan kaynaklanmaktadır. Yazılımcılar, güvenlikçiler, analistler yani endpointlerdeki güvenlik çözümleriyle uğraşan siber güvenlikçiler sistemleri tanıdıkça pocler çıkartıyor bizde bunları işleyeceğiz.
Repoda bizi aşağıdaki gibi bir alan karşılıyor:

Cpp kodlarını hiç yokmuş gibi varsayarak manuel exeyi tetikleyelim:

Target process belirtmiş bir tane, bu test ortamımda aktif çalışan bir process değil ek olarak TimerDll.dll dosyasını istiyor.
ConsoleApplication5.cpp(Bundan sonra cs5 olarak belirteceğim) dosyasını incelediğimizde bizi karşılayan alan:

Alınan 2 hatayı bu 2 satırda görebiliyoruz, targetPrcoess ve dllName değişkenleri.
1-) Target yani hedeflenen process (injection için temel şart) bende açık değil
2-) Burada dllmain.cpp vermiş, buna ek olarak verdiği dll ise cs5.cpp dosyasındaki dllName değişkeniyle eşleşmiyor
Madde 1 kolay madde 2 için ise neler yapabiliriz;
İlk olarak cs5.cpp deki dllName değişkenini değiştirebiliriz veya dllmain.cpp dosyasını compile ettiğimizde bu değişkene göre bir çıktı sağlayabiliriz yani TimerDll.dll
Veya hatasız hiçbir işimiz olmadığını düşünerek işi daha da çorba edip hem değişken adını değiştirip hem de yeniden bu değiştirdiğimiz değişken adına göre compile edebiliriz dllmain.cpp dosyasını.

İşi zor yoldan yapacağız, değişken adını injectdll.dll olarak değiştirdim, compile ederken de eşleşmesi için aynı naming convention kullanacağız.
cs5.cpp compile ettiğimizde hata alıyoruz neden?
C++ kodunuz std::wstring, wchar_t ve L"..." gibi Unicode (geniş karakter) türlerini kullanıyor. Ancak g++ (MinGW) derleyiciniz, varsayılan olarak Windows API fonksiyonlarını ANSI (char, LPCSTR yani normal karakter) sürümlerini kullanacak şekilde çağırıyor. (PoC denemek isteyenler olursa ortama göre değişecektir fakat aynı hataları alanlar konuyu takip edebilir.)


Hatanın devamı var ama bunlar hataya dair net indicatorlar.
Peki bu compile hataları ne:
Hata 1: processName (std::wstring) ile pe32.szExeFile (CHAR [260] yani char*) karşılaştırılamaz.
Hata2: GetModuleHandle fonksiyonuna L"kernel32.dll" (const wchar_t*) gönderiyor, ancak g++ bunu GetModuleHandleA (ANSI sürümü) olarak çağırıyor ve const char* bekliyor.
Çözüm:
Derleyiciye Unicode modunda çalışmasını söylememiz gerek. Bunu da, g++ komutuna bayrak/parametre ile yaparız: (Bu iki parametre eklendiğinde, koddakistd::wstring (wchar_t) türleri ile Windows API'lerinin beklediği wchar_t türleri birbiriyle eşleşecek ve kod başarıyla derlenecektir.)
g++ -o injectionpoc.exe ConsoleApplication5.cpp -D UNICODE -D _UNICODE (-o output için artık cs5 değil injectionpoc.exe üzerinden ilereleyeceğiz)

Bu şekilde compile etti ve mevcut klasörde artık gc5.exe değil injectionpoc.exe var.
Peki bu parametreler ne işe yarar?
-D UNICODE: Bu bayrak, windows.h başlık dosyasına bir direktif gönderir. Bu sayede GetProcessIdByName veya GetModuleHandle gibi fonksiyonlar otomatik olarak GetProcessIdByNameW ve GetModuleHandleW (sondaki W "Wide" yani Unicode anlamına gelir) olarak çağrılır. PROCESSENTRY32 yapısı da PROCESSENTRY32W olarak değişir ve szExeFile alanı char[260] yerine wchar_t[260] olur.
-D _UNICODE: Bu da C/C++ runtime kütüphaneleri için benzer bir ayar yapar.
Şimdi ise dllmain.cpp dosyasını derleyeceğiz:

#include "pch.h" satırı silinmeli veya // #include "pch.h" şeklinde yorum satırı yapılmalı.
Bu satır Visual Studio'ya özgü bir "ön derlenmiş başlık" dosyasıdır ve g++ bunu tanımadığı için hata verecektir ki resimde de hatalı olarak görüntüleyebiliyoruz.
Yorum satırına almayı tercih ediyorum ben.
Exe için açıklamadık fakat dll compile için parametreleri açıklayalım:
g++: Derleyiciyi çağırır.
-o injectdll.dll: Output adını belirler, burada TimerDll den kurtarıyoruz
dllmain.cpp: Derlenecek kaynak kod
-shared: Bu en önemli bayraktır. g++'a standart bir .exe yerine, paylaşılan bir kütüphane (Windows'ta .dll, Linux'ta .so) oluşturmasını söyler
-D UNICODE -D _UNICODE: Tıpkı .exe dosyasındaki gibi, dllmain.cpp içerisindeki fonksiyonların doğru çalışması için bu parametre gerekli

Mevcut klasörde injectdll.dll dosyasını da gördük (exe compile içerisinde de aynı adı vermiştik dllName değişkenine)
Kendi real-time process görüntüleyicimizi oluşturacak olursak (bu ayrı bir proje yalnızca varsayılan applere veya diğer yazılımlara bağlı kalmadan ilerlemek istiyoruz Blue olarak) bunu nasıl görüntüleyebiliriz.

Kendi processimizi (real-time process görüntüleyicimizde) görebiliyoruz.
Ek olarak explorer parent process den injection poc için gerekli (N)otepad.exe'yi görebiliyoruz yani bu şart karşılanıyor.
Ayrıca injectdll.dll ve injectionpoc.exe dosyalarının aynı klasörde olması gerekiyor (bu zorunluluk değil, kodda değişiklik yapıp path verip ona göre compile edebilirsiniz)
Tüm gereksinimler tamam PoC için çalışalım:

Resimdeki gibi exeyi tetiklediğimde hata veriyor, nedeni ise kendi real-time viewerimiz içerisinde de gördüğümüz gibi Notepad.exe process olarak küçük n ile başlıyor yani notepad.exe

Dolayısıyla yukarıdaki gibi olan değişkeni aşağıdaki gibi yapıp düzenliyoruz

Dolayısıyla yeni exemizi injectionpoc2.exe outputunda compile edip tekrardan çalıştırıyoruz:

Başarılı çalıştı, notepad.exe hala açık (3 saniye sonra kapanacak)

notepad processi kapandı

Calc.exe processi açıldı ve Temp altına timer_log.txt adında log dosyası yazıldı.
Peki poc başarılı çalışırsa bu yeterli mi hayır, EDR SIEM ürünleri üzerindeki aktivitelerini (ilk elden security ürünleri üzerinde poc yapamasak da Splunk (SIEM) sysmon loglarını topladığı için kendi sysmonumuz üzerinde bu pocnin detaylarına bi bakalım)
Log dosyasını da bırakıyorum incelemek isteyenler için: (TimerDll.dll olarak var bu kısmı değitirmeye gerek yok önemli olan buradaki dllin işlevsellik olarak injection olması)


UTC verisini, image yani process adını görüyoruz calc.exe ama bunun tree si önemli peki neden?
EDR yani bir işletim sistemindeki telemetri (reg kayıtları, file aktiviteleri, network bağlantıları vb.) verilerini (Windows EDR Telemetry Analysis) toplayan güvenlik ürünleri grafiksel anlamda processler ile ilgili bir process tree sunar, yani EDR ve XDR ürünleri.
Ne kadar calc.exe tetikleyen (shellcode vasıtasıyla) bir notepad.exe de olsa burada bunu bir analist inceleyeceği için zararlı senaryolarında second-stage payload veya sistemde çalıştırılmayı bekleyen bir exe tetiklenebilir. Bu yüzden amaç pocyi başarıyla çalıştırmak kadar EDR’ın process treesinde analisti aldatmak da olmalıdır.
Current directory mevcut klasörü belirtir bu yüzden işimize yaramaz, ek olarak calc.exe processinin company – product – desc üçlüsü legal yani process system32 altındaki LEGAL calc.exe.
IntegrityLevel ise medium yani administrator bir calc.exe değil peki integritylevel daki farklılıkları nasıl anlayacağız? Şu şekilde anlayacaksınız:

Basit bir şekilde tetiklenen powershell.exe 1 sysmon id si ile bize Medium Ilevel da görünür peki admin?

O ise Ilevel da High olarak karşımıza çıkar.
Poc dönecek olursak Ilevel Medium
Şimdi dönelim sysmon loguna:

Çalıştıran user winhost demekki mevcut kullanıcıdan geldi, sistemi tanıyor muyum evet winhost bilinen kullanıcı.
Burada 2 gap var, sistemde yetki elde eden bir saldırgan varsa yetkili başka bir kullanıcı açar W1NHOST olabilir çünkü evasion 1 - illüzyon yarat. İkincisi ise mevcut kullanıcı sistemde çalışan legal bir path üzerinden çalıştırıp normalmiş izlenimi verebilir.
İkisi için de farklı detection senaryoları üretilir.
Hashler var fakat manuel poclerdeki iocler normal ioclerden daha az ömürlüdür çünkü ransom binary veya stealer olmadığı için yani source-code attacker-dependent saldırgan bağımlı olduğu için kaynak koddaki çok basic (basic = boşluk karakteri) bir değişiklik hashi değiştirir fakat büyük executable dosyalarda ransom, stealer için yalnızca exeye sahibiz kaynak koda değil. Tehdit İstihbaratının devreye girdiği, ioc ömrü sunduğu alana basit bir örnek olarak da düşünebilirsiniz.


Buradaki boşluk karakteri compile etkiler oda hash, basic senaryo budur.

Ayrıca buradaki bir diğer ele veren nokta ise ParentCommandLine yani calc.exe process, notepad.exe parent process olduğu için tetiklenen txt dosyasının pathi önemli burada da çok açık bir şekilde …..Shellcode-Execution-main\pocdll.txt dosyasını görüyoruz.
Tüm senaryo başarılı olsa bile sistemde çalıştırdığınız parentcommandline ele verebilir ki burda bağırmış biz burdayız diye.
Tehdit Aktörlerinin avantajı bu adamlar bizden 3 adım önde fakat bizim de test ortamlarımız var, biraz hodri meydan gibi bir durum. PoCleri 1 adım, Tehdit İstihbaratını da 2. adım olarak düşünebiliriz.

Şekil a, bunun AD’de finans departmanında çalışan bir çalışanın bilgisayarından gelmesi ile farklı bir departmandan gelmesi bile farklıdır.
1-) Bu legal olduğu için txt üzerinden ilerleyemeyiz yalnızca bir bakış açısı sunar
2-) Parent cmdline .txt den calc.exe tetiklenmesi şüphelidir, CEO olsa farketmez inceleyeceksin

Blue olarak bu PoC'lerin devamı gelecektir, teknik anlamda boğulduysanız merak etmeyin yorumlar bunun için var veya özel mesaj yoluyla artık nasıl ulaşmak istiyorsanız. Repoyu verdim, hataların çözümünü de verdim, sysmon çıktısını da verdim. Bunlar güzel kaynak olacaktır sizin için. İyi forumlar dilerim Blue adına.
Blue olarak PoC tarafına da artık el atacağız, dolayısıyla bu konuyu hem üyelere bir örnek olması hem de teknik perspektif sunmak adına hazırlıyorum.
Poc nedir ne değildir, neden pocye ihtiyaç duyarız, security ortamlarında simülasyonlar yeterli değil mi, bunlara yönelik güvenlik ürünlerinde kural geliştirilemez mi vesaire gibi konuların DETAYLI cevaplarını ilerleyen konularda işleyeceğiz fakat buradan da yorum tarafında sorabilirsiniz tartışırız, sorularınıza cevap veririm. Zaten geliştirilen projeler bu sorularınıza gerekli cevap niteliğinde olacaktır, eğitim şeklinde de sizlere sunacağız yakında.

Konu "GitHub - andreisss/Remote-DLL-Injection-with-Timer-based-Shellcode-Execution: Remote DLL Injection with Timer-based Shellcode Execution" reposundan kaynaklanmaktadır. Yazılımcılar, güvenlikçiler, analistler yani endpointlerdeki güvenlik çözümleriyle uğraşan siber güvenlikçiler sistemleri tanıdıkça pocler çıkartıyor bizde bunları işleyeceğiz.
Repoda bizi aşağıdaki gibi bir alan karşılıyor:

Cpp kodlarını hiç yokmuş gibi varsayarak manuel exeyi tetikleyelim:

Target process belirtmiş bir tane, bu test ortamımda aktif çalışan bir process değil ek olarak TimerDll.dll dosyasını istiyor.

Alınan 2 hatayı bu 2 satırda görebiliyoruz, targetPrcoess ve dllName değişkenleri.
1-) Target yani hedeflenen process (injection için temel şart) bende açık değil
2-) Burada dllmain.cpp vermiş, buna ek olarak verdiği dll ise cs5.cpp dosyasındaki dllName değişkeniyle eşleşmiyor
İlk olarak cs5.cpp deki dllName değişkenini değiştirebiliriz veya dllmain.cpp dosyasını compile ettiğimizde bu değişkene göre bir çıktı sağlayabiliriz yani TimerDll.dll
Veya hatasız hiçbir işimiz olmadığını düşünerek işi daha da çorba edip hem değişken adını değiştirip hem de yeniden bu değiştirdiğimiz değişken adına göre compile edebiliriz dllmain.cpp dosyasını.

İşi zor yoldan yapacağız, değişken adını injectdll.dll olarak değiştirdim, compile ederken de eşleşmesi için aynı naming convention kullanacağız.
C++ kodunuz std::wstring, wchar_t ve L"..." gibi Unicode (geniş karakter) türlerini kullanıyor. Ancak g++ (MinGW) derleyiciniz, varsayılan olarak Windows API fonksiyonlarını ANSI (char, LPCSTR yani normal karakter) sürümlerini kullanacak şekilde çağırıyor. (PoC denemek isteyenler olursa ortama göre değişecektir fakat aynı hataları alanlar konuyu takip edebilir.)


Hatanın devamı var ama bunlar hataya dair net indicatorlar.
Hata 1: processName (std::wstring) ile pe32.szExeFile (CHAR [260] yani char*) karşılaştırılamaz.
Hata2: GetModuleHandle fonksiyonuna L"kernel32.dll" (const wchar_t*) gönderiyor, ancak g++ bunu GetModuleHandleA (ANSI sürümü) olarak çağırıyor ve const char* bekliyor.
Çözüm:
Derleyiciye Unicode modunda çalışmasını söylememiz gerek. Bunu da, g++ komutuna bayrak/parametre ile yaparız: (Bu iki parametre eklendiğinde, koddakistd::wstring (wchar_t) türleri ile Windows API'lerinin beklediği wchar_t türleri birbiriyle eşleşecek ve kod başarıyla derlenecektir.)
g++ -o injectionpoc.exe ConsoleApplication5.cpp -D UNICODE -D _UNICODE (-o output için artık cs5 değil injectionpoc.exe üzerinden ilereleyeceğiz)

Bu şekilde compile etti ve mevcut klasörde artık gc5.exe değil injectionpoc.exe var.
-D UNICODE: Bu bayrak, windows.h başlık dosyasına bir direktif gönderir. Bu sayede GetProcessIdByName veya GetModuleHandle gibi fonksiyonlar otomatik olarak GetProcessIdByNameW ve GetModuleHandleW (sondaki W "Wide" yani Unicode anlamına gelir) olarak çağrılır. PROCESSENTRY32 yapısı da PROCESSENTRY32W olarak değişir ve szExeFile alanı char[260] yerine wchar_t[260] olur.
-D _UNICODE: Bu da C/C++ runtime kütüphaneleri için benzer bir ayar yapar.

#include "pch.h" satırı silinmeli veya // #include "pch.h" şeklinde yorum satırı yapılmalı.
Bu satır Visual Studio'ya özgü bir "ön derlenmiş başlık" dosyasıdır ve g++ bunu tanımadığı için hata verecektir ki resimde de hatalı olarak görüntüleyebiliyoruz.
Yorum satırına almayı tercih ediyorum ben.
g++: Derleyiciyi çağırır.
-o injectdll.dll: Output adını belirler, burada TimerDll den kurtarıyoruz
dllmain.cpp: Derlenecek kaynak kod
-shared: Bu en önemli bayraktır. g++'a standart bir .exe yerine, paylaşılan bir kütüphane (Windows'ta .dll, Linux'ta .so) oluşturmasını söyler
-D UNICODE -D _UNICODE: Tıpkı .exe dosyasındaki gibi, dllmain.cpp içerisindeki fonksiyonların doğru çalışması için bu parametre gerekli

Mevcut klasörde injectdll.dll dosyasını da gördük (exe compile içerisinde de aynı adı vermiştik dllName değişkenine)
Kendi real-time process görüntüleyicimizi oluşturacak olursak (bu ayrı bir proje yalnızca varsayılan applere veya diğer yazılımlara bağlı kalmadan ilerlemek istiyoruz Blue olarak) bunu nasıl görüntüleyebiliriz.

Kendi processimizi (real-time process görüntüleyicimizde) görebiliyoruz.
Ek olarak explorer parent process den injection poc için gerekli (N)otepad.exe'yi görebiliyoruz yani bu şart karşılanıyor.
Tüm gereksinimler tamam PoC için çalışalım:

Resimdeki gibi exeyi tetiklediğimde hata veriyor, nedeni ise kendi real-time viewerimiz içerisinde de gördüğümüz gibi Notepad.exe process olarak küçük n ile başlıyor yani notepad.exe

Dolayısıyla yukarıdaki gibi olan değişkeni aşağıdaki gibi yapıp düzenliyoruz


Başarılı çalıştı, notepad.exe hala açık (3 saniye sonra kapanacak)

notepad processi kapandı

Calc.exe processi açıldı ve Temp altına timer_log.txt adında log dosyası yazıldı.
Peki poc başarılı çalışırsa bu yeterli mi hayır, EDR SIEM ürünleri üzerindeki aktivitelerini (ilk elden security ürünleri üzerinde poc yapamasak da Splunk (SIEM) sysmon loglarını topladığı için kendi sysmonumuz üzerinde bu pocnin detaylarına bi bakalım)
Log dosyasını da bırakıyorum incelemek isteyenler için: (TimerDll.dll olarak var bu kısmı değitirmeye gerek yok önemli olan buradaki dllin işlevsellik olarak injection olması)


UTC verisini, image yani process adını görüyoruz calc.exe ama bunun tree si önemli peki neden?
Ne kadar calc.exe tetikleyen (shellcode vasıtasıyla) bir notepad.exe de olsa burada bunu bir analist inceleyeceği için zararlı senaryolarında second-stage payload veya sistemde çalıştırılmayı bekleyen bir exe tetiklenebilir. Bu yüzden amaç pocyi başarıyla çalıştırmak kadar EDR’ın process treesinde analisti aldatmak da olmalıdır.
Current directory mevcut klasörü belirtir bu yüzden işimize yaramaz, ek olarak calc.exe processinin company – product – desc üçlüsü legal yani process system32 altındaki LEGAL calc.exe.

Basit bir şekilde tetiklenen powershell.exe 1 sysmon id si ile bize Medium Ilevel da görünür peki admin?

O ise Ilevel da High olarak karşımıza çıkar.
Poc dönecek olursak Ilevel Medium
Şimdi dönelim sysmon loguna:

Çalıştıran user winhost demekki mevcut kullanıcıdan geldi, sistemi tanıyor muyum evet winhost bilinen kullanıcı.
İkisi için de farklı detection senaryoları üretilir.
Hashler var fakat manuel poclerdeki iocler normal ioclerden daha az ömürlüdür çünkü ransom binary veya stealer olmadığı için yani source-code attacker-dependent saldırgan bağımlı olduğu için kaynak koddaki çok basic (basic = boşluk karakteri) bir değişiklik hashi değiştirir fakat büyük executable dosyalarda ransom, stealer için yalnızca exeye sahibiz kaynak koda değil. Tehdit İstihbaratının devreye girdiği, ioc ömrü sunduğu alana basit bir örnek olarak da düşünebilirsiniz.


Buradaki boşluk karakteri compile etkiler oda hash, basic senaryo budur.

Ayrıca buradaki bir diğer ele veren nokta ise ParentCommandLine yani calc.exe process, notepad.exe parent process olduğu için tetiklenen txt dosyasının pathi önemli burada da çok açık bir şekilde …..Shellcode-Execution-main\pocdll.txt dosyasını görüyoruz.
Tüm senaryo başarılı olsa bile sistemde çalıştırdığınız parentcommandline ele verebilir ki burda bağırmış biz burdayız diye.
Tehdit Aktörlerinin avantajı bu adamlar bizden 3 adım önde fakat bizim de test ortamlarımız var, biraz hodri meydan gibi bir durum. PoCleri 1 adım, Tehdit İstihbaratını da 2. adım olarak düşünebiliriz.

Şekil a, bunun AD’de finans departmanında çalışan bir çalışanın bilgisayarından gelmesi ile farklı bir departmandan gelmesi bile farklıdır.
1-) Bu legal olduğu için txt üzerinden ilerleyemeyiz yalnızca bir bakış açısı sunar
2-) Parent cmdline .txt den calc.exe tetiklenmesi şüphelidir, CEO olsa farketmez inceleyeceksin

Blue olarak bu PoC'lerin devamı gelecektir, teknik anlamda boğulduysanız merak etmeyin yorumlar bunun için var veya özel mesaj yoluyla artık nasıl ulaşmak istiyorsanız. Repoyu verdim, hataların çözümünü de verdim, sysmon çıktısını da verdim. Bunlar güzel kaynak olacaktır sizin için. İyi forumlar dilerim Blue adına.





