Sysinternals etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Sysinternals etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

2026-04-01

HTML ayrıştırma

Invoke-WebRequest cmdlet'i ile HTML içinde istenen öğelerin hızlı ayrıştırması yapılabilir. Örneğin şu sayfada yapılmış bir örnekte github üzerindeki görsellerin indirilmesi için powershell kullanılmış. Hedef sayfamız 

$url = "https://github.com/PrateekKumarSingh/CheatSheets/tree/master/Powershell"

 ile belirtilmiş. Bu sayfanın içeriği Invoke-WebRequest ile $page değişkenine atanmış.

$page = Invoke-WebRequest -UseBasicParsing -Uri $url

Bu aşamadan sonra sayfadaki bütün bağlantılara $page.Links ile ulaşmak mümkün. Hatta bir miktar biçimlendirme ile

$page.Links | Where-Object title | Select-Object -Property title, href

gibi bir tablo oluşturulmuş. Daha önce duvar kağıdı indirme için şu örneği yapmıştım, yine Links kullanarak.

Daha karışık bir örnek için live.sysinternals.com/files sayfasında yer alan araçların bir listesini oluşturmak istediğimizi düşünelim. Yine $page.Links ile sayfadaki bağlantılara erişmek mümkün ama bir de sayfada yer alan ama bir şekilde Links veya diğer property'ler ile görüntülenemeyen araçların güncellenme tarihi almak istediğimizi varsayalım. Bunun için sayfanın ham (raw) HTML kaynağını bir HTMLFile nesnesine atarak içinde adım adım ilerlememiz gerek.

İlk iş bir HTMLFile nesnesi oluşturmak

    $htmObj = New-Object -ComObject "HTMLFile"

Daha sonra $page.Content verisini bu nesnenin içine alalım.

    $htmObj.IHTMLDocument2_write($list.Content)

Yukarıdaki satır bazı durumlarda (Office yüklü olmayan bilgisayarlar veya Powershell 6+ sürümlerde)

method invocation failed because [system.__comobject] does not contain a method named 'IHTMLDocument2_write'

hatası verebilir. Bu durumda IHTMLDocument2_write satırını aşağıdaki 2 satır ile değiştirmek gerekebilir.

    $bytes = [System.Text.Encoding]::Unicode.GetBytes($page.content)
    $htmObj.write($bytes)

try/catch bloğu ile iki yöntemin birleşimini sayfanın altına yazıyorum, burası daha fazla karışmasın. 

Sayfadaki tarih ve saat verisi 

     Saturday, March 21, 2026 11:18 AM

şeklinde olduğu için bu yapıyla eşleşebilecek bir regex oluşturalım.

$pattern = '(\w+,\s+\w+\s+\d+,\s+\d+\s+\d+:\d+\s+[AP]M)\s+(\d+)\s+(\S+)'

Sayfanın kaynak kodunda yer alan header bilgisi gibi işimizi yaramayacak verilerden kurtulmak için ilk tarih saat bilgisinin geçtiği konumu bulalım.

$indxStart = ($htmObj.body.outerText | sls -Pattern $pattern).Matches[0].Index

İlk kez tarih ve saat formatının geçtiği yer baz alacağımız başlangıç noktası olacak. Buradan sayfanın sonuna kadar olan yer ile ilgileniyoruz.

    $indxEnd = ($htmObj.body.outerText).Length
    $raw = $htmObj.body.outerText.Substring($indxStart, $indxEnd-$indxStart)

Sıra bu kalıba uyan verileri ayrıştırma adımına geldi. $pattern değişkeninin içinde 3 gruplandırma kullandım, parantezler içinde. Aşağıdaki Groups bölümleri (nesneleri, dizileri, neyse) buna göre oluşturuldu.

$results = [regex]::Matches($raw, $pattern) | ForEach-Object {
    [PSCustomObject]@{
        Date     = $_.Groups[1].Value.Trim()
        Size     = [int]$_.Groups[2].Value
        FileName = $_.Groups[3].Value
    }
}

live.sysinternals.com/files sayfasında bir değişiklik olana kadar bunun çalışacağını umuyorum.

    $results | Out-GridView

Sayfada Date, Size veya FileName alanlarına ait bir veri etiketi/başlık/alan adı bulunmuyor. Bunu en son ayrıştırma aşamasında yaptım. Bu bölümdeki her alan için $pattern değişkeni içindeki bölümlerle eşleşme şöyle:

DateGroups[1](\w+,\s+\w+\s+\d+,\s+\d+\s+\d+:\d+\s+[AP]M)
SizeGroups[2](\d+)
FileNameGroups[3]   
(\S+)

---

$htmObj = New-Object -ComObject "HTMLFile"
$page = iwr -useb "live.sysinternals.com/files"

try {
    # Bu yöntem genellikle MS Office yüklü sistemlerde ve Windows PowerShell'de çalışır
    $html.IHTMLDocument2_write($content)
}
catch {
    # Office yüklü değilse veya PowerShell Core kullanıyorsanız bu yöntem çalışır
    $bytes = [System.Text.Encoding]::Unicode.GetBytes($page.Content)
    $htmObj.write($bytes)
}

 

2026-01-06

Sysmon - ek bilgiler

Sysmon konusunda yeni bazı şeyler öğrendim. Eski bazı kullanımları tekrar vurgulayayım.

sysmon64 -i        # Sysmon64.exe dosyasını C:\Windows klasörünün altına taşı ve hizmet olarak kur
sysmon64 -c # Mevcut yapılandırmayı göster
sysmon64 -s # Yapılandırma şemasını göster
sysmon64 -u # Kurulumu kaldır

