İçeriğe atla
0 XP 0
12 dkderinleşmeyle 13 dk50 XP7 etkinlik

Sanal makine ve hata ayıklayıcı tespiti

Bu derste
  • Zararlı yazılımın sanal makine, kum havuzu ve hata ayıklayıcı kontrollerini tanır, laboratuvarda aşar ve rapora yazarsın.
  • Kontroller iki soruya iner: ortam sanal mı, süreç bir hata ayıklayıcının altında mı.
  • Bu derste bu kontrolleri tanımayı, aşmayı ve savunma tarafında tespit etmeyi öğrenirsin.

Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +50 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.

Analiz karşıtı kod bir soru sorar: burası gerçek bir kullanıcı makinesi mi? Yanıt hayırsa örnek kendini kapatır, zararsız bir iş yapar ya da uzun bir uyku başlatır. Sen de yanlış sonuç çıkarırsın ve dosyayı temiz sanırsın. Altay Kargo'nun güvenlik ekibine düşen şüpheli bir örneği düşün.

Örnek yalıtılmış bir makinede açıldığında hiçbir şey yapmıyor. Bu sessizlik çoğu zaman masumiyet değil, bir kontrolün tetiklenmesidir. Analiz karşıtı kodu tanımak, bu sessizliğin ardındaki kararı görmek demektir.

Triyajözet, türStatik analizdizgi, içe aktarımDinamik analizyalıtılmış VMKod analizitersineIOC ve raportespit kuralı
Analiz hattı: triyaj, statik, dinamik, kod ve rapor. Analiz karşıtı kod dinamik adımı hedefler.

Örnek seni nasıl fark eder

Sanal makine kontrolleri donanım izlerine bakar. Kayıt defterinde sanal sürücü adları aranır. Ağ arayüzünün adres ön eki sorgulanır. Çekirdek sayısı, bellek boyutu ve disk büyüklüğü ölçülür.

Mantık basittir: iki çekirdekli, dört gigabayt bellekli, kırk gigabayt diskli ve hiç belgesi olmayan bir makine gerçek kullanıcıya benzemez. Örnek bu izleri toplar ve bir karara varır. Laboratuvarı gerçekçi kurmak bu kontrolleri büyük ölçüde boşa çıkarır: diski büyütürsün, belge eklersin, çekirdek sayısını artırırsın.

Sanal makine izlerini tek tek görmek işini kolaylaştırır. Örnek kayıt defterinde sanal makine yazılımına ait sürücü ve servis adlarını arar. Ağ kartının adres ön ekini okur, çünkü sanal kartlar belirli üreticilere ayrılmış ön ekler taşır. Çalışan süreçler arasında misafir eklenti servislerini yoklar.

BIOS dizelerinde sanal üretici adını arar. İzlerin her biri ayrı bir kontroldür ve örnek çoğu zaman birkaçını birden sorar. Laboratuvarda bu adları ve servisleri gizlemek, kontrolleri topluca boşa çıkarır.

Bu kontrollerin ortak bir zayıflığı vardır: hepsi bir karşılaştırmaya dayanır. Örnek bir değer okur, bir eşikle ya da bilinen bir adla karşılaştırır ve sonuca göre dallanır. Analistin işi bu karşılaştırmayı bulmaktır.

Değeri değiştiremezsen bile, karşılaştırmadan sonraki atlamayı değiştirip örneği gerçek yoluna sokarsın. Bu yüzden analiz karşıtı kodu aşmak, uzun bir kontrol listesini ezberlemek değil, tek bir deseni tanımaktır: oku, karşılaştır, dallan. Deseni bir kez gördüğünde her yeni kontrolü aynı gözle çözersin.

Hata ayıklayıcı ayrı bir tehdit sayılır. İşletim sistemi buna hazır bir yöntem sunar. Windows'ta IsDebuggerPresent çağrısı, sürecin bir hata ayıklayıcı altında çalışıp çalışmadığını söyler. Çağrı, süreç ortam bloğundaki BeingDebugged bayrağını okur.

