20.07.2024

Crowdstrike strikes back

Dün, 19 Temmuz 2024, bir çok firma için bir siber felaket gibiydi. Havayolları, bankalar, hastaneler, büyük basın kuruluşları... Hepsi ya hizmet veremediler, ya da kesintiler yaşadılar. Uçak seferleri durdu, ameliyatlar iptal edildi, TV yayınları durdu. Herkes dünya çapında mavi ekran yaşayan Windows'ları görünce Microsoft kaynaklı olduğunu düşündü. Ama bugünkü suçlumuz Crowdstrike.

Bütün internet bu konu ile ilgili haberlerler dolu [1],[2]. Önemli konu şu ki, bu ne ilk ne de son olacak. Daha önce bu olayın benzerini benim hatırladığım McAfee ve Avira ile de yaşamıştık. Bilişim dünyası bu gibi olaylara hazır değil mi acaba? Bu gibi olaylara hazır olunabilir mi? Güncellemelerin önce küçük bir grup üzerinde denenmesi ve sorun yaşanmaması sonrasında diğer sistemlere uygulanabilmesi yeni kavramlar değil, ama bunların bir uzman tarafından her gün yapılması çok pratik değil. Belki bunları önümüzdeki günlerde otomatik olarak yapan sistemler tasarlanabilir. Aynı şey işletim sistemi güncellemeleri (Windows, Linux, vs) için de gerekli. Ama güncellemeleri kapatmak hiç bir zaman çözüm olarak düşünülmemeli.

---

[1] https://www.bbc.com/news/articles/cp4wnrxqlewo
[2] https://edition.cnn.com/2024/07/19/tech/crowdstrike-update-global-outage-explainer/index.html

19.07.2024

Get-ChildItem ve -Exclude parametresi

Bazen bir dosya aramak için -Path, -Recurse, -Include parametrelerini kullanmak yetmez, bir de -Exclude kullanmak gerekir. Örneğin Windows klasörünün altında sysdm.cpl dosyasını arıyorum, ama WinSxS klasörünün altındaki kopya(lar|s)ını listelemek istemiyorum. O amaçla aşağıdaki komutlardan herhangi birini kullandığımda hiç sonuca ulaşamıyorum.

Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -Exlude "C:\Windows\WinSxS"
Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -Exlude "C:\Windows\WinSxS*"
Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -Exlude "*WinSxS*"

Çünkü, Exclude parametresi bunun için tasarlanmamış. Sadece dosya isimlerinde bir kıyaslama yapabiliyor. Aynı -Include'da olduğu gibi. Alternatif çözümler mevcut. Örneğin

Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse | where-Object {$_.FullName -notlike "*WinSxS*"}

Ama bu şekilde aslında Get-ChildItem bütün WinSxS alt klasörünü tarıyor, ama çıkan sonuçarın içinde WinSxS geçiyorsa bunlar ekrana yazılmıyor. Bu istediğim birşey değil, ama daha iyisini bulamadım.

Windows klasörünün altında bazı yüksek güvenlikli alt klasörler olduğu için ekranın kırmızı hata mesajları ile dolmasını engellemek için -ErrorAction SilentlyContinue (veya kısaca -EA silent) kullanılabilir.

Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -ErrorAction SilentlyContinue | 
where-Object {$_.FullName -notlike "*WinSxS*"}

Bunu uzun bulanlar için (ki ben de buluyorum) alias'lar ve kısaltmalar var

dir C:\Windows -Inc sysdm.cpl -Rec -EA silent | ? {$_.FullName -notlike "*WinSxS*"}

18.07.2024

WinSxS, sfc ve dism

Uzun dönem Windows kullanıcıları, sistem klasörlerinin (genellikle C:\Windows) altında WinSxS adında bir klasörün olduğunu görmüşlerdir. Bu klasör korunan ve içeriği administrator ile bile değiştirilemeyen bir yapıya sahiptir. Kurulumdaki bütün sistem dosyalarının asılları bu klasörün altındadır. Kullanımdaki kopyası ise aslında bir kopya değil, dosyanın aslına bir harlink'tir. Örnek olarak explorer.exe'ye bakalım.

C:\> dir explorer.exe | fl FullName, LinkType, Target