Varsayılan olarak bir xml dosyası gösterilmeksizin sadece -i ile (veya sonradan -c -- ile sıfırlanarak) yapılandırıldığında sysmon aşağıdaki gibi bir durumda oluyor.

Sysmon64 -c
Current configuration:
- Service name:      Sysmon
- Driver name:      SysmonDrv
- Config file:     
   C:\Users\administrator\Defaults

- HashingAlgorithms: SHA256
- Network connection: disabled
- Archive Directory: -
- Image loading:     disabled
- DNS lookup:     
    enabled
No rules installed

Yapılandırma şemasını (configuration schema) ekrana bastırınca <option> bölümü çıkıyor.

    <options>
      <!-- Command-line only options -->
      <option switch="i" name="Install" argument="optional" noconfig="true" exclusive="true" />
      <option switch="c" name="Configuration" argument="optional" noconfig="true" exclusive="true" />
      <option switch="u" name="UnInstall" argument="optional" noconfig="true" exclusive="true" />
      <option switch="m" name="Manifest" argument="none" noconfig="true" exclusive="true" />
      <option switch="z" name="ClipboardInstance" argument="required" noconfig="true" exclusive="true" />
      <option switch="t" name="DebugMode" argument="optional" noconfig="true" />
      <option switch="btf" name="BTF" argument="optional" noconfig="true" />
      <option switch="service" name="Service" argument="none" noconfig="true" />
      <option switch="s" name="PrintSchema" argument="optional" noconfig="true" exclusive="true" />
      <option switch="nologo" name="NoLogo" argument="none" noconfig="true" />
      <option switch="accepteula" name="AcceptEula" argument="none" noconfig="true" />
      <option switch="-" name="ConfigDefault" argument="none" noconfig="true" />
      <!-- Configuration file -->
      <option switch="a" name="ArchiveDirectory" argument="required" />
      <option name="CaptureClipboard" argument="none" />
      <option switch="d" name="DriverName" argument="required" />
      <option switch="dns" name="DnsQuery" argument="optional" rule="true" />
      <option switch="g" name="PipeMonitoring" argument="required" rule="true" forceconfig="true" />
      <option switch="h" name="HashAlgorithms" argument="required" />
      <option name="DnsLookup" argument="required" />
      <option switch="k" name="ProcessAccess" argument="required" rule="true" forceconfig="true" />
      <option switch="l" name="ImageLoad" argument="optional" rule="true" />
      <option switch="n" name="NetworkConnect" argument="optional" rule="true" />
      <option switch="r" name="CheckRevocation" argument="optional" />
      <option name="FieldSizes" argument="required" />
    </options>

Burada option bölümünün altındaki switch'leri kullanarak yapılandırmayı değiştirmek mümkün. Örneğin varsayılan SHA256 hash'i yerine tüm hash'leri hesaplatmak için -h switch'ini aşağıdaki gibi kullanmak mümkün.

Sysmon64 -c -h *

Bunun sonucunda yapılanmamız aşağıdaki gibi olur.

Sysmon64 -c
Current configuration:
- Service name:      Sysmon
- Driver name:      SysmonDrv
- Config file:     
   "C:\Windows\Sysmon64.exe" -c -h *

- HashingAlgorithms:
SHA1,MD5,SHA256,IMPHASH
- Network connection: disabled
- Archive Directory: -
- Image loading:     disabled
- DNS lookup:     
    enabled
No rules installed

Ya da notepad.exe tarafından yapılan tüm NetworkConnect işlemlerini kayıt altına almak için "n" switch'i kullanılabilir.

Sysmon -c -n notepad.exe

Bunun sonucundaki yapılandırmamız da şu şekilde olur.

Sysmon64 -c
Current configuration:
- Service name:      Sysmon
- Driver name:      SysmonDrv
- Config file:     
   "C:\Windows\Sysmon64.exe" -c -n notepad.exe

- HashingAlgorithms: SHA256
- Network connection:
enabled
- Archive Directory: -
- Image loading:     disabled
- DNS lookup:     
    enabled
No rules installed

Görüldüğü gibi HashingAlgorithms alanı tekrar sadece SHA256'ya döndü, ama config file bölümünü en son kullandığımız komut satırını gösteriyor. Yani bu şekilde yapılan değişiklikler önceki değişikliklerin üzerine yazar, ekleme yapmaz.

Sysmon'un bir de -m komut satırı anahtarı var. Bu, aslında sysmon'u bir hizmet olarak kurmaz ve çalıştırmaz. Ama başka bir makinede toplanan olay kayıtları varsa bunları gerektiği şekilde yerel makinede görebilmemiz için tanımlamaları oluşturur. Elbette böyle bir senaryoda sysmon makinede ilk kez çalıştırılıyor olabilir, bu sebeple -accepteula anahtarı ile birlikte kullanılması gerekebilir.

sysmon64 -m -accepteula

Kurulumlar sırasında Sysmon kendini %systemroot% klasörünün içine kopyalar ve bir hizmet oluşturarak bu kopyanın çalışmasını sağlar. Varsayılan değerlerde sysmon aşağıdaki olaylara ait kayıtlar oluşturur:

  • ProcessCreate
  • ProcessTerminate
  • DriverLoad
  • FileCreateTime
  • SHA256 hash hesaplaması

Bir sunucuda çalışan sysmon hizmeti çok kolay olarak tespit edilebilir. Bu hizmetin ismini değiştirebilsek güzel olmaz mıydı. Olur, onu da sysmon64.exe'yi yeniden adlandırarak yapabiliriz.

ren .\sysmon64.exe .\abc123.exe
.\abc123.exe -i -accepteula