Dönüş değeri sıfırdan farklıysa süreç izleniyor demektir, sıfırsa izlenmiyor. Zararlı kod bu çağrıyı programın en başında yapar ve yanıt evetse hemen kapanır. Çağrı Kernel32.dll içinde durur ve tek satırda sonuç verir.

if (IsDebuggerPresent()) { ExitProcess(0); }

t1 = rdtsc();
islem();
t2 = rdtsc();
if (t2 - t1 > 0x100000) ExitProcess(0);
Bayrak kontrolü ve zamanlama kontrolü: ikisi de sessizce kapatır.

Etkinlik 1 / 7

Hata ayıklayıcı varlığını soran satırı bul.

Zafiyetli satıra tıkla.

İki aileyi birbirinden ayırmak ilk adımdır. Sanal makine kontrolleri dışarıya, donanıma bakar. Hata ayıklayıcı kontrolleri içeriye, sürecin kendi durumuna bakar. Bir örnekte çoğu zaman ikisi de bulunur.

Hangi kontrolün tetiklendiğini bilmek, hangi savunmayı kuracağını söyler. Donanım izini laboratuvarı zenginleştirerek silersin. Bayrak kontrolünü ise kesme noktasıyla aşarsın.

Etkinlik 2 / 7

Her kontrolü hedefine göre ayır.

Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.

0/5 seçenek yerleşti.

Zamanlama ve kum havuzu

Zamanlama kontrolü daha incedir. İşlemci sayacı iki noktada okunur ve fark ölçülür. Normal çalışmada iki okuma arası birkaç mikro saniyedir. Adım adım yürütürsen aradaki süre uzar, çünkü her komutta durup ilerlersin.

Eşik aşılınca program kapanır. Yukarıdaki kod bunu gösterir: rdtsc sayacı okur, işlem yapılır, sayaç yeniden okunur. Fark 0x100000 değerini geçerse örnek çıkar. Karşı hamle, bu karşılaştırmayı bulup atlamayı elle geçersiz kılmaktır.

Zamanlamayı ölçmenin tek yolu işlemci sayacı değildir. Örnek aynı amaçla sistem saatini de okuyabilir. İki okuma arasındaki fark beklenenden büyükse ortamın yavaş, yani izleniyor olduğuna karar verir.

Kimi örnek bir ağ isteği atıp yanıt süresini ölçer. Bu yüzden zamanlama kontrolü tek bir çağrıya bağlı değildir; farkı üreten her ölçüm aynı mantığı taşır. Karşı hamle hep aynıdır: kararı veren karşılaştırmayı bulup atlamayı değiştirmek.

Etkinlik 3 / 7

Bu kod analizde ne sonuç doğurur?

Önce kodu oku, sonra çıktıyı seç.

t1 = rdtsc();
islem();
t2 = rdtsc();
if (t2 - t1 > 0x100000) ExitProcess(0);

Kum havuzu ayrı bir başlıktır. Otomatik kum havuzu her örneğe kısa bir pencere ayırır.

Bir örnek bu pencereyi aşmak için uzun bir uyku başlatır. Kod ancak uyku bittikten sonra çalışır. O ana kadar kum havuzu gözlemini kapatmış olur ve rapor temiz görünür. Kimi örnek uykuyu küçük parçalara böler, kimi de dönüş değeri sahte hızlandırılan uyku çağrısını fark eder.

Kum havuzu başka izlere de bakar. Fare hareketi, açık pencere sayısı ve son kapanma zamanı sorgulanır. Hiç dokunulmamış bir makinede bu değerler tuhaf durur.

Kullanıcı etkileşimi bekleyen örnekler de vardır: kod ancak bir tuşa basıldıktan ya da bir belge kapatıldıktan sonra başlar. Otomatik analiz bu adımı atlar, elle yapılan analiz ise koşulu kolayca üretir.

Kum havuzunu aşan örneklerin ortak yanı sabırdır. Kod çalışmayı geciktirir, böylece otomatik gözlem penceresini boşa çıkarır. Analizde bekleme çağrılarını kısaltırsın.

