APT Gruplarının Davranış Parmak İzi Çıkarma
APT davranış parmak izi çıkarmak için bilinen aktör TTP'leri vektörleştirilerek imza profili oluşturulur. STIX2 verisi ve cosine similarity ile aktör tanımlama: import requests import pandas as pd import numpy as np from sklearn.preprocessing import MultiLabelBinarizer from sklearn.metrics.pairwise import cosine_similarity url = 'https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json' actor_profiles = {} for obj in data['objects']: if obj['type'] == 'intrusion-set': actor_name = obj.get('name','') aliases = obj.get('aliases', []) ttps = [] for rel in data['objects']: if (rel['type'] == 'relationship' and rel['relationship_type'] == 'uses' and rel['source_ref'] == obj['id']): target = next((o for o in data['objects'] if o.get('id') == rel['target_ref']),None) if target and target['type'] == 'attack-pattern': ext_id = target['external_references'][0].get('external_id','') if ext_id: ttps.append(ext_id) if ttps: actors = list(actor_profiles.keys()) print(f'Aktör sayısı: {len(actors)}, TTP boyutu: {len(mlb.classes_)}')
Giris ve Temel Akis
APT davranış parmak izi çıkarmak için bilinen aktör TTP'leri vektörleştirilerek imza profili oluşturulur. STIX2 verisi ve cosine similarity ile aktör tanımlama: import requests import pandas as pd import numpy as np from sklearn.preprocessing import MultiLabelBinarizer from sklearn.metrics.pairwise import cosine_similarity url = 'https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json' actor_profiles = {} for obj in data['objects']: if obj['type'] == 'intrusion-set': actor_name = obj.get('name','') aliases = obj.get('aliases', []) ttps = [] for rel in data['objects']: if (rel['type'] == 'relationship' and rel['relationship_type'] == 'uses' and rel['source_ref'] == obj['id']): target = next((o for o in data['objects'] if o.get('id') == rel['target_ref']),None) if target and target['type'] == 'attack-pattern': ext_id = target['external_references'][0].get('external_id','') if ext_id: ttps.append(ext_id) if ttps: actors = list(actor_profiles.keys()) print(f'Aktör sayısı: {len(actors)}, TTP boyutu: {len(mlb.classes_)}')
Bu bölümün pratik akışı şu sırayla ilerler:
- data = requests.get(url).json()
- for obj in data['objects']: if obj['type']=='intrusion-set': actor_name=obj.get('name','')
- for rel in data['objects']: if rel['type']=='relationship' and rel['source_ref']==obj['id']: ttps.append(ext_id)
- actor_profiles[actor_name] = ttps
- mlb = MultiLabelBinarizer()
- X = mlb.fit_transform(actor_profiles.values())
- df_profiles = pd.DataFrame(X, index=actors, columns=mlb.classes_)
- print(f'Aktör sayısı: {len(actors)}')
Temel Kavram Eslesmeleri
APT davranış parmak izi çıkarmada farklı analitik boyutlar kullanılır. Her boyut aktörü farklı bir perspektiften tanımlar. Örnek APT29 parmak izi boyutları: - TTP seti: T1566.002, T1059.001, T1003.001, T1021.002 - Araç seti: Cobalt Strike, Mimikatz, BloodHound - C2 profili: HTTPS beaconing, 300s interval, low jitter - Hedef sektör: government, think tanks, healthcare - Coğrafya: Rusya kaynaklı, Batı hedefli
- TTP seti: Saldırı metodolojisi — en dayanıklı parmak izi
- Araç seti: Kullanılan yazılımlar — orta dayanıklı
- C2 profili: İletişim kalıbı — JA3 ve beaconing interval
- Hedef sektör: Motivasyon ve kampanya odağı — attribution yardımcı
Ilk Cekirdek Kavram
Bu bölümde öne çıkan çekirdek kavram coverage_pct olarak verilir. Ortamda tespit edilen TTP seti ile bilinen APT profilleri karşılaştırılarak attribution skoru hesaplanır: import pandas as pd import numpy as np from sklearn.metrics.pairwise import cosine_similarity detected_ttps = [ 'T1059.001','T1003.001','T1021.002','T1547.001', 'T1566.002','T1071.001','T1055','T1027' ] detected_vec = mlb.transform([detected_ttps]) attribution_scores = cosine_similarity(detected_vec, X)[0] results = pd.DataFrame({ 'actor': actors, 'similarity': attribution_scores, 'shared_ttps': [len(set(detected_ttps) & set(actor_profiles[a])) for a in actors], 'total_actor_ttps': [len(actor_profiles[a]) for a in actors] }).sort_values('similarity', ascending=False) results['coverage_pct'] = results['shared_ttps'] / len(detected_ttps) * 100 print('Top 5 attribution kandidatı:') print(results[['actor','similarity','shared_ttps','coverage_pct']].head())
Arac, Komut veya Inceleme Akisi
Cobalt Strike C2 trafik parmak izi çıkarma. Malleable C2 profil özelliklerini ağ verisinden tanımlama: import pandas as pd import numpy as np from scipy.stats import entropy df_tls = pd.read_parquet('tls_logs.parquet') known_cs_ja3 = { '72a589da586844d7f0818ce684948eea': 'CS_default', 'a0e9f5d64349fb13191bc781f81f42e1': 'CS_custom1', '6734f37431670b3ab4292b8f60f29984': 'CS_malleable' } beacon_profiles = df_tls.groupby('src_ip').agg( mean_interval=('time_delta','mean'), std_interval=('time_delta','std'), jitter_ratio=('time_delta', lambda x: x.std()/(x.mean()+1)), mean_bytes=('bytes','mean'), std_bytes=('bytes','std'), unique_ja3=('ja3_hash','nunique'), dominant_ja3=('ja3_hash', lambda x: x.mode()[0] if len(x)>0 else ''), uri_entropy=('uri', lambda x: entropy([x.tolist().count(u)/len(x) for u in set(x)])), conn_count=('bytes','count') ).reset_index() beacon_profiles['beacon_score'] = ( (beacon_profiles['jitter_ratio'] < 0.15).astype(int) * 40 + (beacon_profiles['conn_count'] > 100).astype(int) * 30 + (beacon_profiles['is_known_cs']).astype(int) * 30 )
Bu bölümün pratik akışı şu sırayla ilerler:
- beacon_profiles = df_tls.groupby('src_ip').agg(mean_interval=('time_delta','mean'), jitter_ratio=('time_delta',lambda x: x.std()/(x.mean()+1)), dominant_ja3=('ja3_hash',lambda x: x.mode()[0])).reset_index()
- beacon_profiles['is_known_cs'] = beacon_profiles['dominant_ja3'].isin(known_cs_ja3.keys())
- beacon_profiles['cs_variant'] = beacon_profiles['dominant_ja3'].map(known_cs_ja3).fillna('unknown')
- beacon_profiles['beacon_score'] = ((beacon_profiles['jitter_ratio']<0.15).astype(int)*40 + (beacon_profiles['conn_count']>100).astype(int)*30 + (beacon_profiles['is_known_cs']).astype(int)*30)
- cs_candidates = beacon_profiles[beacon_profiles['beacon_score'] >= 70]
- print(f'Cobalt Strike C2 adayı: {len(cs_candidates)}')
- print(cs_candidates[['src_ip','jitter_ratio','cs_variant','beacon_score']].head())
Kanit ve Bilesen Iliskileri
Bilinen APT gruplarının ayırt edici TTP kombinasyonları attribution sürecinde rehber nitelik taşır. Bu kombinasyonlar tehdit aktörüne özel davranış imzasını oluşturur. Örnek ayırt edici TTP'ler: - APT29: T1566.002 + T1059.001 encoded + T1021.002 + SUNBURST - APT28: T1566.001 + T1203 + T1055 + X-Agent toolset - Lazarus: T1486 ransomware + T1059.001 + crypto mining - FIN7: T1566.001 phishing + T1059.007 JS + T1041 exfil
- APT29 (Cozy Bear): Supply chain + encoded PowerShell + SUNBURST implant
- APT28 (Fancy Bear): Spear phishing + exploit + X-Agent RAT
- Lazarus Group: Ransomware + crypto mining + destructive wiper
- FIN7: JS tabanlı phishing + POS malware + finansal exfil
Ikincil Odak Noktasi
Bu bölümde öne çıkan çekirdek kavram multivalue olarak verilir. Splunk ile APT parmak izi korelasyon sorgusu. Ortamda tespit edilen TTP kombinasyonunu bilinen aktör profiliyle eşleştirme: index=sysmon OR index=wineventlog earliest=-7d | eval ttp=case( match(CommandLine,"-[Ee][Nn][Cc]") AND match(ParentImage,"winword|excel"), "T1059.001+T1566", match(TargetImage,"lsass") AND match(SourceImage,"mimikatz"), "T1003.001", match(CommandLine,"net.*use.*445") AND Logon_Type=3, "T1021.002", match(CommandLine,"schtasks.*create"), "T1053.005", match(CommandLine,"reg.*add.*Run"), "T1547.001", true(), null() ) | where isnotnull(ttp) | stats values(ttp) as detected_ttps, dc(hostname) as hosts, dc(user) as users by src_ip | eval apt29_match=mvcount(mvfilter(match(detected_ttps,"T1059.001|T1003.001|T1021.002|T1547.001"))) | eval apt28_match=mvcount(mvfilter(match(detected_ttps,"T1059.001|T1003.001|T1055|T1566"))) | eval lazarus_match=mvcount(mvfilter(match(detected_ttps,"T1486|T1059.001|T1041"))) | eval attribution=case( apt29_match>=3, "APT29", apt28_match>=3, "APT28", lazarus_match>=2, "Lazarus", true(), "UNKNOWN" ) | where attribution!="UNKNOWN" | table src_ip, detected_ttps, apt29_match, apt28_match, attribution, hosts | sort -apt29_match
Operasyonel Dogrulama ve Raporlama
Volatility ile bellek forensics analizi yaparak APT araç imzası tespit etme. Process injection ve hollowing parmak izi: import subprocess import json import pandas as pd def run_volatility(image_path, plugin, profile='Win10x64_19041'): cmd = [ 'python', 'vol.py', '-f', image_path, '--profile', profile, plugin, '--output=json' ] result = subprocess.run(cmd, capture_output=True, text=True) try: return json.loads(result.stdout) except: return {} def extract_apt_memory_iob(image_path): findings = [] psscan = run_volatility(image_path, 'psscan') malfind = run_volatility(image_path, 'malfind') netscan = run_volatility(image_path, 'netscan') if 'rows' in malfind: for row in malfind['rows']: if 'MZ' in str(row.get('Hexdump','')): findings.append({ 'type': 'process_injection', 'pid': row.get('Pid'), 'process': row.get('Process'), 'address': row.get('VadAddress'), 'iob': 'PE_in_non_image_memory' }) hollow_procs = [] if 'rows' in psscan: for proc in psscan['rows']: if proc.get('ExitTime') and not proc.get('PPID'): hollow_procs.append({'type':'orphan_process','process':proc.get('Name'),'pid':proc.get('PID')}) return pd.DataFrame(findings + hollow_procs) df_memory_iob = extract_apt_memory_iob('memory.raw') print(df_memory_iob.groupby('type').size())
Bu bölümün pratik akışı şu sırayla ilerler:
- malfind
Cikti ve Kullanım Amaci
APT attribution sürecinde dikkat edilmesi gereken tuzaklar analiz güvenilirliğini etkiler. False flag ve attribution bias en yaygın hatalar arasındadır. Örnek attribution tuzakları: - False flag: saldırgan kasıtlı olarak başka aktör TTP'si kullanır - TTP overlap: birden fazla aktör aynı araçları kullanabilir - Shared infrastructure: farklı aktörler aynı bulletproof hosting kullanır - Attribution bias: önceki analizin yeni vakaları etkilemesi
- False flag: Tek TTP yerine çok boyutlu parmak izi gerektir
- TTP overlap: Araç + altyapı + hedef sektör kombinasyonu kullan
- Attribution bias: Alternatif aktör hipotezlerini sistematik olarak test et
- Shared infrastructure: IP yerine TTP ve davranış bazlı tespit önceliklendir
Son Kavram ve Cikis
Bu bölümde öne çıkan çekirdek kavram campaigns_against olarak verilir. APT kampanya takibi için Diamond Model analizi uygulanır. Düşman, altyapı, kapasite ve kurban arasındaki ilişkiler haritalanır: import networkx as nx import pandas as pd G = nx.DiGraph() campaign_data = [ {'adversary':'APT29','infrastructure':'185.220.101.50','capability':'Cobalt_Strike','victim':'MFA_GOV'}, {'adversary':'APT29','infrastructure':'185.220.101.50','capability':'Mimikatz','victim':'MFA_GOV'}, {'adversary':'APT29','infrastructure':'91.219.236.14','capability':'SUNBURST','victim':'IT_VENDOR'}, {'adversary':'APT29','infrastructure':'91.219.236.14','capability':'Cobalt_Strike','victim':'THINK_TANK'} ] for item in campaign_data: G.add_edge(item['adversary'], item['infrastructure'], relation='uses') G.add_edge(item['infrastructure'], item['capability'], relation='delivers') G.add_edge(item['capability'], item['victim'], relation='targets') G.add_edge(item['adversary'], item['victim'], relation='campaigns_against') print(f'Diamond Model düğüm: {G.number_of_nodes()}') print(f'Diamond Model kenar: {G.number_of_edges()}') shared_infra = [n for n in G.nodes() if G.out_degree(n)>2 and G.in_degree(n)>0] print(f'Paylaşılan altyapı: {shared_infra}') victims = [n for n in G.nodes() if G.out_degree(n)==0] print(f'Tespit edilen kurbanlar: {victims}')
Bu Egitimden Ne Kazanirsiniz?
Bu icerik, APT Gruplarının Davranış Parmak İzi Çıkarma konusunu SOC L3 - İleri Tehdit Avcılığı - Veri Madenciliği ve Modelleme baglaminda parcali degil, butunlu bir ogrenme akisina donusturur. Yalnizca kavramlari ezberlemek yerine surec sirasini, bilesenler arasi iliskiyi ve hangi kanitin neden onemli oldugunu kavramayi hedefler.
Ozet
Bu ders kapsaminda one cikan basliklar: TTP seti, Araç seti, C2 profili, Hedef sektör, APT29 (Cozy Bear), APT28 (Fancy Bear), Lazarus Group, FIN7, False flag, TTP overlap. Egitimin mantigi; once temel akis kurmak, sonra eslestirme ve kavram netlestirme yapmak, en sonda ise bulguyu operasyonel bir sonuca baglamaktir.