FullName : C:\Windows\explorer.exe
LinkType : HardLink
Target   : {C:\Windows\WinSxS\amd64_microsoft-windows-explorer...

Bu klasördeki bütün dosyaları görmek için

dir * -file | ft Name, LinkType

kullanabiliriz. Evet, bu güvenlik önlemlerine karşı kötü niyetli yazılımların da karşı yöntemleri var. Herşeye rağmen hardlink bozulabilir, sistem dosyası kötü bir kopya ile değiştirilebilr. Hatta WinSxS klasörü altındaki dosya bile değiştirilebilir. Sistemimizde beklenmeyen bir durum olduğunda her kaynakta ilk yapılması gereken

sfc /scannow

olarak önerilmiş. Arka planda bu komut, sistem dosyalarını tarar, bütünlüğünü, denetler ve güvenilir bir katalogdaki özelliklere (imza, hash vs) sahip olup olmadığını kontrol eder. Ayrıca hardlink'inin doğru olup olmadığına da bakar. Sonra eğer burada bir sorun algılarsa WinSxS altındaki doğru dosyaya olan hardlink'i tekrar oluşturarak onarmaya çalışır. WinSxS altında bir dosyanın birden fazla sürümü olabilir. Bütün sürümler yinw WinSxS klasöründe saklanır. O yüzden en son güncelleme ile gelen sürüme hardlink oluşturulması önemli.

WinSxS klasöründe bir bozulma olmuşsa sfc bu aşamada yetersiz kalır. Bu bozulmayı onarmak için kullanılacak araç dism. Dism'in kafa karıştıran 3 farklı komutu var:

  • CheckHealth
  • ScanHealth
  • RestoreHealth

Bu 3 komutu, bir disk taramasındaki işlemlere benzeterek açıklamaya çalışacağım.

Diskimizde bir sorun olduğunu anlamak için bir tarama yapmak istiyoruz. Ama hızlı olmasını istiyoruz. Bütün diski taramak çok zaman ve enerji alan bir işlem. Aslında diskte işlem yaparken hata ile karşılaşan bir program var mı diye baksak olmaz mı? Bunun için önce evenlog'a bakıyoruz, herhangi bir program buraya disk ile ilgili hata olayı yazmış mı diye. Bu CheckHealth'a karşılık gelen bir işlem. Bütün WinSxS klasöründeki dosyaları taramak da çok zaman ve enerji alan bir işlem olduğu için kaydı düşülen bir sorun var mı, ona bakıyoruz. Bu işlemde bir düzeltme işlemi uygulanmıyor. Örnek kullanım:

DISM /Online /Cleanup-Image /CheckHealth

İkinci komut ScanHealth, daha çok diskte bir düzeltme işlemi yapmadan taramaya benziyor. Sistem açıkken diskte onarım yapmak istemiyorsak, sadece hata var mı yok mu bize onu söylesin diyorsak bu işlem uygulanabilir. Yine bu adımda da diskte bir düzeltme yapılmayacak. Örnek kullanım:

DISM /Online /Cleanup-Image /ScanHealth

Üçüncü komut RestoreHealth ise aktif olarak diskte hataları bul ve düzelt komutu gibi. Bütün WinSxS klasörü taranır, bulunan hatalar (ISO dosyasından veya internetten) bozulmamış kopyalar kullanılarak düzeltilir. Örnek kullanım:

DISM /Online /Cleanup-Image /RestoreHealth

Dism, bunun yanı sıra açık olan Windows kurulumu üzerinde de işlem yapabilir, DVD veya USB'den boot edilerek disklerden birindeki kurulum üzerinde de çalışabilir. /ONLINE anahtarı şu an çalışan sistem üzerinde işlem yapılmasını söylüyor.

Dism'in bunun dışında çok güzel kullanımları var. Örneğin WinSxS klasörümüzün boyutu çok büyüdüyse ve eski  sürümlere ait dosyaları silmek istersek (kesinlikle elle yapılmaması gereken bir işlem) aşağıdaki komut kullanılabilir.

Önce mevcut WinSxS (component store - Windows Side-by-side) boyutunu kontrol edelim:

C:\> dism /online /cleanup-image /analyzecomponentstore

Deployment Image Servicing and Management tool
Version: 10.0.22621.2792

Image Version: 10.0.22631.3880

[===========================99.6%========================= ]

Component Store (WinSxS) information:

Windows Explorer Reported Size of Component Store : 14.29 GB

Actual Size of Component Store : 13.35 GB

    Shared with Windows : 7.30 GB
    Backups and Disabled Features : 6.05 GB
    Cache and Temporary Data :  0 bytes

Date of Last Cleanup : 2024-07-15 12:24:43

Number of Reclaimable Packages : 3
Component Store Cleanup Recommended : Yes

The operation completed successfully.

Eski ve kullanılmayan (superseded) sürümleri silelim

Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase

Bu komut sonrasında da kurulmuş güncellemerin kaldırılması imkansız hale gelir. Görece daha "hafif" bir temizlik için /ResetBase olmadan kullanabiliriz.

Bir service pack ile eski duruma düşmüş dosyaları silmek için (service pack'in kaldırılmasını imkansız hale getirir)

Dism.exe /online /Cleanup-Image /SPSuperseded

dism'in kullanımına benzer olarak Powershell'in de Repair-WindowsImage cmdlet'i var, aşağıdaki gibi kullanımı mümkün:

Repair-WindowsImage -CheckHealth
Repair-WindowsImage -ScanHealth
Repair-WindowsImage -RestoreHealth

Bir sistemde kurulu olan güncellemeleri listelemek için

dism /online /Get-Packages /Format:Table

Şu an açık olan sistemde bunu elde etmenin başka yolları da var. Ama DVD veya USB'den açılmış sistem üzerinde aynısını yapabilmek için

dism /image:D:\ /Get-Packages /Format:Table

Burada /image:D:\ Windows'un bulunduğu sürücüyü göstermeli.

Karşılaşılan sorunlar ile ilgili şu videoya bakılabilir.

17.07.2024

Windows'da istenilen boyutta dosya oluşturmak

Amacım, Windows kullanarak diskte anlık olarak istenilen boyutta bir dosya oluşturmak. Bununla ilgili yöntemleri zaten, konunun bilir kişileri [1] adresinde özetlemiş. Ben de onları bir kez daha burada toparlamak istedim.

Yöntemlerden birisi fsutil kullanmak. 1 MB boyutunda file1.txt dosyasını, mevcut klasörde oluşturmak için, boyutu byte cinsinden vermek gerek:

fsutil file createnew file1.txt 1048576

Powershell (.Net kütüphanesi) kullanarak oluşturmak için yöntem şöyle:

[io.file]::Create("file2.txt").SetLength(1MB).Close

Sysinternals aracı contig'i kullanmak da bir seçenek:

contig64 -n testfile (1MB)

Bu da olmadıysa son yöntem olmasa da bu yazının son önerisi diskpart ile vdisk oluşturmak:

DISKPART
CREATE VDISK FILE="C:\file3.txt" MAXIMUM=1 TYPE=FIXED

Burada dikkat edilecek MAXIMUM parametresi ile verilen dosya boyutunun megabyte cinsinden veri olması gerek. Ayrıca FILE parametresi ile kısmi değil tam dosya yolu verilmeli. Bu yöntem, kullanımı en zor yöntem.

Gördüğüm kadarıyla bu yöntemlerin hepsi içine birşey yazmadan oluşturuyor. Her dosyaya bir veri kaydedilmemiş olsa da dosya boyutu ile diskte yer kapladığı alan bölümleri aynı, 1MB.


 Bir de sparse (seyrek, aralıklı) dosya denen bir kavram var. Önceki yöntemlerin hiçbirinin sparse dosya oluşturmadığı söylenmiş. Bir dosyanın sparse olup olmadığını anlamak için

fsutil sparse queryflag file1.txt

ve bir sparse dosya oluşturmak için

fsutil sparse setflag file2.txt
fsutil Sparse SetRange file2.txt 0 1048576

Bu şekilde oluştup fsutil sparse queryflag ile sorgulayınca dosya tipi sparse olarak görüntülendi.

C:\> fsutil sparse queryflag file2.txt
This file is set as sparse
[1] https://stackoverflow.com/questions/982659/quickly-create-large-file-on-a-windows-system

5.07.2024

Zamanlanmış görevler ile yeniden başlatma ayarlamak

Daha önce şu yazımda tek satırlık powershell komutları ile bir sunucuyu yeniden başlatma fikirleri paylaşmıştım.

Daha iyi bir fikrim var.

Yeniden başlatma zamanlamasını kendi bilgisayarımdan yapmak istiyorum. Tek tek yeniden başlatılacak bilgisayarlara uzak masaüstü veya uzak PSSsession bağlantıları ile değil. Aşağıdaki gibi schedule-restart.ps1 dosyasını oluşturuyorum.

param(    
    [string]$Computername,
    [string]$ScheduledTime="23:00"
)
Invoke-Command -Computername $Computername -ScriptBlock {
    $trig1 = New-JobTrigger -At $ScheduledTime -Once
    $obj1 = Register-ScheduledJob -Trigger $trig1 -Name "YenidenBaslatma" -ScriptBlock {Restart-Computer -Force}
    "Görev oluşturuldu: $($obj1.Name)"
    "Zaman : $($trig1.At)"
}

Bu betikle uzaktaki bir bilgisayar için yeniden başlatma görevi oluşturmak istediğimde şu şekilde bir kullanım yeterli:

.\schedule-restart.ps1 -ComputerName uzakpc

Varsayılan yeniden başlatma zamanı saat 23:00. Eğer değer vermezsek bu saatte, -ScheduledTime ile değer verirsek başka bir saatte yeniden başlatılacak. Zamanlama bir kez, bugün için geçerli olacak. Yani tekrarlama yok.

Peki bu isimde bir görev daha varsa ne olur? Bir önceki seferden oluşturduğum bir zamanlanmış görev varsa bir tane daha oluşturmayacaktır. İsmini farklı seçerek bir görev daha oluşturabilirim, ama bu durumda gereksiz görev kalabalığı olur. Aşağıda kırmızı ile vurguladığım bölüm, önce aynı isimle bir görev olup olmadığını kontrol ediyor, sonra bunu silmeyi öneriyor.

param(    
    [string]$Computername,
    [string]$ScheduledTime="23:00"
)
$bSilme = $false 
Invoke-Command -Computername $Computername -ScriptBlock {
$prev1 = Get-ScheduledJob -Name "YenidenBaslatma" -EA Silent
    if ($prev1) {
$resp1 = Read-Host "Aynı isimde bir görev daha var. Silinsin mi (N/y)?"
if ($resp1 -eq "Y" -or $resp1 -eq "y") {
try {
Unregister-ScheduledJob -InputObject $prev1
}
catch {
$_.ErrorDetails.Message
}
}
else {
"Silmemeyi sectigin icin yeni gorev olusturulmayacak"
$bSilme = $true
}
    }
else {

        $trig1 = New-JobTrigger -At $ScheduledTime -Once
        $job1 = Register-ScheduledJob -Trigger $trig1 -Name "YenidenBaslatma" -ScriptBlock {Restart-Computer -Force}
        "Görev oluşturuldu: $($job1.Name)"
        "Zaman : $($trig1.At)"
    }
}

Takıntılı olanlar, bu görevi daha karmaşık sonuçlar yaratmadan silmek isteyebilir. Bunun için de bir delete-restartjob.ps1 betiği oluşturdum.

param(    
    [string]$Computername
)
Invoke-Command -Computername $Computername -ScriptBlock {
    $job1 = Get-ScheduledJob -Name "YenidenBaslatma" -EA Silent
    if ($job1) {
        $trig1 = $job1 | Get-JobTrigger
        "Bulunan gorev: $($job1.Name)"
        "Zamanlamasi : $($trig1.At)"
        $resp1 = Read-Host "Bu gorev silinsin mi (N/y)?"
        if ($resp1 -eq "Y" -or $resp1 -eq "y") {
            $job1 | Unregister-Scheduled 
        }
        else {
            "Silinme iptal edildi." 
        }
    
    else {
        "Silinecek yeniden baslatma gorevi bulunamadi" 
    
İyileştirmenin sonu yok. Daha neler eklenebilir, neler...

5.06.2024

4 rakamdan oluşan pin seçmek gerektiğinde

Kredi kartları, banka kartları ve SIM kartlarda hala 4 haneli pinler kullanıyoruz. Çoğumuz ilk deneyimimizde belirlediğimiz pinleri hayatımızın sonuna kadar kullanıyor. Ve daha da büyük bir çoğunluk "unutmamak için" bu pinleri kendi doğum tarihleri, eşlerinin veya çocuklarının doğum tarihlerinden seçiyor. Zaman içinde farklı yerlerde ve zamanlarda sızan pinler üzerinden yapılan istatistiksel bir çalışmada olası pinlerin kullanılma oranları görselleştirilmiş. İşte bu çalışmanın sonucu olan görsel:

 
Bazı önemli noktaları vurgulamak lazım:
  • Açık renk en fazla kullanımı, koyu renk en az kullanımı gösteriyor.
  • 19xx veya 20xx gibi (muhtemelen) doğum tarihleri çokça kullanılmış.
  • Belli tarihlerin ay/yıl(son iki hane) veya yıl/ay şeklinde ifade edildiği pinler de çok kullanılmış.
  • Köşegen üzerinde 1111 veya 1212 gibi pinler de çok kullanılmış.
  • Araya sıkışan koyu renk noktalar ilginç bir şekilde en az kullanılan pinler.
  • Aşağıdaki pinler, tüm araştırmaya konu 3,4 milyon içinde %27'lik bir oranlar kabaca 918.000 kişi tarafından tercih edilmiş:
    • 1234, 0000, 7777, 2000, 2222, 5555, 1122, 8888, 2001, 1111, 1212, 1004, 4444, 6969, 3333, 6666, 1313, 4321, 1010
  • Aşağıdaki pinler ise en az kullanılanlar olarak listelenmiş:
    •  8557, 8438, 9539, 7063, 6827, 0859, 6793, 0738, 6835, 8093, 9047, 0439, 8196, 6093, 7394, 9480, 8398, 7637, 9629, 8068 

Benzer bir paylaşım Reddit'te de var.

---

https://www.howtogeek.com/125378/the-most-common-and-least-used-4-digit-pin-numbers-security-analysis-report/

3.06.2024

Lockout policies and cached credentials

İlginç bir olay. Kullanıcı bir bilgisayar oturum açmayı deniyor ama başka yerde kullandığı şifresini giriyor (yeterli sayıda) ve hesabı lockout oluyor. Domain controller üzerinde 4740 olayı oluşuyor, Security eventlog'da. Kullanıcıya da belli sayıda yanlış parola denemesinden sonra hesabının kilitlendiği bilgisi gösteriliyor. Kullanıcı da mevcut bilgisayarını yeniden başlatıyor. Yeniden başladıktan sonra şifresini girmesi gereken doğru şifreyi hatırlıyor ve giriyor. Bu durumda ne olması gerekirdi? Ben domain controller'a danışarak oturum açmayı reddetmesini beklerdim. Ama öyle olmamış. Oturum açma işlemi başarılı olmuş. Söz konusu bilgisayar üzerinde o tarih ve saatteki 4624 eventlog'una baktığımda Logon Type olarak 11 gördüm. 11 neydi? Şifre doğrulaması için domain controller'a sorma, yerel bilgisayardaki cache'lenmiş şifrelere bak. Bu bilgisayarda da en son başarılı şifre girişine ait bir cache'lenmiş şifre olduğu için bilgisayar girişe izin veriyor. Ve kullanıcı oturum açabiliyor.

Kullanıcının hesabının unlock olmasına ait kayıt 4767, domain contorller üzerinde security eventlog'da tutuluyor. Ama bu olayda bu event yok, çünkü bu event sadece bir yetkili kullanıcının hesabı unlock etmesi sırasında oluşuyor. Lockout süresinin geçmesi sonrasında otomatik olarak unlock olması durumunda oluşmuyor.

Bu nahoş bir durum. Ama çözümünü bulamadım. Cached credentials'ı tümden engelleyebiliriz. Ama bu mobil bilgisayarlarını taşıyan ve yerel ağın dışında kullanan kullanıcılar için soruna sebep olur.

Önerilere açığım.