Bir uyku çağrısına kesme noktası koyar, süreyi sıfıra indirir ve çalışmayı hızlandırırsın. Fare hareketini ve pencere sayısını sahte değerlerle beslersin. Gerçekçi bir ortam bu kontrollerin çoğunu daha ilk çalıştırmada susturur.

Etkinlik 4 / 7

Uzun Sleep çağrısı neden analiz karşıtı sayılır?

Kontrolleri laboratuvarda aşmak

Kontroller bazen zincirlenir. On beş ayrı soru sorulur ve her biri bir puan ekler. Toplam eşiği geçerse örnek durur. Tek tek aşmak yerine ortak karar noktasını bulmak daha verimlidir.

Çıkış çağrısına kesme noktası koyarsın. Program kapanmaya karar verdiği anda durursun ve yığını geri okursun. Hangi kontrolün tetiklediği böyle ortaya çıkar. Bir ailede bu deseni bir kez çözersen, sonraki örnekleri dakikalar içinde geçersin.

Tek bir kontrolü aşmak da benzer işler. Önce kontrolü bulursun. Sonra o çağrıya kesme noktası koyarsın.

Çağrı durduğunda dönüş değerini elle değiştirirsin: hata ayıklayıcı var diyen değeri yok diyene çevirirsin. Bekleme çağrısını da kısaltabilirsin. Her müdahaleyi rapora yazarsın, yoksa gözlemin doğallığı tartışmalı kalır. Bir araç dönüş değerini otomatik düzeltse bile, hangi kontrolün geçtiğini kayda geçirirsin.

Bir müdahaleyi belgelemek, onu yapmak kadar önemlidir. Hangi dönüş değerini değiştirdin, hangi uykuyu kısalttın, hangi bayrağı sıfırladın? Bunları yazmazsan, gözlediğin davranışın ne kadarının gerçek, ne kadarının müdahalenin sonucu olduğu belirsiz kalır.

Raporu okuyan ikinci analist senin adımlarını tekrarlayabilmeli. Belgeleme, analizin tekrarlanabilir ve savunulabilir olmasının tek yoludur.

$ gdb ./ornek
(gdb) break IsDebuggerPresent
Breakpoint 1 at 0x7ffff7a1c230
(gdb) run
Breakpoint 1, 0x00007ffff7a1c230 in IsDebuggerPresent ()
(gdb) finish
(gdb) set $rax = 0
(gdb) continue
Çağrı durur, dönüş değeri sıfırlanır, çalışma sürer. rax dönüş değerini taşır.

Bu adımı araçlar otomatikleştirir. x64dbg eklentileri bayrağı her çağrıda sıfırlar. x64dbg'nin HideDebugger komutu da süreç ortam bloğunu değiştirir, böylece IsDebuggerPresent her zaman yanlış döner.

ScyllaHide gibi bir eklenti aynı işi geniş bir kontrol listesi için yapar. Elle müdahale ile otomatik eklenti arasındaki fark hızdır; ikisi de aynı ilkeye dayanır: kontrolün yanıtını analist belirler.

Etkinlik 5 / 7

gdb içinde IsDebuggerPresent dönüşünü sıfıra çekmek için önce kesme noktası koy.

ogrenci@lab

Yorumlama, tespit ve savunma

Dil ve bölge kontrolleri de sık görülür. Bazı aileler belirli klavye düzenlerinde çalışmayı reddeder. Bu kontrol, yazarın kendi ülkesini dışarıda tutma çabası olarak okunur ve kaynağa dair ipucu verir. Tarih kontrolü de kullanılır: kod ancak belirli bir günden sonra çalışır.

Laboratuvar saatini ileri almak bu koşulu açar; değişikliği rapora yazarsın. Bu küçük izler tek başına kanıt değildir, ama örneği başka örneklerle ilişkilendirir.

