2017년 6월 13일 화요일

Windows Event Log 분석(Dns Request - 5th)

DNS 관련 이벤트 로그를 조회 시도 프로세스명과 함께 기록해보려 했으나 잘 안 되는 중. 정확히 얘기하면 같은 시간대에 여러 개의 DNS 조회가 발생해도 마지막 조회만 기록 중. 스크립트를 좀 바꿔봤다. 작업 스케줄 설정(3006 이벤트 발생 시 실행)은 동일.
$TIMESTAMP = Get-WinEvent Microsoft-Windows-DNS-Client/Operational -FilterXpath {*[System/EventID=3006]} -MaxEvents 1 | Select-Object -ExpandProperty timecreated
$LOG_LIST = Get-WinEvent -FilterHashtable @{ LogName='microsoft-windows-dns-client/operational'; StartTime=$TIMESTAMP; ID=3006 }

foreach($LOG in $LOG_LIST) {
    $TIMESTAMP_SPLIT = $TIMESTAMP -split " "
    $LOG_DATE = $TIMESTAMP_SPLIT[0]
    $LOG_TIME = $TIMESTAMP_SPLIT[1]
    $PROC_ID = $LOG | Select-Object -ExpandProperty processid
    $PROC_NAME = Get-Process -id $PROC_ID | Select-Object -ExpandProperty processname
    $MSG = $LOG | Select-Object -ExpandProperty message
    $URL_1 = $MSG -replace '^\S{2}\s([^,]+).+','$1'
    $URL_2 = $URL_1 -replace '^.*?([^.]+\.[^.]+\.?|[^.]+\.(ac|co|go|ne|nm|or|pe|re)\.[^.]+\.?)$','$1'
    $QUERY_TYPE = $MSG -replace '^.+?(\d+),.+','$1'
    $LOG_SET = "$LOG_DATE`t$LOG_TIME`t$PROC_ID`t$PROC_NAME`t$URL_1`t$URL_2`t$QUERY_TYPE"
    $LOG_SET >> C:\dns2.csv
}

정규표현식 ^.*?([^.]+\.[^.]+\.?|[^.]+\.(ac|co|go|ne|nm|or|pe|re)\.[^.]+\.?)$을 이용해서 전체 도메인 중 상위 도메인(녹색 영역)만 분리하는 과정도 추가.


하지만 여전히 잘 안 된다.-_- '17:28'분대 실제 발생 로그는 19개.


하지만 기록된 로그는 11개.


뭐가 문제일까? 기본적으로 로그 조회가 너무 느리다. 고작 두 줄 조회하는데 걸리는 시간이 자그마치 3초. 조회하는 동안 새로 발생하는 DNS 조회 이벤트는 못가져온다는 얘기. 파워쉘이 구린 건가? 스크립트가 구린 건가? 아님 컴퓨터가 구린가?


작업 스케줄 설정 없이 다음 스크립트를 이용하면 손실 없이 모든 이벤트 로그를 기록할 수 있는데, 대신 프로세스명 추출이 안 될 때가 있다. 60초 대기하는 사이에 프로세스가 종료될 수도 있기 때문인데, 대략 5% 정도의 로그에서 프로세스명 추출에 실패한다.
while($true) {
    $QUERY = @"
    <QueryList><Query><Select Path='Microsoft-Windows-DNS-Client/Operational'>
       *[System/EventID = 3006] and 
       *[System/TimeCreated[timediff(@SystemTime) &lt;= 60000]] and
       *[EventData/Data[@Name='QueryType'] != 28]
    </Select></Query></QueryList>
"@

    $CMD = (Get-WinEvent -FilterXml $QUERY).count 2>$null
    if($CMD -ne 0) {
       $LOG_LIST = Get-WinEvent -FilterXml $QUERY | Select-Object timecreated, processid, message | Sort-Object timecreated

       foreach($LOG in $LOG_LIST) {
            $TIMESTAMP = $LOG | Select-Object -ExpandProperty timecreated
            $TIMESTAMP_SPLIT = $TIMESTAMP -split " "
            $LOG_DATE = $TIMESTAMP_SPLIT[0]
            $LOG_TIME = $TIMESTAMP_SPLIT[1]
            $PROC_ID = $LOG | Select-Object -ExpandProperty processid
            $PROC_NAME = Get-Process -id $PROC_ID | Select-Object -ExpandProperty processname
            $MSG = $LOG | Select-Object -ExpandProperty message
            $URL_1 = $MSG -replace '^\S{2}\s([^,]+).+','$1'
            $URL_2 = $URL_1 -replace '^.*?([^.]+\.[^.]+\.?|[^.]+\.(ac|co|go|ne|nm|or|pe|re)\.[^.]+\.?)$','$1'
            $LOG_SET = "$LOG_DATE`t$LOG_TIME`t$PROC_ID`t$PROC_NAME`t$URL_1`t$URL_2"
            $LOG_SET >> C:\dns.csv
            }
        }
    Start-Sleep 60
    }

60초 인터벌을 더 줄이면 프로세스명 추출 실패율을 줄일 수는 있는데, 대신 노트북이 발악을 함. 미안해 쿨링팬 3006 이벤트에 프로세스 이름만 기록되면 이런 삽질 필요없지만, 마소가 해줄리도 없고(..)


관련 글

댓글 없음:

댓글 쓰기

크리에이티브 커먼즈 라이선스