最近はセキュリティロギングに興味があり、bash-shellをよりよく扱いたいと思います。 awkは9つの逆参照だけを保存することを発見しました。ただし、10個の逆参照を使用する必要があります。
試験を終えた
awk '{print gensub(/^([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}).+?\sID\s(\[[0-9]{4}\]).+?\sTargetUserName\s=\s(.+?)\sTargetDomainName\s=\s(.+?)\sTargetLogonId\s=\s(.+?)\sLogonType\s=\s([0-9]{1,2})\s(.+?\sWorkstationName\s=\s(.+?)\sLogonGuid\s=\s.+?TransmittedServices\s=\s.+?\sLmPackageName\s=\s.+?KeyLength\s=\s.+?\sProcessId\s=\s.+?\sProcessName\s=\s.+?\sIpAddress\s=\s(.+?)\sIpPort\s\=\s([0-9]{1,}))?.+?$/,"\\5,\\4,\\3,\\2\\6,\\1,\\8,\\9,","g") }'
ターゲット文字列(実際には何千もの文字列)
2017-03-21T02:00:00 kornawesome Security/Microsoft-Windows-Security-Auditing ID [4624] :EventData/Data -> SubjectUserSid = S-1-5-18 SubjectUserName = PRETENDERS$ SubjectDomainName = WORKGROUP SubjectLogonId = 0x00000000000004j7 TargetUserSid = X-12-54-181 TargetUserName = SYSTEMS TargetDomainName = NT AUTHORITY TargetLogonId = 0x00000000000003e7 LogonType = 8 LogonProcessName = Lxxoi AuthenticationPackageName = Negotiate WorkstationName = - LogonGuid = {00344000-0000-0000-0000-0000000003440} TransmittedServices = - LmPackageName = Stainless KeyLength = 0 ProcessId = 0x0000000000000244 ProcessName = C:/Windows/System32/services.exe IpAddress = 10.0.0.0 IpPort = 10.5.3.2 ImpersonationLevel = %%1122
awkを使用して実行できる他の方法がある場合は、デフォルトのbash配列と連想配列を使用したいと思います。私(初心者)のために...親切な説明もお願いします。
ベストアンサー1
セキュリティログの問題の1つは、一部のテキストがユーザー制御下にある可能性があるため、正規表現を使用してコンテンツを分割することが問題になることです。ただし、複数の式を使用して問題を分割することができ、これは9つの逆参照制限を中心に機能します。たとえば、すべてのログエントリがタイムスタンプで始まる場合は、そのエントリを削除できます。
awk '{t=$1 ;$1="";
print gensub(/^.+?\sID\s(\[[0-9]{4}\]).+?\sTargetUserName\s=\s(.+?)\sTargetDomainName\s=\s(.+?)\sTargetLogonId\s=\s(.+?)\sLogonType\s=\s([0-9]{1,2})\s(.+?\sWorkstationName\s=\s(.+?)\sLogonGuid\s=\s.+?TransmittedServices\s=\s.+?\sLmPackageName\s=\s.+?KeyLength\s=\s.+?\sProcessId\s=\s.+?\sProcessName\s=\s.+?\sIpAddress\s=\s(.+?)\sIpPort\s\=\s([0-9]{1,}))?.+?$/,"\\4,\\3,\\2,\\1\\5" t ",\\7,\\8,","g") }'
オプションであるため、WorkstationName\s=\s(.+?)\sLogonGuid
パターンの一部として使用できます。
awk {t=$1; $1="" ; printf("%s", gensub(/^.+?WorkstationName\s=\s(.+?)\sLogonGuid.*$/,"\\1,")); printf("%s,", t)}
フィールドを取り出すと、この操作を繰り返すことができます。
@casはコメントで、データを前のコンテンツEventData/Data ->
と次のコンテンツの2つの部分として見ることができ、次のコンテンツを分割できることを指摘しました=
(スペースはスペースと同じです)。もう一度ステップをキー/値のペアとして処理し、オプションの/\s\S+\s=\s/
4番目のパラメータを分割してsplit
キーを取得します。いくつかの重要な仮定があります。つまり、ユーザーが行に等号を入れることができず、各データに単語キーがあるという仮定があります。キーと値のインデックスは1だけ異なり、行の最初の部分はで終わりますv[1]
。
/usr/bin/awk '{
n=split($0,v,/\s\S+\s=\s/,k)
printf("There are %d fields\n",n)
for(i=0;i<n;i++) { printf("%d key \"%s\" value \"%s\"\n",i,k[i],v[i+1]) }
}'
サンプルデータに付属
There are 22 fields
0 key "" value "2017-03-21T02:00:00 kornawesome Security/Microsoft-Windows-Security-Auditing ID [4624] :EventData/Data ->"
1 key " SubjectUserSid = " value "S-1-5-18"
2 key " SubjectUserName = " value "PRETENDERS$"
3 key " SubjectDomainName = " value "WORKGROUP"
4 key " SubjectLogonId = " value "0x00000000000004j7"
5 key " TargetUserSid = " value "X-12-54-181"
6 key " TargetUserName = " value "SYSTEMS"
7 key " TargetDomainName = " value "NT AUTHORITY"
8 key " TargetLogonId = " value "0x00000000000003e7"
9 key " LogonType = " value "8"
10 key " LogonProcessName = " value "Lxxoi "
11 key " AuthenticationPackageName = " value "Negotiate"
12 key " WorkstationName = " value "-"
13 key " LogonGuid = " value "{00344000-0000-0000-0000-0000000003440}"
14 key " TransmittedServices = " value "-"
15 key " LmPackageName = " value "Stainless"
16 key " KeyLength = " value "0"
17 key " ProcessId = " value "0x0000000000000244"
18 key " ProcessName = " value "C:/Windows/System32/services.exe"
19 key " IpAddress = " value "10.0.0.0"
20 key " IpPort = " value "10.5.3.2"
21 key " ImpersonationLevel = " value "%%1122"
ここでは、さらに一歩進んで、データという連想配列を作成できます。
for(i=1;i<n;i++) {gsub(/[ =]/,"",k[i]);data[k[i]]=v[i+1]}
data["IpPort"]
これにより、フィールド20か21かを気にせずにこのような内容を印刷できます。