Gerçek kurumlarda analiz ortamı bir kerelik kurulmaz. Ekip, analiz karşıtı kontrolleri yanıltan hazır bir sanal makine şablonu tutar: gerçekçi donanım değerleri, dolu bir belge klasörü, geçmiş tarama kayıtları ve kullanıcı izleri. Yeni bir örnek geldiğinde bu şablondan taze bir kopya açılır. Böylece her analiz aynı sağlam zeminde başlar ve kontrollerin çoğu daha ilk saniyede etkisiz kalır.

Kontrollerin varlığı tek başına suç kanıtı değildir. Lisans korumaları ve hile karşıtı çözümler de aynı yöntemleri kullanır. Bir oyunun hile karşıtı katmanı da hata ayıklayıcı arar.

Kontroller şüpheyi artırır, kararı davranış verir. Bu ayrım rapor yazarken de önemlidir: kontrolü bulman tek başına kötü niyet göstermez. Sonuç cümleni davranışa dayandırırsın, yalnız kontrolün varlığına değil.

Etkinlik 6 / 7

Doğru mu, yanlış mı?

Analiz karşıtı kontrollerin varlığı tek başına dosyanın zararlı olduğunu kanıtlar.

Tespit tarafına geçmek, analistin bakışını savunmaya çevirir. Bir örneğin hangi kontrolü kullandığını bilmek, aynı aileyi ağda ve uç noktada yakalamana yarar. Kontrol desenleri tespit kuralına dönüşür: art arda gelen sorgular, kısa aralıklı ölçümler ve beklenmedik bellek yazmaları işaretlenir. Böylece tek bir örneğin analizi, bütün filoyu koruyan bir kurala genişler.

Etkinlik 7 / 7

Bir uç nokta ürünü hata ayıklayıcı kaçınmasını nasıl tespit eder?

Derinleş:Süreç ortam bloğundaki iki bayrak

Hazır çağrıları atlayan örnekler süreç ortam bloğunu doğrudan okur. İki alan sık kullanılır. BeingDebugged bayrağı, bloğun başındaki üçüncü bayttır ve IsDebuggerPresent da onu okur; bu yüzden örnek hazır çağrıyı hiç kullanmadan, yalnız bu baytı okuyarak aynı sonuca ulaşır. NtGlobalFlag alanı ise bloğun ilerisinde durur ve bir hata ayıklayıcı altında başlatılan süreçte belirli bitleri açar, çünkü hata ayıklayıcı yığını farklı başlatır.

Üçüncü bir yol NtQueryInformationProcess çağrısıdır; ProcessDebugPort bilgisini sorar ve bir hata ayıklayıcı bağlıysa sıfırdan farklı değer döner. Dördüncü bir yol CheckRemoteDebuggerPresent çağrısıdır; o da aynı bilgiyi başka bir yoldan ister. Bu yolları bilmek, içe aktarma tablosunda hiç hata ayıklayıcı çağrısı görünmese bile kontrolü yığını okuyarak bulmanı getirir.

Derinleş:Linux tarafı: ptrace ve TracerPid

Linux'ta hata ayıklama ptrace sistem çağrısına dayanır. Bir sürece aynı anda tek hata ayıklayıcı bağlanabilir. Zararlı kod bundan yararlanır: kendi kendine ptrace ile bağlanmayı dener.

Çağrı başarılıysa başka bir hata ayıklayıcı yok demektir; başarısızsa süreç zaten izleniyordur ve kod kapanır. Aynı çağrı PTRACE_TRACEME isteğiyle yapılır ve kendini izlemeye alarak ikinci bir bağlanmayı baştan kapatır.

İkinci yöntem /proc/self/status dosyasını okumaktır. Dosyadaki TracerPid satırı sıfırsa süreç izlenmiyor, sıfırdan farklıysa izleyen sürecin kimliğini verir. Analizde bu dosyayı sahte sıfır dönecek biçimde kancalamak ya da ptrace çağrısını geçersiz kılmak kontrolü aşar. Savunma tarafı bu iki izi birlikte arar: kısa aralıkta gelen ptrace çağrısı ve status dosyasının okunması aynı niyete işaret eder.

Bu derste bir hata mı gördün? Bildir