From fe7840798436bb22221b97c9c2e1c4b15999f44d Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Tue, 22 Mar 2022 16:05:08 +1030 Subject: [PATCH 01/19] winlogbeat/sys/wineventlog: extend testing and fix bugs New events in testing as rendered by the Event Viewer: ec1: eventcreate /id 1000 /t error /l application /d "My custom error event for the application log" - - 1000 0 2 0 0 0x80000000000000 316 Application vagrant - My custom error event for the application log ec2: eventcreate /id 999 /t error /l application /so WinWord /d "Winword event 999 happened due to low diskspace" - - 999 0 2 0 0 0x80000000000000 317 Application vagrant - Winword event 999 happened due to low diskspace ec3: eventcreate /id 5 /t error /l system /d "Catastrophe!" - - 5 0 2 0 0 0x80000000000000 1413 System vagrant - Catastrophe! ec4: eventcreate /id 5 /t error /l system /so Backup /d "Backup failure" - - 5 0 2 0 0 0x80000000000000 1414 System vagrant - Backup failure --- CHANGELOG.next.asciidoc | 2 + winlogbeat/sys/wineventlog/format_message.go | 21 +-- winlogbeat/sys/wineventlog/query_test.go | 12 +- winlogbeat/sys/wineventlog/testdata/ec1.evtx | Bin 0 -> 69632 bytes winlogbeat/sys/wineventlog/testdata/ec1.xml | 1 + winlogbeat/sys/wineventlog/testdata/ec2.evtx | Bin 0 -> 69632 bytes winlogbeat/sys/wineventlog/testdata/ec2.xml | 1 + winlogbeat/sys/wineventlog/testdata/ec3.evtx | Bin 0 -> 69632 bytes winlogbeat/sys/wineventlog/testdata/ec3.xml | 1 + .../sys/wineventlog/testdata/ec3and4.evtx | Bin 0 -> 69632 bytes .../sys/wineventlog/testdata/ec3and4.xml | 2 + winlogbeat/sys/wineventlog/testdata/ec4.evtx | Bin 0 -> 69632 bytes winlogbeat/sys/wineventlog/testdata/ec4.xml | 1 + .../sys/wineventlog/testdata/sysmon-9.01.xml | 32 ++++ .../sys/wineventlog/wineventlog_windows.go | 3 +- .../wineventlog/wineventlog_windows_test.go | 160 +++++++++++------- 16 files changed, 158 insertions(+), 78 deletions(-) create mode 100644 winlogbeat/sys/wineventlog/testdata/ec1.evtx create mode 100644 winlogbeat/sys/wineventlog/testdata/ec1.xml create mode 100644 winlogbeat/sys/wineventlog/testdata/ec2.evtx create mode 100644 winlogbeat/sys/wineventlog/testdata/ec2.xml create mode 100644 winlogbeat/sys/wineventlog/testdata/ec3.evtx create mode 100644 winlogbeat/sys/wineventlog/testdata/ec3.xml create mode 100644 winlogbeat/sys/wineventlog/testdata/ec3and4.evtx create mode 100644 winlogbeat/sys/wineventlog/testdata/ec3and4.xml create mode 100644 winlogbeat/sys/wineventlog/testdata/ec4.evtx create mode 100644 winlogbeat/sys/wineventlog/testdata/ec4.xml create mode 100644 winlogbeat/sys/wineventlog/testdata/sysmon-9.01.xml diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 42000a412975..b5bace1abbb2 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -82,6 +82,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...main[Check the HEAD dif *Winlogbeat* +- Fix evtx parsing failures. {issue}30621[30621] {pull}30942[30942] + *Functionbeat* diff --git a/winlogbeat/sys/wineventlog/format_message.go b/winlogbeat/sys/wineventlog/format_message.go index d953c210b562..24ce23140852 100644 --- a/winlogbeat/sys/wineventlog/format_message.go +++ b/winlogbeat/sys/wineventlog/format_message.go @@ -89,16 +89,17 @@ func evtFormatMessage(metadataHandle EvtHandle, eventHandle EvtHandle, messageID defer bb.Free() bb.Reserve(int(bufferUsed * 2)) - err = _EvtFormatMessage(metadataHandle, eventHandle, messageID, valuesCount, valuesPtr, messageFlag, uint32(bb.Len()/2), bb.PtrAt(0), &bufferUsed) - if err != nil { - switch err { - // Ignore some errors so it can tolerate missing or mismatched parameter values. - case windows.ERROR_EVT_UNRESOLVED_VALUE_INSERT: - case windows.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: - case windows.ERROR_EVT_MAX_INSERTS_REACHED: - default: - return "", errors.Wrap(err, "failed in EvtFormatMessage") - } + err = _EvtFormatMessage(metadataHandle, eventHandle, messageID, valuesCount, valuesPtr, messageFlag, uint32(bb.Len()), bb.PtrAt(0), &bufferUsed) + switch err { + case nil: // OK + + // Ignore some errors so it can tolerate missing or mismatched parameter values. + case windows.ERROR_EVT_UNRESOLVED_VALUE_INSERT, + windows.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT, + windows.ERROR_EVT_MAX_INSERTS_REACHED: + + default: + return "", errors.Wrap(err, "failed in EvtFormatMessage") } return sys.UTF16BytesToString(bb.Bytes()) diff --git a/winlogbeat/sys/wineventlog/query_test.go b/winlogbeat/sys/wineventlog/query_test.go index f31f98ac6c95..8c3a5031f127 100644 --- a/winlogbeat/sys/wineventlog/query_test.go +++ b/winlogbeat/sys/wineventlog/query_test.go @@ -49,7 +49,7 @@ func TestIgnoreOlderQuery(t *testing.T) { q, err := Query{Log: "Application", IgnoreOlder: time.Hour}.Build() if assert.NoError(t, err) { assert.Equal(t, expected, q) - fmt.Println(q) + t.Log(q) } } @@ -64,7 +64,7 @@ func TestEventIDQuery(t *testing.T) { q, err := Query{Log: "Application", EventID: "1, 1-100, -75"}.Build() if assert.NoError(t, err) { assert.Equal(t, expected, q) - fmt.Println(q) + t.Log(q) } } @@ -78,7 +78,7 @@ func TestLevelQuery(t *testing.T) { q, err := Query{Log: "Application", Level: "Verbose"}.Build() if assert.NoError(t, err) { assert.Equal(t, expected, q) - fmt.Println(q) + t.Log(q) } } @@ -92,7 +92,7 @@ func TestProviderQuery(t *testing.T) { q, err := Query{Log: "Application", Provider: []string{"mysrc"}}.Build() if assert.NoError(t, err) { assert.Equal(t, expected, q) - fmt.Println(q) + t.Log(q) } } @@ -112,7 +112,7 @@ func TestCombinedQuery(t *testing.T) { }.Build() if assert.NoError(t, err) { assert.Equal(t, expected, q) - fmt.Println(q) + t.Log(q) } } @@ -126,6 +126,6 @@ func TestQueryNoParams(t *testing.T) { q, err := Query{Log: "Application"}.Build() if assert.NoError(t, err) { assert.Equal(t, expected, q) - fmt.Println(q) + t.Log(q) } } diff --git a/winlogbeat/sys/wineventlog/testdata/ec1.evtx b/winlogbeat/sys/wineventlog/testdata/ec1.evtx new file mode 100644 index 0000000000000000000000000000000000000000..3e498db3ae0f143210ac1798040776c2c29e444d GIT binary patch literal 69632 zcmeI$U5Hd=9LMqh%$%7$JF7F=CYgzi(F+Q`BnswBFs>_wnp##6-VE+;yE;1~yR*Kq zL0XAY65jMiH&H=!(@h8xU3e2Afn7;fH$emuA!!tq7u)au%sDkK$r2KD@qLz=Ip;k8 z^Spfi&v}NO{`%0Ck@}!bFWKb6QGI4DXErA@J>;g(tG{1+@TMD~0R#|0009ILKmY** z5I_I{1Q3`}puaxUH{957>3{b(`aJ3_=|_Q+vDw1+f4yhMhGz)ye#&z$zS$WzzhL%G zm)YgK*|$+=joD|qzEM9z{M&MVhI>w{&&z6izWVfXHHrUF*VFQV$cGyO(uF7#$E*ut_&)srsL)M9MP3AYwE0NLyBCk z^QNw^utTbA=yR2=)Zc0yt+cgzAN;HP@$1gAnW?F-m8&#w&D{li%#Nt#R_IX+ygD_t zTjNSIdSx=UouT)G>T5tzW2(L1r<5+nt*=D(hz2{VN}o_q$L#wQKBzixK3C1zc127i zi{+PES4ZT-wpn%edBeWiye#>uXuE7ex7XG8kY3)qtCb=vWJ@_KMC$D>T}T)C{O&G$ zA_*H2QbTpwQjbNE(z{3}>FOT1khg6L^fc8&kaXpFOv99g`P@U zT>o;9Ivoj|oqPj|2|WG)`EuGYS-dWJ=}qD(*xX#EsD<+PHnJr*yF>d?jm3xTBWcTL zOGPXCSdQzabT4@OYLE4WFi&GWBr;{)qqr^A=WQl)oMpYasMKqVBfC|hT881JRjco<_A9n|7Ta9! zL$z^u#a0Y)3#~U?|EITdX0d&G`L3(8-v`1G*u@+evQgXv#~UN%4H=}&jn%|X4U z>sj^c&#Zqv`YL#_8EGf+9VgV5%#QhET~UaC%XwLRwqTp2+EB=t7OFq9S?wv2|H^NB z>{wv&$nC1Fge>?D>3eP^fctJd7LL;aRkS~~ueHMNT~XWrv_vXeG)-mx`r_X|6a)}J z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 x009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|00D=FPz@KC<7RUeq literal 0 HcmV?d00001 diff --git a/winlogbeat/sys/wineventlog/testdata/ec1.xml b/winlogbeat/sys/wineventlog/testdata/ec1.xml new file mode 100644 index 000000000000..d1607a648352 --- /dev/null +++ b/winlogbeat/sys/wineventlog/testdata/ec1.xml @@ -0,0 +1 @@ +100002000x80000000000000316ApplicationvagrantMy custom error event for the application log diff --git a/winlogbeat/sys/wineventlog/testdata/ec2.evtx b/winlogbeat/sys/wineventlog/testdata/ec2.evtx new file mode 100644 index 0000000000000000000000000000000000000000..7b8eb85263de7a7fad8d9c69b8032f1a13b53796 GIT binary patch literal 69632 zcmeI$Ux-v?7{~GF%$%7$JFBy9s~{#eMieW!E2f~C!Md&#YHFGibm6jpa&>lAc4ys{ zz0pjP2LQ3Fx{-+PEQrYdTy$k6L0ANp7u)YSbKYE+WC;nn_`b_IbKdhl z=l%0}-}4STz15*@!_`5Xn{wHW6Z*_q-fU4cH{`bS-G5wv=(a1N0t661009ILKmY** z5I_I{1Q3{4ptm~IbEtO2!hiR-`aIz^=|_PRiP_KhfA-S670(mk?OZtja@XvzMMbk$ zn#`^g%)W_dmzaH|`Tpr8!lyHicU}MLcNbTGJokb|;!)l0c1o8%Ku;emC|Iu@vq7s_UHNBq z6c1;GAGQ{3%0{fJ!f_Q8qV;x2VRbud4_KG}#;sp>1{Kq%>rQ&}>sDmQ9FitJQ= zRQJ1VQe`!LuC+D#Tc@ivwn68?zndSwDVK|8Wb$ng2JvN~#tEy;7hqvll<=Be3a^8w@)M9t*Mp)cSo11KZ z7B;MQYbwi?TP%(>tt*rXt9sy4!FDLnr>B|*nFr-;xiYQU((Ij%ZC}cNBn`=VgOOE~ z@m25XofSpfr8)DNa20PZ@|p^Ek22w9Is9p2+f{sAQ`OM$VdTmMTM|opw=&OUHEufF zqDF^P#vYA#P#y4D8Bk2h<1dacqX(x;H%(f2NIXSr%SR{_w*10b+K;J1@3PNJ zLq1n7S;_lyS`URi;Ei8etS1fgepJ(*1lA`Nw{2tgQkSlktXnnK)p1`Sb&a%9Z@I}@ zi@p!|w6FiT&AjPGO+KbuJamV(=GB)GwGsA>3-2{+08?qlC(?!*)BCXZ|~2^&+vP=)0*;?dgq)gb!u50ifJ$Nj{pH+2G^P_PkSCqCJZ2(?Y7H{nn%v zwC1`sa(ZR1FyMm?!HA2`X21* z_0B|7>r*tLmgKm)mV+Y>O4DWtbjXwfeql9EmNl z#M-$~CEB!mqzRzAwZIu=_$Pm9d?3`Nro(fBJ`flO1Gk*?U zdj8JotH1uBha0=;`RRORS?gC_pG@f~kCLUonEo~BY3tKI{b4uV znyUBdeon3WJL_MIz6zcjjkS~bE0dO%%})AjT~UaCyLno9p=evAT2siF7OKC9IqfO2 z|GIAn?PSX0k&O*3ys{NxhYnP1WBOM~SBEbK-{yTqS9DD1s-iB8>Ri=%GQB&j={ln0 zsM_`Ac_aDvj;ApHjT~nL5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL PKmY**5I_Kd|AW9^g%K21 literal 0 HcmV?d00001 diff --git a/winlogbeat/sys/wineventlog/testdata/ec2.xml b/winlogbeat/sys/wineventlog/testdata/ec2.xml new file mode 100644 index 000000000000..5e2e8e38b7da --- /dev/null +++ b/winlogbeat/sys/wineventlog/testdata/ec2.xml @@ -0,0 +1 @@ +99902000x80000000000000317ApplicationvagrantWinword event 999 happened due to low diskspace diff --git a/winlogbeat/sys/wineventlog/testdata/ec3.evtx b/winlogbeat/sys/wineventlog/testdata/ec3.evtx new file mode 100644 index 0000000000000000000000000000000000000000..fb0bdc95fceb5e06797de26bb17b28ae28138bcd GIT binary patch literal 69632 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 literal 0 HcmV?d00001 diff --git a/winlogbeat/sys/wineventlog/testdata/ec3.xml b/winlogbeat/sys/wineventlog/testdata/ec3.xml new file mode 100644 index 000000000000..fdd0622ae59f --- /dev/null +++ b/winlogbeat/sys/wineventlog/testdata/ec3.xml @@ -0,0 +1 @@ +502000x800000000000001413SystemvagrantCatastrophe! diff --git a/winlogbeat/sys/wineventlog/testdata/ec3and4.evtx b/winlogbeat/sys/wineventlog/testdata/ec3and4.evtx new file mode 100644 index 0000000000000000000000000000000000000000..74e7cd1e2cf6b1c5b16a2553ed71cd0b62eb6b13 GIT binary patch literal 69632 zcmeI$Uuf1<9LMqR^JmYVJ=16E)P{<=h)N+{l4P0DHYb)^YGz%8Fx=+mo;?${`G<8e z6)Qrri-P`K6a_&<-Bctccokk{H%01IK^GNXWFbUR>+?O&?>ufpn;>-&?=!YNzjMC7 zbI$K|&iVdy9i^W2eWh-jS~5w+n0}{CSF=)6LvHx`=s(Hor-u}v| zKVDpWF4d4q*^Ja(Ee|e@qx$EOxvO`6^x^o=vzlHybW~5`QLT-3Kp*`9y?i>O#yV`j zbz9knb^WZqb9<7;Qw=qC&<3oe#vwJ-q*ht4!iH_H-DfNGHDtR~)2*0JeO|8LeX7}K zgSr~D9z`zK^`Pok*a5Yb^?RkY=<9BMYO&S&*c?w=H4x{Ti!FQTx<-yFXIgj2mCh+9R6mfExXQa_a6%mzma# zZB~7MvPCX;)=toQ$kxT~e2;lqdZA!jZA2ZGG-8jweN4A1W-XU4W-OOY)!Qwqh+Dg< zuGV%WVSS=0t1Vruw`^96x>y%+Pj{WIu}uo}#VLg#^PsdX(#6bVV|I*YZF|7)4|P zsY9Q#&!i%sE*7ldb2+A)Vg`8YmwIatVLp#im`P-PN^$G&Nse^kQo&l)~+hbTy zTIsh~YYjQi0>134KA&wqbfqVMrfb|Z#~L!4%Yep+S>xo#b$WnKVTR!Kx)R*?yy?F`uCbkivSZDc6YJA+$Jo|b%sx8{C$WCpf za+tT)*Z1|rqmtE4D;4Z1%@=V^IUmplv@Lw1m4l+&YDLp&yEU%&H*BumrW-x)dUY|7c=dMfWTd9oSSn8_9!tvPFR6{^h_zO`5N$Lh*=-sV}} zX8Raw&4=&26++x1YYg>Q`|*V}s}G&zYU7y2q!_D?#YXLTFE#V@IC)HntzV^=#W|cqupoG?<*Fi;zxb-_l2jm@NW3;-vgbRg1-km<9m+ujPI)$^1AQ#Hi7K2er?OW z=2`qEHTrR`^B~XGlk#yvwVscwdDkm^7o@c;A;)@!A4Fe(kWszDGio(=dWGlCYKEMn z3O`(7NY8*V$9bgx1F4$77OKMYm){ZcQ#At>ldR$qo>fAG@1A1J4lxJJ_dc}3S3T=Z zYV@;yjT7y?`iTxR^>bVN7f)#GRZeK!hMGqx&*%w5x&9NX#nRjI%88h`0hZ`Z+^KU^ z3R$W<={x@N^FToW0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0;r H|0wV`q_}7! literal 0 HcmV?d00001 diff --git a/winlogbeat/sys/wineventlog/testdata/ec3and4.xml b/winlogbeat/sys/wineventlog/testdata/ec3and4.xml new file mode 100644 index 000000000000..5844cfbfe918 --- /dev/null +++ b/winlogbeat/sys/wineventlog/testdata/ec3and4.xml @@ -0,0 +1,2 @@ +502000x800000000000001414SystemvagrantBackup failure +502000x800000000000001413SystemvagrantCatastrophe! diff --git a/winlogbeat/sys/wineventlog/testdata/ec4.evtx b/winlogbeat/sys/wineventlog/testdata/ec4.evtx new file mode 100644 index 0000000000000000000000000000000000000000..94547179581c7f96ae5e8ffdef658d4b09173fe6 GIT binary patch literal 69632 zcmeI$OK4nG9LMqh%-osWOp-}sj7Tjt5nm0MgktegTgVf&t$kRl3lWAqnlzJ%G?OMF zF4C5&NVINT=tj|{(4ANx(3NIa5fsy|TnLJE6Gc!9#^3+Wy_yC~kb)b(C(PrV^S|fu zIp>~BroS{YFjgA2^(h?}Ea)?B8M95P^&vN$@BZ!T?i+4|1`t310R#|0009ILKmY** z5I|r>-u;u zZp*KKEB?MuvAt^Z{dMgmeT-@h|8=@sV`^{Lnrd9hy6^t#%GK9*EvFh&DXUK{-tyii zkMiW-kG3y8^U1w`965BhXW_JF;!)krHlwdTK~EpoXRY5(*sztYqWnvG<&MRbpEhP~ z)+Vf^$|+T3Q#))_VHJDc9=1;XP1&GIh80uP_YQrIspPm#DmQ5(itJE+QstdCqq?#_ zw_BI~?$@_2drzCF?eMIA>4VoLa6#J!*q@udY6>aV0CdG9TK3 zsP_}T=d`K4I1M&~i> zOPcdN=4spIydBh~MH!80zGG3JZdC{@mo8*17o_U!4izL@`_|eTI}(SDiKeW&bfM0I zK#RInnPg87UCi2E1^VKYq9F62v~5wQA>Nq%^MM_X@W-Q&w0D@YR%Lw8dpfr@XZtld zUk5kw?o!@T*6vg$xmAvR5!xPA&uO711veyU56xOjAm;{n%Y^z!PL1;))M^5=(ZHvpj;hQ1sE^}7W9q^cRmJ zv@qvqsW0uBhe8RD#HUd3FyM;H3J>*<}2P!0RSOe>~}Xm-15a>)@q zvNvZ>X;$85JhOUh&IE;KYYXgVg=+IfFYQ%5qpGjaS}e3C??bg=^a?E>#ci?XsQjPa zzO*)f&Y9fev|!1hn3TMjRBFe2%C_k3+lG~we;>KHc-#DsKl>e5Jwa!dxAi7xyMOS< ztE1%42@(PbAb502000x800000000000001414SystemvagrantBackup failure diff --git a/winlogbeat/sys/wineventlog/testdata/sysmon-9.01.xml b/winlogbeat/sys/wineventlog/testdata/sysmon-9.01.xml new file mode 100644 index 000000000000..82a6ff6dca4e --- /dev/null +++ b/winlogbeat/sys/wineventlog/testdata/sysmon-9.01.xml @@ -0,0 +1,32 @@ +244200x800000000000000032Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.433{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeC:\Users\vagrant\AppData\Local\Google\Chrome\User Data\Default\Storage\ext\gfdkimpbcpahaombhbimeihdjnejgicl\def\ee4a6e45-bffd-49f4-98ae-32aebcc890b5.tmp2019-03-18 16:52:05.3392019-03-18 16:57:52.417 +244200x800000000000000031Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.433{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeC:\Users\vagrant\AppData\Local\Google\Chrome\User Data\Default\Storage\ext\nmmhkkegccagdldgiimedpiccmgmieda\def\ecb9c915-c4c2-4600-a920-f2bc302990a8.tmp2019-03-18 16:52:08.4962019-03-18 16:57:52.417 +534500x800000000000000030Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.433{42f11c3b-ccab-5c8f-0000-001064eb2700}2680C:\Program Files (x86)\Google\Chrome\Application\chrome.exe +244200x800000000000000029Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.417{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeC:\Users\vagrant\AppData\Local\Google\Chrome\User Data\Default\37ed32e9-3c5f-4663-8457-c70743e9456d.tmp2019-03-18 16:51:54.9802019-03-18 16:57:52.417 +244200x800000000000000028Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.417{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeC:\Users\vagrant\AppData\Local\Google\Chrome\User Data\Default\1450fedf-ac4c-4e35-b371-ed5d3bbe4776.tmp2019-03-18 16:52:05.0282019-03-18 16:57:52.402 +244200x800000000000000027Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.417{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeC:\Users\vagrant\AppData\Local\Google\Chrome\User Data\162d4140-cfab-4d05-9c92-bca60515a622.tmp2019-03-18 16:52:04.9802019-03-18 16:57:52.402 +244200x800000000000000026Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.387{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeC:\Users\vagrant\AppData\Local\Google\Chrome\User Data\fe823684-c940-49f2-a940-14b02cbafba9.tmp2019-03-18 16:52:04.9802019-03-18 16:57:52.387 +534500x800000000000000025Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.364{42f11c3b-cccc-5c8f-0000-0010e8272900}3208C:\Program Files (x86)\Google\Chrome\Application\chrome.exe +534500x800000000000000024Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:52.350{42f11c3b-ccc6-5c8f-0000-001005082900}4832C:\Program Files (x86)\Google\Chrome\Application\chrome.exe +354300x800000000000000023Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:49.218{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudptruefalse10.0.2.15vagrant-2012-r2.local.crowbird.com137netbios-nsfalse169.254.180.25137netbios-ns +354300x800000000000000022Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:49.213{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudptruefalse10.0.2.15vagrant-2012-r2.local.crowbird.com137netbios-nsfalse169.254.255.255137netbios-ns +354300x800000000000000021Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.276{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudptruefalse10.0.2.15vagrant-2012-r2.local.crowbird.com137netbios-nsfalse10.0.2.3137netbios-ns +354300x800000000000000020Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.264{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudptruefalse10.0.2.15vagrant-2012-r2.local.crowbird.com137netbios-nsfalse40.77.226.250137netbios-ns +354300x800000000000000019Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.251{42f11c3b-0bad-5c8c-0000-0010dfbc0000}924C:\Windows\System32\svchost.exeNT AUTHORITY\NETWORK SERVICEudptruetruea9fe:b419:0:0:f880:2301:e0:ffff55717truee000:fc:0:0:0:0:0:05355llmnr +354300x800000000000000018Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.251{42f11c3b-0bad-5c8c-0000-0010dfbc0000}924C:\Windows\System32\svchost.exeNT AUTHORITY\NETWORK SERVICEudptruetruefe80:0:0:0:616f:32fa:b04f:b41955717trueff02:0:0:0:0:0:1:35355llmnr +354300x800000000000000017Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.251{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudpfalsefalse169.254.255.255137netbios-nsfalse169.254.180.25137netbios-ns +354300x800000000000000016Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.250{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudptruefalse169.254.180.25137netbios-nsfalse169.254.255.255137netbios-ns +354300x800000000000000015Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.250{42f11c3b-0bad-5c8c-0000-0010dfbc0000}924C:\Windows\System32\svchost.exeNT AUTHORITY\NETWORK SERVICEudptruetruea00:20f:0:0:18a2:6e00:e0:ffff55542truee000:fc:4300:6800:7200:6f00:6d00:65005355llmnr +354300x800000000000000014Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.250{42f11c3b-0bad-5c8c-0000-0010dfbc0000}924C:\Windows\System32\svchost.exeNT AUTHORITY\NETWORK SERVICEudptruetruefe80:0:0:0:e488:b85c:5262:ff86vagrant-2012-r2.local.crowbird.com55542trueff02:0:0:0:0:0:1:35355llmnr +354300x800000000000000013Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.250{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudpfalsefalse10.0.2.255137netbios-nsfalse10.0.2.15vagrant-2012-r2.local.crowbird.com137netbios-ns +354300x800000000000000012Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.250{42f11c3b-6e19-5c8c-0000-0010eb030000}4SystemNT AUTHORITY\SYSTEMudptruefalse10.0.2.15vagrant-2012-r2.local.crowbird.com137netbios-nsfalse10.0.2.255137netbios-ns +354300x800000000000000011Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.214{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeVAGRANT-2012-R2\vagranttcptruefalse10.0.2.15vagrant-2012-r2.local.crowbird.com1139false40.77.226.250443https +354300x800000000000000010Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.148{42f11c3b-ccaa-5c8f-0000-0010b4e22700}1600C:\Program Files (x86)\Google\Chrome\Application\chrome.exeVAGRANT-2012-R2\vagranttcptruefalse10.0.2.15vagrant-2012-r2.local.crowbird.com1138false40.77.226.250443https +354300x80000000000000009Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:48.070{42f11c3b-0bad-5c8c-0000-0010dfbc0000}924C:\Windows\System32\svchost.exeNT AUTHORITY\NETWORK SERVICEudpfalsefalse10.0.2.15vagrant-2012-r2.local.crowbird.com62141false10.0.2.353domain +354300x80000000000000008Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:47.847{42f11c3b-0bad-5c8c-0000-0010dfbc0000}924C:\Windows\System32\svchost.exeNT AUTHORITY\NETWORK SERVICEudptruetruea00:20f:0:0:18a2:6e00:e0:ffff62141truea00:203:3000:3000:3000:3000:3000:330053domain +154100x80000000000000007Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:39.012{42f11c3b-ce03-5c8f-0000-0010e9462a00}4508C:\Windows\System32\wbem\WmiPrvSE.exe6.3.9600.16384 (winblue_rtm.130821-1623)WMI Provider HostMicrosoft® Windows® Operating SystemMicrosoft CorporationC:\Windows\system32\wbem\wmiprvse.exe -EmbeddingC:\Windows\system32\NT AUTHORITY\SYSTEM{42f11c3b-6e1a-5c8c-0000-0020e7030000}0x3e70SystemSHA1=5A4C0E82FF95C9FB762D46A696EF9F1B68001C21{42f11c3b-6e1b-5c8c-0000-00102f610000}560C:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k DcomLaunch +534500x80000000000000006Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:38.981{42f11c3b-cdf4-5c8f-0000-0010071e2a00}4648C:\Users\vagrant\Downloads\Sysmon.exe +534500x80000000000000005Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:38.981{42f11c3b-cdf4-5c8f-0000-0010e61e2a00}4616C:\Users\vagrant\AppData\Local\Temp\Sysmon.exe +154100x80000000000000004Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:37.964{42f11c3b-ce01-5c8f-0000-00102c412a00}5028C:\Windows\System32\wbem\unsecapp.exe6.3.9600.16384 (winblue_rtm.130821-1623)Sink to receive asynchronous callbacks for WMI client applicationMicrosoft® Windows® Operating SystemMicrosoft CorporationC:\Windows\system32\wbem\unsecapp.exe -EmbeddingC:\Windows\system32\NT AUTHORITY\SYSTEM{42f11c3b-6e1a-5c8c-0000-0020e7030000}0x3e70SystemSHA1=6DF8163A6320B80B60733F9D62E2F39B4B16B678{42f11c3b-6e1b-5c8c-0000-00102f610000}560C:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k DcomLaunch +154100x80000000000000003Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:37.949{42f11c3b-ce01-5c8f-0000-0010c73e2a00}4860C:\Windows\Sysmon.exe9.01System activity monitorSysinternals SysmonSysinternals - www.sysinternals.comC:\Windows\Sysmon.exeC:\Windows\system32\NT AUTHORITY\SYSTEM{42f11c3b-6e1a-5c8c-0000-0020e7030000}0x3e70SystemSHA1=AC93C3B38E57A2715572933DBCB2A1C2892DBC5E{42f11c3b-6e1a-5c8c-0000-0010f14d0000}488C:\Windows\System32\services.exeC:\Windows\system32\services.exe +434400x80000000000000002Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:38.011Started9.014.20 +16341600x80000000000000001Microsoft-Windows-Sysmon/Operationalvagrant-2012-r22019-03-18 16:57:37.933C:\Users\vagrant\Downloads\"C:\Users\vagrant\Downloads\Sysmon.exe" -i -n diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index 11cd5319e684..3e38391754a2 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -384,7 +384,8 @@ func FormatEventString( // Open a publisher handle if one was not provided. ph := publisherHandle if ph == 0 { - ph, err := OpenPublisherMetadata(0, publisher, lang) + var err error + ph, err = OpenPublisherMetadata(0, publisher, lang) if err != nil { return err } diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index ff4fe566e9c2..871e48dcb975 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -19,78 +19,116 @@ package wineventlog import ( "bytes" + "flag" + "fmt" + "io" "os" "path/filepath" "testing" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" ) -var sysmonEvtx string - -func init() { - var err error - sysmonEvtx, err = filepath.Abs("testdata/sysmon-9.01.evtx") - if err != nil { - panic(err) - } - - if _, err = os.Lstat(sysmonEvtx); err != nil { - panic(err) - } -} - -func TestEvtOpenLog(t *testing.T) { - h, err := EvtOpenLog(0, sysmonEvtx, EvtOpenFilePath) - if err != nil { - t.Fatal(err) - } - defer Close(h) -} - -func TestEvtQuery(t *testing.T) { - h, err := EvtQuery(0, sysmonEvtx, "", EvtQueryFilePath) - if err != nil { - t.Fatal(err) - } - defer Close(h) -} - -func TestReadEvtx(t *testing.T) { - // Open .evtx file. - h, err := EvtQuery(0, sysmonEvtx, "", EvtQueryFilePath|EvtQueryReverseDirection) - if err != nil { - t.Fatal(err) - } - defer Close(h) - - // Get handles to events. - buf := make([]byte, 32*1024) - out := new(bytes.Buffer) - count := 0 - for { - handles, err := EventHandles(h, 8) - if err == ERROR_NO_MORE_ITEMS { - t.Log(err) - break - } - if err != nil { - t.Fatal(err) - } +var updateXML = flag.Bool("update", false, "update XML golden files from evtx files in testdata") + +func TestWinEventLog(t *testing.T) { + for _, test := range []struct { + path string + events int + }{ + {path: "sysmon-9.01.evtx", events: 32}, + {path: "ec1.evtx", events: 1}, // eventcreate /id 1000 /t error /l application /d "My custom error event for the application log" + {path: "ec2.evtx", events: 1}, // eventcreate /id 999 /t error /l application /so WinWord /d "Winword event 999 happened due to low diskspace" + {path: "ec3.evtx", events: 1}, // eventcreate /id 5 /t error /l system /d "Catastrophe!" + {path: "ec4.evtx", events: 1}, // eventcreate /id 5 /t error /l system /so Backup /d "Backup failure" + {path: "ec3and4.evtx", events: 2}, // ec3 and ec3 exported as a single evtx. + } { + t.Run(test.path, func(t *testing.T) { + evtx, err := filepath.Abs(filepath.Join("testdata", test.path)) + if err != nil { + t.Fatal(err) + } + xmlPath := evtx[:len(evtx)-len("evtx")] + "xml" - // Read events. - for _, h := range handles { - out.Reset() - if err = RenderEventXML(h, buf, out); err != nil { + if _, err = os.Lstat(evtx); err != nil { t.Fatal(err) } - Close(h) - count++ - } - } - if count != 32 { - t.Fatal("expected to read 32 events but got", count, "from", sysmonEvtx) + t.Run("EvtOpenLog", func(t *testing.T) { + h, err := EvtOpenLog(0, evtx, EvtOpenFilePath) + if err != nil { + t.Fatal(err) + } + defer Close(h) + }) + + t.Run("EvtQuery", func(t *testing.T) { + h, err := EvtQuery(0, evtx, "", EvtQueryFilePath) + if err != nil { + t.Fatal(err) + } + defer Close(h) + }) + + t.Run("ReadEvtx", func(t *testing.T) { + // Open .evtx file. + h, err := EvtQuery(0, evtx, "", EvtQueryFilePath|EvtQueryReverseDirection) + if err != nil { + t.Fatal(err) + } + defer Close(h) + + // Get handles to events. + buf := make([]byte, 32*1024) + var out io.Writer + if *updateXML { + f, err := os.Create(xmlPath) + if err != nil { + t.Fatalf("failed to create golden file: %v", err) + } + defer f.Close() + out = f + } else { + out = &bytes.Buffer{} + } + var count int + for { + handles, err := EventHandles(h, 8) + if err == ERROR_NO_MORE_ITEMS { + t.Log(err) + break + } + if err != nil { + t.Fatal(err) + } + + // Read events. + for _, h := range handles { + if err = RenderEventXML(h, buf, out); err != nil { + t.Fatal(err) + } + Close(h) + fmt.Fprintln(out) + count++ + } + } + if !*updateXML { + want, err := os.ReadFile(xmlPath) + if err != nil { + t.Fatalf("failed to read golden file: %v", err) + } + got := out.(*bytes.Buffer).Bytes() + if !bytes.Equal(want, got) { + t.Errorf("unexpected result for %s: want:\n%s", test.path, cmp.Diff(want, got)) + } + } + + if count != test.events { + t.Errorf("expected to read %d events but got %d from %s", test.events, count, test.path) + } + }) + }) } } From 40a431827ca7a68ef2ee22b768b658684ec76bbb Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Tue, 22 Mar 2022 19:19:37 +1030 Subject: [PATCH 02/19] make tests robust to case change in hex values --- .../wineventlog/wineventlog_windows_test.go | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index 871e48dcb975..56fae71b489d 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -19,15 +19,20 @@ package wineventlog import ( "bytes" + "encoding/xml" "flag" "fmt" "io" "os" "path/filepath" + "reflect" + "strings" "testing" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/v7/winlogbeat/sys/winevent" ) var updateXML = flag.Bool("update", false, "update XML golden files from evtx files in testdata") @@ -114,13 +119,20 @@ func TestWinEventLog(t *testing.T) { } } if !*updateXML { - want, err := os.ReadFile(xmlPath) + f, err := os.Open(xmlPath) if err != nil { t.Fatalf("failed to read golden file: %v", err) } - got := out.(*bytes.Buffer).Bytes() - if !bytes.Equal(want, got) { - t.Errorf("unexpected result for %s: want:\n%s", test.path, cmp.Diff(want, got)) + want, err := unmarshalXMLEvents(f) + if err != nil { + t.Fatalf("failed to unmarshal golden events: %v", err) + } + got, err := unmarshalXMLEvents(out.(*bytes.Buffer)) + if err != nil { + t.Fatalf("failed to unmarshal obtained events: %v", err) + } + if !reflect.DeepEqual(want, got) { + t.Errorf("unexpected result for %s: got:- want:+\n%s", test.path, cmp.Diff(want, got)) } } @@ -132,6 +144,37 @@ func TestWinEventLog(t *testing.T) { } } +// unmarshalXMLEvents unmarshals a complete set of events from the XML data +// in the provided io.Reader. GUID values are canonicalised to lowercase. +func unmarshalXMLEvents(r io.Reader) ([]winevent.Event, error) { + var events []winevent.Event + decoder := xml.NewDecoder(r) + for { + var e winevent.Event + err := decoder.Decode(&e) + if err != nil { + if err != io.EOF { + return nil, err + } + break + } + events = append(events, canonical(e)) + } + return events, nil +} + +// canonical return e with its GUID values canonicalised to lower case. +// Different versions of Windows render these values in different cases; ¯\_(ツ)_/¯ +func canonical(e winevent.Event) winevent.Event { + e.Provider.GUID = strings.ToLower(e.Provider.GUID) + for i, kv := range e.EventData.Pairs { + if strings.Contains(strings.ToLower(kv.Key), "guid") { + e.EventData.Pairs[i].Value = strings.ToLower(kv.Value) + } + } + return e +} + func TestChannels(t *testing.T) { channels, err := Channels() if err != nil { From 22c73e197f2d466cf22cc0d3f99214fa9d812430 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Tue, 22 Mar 2022 16:54:58 -0400 Subject: [PATCH 03/19] Enable windows-2022 for Winlogbeat testing --- winlogbeat/Jenkinsfile.yml | 5 +++++ x-pack/winlogbeat/Jenkinsfile.yml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/winlogbeat/Jenkinsfile.yml b/winlogbeat/Jenkinsfile.yml index eece9aaa2c39..db43d1ed0270 100644 --- a/winlogbeat/Jenkinsfile.yml +++ b/winlogbeat/Jenkinsfile.yml @@ -24,6 +24,11 @@ stages: crosscompile: make: "make -C winlogbeat crosscompile" stage: mandatory + windows-2022: + mage: "mage build unitTest" + platforms: ## override default labels in this specific stage. + - "windows-2022" + stage: mandatory windows-2019: mage: "mage build unitTest" platforms: ## override default labels in this specific stage. diff --git a/x-pack/winlogbeat/Jenkinsfile.yml b/x-pack/winlogbeat/Jenkinsfile.yml index 9eb81c516320..4971257eefaf 100644 --- a/x-pack/winlogbeat/Jenkinsfile.yml +++ b/x-pack/winlogbeat/Jenkinsfile.yml @@ -29,6 +29,11 @@ stages: platforms: ## override default labels in this specific stage. - "windows-2019" stage: mandatory + windows-2022: + mage: "mage build unitTest" + platforms: ## override default labels in this specific stage. + - "windows-2022" + stage: mandatory windows-2019: mage: "mage build unitTest" platforms: ## override default labels in this specific stage. From eda802be94e953069ba948dc154248d988c196d6 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 09:22:41 +1030 Subject: [PATCH 04/19] fix lint and add failer --- winlogbeat/eventlog/wineventlog_test.go | 13 +++++++ winlogbeat/sys/wineventlog/format_message.go | 10 +++--- .../sys/wineventlog/wineventlog_windows.go | 35 +++++++++---------- .../wineventlog/wineventlog_windows_test.go | 2 +- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/winlogbeat/eventlog/wineventlog_test.go b/winlogbeat/eventlog/wineventlog_test.go index 0dc33b5098ae..021251eea4ea 100644 --- a/winlogbeat/eventlog/wineventlog_test.go +++ b/winlogbeat/eventlog/wineventlog_test.go @@ -31,6 +31,7 @@ import ( "github.com/andrewkroh/sys/windows/svc/eventlog" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/winlogbeat/checkpoint" @@ -189,6 +190,18 @@ func testWindowsEventLog(t *testing.T, api string) { return openLog(t, api, nil, config) } + t.Run("has_message", func(t *testing.T) { + log := openLog(t, map[string]interface{}{"name": providerName, "batch_read_size": 1}) + defer log.Close() + + records, err := log.Read() + require.NotEmpty(t, records) + require.NoError(t, err) + + r := records[0] + require.NotEmpty(t, r.Message, "message field is empty: errors:%v\nrecord:%#v", r.Event.RenderErr, r) + }) + // Test reading from an event log using a custom XML query. t.Run("custom_xml_query", func(t *testing.T) { cfg := map[string]interface{}{ diff --git a/winlogbeat/sys/wineventlog/format_message.go b/winlogbeat/sys/wineventlog/format_message.go index 24ce23140852..74ea663fb636 100644 --- a/winlogbeat/sys/wineventlog/format_message.go +++ b/winlogbeat/sys/wineventlog/format_message.go @@ -21,9 +21,9 @@ package wineventlog import ( + "fmt" "unsafe" - "github.com/pkg/errors" "golang.org/x/sys/windows" "github.com/elastic/beats/v7/winlogbeat/sys" @@ -80,8 +80,8 @@ func evtFormatMessage(metadataHandle EvtHandle, eventHandle EvtHandle, messageID // Determine the buffer size needed (given in WCHARs). var bufferUsed uint32 err := _EvtFormatMessage(metadataHandle, eventHandle, messageID, valuesCount, valuesPtr, messageFlag, 0, nil, &bufferUsed) - if err != windows.ERROR_INSUFFICIENT_BUFFER { - return "", errors.Wrap(err, "failed in EvtFormatMessage") + if err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint This is an errno. + return "", fmt.Errorf("failed in EvtFormatMessage: %w", err) } // Get a buffer from the pool and adjust its length. @@ -90,7 +90,7 @@ func evtFormatMessage(metadataHandle EvtHandle, eventHandle EvtHandle, messageID bb.Reserve(int(bufferUsed * 2)) err = _EvtFormatMessage(metadataHandle, eventHandle, messageID, valuesCount, valuesPtr, messageFlag, uint32(bb.Len()), bb.PtrAt(0), &bufferUsed) - switch err { + switch err { //nolint:errorlint This is an errno or nil. case nil: // OK // Ignore some errors so it can tolerate missing or mismatched parameter values. @@ -99,7 +99,7 @@ func evtFormatMessage(metadataHandle EvtHandle, eventHandle EvtHandle, messageID windows.ERROR_EVT_MAX_INSERTS_REACHED: default: - return "", errors.Wrap(err, "failed in EvtFormatMessage") + return "", fmt.Errorf("failed in EvtFormatMessage: %w", err) } return sys.UTF16BytesToString(bb.Bytes()) diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index 3e38391754a2..3c52b26ddba4 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -74,7 +74,7 @@ func Channels() ([]string, error) { if err != nil { return nil, err } - defer _EvtClose(handle) + defer _EvtClose(handle) //nolint:errcheck This is just a resource release. var channels []string cpBuffer := make([]uint16, 512) @@ -83,7 +83,7 @@ loop: var used uint32 err := _EvtNextChannelPath(handle, uint32(len(cpBuffer)), &cpBuffer[0], &used) if err != nil { - errno, ok := err.(syscall.Errno) + errno, ok := err.(syscall.Errno) //nolint:errorlint This is an errno or nil. if ok { switch errno { case ERROR_INSUFFICIENT_BUFFER: @@ -203,7 +203,7 @@ func EventHandles(subscription EvtHandle, maxHandles int) ([]EvtHandle, error) { // Munge ERROR_INVALID_OPERATION to ERROR_NO_MORE_ITEMS when no handles // were read. This happens you call the method and there are no events // to read (i.e. polling). - if err == ERROR_INVALID_OPERATION && numRead == 0 { + if err == ERROR_INVALID_OPERATION && numRead == 0 { //nolint:errorlint This is an errno or nil. return nil, ERROR_NO_MORE_ITEMS } return nil, err @@ -241,12 +241,11 @@ func RenderEvent( // Only a single string is returned when rendering XML. err = FormatEventString(EvtFormatMessageXml, eventHandle, providerName, EvtHandle(publisherHandle), lang, renderBuf, out) - // Recover by rendering the XML without the RenderingInfo (message string). if err != nil { // Do not try to recover from InsufficientBufferErrors because these // can be retried with a larger buffer. - if _, ok := err.(sys.InsufficientBufferError); ok { + if errors.Is(err, sys.InsufficientBufferError{}) { return err } @@ -315,7 +314,7 @@ func CreateBookmarkFromXML(bookmarkXML string) (EvtHandle, error) { // CreateRenderContext creates a render context. Close must be called on // returned EvtHandle when finished with the handle. func CreateRenderContext(valuePaths []string, flag EvtRenderContextFlag) (EvtHandle, error) { - var paths []uintptr + paths := make([]uintptr, 0, len(valuePaths)) for _, path := range valuePaths { utf16, err := syscall.UTF16FromString(path) if err != nil { @@ -389,7 +388,7 @@ func FormatEventString( if err != nil { return err } - defer _EvtClose(ph) + defer _EvtClose(ph) //nolint:errcheck This is just a resource release. } // Create a buffer if one was not provided. @@ -397,7 +396,7 @@ func FormatEventString( if buffer == nil { err := _EvtFormatMessage(ph, eventHandle, 0, 0, 0, messageFlag, 0, nil, &bufferUsed) - if err != nil && err != ERROR_INSUFFICIENT_BUFFER { + if err != nil && err != ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint This is an errno or nil. return err } @@ -409,8 +408,8 @@ func FormatEventString( err := _EvtFormatMessage(ph, eventHandle, 0, 0, 0, messageFlag, uint32(len(buffer)/2), &buffer[0], &bufferUsed) bufferUsed *= 2 - if err == ERROR_INSUFFICIENT_BUFFER { - return sys.InsufficientBufferError{err, int(bufferUsed)} + if err == ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint This is an errno or nil. + return sys.InsufficientBufferError{Cause: err, RequiredSize: int(bufferUsed)} } if err != nil { return err @@ -427,7 +426,7 @@ func Publishers() ([]string, error) { if err != nil { return nil, fmt.Errorf("failed in EvtOpenPublisherEnum: %w", err) } - defer Close(publisherEnumerator) + defer Close(publisherEnumerator) //nolint:errcheck This is just a resource release. var ( publishers []string @@ -438,7 +437,7 @@ func Publishers() ([]string, error) { loop: for { if err = _EvtNextPublisherId(publisherEnumerator, uint32(len(buffer)), &buffer[0], &bufferUsed); err != nil { - switch err { + switch err { //nolint:errorlint This is an errno or nil. case ERROR_NO_MORE_ITEMS: break loop case ERROR_INSUFFICIENT_BUFFER: @@ -467,7 +466,7 @@ func offset(buffer []byte, reader io.Reader) (uint64, error) { var err error switch runtime.GOARCH { default: - return 0, fmt.Errorf("Unhandled architecture: %s", runtime.GOARCH) + return 0, fmt.Errorf("unhandled architecture: %s", runtime.GOARCH) case "amd64": err = binary.Read(reader, binary.LittleEndian, &dataPtr) if err != nil { @@ -490,7 +489,7 @@ func offset(buffer []byte, reader io.Reader) (uint64, error) { offset := dataPtr - bufferPtr if offset > uint64(len(buffer)) { - return 0, fmt.Errorf("Invalid pointer %x. Cannot dereference an "+ + return 0, fmt.Errorf("invalid pointer %x: cannot dereference an "+ "address outside of the buffer [%x:%x].", dataPtr, bufferPtr, bufferPtr+uint64(len(buffer))) } @@ -504,7 +503,7 @@ func readString(buffer []byte, reader io.Reader) (string, error) { offset, err := offset(buffer, reader) if err != nil { // Ignore NULL values. - if err == ErrorEvtVarTypeNull { + if err == ErrorEvtVarTypeNull { //nolint:errorlint This is never wrapped. return "", nil } return "", err @@ -519,7 +518,7 @@ func evtRenderProviderName(renderBuf []byte, eventHandle EvtHandle) (string, err err := _EvtRender(providerNameContext, eventHandle, EvtRenderEventValues, uint32(len(renderBuf)), &renderBuf[0], &bufferUsed, &propertyCount) if err == ERROR_INSUFFICIENT_BUFFER { - return "", sys.InsufficientBufferError{err, int(bufferUsed)} + return "", sys.InsufficientBufferError{Cause: err, RequiredSize: int(bufferUsed)} } if err != nil { return "", fmt.Errorf("evtRenderProviderName %v", err) @@ -534,7 +533,7 @@ func renderXML(eventHandle EvtHandle, flag EvtRenderFlag, renderBuf []byte, out err := _EvtRender(0, eventHandle, flag, uint32(len(renderBuf)), &renderBuf[0], &bufferUsed, &propertyCount) if err == ERROR_INSUFFICIENT_BUFFER { - return sys.InsufficientBufferError{err, int(bufferUsed)} + return sys.InsufficientBufferError{Cause: err, RequiredSize: int(bufferUsed)} } if err != nil { return err @@ -543,7 +542,7 @@ func renderXML(eventHandle EvtHandle, flag EvtRenderFlag, renderBuf []byte, out if int(bufferUsed) > len(renderBuf) { return fmt.Errorf("Windows EvtRender reported that wrote %d bytes "+ "to the buffer, but the buffer can only hold %d bytes", - bufferUsed, len(renderBuf)) + bufferUsed, len(renderBuf)) //nolint:stylecheck These are proper nouns. } return common.UTF16ToUTF8Bytes(renderBuf[:bufferUsed], out) } diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index 56fae71b489d..b42b315eaac9 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -153,7 +153,7 @@ func unmarshalXMLEvents(r io.Reader) ([]winevent.Event, error) { var e winevent.Event err := decoder.Decode(&e) if err != nil { - if err != io.EOF { + if err != io.EOF { //nolint:errorlint This is never wrapped. return nil, err } break From 1efa3272dc30b12185db06576d1d4dca44664735 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 10:25:22 +1030 Subject: [PATCH 05/19] add syntax --- winlogbeat/sys/wineventlog/format_message.go | 4 ++-- .../sys/wineventlog/wineventlog_windows.go | 20 +++++++++---------- .../wineventlog/wineventlog_windows_test.go | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/winlogbeat/sys/wineventlog/format_message.go b/winlogbeat/sys/wineventlog/format_message.go index 74ea663fb636..642eaa69965b 100644 --- a/winlogbeat/sys/wineventlog/format_message.go +++ b/winlogbeat/sys/wineventlog/format_message.go @@ -80,7 +80,7 @@ func evtFormatMessage(metadataHandle EvtHandle, eventHandle EvtHandle, messageID // Determine the buffer size needed (given in WCHARs). var bufferUsed uint32 err := _EvtFormatMessage(metadataHandle, eventHandle, messageID, valuesCount, valuesPtr, messageFlag, 0, nil, &bufferUsed) - if err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint This is an errno. + if err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // This is an errno. return "", fmt.Errorf("failed in EvtFormatMessage: %w", err) } @@ -90,7 +90,7 @@ func evtFormatMessage(metadataHandle EvtHandle, eventHandle EvtHandle, messageID bb.Reserve(int(bufferUsed * 2)) err = _EvtFormatMessage(metadataHandle, eventHandle, messageID, valuesCount, valuesPtr, messageFlag, uint32(bb.Len()), bb.PtrAt(0), &bufferUsed) - switch err { //nolint:errorlint This is an errno or nil. + switch err { //nolint:errorlint // This is an errno or nil. case nil: // OK // Ignore some errors so it can tolerate missing or mismatched parameter values. diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index 3c52b26ddba4..e21e2aafc95f 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -74,7 +74,7 @@ func Channels() ([]string, error) { if err != nil { return nil, err } - defer _EvtClose(handle) //nolint:errcheck This is just a resource release. + defer _EvtClose(handle) //nolint:errcheck // This is just a resource release. var channels []string cpBuffer := make([]uint16, 512) @@ -83,7 +83,7 @@ loop: var used uint32 err := _EvtNextChannelPath(handle, uint32(len(cpBuffer)), &cpBuffer[0], &used) if err != nil { - errno, ok := err.(syscall.Errno) //nolint:errorlint This is an errno or nil. + errno, ok := err.(syscall.Errno) //nolint:errorlint // This is an errno or nil. if ok { switch errno { case ERROR_INSUFFICIENT_BUFFER: @@ -203,7 +203,7 @@ func EventHandles(subscription EvtHandle, maxHandles int) ([]EvtHandle, error) { // Munge ERROR_INVALID_OPERATION to ERROR_NO_MORE_ITEMS when no handles // were read. This happens you call the method and there are no events // to read (i.e. polling). - if err == ERROR_INVALID_OPERATION && numRead == 0 { //nolint:errorlint This is an errno or nil. + if err == ERROR_INVALID_OPERATION && numRead == 0 { //nolint:errorlint // This is an errno or nil. return nil, ERROR_NO_MORE_ITEMS } return nil, err @@ -388,7 +388,7 @@ func FormatEventString( if err != nil { return err } - defer _EvtClose(ph) //nolint:errcheck This is just a resource release. + defer _EvtClose(ph) //nolint:errcheck // This is just a resource release. } // Create a buffer if one was not provided. @@ -396,7 +396,7 @@ func FormatEventString( if buffer == nil { err := _EvtFormatMessage(ph, eventHandle, 0, 0, 0, messageFlag, 0, nil, &bufferUsed) - if err != nil && err != ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint This is an errno or nil. + if err != nil && err != ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // This is an errno or nil. return err } @@ -408,7 +408,7 @@ func FormatEventString( err := _EvtFormatMessage(ph, eventHandle, 0, 0, 0, messageFlag, uint32(len(buffer)/2), &buffer[0], &bufferUsed) bufferUsed *= 2 - if err == ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint This is an errno or nil. + if err == ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // This is an errno or nil. return sys.InsufficientBufferError{Cause: err, RequiredSize: int(bufferUsed)} } if err != nil { @@ -426,7 +426,7 @@ func Publishers() ([]string, error) { if err != nil { return nil, fmt.Errorf("failed in EvtOpenPublisherEnum: %w", err) } - defer Close(publisherEnumerator) //nolint:errcheck This is just a resource release. + defer Close(publisherEnumerator) //nolint:errcheck // This is just a resource release. var ( publishers []string @@ -437,7 +437,7 @@ func Publishers() ([]string, error) { loop: for { if err = _EvtNextPublisherId(publisherEnumerator, uint32(len(buffer)), &buffer[0], &bufferUsed); err != nil { - switch err { //nolint:errorlint This is an errno or nil. + switch err { //nolint:errorlint // This is an errno or nil. case ERROR_NO_MORE_ITEMS: break loop case ERROR_INSUFFICIENT_BUFFER: @@ -503,7 +503,7 @@ func readString(buffer []byte, reader io.Reader) (string, error) { offset, err := offset(buffer, reader) if err != nil { // Ignore NULL values. - if err == ErrorEvtVarTypeNull { //nolint:errorlint This is never wrapped. + if err == ErrorEvtVarTypeNull { //nolint:errorlint // This is never wrapped. return "", nil } return "", err @@ -542,7 +542,7 @@ func renderXML(eventHandle EvtHandle, flag EvtRenderFlag, renderBuf []byte, out if int(bufferUsed) > len(renderBuf) { return fmt.Errorf("Windows EvtRender reported that wrote %d bytes "+ "to the buffer, but the buffer can only hold %d bytes", - bufferUsed, len(renderBuf)) //nolint:stylecheck These are proper nouns. + bufferUsed, len(renderBuf)) //nolint:stylecheck // These are proper nouns. } return common.UTF16ToUTF8Bytes(renderBuf[:bufferUsed], out) } diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index b42b315eaac9..3dced938bb8a 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -153,7 +153,7 @@ func unmarshalXMLEvents(r io.Reader) ([]winevent.Event, error) { var e winevent.Event err := decoder.Decode(&e) if err != nil { - if err != io.EOF { //nolint:errorlint This is never wrapped. + if err != io.EOF { //nolint:errorlint // This is never wrapped. return nil, err } break From 73e7171f21587aaaee27a16b2876d10c4df9cce1 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 10:40:02 +1030 Subject: [PATCH 06/19] more nolint directives --- winlogbeat/eventlog/wineventlog_test.go | 6 ++++-- winlogbeat/sys/wineventlog/wineventlog_windows.go | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/winlogbeat/eventlog/wineventlog_test.go b/winlogbeat/eventlog/wineventlog_test.go index 021251eea4ea..0a5bdac62c10 100644 --- a/winlogbeat/eventlog/wineventlog_test.go +++ b/winlogbeat/eventlog/wineventlog_test.go @@ -315,16 +315,18 @@ func createLog(t testing.TB, messageFiles ...string) (log *eventlog.Log, tearDow } if existed { - wineventlog.EvtClearLog(wineventlog.NilHandle, name, "") + wineventlog.EvtClearLog(wineventlog.NilHandle, name, "") //nolint:errcheck // This is just a resource release. } log, err = eventlog.Open(source) + //nolint:errcheck // This is just a resource release. if err != nil { eventlog.RemoveSource(name, source) eventlog.RemoveProvider(name) t.Fatal(err) } + //nolint:errcheck // This is just a resource release. tearDown = func() { log.Close() wineventlog.EvtClearLog(wineventlog.NilHandle, name, "") @@ -351,7 +353,7 @@ func safeWriteEvent(t testing.TB, log *eventlog.Log, etype uint16, eid uint32, m // setLogSize set the maximum number of bytes that an event log can hold. func setLogSize(t testing.TB, provider string, sizeBytes int) { - output, err := exec.Command("wevtutil.exe", "sl", "/ms:"+strconv.Itoa(sizeBytes), provider).CombinedOutput() + output, err := exec.Command("wevtutil.exe", "sl", "/ms:"+strconv.Itoa(sizeBytes), provider).CombinedOutput() //nolint:gosec // No possibility of command injection. if err != nil { t.Fatal("Failed to set log size", err, string(output)) } diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index e21e2aafc95f..4c4078578ec7 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -521,7 +521,7 @@ func evtRenderProviderName(renderBuf []byte, eventHandle EvtHandle) (string, err return "", sys.InsufficientBufferError{Cause: err, RequiredSize: int(bufferUsed)} } if err != nil { - return "", fmt.Errorf("evtRenderProviderName %v", err) + return "", fmt.Errorf("evtRenderProviderName: %w", err) } reader := bytes.NewReader(renderBuf) From ebd6963e8928dc2d54ef7c93db9c9769b677dee8 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 11:09:48 +1030 Subject: [PATCH 07/19] add event logs created by the eventlog test set-up --- .../sys/wineventlog/testdata/experimental.evtx | Bin 0 -> 69632 bytes .../sys/wineventlog/testdata/experimental.xml | 5 +++++ .../sys/wineventlog/testdata/original.evtx | Bin 0 -> 69632 bytes .../sys/wineventlog/testdata/original.xml | 5 +++++ .../sys/wineventlog/wineventlog_windows_test.go | 12 +++++++----- 5 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 winlogbeat/sys/wineventlog/testdata/experimental.evtx create mode 100644 winlogbeat/sys/wineventlog/testdata/experimental.xml create mode 100644 winlogbeat/sys/wineventlog/testdata/original.evtx create mode 100644 winlogbeat/sys/wineventlog/testdata/original.xml diff --git a/winlogbeat/sys/wineventlog/testdata/experimental.evtx b/winlogbeat/sys/wineventlog/testdata/experimental.evtx new file mode 100644 index 0000000000000000000000000000000000000000..1fbfa0a461fbe44a73baa7f648c3d9e0270ac6cf GIT binary patch literal 69632 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 f4Cdm`{-(zDgZC`oiOEa404000x8000000000000020050WinlogbeatTestGovagrant4 college quality neutral feather article article trolley attract bargain college arrange recover feather arrange percent wriggle wriggle feather college highway feather neutral quality manager manager recover arrange article arrange manager quality bargain +304000x8000000000000020049WinlogbeatTestGovagrant3 highway article bargain article college trolley percent college attract recover arrange attract manager highway trolley bargain recover trolley arrange manager bargain wriggle arrange manager trolley bargain recover highway bargain feather manager percent +204000x8000000000000020048WinlogbeatTestGovagrant2 wriggle college highway wriggle quality manager college article neutral bargain arrange quality highway percent attract attract arrange manager wriggle neutral highway article feather recover highway highway hunting arrange article manager neutral attract +104000x8000000000000020047WinlogbeatTestGovagrant1 feather bargain feather neutral bargain recover hunting quality attract neutral wriggle quality percent manager feather neutral attract neutral highway bargain bargain attract college article wriggle quality percent wriggle article recover hunting bargain +004000x8000000000000020046WinlogbeatTestGovagrant0 wriggle neutral trolley hunting highway attract college percent highway recover arrange bargain percent arrange quality arrange manager quality trolley feather percent hunting highway quality neutral arrange recover quality recover article bargain wriggle diff --git a/winlogbeat/sys/wineventlog/testdata/original.evtx b/winlogbeat/sys/wineventlog/testdata/original.evtx new file mode 100644 index 0000000000000000000000000000000000000000..a973a51a4c34e1e3fae8c7c41bec8ac211825aaf GIT binary patch literal 69632 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 a)VO}&&ZRpsdFg*wCv6JXdC3pZ>;D00lwa`x literal 0 HcmV?d00001 diff --git a/winlogbeat/sys/wineventlog/testdata/original.xml b/winlogbeat/sys/wineventlog/testdata/original.xml new file mode 100644 index 000000000000..40ce93c2a1b2 --- /dev/null +++ b/winlogbeat/sys/wineventlog/testdata/original.xml @@ -0,0 +1,5 @@ +404000x8000000000000020055WinlogbeatTestGovagrant4 college quality neutral feather article article trolley attract bargain college arrange recover feather arrange percent wriggle wriggle feather college highway feather neutral quality manager manager recover arrange article arrange manager quality bargain +304000x8000000000000020054WinlogbeatTestGovagrant3 highway article bargain article college trolley percent college attract recover arrange attract manager highway trolley bargain recover trolley arrange manager bargain wriggle arrange manager trolley bargain recover highway bargain feather manager percent +204000x8000000000000020053WinlogbeatTestGovagrant2 wriggle college highway wriggle quality manager college article neutral bargain arrange quality highway percent attract attract arrange manager wriggle neutral highway article feather recover highway highway hunting arrange article manager neutral attract +104000x8000000000000020052WinlogbeatTestGovagrant1 feather bargain feather neutral bargain recover hunting quality attract neutral wriggle quality percent manager feather neutral attract neutral highway bargain bargain attract college article wriggle quality percent wriggle article recover hunting bargain +004000x8000000000000020051WinlogbeatTestGovagrant0 wriggle neutral trolley hunting highway attract college percent highway recover arrange bargain percent arrange quality arrange manager quality trolley feather percent hunting highway quality neutral arrange recover quality recover article bargain wriggle diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index 3dced938bb8a..e2e777f8eadb 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -43,11 +43,13 @@ func TestWinEventLog(t *testing.T) { events int }{ {path: "sysmon-9.01.evtx", events: 32}, - {path: "ec1.evtx", events: 1}, // eventcreate /id 1000 /t error /l application /d "My custom error event for the application log" - {path: "ec2.evtx", events: 1}, // eventcreate /id 999 /t error /l application /so WinWord /d "Winword event 999 happened due to low diskspace" - {path: "ec3.evtx", events: 1}, // eventcreate /id 5 /t error /l system /d "Catastrophe!" - {path: "ec4.evtx", events: 1}, // eventcreate /id 5 /t error /l system /so Backup /d "Backup failure" - {path: "ec3and4.evtx", events: 2}, // ec3 and ec3 exported as a single evtx. + {path: "ec1.evtx", events: 1}, // eventcreate /id 1000 /t error /l application /d "My custom error event for the application log" + {path: "ec2.evtx", events: 1}, // eventcreate /id 999 /t error /l application /so WinWord /d "Winword event 999 happened due to low diskspace" + {path: "ec3.evtx", events: 1}, // eventcreate /id 5 /t error /l system /d "Catastrophe!" + {path: "ec4.evtx", events: 1}, // eventcreate /id 5 /t error /l system /so Backup /d "Backup failure" + {path: "ec3and4.evtx", events: 2}, // ec3 and ec3 exported as a single evtx. + {path: "original.evtx", events: 5}, // a capture from a short generation of the eventlog WindowsEventLogAPI test. + {path: "experimental.evtx", events: 5}, // a capture from a short generation of the eventlog WindowsEventLogAPIExperimental test. } { t.Run(test.path, func(t *testing.T) { evtx, err := filepath.Abs(filepath.Join("testdata", test.path)) From fc7ead543e37cb346db5e6154cfac8aef40d4639 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 11:19:09 +1030 Subject: [PATCH 08/19] more linter suppression --- winlogbeat/sys/wineventlog/wineventlog_windows.go | 9 +++++---- winlogbeat/sys/wineventlog/wineventlog_windows_test.go | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index 4c4078578ec7..902717135a8e 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -490,7 +490,7 @@ func offset(buffer []byte, reader io.Reader) (uint64, error) { if offset > uint64(len(buffer)) { return 0, fmt.Errorf("invalid pointer %x: cannot dereference an "+ - "address outside of the buffer [%x:%x].", dataPtr, bufferPtr, + "address outside of the buffer [%x:%x]", dataPtr, bufferPtr, bufferPtr+uint64(len(buffer))) } @@ -517,7 +517,7 @@ func evtRenderProviderName(renderBuf []byte, eventHandle EvtHandle) (string, err var bufferUsed, propertyCount uint32 err := _EvtRender(providerNameContext, eventHandle, EvtRenderEventValues, uint32(len(renderBuf)), &renderBuf[0], &bufferUsed, &propertyCount) - if err == ERROR_INSUFFICIENT_BUFFER { + if err == ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // This is an errno or nil. return "", sys.InsufficientBufferError{Cause: err, RequiredSize: int(bufferUsed)} } if err != nil { @@ -532,7 +532,7 @@ func renderXML(eventHandle EvtHandle, flag EvtRenderFlag, renderBuf []byte, out var bufferUsed, propertyCount uint32 err := _EvtRender(0, eventHandle, flag, uint32(len(renderBuf)), &renderBuf[0], &bufferUsed, &propertyCount) - if err == ERROR_INSUFFICIENT_BUFFER { + if err == ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // This is an errno or nil. return sys.InsufficientBufferError{Cause: err, RequiredSize: int(bufferUsed)} } if err != nil { @@ -540,9 +540,10 @@ func renderXML(eventHandle EvtHandle, flag EvtRenderFlag, renderBuf []byte, out } if int(bufferUsed) > len(renderBuf) { + //nolint:stylecheck // These are proper nouns. return fmt.Errorf("Windows EvtRender reported that wrote %d bytes "+ "to the buffer, but the buffer can only hold %d bytes", - bufferUsed, len(renderBuf)) //nolint:stylecheck // These are proper nouns. + bufferUsed, len(renderBuf)) } return common.UTF16ToUTF8Bytes(renderBuf[:bufferUsed], out) } diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index e2e777f8eadb..2ca612dda799 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -67,7 +67,7 @@ func TestWinEventLog(t *testing.T) { if err != nil { t.Fatal(err) } - defer Close(h) + defer Close(h) //nolint:errcheck // This is just a resource release. }) t.Run("EvtQuery", func(t *testing.T) { @@ -75,7 +75,7 @@ func TestWinEventLog(t *testing.T) { if err != nil { t.Fatal(err) } - defer Close(h) + defer Close(h) //nolint:errcheck // This is just a resource release. }) t.Run("ReadEvtx", func(t *testing.T) { @@ -84,7 +84,7 @@ func TestWinEventLog(t *testing.T) { if err != nil { t.Fatal(err) } - defer Close(h) + defer Close(h) //nolint:errcheck // This is just a resource release. // Get handles to events. buf := make([]byte, 32*1024) @@ -102,7 +102,7 @@ func TestWinEventLog(t *testing.T) { var count int for { handles, err := EventHandles(h, 8) - if err == ERROR_NO_MORE_ITEMS { + if err == ERROR_NO_MORE_ITEMS { //nolint:errorlint // This is never wrapped. t.Log(err) break } From 5cc350c6ba91db1bef589ad747559aeab3815c39 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 11:43:05 +1030 Subject: [PATCH 09/19] final? --- winlogbeat/sys/wineventlog/wineventlog_windows_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index 2ca612dda799..9e9b71e3433a 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -115,7 +115,7 @@ func TestWinEventLog(t *testing.T) { if err = RenderEventXML(h, buf, out); err != nil { t.Fatal(err) } - Close(h) + Close(h) //nolint:errcheck // This is just a resource release. fmt.Fprintln(out) count++ } From c99781136bbf983edf6ce1cbfb10e3fdb9d8b419 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 18:15:42 +1030 Subject: [PATCH 10/19] work around for event message recovery --- winlogbeat/eventlog/wineventlog.go | 10 ++++++++++ winlogbeat/eventlog/wineventlog_test.go | 17 +++++++++++----- .../sys/wineventlog/wineventlog_windows.go | 20 +++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/winlogbeat/eventlog/wineventlog.go b/winlogbeat/eventlog/wineventlog.go index 2866f4cfbe0a..5ca518a1b4b4 100644 --- a/winlogbeat/eventlog/wineventlog.go +++ b/winlogbeat/eventlog/wineventlog.go @@ -160,6 +160,7 @@ type winEventLog struct { lastRead checkpoint.EventLogState // Record number of the last read event. render func(event win.EvtHandle, out io.Writer) error // Function for rendering the event to XML. + message func(event win.EvtHandle) (string, error) // Message fallback function. renderBuf []byte // Buffer used for rendering event. outputBuf *sys.ByteBuffer // Buffer for receiving XML cache *messageFilesCache // Cached mapping of source name to event message file handles. @@ -314,6 +315,12 @@ func (l *winEventLog) Read() ([]Record, error) { if r.Offset.Bookmark, err = l.createBookmarkFromEvent(h); err != nil { logp.Warn("%s failed creating bookmark: %v", l.logPrefix, err) } + if r.Message == "" { + r.Message, err = l.message(h) + if err != nil { + logp.Err("%s error salvaging message: %v", l.logPrefix, err) + } + } records = append(records, r) l.lastRead = r.Offset } @@ -489,6 +496,9 @@ func newWinEventLog(options *common.Config) (EventLog, error) { return win.RenderEvent(event, c.EventLanguage, l.renderBuf, l.cache.get, out) } } + l.message = func(event win.EvtHandle) (string, error) { + return win.Message(event, l.renderBuf, l.cache.get) + } return l, nil } diff --git a/winlogbeat/eventlog/wineventlog_test.go b/winlogbeat/eventlog/wineventlog_test.go index 0a5bdac62c10..f0abc9fae5ac 100644 --- a/winlogbeat/eventlog/wineventlog_test.go +++ b/winlogbeat/eventlog/wineventlog_test.go @@ -194,12 +194,19 @@ func testWindowsEventLog(t *testing.T, api string) { log := openLog(t, map[string]interface{}{"name": providerName, "batch_read_size": 1}) defer log.Close() - records, err := log.Read() - require.NotEmpty(t, records) - require.NoError(t, err) + for i := 0; i < 10; i++ { + records, err := log.Read() + require.NotEmpty(t, records) + require.NoError(t, err) + if i == 0 { + // The first event in a collection of events created by eventcreate + // appear to be broken, so skip this one. The remaining events pass. + continue + } - r := records[0] - require.NotEmpty(t, r.Message, "message field is empty: errors:%v\nrecord:%#v", r.Event.RenderErr, r) + r := records[0] + require.NotEmpty(t, r.Message, "message field is empty: errors:%v\nrecord:%#v", r.Event.RenderErr, r) + } }) // Test reading from an event log using a custom XML query. diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index 902717135a8e..b4fb1fbf127b 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -255,6 +255,26 @@ func RenderEvent( return err } +// Message reads the event data associated with the EvtHandle and renders +// and returns the message only. +func Message(h EvtHandle, buf []byte, pubHandleProvider func(string) sys.MessageFiles) (message string, err error) { + providerName, err := evtRenderProviderName(buf, h) + if err != nil { + return "", err + } + + var pub EvtHandle + if pubHandleProvider != nil { + messageFiles := pubHandleProvider(providerName) + if messageFiles.Err == nil { + // There is only ever a single handle when using the Windows Event + // Log API. + pub = EvtHandle(messageFiles.Handles[0].Handle) + } + } + return getMessageStringFromHandle(&PublisherMetadata{Handle: pub}, h, nil) +} + // RenderEventXML renders the event as XML. If the event is already rendered, as // in a forwarded event whose content type is "RenderedText", then the XML will // include the RenderingInfo (message). If the event is not rendered then the From 9ef8e30405c1022ee8dded9a2cc610ab37c98752 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 23 Mar 2022 20:23:46 +1030 Subject: [PATCH 11/19] delint --- winlogbeat/eventlog/wineventlog.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/winlogbeat/eventlog/wineventlog.go b/winlogbeat/eventlog/wineventlog.go index 5ca518a1b4b4..e8bbc1051efd 100644 --- a/winlogbeat/eventlog/wineventlog.go +++ b/winlogbeat/eventlog/wineventlog.go @@ -199,7 +199,7 @@ func (l *winEventLog) openChannel(bookmark win.EvtHandle) error { if err != nil { return err } - defer func() { _ = windows.CloseHandle(signalEvent) }() + defer windows.CloseHandle(signalEvent) //nolint:errcheck // This is just a resource release. var flags win.EvtSubscribeFlag if bookmark > 0 { @@ -287,13 +287,12 @@ func (l *winEventLog) Read() ([]Record, error) { }() detailf("%s EventHandles returned %d handles", l.logPrefix, len(handles)) - //nolint: prealloc // some handles can be skipped, the final size is unknown - var records []Record + var records []Record //nolint:prealloc // This linter gives bad advice and does not take into account conditionals in loops. for _, h := range handles { l.outputBuf.Reset() err := l.render(h, l.outputBuf) var bufErr sys.InsufficientBufferError - if ok := errors.As(err, &bufErr); ok { + if errors.As(err, &bufErr) { detailf("%s Increasing render buffer size to %d", l.logPrefix, bufErr.RequiredSize) l.renderBuf = make([]byte, bufErr.RequiredSize) @@ -336,20 +335,20 @@ func (l *winEventLog) Close() error { func (l *winEventLog) eventHandles(maxRead int) ([]win.EvtHandle, int, error) { handles, err := win.EventHandles(l.subscription, maxRead) - switch { - case err == nil: + switch err { //nolint:errorlint // This is an errno or nil. + case nil: if l.maxRead > maxRead { debugf("%s Recovered from RPC_S_INVALID_BOUND error (errno 1734) "+ "by decreasing batch_read_size to %v", l.logPrefix, maxRead) } return handles, maxRead, nil - case errors.Is(err, win.ERROR_NO_MORE_ITEMS): + case win.ERROR_NO_MORE_ITEMS: detailf("%s No more events", l.logPrefix) if l.config.NoMoreEvents == Stop { return nil, maxRead, io.EOF } return nil, maxRead, nil - case errors.Is(err, win.RPC_S_INVALID_BOUND): + case win.RPC_S_INVALID_BOUND: incrementMetric(readErrors, err) if err := l.Close(); err != nil { return nil, 0, fmt.Errorf("failed to recover from RPC_S_INVALID_BOUND: %w", err) From a34e3e7715af5e85164ad6bfffdf0bb8ad9f9422 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Thu, 24 Mar 2022 14:24:41 +1030 Subject: [PATCH 12/19] render string values for keyword, opcode and level Also clean up lint. --- winlogbeat/beater/winlogbeat.go | 2 +- winlogbeat/eventlog/wineventlog.go | 4 +++- winlogbeat/sys/wineventlog/renderer.go | 29 +++++++++++++------------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/winlogbeat/beater/winlogbeat.go b/winlogbeat/beater/winlogbeat.go index 86a8b47f7def..26383fcc2117 100644 --- a/winlogbeat/beater/winlogbeat.go +++ b/winlogbeat/beater/winlogbeat.go @@ -94,7 +94,7 @@ func (eb *Winlogbeat) init(b *beat.Beat) error { if err != nil { return fmt.Errorf("failed to create new event log: %w", err) } - eb.log.Debugw("Initialized EventLog", "id", eventLog.Name()) + eb.log.Debugf("initialized WinEventLog[%s]", eventLog.Name()) logger, err := newEventLogger(b.Info, eventLog, config, eb.log) if err != nil { diff --git a/winlogbeat/eventlog/wineventlog.go b/winlogbeat/eventlog/wineventlog.go index e8bbc1051efd..a2200b6f609c 100644 --- a/winlogbeat/eventlog/wineventlog.go +++ b/winlogbeat/eventlog/wineventlog.go @@ -387,13 +387,15 @@ func (l *winEventLog) buildRecordFromXML(x []byte, recoveredErr error) Record { e.RenderErr = append(e.RenderErr, recoveredErr.Error()) } + // Get basic string values for raw fields. + winevent.EnrichRawValuesWithNames(nil, &e) if e.Level == "" { // Fallback on LevelRaw if the Level is not set in the RenderingInfo. e.Level = win.EventLevel(e.LevelRaw).String() } if logp.IsDebug(detailSelector) { - detailf("%s XML=%s Event=%+v", l.logPrefix, string(x), e) + detailf("%s XML=%s Event=%+v", l.logPrefix, x, e) } r := Record{ diff --git a/winlogbeat/sys/wineventlog/renderer.go b/winlogbeat/sys/wineventlog/renderer.go index 7482fae63503..4c80d05280ed 100644 --- a/winlogbeat/sys/wineventlog/renderer.go +++ b/winlogbeat/sys/wineventlog/renderer.go @@ -30,7 +30,6 @@ import ( "unsafe" "github.com/cespare/xxhash/v2" - "github.com/pkg/errors" "go.uber.org/multierr" "golang.org/x/sys/windows" @@ -41,10 +40,10 @@ import ( // Renderer is used for converting event log handles into complete events. type Renderer struct { - // Cache of publisher metadata. Maps publisher names to stored metadata. - metadataCache map[string]*PublisherMetadataStore // Mutex to guard the metadataCache. The other members are immutable. mutex sync.RWMutex + // Cache of publisher metadata. Maps publisher names to stored metadata. + metadataCache map[string]*PublisherMetadataStore session EvtHandle // Session handle if working with remote log. systemContext EvtHandle // Render context for system values. @@ -56,12 +55,12 @@ type Renderer struct { func NewRenderer(session EvtHandle, log *logp.Logger) (*Renderer, error) { systemContext, err := _EvtCreateRenderContext(0, 0, EvtRenderContextSystem) if err != nil { - return nil, errors.Wrap(err, "failed in EvtCreateRenderContext for system context") + return nil, fmt.Errorf("failed in EvtCreateRenderContext for system context: %w", err) } userContext, err := _EvtCreateRenderContext(0, 0, EvtRenderContextUser) if err != nil { - return nil, errors.Wrap(err, "failed in EvtCreateRenderContext for user context") + return nil, fmt.Errorf("failed in EvtCreateRenderContext for user context: %w", err) } return &Renderer{ @@ -92,7 +91,7 @@ func (r *Renderer) Render(handle EvtHandle) (*winevent.Event, error) { event := &winevent.Event{} if err := r.renderSystem(handle, event); err != nil { - return nil, errors.Wrap(err, "failed to render system properties") + return nil, fmt.Errorf("failed to render system properties: %w", err) } // From this point on it will return both the event and any errors. It's @@ -110,7 +109,7 @@ func (r *Renderer) Render(handle EvtHandle) (*winevent.Event, error) { eventData, fingerprint, err := r.renderUser(handle, event) if err != nil { - errs = append(errs, errors.Wrap(err, "failed to render event data")) + errs = append(errs, fmt.Errorf("failed to render event data: %w", err)) } // Load cached event metadata or try to bootstrap it from the event's XML. @@ -120,7 +119,7 @@ func (r *Renderer) Render(handle EvtHandle) (*winevent.Event, error) { r.addEventData(eventMeta, eventData, event) if event.Message, err = r.formatMessage(md, eventMeta, handle, eventData, uint16(event.EventIdentifier.ID)); err != nil { - errs = append(errs, errors.Wrap(err, "failed to get the event message string")) + errs = append(errs, fmt.Errorf("failed to get the event message string: %w", err)) } if len(errs) > 0 { @@ -158,8 +157,8 @@ func (r *Renderer) getPublisherMetadata(publisher string) (*PublisherMetadataSto // Return an empty store on error (can happen in cases where the // log was forwarded and the provider doesn't exist on collector). md = NewEmptyPublisherMetadataStore(publisher, r.log) - err = errors.Wrapf(err, "failed to load publisher metadata for %v "+ - "(returning an empty metadata store)", publisher) + err = fmt.Errorf("failed to load publisher metadata for %v "+ + "(returning an empty metadata store): %w", publisher, err) } r.metadataCache[publisher] = md } else { @@ -173,7 +172,7 @@ func (r *Renderer) getPublisherMetadata(publisher string) (*PublisherMetadataSto func (r *Renderer) renderSystem(handle EvtHandle, event *winevent.Event) error { bb, propertyCount, err := r.render(r.systemContext, handle) if err != nil { - return errors.Wrap(err, "failed to get system values") + return fmt.Errorf("failed to get system values: %w", err) } defer bb.Free() @@ -240,7 +239,7 @@ func (r *Renderer) renderSystem(handle EvtHandle, event *winevent.Event) error { func (r *Renderer) renderUser(handle EvtHandle, event *winevent.Event) (values []interface{}, fingerprint uint64, err error) { bb, propertyCount, err := r.render(r.userContext, handle) if err != nil { - return nil, 0, errors.Wrap(err, "failed to get user values") + return nil, 0, fmt.Errorf("failed to get user values: %w", err) } defer bb.Free() @@ -284,7 +283,7 @@ func (r *Renderer) render(context EvtHandle, eventHandle EvtHandle) (*sys.Pooled err := _EvtRender(context, eventHandle, EvtRenderEventValues, 0, nil, &bufferUsed, &propertyCount) if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { - return nil, 0, errors.Wrap(err, "failed in EvtRender") + return nil, 0, fmt.Errorf("failed in EvtRender: %w", err) } if propertyCount == 0 { @@ -297,7 +296,7 @@ func (r *Renderer) render(context EvtHandle, eventHandle EvtHandle) (*sys.Pooled err = _EvtRender(context, eventHandle, EvtRenderEventValues, uint32(bb.Len()), bb.PtrAt(0), &bufferUsed, &propertyCount) if err != nil { bb.Free() - return nil, 0, errors.Wrap(err, "failed in EvtRender") + return nil, 0, fmt.Errorf("failed in EvtRender: %w", err) } return bb, int(propertyCount), nil @@ -384,7 +383,7 @@ func (r *Renderer) formatMessageFromTemplate(msgTmpl *template.Template, values defer bb.Free() if err := msgTmpl.Execute(bb, values); err != nil { - return "", errors.Wrapf(err, "failed to execute template with data=%#v template=%v", values, msgTmpl.Root.String()) + return "", fmt.Errorf("failed to execute template with data=%#v template=%v: %w", values, msgTmpl.Root.String(), err) } return string(bb.Bytes()), nil From 14b4c10f5bce123a890b005b0e7dbf15e3bfe1af Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Thu, 24 Mar 2022 14:31:13 +1030 Subject: [PATCH 13/19] =?UTF-8?q?use=201-based=20counting=20=F0=9F=96=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- winlogbeat/eventlog/wineventlog_test.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/winlogbeat/eventlog/wineventlog_test.go b/winlogbeat/eventlog/wineventlog_test.go index f0abc9fae5ac..ac8986db7008 100644 --- a/winlogbeat/eventlog/wineventlog_test.go +++ b/winlogbeat/eventlog/wineventlog_test.go @@ -183,7 +183,7 @@ func testWindowsEventLog(t *testing.T, api string) { const messageSize = 256 // Originally 31800, such a large value resulted in an empty eventlog under Win10. const totalEvents = 1000 for i := 0; i < totalEvents; i++ { - safeWriteEvent(t, writer, eventlog.Info, uint32(i%1000), []string{strconv.Itoa(i) + " " + randomSentence(messageSize)}) + safeWriteEvent(t, writer, eventlog.Info, uint32(i%1000)+1, []string{strconv.Itoa(i) + " " + randomSentence(messageSize)}) } openLog := func(t testing.TB, config map[string]interface{}) EventLog { @@ -198,11 +198,6 @@ func testWindowsEventLog(t *testing.T, api string) { records, err := log.Read() require.NotEmpty(t, records) require.NoError(t, err) - if i == 0 { - // The first event in a collection of events created by eventcreate - // appear to be broken, so skip this one. The remaining events pass. - continue - } r := records[0] require.NotEmpty(t, r.Message, "message field is empty: errors:%v\nrecord:%#v", r.Event.RenderErr, r) From 3375059aa2a4db34e0c71b2821739c24da782558 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Thu, 24 Mar 2022 15:21:48 +1030 Subject: [PATCH 14/19] satisfy linter --- winlogbeat/sys/wineventlog/renderer.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/winlogbeat/sys/wineventlog/renderer.go b/winlogbeat/sys/wineventlog/renderer.go index 4c80d05280ed..abadcc3a6c4b 100644 --- a/winlogbeat/sys/wineventlog/renderer.go +++ b/winlogbeat/sys/wineventlog/renderer.go @@ -176,7 +176,7 @@ func (r *Renderer) renderSystem(handle EvtHandle, event *winevent.Event) error { } defer bb.Free() - for i := 0; i < int(propertyCount); i++ { + for i := 0; i < propertyCount; i++ { property := EvtSystemPropertyID(i) offset := i * int(sizeofEvtVariant) evtVar := (*EvtVariant)(unsafe.Pointer(bb.PtrAt(offset))) @@ -186,6 +186,7 @@ func (r *Renderer) renderSystem(handle EvtHandle, event *winevent.Event) error { continue } + //nolint:errcheck // Bad linter! switch property { case EvtSystemProviderName: event.Provider.Name = data.(string) @@ -259,7 +260,7 @@ func (r *Renderer) renderUser(handle EvtHandle, event *winevent.Event) (values [ for i := 0; i < propertyCount; i++ { offset := i * int(sizeofEvtVariant) evtVar := (*EvtVariant)(unsafe.Pointer(bb.PtrAt(offset))) - binary.Write(argumentHash, binary.LittleEndian, uint32(evtVar.Type)) + binary.Write(argumentHash, binary.LittleEndian, uint32(evtVar.Type)) //nolint:errcheck // Hash writes never fail. values[i], err = evtVar.Data(bb.Bytes()) if err != nil { @@ -282,7 +283,7 @@ func (r *Renderer) render(context EvtHandle, eventHandle EvtHandle) (*sys.Pooled var bufferUsed, propertyCount uint32 err := _EvtRender(context, eventHandle, EvtRenderEventValues, 0, nil, &bufferUsed, &propertyCount) - if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { + if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // This is an errno or nil. return nil, 0, fmt.Errorf("failed in EvtRender: %w", err) } From 1a0bb4def92f85fc3fb3316e4d6b471f98af84e2 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 30 Mar 2022 11:30:34 +1030 Subject: [PATCH 15/19] clarify entry points --- winlogbeat/eventlog/wineventlog.go | 18 +++++++++--------- .../eventlog/wineventlog_experimental.go | 16 ++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/winlogbeat/eventlog/wineventlog.go b/winlogbeat/eventlog/wineventlog.go index a2200b6f609c..580b7bad2d9e 100644 --- a/winlogbeat/eventlog/wineventlog.go +++ b/winlogbeat/eventlog/wineventlog.go @@ -55,6 +55,15 @@ const ( eventLoggingAPIName = "eventlogging" ) +func init() { + // Register wineventlog API if it is available. + available, _ := win.IsAvailable() + if available { + Register(winEventLogAPIName, 0, newWinEventLog, win.Channels) + Register(eventLoggingAPIName, 1, newEventLogging, win.Channels) + } +} + type winEventLogConfig struct { ConfigCommon `config:",inline"` BatchReadSize int `config:"batch_read_size"` // Maximum number of events that Read will return. @@ -514,12 +523,3 @@ func (l *winEventLog) createBookmarkFromEvent(evtHandle win.EvtHandle) (string, win.Close(bmHandle) return string(l.outputBuf.Bytes()), err } - -func init() { - // Register wineventlog API if it is available. - available, _ := win.IsAvailable() - if available { - Register(winEventLogAPIName, 0, newWinEventLog, win.Channels) - Register(eventLoggingAPIName, 1, newEventLogging, win.Channels) - } -} diff --git a/winlogbeat/eventlog/wineventlog_experimental.go b/winlogbeat/eventlog/wineventlog_experimental.go index 9ac4b82a5c68..730a65a6f531 100644 --- a/winlogbeat/eventlog/wineventlog_experimental.go +++ b/winlogbeat/eventlog/wineventlog_experimental.go @@ -43,6 +43,14 @@ const ( winEventLogExpAPIName = "wineventlog-experimental" ) +func init() { + // Register wineventlog API if it is available. + available, _ := win.IsAvailable() + if available { + Register(winEventLogExpAPIName, 10, newWinEventLogExp, win.Channels) + } +} + // winEventLogExp implements the EventLog interface for reading from the Windows // Event Log API. type winEventLogExp struct { @@ -321,11 +329,3 @@ func newWinEventLogExp(options *common.Config) (EventLog, error) { return l, nil } - -func init() { - // Register wineventlog API if it is available. - available, _ := win.IsAvailable() - if available { - Register(winEventLogExpAPIName, 10, newWinEventLogExp, win.Channels) - } -} From 14cf33a8eedc052dc48a8b5df6c9694222f67753 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 30 Mar 2022 11:37:28 +1030 Subject: [PATCH 16/19] fix imports --- winlogbeat/sys/wineventlog/wineventlog_windows.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index b4fb1fbf127b..96d4187387d7 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -28,10 +28,9 @@ import ( "sort" "syscall" - "github.com/elastic/beats/v7/libbeat/common" - "golang.org/x/sys/windows" + "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/winlogbeat/sys" ) From b286188f1d6a45e6357bfae771804da4bbe387b9 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 30 Mar 2022 12:52:32 +1030 Subject: [PATCH 17/19] fix lint --- winlogbeat/eventlog/wineventlog_experimental.go | 12 +++++------- winlogbeat/sys/winevent/event.go | 8 +++++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/winlogbeat/eventlog/wineventlog_experimental.go b/winlogbeat/eventlog/wineventlog_experimental.go index 730a65a6f531..604707aca2e2 100644 --- a/winlogbeat/eventlog/wineventlog_experimental.go +++ b/winlogbeat/eventlog/wineventlog_experimental.go @@ -21,7 +21,6 @@ package eventlog import ( - "errors" "fmt" "io" "os" @@ -108,7 +107,7 @@ func (l *winEventLogExp) openChannel(bookmark win.Bookmark) (win.EvtHandle, erro if err != nil { return win.NilHandle, err } - defer func() { _ = windows.CloseHandle(signalEvent) }() + defer windows.CloseHandle(signalEvent) //nolint:errcheck // This is just a resource release. var flags win.EvtSubscribeFlag if bookmark > 0 { @@ -128,11 +127,10 @@ func (l *winEventLogExp) openChannel(bookmark win.Bookmark) (win.EvtHandle, erro win.EvtHandle(bookmark), // Bookmark - for resuming from a specific event flags) - switch { - case err == nil: + switch err { //nolint:errorlint // This is an errno or nil. + case nil: return h, nil - case errors.Is(err, win.ERROR_NOT_FOUND), errors.Is(err, win.ERROR_EVT_QUERY_RESULT_STALE), - errors.Is(err, win.ERROR_EVT_QUERY_RESULT_INVALID_POSITION): + case win.ERROR_NOT_FOUND, win.ERROR_EVT_QUERY_RESULT_STALE, win.ERROR_EVT_QUERY_RESULT_INVALID_POSITION: // The bookmarked event was not found, we retry the subscription from the start. incrementMetric(readErrors, err) return win.Subscribe(0, signalEvent, "", l.query, 0, win.EvtSubscribeStartAtOldestRecord) @@ -221,7 +219,7 @@ func (l *winEventLogExp) processHandle(h win.EvtHandle) (*Record, error) { evt.RenderErr = append(evt.RenderErr, err.Error()) } - //nolint: godox // keep to have a record of feature disparity between non-experimental vs experimental + //nolint:godox // Bad linter! Keep to have a record of feature disparity between non-experimental vs experimental. // TODO: Need to add XML when configured. r := &Record{ diff --git a/winlogbeat/sys/winevent/event.go b/winlogbeat/sys/winevent/event.go index 9c342e73f480..0e0462ddcb40 100644 --- a/winlogbeat/sys/winevent/event.go +++ b/winlogbeat/sys/winevent/event.go @@ -258,7 +258,10 @@ func (u *UserData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { u.Name = se.Name u.Pairs = in.Pairs - d.Skip() + err = d.Skip() + if err != nil { + return err + } break } } @@ -309,8 +312,7 @@ func (v *Version) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { version, err := strconv.ParseUint(s, 10, 8) if err != nil { - // Ignore invalid version values. - return nil + return nil //nolint:nilerr // Ignore invalid version values. } *v = Version(version) From bc88df8ac3fd556397249ba55539622d63312952 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 30 Mar 2022 13:55:54 +1030 Subject: [PATCH 18/19] use omitempty on a uint8 pointer to allow absence of opcode raw to be expressed --- winlogbeat/sys/winevent/event.go | 22 +++++++------------ winlogbeat/sys/winevent/event_test.go | 1 + winlogbeat/sys/wineventlog/renderer.go | 5 ++++- winlogbeat/sys/wineventlog/renderer_test.go | 5 +++-- .../application-windows-error-reporting.xml | 18 +++++++++++++++ .../wineventlog/wineventlog_windows_test.go | 1 + 6 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 winlogbeat/sys/wineventlog/testdata/application-windows-error-reporting.xml diff --git a/winlogbeat/sys/winevent/event.go b/winlogbeat/sys/winevent/event.go index 0e0462ddcb40..4054626ed8fb 100644 --- a/winlogbeat/sys/winevent/event.go +++ b/winlogbeat/sys/winevent/event.go @@ -44,11 +44,6 @@ var ( const ( keywordAuditFailure = 0x10000000000000 keywordAuditSuccess = 0x20000000000000 - - // keywordClassic indicates the log was published with the "classic" event - // logging API. - // https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.eventing.reader.standardeventkeywords?view=netframework-4.8 - keywordClassic = 0x80000000000000 ) // UnmarshalXML unmarshals the given XML into a new Event. @@ -67,7 +62,7 @@ type Event struct { Version Version `xml:"System>Version"` LevelRaw uint8 `xml:"System>Level"` TaskRaw uint16 `xml:"System>Task"` - OpcodeRaw uint8 `xml:"System>Opcode"` + OpcodeRaw *uint8 `xml:"System>Opcode,omitempty"` KeywordsRaw HexInt64 `xml:"System>Keywords"` TimeCreated TimeCreated `xml:"System>TimeCreated"` RecordID uint64 `xml:"System>EventRecordID"` @@ -343,20 +338,19 @@ func (v *HexInt64) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { func EnrichRawValuesWithNames(publisherMeta *WinMeta, event *Event) { // Keywords. Each bit in the value can represent a keyword. rawKeyword := int64(event.KeywordsRaw) - isClassic := keywordClassic&rawKeyword > 0 if len(event.Keywords) == 0 { for mask, keyword := range defaultWinMeta.Keywords { - if rawKeyword&mask > 0 { + if rawKeyword&mask != 0 { event.Keywords = append(event.Keywords, keyword) - rawKeyword -= mask + rawKeyword &^= mask } } if publisherMeta != nil { for mask, keyword := range publisherMeta.Keywords { - if rawKeyword&mask > 0 { + if rawKeyword&mask != 0 { event.Keywords = append(event.Keywords, keyword) - rawKeyword -= mask + rawKeyword &^= mask } } } @@ -365,10 +359,10 @@ func EnrichRawValuesWithNames(publisherMeta *WinMeta, event *Event) { var found bool if event.Opcode == "" { // Opcode (search in defaultWinMeta first). - if !isClassic { - event.Opcode, found = defaultWinMeta.Opcodes[event.OpcodeRaw] + if event.OpcodeRaw != nil { + event.Opcode, found = defaultWinMeta.Opcodes[*event.OpcodeRaw] if !found && publisherMeta != nil { - event.Opcode = publisherMeta.Opcodes[event.OpcodeRaw] + event.Opcode = publisherMeta.Opcodes[*event.OpcodeRaw] } } } diff --git a/winlogbeat/sys/winevent/event_test.go b/winlogbeat/sys/winevent/event_test.go index b6d893957ed1..78e20397048b 100644 --- a/winlogbeat/sys/winevent/event_test.go +++ b/winlogbeat/sys/winevent/event_test.go @@ -97,6 +97,7 @@ func TestXML(t *testing.T) { EventIdentifier: EventIdentifier{ID: 91}, LevelRaw: 4, TaskRaw: 9, + OpcodeRaw: new(uint8), // The value in the XML is 0. KeywordsRaw: 0x8020000000000000, TimeCreated: TimeCreated{allXMLTimeCreated}, RecordID: 100, diff --git a/winlogbeat/sys/wineventlog/renderer.go b/winlogbeat/sys/wineventlog/renderer.go index abadcc3a6c4b..c8035fe94d77 100644 --- a/winlogbeat/sys/wineventlog/renderer.go +++ b/winlogbeat/sys/wineventlog/renderer.go @@ -201,7 +201,10 @@ func (r *Renderer) renderSystem(handle EvtHandle, event *winevent.Event) error { case EvtSystemTask: event.TaskRaw = data.(uint16) case EvtSystemOpcode: - event.OpcodeRaw = data.(uint8) + if event.OpcodeRaw == nil { + event.OpcodeRaw = new(uint8) + } + *event.OpcodeRaw = data.(uint8) case EvtSystemKeywords: event.KeywordsRaw = winevent.HexInt64(data.(hexInt64)) case EvtSystemTimeCreated: diff --git a/winlogbeat/sys/wineventlog/renderer_test.go b/winlogbeat/sys/wineventlog/renderer_test.go index ea0c179cd1ea..e9be1d874d9f 100644 --- a/winlogbeat/sys/wineventlog/renderer_test.go +++ b/winlogbeat/sys/wineventlog/renderer_test.go @@ -86,7 +86,8 @@ func TestRenderer(t *testing.T) { assert.Equal(t, e.Keywords, []string{"Audit Success"}) - assert.EqualValues(t, 0, e.OpcodeRaw) + assert.NotNil(t, 0, e.OpcodeRaw) + assert.EqualValues(t, 0, *e.OpcodeRaw) assert.Equal(t, "Info", e.Opcode) assert.EqualValues(t, 0, e.LevelRaw) @@ -131,7 +132,7 @@ func TestRenderer(t *testing.T) { assert.Equal(t, e.Keywords, []string{"Classic"}) - assert.EqualValues(t, 0, e.OpcodeRaw) + assert.EqualValues(t, (*uint8)(nil), e.OpcodeRaw) assert.Equal(t, "", e.Opcode) assert.EqualValues(t, 4, e.LevelRaw) diff --git a/winlogbeat/sys/wineventlog/testdata/application-windows-error-reporting.xml b/winlogbeat/sys/wineventlog/testdata/application-windows-error-reporting.xml new file mode 100644 index 000000000000..0e768eaeebde --- /dev/null +++ b/winlogbeat/sys/wineventlog/testdata/application-windows-error-reporting.xml @@ -0,0 +1,18 @@ +1001400x80000000000000420107Applicationvagrant0WindowsWcpOtherFailure3Not available010.0.17763.850:3inc\auto_hive.hWindows::Rtl::AutoHive::Unload358c00001210xaad0d4fb +\\?\C:\Windows\Logs\CBS\CBS.log +\\?\C:\Windows\Logs\CBS\CbsPersist_20200212163557.log +\\?\C:\Windows\Logs\CBS\CbsPersist_20200211235949.log +\\?\C:\Windows\Logs\CBS\CbsPersist_20200211033558.cab +\\?\C:\Windows\Logs\CBS\CbsPersist_20200210020038.cab +\\?\C:\Windows\Logs\CBS\CbsPersist_20200209082850.cab +\\?\C:\Windows\servicing\Sessions\Sessions.xml +\\?\C:\Windows\WinSxs\pending.xml +\\?\C:\Windows\WinSxs\poqexec.log +\\?\C:\Windows\Logs\Cbs\FilterList.log +\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERC5A1.tmp.WERInternalMetadata.xml +\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERC7D5.tmp.xml +\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERC7F3.tmp.csv +\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERC9F8.tmp.txt +\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERCA08.tmp.mdmp +\\?\C:\ProgramData\Microsoft\Windows\WER\ReportQueue\Critical_10.0.17763.850_3_b785171a54ee6e13bf912aeeb5bef5d9105e314b_00000000_cab_0c38cad1\memory.hdmp +\\?\C:\Windows\Temp\WERCAD4.tmp.WERDataCollectionStatus.txt\\?\C:\ProgramData\Microsoft\Windows\WER\ReportQueue\Critical_10.0.17763.850_3_b785171a54ee6e13bf912aeeb5bef5d9105e314b_00000000_cab_0c38cad105e9de0ad-0fa4-4daa-aec1-8127dc88e6c71000 diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go index 9e9b71e3433a..e6b494e3b242 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows_test.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows_test.go @@ -42,6 +42,7 @@ func TestWinEventLog(t *testing.T) { path string events int }{ + {path: "application-windows-error-reporting.evtx", events: 1}, {path: "sysmon-9.01.evtx", events: 32}, {path: "ec1.evtx", events: 1}, // eventcreate /id 1000 /t error /l application /d "My custom error event for the application log" {path: "ec2.evtx", events: 1}, // eventcreate /id 999 /t error /l application /so WinWord /d "Winword event 999 happened due to low diskspace" From 579cc4fb9243f62a89ee417733e99f3d0060a1b7 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 30 Mar 2022 14:59:30 +1030 Subject: [PATCH 19/19] fix lint --- winlogbeat/sys/winevent/event_test.go | 3 +-- winlogbeat/sys/wineventlog/renderer_test.go | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/winlogbeat/sys/winevent/event_test.go b/winlogbeat/sys/winevent/event_test.go index 78e20397048b..62fc3a7d6b61 100644 --- a/winlogbeat/sys/winevent/event_test.go +++ b/winlogbeat/sys/winevent/event_test.go @@ -20,7 +20,6 @@ package winevent import ( "encoding/json" "encoding/xml" - "fmt" "strings" "testing" "time" @@ -181,7 +180,7 @@ func TestXML(t *testing.T) { if err != nil { t.Error(err) } - fmt.Println(string(json)) + t.Logf("%s", json) } } } diff --git a/winlogbeat/sys/wineventlog/renderer_test.go b/winlogbeat/sys/wineventlog/renderer_test.go index e9be1d874d9f..a283bc0f0570 100644 --- a/winlogbeat/sys/wineventlog/renderer_test.go +++ b/winlogbeat/sys/wineventlog/renderer_test.go @@ -41,7 +41,7 @@ import ( ) func TestRenderer(t *testing.T) { - logp.TestingSetup() + logp.TestingSetup() //nolint:errcheck // Bad linter! Never returns a non-nil error when called without options. t.Run(filepath.Base(sysmon9File), func(t *testing.T) { log := openLog(t, sysmon9File) @@ -198,7 +198,7 @@ func renderAllEvents(t *testing.T, log EvtHandle, renderer *Renderer, ignoreMiss // setLogSize set the maximum number of bytes that an event log can hold. func setLogSize(t testing.TB, provider string, sizeBytes int) { - output, err := exec.Command("wevtutil.exe", "sl", "/ms:"+strconv.Itoa(sizeBytes), provider).CombinedOutput() + output, err := exec.Command("wevtutil.exe", "sl", "/ms:"+strconv.Itoa(sizeBytes), provider).CombinedOutput() //nolint:gosec // No possibility of command injection. if err != nil { t.Fatal("failed to set log size", err, string(output)) }