*Q1N>b+ zc(Y}A(ZOzU&)v>u&m9{@9imMo!U1M$#xvz#k2~s|h$Gma?!C|lZEBULrVd<_DO`Pm z+m}1K)DK*jZa!NMTz}v?cI5?c+5orBPjtenJ3}1sZ7YPW@csC#gOiRsQxqUwa;qdm zP54YQdZ^-iiEF{V4?Zp#-F(~(ZBafIe47c^2h4%Kc|~djGZ$*?1kKfBtmse9eEel; zI*c2;z#N60tVl9&s^Jg;)JJ0Y(jE+3CPNDnTOiJrivLXB!b0RVmERlcC!}FVqk~wY z?6iv_&KD^O0I;))Uv5EC9Lv_2+e~wP?{N-98uliH*b9ho5sQu3Gra7Q~42JI(PE%}C7sEhI6ET!gl_{k;(4dr-;e)&5&6 z9M;MY9u)aR%Ew2v&>Q+IhG-%KH_Bx2Y->&NwgisJDB#S+mL~pXaap$MZgKzmI-CG@ zHV=O9c6~lRl%U?Py&VL<-}JPXa%<;ecXubvLLlxtk|~Ja@9#I%_t)>c!lx?|^PZp` zFQHw6FDP%~fknhNNPeYJI9X5cJEb@ZumsyBK`rKO1Z_Q4A8lrR9DDL1kKZXNtUzZl z%Od0Kx=>C`^J+#-LNe~yIK5CnMwsa6qd7)(bm{0ZK!O2ZTsR!mP(Oo%{ET4@-1Cn! z{q8qx5*9)?jN*9U*@1H8RZ4~d{qs QE zhrrxzdBmme#cNe*I)I Os1Y|ji#(*HL* GjX^^ zb4;eXBA6_4)zd~YF!< ~u{sOlkAMnRFSv-CH1R7PWp zA4XXwjYlz(%Hyy&+zD79w9;zkeBk >gM8t@el^H zHz%YVsX-`0s$ltDRjNMMK9LTZ$cO5a#Se!=@R$L`3J0rRHe5yX$S8U*HrJ%o AuPMce z{?nA9Q|&A#rY@+;C*pC!CzMC@MG60!(oAW*2D0Hxm_Vhyb@l9U;Tq6 u_6_G5_+9KyH{XSH@DXx2JCQ3_B4xCX)44pOA&@JYuIE4` ;&SHl zQ!s0OkXhMbb=K6ucE%D5O(T*|HOv9-Yrd7@(#Z8h zI9szg**JG9Y|-~M zD4?R*w)%GZA2Hu7Y!JTJC+}yU_wyN9=8AuHsUJ&0R>V%?%~D3=7|7*u!)$E$qN+l* zK^>1dkb%s>)D#wwZPB>!Xi`?AV46AID)+g=fwR^0Lf@sw1T~`K0*!<}0lz>E@v=i0 z8pHU3Cre`Ng-&fC I$w2I>E%bYK2c5#dyxzKULj2vQe&AKu zVs%yD!gj^*uY42#f8~dMnQcWmH*&pDxR8u}J6}0q{O ^biU^cEU>K6o<2!{ zOxxu=alkbflp&7<&}tA+5SR4Y>4Vgvzf$EPmYLBZ&7{iM&qi1Lj~;kBpu6d;1)uOd z>Y9=Qg){dz;Eo2LVBkwtNQg|V_L3JkfHDvM4(o~B4GDbM2EI+{eWcD6DOIrAb-PvF z@$%)7V!Iht4#*h97mBd>$M`dy#ur>aVh}XzskJCV)E0PV%SFQ`dJAJ+%!1JHPLjna zDD$89%OUNlXUo{t&bc|~v`Qk$fU7Ow(KoYQ|B4-MOOdC&kv&SZsWU{hn9;zDkSXk= z!f856$3&5Rn83{8jLSSm TPwBr3?zpQ5| aTemo_F)$N$M$g+!LPTo zv(R-fc_C0i8j_z1@2%wj{&0os_csco!v$4AHdRJAV%4=7mYCVd-2$E%Kq2zhNcshZ z))8PcL~@JkvL4m61)bgjo9{M(kRqVm`%aK=!Q_C%g2wC-;;otASI8kWLz&%+Wkp}q zt8LKHZEoo>I4um70#ku`i*>OX=LgDSeI`vvI)#7G)|VK*cR=VAsKlflUSwG7+M!l4 z{nJp$6oJRfG10$hm}fXTjHL?hk_x^t_kso?(S!{uh0fy?{e)s)tP5#HJs0 zjC!Ahn@!xr`lsVmnpK8&`yK-4%I3@miBq@{9Pvm&(oWF?pq3-a$irY5mT!mB`jygG z=Bt2<;P`P6TX7h!%x20q4Flu+W6NVQoovb3z!qHEdznD=epOA2;Qw(-_czt)=4LR> zJ?tQp33Drkl}44pliV8gWt?6W>H~w@fF&NWa>cNfX_r@_!dU4(hYIc~(7e-@Jng_a z1Og{s*fz+X0=GP4j5utO1okSL0p$SeQH+}ip-}*|qj0b!a)MzTBgJtclS|6f@WG`p zJlP=RLO%ROC+IgaKhY;~%U$T?>^=deF!YFu01*w&5wqXUH0%24R4q%cuI$wTsn$kO z_P~f*+X6g&D+=8gAP#DvAMgo-vWS)P=t%Gsnq(4`+8c`aa$~$%mobW`R3}kT)jl}K z?3&cxJe~=f6xY bH&;U&R_KQWiF_YsKoxOE4#R zhfPbwn7YUso* cO(z!4$QgW3KXiSDObZ4*4yRwzz%Nz|!T~7Y@fho ;U}xS=HrDEhl$X z js|d`<&TSka|AHv>QANCCfBa2*FGn`!kJ7j-(`E7p)DFC;%iL>t>LH57o;h`7%Zv zkjmm=4{~y5rG@Bz#cR<+IVYoHYOhEI1ccxU@SiAy*}z6n;rhG50vrcKPOCITWEu=~ zh0;gWrj3{AYM}628~T0ilxS#-Bxg%hMs@HkXnIUlieD3NL@7w$cpjDdt^bDFa6|$` zl}NuM(ZrvF4&7%OxcZ^XKji&q2C_5 Mc zF*XK41iI~Opa$aaw}NA%ezOsj{`iTQ-zicYKY@HC6) AQfN)<5Kp%E*!)CXNcMutkyHnlw#1px->-NYySZnYD4b>m_Vz%v zO3nC`6R0q;X>T!cpK3YHmDF~&Ljag$jsPLUA!1e2gg&T#q`---1_;#_nbd>!XdGf0 z!6pgWMWAVpoxaItKn|GwwD_>&-XF!L7y-+bMq#$-El{L53Ua=pIVrUefnscd8cO}L zL0&koSf%^h@L$8)CJItA)9yZq!I%2cr}@CDk891Xd_8&E3_BI6)?}+U*ZJ=8#Blcw z`P%EvehfEIeMH~}+yv_C_oYd@DM<`0S;Nq$*8G_`9a#(-kJm+644+GlHAN0sOU`|+ zfJ)vio7x>1I`3`(pIe^3!t^u1X8uws-;@>FaaSo?x=6svE-$O$Cut;>fnGsByZok? zJsyU=4b6OwtuG604kk9&A)|a?Nd3tx5S(A*<85?a)5+gl9{M8we7HY0@&Ym8n{H|* zIbXMgS7?&Rcu*(ovm;{Tp`ogrWV-l7cz;dL=(YISYd6%l>52+!26;vc_D*#MeQ1^C za|by`?24KknujF%k_g25{0cF(OA@0YhG-WT?Tz4hsow(FIseEuq+mnF4$8`Vqaix` zc<>sSB8nU38!gZ i9}i#qYJv!yx9Jz8MS(4r%CNL2_cv-D97+6H$s z=xFh|$G~_vm~?gu1-?@p2$1A1E5&ec0EdKz o`b@~6@8)j9lwFSu*5y?xj5_2J*? zJ9@a`Z|P0%-?a2^vr>oC+XHd^c7@1O0{bfky1N|GlR@k0Q|R^3@8R|u=#cU#iR#zM zkA28A51)VycRVX%Nm$nKodMW^iW4W<6or$=d(3dJhc-4~CA@j3z~?-@+&!d8#qLM~ zeJl%D`@QC-WqQzNOFGPXSkdj`L{8L9Ok*Jtu){DD8|rvNHh&T$4ar5XiM}n!t7B4> zCACVrc;LBKMw=rqYBe+>C^0ooO2aiLj){(1idvK_=JZ@(n`xkIXCMlqxlfp)|MSc1 z%a_q!*hg-lwBz~leChe>o-0Nf5!kcC*c)zwS@GG=6f{mD2wDyn44r#S^q-(pJKE!> zy7h&SYH+|1Riq(G$6ZouN01?uMNxb7*wiNO2orHm4p3SNSx{JDBS2Ul7xL~z_KHw} z+t_Ctmh3Lo2Yg`K)e~b47o&kI7cT)Ts{Azw&1H$Zm~&ZfF0;_5g4I*8xR%p_E4g6W zEDCggKx(UTiC^LD ulq-zRo&-Q|5&xouD$nJ%)@GpjI0+9i4hf2yFm|< zgl1*eVhmGqo6C{FJh?SulnA+c+5A~d6td tnANq^P*d-|>wJH2R5?#mG?$G}KRrU>L(VJrDQ-flrH8IF&eQE+r2_XJEWY zsuwv8_@yDjJ)Axv^Uh1jAB?=Umy&%Q-svsXPz>9RP4n5S|8{{5{lj&KFSk-KHEI2p zvR4QBOFFyZe1EK3P^7z_axZ_M2q&}GTh(-)T;LOet5m6zplp09jpOxL(t3}p%xyRt4T87s#Rowb1E-V0V8 z2;;{A+|)mG(KM_-$$W3HeMpWQ){Sa=r|N*%`P6&a=#u4#Mhhqn*d_WEL-q@^SAR66 zm#I&WWd@co$CC|eN&%R(Z35WSCb+$q)GociExhxQG__G#`#Q1uZ369*?L)@9A9+96 zH_0#JxH 3|DQ&Al*Q(cHvwa@6ERimw~XGkLJ+gST*EvUR~$IfiL(!DW%n`x!RO zaanie83ygv3Hrhl>BSj#Tba=?J2oEo)tU2Zb9)|#5ZAom$;If`@E~;xiS~IZ--DNy zS1?kSUv2K8LVOAyo$R08K^GA7n>%8&(m{W@;Z=yac;GoV6=D$u=1_D)u1kL2uH!KE z2}GE_O? lU?+6e-e@mD~pLM@HX-k?_A2=6gLR3hA!_~#4fxvzp zv>6~Hr6eHi@gvJMDuw>!Fv%99W6fQhBcneqy1%eDZlTTxM8X>jD %&fj7`YykGMM3Z&H>h?*fake8l@(nq4I-wc7zoRnDB02)J3 zBc5ZElol0lnP+?xao0?Y9Sd|#;0m!+`K{x&`rR0KwrQx^L~u+;N#@NYEsj}+Omx%S z+t-<2m^CZ!Wu&AG%O-#5t1+pYdMuK_8Wo)HaZU9(er$+YT+v}3;!o+m?)eJVBsN&T z6`fA-OYWp65O6hKy=EIF3_}M1zSR30EE>~#h!BwKk5#jG;hD>%xRjI1#}jWXK!idM z3CQ(Yv1dcI@EWu2cZ2YFyKlqwL4 k%8oE_nOTc1iU>Qw@~{>`xiAtU@0Ckq}6r2ff+qFzOu)^)lqU zn?6D`)4Ablysgo1vMNy6{1e+Jdeh(>DaY02z CA68bCjB`Sp8lyXIXT$(ZGr#Co&m~20XII=+b;$DV>ZBC@1WzfRz(a>4X=3~(G z^KT%Jvk={!D!*c1>ZgQR>`O&|h>S-FQKyZ8L>O*xpndp7)8sZCaWl!s;&sGdVn1Z= zd7h_dzk1$}BiBp`KQ>gfAZ6-J-!t@@EviGh!FD6PW2&u=tvytlc0f@a4D03R;xy5V z*RF>*VSvG&jxI7A$KQvF6exuaX!J)t)}^V2|Jf#uHmI0t_9UX<40}30XC^yZ w|Dv6-8=^7s8)=3qgF|&0Mn?o_4)_@^;exBt_EZhcn zgX^E&@SxTe_BetDl1rN!^wS8$KtXr;!)vG)++tfhI>$tA!q*t}9Xe=zLcXt(f5o^p z=&D(5V( W3o5lFNfXoOlTCP z@rr%VLtjV (jvAg0X zgk7z7Xn5`N7l58;i&l#7H`Gyz*pDwhug_ET&ObckZZ#P3I*_4&^POOLzMqgn89QRc zV0j}SkpAJi7sG5s1XgsYE9}uIbNgk<^GMWqRaK_9L6l&wp&o0l7^&!uGI95PYqw=e z3K}5jUu0d+HIQKLh}AgP*Wrf7^}&6-JIDOmo_56rFZd=+`aNEUG-0<3g6h#vAfRff z1qukhg4v`?-w88HMP3vN-g(0@-=u-sZ>4;P+uQEaAAn0-TG&{v5LM7xALB-Q%dOwU zb?mQ_Mj;_ub7uO}LY1uv>ShV@oO!)3-%8Ya(TdRpI%3^UH~5lVjw)7oR3sE$!6Dxb zgTqD&R18|$6|7>X?WmGeDZV#jfcJFZ0zNd~@2TrYK2o}Ps-Go>jW39BVDJ#IbyX34 zWI395wYNeDNyzwxuY{;>Dk~Fbn-7PEep>PTGpS5sK4qpF$lYi`#Gl_tO3_tn$RBFr z`l11MMX6=Y`&6r-%`LCGO*&5ysY`&kf5LbXo8SFNT^i>=hVe8Wd2Z|>eMnuJ>|&t+ z@gGo!r}woyL=t^*S=fvql00MV(I8-|z)<))e>LvGVv%XGv K#2)jM3*fp5r+Fs7Mz|Y`k%WYEkH_q~|%&uqBND#8tbmmq7co22<4N z&c=9KF}#|2|K!Zfp7?^#^yc%hDftuZbfs#geWyo(yn`uC6nAo@+%1t88{Z_#m==X= zv!1icNvcc0;LZ!#vqyPmrW2nrm{>Ah>l?K$)#D1c_Ck>k-M0NWNej9(AntyTU9?!^ zj&@egz(Tc&3JCZ~MITeHfw?$+9-~UgD^HAS!wDkq{#?CEUmg1mcCgloIM-01wbyS1 zx|-|le$IYIxV*~ AYPesO2lIAyt`9e{8~YGq=^R zf6%iLsJO3MW>7<%+8ST*?t=2(3K)wE4EAnue9k!0$O2eKnGUo$i8??guZr!r;zhns z`47F*HJ>Bo{tCU#z8SK_+83Et6U#nP>U6N40=q0%I4go(klBPtKb-*=oIfK0oonG9 zKlG7x--{ja5uZZaLUG!RC05xPV~Z)HE7zAR8ua(ytP?2F^$;PQ4g_eG80bOx2z5&| zSJY MQAg zORl`mPxwZnbxp2vJ4c8%#Q=bI7SHt0H =O|Ii<}sodCzu8C zHi)FH3!6+v{PM soBV-~er&Kb3AtpZF_&u$r&JJ+SbEnltSw zg3wwv2xTd9q=B8QwFL~gvhN?(Oq;IqUHyLs2m2f4Jb-Qy(5LpchwGC&mg}p2ICQc$ zA^l>|yOr|%VIrZ*nv7+)`yfO!r5ZrGLT_e;%b@%Sz5yBijgCEo8o|*l8Na27Na6K0 z$1aau!@@zPxsz(u4@1luZzK!NO?%KG4eB@^S6t5f_HiaRFJy@L$7JOXFsug(Wzr=! zp0m zKHQK}ZLolA32cUkS>v-XGF00!LE%z3$=xM1 OIL4G-x+PWmjUQNV z&o-mB5ywEIZ-vFn+^`!`2o{6?y3?=HavN*sQpZd+4BM{2S`xldqO{<1++eY>H<$dHpQ#Gy^X}zMKwQe=-yWf`0%(Z?_qrFISqinFm z`JSupU$hRtx#STt3-o#XAQk G5D3_bJ=orVV4Tp|gx^Vv3t^t>VLw0aYXVrY@jLS} zK0ZB;Jz;!O+iwA*ZDYNmM%_a+w2zuUYmT)~D5cT>FLXZgMqkqT6EOAXeT2N1p=ev9 z7bXZYDi@%KQ}*?4HiXYI0Jqcn&600IWwmw-7~)}+-&9w?L?Nc`vPO~z1k+4an_DpA z1J@$~vbyzVNV^>I`4@PQ1vZr`sS`10aAJgOJh>M?*XMTx3AWTmmp?NMxckuiP-g>v zsC{*ukdUXVOQ%310^6sVILYNrOE%zbq6dzgJag8Ru0tsbJlmWW%$<^2oz-YBf5dy* z^JXyE9|I)f&}&B!2jIl3n5xNKsS3!wn4(Ai^PVVINvQsl5m56HM{jQNOm%Z<*8WvQ z@L`>%0F~cjwxm#dxjy_=y@r2b>5SxvYRlr!*}F`=BiLPPeTCPp6$-)^Ke?_nOrzyD zur3P#t8fU5FTE)B`&p^4`}SzYC=ngEwDTzordO=vBE}V`3agkkd=YRmns0))>b&wK zwfAsp>RegWFwou6)`3zmH&=Xdr~d?M3J&zPXq9+q2=2G-cssK9SC;SiY6!TQ@9S0^ zUw3tNeJ2|v*=E;X&$T)`3Nb6!?y^`2uDjrKdfe_vT0dX I4wne3`2ji}t*)699$LqYIUR!E_p9!QZGi$H0Nn-Mz}_Bdal05SXG3}6hSs71-r z`fM;QXqK^|!38AprKOrKOndKWEl7O{6@=TNDAe9n?4#0clGfuNlQuC<34Bm?A1 gSi%zZ+RnC z_~TnUgfMW`7cr%sB#Bov`VYtoun9M>eyUkVpnC?J#X@8Lo HfAmKw!fh5qD=qKa627M;CewJj`s8T)J>|2(Gws2&=k)k0zi&rA zx;{VJzDL`c<^09cQbSj@wkSM9x_uW)$0;IQO3XE!tzm|{H^R?rU(5MrIQoIiu!<$x zT=B5*1wiaM6Dj#?;npLNhC{rR&S+iqh))U(i``{3UymEI1y?V$c4HvRXD(`_0>5~d zcH~>6v&ta8!oh-yPqy%i=aVbqwRlbRt-gLquvhABF-s{f2D$Pjg=wDCiRUJB;=V%G z&jA6rs#66UWU6I+$Iv3{12?RRVs&ScudXR)e&-hXs=uMB9oNa3wZ5rZI}3Q? ;-HoX)6%skt~ zt~PVOEl*ExDV6o(5YqykozI|+WAAT+NpDB?OG}5-NOcn@rPrMOFn{(-D~Hn}B-H;G zB3&)|kkIyDXyb6YgM>c+LR*JZ%r_=Z(0`%br}umvIlxVyyx+JhUa%b8GH>LlFUUkw zZtkGLe?sor-)QG5z`^@*R(EOd_$2QkSy{HcZa}wN8@G*vTc0uO#5FpP=32*isy|jc zxf&Tk8szVq+Zrv+b$Kt-xVj?HvSp0-fGNdJTe4>^Pd=pM$boIBM%+nRaUD=w=Q`U5 z00+G(T04kGy?(qfUF&!v1goK \n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Global%20Secure%20Access/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\n[Global Secure Access](https://aka.ms/GlobalSecureAccess) is a [domain solution](https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fsentinel%2Fsentinel-solutions-catalog%23domain-solutions&data=05%7C01%7Ckavishbakshi%40microsoft.com%7Cbe2a496082b24caa4b8c08da9cefacca%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637994850502413731%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=OJegu%2B2EqD7rmYmK9pm9QniD6YWp5ooloZ6tHzcwVi0%3D&reserved=0) and does not include any data connectors. The content in this solution requires one of the product solutions below.\n\n**Prerequisite :-**\n\n Install one or more of the listed solutions to unlock the value provided by this solution.\n 1. Microsoft Entra Id \n\n**Underlying Microsoft Technologies used:** \n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs: \n 1. Product solutions as described above \n\n\n**Workbooks:** 2, **Hunting Queries:** 21\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "subscription": { + "resourceProviders": [ + "Microsoft.OperationsManagement/solutions", + "Microsoft.OperationalInsights/workspaces/providers/alertRules", + "Microsoft.Insights/workbooks", + "Microsoft.Logic/workflows" + ] + }, + "location": { + "metadata": { + "hidden": "Hiding location, we get it from the log analytics workspace" + }, + "visible": false + }, + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "getLAWorkspace", + "type": "Microsoft.Solutions.ArmApiControl", + "toolTip": "This filters by workspaces that exist in the Resource Group selected", + "condition": "[greater(length(resourceGroup().name),0)]", + "request": { + "method": "GET", + "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]" + } + }, + { + "name": "workspace", + "type": "Microsoft.Common.DropDown", + "label": "Workspace", + "placeholder": "Select a workspace", + "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected", + "constraints": { + "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", + "required": true + }, + "visible": true + } + ], + "steps": [ + { + "name": "workbooks", + "label": "Workbooks", + "subLabel": { + "preValidation": "Configure the workbooks", + "postValidation": "Done" + }, + "bladeTitle": "Workbooks", + "elements": [ + { + "name": "workbooks-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This Microsoft Sentinel Solution installs workbooks. Workbooks provide a flexible canvas for data monitoring, analysis, and the creation of rich visual reports within the Azure portal. They allow you to tap into one or many data sources from Microsoft Sentinel and combine them into unified interactive experiences." + } + }, + { + "name": "workbooks-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data" + } + } + }, + { + "name": "workbook1", + "type": "Microsoft.Common.Section", + "label": "TextBlock", + "elements": [ + { + "name": "workbook1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "TextBlock" + } + } + ] + }, + { + "name": "workbook2", + "type": "Microsoft.Common.Section", + "label": "TextBlock", + "elements": [ + { + "name": "workbook2-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "TextBlock" + } + } + ] + } + ] + }, + { + "name": "huntingqueries", + "label": "Hunting Queries", + "bladeTitle": "Hunting Queries", + "elements": [ + { + "name": "huntingqueries-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs the following hunting queries. After installing the solution, run these hunting queries to hunt for threats in Manage solution view." + } + }, + { + "name": "huntingqueries-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/hunting" + } + } + }, + { + "name": "huntingquery1", + "type": "Microsoft.Common.Section", + "label": "Anomalous access to other users' mailboxes", + "elements": [ + { + "name": "huntingquery1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Looks for users accessing multiple other users' mailboxes or accessing multiple folders in another users mailbox. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery2", + "type": "Microsoft.Common.Section", + "label": "External User Added and Removed in a Short Timeframe", + "elements": [ + { + "name": "huntingquery2-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This hunting query identifies external user accounts that are added to a Team and then removed within one hour. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery3", + "type": "Microsoft.Common.Section", + "label": "External user from a new organisation added to Teams", + "elements": [ + { + "name": "huntingquery3-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This query identifies external users added to Teams where the user's domain is not one previously seen in Teams data. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery4", + "type": "Microsoft.Common.Section", + "label": "Mail Redirect via ExO Transport Rule", + "elements": [ + { + "name": "huntingquery4-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Identifies when Exchange Online transport rule is configured to forward emails.\nThis could be an adversary mailbox configured to collect mail from multiple user accounts. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery5", + "type": "Microsoft.Common.Section", + "label": "Bots added to multiple teams", + "elements": [ + { + "name": "huntingquery5-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This hunting query helps identify bots added to multiple Teams in a short space of time. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery6", + "type": "Microsoft.Common.Section", + "label": "User made Owner of multiple teams", + "elements": [ + { + "name": "huntingquery6-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This hunting query identifies users who have been made Owner of multiple Teams. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery7", + "type": "Microsoft.Common.Section", + "label": "Multiple Teams deleted by a single user", + "elements": [ + { + "name": "huntingquery7-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This hunting query identifies where multiple Teams have been deleted by a single user in a short timeframe. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery8", + "type": "Microsoft.Common.Section", + "label": "Previously Unseen Bot or Application Added to Teams", + "elements": [ + { + "name": "huntingquery8-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This hunting query helps identify new, and potentially unapproved applications or bots being added to Teams. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery9", + "type": "Microsoft.Common.Section", + "label": "New Windows Reserved Filenames staged on Office file services", + "elements": [ + { + "name": "huntingquery9-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This identifies new Windows Reserved Filenames on Office services like SharePoint and OneDrive in the past 7 days. It also detects when a user uploads these files to another user's workspace, which may indicate malicious activity. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery10", + "type": "Microsoft.Common.Section", + "label": "Office Mail Forwarding - Hunting Version", + "elements": [ + { + "name": "huntingquery10-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Adversaries often abuse email-forwarding rules to monitor victim activities, steal information, and gain intelligence on the victim or their organization. This query highlights cases where user mail is being forwarded, including to external domains. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery11", + "type": "Microsoft.Common.Section", + "label": "Files uploaded to teams and access summary", + "elements": [ + { + "name": "huntingquery11-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This hunting query identifies files uploaded to SharePoint via a Teams chat and\nsummarizes users and IP addresses that have accessed these files. This allows for \nidentification of anomalous file sharing patterns. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery12", + "type": "Microsoft.Common.Section", + "label": "User added to Teams and immediately uploads file", + "elements": [ + { + "name": "huntingquery12-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This hunting query identifies users who are added to a Teams Channel or Teams chat\nand within 1 minute of being added upload a file via the chat. This might be\nan indicator of suspicious activity. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery13", + "type": "Microsoft.Common.Section", + "label": "Windows Reserved Filenames Staged on Office File Services", + "elements": [ + { + "name": "huntingquery13-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This identifies Windows Reserved Filenames on Office services like SharePoint and OneDrive. It also detects when a user uploads these files to another user's workspace, which may indicate malicious activity. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery14", + "type": "Microsoft.Common.Section", + "label": "Exes with double file extension and access summary", + "elements": [ + { + "name": "huntingquery14-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Provides a summary of executable files with double file extensions in SharePoint \n and the users and IP addresses that have accessed them. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery15", + "type": "Microsoft.Common.Section", + "label": "New Admin Account Activity Seen Which Was Not Seen Historically", + "elements": [ + { + "name": "huntingquery15-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This will help you discover any new admin account activity which was seen and were not seen historically.\nAny new accounts seen in the results can be validated and investigated for any suspicious activities. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery16", + "type": "Microsoft.Common.Section", + "label": "SharePointFileOperation via previously unseen IPs", + "elements": [ + { + "name": "huntingquery16-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Shows SharePoint upload/download volume by IPs with high-risk ASNs. New IPs with volume spikes may be unauthorized and exfiltrating documents. This hunting query depends on AzureActiveDirectory AzureActiveDirectory data connector (SigninLogs EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery17", + "type": "Microsoft.Common.Section", + "label": "SharePointFileOperation via devices with previously unseen user agents", + "elements": [ + { + "name": "huntingquery17-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Tracking via user agent is one way to differentiate between types of connecting device.\nIn homogeneous enterprise environments the user agent associated with an attacker device may stand out as unusual. This hunting query depends on AzureActiveDirectory AzureActiveDirectory data connector (SigninLogs EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery18", + "type": "Microsoft.Common.Section", + "label": "Non-owner mailbox login activity", + "elements": [ + { + "name": "huntingquery18-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Finds non-owner mailbox access by admin/delegate permissions. Whitelist valid users and check others for unauthorized access. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery19", + "type": "Microsoft.Common.Section", + "label": "PowerShell or non-browser mailbox login activity", + "elements": [ + { + "name": "huntingquery19-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Detects mailbox login from Exchange PowerShell. All accounts can use it by default, but admins can change it. Whitelist benign activities. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery20", + "type": "Microsoft.Common.Section", + "label": "SharePoint File Operation via Client IP with Previously Unseen User Agents", + "elements": [ + { + "name": "huntingquery20-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "New user agents associated with a client IP for SharePoint file uploads/downloads. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + }, + { + "name": "huntingquery21", + "type": "Microsoft.Common.Section", + "label": "Multiple Users Email Forwarded to Same Destination", + "elements": [ + { + "name": "huntingquery21-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Identifies when multiple (more than one) users' mailboxes are configured to forward to the same destination. \nThis could be an attacker-controlled destination mailbox configured to collect mail from multiple compromised user accounts. This hunting query depends on AzureActiveDirectory data connector (EnrichedMicrosoft365AuditLogs Parser or Table)" + } + } + ] + } + ] + } + ], + "outputs": { + "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", + "location": "[location()]", + "workspace": "[basics('workspace')]" + } + } +} \ No newline at end of file diff --git a/Solutions/Global Secure Access/Package/mainTemplate.json b/Solutions/Global Secure Access/Package/mainTemplate.json new file mode 100644 index 00000000000..344ae182315 --- /dev/null +++ b/Solutions/Global Secure Access/Package/mainTemplate.json @@ -0,0 +1,2277 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "author": "Microsoft - support@microsoft.com", + "comments": "Solution template for Global Secure Access" + }, + "parameters": { + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + }, + "workbook1-name": { + "type": "string", + "defaultValue": null, + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + }, + "workbook2-name": { + "type": "string", + "defaultValue": null, + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + } + }, + "variables": { + "email": "support@microsoft.com", + "_email": "[variables('email')]", + "_solutionName": "Global Secure Access", + "_solutionVersion": "3.0.0", + "solutionId": "azuresentinel.azure-sentinel-solution-globalsecureaccess", + "_solutionId": "[variables('solutionId')]", + "workbookVersion1": "", + "workbookContentId1": "", + "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", + "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]", + "_workbookContentId1": "[variables('workbookContentId1')]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", + "workbookVersion2": "", + "workbookContentId2": "", + "workbookId2": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId2'))]", + "workbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId2'))))]", + "_workbookContentId2": "[variables('workbookContentId2')]", + "_workbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId2'),'-', variables('workbookVersion2'))))]", + "huntingQueryObject1": { + "huntingQueryVersion1": "2.0.1", + "_huntingQuerycontentId1": "271e8881-3044-4332-a5f4-42264c2e0315", + "huntingQueryTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('271e8881-3044-4332-a5f4-42264c2e0315')))]" + }, + "huntingQueryObject2": { + "huntingQueryVersion2": "2.0.1", + "_huntingQuerycontentId2": "119d9e1c-afcc-4d23-b239-cdb4e7bf851c", + "huntingQueryTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('119d9e1c-afcc-4d23-b239-cdb4e7bf851c')))]" + }, + "huntingQueryObject3": { + "huntingQueryVersion3": "2.0.1", + "_huntingQuerycontentId3": "6fce5baf-bfc2-4c56-a6b7-9c4733fc5a45", + "huntingQueryTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('6fce5baf-bfc2-4c56-a6b7-9c4733fc5a45')))]" + }, + "huntingQueryObject4": { + "huntingQueryVersion4": "2.0.1", + "_huntingQuerycontentId4": "9891684a-1e3a-4546-9403-3439513cbc70", + "huntingQueryTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('9891684a-1e3a-4546-9403-3439513cbc70')))]" + }, + "huntingQueryObject5": { + "huntingQueryVersion5": "2.0.1", + "_huntingQuerycontentId5": "9eb64924-ec8d-44d0-b1f2-10665150fb74", + "huntingQueryTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('9eb64924-ec8d-44d0-b1f2-10665150fb74')))]" + }, + "huntingQueryObject6": { + "huntingQueryVersion6": "2.0.1", + "_huntingQuerycontentId6": "558f15dd-3171-4b11-bf24-31c0610a20e0", + "huntingQueryTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('558f15dd-3171-4b11-bf24-31c0610a20e0')))]" + }, + "huntingQueryObject7": { + "huntingQueryVersion7": "2.0.1", + "_huntingQuerycontentId7": "64990414-b015-4edf-bef0-343b741e68c5", + "huntingQueryTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('64990414-b015-4edf-bef0-343b741e68c5')))]" + }, + "huntingQueryObject8": { + "huntingQueryVersion8": "2.0.1", + "_huntingQuerycontentId8": "bf76e508-9282-4cf1-9cc1-5c20c3dea2ee", + "huntingQueryTemplateSpecName8": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('bf76e508-9282-4cf1-9cc1-5c20c3dea2ee')))]" + }, + "huntingQueryObject9": { + "huntingQueryVersion9": "2.0.1", + "_huntingQuerycontentId9": "641ecd2d-27c9-4f05-8433-8205096b09fc", + "huntingQueryTemplateSpecName9": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('641ecd2d-27c9-4f05-8433-8205096b09fc')))]" + }, + "huntingQueryObject10": { + "huntingQueryVersion10": "2.0.1", + "_huntingQuerycontentId10": "d49fc965-aef3-49f6-89ad-10cc4697eb5b", + "huntingQueryTemplateSpecName10": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('d49fc965-aef3-49f6-89ad-10cc4697eb5b')))]" + }, + "huntingQueryObject11": { + "huntingQueryVersion11": "2.0.1", + "_huntingQuerycontentId11": "90e198a9-efb6-4719-ad89-81b8e93633a7", + "huntingQueryTemplateSpecName11": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('90e198a9-efb6-4719-ad89-81b8e93633a7')))]" + }, + "huntingQueryObject12": { + "huntingQueryVersion12": "2.0.1", + "_huntingQuerycontentId12": "3d6d0c04-7337-40cf-ace6-c471d442356d", + "huntingQueryTemplateSpecName12": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('3d6d0c04-7337-40cf-ace6-c471d442356d')))]" + }, + "huntingQueryObject13": { + "huntingQueryVersion13": "2.0.1", + "_huntingQuerycontentId13": "61c28cd7-3139-4731-8ea7-2cbbeabb4684", + "huntingQueryTemplateSpecName13": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('61c28cd7-3139-4731-8ea7-2cbbeabb4684')))]" + }, + "huntingQueryObject14": { + "huntingQueryVersion14": "2.0.1", + "_huntingQuerycontentId14": "d12580c2-1474-4125-a8a3-553f50d91215", + "huntingQueryTemplateSpecName14": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('d12580c2-1474-4125-a8a3-553f50d91215')))]" + }, + "huntingQueryObject15": { + "huntingQueryVersion15": "2.0.1", + "_huntingQuerycontentId15": "723c5f46-133f-4f1e-ada6-5c138f811d75", + "huntingQueryTemplateSpecName15": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('723c5f46-133f-4f1e-ada6-5c138f811d75')))]" + }, + "huntingQueryObject16": { + "huntingQueryVersion16": "2.0.1", + "_huntingQuerycontentId16": "e3d24cfd-b2a1-4ba7-8f80-0360892f9d57", + "huntingQueryTemplateSpecName16": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('e3d24cfd-b2a1-4ba7-8f80-0360892f9d57')))]" + }, + "huntingQueryObject17": { + "huntingQueryVersion17": "2.0.1", + "_huntingQuerycontentId17": "f2367171-1514-4c67-88ef-27434b6a1093", + "huntingQueryTemplateSpecName17": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('f2367171-1514-4c67-88ef-27434b6a1093')))]" + }, + "huntingQueryObject18": { + "huntingQueryVersion18": "2.0.1", + "_huntingQuerycontentId18": "0a8f410d-38b5-4d75-90da-32b472b97230", + "huntingQueryTemplateSpecName18": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('0a8f410d-38b5-4d75-90da-32b472b97230')))]" + }, + "huntingQueryObject19": { + "huntingQueryVersion19": "2.0.1", + "_huntingQuerycontentId19": "49a4f65a-fe18-408e-afec-042fde93d3ce", + "huntingQueryTemplateSpecName19": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('49a4f65a-fe18-408e-afec-042fde93d3ce')))]" + }, + "huntingQueryObject20": { + "huntingQueryVersion20": "2.0.1", + "_huntingQuerycontentId20": "e8ae1375-4640-430c-ae8e-2514d09c71eb", + "huntingQueryTemplateSpecName20": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('e8ae1375-4640-430c-ae8e-2514d09c71eb')))]" + }, + "huntingQueryObject21": { + "huntingQueryVersion21": "2.0.1", + "_huntingQuerycontentId21": "a1551ae4-f61c-4bca-9c57-4d0d681db2e9", + "huntingQueryTemplateSpecName21": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('a1551ae4-f61c-4bca-9c57-4d0d681db2e9')))]" + }, + "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('workbookTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "GSAM365EnrichedEvents Workbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('workbookVersion1')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Insights/workbooks", + "name": "[variables('workbookContentId1')]", + "location": "[parameters('workspace-location')]", + "kind": "shared", + "apiVersion": "2021-08-01", + "metadata": { + "description": "" + }, + "properties": { + "displayName": "[parameters('workbook1-name')]", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Traffic Logs workbook\\n---\\n\\nLog information in the dashboard is limited to 30 days.\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"ff8b2a55-1849-4848-acf8-eab5452e9f10\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LogAnalyticWorkspace\",\"label\":\"Log Analytic Workspace\",\"type\":5,\"description\":\"The log analytic workspace in which to execute the queries\",\"isRequired\":true,\"query\":\"resources\\r\\n| where type == \\\"microsoft.operationalinsights/workspaces\\\"\\r\\n| project id\",\"typeSettings\":{\"resourceTypeFilter\":{\"microsoft.operationalinsights/workspaces\":true},\"additionalResourceOptions\":[\"value::1\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"defaultValue\":\"value::1\",\"queryType\":1,\"resourceType\":\"microsoft.resourcegraph/resources\"},{\"id\":\"f15f34d8-8e2d-4c39-8dee-be2f979c86a8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":2592000000}},{\"id\":\"8bab511b-53b3-4220-9d1c-372345b06728\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Users\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"EnrichedMicrosoft365AuditLogsDemos_CL\\r\\n| summarize Count = count() by UserId_s\\r\\n| order by Count desc, UserId_s asc\\r\\n| project Value = UserId_s, Label = strcat(UserId_s, ' - ', Count, ' Logs'), Selected = false\",\"typeSettings\":{\"limitSelectTo\":20,\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":1,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 15\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"2b2cd1be-9d25-412c-8444-f005c4789b55\",\"cellValue\":\"tabSel\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Overview\",\"subTarget\":\"Overview\",\"style\":\"link\"},{\"id\":\"cc3e67f2-f20f-4430-8dee-d0773b90d9ce\",\"cellValue\":\"tabSel\",\"linkTarget\":\"parameter\",\"linkLabel\":\"All Traffic\",\"subTarget\":\"AllTraffic\",\"style\":\"link\"}]},\"name\":\"links - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| project \\r\\n Timestamp = createdDateTime_t,\\r\\n User = userPrincipalName_s,\\r\\n SourceIP = SourceIP,\\r\\n DestinationIP = destinationIp_s,\\r\\n DestinationPort = destinationPort_d,\\r\\n Action = action_s,\\r\\n PolicyName = policyName_s,\\r\\n TransportProtocol = transportProtocol_s,\\r\\n TrafficType = trafficType_s,\\r\\n DestinationURL = destinationUrl_s,\\r\\n ReceivedBytes = receivedBytes_d,\\r\\n SentBytes = sentBytes_d,\\r\\n DeviceOS = deviceOperatingSystem_s,\\r\\n PolicyRuleID = policyRuleId_s\\r\\n| order by Timestamp desc\",\"size\":3,\"showAnalytics\":true,\"title\":\"Log\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":1000,\"filter\":true}},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"AllTraffic\"},\"name\":\"query - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"// Unique Users\\nNetworkAccessDemo_CL\\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\n| project SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\\n| summarize UniqueUsers=dcount(Country)\\n| extend snapshot = \\\"Total Locations\\\"\\n| project col1 = UniqueUsers, snapshot\\n\\n// Union with Unique Devices\\n| union (\\n NetworkAccessDemo_CL\\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\\n | extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\\n | summarize TotalBytesGB = sum(BytesInGB)\\n | extend snapshot = \\\"Total Bytes (GB)\\\"\\n | project col1 = tolong(TotalBytesGB), snapshot\\n)\\n\\n// Union with Total Internet Access\\n| union (\\n NetworkAccessDemo_CL\\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\\n | summarize TotalTransactions = count()\\n | extend snapshot = \\\"Total Transactions\\\"\\n | project col1 = TotalTransactions, snapshot\\n)\\n\\n// Union with Total Private Access\\n// Order by Snapshot for consistent tile ordering on dashboard\\n| order by snapshot\",\"size\":4,\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"snapshot\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"col1\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"}},\"showBorder\":true,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"ExistingClients\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"ExistingClients\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"ExistingClients\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"Overview\"},\"name\":\"query - 2\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\\r\\n| summarize TotalBytesGB = sum(BytesInGB) by bin(createdDateTime_t, 1h), trafficType_s\\r\\n| order by bin(createdDateTime_t, 1h) asc, trafficType_s asc\\r\\n| project createdDateTime_t, trafficType_s, TotalBytesGB\\r\\n\",\"size\":2,\"title\":\"Usage over Time (GB)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"Overview\"},\"name\":\"query - 0\"}]},\"name\":\"group - 5\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\\r\\n| project createdDateTime_t, SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\\r\\n| where Country != \\\"\\\"\\r\\n| summarize Count = count() by City, State, Country\\r\\n\",\"size\":0,\"title\":\"Locations\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"map\",\"mapSettings\":{\"locInfo\":\"CountryRegion\",\"locInfoColumn\":\"Country\",\"latitude\":\"Latitude\",\"longitude\":\"Longitude\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"labelSettings\":\"Country\",\"legendMetric\":\"Country\",\"legendAggregation\":\"Count\",\"itemColorSettings\":{\"nodeColorField\":\"Count\",\"colorAggregation\":\"Sum\",\"type\":\"heatmap\",\"heatmapPalette\":\"turquoise\"}}},\"customWidth\":\"50\",\"name\":\"query - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where tolower(action_s) == \\\"allow\\\" and destinationWebCategory_displayName_s != '' // Filter for allowed traffic\\r\\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\\r\\n| summarize Count = count() by firstCategory\\r\\n| top 10 by Count\\r\\n\",\"size\":2,\"title\":\"Top Allowed Web Categories\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where tolower(action_s) == \\\"block\\\" and destinationFQDN_s != '' // Filter for allowed traffic\\r\\n| summarize Count = count() by destinationFQDN_s\\r\\n| top 100 by Count\",\"size\":0,\"title\":\"Top Blocked Destinations\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where tolower(action_s) == \\\"block\\\" and destinationWebCategory_displayName_s != '' // Filter for blocked traffic\\r\\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\\r\\n| summarize Count = count() by firstCategory\\r\\n| top 10 by Count\\r\\n\",\"size\":3,\"title\":\"Top Blocked Web Categories\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where sentBytes_d > 0\\r\\n| where tolower(action_s) != \\\"block\\\" \\r\\n| summarize Count = count() , Sent = sum(sentBytes_d), Recived = sum(receivedBytes_d), Total = sum(receivedBytes_d+ sentBytes_d) by destinationFQDN_s\\r\\n| order by Count desc\\r\\n\",\"size\":0,\"title\":\"Top Allowed Destinations\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Count\",\"formatter\":4,\"formatOptions\":{\"palette\":\"magenta\"}},{\"columnMatch\":\"Recived\",\"formatter\":4,\"formatOptions\":{\"palette\":\"turquoise\"}},{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"palette\":\"pink\"}},{\"columnMatch\":\"Sent\",\"formatter\":4,\"formatOptions\":{\"palette\":\"blue\"}}]}},\"customWidth\":\"50\",\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where transportProtocol_s != ''\\r\\n| summarize Count = count() by toupper(transportProtocol_s)\\r\\n| top 10 by Count\\r\\n\",\"size\":2,\"title\":\"Protocol Distburion\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 3\"}]},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"Overview\"},\"name\":\"group - 4\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", + "version": "1.0", + "sourceId": "[variables('workspaceResourceId')]", + "category": "sentinel" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", + "properties": { + "description": ".description", + "parentId": "[variables('workbookId1')]", + "contentId": "[variables('_workbookContentId1')]", + "kind": "Workbook", + "version": "[variables('workbookVersion1')]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_workbookContentId1')]", + "contentKind": "Workbook", + "displayName": "[parameters('workbook1-name')]", + "contentProductId": "[variables('_workbookcontentProductId1')]", + "id": "[variables('_workbookcontentProductId1')]", + "version": "[variables('workbookVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('workbookTemplateSpecName2')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "GSANetworkTraffic Workbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('workbookVersion2')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Insights/workbooks", + "name": "[variables('workbookContentId2')]", + "location": "[parameters('workspace-location')]", + "kind": "shared", + "apiVersion": "2021-08-01", + "metadata": { + "description": "" + }, + "properties": { + "displayName": "[parameters('workbook2-name')]", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Traffic Logs workbook\\n---\\n\\nLog information in the dashboard is limited to 30 days.\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"crossComponentResources\":[\"\"],\"parameters\":[{\"id\":\"ff8b2a55-1849-4848-acf8-eab5452e9f10\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LogAnalyticWorkspace\",\"label\":\"Log Analytic Workspace\",\"type\":5,\"description\":\"The log analytic workspace in which to execute the queries\",\"isRequired\":true,\"query\":\"resources\\r\\n| where type == \\\"microsoft.operationalinsights/workspaces\\\"\\r\\n| project id\",\"typeSettings\":{\"resourceTypeFilter\":{\"microsoft.operationalinsights/workspaces\":true},\"additionalResourceOptions\":[\"value::1\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"defaultValue\":\"value::1\",\"queryType\":1,\"resourceType\":\"microsoft.resourcegraph/resources\"},{\"id\":\"f15f34d8-8e2d-4c39-8dee-be2f979c86a8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":2592000000}},{\"id\":\"8bab511b-53b3-4220-9d1c-372345b06728\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Users\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"EnrichedMicrosoft365AuditLogsDemos_CL\\r\\n| summarize Count = count() by UserId_s\\r\\n| order by Count desc, UserId_s asc\\r\\n| project Value = UserId_s, Label = strcat(UserId_s, ' - ', Count, ' Logs'), Selected = false\",\"typeSettings\":{\"limitSelectTo\":20,\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":1,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 15\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"2b2cd1be-9d25-412c-8444-f005c4789b55\",\"cellValue\":\"tabSel\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Overview\",\"subTarget\":\"Overview\",\"style\":\"link\"},{\"id\":\"cc3e67f2-f20f-4430-8dee-d0773b90d9ce\",\"cellValue\":\"tabSel\",\"linkTarget\":\"parameter\",\"linkLabel\":\"All Traffic\",\"subTarget\":\"AllTraffic\",\"style\":\"link\"}]},\"name\":\"links - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| project \\r\\n Timestamp = createdDateTime_t,\\r\\n User = userPrincipalName_s,\\r\\n SourceIP = SourceIP,\\r\\n DestinationIP = destinationIp_s,\\r\\n DestinationPort = destinationPort_d,\\r\\n Action = action_s,\\r\\n PolicyName = policyName_s,\\r\\n TransportProtocol = transportProtocol_s,\\r\\n TrafficType = trafficType_s,\\r\\n DestinationURL = destinationUrl_s,\\r\\n ReceivedBytes = receivedBytes_d,\\r\\n SentBytes = sentBytes_d,\\r\\n DeviceOS = deviceOperatingSystem_s,\\r\\n PolicyRuleID = policyRuleId_s\\r\\n| order by Timestamp desc\",\"size\":3,\"showAnalytics\":true,\"title\":\"Log\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":1000,\"filter\":true}},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"AllTraffic\"},\"name\":\"query - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"// Unique Users\\nNetworkAccessDemo_CL\\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\n| project SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\\n| summarize UniqueUsers=dcount(Country)\\n| extend snapshot = \\\"Total Locations\\\"\\n| project col1 = UniqueUsers, snapshot\\n\\n// Union with Unique Devices\\n| union (\\n NetworkAccessDemo_CL\\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\\n | extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\\n | summarize TotalBytesGB = sum(BytesInGB)\\n | extend snapshot = \\\"Total Bytes (GB)\\\"\\n | project col1 = tolong(TotalBytesGB), snapshot\\n)\\n\\n// Union with Total Internet Access\\n| union (\\n NetworkAccessDemo_CL\\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\\n | summarize TotalTransactions = count()\\n | extend snapshot = \\\"Total Trasnacations\\\"\\n | project col1 = TotalTransactions, snapshot\\n)\\n\\n// Union with Total Private Access\\n// Order by Snapshot for consistent tile ordering on dashboard\\n| order by snapshot\",\"size\":4,\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"snapshot\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"col1\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"}},\"showBorder\":true,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"ExistingClients\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"ExistingClients\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"ExistingClients\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"Overview\"},\"name\":\"query - 2\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\\r\\n| summarize TotalBytesGB = sum(BytesInGB) by bin(createdDateTime_t, 1h), trafficType_s\\r\\n| order by bin(createdDateTime_t, 1h) asc, trafficType_s asc\\r\\n| project createdDateTime_t, trafficType_s, TotalBytesGB\\r\\n\",\"size\":2,\"title\":\"Usage over Time (GB)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"Overview\"},\"name\":\"query - 0\"}]},\"name\":\"group - 5\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\\r\\n| project createdDateTime_t, SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\\r\\n| where Country != \\\"\\\"\\r\\n| summarize Count = count() by City, State, Country\\r\\n\\r\\n\",\"size\":0,\"title\":\"Locations\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"map\",\"mapSettings\":{\"locInfo\":\"CountryRegion\",\"locInfoColumn\":\"Country\",\"latitude\":\"Latitude\",\"longitude\":\"Longitude\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"labelSettings\":\"Country\",\"legendMetric\":\"Country\",\"legendAggregation\":\"Count\",\"itemColorSettings\":{\"nodeColorField\":\"Count\",\"colorAggregation\":\"Sum\",\"type\":\"heatmap\",\"heatmapPalette\":\"turquoise\"}}},\"customWidth\":\"50\",\"name\":\"query - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where tolower(action_s) == \\\"allow\\\" and destinationWebCategory_displayName_s != '' // Filter for allowed traffic\\r\\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\\r\\n| summarize Count = count() by firstCategory\\r\\n| top 10 by Count\\r\\n\",\"size\":2,\"title\":\"Top Allowed Web Categories\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where tolower(action_s) == \\\"block\\\" and destinationFQDN_s != '' // Filter for allowed traffic\\r\\n| summarize Count = count() by destinationFQDN_s\\r\\n| top 100 by Count\",\"size\":0,\"title\":\"Top Blocked Destinations\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where tolower(action_s) == \\\"block\\\" and destinationWebCategory_displayName_s != '' // Filter for blocked traffic\\r\\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\\r\\n| summarize Count = count() by firstCategory\\r\\n| top 10 by Count\\r\\n\",\"size\":3,\"title\":\"Top Blocked Web Categories\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where sentBytes_d > 0\\r\\n| where tolower(action_s) != \\\"block\\\" \\r\\n| summarize Count = count() , Sent = sum(sentBytes_d), Recived = sum(receivedBytes_d), Total = sum(receivedBytes_d+ sentBytes_d) by destinationFQDN_s\\r\\n| order by Count desc\\r\\n\",\"size\":0,\"title\":\"Top Allowed Destinations\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Count\",\"formatter\":4,\"formatOptions\":{\"palette\":\"magenta\"}},{\"columnMatch\":\"Recived\",\"formatter\":4,\"formatOptions\":{\"palette\":\"turquoise\"}},{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"palette\":\"pink\"}},{\"columnMatch\":\"Sent\",\"formatter\":4,\"formatOptions\":{\"palette\":\"blue\"}}]}},\"customWidth\":\"50\",\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"NetworkAccessDemo_CL\\r\\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\\r\\n| where transportProtocol_s != ''\\r\\n| summarize Count = count() by toupper(transportProtocol_s)\\r\\n| top 10 by Count\\r\\n\",\"size\":2,\"title\":\"Protocol Distburion\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 3\"}]},\"conditionalVisibility\":{\"parameterName\":\"tabSel\",\"comparison\":\"isEqualTo\",\"value\":\"Overview\"},\"name\":\"group - 4\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", + "version": "1.0", + "sourceId": "[variables('workspaceResourceId')]", + "category": "sentinel" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId2'),'/'))))]", + "properties": { + "description": ".description", + "parentId": "[variables('workbookId2')]", + "contentId": "[variables('_workbookContentId2')]", + "kind": "Workbook", + "version": "[variables('workbookVersion2')]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_workbookContentId2')]", + "contentKind": "Workbook", + "displayName": "[parameters('workbook2-name')]", + "contentProductId": "[variables('_workbookcontentProductId2')]", + "id": "[variables('_workbookcontentProductId2')]", + "version": "[variables('workbookVersion2')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject1').huntingQueryTemplateSpecName1]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "AnomolousUserAccessingOtherUsersMailbox_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_1", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Anomalous access to other users' mailboxes", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = totimespan((endtime - starttime) * 2);\n// Adjust this value to alter how many mailbox (other than their own) a user needs to access before being included in results\nlet user_threshold = 1;\n// Adjust this value to alter how many mailbox folders in other's email accounts a users needs to access before being included in results.\nlet folder_threshold = 5;\n// Exclude historical as known good (set lookback and timeframe to same value to skip this)\nEnrichedMicrosoft365AuditLogs\n| where TimeGenerated between (ago(lookback)..starttime)\n| where Operation =~ \"MailItemsAccessed\"\n| where ResultStatus =~ \"Succeeded\"\n| extend MailboxOwnerUPN = tostring(parse_json(AdditionalProperties).MailboxOwnerUPN)\n| where tolower(MailboxOwnerUPN) != tolower(UserId)\n| join kind=rightanti (\n EnrichedMicrosoft365AuditLogs\n | where TimeGenerated between (starttime..endtime)\n | where Operation =~ \"MailItemsAccessed\"\n | where ResultStatus =~ \"Succeeded\"\n | extend MailboxOwnerUPN = tostring(parse_json(AdditionalProperties).MailboxOwnerUPN)\n | where tolower(MailboxOwnerUPN) != tolower(UserId)\n) on MailboxOwnerUPN, UserId\n| where isnotempty(tostring(parse_json(AdditionalProperties).Folders))\n| mv-expand Folders = parse_json(AdditionalProperties).Folders\n| extend folders = tostring(Folders.Path)\n| extend ClientIP = iif(ClientIp startswith \"[\", extract(\"\\\\[([^\\\\]]*)\", 1, ClientIp), ClientIp)\n| extend ClientInfoString = tostring(parse_json(AdditionalProperties).ClientInfoString)\n| extend MailboxGuid = tostring(parse_json(AdditionalProperties).MailboxGuid)\n| summarize StartTime = max(TimeGenerated), EndTime = min(TimeGenerated), set_folders = make_set(folders, 100000), set_ClientInfoString = make_set(ClientInfoString, 100000), set_ClientIP = make_set(ClientIP, 100000), set_MailboxGuid = make_set(MailboxGuid, 100000), set_MailboxOwnerUPN = make_set(MailboxOwnerUPN, 100000) by UserId\n| extend folder_count = array_length(set_folders)\n| extend user_count = array_length(set_MailboxGuid)\n| where user_count > user_threshold or folder_count > folder_threshold\n| extend Reason = case(user_count > user_threshold and folder_count > folder_threshold, \"Both User and Folder Threshold Exceeded\", folder_count > folder_threshold and user_count < user_threshold, \"Folder Count Threshold Exceeded\", \"User Threshold Exceeded\")\n| sort by user_count desc\n| project-reorder UserId, user_count, folder_count, set_MailboxOwnerUPN, set_ClientIP, set_ClientInfoString, set_folders\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Looks for users accessing multiple other users' mailboxes or accessing multiple folders in another users mailbox." + }, + { + "name": "tactics", + "value": "Collection" + }, + { + "name": "techniques", + "value": "T1114.002" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject1')._huntingQuerycontentId1),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 1", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject1')._huntingQuerycontentId1)]", + "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject1').huntingQueryVersion1]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]", + "contentKind": "HuntingQuery", + "displayName": "Anomalous access to other users' mailboxes", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject2').huntingQueryTemplateSpecName2]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "ExternalUserAddedRemovedInTeams_HuntVersion_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_2", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "External User Added and Removed in a Short Timeframe", + "category": "Hunting Queries", + "query": "// If you want to look at user added further than 7 days ago adjust this value\n// If you want to change the timeframe of how quickly accounts need to be added and removed change this value\nlet time_delta = 1h;\nEnrichedMicrosoft365AuditLogs\n| where Workload == \"MicrosoftTeams\"\n| where Operation == \"MemberAdded\"\n| extend UPN = tostring(parse_json(tostring(AdditionalProperties)).UPN) // Assuming UPN is stored in AdditionalProperties\n| where UPN contains \"#EXT#\"\n| project TimeAdded = TimeGenerated, Operation, UPN, UserWhoAdded = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName), TeamGuid = tostring(parse_json(tostring(AdditionalProperties)).TeamGuid)\n| join kind=innerunique (\n EnrichedMicrosoft365AuditLogs\n | where Workload == \"MicrosoftTeams\"\n | where Operation == \"MemberRemoved\"\n | extend UPN = tostring(parse_json(tostring(AdditionalProperties)).UPN) // Assuming UPN is stored in AdditionalProperties\n | where UPN contains \"#EXT#\"\n | project TimeDeleted = TimeGenerated, Operation, UPN, UserWhoDeleted = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName), TeamGuid = tostring(parse_json(tostring(AdditionalProperties)).TeamGuid)\n) on UPN, TeamGuid\n| where TimeDeleted < (TimeAdded + time_delta)\n| project TimeAdded, TimeDeleted, UPN, UserWhoAdded, UserWhoDeleted, TeamName, TeamGuid\n| extend AccountName = tostring(split(UPN, \"@\")[0]), AccountUPNSuffix = tostring(split(UPN, \"@\")[1])\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This hunting query identifies external user accounts that are added to a Team and then removed within one hour." + }, + { + "name": "tactics", + "value": "Persistence" + }, + { + "name": "techniques", + "value": "T1136" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject2')._huntingQuerycontentId2),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 2", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject2')._huntingQuerycontentId2)]", + "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject2').huntingQueryVersion2]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]", + "contentKind": "HuntingQuery", + "displayName": "External User Added and Removed in a Short Timeframe", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject3').huntingQueryTemplateSpecName3]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "ExternalUserFromNewOrgAddedToTeams_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_3", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "External user from a new organisation added to Teams", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = totimespan((endtime - starttime) * 7);\nlet known_orgs = (\n EnrichedMicrosoft365AuditLogs\n | where TimeGenerated between (ago(lookback) .. starttime)\n | where Workload == \"MicrosoftTeams\"\n | where Operation in (\"MemberAdded\", \"TeamsSessionStarted\")\n // Extract the correct UPN and parse our external organization domain\n | extend Members = parse_json(tostring(AdditionalProperties.Members))\n | extend UPN = iif(Operation == \"MemberAdded\", tostring(Members[0].UPN), UserId)\n | extend Organization = tostring(split(split(UPN, \"_\")[1], \"#\")[0])\n | where isnotempty(Organization)\n | summarize by Organization\n);\nEnrichedMicrosoft365AuditLogs\n| where TimeGenerated between (starttime .. endtime)\n| where Workload == \"MicrosoftTeams\"\n| where Operation == \"MemberAdded\"\n| extend Members = parse_json(tostring(AdditionalProperties.Members))\n| extend UPN = tostring(Members[0].UPN)\n| extend Organization = tostring(split(split(UPN, \"_\")[1], \"#\")[0])\n| where isnotempty(Organization)\n| where Organization !in (known_orgs)\n| extend AccountName = tostring(split(UPN, \"@\")[0]), AccountUPNSuffix = tostring(split(UPN, \"@\")[1])\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This query identifies external users added to Teams where the user's domain is not one previously seen in Teams data." + }, + { + "name": "tactics", + "value": "Persistence" + }, + { + "name": "techniques", + "value": "T1136" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject3')._huntingQuerycontentId3),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 3", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject3')._huntingQuerycontentId3)]", + "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject3').huntingQueryVersion3]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]", + "contentKind": "HuntingQuery", + "displayName": "External user from a new organisation added to Teams", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject4').huntingQueryTemplateSpecName4]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "Mail_redirect_via_ExO_transport_rule_hunting_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_4", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Mail Redirect via ExO Transport Rule", + "category": "Hunting Queries", + "query": "EnrichedMicrosoft365AuditLogs\n| where Workload == \"Exchange\"\n| where Operation in (\"New-TransportRule\", \"Set-TransportRule\")\n| mv-apply DynamicParameters = todynamic(AdditionalProperties.Parameters) on (summarize ParsedParameters = make_bag(pack(tostring(DynamicParameters.Name), DynamicParameters.Value)))\n| extend RuleName = case(\n Operation == \"Set-TransportRule\", ObjectId,\n Operation == \"New-TransportRule\", ParsedParameters.Name,\n \"Unknown\")\n| mv-expand ExpandedParameters = todynamic(AdditionalProperties.Parameters)\n| where ExpandedParameters.Name in (\"BlindCopyTo\", \"RedirectMessageTo\") and isnotempty(ExpandedParameters.Value)\n| extend RedirectTo = ExpandedParameters.Value\n| extend ClientIPValues = extract_all(@'\\[?(::ffff:)?(?P (\\d+\\.\\d+\\.\\d+\\.\\d+)|[^\\]]+)\\]?([-:](?P \\d+))?', dynamic([\"IPAddress\", \"Port\"]), ClientIp)[0]\n| project TimeGenerated, RedirectTo, IPAddress = tostring(ClientIPValues[0]), Port = tostring(ClientIPValues[1]), UserId, Operation, RuleName, AdditionalProperties\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Identifies when Exchange Online transport rule is configured to forward emails.\nThis could be an adversary mailbox configured to collect mail from multiple user accounts." + }, + { + "name": "tactics", + "value": "Collection,Exfiltration" + }, + { + "name": "techniques", + "value": "T1114,T1020" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject4')._huntingQuerycontentId4),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 4", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject4')._huntingQuerycontentId4)]", + "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject4').huntingQueryVersion4]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]", + "contentKind": "HuntingQuery", + "displayName": "Mail Redirect via ExO Transport Rule", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject5').huntingQueryTemplateSpecName5]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "MultiTeamBot_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_5", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Bots added to multiple teams", + "category": "Hunting Queries", + "query": "// Adjust these thresholds to suit your environment.\nlet threshold = 2;\nlet time_threshold = timespan(5m);\nEnrichedMicrosoft365AuditLogs\n | where Workload == \"MicrosoftTeams\"\n | where Operation == \"BotAddedToTeam\"\n | extend TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)\n | summarize Start = max(TimeGenerated), End = min(TimeGenerated), Teams = make_set(TeamName, 10000) by UserId\n | extend CountOfTeams = array_length(Teams)\n | extend TimeDelta = End - Start\n | where CountOfTeams > threshold\n | where TimeDelta <= time_threshold\n | project Start, End, Teams, CountOfTeams, UserId\n | extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n | extend Account_0_Name = AccountName\n | extend Account_0_UPNSuffix = AccountUPNSuffix\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This hunting query helps identify bots added to multiple Teams in a short space of time." + }, + { + "name": "tactics", + "value": "Persistence,Collection" + }, + { + "name": "techniques", + "value": "T1176,T1119" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject5')._huntingQuerycontentId5),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 5", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject5')._huntingQuerycontentId5)]", + "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject5').huntingQueryVersion5]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]", + "contentKind": "HuntingQuery", + "displayName": "Bots added to multiple teams", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject6').huntingQueryTemplateSpecName6]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "MultiTeamOwner_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_6", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "User made Owner of multiple teams", + "category": "Hunting Queries", + "query": "// Adjust this value to change how many teams a user is made owner of before detecting\nlet max_owner_count = 3;\n// Identify users who have been made owner of multiple Teams\nlet high_owner_count = (\n EnrichedMicrosoft365AuditLogs\n | where Workload == \"MicrosoftTeams\"\n | where Operation == \"MemberRoleChanged\"\n | extend Member = tostring(UserId)\n | extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)\n | where NewRole == 2\n | summarize TeamCount = dcount(ObjectId) by Member\n | where TeamCount > max_owner_count\n | project Member\n);\nEnrichedMicrosoft365AuditLogs\n| where Workload == \"MicrosoftTeams\"\n| where Operation == \"MemberRoleChanged\"\n| extend Member = tostring(UserId)\n| extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)\n| where NewRole == 2\n| where Member in (high_owner_count)\n| extend AccountName = tostring(split(Member, \"@\")[0]), AccountUPNSuffix = tostring(split(Member, \"@\")[1])\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This hunting query identifies users who have been made Owner of multiple Teams." + }, + { + "name": "tactics", + "value": "PrivilegeEscalation" + }, + { + "name": "techniques", + "value": "T1078" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject6')._huntingQuerycontentId6),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 6", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject6')._huntingQuerycontentId6)]", + "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject6').huntingQueryVersion6]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]", + "contentKind": "HuntingQuery", + "displayName": "User made Owner of multiple teams", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject7').huntingQueryTemplateSpecName7]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "MultipleTeamsDeletes_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_7", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Multiple Teams deleted by a single user", + "category": "Hunting Queries", + "query": "// Adjust this value to change how many Teams should be deleted before including\nlet max_delete = 3;\nlet deleting_users = (\n EnrichedMicrosoft365AuditLogs\n | where Workload == \"MicrosoftTeams\"\n | where Operation == \"TeamDeleted\"\n | summarize count_ = count() by UserId\n | where count_ > max_delete\n | project UserId\n);\nEnrichedMicrosoft365AuditLogs\n| where Workload == \"MicrosoftTeams\"\n| where Operation == \"TeamDeleted\"\n| where UserId in (deleting_users)\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This hunting query identifies where multiple Teams have been deleted by a single user in a short timeframe." + }, + { + "name": "tactics", + "value": "Impact" + }, + { + "name": "techniques", + "value": "T1485,T1489" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject7')._huntingQuerycontentId7),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 7", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject7')._huntingQuerycontentId7)]", + "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject7').huntingQueryVersion7]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]", + "contentKind": "HuntingQuery", + "displayName": "Multiple Teams deleted by a single user", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject8').huntingQueryTemplateSpecName8]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "NewBotAddedToTeams_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_8", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Previously Unseen Bot or Application Added to Teams", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = starttime - 14d;\nlet historical_bots = \n EnrichedMicrosoft365AuditLogs\n | where TimeGenerated between (lookback .. starttime)\n | where Workload == \"MicrosoftTeams\"\n | extend AddonName = tostring(parse_json(tostring(AdditionalProperties)).AddonName)\n | where isnotempty(AddonName)\n | distinct AddonName;\nEnrichedMicrosoft365AuditLogs\n| where TimeGenerated between (starttime .. endtime)\n| where Workload == \"MicrosoftTeams\"\n| extend AddonName = tostring(parse_json(tostring(AdditionalProperties)).AddonName)\n| where AddonName !in (historical_bots)\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This hunting query helps identify new, and potentially unapproved applications or bots being added to Teams." + }, + { + "name": "tactics", + "value": "Persistence,Collection" + }, + { + "name": "techniques", + "value": "T1176,T1119" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject8')._huntingQuerycontentId8),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 8", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject8')._huntingQuerycontentId8)]", + "contentId": "[variables('huntingQueryObject8')._huntingQuerycontentId8]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject8').huntingQueryVersion8]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject8')._huntingQuerycontentId8]", + "contentKind": "HuntingQuery", + "displayName": "Previously Unseen Bot or Application Added to Teams", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject8')._huntingQuerycontentId8,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject8')._huntingQuerycontentId8,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject9').huntingQueryTemplateSpecName9]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "New_WindowsReservedFileNamesOnOfficeFileServices_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject9').huntingQueryVersion9]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_9", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "New Windows Reserved Filenames staged on Office file services", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = totimespan((endtime - starttime) * 7);\nlet Reserved = dynamic(['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9']);\nEnrichedMicrosoft365AuditLogs\n| where TimeGenerated between (starttime .. endtime)\n| extend FileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)\n| extend ClientUserAgent = tostring(parse_json(tostring(AdditionalProperties)).ClientUserAgent)\n| extend SiteUrl = tostring(parse_json(tostring(AdditionalProperties)).SiteUrl)\n| where isnotempty(ObjectId)\n| where ObjectId !~ FileName\n| where ObjectId in (Reserved) or FileName in (Reserved)\n| where ClientUserAgent !has \"Mac OS\"\n| project TimeGenerated, Id, Workload, RecordType, Operation, UserType, UserKey, UserId, ClientIp, ClientUserAgent, SiteUrl, ObjectId, FileName\n| join kind=leftanti (\n EnrichedMicrosoft365AuditLogs\n | where TimeGenerated between (ago(lookback) .. starttime)\n | extend FileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)\n | extend ClientUserAgent = tostring(parse_json(tostring(AdditionalProperties)).ClientUserAgent)\n | extend SiteUrl = tostring(parse_json(tostring(AdditionalProperties)).SiteUrl)\n | where isnotempty(ObjectId)\n | where ObjectId !~ FileName\n | where ObjectId in (Reserved) or FileName in (Reserved)\n | where ClientUserAgent !has \"Mac OS\"\n | summarize PrevSeenCount = count() by ObjectId, UserId, FileName\n) on ObjectId\n| extend SiteUrlUserFolder = tolower(split(SiteUrl, '/')[-2])\n| extend UserIdUserFolderFormat = tolower(replace_regex(UserId, '@|\\\\.', '_'))\n| extend UserIdDiffThanUserFolder = iff(SiteUrl has '/personal/' and SiteUrlUserFolder != UserIdUserFolderFormat, true, false)\n| summarize TimeGenerated = make_list(TimeGenerated, 100000), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), Operations = make_list(Operation, 100000), UserAgents = make_list(ClientUserAgent, 100000),\n Ids = make_list(Id, 100000), SourceRelativeUrls = make_list(ObjectId, 100000), FileNames = make_list(FileName, 100000)\n by Workload, RecordType, UserType, UserKey, UserId, ClientIp, SiteUrl, ObjectId, SiteUrlUserFolder, UserIdUserFolderFormat, UserIdDiffThanUserFolder\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend IP_0_Address = ClientIp\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n| extend URL_0_Url = SiteUrl\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This identifies new Windows Reserved Filenames on Office services like SharePoint and OneDrive in the past 7 days. It also detects when a user uploads these files to another user's workspace, which may indicate malicious activity." + }, + { + "name": "tactics", + "value": "CommandAndControl" + }, + { + "name": "techniques", + "value": "T1105" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject9')._huntingQuerycontentId9),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 9", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject9')._huntingQuerycontentId9)]", + "contentId": "[variables('huntingQueryObject9')._huntingQuerycontentId9]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject9').huntingQueryVersion9]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject9')._huntingQuerycontentId9]", + "contentKind": "HuntingQuery", + "displayName": "New Windows Reserved Filenames staged on Office file services", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject9')._huntingQuerycontentId9,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject9')._huntingQuerycontentId9,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject10').huntingQueryTemplateSpecName10]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "OfficeMailForwarding_hunting_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject10').huntingQueryVersion10]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_10", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Office Mail Forwarding - Hunting Version", + "category": "Hunting Queries", + "query": "EnrichedMicrosoft365AuditLogs\n| where Workload == \"Exchange\"\n| where (Operation == \"Set-Mailbox\" and tostring(parse_json(tostring(AdditionalProperties))) contains 'ForwardingSmtpAddress') \n or (Operation in ('New-InboxRule', 'Set-InboxRule') and (tostring(parse_json(tostring(AdditionalProperties))) contains 'ForwardTo' or tostring(parse_json(tostring(AdditionalProperties))) contains 'RedirectTo'))\n| extend parsed = parse_json(tostring(AdditionalProperties))\n| extend fwdingDestination_initial = iif(Operation == \"Set-Mailbox\", tostring(parsed.ForwardingSmtpAddress), coalesce(tostring(parsed.ForwardTo), tostring(parsed.RedirectTo)))\n| where isnotempty(fwdingDestination_initial)\n| extend fwdingDestination = iff(fwdingDestination_initial has \"smtp\", (split(fwdingDestination_initial, \":\")[1]), fwdingDestination_initial)\n| parse fwdingDestination with * '@' ForwardedtoDomain \n| parse UserId with *'@' UserDomain\n| extend subDomain = ((split(strcat(tostring(split(UserDomain, '.')[-2]), '.', tostring(split(UserDomain, '.')[-1])), '.'))[0])\n| where ForwardedtoDomain !contains subDomain\n| extend Result = iff(ForwardedtoDomain != UserDomain, \"Mailbox rule created to forward to External Domain\", \"Forward rule for Internal domain\")\n| extend ClientIPAddress = case(ClientIp has \".\", tostring(split(ClientIp, \":\")[0]), ClientIp has \"[\", tostring(trim_start(@'[[]', tostring(split(ClientIp, \"]\")[0]))), ClientIp)\n| extend Port = case(\n ClientIp has \".\",\n (split(ClientIp, \":\")[1]),\n ClientIp has \"[\",\n tostring(split(ClientIp, \"]:\")[1]),\n ClientIp\n )\n| project\n TimeGenerated,\n UserId,\n UserDomain,\n subDomain,\n Operation,\n ForwardedtoDomain,\n ClientIPAddress,\n Result,\n Port,\n ObjectId,\n fwdingDestination,\n AdditionalProperties\n| extend\n AccountName = tostring(split(UserId, \"@\")[0]),\n AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend Host = tostring(parse_json(tostring(AdditionalProperties)).OriginatingServer)\n| extend HostName = tostring(split(Host, \".\")[0])\n| extend DnsDomain = tostring(strcat_array(array_slice(split(Host, '.'), 1, -1), '.'))\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n| extend IP_0_Address = ClientIPAddress\n| extend Host_0_HostName = HostName\n| extend Host_0_DnsDomain = DnsDomain\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Adversaries often abuse email-forwarding rules to monitor victim activities, steal information, and gain intelligence on the victim or their organization. This query highlights cases where user mail is being forwarded, including to external domains." + }, + { + "name": "tactics", + "value": "Collection,Exfiltration" + }, + { + "name": "techniques", + "value": "T1114,T1020" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject10')._huntingQuerycontentId10),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 10", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject10')._huntingQuerycontentId10)]", + "contentId": "[variables('huntingQueryObject10')._huntingQuerycontentId10]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject10').huntingQueryVersion10]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject10')._huntingQuerycontentId10]", + "contentKind": "HuntingQuery", + "displayName": "Office Mail Forwarding - Hunting Version", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject10')._huntingQuerycontentId10,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject10')._huntingQuerycontentId10,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject11').huntingQueryTemplateSpecName11]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "TeamsFilesUploaded_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject11').huntingQueryVersion11]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_11", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Files uploaded to teams and access summary", + "category": "Hunting Queries", + "query": "EnrichedMicrosoft365AuditLogs\n| where RecordType == \"SharePointFileOperation\"\n| where Operation == \"FileUploaded\"\n| where UserId != \"app@sharepoint\"\n| where ObjectId has \"Microsoft Teams Chat Files\"\n| extend SourceFileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)\n| join kind=leftouter (\n EnrichedMicrosoft365AuditLogs\n | where RecordType == \"SharePointFileOperation\"\n | where Operation == \"FileDownloaded\" or Operation == \"FileAccessed\"\n | where UserId != \"app@sharepoint\"\n | where ObjectId has \"Microsoft Teams Chat Files\"\n | extend UserId1 = UserId, ClientIp1 = ClientIp\n) on ObjectId\n| extend userBag = bag_pack(\"UserId1\", UserId1, \"ClientIp1\", ClientIp1)\n| summarize AccessedBy = make_bag(userBag), make_set(UserId1, 10000) by bin(TimeGenerated, 1h), UserId, ObjectId, SourceFileName\n| extend NumberOfUsersAccessed = array_length(bag_keys(AccessedBy))\n| project timestamp = TimeGenerated, UserId, FileLocation = ObjectId, FileName = SourceFileName, AccessedBy, NumberOfUsersAccessed\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This hunting query identifies files uploaded to SharePoint via a Teams chat and\nsummarizes users and IP addresses that have accessed these files. This allows for \nidentification of anomalous file sharing patterns." + }, + { + "name": "tactics", + "value": "InitialAccess,Exfiltration" + }, + { + "name": "techniques", + "value": "T1199,T1102,T1078" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject11')._huntingQuerycontentId11),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 11", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject11')._huntingQuerycontentId11)]", + "contentId": "[variables('huntingQueryObject11')._huntingQuerycontentId11]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject11').huntingQueryVersion11]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject11')._huntingQuerycontentId11]", + "contentKind": "HuntingQuery", + "displayName": "Files uploaded to teams and access summary", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject11')._huntingQuerycontentId11,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject11')._huntingQuerycontentId11,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject12').huntingQueryTemplateSpecName12]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "UserAddToTeamsAndUploadsFile_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject12').huntingQueryVersion12]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_12", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "User added to Teams and immediately uploads file", + "category": "Hunting Queries", + "query": "let threshold = 1m;\nlet MemberAddedEvents = EnrichedMicrosoft365AuditLogs\n | where Workload == \"MicrosoftTeams\"\n | where Operation == \"MemberAdded\"\n | extend TeamName = tostring(parse_json(AdditionalProperties).TeamName)\n | project TimeGenerated, UploaderID = UserId, TeamName;\nlet FileUploadEvents = EnrichedMicrosoft365AuditLogs\n | where RecordType == \"SharePointFileOperation\"\n | where ObjectId has \"Microsoft Teams Chat Files\"\n | where Operation == \"FileUploaded\"\n | extend SourceFileName = tostring(parse_json(AdditionalProperties).SourceFileName)\n | project UploadTime = TimeGenerated, UploaderID = UserId, FileLocation = ObjectId, SourceFileName;\nMemberAddedEvents\n | join kind=inner (FileUploadEvents) on UploaderID\n | where UploadTime > TimeGenerated and UploadTime < TimeGenerated + threshold\n | extend timestamp = TimeGenerated, AccountCustomEntity = UploaderID\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This hunting query identifies users who are added to a Teams Channel or Teams chat\nand within 1 minute of being added upload a file via the chat. This might be\nan indicator of suspicious activity." + }, + { + "name": "tactics", + "value": "InitialAccess" + }, + { + "name": "techniques", + "value": "T1566" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject12')._huntingQuerycontentId12),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 12", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject12')._huntingQuerycontentId12)]", + "contentId": "[variables('huntingQueryObject12')._huntingQuerycontentId12]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject12').huntingQueryVersion12]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject12')._huntingQuerycontentId12]", + "contentKind": "HuntingQuery", + "displayName": "User added to Teams and immediately uploads file", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject12')._huntingQuerycontentId12,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject12')._huntingQuerycontentId12,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject13').huntingQueryTemplateSpecName13]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "WindowsReservedFileNamesOnOfficeFileServices_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject13').huntingQueryVersion13]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_13", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Windows Reserved Filenames Staged on Office File Services", + "category": "Hunting Queries", + "query": "// Reserved FileNames/Extension for Windows\nlet Reserved = dynamic(['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9']);\nEnrichedMicrosoft365AuditLogs\n| extend SourceFileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)\n| extend UserAgent = tostring(parse_json(tostring(AdditionalProperties)).UserAgent)\n| extend Site_Url = tostring(parse_json(tostring(AdditionalProperties)).SiteUrl)\n| where isnotempty(ObjectId)\n| where ObjectId in (Reserved) or SourceFileName in (Reserved)\n| where UserAgent !has \"Mac OS\"\n| extend SiteUrlUserFolder = tolower(split(Site_Url, '/')[-2])\n| extend UserIdUserFolderFormat = tolower(replace_regex(UserId, '@|\\\\.', '_'))\n// identify when UserId is not a match to the specific site url personal folder reference\n| extend UserIdDiffThanUserFolder = iff(Site_Url has '/personal/' and SiteUrlUserFolder != UserIdUserFolderFormat, true, false)\n| summarize TimeGenerated = make_list(TimeGenerated, 100000), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), Operations = make_list(Operation, 100000), UserAgents = make_list(UserAgent, 100000), ObjectIds = make_list(Id, 100000), SourceRelativeUrls = make_list(ObjectId, 100000), FileNames = make_list(SourceFileName, 100000)\nby Workload, RecordType, UserType, UserKey, UserId, ClientIp, Site_Url, ObjectId, SiteUrlUserFolder, UserIdUserFolderFormat, UserIdDiffThanUserFolder\n// Use mvexpand on any list items and you can expand out the exact time and other metadata about the hit\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend IP_0_Address = ClientIp\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n| extend URL_0_Url = Site_Url\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This identifies Windows Reserved Filenames on Office services like SharePoint and OneDrive. It also detects when a user uploads these files to another user's workspace, which may indicate malicious activity." + }, + { + "name": "tactics", + "value": "CommandAndControl" + }, + { + "name": "techniques", + "value": "T1105" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject13')._huntingQuerycontentId13),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 13", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject13')._huntingQuerycontentId13)]", + "contentId": "[variables('huntingQueryObject13')._huntingQuerycontentId13]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject13').huntingQueryVersion13]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject13')._huntingQuerycontentId13]", + "contentKind": "HuntingQuery", + "displayName": "Windows Reserved Filenames Staged on Office File Services", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject13')._huntingQuerycontentId13,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject13')._huntingQuerycontentId13,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject14').huntingQueryTemplateSpecName14]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "double_file_ext_exes_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject14').huntingQueryVersion14]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_14", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Exes with double file extension and access summary", + "category": "Hunting Queries", + "query": "let known_ext = dynamic([\"lnk\", \"log\", \"option\", \"config\", \"manifest\", \"partial\"]);\nlet excluded_users = dynamic([\"app@sharepoint\"]);\nEnrichedMicrosoft365AuditLogs\n| where RecordType == \"SharePointFileOperation\" and isnotempty(ObjectId)\n| where ObjectId has \".exe.\" \n and not(ObjectId endswith \".lnk\") \n and not(ObjectId endswith \".log\") \n and not(ObjectId endswith \".option\") \n and not(ObjectId endswith \".config\") \n and not(ObjectId endswith \".manifest\") \n and not(ObjectId endswith \".partial\")\n| extend Extension = extract(\"[^.]*\\\\.[^.]*$\", 0, ObjectId)\n| extend SourceFileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)\n| join kind=leftouter (\n EnrichedMicrosoft365AuditLogs\n | where RecordType == \"SharePointFileOperation\" and (Operation == \"FileDownloaded\" or Operation == \"FileAccessed\")\n | where not(ObjectId endswith \".lnk\") \n and not(ObjectId endswith \".log\") \n and not(ObjectId endswith \".option\") \n and not(ObjectId endswith \".config\") \n and not(ObjectId endswith \".manifest\") \n and not(ObjectId endswith \".partial\")\n) on ObjectId\n| where UserId1 !in (excluded_users)\n| extend userBag = bag_pack(\"UserId\", UserId1, \"ClientIp\", ClientIp1)\n| summarize make_set(UserId1, 10000), userBag = make_bag(userBag), UploadTime = max(TimeGenerated) by UserId, ObjectId, SourceFileName, Extension\n| extend NumberOfUsers = array_length(bag_keys(userBag))\n| project UploadTime, Uploader = UserId, FileLocation = ObjectId, FileName = SourceFileName, AccessedBy = userBag, Extension, NumberOfUsers\n| extend UploaderName = tostring(split(Uploader, \"@\")[0]), UploaderUPNSuffix = tostring(split(Uploader, \"@\")[1])\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Provides a summary of executable files with double file extensions in SharePoint \n and the users and IP addresses that have accessed them." + }, + { + "name": "tactics", + "value": "DefenseEvasion" + }, + { + "name": "techniques", + "value": "T1036" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject14')._huntingQuerycontentId14),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 14", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject14')._huntingQuerycontentId14)]", + "contentId": "[variables('huntingQueryObject14')._huntingQuerycontentId14]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject14').huntingQueryVersion14]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject14')._huntingQuerycontentId14]", + "contentKind": "HuntingQuery", + "displayName": "Exes with double file extension and access summary", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject14')._huntingQuerycontentId14,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject14')._huntingQuerycontentId14,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject15').huntingQueryTemplateSpecName15]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "new_adminaccountactivity_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject15').huntingQueryVersion15]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_15", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "New Admin Account Activity Seen Which Was Not Seen Historically", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = starttime - 14d;\nlet historicalActivity =\n EnrichedMicrosoft365AuditLogs\n | where TimeGenerated between (lookback .. starttime)\n | where RecordType == \"ExchangeAdmin\" and UserType in (\"Admin\", \"DcAdmin\")\n | summarize historicalCount = count() by UserId;\nlet recentActivity = EnrichedMicrosoft365AuditLogs\n | where TimeGenerated between (starttime .. endtime)\n | where UserType in (\"Admin\", \"DcAdmin\")\n | summarize recentCount = count() by UserId;\nrecentActivity\n| join kind=leftanti (historicalActivity) on UserId\n| project UserId, recentCount\n| join kind=rightsemi (\n EnrichedMicrosoft365AuditLogs\n | where TimeGenerated between (starttime .. endtime)\n | where RecordType == \"ExchangeAdmin\" \n | where UserType in (\"Admin\", \"DcAdmin\")\n ) on UserId\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by RecordType, Operation, UserType, UserId, ResultStatus\n| extend AccountName = iff(UserId contains '@', tostring(split(UserId, '@')[0]), UserId)\n| extend AccountUPNSuffix = iff(UserId contains '@', tostring(split(UserId, '@')[1]), '')\n| extend AccountName = iff(UserId contains '\\\\', tostring(split(UserId, '\\\\')[1]), AccountName)\n| extend AccountNTDomain = iff(UserId contains '\\\\', tostring(split(UserId, '\\\\')[0]), '')\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "This will help you discover any new admin account activity which was seen and were not seen historically.\nAny new accounts seen in the results can be validated and investigated for any suspicious activities." + }, + { + "name": "tactics", + "value": "PrivilegeEscalation,Collection" + }, + { + "name": "techniques", + "value": "T1078,T1114" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject15')._huntingQuerycontentId15),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 15", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject15')._huntingQuerycontentId15)]", + "contentId": "[variables('huntingQueryObject15')._huntingQuerycontentId15]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject15').huntingQueryVersion15]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject15')._huntingQuerycontentId15]", + "contentKind": "HuntingQuery", + "displayName": "New Admin Account Activity Seen Which Was Not Seen Historically", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject15')._huntingQuerycontentId15,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject15')._huntingQuerycontentId15,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject16').huntingQueryTemplateSpecName16]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "new_sharepoint_downloads_by_IP_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject16').huntingQueryVersion16]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_16", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "SharePointFileOperation via previously unseen IPs", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = starttime - 14d;\nlet BLOCK_THRESHOLD = 1.0;\nlet HighBlockRateASNs =\n SigninLogs\n | where TimeGenerated > lookback\n | where isnotempty(AutonomousSystemNumber)\n | summarize make_set(IPAddress), TotalIps = dcount(IPAddress), BlockedSignins = countif(ResultType == \"50053\"), TotalSignins = count() by AutonomousSystemNumber\n | extend BlockRatio = 1.00 * BlockedSignins / TotalSignins\n | where BlockRatio >= BLOCK_THRESHOLD\n | distinct AutonomousSystemNumber;\nlet ASNIPs =\n SigninLogs\n | where TimeGenerated > lookback\n | where AutonomousSystemNumber in (HighBlockRateASNs)\n | distinct IPAddress, AutonomousSystemNumber;\nEnrichedMicrosoft365AuditLogs\n| where TimeGenerated between (starttime .. endtime)\n| where RecordType == \"SharePointFileOperation\"\n| where Operation in (\"FileDownloaded\", \"FileUploaded\")\n| where ClientIp in (ASNIPs)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), RecentFileActivities = count() by ClientIp\n| extend IP_0_Address = ClientIp\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Shows SharePoint upload/download volume by IPs with high-risk ASNs. New IPs with volume spikes may be unauthorized and exfiltrating documents." + }, + { + "name": "tactics", + "value": "Exfiltration" + }, + { + "name": "techniques", + "value": "T1030" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject16')._huntingQuerycontentId16),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 16", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject16')._huntingQuerycontentId16)]", + "contentId": "[variables('huntingQueryObject16')._huntingQuerycontentId16]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject16').huntingQueryVersion16]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject16')._huntingQuerycontentId16]", + "contentKind": "HuntingQuery", + "displayName": "SharePointFileOperation via previously unseen IPs", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject16')._huntingQuerycontentId16,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject16')._huntingQuerycontentId16,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject17').huntingQueryTemplateSpecName17]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "new_sharepoint_downloads_by_UserAgent_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject17').huntingQueryVersion17]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_17", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "SharePointFileOperation via devices with previously unseen user agents", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = starttime - 14d;\nlet MINIMUM_BLOCKS = 10;\nlet SUCCESS_THRESHOLD = 0.2;\nlet HistoricalActivity = \n SigninLogs\n | where TimeGenerated > lookback\n | where isnotempty(ClientAppUsed)\n | summarize SuccessfulSignins = countif(ResultType == \"0\"), BlockedSignins = countif(ResultType == \"50053\") by ClientAppUsed\n | extend SuccessBlockRatio = 1.00 * SuccessfulSignins / BlockedSignins\n | where SuccessBlockRatio < SUCCESS_THRESHOLD\n | where BlockedSignins > MINIMUM_BLOCKS;\nEnrichedMicrosoft365AuditLogs\n| where TimeGenerated between (starttime .. endtime)\n| where RecordType == \"SharePointFileOperation\"\n| where Operation in (\"FileDownloaded\", \"FileUploaded\")\n| extend ClientAppUsed = tostring(parse_json(AdditionalProperties).UserAgent)\n| extend SiteUrl = tostring(parse_json(AdditionalProperties).SiteUrl)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), RecentFileActivities = count() by ClientAppUsed, UserId, ClientIp, SiteUrl\n| join kind=innerunique (HistoricalActivity) on ClientAppUsed\n| project-away ClientAppUsed1\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend IP_0_Address = ClientIp\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n| extend URL_0_Url = SiteUrl\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Tracking via user agent is one way to differentiate between types of connecting device.\nIn homogeneous enterprise environments the user agent associated with an attacker device may stand out as unusual." + }, + { + "name": "tactics", + "value": "Exfiltration" + }, + { + "name": "techniques", + "value": "T1030" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject17')._huntingQuerycontentId17),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 17", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject17')._huntingQuerycontentId17)]", + "contentId": "[variables('huntingQueryObject17')._huntingQuerycontentId17]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject17').huntingQueryVersion17]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject17')._huntingQuerycontentId17]", + "contentKind": "HuntingQuery", + "displayName": "SharePointFileOperation via devices with previously unseen user agents", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject17')._huntingQuerycontentId17,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject17')._huntingQuerycontentId17,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject18').huntingQueryTemplateSpecName18]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "nonowner_MailboxLogin_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject18').huntingQueryVersion18]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_18", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Non-owner mailbox login activity", + "category": "Hunting Queries", + "query": "EnrichedMicrosoft365AuditLogs\n| where Workload == \"Exchange\"\n| where Operation == \"MailboxLogin\"\n| extend Logon_Type = tostring(parse_json(tostring(AdditionalProperties)).LogonType)\n| extend MailboxOwnerUPN = tostring(parse_json(tostring(AdditionalProperties)).MailboxOwnerUPN)\n| where Logon_Type != \"Owner\"\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by Operation, UserType, UserId, MailboxOwnerUPN, Logon_Type, ClientIp\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n| extend IP_0_Address = ClientIp\n| extend Account_0_Name = AccountName\n| extend Account_0_UPNSuffix = AccountUPNSuffix\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Finds non-owner mailbox access by admin/delegate permissions. Whitelist valid users and check others for unauthorized access." + }, + { + "name": "tactics", + "value": "Collection,Exfiltration" + }, + { + "name": "techniques", + "value": "T1114,T1020" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject18')._huntingQuerycontentId18),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 18", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject18')._huntingQuerycontentId18)]", + "contentId": "[variables('huntingQueryObject18')._huntingQuerycontentId18]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject18').huntingQueryVersion18]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject18')._huntingQuerycontentId18]", + "contentKind": "HuntingQuery", + "displayName": "Non-owner mailbox login activity", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject18')._huntingQuerycontentId18,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject18')._huntingQuerycontentId18,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject19').huntingQueryTemplateSpecName19]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "powershell_or_nonbrowser_MailboxLogin_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject19').huntingQueryVersion19]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_19", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "PowerShell or non-browser mailbox login activity", + "category": "Hunting Queries", + "query": "EnrichedMicrosoft365AuditLogs\n| where Workload == \"Exchange\" and Operation == \"MailboxLogin\"\n| extend ClientApplication = tostring(parse_json(AdditionalProperties).ClientInfoString)\n| where ClientApplication == \"Client=Microsoft.Exchange.Powershell; Microsoft WinRM Client\"\n| extend TenantName = tostring(parse_json(AdditionalProperties).TenantName)\n| extend MailboxOwner = tostring(parse_json(AdditionalProperties).MailboxOwnerUPN)\n| extend LogonType = tostring(parse_json(AdditionalProperties).LogonType)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by Operation, TenantName, UserType, UserId, MailboxOwner, LogonType, ClientApplication\n| extend AccountName = iff(UserId contains '@', tostring(split(UserId, '@')[0]), UserId)\n| extend AccountUPNSuffix = iff(UserId contains '@', tostring(split(UserId, '@')[1]), '')\n| extend AccountName = iff(UserId contains '\\\\', tostring(split(UserId, '\\\\')[1]), AccountName)\n| extend AccountNTDomain = iff(UserId contains '\\\\', tostring(split(UserId, '\\\\')[0]), '')\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Detects mailbox login from Exchange PowerShell. All accounts can use it by default, but admins can change it. Whitelist benign activities." + }, + { + "name": "tactics", + "value": "Execution,Persistence,Collection" + }, + { + "name": "techniques", + "value": "T1059,T1098,T1114" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject19')._huntingQuerycontentId19),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 19", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject19')._huntingQuerycontentId19)]", + "contentId": "[variables('huntingQueryObject19')._huntingQuerycontentId19]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject19').huntingQueryVersion19]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject19')._huntingQuerycontentId19]", + "contentKind": "HuntingQuery", + "displayName": "PowerShell or non-browser mailbox login activity", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject19')._huntingQuerycontentId19,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject19')._huntingQuerycontentId19,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject20').huntingQueryTemplateSpecName20]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "sharepoint_downloads_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject20').huntingQueryVersion20]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_20", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "SharePoint File Operation via Client IP with Previously Unseen User Agents", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet lookback = starttime - 14d;\nlet historicalUA = EnrichedMicrosoft365AuditLogs\n| where RecordType == \"SharePointFileOperation\"\n| where Operation in (\"FileDownloaded\", \"FileUploaded\")\n| where TimeGenerated between(lookback..starttime)\n| extend ClientApplication = tostring(parse_json(AdditionalProperties).UserAgent)\n| summarize by ClientIp, ClientApplication;\nlet recentUA = EnrichedMicrosoft365AuditLogs\n| where RecordType == \"SharePointFileOperation\"\n| where Operation in (\"FileDownloaded\", \"FileUploaded\")\n| where TimeGenerated between(starttime..endtime)\n| extend ClientApplication = tostring(parse_json(AdditionalProperties).UserAgent)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by ClientIp, ClientApplication;\nrecentUA | join kind=leftanti (\n historicalUA\n) on ClientIp, ClientApplication\n// Some EnrichedMicrosoft365AuditLogs records do not contain ClientIp information - exclude these for fewer results\n| where not(isempty(ClientIp))\n| extend IP_0_Address = ClientIp\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "New user agents associated with a client IP for SharePoint file uploads/downloads." + }, + { + "name": "tactics", + "value": "Exfiltration" + }, + { + "name": "techniques", + "value": "T1030" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject20')._huntingQuerycontentId20),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 20", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject20')._huntingQuerycontentId20)]", + "contentId": "[variables('huntingQueryObject20')._huntingQuerycontentId20]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject20').huntingQueryVersion20]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject20')._huntingQuerycontentId20]", + "contentKind": "HuntingQuery", + "displayName": "SharePoint File Operation via Client IP with Previously Unseen User Agents", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject20')._huntingQuerycontentId20,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject20')._huntingQuerycontentId20,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryObject21').huntingQueryTemplateSpecName21]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "MultipleUsersEmailForwardedToSameDestination_HuntingQueries Hunting Query with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('huntingQueryObject21').huntingQueryVersion21]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Global_Secure_Access_Hunting_Query_21", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Multiple Users Email Forwarded to Same Destination", + "category": "Hunting Queries", + "query": "let queryfrequency = 1d;\nlet queryperiod = 7d;\nEnrichedMicrosoft365AuditLogs\n| where TimeGenerated > ago(queryperiod)\n| where Workload == \"Exchange\"\n| where AdditionalProperties has_any (\"ForwardTo\", \"RedirectTo\", \"ForwardingSmtpAddress\")\n| mv-apply DynamicParameters = todynamic(AdditionalProperties) on (summarize ParsedParameters = make_bag(bag_pack(tostring(DynamicParameters.Name), DynamicParameters.Value)))\n| evaluate bag_unpack(ParsedParameters, columnsConflict='replace_source')\n| extend DestinationMailAddress = tolower(case(\n isnotempty(column_ifexists(\"ForwardTo\", \"\")), column_ifexists(\"ForwardTo\", \"\"),\n isnotempty(column_ifexists(\"RedirectTo\", \"\")), column_ifexists(\"RedirectTo\", \"\"),\n isnotempty(column_ifexists(\"ForwardingSmtpAddress\", \"\")), trim_start(@\"smtp:\", column_ifexists(\"ForwardingSmtpAddress\", \"\")),\n \"\"))\n| where isnotempty(DestinationMailAddress)\n| mv-expand split(DestinationMailAddress, \";\")\n| extend ClientIPValues = extract_all(@'\\[?(::ffff:)?(?P (\\d+\\.\\d+\\.\\d+\\.\\d+)|[^\\]]+)\\]?([-:](?P \\d+))?', dynamic([\"IPAddress\", \"Port\"]), ClientIp)[0]\n| extend ClientIp = tostring(ClientIPValues[0]), Port = tostring(ClientIPValues[1])\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), DistinctUserCount = dcount(UserId), UserId = make_set(UserId, 250), Ports = make_set(Port, 250), EventCount = count() by tostring(DestinationMailAddress), ClientIp\n| where DistinctUserCount > 1 and EndTime > ago(queryfrequency)\n| mv-expand UserId to typeof(string)\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "Identifies when multiple (more than one) users' mailboxes are configured to forward to the same destination. \nThis could be an attacker-controlled destination mailbox configured to collect mail from multiple compromised user accounts." + }, + { + "name": "tactics", + "value": "Collection,Exfiltration" + }, + { + "name": "techniques", + "value": "T1114,T1020" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject21')._huntingQuerycontentId21),'/'))))]", + "properties": { + "description": "Global Secure Access Hunting Query 21", + "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject21')._huntingQuerycontentId21)]", + "contentId": "[variables('huntingQueryObject21')._huntingQuerycontentId21]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryObject21').huntingQueryVersion21]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('huntingQueryObject21')._huntingQuerycontentId21]", + "contentKind": "HuntingQuery", + "displayName": "Multiple Users Email Forwarded to Same Destination", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject21')._huntingQuerycontentId21,'-', '2.0.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject21')._huntingQuerycontentId21,'-', '2.0.1')))]", + "version": "2.0.1" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "apiVersion": "2023-04-01-preview", + "location": "[parameters('workspace-location')]", + "properties": { + "version": "3.0.0", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "displayName": "Global Secure Access", + "publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation", + "descriptionHtml": " Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nGlobal Secure Access is a domain solution and does not include any data connectors. The content in this solution requires one of the product solutions below.
\nPrerequisite :-
\nInstall one or more of the listed solutions to unlock the value provided by this solution.
\n\n
\n- Microsoft Entra Id
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\n
\n- Product solutions as described above
\nWorkbooks: 2, Hunting Queries: 21
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", + "contentKind": "Solution", + "contentProductId": "[variables('_solutioncontentProductId')]", + "id": "[variables('_solutioncontentProductId')]", + "icon": "", + "contentId": "[variables('_solutionId')]", + "parentId": "[variables('_solutionId')]", + "source": { + "kind": "Solution", + "name": "Global Secure Access", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "tier": "Microsoft", + "link": "https://support.microsoft.com/" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "Workbook", + "contentId": "[variables('_workbookContentId1')]", + "version": "[variables('workbookVersion1')]" + }, + { + "kind": "Workbook", + "contentId": "[variables('_workbookContentId2')]", + "version": "[variables('workbookVersion2')]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]", + "version": "[variables('huntingQueryObject1').huntingQueryVersion1]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]", + "version": "[variables('huntingQueryObject2').huntingQueryVersion2]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]", + "version": "[variables('huntingQueryObject3').huntingQueryVersion3]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]", + "version": "[variables('huntingQueryObject4').huntingQueryVersion4]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]", + "version": "[variables('huntingQueryObject5').huntingQueryVersion5]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]", + "version": "[variables('huntingQueryObject6').huntingQueryVersion6]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]", + "version": "[variables('huntingQueryObject7').huntingQueryVersion7]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject8')._huntingQuerycontentId8]", + "version": "[variables('huntingQueryObject8').huntingQueryVersion8]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject9')._huntingQuerycontentId9]", + "version": "[variables('huntingQueryObject9').huntingQueryVersion9]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject10')._huntingQuerycontentId10]", + "version": "[variables('huntingQueryObject10').huntingQueryVersion10]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject11')._huntingQuerycontentId11]", + "version": "[variables('huntingQueryObject11').huntingQueryVersion11]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject12')._huntingQuerycontentId12]", + "version": "[variables('huntingQueryObject12').huntingQueryVersion12]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject13')._huntingQuerycontentId13]", + "version": "[variables('huntingQueryObject13').huntingQueryVersion13]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject14')._huntingQuerycontentId14]", + "version": "[variables('huntingQueryObject14').huntingQueryVersion14]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject15')._huntingQuerycontentId15]", + "version": "[variables('huntingQueryObject15').huntingQueryVersion15]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject16')._huntingQuerycontentId16]", + "version": "[variables('huntingQueryObject16').huntingQueryVersion16]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject17')._huntingQuerycontentId17]", + "version": "[variables('huntingQueryObject17').huntingQueryVersion17]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject18')._huntingQuerycontentId18]", + "version": "[variables('huntingQueryObject18').huntingQueryVersion18]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject19')._huntingQuerycontentId19]", + "version": "[variables('huntingQueryObject19').huntingQueryVersion19]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject20')._huntingQuerycontentId20]", + "version": "[variables('huntingQueryObject20').huntingQueryVersion20]" + }, + { + "kind": "HuntingQuery", + "contentId": "[variables('huntingQueryObject21')._huntingQuerycontentId21]", + "version": "[variables('huntingQueryObject21').huntingQueryVersion21]" + } + ] + }, + "firstPublishDate": "2024-04-08", + "providers": [ + "Microsoft" + ], + "categories": { + "domains": [ + "Identity" + ] + } + }, + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + } + ], + "outputs": {} +} diff --git a/Solutions/Global Secure Access/Package/testParameters.json b/Solutions/Global Secure Access/Package/testParameters.json new file mode 100644 index 00000000000..42428e73d9b --- /dev/null +++ b/Solutions/Global Secure Access/Package/testParameters.json @@ -0,0 +1,40 @@ +{ + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + }, + "workbook1-name": { + "type": "string", + "defaultValue": null, + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + }, + "workbook2-name": { + "type": "string", + "defaultValue": null, + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + } +} diff --git a/Solutions/Global Secure Access/SolutionMetadata.json b/Solutions/Global Secure Access/SolutionMetadata.json new file mode 100644 index 00000000000..2f6d9a50f6c --- /dev/null +++ b/Solutions/Global Secure Access/SolutionMetadata.json @@ -0,0 +1,15 @@ +{ + "publisherId": "azuresentinel", + "offerId": "azure-sentinel-solution-globalsecureaccess", + "firstPublishDate": "2024-04-08", + "providers": [ "Microsoft" ], + "categories": { + "domains": [ "Identity"] + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } +} \ No newline at end of file diff --git a/Solutions/Global Secure Access/Workbooks/GSAM365EnrichedEvents.json b/Solutions/Global Secure Access/Workbooks/GSAM365EnrichedEvents.json new file mode 100644 index 00000000000..e983bfd5a4c --- /dev/null +++ b/Solutions/Global Secure Access/Workbooks/GSAM365EnrichedEvents.json @@ -0,0 +1,418 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "## Traffic Logs workbook\n---\n\nLog information in the dashboard is limited to 30 days." + }, + "name": "text - 2" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [], + "parameters": [ + { + "id": "ff8b2a55-1849-4848-acf8-eab5452e9f10", + "version": "KqlParameterItem/1.0", + "name": "LogAnalyticWorkspace", + "label": "Log Analytic Workspace", + "type": 5, + "description": "The log analytic workspace in which to execute the queries", + "isRequired": true, + "query": "resources\r\n| where type == \"microsoft.operationalinsights/workspaces\"\r\n| project id", + "typeSettings": { + "resourceTypeFilter": { + "microsoft.operationalinsights/workspaces": true + }, + "additionalResourceOptions": [ + "value::1" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "f15f34d8-8e2d-4c39-8dee-be2f979c86a8", + "version": "KqlParameterItem/1.0", + "name": "TimeRange", + "label": "Time Range", + "type": 4, + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 300000 + }, + { + "durationMs": 900000 + }, + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 172800000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + } + ], + "allowCustom": true + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 2592000000 + } + }, + { + "id": "8bab511b-53b3-4220-9d1c-372345b06728", + "version": "KqlParameterItem/1.0", + "name": "Users", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "EnrichedMicrosoft365AuditLogsDemos_CL\r\n| summarize Count = count() by UserId_s\r\n| order by Count desc, UserId_s asc\r\n| project Value = UserId_s, Label = strcat(UserId_s, ' - ', Count, ' Logs'), Selected = false", + "typeSettings": { + "limitSelectTo": 20, + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "timeContext": { + "durationMs": 0 + }, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 15" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "2b2cd1be-9d25-412c-8444-f005c4789b55", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "Overview", + "subTarget": "Overview", + "style": "link" + }, + { + "id": "cc3e67f2-f20f-4430-8dee-d0773b90d9ce", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "All Traffic", + "subTarget": "AllTraffic", + "style": "link" + } + ] + }, + "name": "links - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| project \r\n Timestamp = createdDateTime_t,\r\n User = userPrincipalName_s,\r\n SourceIP = SourceIP,\r\n DestinationIP = destinationIp_s,\r\n DestinationPort = destinationPort_d,\r\n Action = action_s,\r\n PolicyName = policyName_s,\r\n TransportProtocol = transportProtocol_s,\r\n TrafficType = trafficType_s,\r\n DestinationURL = destinationUrl_s,\r\n ReceivedBytes = receivedBytes_d,\r\n SentBytes = sentBytes_d,\r\n DeviceOS = deviceOperatingSystem_s,\r\n PolicyRuleID = policyRuleId_s\r\n| order by Timestamp desc", + "size": 3, + "showAnalytics": true, + "title": "Log", + "timeContextFromParameter": "TimeRange", + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "rowLimit": 1000, + "filter": true + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "AllTraffic" + }, + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "// Unique Users\nNetworkAccessDemo_CL\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\n| project SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\n| summarize UniqueUsers=dcount(Country)\n| extend snapshot = \"Total Locations\"\n| project col1 = UniqueUsers, snapshot\n\n// Union with Unique Devices\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\n | summarize TotalBytesGB = sum(BytesInGB)\n | extend snapshot = \"Total Bytes (GB)\"\n | project col1 = tolong(TotalBytesGB), snapshot\n)\n\n// Union with Total Internet Access\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | summarize TotalTransactions = count()\n | extend snapshot = \"Total Transactions\"\n | project col1 = TotalTransactions, snapshot\n)\n\n// Union with Total Private Access\n// Order by Snapshot for consistent tile ordering on dashboard\n| order by snapshot", + "size": 4, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "snapshot", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "col1", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": true, + "size": "auto" + }, + "mapSettings": { + "locInfo": "LatLong", + "sizeSettings": "ExistingClients", + "sizeAggregation": "Sum", + "legendMetric": "ExistingClients", + "legendAggregation": "Sum", + "itemColorSettings": { + "type": "heatmap", + "colorAggregation": "Sum", + "nodeColorField": "ExistingClients", + "heatmapPalette": "greenRed" + } + }, + "textSettings": { + "style": "bignumber" + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 2" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\r\n| summarize TotalBytesGB = sum(BytesInGB) by bin(createdDateTime_t, 1h), trafficType_s\r\n| order by bin(createdDateTime_t, 1h) asc, trafficType_s asc\r\n| project createdDateTime_t, trafficType_s, TotalBytesGB\r\n", + "size": 2, + "title": "Usage over Time (GB)", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 0" + } + ] + }, + "name": "group - 5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\r\n| project createdDateTime_t, SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\r\n| where Country != \"\"\r\n| summarize Count = count() by City, State, Country\r\n", + "size": 0, + "title": "Locations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "map", + "mapSettings": { + "locInfo": "CountryRegion", + "locInfoColumn": "Country", + "latitude": "Latitude", + "longitude": "Longitude", + "sizeSettings": "Count", + "sizeAggregation": "Sum", + "labelSettings": "Country", + "legendMetric": "Country", + "legendAggregation": "Count", + "itemColorSettings": { + "nodeColorField": "Count", + "colorAggregation": "Sum", + "type": "heatmap", + "heatmapPalette": "turquoise" + } + } + }, + "customWidth": "50", + "name": "query - 0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"allow\" and destinationWebCategory_displayName_s != '' // Filter for allowed traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Top Allowed Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationFQDN_s != '' // Filter for allowed traffic\r\n| summarize Count = count() by destinationFQDN_s\r\n| top 100 by Count", + "size": 0, + "title": "Top Blocked Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "50", + "name": "query - 5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationWebCategory_displayName_s != '' // Filter for blocked traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 3, + "title": "Top Blocked Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where sentBytes_d > 0\r\n| where tolower(action_s) != \"block\" \r\n| summarize Count = count() , Sent = sum(sentBytes_d), Recived = sum(receivedBytes_d), Total = sum(receivedBytes_d+ sentBytes_d) by destinationFQDN_s\r\n| order by Count desc\r\n", + "size": 0, + "title": "Top Allowed Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Count", + "formatter": 4, + "formatOptions": { + "palette": "magenta" + } + }, + { + "columnMatch": "Recived", + "formatter": 4, + "formatOptions": { + "palette": "turquoise" + } + }, + { + "columnMatch": "Total", + "formatter": 4, + "formatOptions": { + "palette": "pink" + } + }, + { + "columnMatch": "Sent", + "formatter": 4, + "formatOptions": { + "palette": "blue" + } + } + ] + } + }, + "customWidth": "50", + "name": "query - 1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where transportProtocol_s != ''\r\n| summarize Count = count() by toupper(transportProtocol_s)\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Protocol Distburion", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 3" + } + ] + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "group - 4" + } + ], + "fallbackResourceIds": [], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} diff --git a/Solutions/Global Secure Access/Workbooks/GSANetworkTraffic.json b/Solutions/Global Secure Access/Workbooks/GSANetworkTraffic.json new file mode 100644 index 00000000000..75f2f99880b --- /dev/null +++ b/Solutions/Global Secure Access/Workbooks/GSANetworkTraffic.json @@ -0,0 +1,421 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "## Traffic Logs workbook\n---\n\nLog information in the dashboard is limited to 30 days." + }, + "name": "text - 2" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "" + ], + "parameters": [ + { + "id": "ff8b2a55-1849-4848-acf8-eab5452e9f10", + "version": "KqlParameterItem/1.0", + "name": "LogAnalyticWorkspace", + "label": "Log Analytic Workspace", + "type": 5, + "description": "The log analytic workspace in which to execute the queries", + "isRequired": true, + "query": "resources\r\n| where type == \"microsoft.operationalinsights/workspaces\"\r\n| project id", + "typeSettings": { + "resourceTypeFilter": { + "microsoft.operationalinsights/workspaces": true + }, + "additionalResourceOptions": [ + "value::1" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "f15f34d8-8e2d-4c39-8dee-be2f979c86a8", + "version": "KqlParameterItem/1.0", + "name": "TimeRange", + "label": "Time Range", + "type": 4, + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 300000 + }, + { + "durationMs": 900000 + }, + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 172800000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + } + ], + "allowCustom": true + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 2592000000 + } + }, + { + "id": "8bab511b-53b3-4220-9d1c-372345b06728", + "version": "KqlParameterItem/1.0", + "name": "Users", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "EnrichedMicrosoft365AuditLogsDemos_CL\r\n| summarize Count = count() by UserId_s\r\n| order by Count desc, UserId_s asc\r\n| project Value = UserId_s, Label = strcat(UserId_s, ' - ', Count, ' Logs'), Selected = false", + "typeSettings": { + "limitSelectTo": 20, + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "timeContext": { + "durationMs": 0 + }, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 15" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "2b2cd1be-9d25-412c-8444-f005c4789b55", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "Overview", + "subTarget": "Overview", + "style": "link" + }, + { + "id": "cc3e67f2-f20f-4430-8dee-d0773b90d9ce", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "All Traffic", + "subTarget": "AllTraffic", + "style": "link" + } + ] + }, + "name": "links - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| project \r\n Timestamp = createdDateTime_t,\r\n User = userPrincipalName_s,\r\n SourceIP = SourceIP,\r\n DestinationIP = destinationIp_s,\r\n DestinationPort = destinationPort_d,\r\n Action = action_s,\r\n PolicyName = policyName_s,\r\n TransportProtocol = transportProtocol_s,\r\n TrafficType = trafficType_s,\r\n DestinationURL = destinationUrl_s,\r\n ReceivedBytes = receivedBytes_d,\r\n SentBytes = sentBytes_d,\r\n DeviceOS = deviceOperatingSystem_s,\r\n PolicyRuleID = policyRuleId_s\r\n| order by Timestamp desc", + "size": 3, + "showAnalytics": true, + "title": "Log", + "timeContextFromParameter": "TimeRange", + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "rowLimit": 1000, + "filter": true + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "AllTraffic" + }, + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "// Unique Users\nNetworkAccessDemo_CL\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\n| project SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\n| summarize UniqueUsers=dcount(Country)\n| extend snapshot = \"Total Locations\"\n| project col1 = UniqueUsers, snapshot\n\n// Union with Unique Devices\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\n | summarize TotalBytesGB = sum(BytesInGB)\n | extend snapshot = \"Total Bytes (GB)\"\n | project col1 = tolong(TotalBytesGB), snapshot\n)\n\n// Union with Total Internet Access\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | summarize TotalTransactions = count()\n | extend snapshot = \"Total Trasnacations\"\n | project col1 = TotalTransactions, snapshot\n)\n\n// Union with Total Private Access\n// Order by Snapshot for consistent tile ordering on dashboard\n| order by snapshot", + "size": 4, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "snapshot", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "col1", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": true, + "size": "auto" + }, + "mapSettings": { + "locInfo": "LatLong", + "sizeSettings": "ExistingClients", + "sizeAggregation": "Sum", + "legendMetric": "ExistingClients", + "legendAggregation": "Sum", + "itemColorSettings": { + "type": "heatmap", + "colorAggregation": "Sum", + "nodeColorField": "ExistingClients", + "heatmapPalette": "greenRed" + } + }, + "textSettings": { + "style": "bignumber" + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 2" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\r\n| summarize TotalBytesGB = sum(BytesInGB) by bin(createdDateTime_t, 1h), trafficType_s\r\n| order by bin(createdDateTime_t, 1h) asc, trafficType_s asc\r\n| project createdDateTime_t, trafficType_s, TotalBytesGB\r\n", + "size": 2, + "title": "Usage over Time (GB)", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 0" + } + ] + }, + "name": "group - 5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\r\n| project createdDateTime_t, SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\r\n| where Country != \"\"\r\n| summarize Count = count() by City, State, Country\r\n\r\n", + "size": 0, + "title": "Locations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "map", + "mapSettings": { + "locInfo": "CountryRegion", + "locInfoColumn": "Country", + "latitude": "Latitude", + "longitude": "Longitude", + "sizeSettings": "Count", + "sizeAggregation": "Sum", + "labelSettings": "Country", + "legendMetric": "Country", + "legendAggregation": "Count", + "itemColorSettings": { + "nodeColorField": "Count", + "colorAggregation": "Sum", + "type": "heatmap", + "heatmapPalette": "turquoise" + } + } + }, + "customWidth": "50", + "name": "query - 0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"allow\" and destinationWebCategory_displayName_s != '' // Filter for allowed traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Top Allowed Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationFQDN_s != '' // Filter for allowed traffic\r\n| summarize Count = count() by destinationFQDN_s\r\n| top 100 by Count", + "size": 0, + "title": "Top Blocked Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "50", + "name": "query - 5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationWebCategory_displayName_s != '' // Filter for blocked traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 3, + "title": "Top Blocked Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where sentBytes_d > 0\r\n| where tolower(action_s) != \"block\" \r\n| summarize Count = count() , Sent = sum(sentBytes_d), Recived = sum(receivedBytes_d), Total = sum(receivedBytes_d+ sentBytes_d) by destinationFQDN_s\r\n| order by Count desc\r\n", + "size": 0, + "title": "Top Allowed Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Count", + "formatter": 4, + "formatOptions": { + "palette": "magenta" + } + }, + { + "columnMatch": "Recived", + "formatter": 4, + "formatOptions": { + "palette": "turquoise" + } + }, + { + "columnMatch": "Total", + "formatter": 4, + "formatOptions": { + "palette": "pink" + } + }, + { + "columnMatch": "Sent", + "formatter": 4, + "formatOptions": { + "palette": "blue" + } + } + ] + } + }, + "customWidth": "50", + "name": "query - 1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where transportProtocol_s != ''\r\n| summarize Count = count() by toupper(transportProtocol_s)\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Protocol Distburion", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 3" + } + ] + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "group - 4" + } + ], + "fallbackResourceIds": [ + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/Workbooks/GSAM365EnrichedEvents.json b/Workbooks/GSAM365EnrichedEvents.json new file mode 100644 index 00000000000..e983bfd5a4c --- /dev/null +++ b/Workbooks/GSAM365EnrichedEvents.json @@ -0,0 +1,418 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "## Traffic Logs workbook\n---\n\nLog information in the dashboard is limited to 30 days." + }, + "name": "text - 2" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [], + "parameters": [ + { + "id": "ff8b2a55-1849-4848-acf8-eab5452e9f10", + "version": "KqlParameterItem/1.0", + "name": "LogAnalyticWorkspace", + "label": "Log Analytic Workspace", + "type": 5, + "description": "The log analytic workspace in which to execute the queries", + "isRequired": true, + "query": "resources\r\n| where type == \"microsoft.operationalinsights/workspaces\"\r\n| project id", + "typeSettings": { + "resourceTypeFilter": { + "microsoft.operationalinsights/workspaces": true + }, + "additionalResourceOptions": [ + "value::1" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "f15f34d8-8e2d-4c39-8dee-be2f979c86a8", + "version": "KqlParameterItem/1.0", + "name": "TimeRange", + "label": "Time Range", + "type": 4, + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 300000 + }, + { + "durationMs": 900000 + }, + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 172800000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + } + ], + "allowCustom": true + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 2592000000 + } + }, + { + "id": "8bab511b-53b3-4220-9d1c-372345b06728", + "version": "KqlParameterItem/1.0", + "name": "Users", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "EnrichedMicrosoft365AuditLogsDemos_CL\r\n| summarize Count = count() by UserId_s\r\n| order by Count desc, UserId_s asc\r\n| project Value = UserId_s, Label = strcat(UserId_s, ' - ', Count, ' Logs'), Selected = false", + "typeSettings": { + "limitSelectTo": 20, + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "timeContext": { + "durationMs": 0 + }, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 15" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "2b2cd1be-9d25-412c-8444-f005c4789b55", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "Overview", + "subTarget": "Overview", + "style": "link" + }, + { + "id": "cc3e67f2-f20f-4430-8dee-d0773b90d9ce", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "All Traffic", + "subTarget": "AllTraffic", + "style": "link" + } + ] + }, + "name": "links - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| project \r\n Timestamp = createdDateTime_t,\r\n User = userPrincipalName_s,\r\n SourceIP = SourceIP,\r\n DestinationIP = destinationIp_s,\r\n DestinationPort = destinationPort_d,\r\n Action = action_s,\r\n PolicyName = policyName_s,\r\n TransportProtocol = transportProtocol_s,\r\n TrafficType = trafficType_s,\r\n DestinationURL = destinationUrl_s,\r\n ReceivedBytes = receivedBytes_d,\r\n SentBytes = sentBytes_d,\r\n DeviceOS = deviceOperatingSystem_s,\r\n PolicyRuleID = policyRuleId_s\r\n| order by Timestamp desc", + "size": 3, + "showAnalytics": true, + "title": "Log", + "timeContextFromParameter": "TimeRange", + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "rowLimit": 1000, + "filter": true + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "AllTraffic" + }, + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "// Unique Users\nNetworkAccessDemo_CL\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\n| project SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\n| summarize UniqueUsers=dcount(Country)\n| extend snapshot = \"Total Locations\"\n| project col1 = UniqueUsers, snapshot\n\n// Union with Unique Devices\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\n | summarize TotalBytesGB = sum(BytesInGB)\n | extend snapshot = \"Total Bytes (GB)\"\n | project col1 = tolong(TotalBytesGB), snapshot\n)\n\n// Union with Total Internet Access\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | summarize TotalTransactions = count()\n | extend snapshot = \"Total Transactions\"\n | project col1 = TotalTransactions, snapshot\n)\n\n// Union with Total Private Access\n// Order by Snapshot for consistent tile ordering on dashboard\n| order by snapshot", + "size": 4, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "snapshot", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "col1", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": true, + "size": "auto" + }, + "mapSettings": { + "locInfo": "LatLong", + "sizeSettings": "ExistingClients", + "sizeAggregation": "Sum", + "legendMetric": "ExistingClients", + "legendAggregation": "Sum", + "itemColorSettings": { + "type": "heatmap", + "colorAggregation": "Sum", + "nodeColorField": "ExistingClients", + "heatmapPalette": "greenRed" + } + }, + "textSettings": { + "style": "bignumber" + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 2" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\r\n| summarize TotalBytesGB = sum(BytesInGB) by bin(createdDateTime_t, 1h), trafficType_s\r\n| order by bin(createdDateTime_t, 1h) asc, trafficType_s asc\r\n| project createdDateTime_t, trafficType_s, TotalBytesGB\r\n", + "size": 2, + "title": "Usage over Time (GB)", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 0" + } + ] + }, + "name": "group - 5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\r\n| project createdDateTime_t, SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\r\n| where Country != \"\"\r\n| summarize Count = count() by City, State, Country\r\n", + "size": 0, + "title": "Locations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "map", + "mapSettings": { + "locInfo": "CountryRegion", + "locInfoColumn": "Country", + "latitude": "Latitude", + "longitude": "Longitude", + "sizeSettings": "Count", + "sizeAggregation": "Sum", + "labelSettings": "Country", + "legendMetric": "Country", + "legendAggregation": "Count", + "itemColorSettings": { + "nodeColorField": "Count", + "colorAggregation": "Sum", + "type": "heatmap", + "heatmapPalette": "turquoise" + } + } + }, + "customWidth": "50", + "name": "query - 0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"allow\" and destinationWebCategory_displayName_s != '' // Filter for allowed traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Top Allowed Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationFQDN_s != '' // Filter for allowed traffic\r\n| summarize Count = count() by destinationFQDN_s\r\n| top 100 by Count", + "size": 0, + "title": "Top Blocked Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "50", + "name": "query - 5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationWebCategory_displayName_s != '' // Filter for blocked traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 3, + "title": "Top Blocked Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where sentBytes_d > 0\r\n| where tolower(action_s) != \"block\" \r\n| summarize Count = count() , Sent = sum(sentBytes_d), Recived = sum(receivedBytes_d), Total = sum(receivedBytes_d+ sentBytes_d) by destinationFQDN_s\r\n| order by Count desc\r\n", + "size": 0, + "title": "Top Allowed Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Count", + "formatter": 4, + "formatOptions": { + "palette": "magenta" + } + }, + { + "columnMatch": "Recived", + "formatter": 4, + "formatOptions": { + "palette": "turquoise" + } + }, + { + "columnMatch": "Total", + "formatter": 4, + "formatOptions": { + "palette": "pink" + } + }, + { + "columnMatch": "Sent", + "formatter": 4, + "formatOptions": { + "palette": "blue" + } + } + ] + } + }, + "customWidth": "50", + "name": "query - 1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where transportProtocol_s != ''\r\n| summarize Count = count() by toupper(transportProtocol_s)\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Protocol Distburion", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 3" + } + ] + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "group - 4" + } + ], + "fallbackResourceIds": [], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} diff --git a/Workbooks/GSANetworkTraffic.json b/Workbooks/GSANetworkTraffic.json new file mode 100644 index 00000000000..75f2f99880b --- /dev/null +++ b/Workbooks/GSANetworkTraffic.json @@ -0,0 +1,421 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "## Traffic Logs workbook\n---\n\nLog information in the dashboard is limited to 30 days." + }, + "name": "text - 2" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "" + ], + "parameters": [ + { + "id": "ff8b2a55-1849-4848-acf8-eab5452e9f10", + "version": "KqlParameterItem/1.0", + "name": "LogAnalyticWorkspace", + "label": "Log Analytic Workspace", + "type": 5, + "description": "The log analytic workspace in which to execute the queries", + "isRequired": true, + "query": "resources\r\n| where type == \"microsoft.operationalinsights/workspaces\"\r\n| project id", + "typeSettings": { + "resourceTypeFilter": { + "microsoft.operationalinsights/workspaces": true + }, + "additionalResourceOptions": [ + "value::1" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "f15f34d8-8e2d-4c39-8dee-be2f979c86a8", + "version": "KqlParameterItem/1.0", + "name": "TimeRange", + "label": "Time Range", + "type": 4, + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 300000 + }, + { + "durationMs": 900000 + }, + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 172800000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + } + ], + "allowCustom": true + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 2592000000 + } + }, + { + "id": "8bab511b-53b3-4220-9d1c-372345b06728", + "version": "KqlParameterItem/1.0", + "name": "Users", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "EnrichedMicrosoft365AuditLogsDemos_CL\r\n| summarize Count = count() by UserId_s\r\n| order by Count desc, UserId_s asc\r\n| project Value = UserId_s, Label = strcat(UserId_s, ' - ', Count, ' Logs'), Selected = false", + "typeSettings": { + "limitSelectTo": 20, + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "timeContext": { + "durationMs": 0 + }, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 15" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "2b2cd1be-9d25-412c-8444-f005c4789b55", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "Overview", + "subTarget": "Overview", + "style": "link" + }, + { + "id": "cc3e67f2-f20f-4430-8dee-d0773b90d9ce", + "cellValue": "tabSel", + "linkTarget": "parameter", + "linkLabel": "All Traffic", + "subTarget": "AllTraffic", + "style": "link" + } + ] + }, + "name": "links - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| project \r\n Timestamp = createdDateTime_t,\r\n User = userPrincipalName_s,\r\n SourceIP = SourceIP,\r\n DestinationIP = destinationIp_s,\r\n DestinationPort = destinationPort_d,\r\n Action = action_s,\r\n PolicyName = policyName_s,\r\n TransportProtocol = transportProtocol_s,\r\n TrafficType = trafficType_s,\r\n DestinationURL = destinationUrl_s,\r\n ReceivedBytes = receivedBytes_d,\r\n SentBytes = sentBytes_d,\r\n DeviceOS = deviceOperatingSystem_s,\r\n PolicyRuleID = policyRuleId_s\r\n| order by Timestamp desc", + "size": 3, + "showAnalytics": true, + "title": "Log", + "timeContextFromParameter": "TimeRange", + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "rowLimit": 1000, + "filter": true + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "AllTraffic" + }, + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "// Unique Users\nNetworkAccessDemo_CL\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\n| project SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\n| summarize UniqueUsers=dcount(Country)\n| extend snapshot = \"Total Locations\"\n| project col1 = UniqueUsers, snapshot\n\n// Union with Unique Devices\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\n | summarize TotalBytesGB = sum(BytesInGB)\n | extend snapshot = \"Total Bytes (GB)\"\n | project col1 = tolong(TotalBytesGB), snapshot\n)\n\n// Union with Total Internet Access\n| union (\n NetworkAccessDemo_CL\n | where userPrincipalName_s in ({Users}) or '*' in ({Users})\n | summarize TotalTransactions = count()\n | extend snapshot = \"Total Trasnacations\"\n | project col1 = TotalTransactions, snapshot\n)\n\n// Union with Total Private Access\n// Order by Snapshot for consistent tile ordering on dashboard\n| order by snapshot", + "size": 4, + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "snapshot", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "col1", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": true, + "size": "auto" + }, + "mapSettings": { + "locInfo": "LatLong", + "sizeSettings": "ExistingClients", + "sizeAggregation": "Sum", + "legendMetric": "ExistingClients", + "legendAggregation": "Sum", + "itemColorSettings": { + "type": "heatmap", + "colorAggregation": "Sum", + "nodeColorField": "ExistingClients", + "heatmapPalette": "greenRed" + } + }, + "textSettings": { + "style": "bignumber" + } + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 2" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend BytesInGB = todouble(sentBytes_d + receivedBytes_d) / (1024 * 1024 * 1024) // Convert bytes to gigabytes\r\n| summarize TotalBytesGB = sum(BytesInGB) by bin(createdDateTime_t, 1h), trafficType_s\r\n| order by bin(createdDateTime_t, 1h) asc, trafficType_s asc\r\n| project createdDateTime_t, trafficType_s, TotalBytesGB\r\n", + "size": 2, + "title": "Usage over Time (GB)", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "query - 0" + } + ] + }, + "name": "group - 5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| extend GeoInfo = geo_info_from_ip_address(SourceIP) // Extend each row with geolocation info\r\n| project createdDateTime_t, SourceIP, Country = tostring(GeoInfo.country), State = tostring(GeoInfo.state), City = tostring(GeoInfo.city), Latitude = tostring(GeoInfo.latitude), Longitude = tostring(GeoInfo.longitude)\r\n| where Country != \"\"\r\n| summarize Count = count() by City, State, Country\r\n\r\n", + "size": 0, + "title": "Locations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "map", + "mapSettings": { + "locInfo": "CountryRegion", + "locInfoColumn": "Country", + "latitude": "Latitude", + "longitude": "Longitude", + "sizeSettings": "Count", + "sizeAggregation": "Sum", + "labelSettings": "Country", + "legendMetric": "Country", + "legendAggregation": "Count", + "itemColorSettings": { + "nodeColorField": "Count", + "colorAggregation": "Sum", + "type": "heatmap", + "heatmapPalette": "turquoise" + } + } + }, + "customWidth": "50", + "name": "query - 0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"allow\" and destinationWebCategory_displayName_s != '' // Filter for allowed traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Top Allowed Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationFQDN_s != '' // Filter for allowed traffic\r\n| summarize Count = count() by destinationFQDN_s\r\n| top 100 by Count", + "size": 0, + "title": "Top Blocked Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "50", + "name": "query - 5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where tolower(action_s) == \"block\" and destinationWebCategory_displayName_s != '' // Filter for blocked traffic\r\n| extend firstCategory = tostring(split(destinationWebCategory_displayName_s, ',')[0]) // Split and get the first category\r\n| summarize Count = count() by firstCategory\r\n| top 10 by Count\r\n", + "size": 3, + "title": "Top Blocked Web Categories", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where sentBytes_d > 0\r\n| where tolower(action_s) != \"block\" \r\n| summarize Count = count() , Sent = sum(sentBytes_d), Recived = sum(receivedBytes_d), Total = sum(receivedBytes_d+ sentBytes_d) by destinationFQDN_s\r\n| order by Count desc\r\n", + "size": 0, + "title": "Top Allowed Destinations", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Count", + "formatter": 4, + "formatOptions": { + "palette": "magenta" + } + }, + { + "columnMatch": "Recived", + "formatter": 4, + "formatOptions": { + "palette": "turquoise" + } + }, + { + "columnMatch": "Total", + "formatter": 4, + "formatOptions": { + "palette": "pink" + } + }, + { + "columnMatch": "Sent", + "formatter": 4, + "formatOptions": { + "palette": "blue" + } + } + ] + } + }, + "customWidth": "50", + "name": "query - 1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "NetworkAccessDemo_CL\r\n| where userPrincipalName_s in ({Users}) or '*' in ({Users})\r\n| where transportProtocol_s != ''\r\n| summarize Count = count() by toupper(transportProtocol_s)\r\n| top 10 by Count\r\n", + "size": 2, + "title": "Protocol Distburion", + "timeContextFromParameter": "TimeRange", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart" + }, + "customWidth": "50", + "name": "query - 3" + } + ] + }, + "conditionalVisibility": { + "parameterName": "tabSel", + "comparison": "isEqualTo", + "value": "Overview" + }, + "name": "group - 4" + } + ], + "fallbackResourceIds": [ + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/Workbooks/Images/Logos/gsa.svg b/Workbooks/Images/Logos/gsa.svg new file mode 100644 index 00000000000..407569607d0 --- /dev/null +++ b/Workbooks/Images/Logos/gsa.svg @@ -0,0 +1,5 @@ + diff --git a/Workbooks/Images/Preview/GSAEnrichedLogsBlack.png b/Workbooks/Images/Preview/GSAEnrichedLogsBlack.png new file mode 100644 index 0000000000000000000000000000000000000000..e255e73c2ba95a19e201decc916ac03cdf623155 GIT binary patch literal 192716 zcmdqJcTkhv*Dh>96ctfXkd9R8N|g>GB~=d;WFI=dIxpDmJ%DGM9 zs%GMG;Q|fkKR*`%dK_C9E}Z27o+}#o0M~I8=~@eC-?kB6Hgs_r4 yit_(HEf72k1ag#UZGl^fm-4^bm(QJ4c*$yv!x^K4p!1*5id=OPI !e5Ef@>7gt~3n`P&*wi&G61 z(uvirkHwPZxh=kZmyfE$p0pP&RQhjUN|AdNzuU+@C@FH*au~og``f?$-Jm3O< xrLH^fxZWSrXLG`y*kd8t!UQs7(3g-mlr4D^UdWqMA#$X6P=dH6P^6zilEQp z0l5y;5;=Ocs7MmD=dvsT*2v62lf3v9YE4Ba<5$!Rd@SwsP5mPw;fUbCL&?{nkuKrQ zE(lb|xbVmV(*)Yv 8 zo3(oz#lr2TJj z0x7Yi4`{)4X|BFtt z$&f}TjWIcF*$@z4)*O2E5|L{- Rol)FZh#Tr;Myx zLXd=|(OJrRzvmC*B%=Xssc2(MA1~PCrn5k}n1+U};GLADS#vX)u4Ov8j6@N;!$`YH zwGev4yf;yuLo=nj7!I4y v z?5dhNQ}{}_-Gc0Cq2!W6Dl*7{0UW4!xncg|665b-N^h7CVEy#tZpm!m@gyKlK;9>M zP-NFHLWHSnGf~iD{_{@r+y`19$Mm1rpEo_9Kck62aUHqJ+?oXsiCkqE;5hZ7cV{9r zNo{CMZS$_;zB-IUhl);dZ46x&K=6^G7+Olq55|k%LL}-y yySauWiA$ULmJ9um zI*EXF))j*(i(c+z@+qmRE|Sg^`|}g+A(vf)lx8d6)ym>T^t%*&&~N?H%NHM&Ss`6Y z2- |deHvlp2@02YbFE|Mv@H+IXZ4M&aEYOKZl4;+k!pw zrIGHbGW$8wnGXv-J4wHECsO!Xs4b#?m5@eUQ=~BZ&izvQS3O}!3zeQr(i>~11fnF* z^NDKh09kXt+UstohF}3%JfqNX#=?p3<2_vF(1->9T{8)&IDj&qi0ONA*K{v_2JgZ7 zF@U@yIq>X&MVQhwnm`0AKY~EQ9V?uZWyC=>M~b ^ zq2FuX&E?iF2YWLLpz fI~Z#qYa^x=TSnQTenuK#(4FDDfn_IufR>VOya&GqVbSW`qr#F`ywdlTIT z@|%TnKP@zo3fP|?20cjdmW5hCc?TPc>x*i%ECM~>XBN9Fn470Jo%Bl+$IO&CIXRV2 zkEYI0`x}!BHJFcTr^i>Yd4Evi9{MOm;5qE7_KlWzUkJW+1ul<}n_K`<92*B3+j9pf zc1QP}CzGTZ*Pb(9_~ U}RIPSS|&kM~*izdir>A>1Z zHJWG6es)lbrJ6*!Ia~Bs=^ %l?2rU*Dlu-+1i+D2R#e*F6iBK zdF@%WVN$*YdCy4CNmY%mh?3#mybheU6qh#)=_eCfhpN6ql^;;k#pK1=COek9K%G0P zpJRip%XSae7ktQ&GnW^;vCyoiK?h2Tx%VJ8PuRFKzbwjoY;DM(C}}r7tx9`OJYc>( z$PR*JcZ=!C5--&sO;yKSoEu`&Y0VCq$I~pSy{l@Hrz)}>GsORvN?Wz^528DLW(;1H zHO2 h2JzS OmzyjW z;1s{x)cxG?DU1_5_LA=BoTBeHI`SrYEh85%(k9%sUsC&!OJiz3No};qFmLrtwn#s3 zZCP=sFnW?0598QTp?W;&_nCA%rSkj6fP4`6e Q|#XOzcn*7W4GD zMG(_`1%|soOR4HqxCyGyvr!wtiAd&G@@rgSlC^|kmFM2nCY-ul1=2nC-O33T^}plj zo{%eaX-($moUZQ%LtNazRXH7smQHq)#b!{_3LiVJFwQGMcb{TuQ>7=3sxEQ$gFc6E zpD5kf9Qn$uP|hmoosJZ(y1y|w1Q1W=q6G2>7f$BKM5bY @$TDxvJ$?Lv2iCL1DYZ5?V`vhkHGny<0K@% H=Pkk9j*@EXW!?^TCUjokJfYMYw0D{iBvsEt=y%T(oF z9>4sL$|82Xh7o=dwR*C?;gP<&Np!5%H2Gx=Q}c_SnDFvw_LJ0)@0oURqPws=t@WES z?mr~J0s+ShgoaKV-v&Dy++BcrA6wSFapVic!$M4Y%bf956t;oQ(8aCMY>_<|!2|Cp z3})!r$=ES1kZj*!$A(Aqf2CdVg-&eWnt|fN^CFv`Sx&Nl9a8F~^j^({u2gn8BPghY z05BT~`^QngpMys^v|%kbMnZuIog2Vb&N8Gq#4b6>t^+Y+4A`7aC zY*@P6kiB%fsx*9)D%M#55%*Bshoh{_oD>h0u}e&x4So{0Cz3b0Hhc-u`BFluv&qLe zRTK-gTeHdm5=&a#wa|?=-;SL9ptW%t1c1{`fdDY~%F3};s+eT#$L3njUH~5dO^Uip zCy{RLd7?k{@2275M?O|n7M)r;w)PjEC#VeV9;Ss@V9hM3QT5i^rsxFkTlO`Yo(w9X zniZ5S!Q?+Ob$qkRGWp=Djg ;@srdF2@rIT0iW3TmM?@jHv`$M{p#XcrW&F~wxe=Eq;FqS&wxT; z{BQb|{n=|NwJ!=ddLrwX;{`1z=^qGDM6q3M{)JqL;yzzwJ<~m0x}z}N)`&G>rTL1n zvjlLP_pY#BVTE*R@SJ)O@g|+CK7#}$d#>@MDhQQDXgVHUC}F_51vOB$a*^U2J(#2X ziyB0oOEIw{4*liK7W2|+o7)sa-DC* ouEQIoi?FdwyvUqbU7x=L93(zL~E4rI| zq(=6gck?7bN#ZvjsPAP1TGkt?<@31|$bM<(1lCfoA=n`Hf<>k2m$H<9d}@r_!rI}x zUcJ)OdBuiKbBId!TQlkI WoYwq?hPc+5qUp9h2i9>3+{(8!FW2Uinp# zbHuYN{4cgI7-_cA5LZ=&+nsiJELv--Z$zrUCglfX^t<1rJbB!Q=J^7#`_f1m7jO9y z5L)-eWfuV4&AYiJL1t+v@%ws6sYqy#^-3m62X-;XF3gE`tn*RTu|zRvkN8JJ2Z7 UyIPhhwhVY8w;E0wyUqB-1PH}azWs-5`#)jd z5`~_ATe}SO;r_mMx%y(Wp@;7`rw2?wOB-aK;+ZYdN1WWNq{}){Z!?`QXWcrFn=a>O z75chmK9SnSh##W~`K0%#_PO|R;lwe$F7hCbfdq=?lNr8#KloC<+(8DN+0s>p$4a+$ zLhewU@1S_VwfaF=H;3L{Luce{?xAExZ!-N(+qF0@r##gu37e7kg~DEo=j_&}LDL1E zy4j)e(T`$a8xTZ@N=R{dmo0hMvY)B%+jefynvgZ
UoJY!8>Cf6qhhlDkleFE-ZWQC(!egiouJbkT z>p*`%2Q*-HNzm0%R1fhj30dv@siaPktKTi_HCi0L6c7uK?veFh3BvE7Qe9W%gT) ew`AB%s!Dd{(>9Pc?=qLB^L@pLOXtOG)7J zzX1CD`bKSR1#w@q?jYauOLeo3>I7 dC$S%!XV5Z>|$1lch dkdU2+ -90AQ!o1GBN;c&Rk zb_~Hsw3=VoW7ECt _Db8oy)tA z;`*vZ7&t|H8JXv4wh>mp$C!LlTv8|U4@@^Xw-Ri3A+$GAJt;= ztM5TnLHZNSw_seiVx3DFG)m9bSYw*ym1>c3 G|ky0uRGiX(8irJr(sOmot`PWn?!FFm(D-PsQ#=}xKPKMMLS?Zy4VI83Gut6 zIy=ib$fT9?dV8dLiFNZy>1llt_yLuKs69dz&bo28xDf>Bn3Bb+F#EW@*F5HW@r>f& zU0$Nbg4LmpXM+S(iO|sd(bO@4j-^rdw*i 5=kHBY zt7x7Q_Si&f)rdfd=yx$miBBg@@{;KR`{TksTUHH6gvNz~mH~9*W;1t^xqJA!yu#-{ zY`^>DHC1ga$BLM5;O9Z%APazu&` ;E-YHU>!MGZ&qqpIpioWtU0(q9S5bWq~ z+{d=LN#wac<=T~J;sCy1q+9hVF+0FT{ZmP%?02RCsT9GvZ4Hhdag>pIJe07NWUlYK z^XaE#G7e^&$E?4110VK eblO`Nfc5SIvM)GT_-9JK)qG5%WRJ4>HVJM%? z{Z;jXxM7gN6tu6_)Qj-YMLUy&lsWg2$ua98JBw@kRpd>`zKHrE4ySh)$NCQ0M@ZnN z&uh__2ZLElayOyFdJIQGYdmvYO%G+ICU>KgR@yp8@0rMMbGl_&$C$crJvsJ~EcRl7 z)5@ycO3EaRxUSX)sc;D-^X8D}E?O3ZPQ?PMreeKEvDVs|53MbCYQIG%0J8+#vW{bt zeyG}_pTaFk>a7*S3sJ>bTXZ}p5$vL4Qde(GuH%MU#mTuN#*MjGo_v$s=aJ>C$ZhOJ z_6T!`G-v+6#I{`~|M1{Y4HJ=mkRo7B#|oz%cLt A&ozN%EG>q S;P8*+)%%X(VAl` zMaZ+O-)*dR@Kzlnl&z*^8Hcx$+FCB8m&EO@P`QLfW`H1z@lcYRGZO@T5-JfL6x1Sh zw73iq4j`DOj5HU<*B0Q1?hvhxUKJ|dpDIb3*6=S9O;Bu}l)_{pheiOyxwNJl&wgbJ zc;~e&K04(G;~L=}{IWJ9lYSq%`~9Qf!nDu<)qyQX%um^m^I;q-3k_Ud5-U9LmSG3q zX?puI3hG_tqF`*=4}Uxhw~LUFp %X-&fX+s-q zy_ @CHj6cU14>3u2A$#)c!LzWp$24QXI`0JNnqDT8EC|N zQ?)+KX))t-z?3BbTu8ArhL?`CO+<{yWgJwL -}CAhL?HV{7wqPNLD8v1+#x*lCB zlIyZ`6_k4Pgez}=LKK$IPzFc$k6aNp>tt(ZW`NN@j-LXwT5QhL4wajK>U|)u
5 zuj9@+rWks*^A%#Y{o|f(vGit>KGLgEBk*L;7@}U3r;*fP{V!lHG?;On^8v0F2_;7l z9E>HDtSbhMd^NQ2jv*JbOjqgG=)`qXZ9J1>rzMl^iR>oQ`MqZ&zZbNv;2RT9j~S>Z z{vlDJ*dZ4qL3m!{p4n?rF*;oQey+TVus XSNq!5H5d$wz>X zIR6lttyLQnVnIRAfor9s#ZyH;+|QR%O$*X6%f+6iy&k{%LYV_Et+`!ACKFx}P)Ry+ zY^L)n=obXMBXKamDO^En&1=64dB^U%_6EWq>OVJcR;(~ldwBf`$fc6wMA+nG6Kq09 zedwFGJH~8yC|xA=Z1E|~KY^8=E38|xwORLSkD1M+Hbf=@vLT&tXDa%3yGfDqc)kD CBj z5@*3+y{hwP(Z6uP6~_MS(iUL(sku}J?NXpR>>$ggN5lOOJ}z9~rU0_P3(6O42l-*h z0I3p6wt*r#r;n+ra|dfm7myJ}8vcPIih7Gwaf?pm*Jl2%fks%}I2Q4u dx`s9CRs6gi*pzWGY|=JuX_sv@VQRyZnefzz z%y KG}Vo8>%9DG>tU%s23 zztdtD(OIWH<(vmvq}EZ_k=Fbr$cbv)(RrI+hvOMFqNL2X%NLDJB{X3lD)yIESe*VE ze4Z-q&HdLSd<$1kwu;~yDy``r;l?L`3HPk`8=vgGh^x7qs~OHzX$yR#Lo>`ZUx{bG zORrYLgr4tHcF1*a<{~`*Yc8(BJ+zi3FI^xqhI5NU`P0I_cBg)jXMTnZK*79Pe?AZK zW$u9HF7~0BRdk+-h}~DDPKz6clD|%;zqv83deE2h2KtbWZ$Zc|v&B6}wV?R&nrJbb zYU_z%AXS-lof9W|W+;5CrJ%4a_b|!F4 z6lby~S~yt {;g~M@dT|ytx~`XOJ+TQfz&h#%LY5j7Lma%((-~ zKaeF(c|>Eg+pgfhU82;s=N2Y3NPtS5b&}jdxKr`_VI!7Vsp3_ApO)0BDkt?q1Z1)_ zM%Cjxqjt!L975<;1>l)NQP*;-c5B>2()z1YyQ4Bbp+3dYKd1nHGCWBd;kSy(4)=ua zGLHXV3|dIg+4a#6;hwm6%2n@F)mPr7*W);~XwABzjjxk87H{2jPWn&ipWl3?MK>m_ z x*R!r5}7!273<8-4> V%umc!Nu#6Io{$D(+;0IK2*;2acgZo zAE0o+t_+$yc~!z6o9gcUPI{&e5WMkgCJ#`_mK`6DtuPcvM%avHjw=m2A2C_JeV+qv zegl3dtQq@0EtI~z!Y&Pwc8gMvr^2H4{in+mUi>f)YoL2)R~Yv5WUIjK?k5{e7PcuP zBVh2QCx0PH!TTDMW1J|Uv+tZ@C_hZ6tW-+vrYv HE9|Lj&(tvXGXO`r_+`-JE z`F@u<(qFB*jLu)Oo8nuPlpL%t6$+@b`5@BTz#w|(9^oZ_f#adv6Tqn&^-U2Cy#H(a ziD~M;CKxL~G$?s-nk=2E-8UxN>mc&ZyB9{%5<0KNx R*a(@RCFlRi1*Rz~w~ zq_l0EwDEI0 @lFugk{=v9_)1BnzSPKzgYYSZT0~23(G^_os33f8{|!ehB!MFaLcd zM%CoKzfzV$ZTN%#mY3gFKWkO_JLz9|c;~9n$X zAzA^%MYN0D8u|L?Xe7Jp<)HcQICkPrmk8*n?Mq$>=w>v ztg&Bq3KS1It!5mrYtJ|$=^Z3e*;dSIPPf3CL`?;p{s>J>s!hUwytqR|%xg$JyYs&lR32+gQir-$2PGy9nvM zA6rQtDnlb7jCv(T9^vvwmi=Czvk#hrPGrW#f=bp+wxbS?b>dpP!Fo-vq eMa zS5zPMnJK7?B74Z5uBXat*Pi`GdJum7%u6@UJ Syc2gQB&+`IjnbIGvBH;$eZ1S0W$>XSc{a0_b%CSP-yNEK z{)Y#8`zX1}h2k@H;+JsSi5`BP)2BScvlP_1HP(xdCCl9^7_klbUcQ$^PilYN)gdTo z3TbHr_i&PgRZjN)@!B_evqd1gUU@8|B$xXyx}js))cu`orBG03vSj7X3ol8(-LG^+ z8liP(GH%m5l-2g6kBlCug ND^&mxEgG!ZiNpZv@v(h}Znuy$4EhSDJyg#8g zJr68f^U7?z&N;D=U26U8#7=S#yAP8n``TzgfXTNsIUWVZatIw86nWC|9YiE}EzLLO z@bnN~65w?&n&KN~0RZ|zMQ@=q)UIt#J0TCg5JQ^ONJ-R5Q}_%|Sn=X;xmbuDm!yqh zj+>flQupp>;JbQi&Z|nrkv8+K^Fw98;^Tvj(R|wsl!ctPkz_~YA3sfJ3Fx=c97dkR z-44R^rwarLnmNm{NcpP;GE1B7Gs?368db)#9poy2=!@JhQ&xX<9Zsv92_m68D@bY` z-Y%)!jW>)Xb@pA%X9Yj3zsT=^yKf 13^tRH5D?}|xLzJQ znVQD6g6JE-q)afVUR ^S64@h_w*J~`2SQvFC4?qBkI{@zUrmxn_EY{mNp#|yp>kkcgE{|DthUqbzm_D zaBJ0=6vgXH3C9#4=92~ezj!h6X-N1B2_adUfyaS4{3rEkM?8F#v0#QobaEM?i~4If z9c`*YL=?*uH`F*t2#V>CrL-m_s&7oiUqACxuGRGIw-8>#9&8h>THY`t&H~@kofYuB z`10vqVPN?2!8kSHUik0TFl$vRbUsCl+VQv(N13A* x>CRd1am@g_)9uV{|E%2C zNi8q!qg1;YSJ zO)OP?y!f!2WwR#fG6QW2c(R4*QIAGT zEN@*Ddi!m}Yp=5S;mvdou`F{g!_C8IpGJ}2GvLyU_=dLK`P eT1H! z(cn|d(}0r6J-_BJNta;n313f^G>>M+u4(uD8jP1+tYIq *;{zB&o~XM7}7ZYMr&mGB-CR5l)=%6LQOQNLIWYhN|-e zp880L{d{(xHz;xaXoH)(6{2w Idj!@gv$Xicno=0q6MX%B_pvPRUrefUfH=i_g zw0N~9 *PMn4w@tFEqT)WSot$43tQ)a-p{{4uLXCN|@|N9`b;A!e<>W{2Z zRK{H<>h9ZX&Ai-*sQ#9+vKDm}<6ZMKom{Kw_e?{WLRx7chwvO-p+QArHACY5-ySzF z@6e5Fmtwp@X3B4Aq8QE8$F3T~EJnE>-0B=dQ!t-!e1A?ewnNwMgEi8foH?^meRcpT zqt$M(C%nzJy|>`56N1j50CD 2#EOs1#~8~L3I ztUMlRd}lC3F2(ewu1^-^w*K`Vzc2EhTr=Q@Vv-w;_}RjHeQkNm{nLH;5sx3#SR4M` z&U`r#1uPIJJnD&%gU9#rVR>ele%1e!yvp5Exa8$tFdsQfIiVJ%x^xcStb|I;u`#M9 zQ1{e_#040K9U3%}n;H;g)YUEgT765q^S5z0$#KN)0uGc@)rvzGpyJ|jmFFid&a=*m z9&%iXaJRv11{Ib2qN55lmCAzU;bz&;?Ua7*Ktdt%UVNy+>gfJd_$XX#laSjSv>?@! z2C9+vdj`G@+B~f6hPtdYzgXSFKN|Mm)=PuqJ-g1!gnxKmrGEZ90a5d3p_Ds82?>0B zpBT}0`D `a%HQ*Fyug-;Wj7_d8C{5Nv`gY*Q7=Yh#K+c z21qm 8oI5-P |2W9-dbMMz9meO8&xmEl>F)x0%rI)fv-hz& Ef57T%WIv_1O$p14*M!chew;PKp%!E_+a zgQ0w$-DXiADz&b0)y7Jq{-%P Hf=u*C3PDT|DB;OMQmJ1CM zyY(lT8KDfyJ6_p64yMsSqXw;gwWw%RGtP*{f*c2YG{V6&dQW5Kg; zc#aK&Gv7t&@bh^*+ilsJCF!6)n5h(`FlYJHROvv>ti{nEnw_lS;>7Bt%KT#Dx8uPf zxtc-yX%f+3c2U82T`IZ2Z5VPHL20sqK7KS{)MUWyUB}Z_eMFy9`Sv_`gfHHgyl4Lk z)xKj>sej9uyR&ge25GrEKNtgBkFQ%a$zZ4=6wc>TIRi-Ze)SK*Bc%k>@y%ovW>Dv# z5{%m=UmKI$kx;~SB$3 CJH(ka;uuat@!A68lGq+)E ze(mMt)jiyiRoGE{L2vI#@3<+e78o&yhpsG-YWqpqzVP-#=l~y0eMDYOW!2nZn%4pw zo7FA(>;K#xX?Y>2zSB_J_(zgc*hd+xZR8)cqTWdSe8!MbZ5?sR@VZ9kr2`I~8GpUc zdarn1w3M%$vi(f^aEst$;MC`Ws*8Y!1m71DFM3$KxPRNE)&y3Z#b94jWMMRGJP;R} zF(@tHV)~|pIb%X?zGRA^p=0%t-M7=es>B$?usaP^4IoA;7G9*nsiJknx2&z84KD)Y z+cG jK`4AMI8rb}be9F3-15)AbNSgK9&}jO} v?*!bi!ghb+CXCIHy3cMy;0tz72%RY8mohL`W+|WOG)3txpYhW7Mu$d68XlHQC56U| z^?L~n4*_W}DM1To`fD(QG3$GNzv?O UcbL zqL;m~cGvPu3i9S{X2ex-0dINGH^yQH8LQ}Fh LHJDy8otxx8|(pl$nn< zDY0GkvaBg1+C!6Q%*z22ieVhZ^W9>h=809U=8ni|V;1oATfI#gaQ*4HXs;(61%iRl z!ggN@f>kd+hSiZ}-ZjR%DP0!%E_&h0NbC)2PAw&%eXvy+Ymm~y$6Muj3UWWcgaW3&<}C+?BdH@Qzskw!l3A-D{4rTS3i{ z{WN}W(6W$It~59yfaO$9PhE`$Ax?sh*^~!vp7^~}+ZAIv8atj2M9CeRMp%bZsg)KO ztB*qS)w8ef;Urg99JF}7d{q1W9fKKVt97oYn+|5cMRxDgN(a(CEU@sei$|`vefyCU zI{&ku12FFWdTr`7SMq%4bPKR7gKA>q$eufL_nfkHckN;!++~|=VTgCQBw#R@nv{m; zk8V|ssK$Kw_SkeNKI{nfNrAO<*!@)#>Avor<-IW`Ss)0pYQ3ucv@t1&Gff_9KC7Nd z(5Cq5v8@m<+nRhdGV6kas;IQxp^G> 2$r!V)2@gK zr5Zs*zm$WE9)e~i&@AE?{%A4NWa#sp{-nq56cI$^PG|EaE 1;b86N z1p33u3R`*9O|aF6ktFn0py1v*yzPrDa2dLJHTlBLjZ~aE>3!M0|DAmblNxoE0$*jd zr x_Wzh3{jcA;l9MfFb%naxJA(hxBzbWus0?`37tyufYlqrj{b=SR0KwXfgf zTN6z2@a{iRQwO>>&Py*CK-4>lv^+d{Ld}-my+_>{umIj#sD7=~{TG(t3N)a2EZY@T zvns@sW}IwXyPm$2ZBQ>4!Rs7 Iz{O&pO+cYqru&v&ql|(WCSVu5FV_6 zw0f(wR~jTkZ(V+PQv*Yz|s#^!yIWaXG4{*N)oLO$Omh(Zc)VWE}*20uuvK{Tqg{ z_l3{9h=T9?#sFH>3+m4UQAE}>Ig@|=oQRbN$;z5Nof{lv=A2#l?oAs`mUZ*iu21%6 zGnIEAL0h8?kEhO^_D(57Fo!?S>dw$Lns8BLaJ{qXi#W|-kxxbn4d3>RlbK!#nC*xb z4 XNO$5L<9HJUv%YbYb$QFk<%C z6X<(J>}jJ%pS1lcA$hNiBMPa^i+%j^TqT+*i;I}=V|N#wSle;?xn`fb=Ec!3`#Hy{ z2~xI(8^%*bcb$4wfd)Pm>MfozdllGxlcj|xX~%_326}LRw6i>#p?dM4Sqivnk&W>Q z5cs%M!*;nfY5z_cJf&rTE?D8bp+$Asmkss^%|FDa+yp$9GZ)g9ozJ1umO3G+a=VPx z@i8dt{5i3FL6ZAC*TUpu=8IpxB-)?%=Z!E6{MfZWuc J$G^YAZwrE<<>k2U zg7atlV9aQBcZ``GTM#NCBLHfNBmlqxY>?em`k_FjH*?y=$UgV7BMzc|cpAuaYh{Xg zsCw3ZeBD>?U{zp%%rYx`@;aGI{mQb1ksKm O_zbQmeqE2ga_?zrQT)?08q#oh-2vJz&uWEUZ#%z^ZQnIpXK>BI z>OAq9)M^HHW~4UXI&LsfPsj8`COt*u?2MCuj4_wf64l~XlTx?YMuncNEx!Mrz#!@6 zn|v&}{bWh%_VO!*;d6eTmiuxevC{20q`!vi;|(nu-V~oS3M0UH6E*{uxH#C~z@lEL z!Qxsl&n$kM=SUJWD2j2gyLNOKZgT)eHxS(ap`w+GhxSgVM7nbs)r=SWyXfAdlzrsP zeHq$0K2)L*v{9dZg)1rRK8x_}XPXYeZ{ qbPJ}%)h3N1{p*ZIb)1heNuz$n*tvQEI$MuDnhB@8hp`h&f za6Z !)*H3_5NMvPnGMfI;W0BM6D|=PSym(Uu|2$yT@Ect@;>__-K*P=XQ-GT29)8F~w) zy_Q>w5#qi-(c}osilY|o{_>qNB=^NLrSXHEYvawwe3HM<4>)tX0C`@pDbB8$a~5P` zboWb-OvD3-u`4O;-1Z?J<9txS3~C9LxiF>PCOn!UlgbY@@^=E#eVIj#!M=#40V+%d z=BI1L`hTCLcsd_c#xP>zY!Z6}C!{qNv^S-_4k!RX*s0+y-?>luzE0ZO(sOv1`ItLQ z^RC1!Lj3MIE_92qazLY2&lc$`+5gB;Wr+gKRdsQ)I{0I~RU%<=Pp*;1|FvJ^)AGPf zk144){T;8p5Q%q}yki4e&(_VAkkWg6n$!R3Iz81DzVE1u+)2}`KkeXh{Z6h+=2v!& zO#l61T9=9D8NremwVu8eJASKDXF-q!oz1jnGc{qdC`J|PT?Sc7KUU|$KRlOvu_yP^ z(y!N+pR2wvKV=OYUC+WlC(;Ul@|o~eeLQt^m1~$7&}J%2Up4hV(x_euzDBRa_J(Ah zx;6F9FJ5m*pLi;vGtZZfG2KP!@SocOaG_e&2yDJBLacH&WwpPfzhUb`cGQubT!T!x zxuD)^rGg8C ZUyFlv(x+EiQlmZ=&K?82V@s6eCt`+0c15;&ve{#+-?n@ zQX|IcFZ`;I`AeQXcXMl JvkJ(>UV zkAk!Nvk(E%&tIOwmpEG7J$PQ!H>ojmOZI=BlhRsR`A^rx`DYqBC~nj~f&g`>U(Af= z?(^7g4S_tz?Jc}tv73mH^v7FgR7KWJrL{8sev6CfoOgUkj`73IPL3=EG!OS&ywfB$ zF8j{qbzyZXhP}KP#sQ=XP=~PzjHQAZK@b5CF0~y}^Of3}PBpECPUPnU&@zdB2avDm zIQv5}mS+hL)m{1MzVzd0I*d&9Qq!%9#e&1vz0+ZPCc}PBOSWI7vgiCVt|xgjVZc&4 zF~fq0rH)@S0qu*{DowsLtBk|P x4{6b~Kn2?JJ z=&GzrT5Dk3;)fj2?V`-prMZSolM0~fiKoS8z_>;M_@rXT)3Sm&$Y{v(mq%Y#R$!_& z6u2CV^BN{5*4@JIh~#+Mr#hJ&4sQyvGYzcQa5ZLhSFgxb%{CE-H^z?`{>$yGB&mmO zG!teWJbCozy#=P3#?MvcfcTqIggkWTP`fg!Eo2Dtv(a6>BVs-eBOfa*RnwC|NoFEo zpj3w07KdeAv&%A6s&$&;VRC6gWx$%7e0OKg^3|R-7cY#{ieRR {AW7ZzD2&pzUjKnQDc<}t!W;>&^J+K5t8zV zH>9_sjuV3?@glp)n~lvG4cg z89PV<{(7u+TgBEF{d@qO{^pw;9cbS#k%<(AgYFkJ2$~v;X~c(IrE1Lj5#L-2<$gyp zpR5O)eZ&-k<@+f!MF!0^D!E-qJx)|I44R?DtI8kdv|531W@MxF;{d$Fe)wXmosHeZ zGh9|B5&CcRPj3ozg$T^5kEmgCK1kKr%R%@z>d#v*krjupIuVu70pPG&SSziQV{}9W ze4yZzqrg}&i!-WD(#c|oYuMf?V``b7`rhZD1ZFt%WUu6nKD%QN`|&CF;TmB=mCLZ` z2w33*xx5YJ?O?kO)h%*$`x8Ecub%<%Oo&*qaa ;@S{!v(9mnpsi^1^D`CY*wE+Fm&;;+%Yv1>uK)bEk$=WpxNh`SvwNkk zh0=**s>3kQ^jU41VwVy{owMx z`)Iy&SKqHqzS%)FY3r`IA8Y!=Am;-Oxh$gfbXCE&QJo~A`E+H789Y_wKR(>+Zx*Od zLZDZs`*Q49T8EEox|n%&gn8RpZ2OXCx0U-Uz45;X3a%6wKC)Dwy-pJ^=734_P5t;{ za#-{Ya3%1h%Vsza?X!a!6Jy%#!GfvrH=QS$TOqzoO`tnvw|s^l6s>! Y5 RU8<&3LNmXrHB>=fmu~ zHJ<^oR#&f~wEZJzmo;rIjk?04pRL~Jh-`0J7daDT>w3M5{mGCbVmpzXc14u(u;TkD zbs7+tC7{~a>bk&E*85#xQ+EG;)hX@vDSfyg!zyqA*OHIMyX>agtcBK@{}1xsGpxyN z?HW~4Toy!^9RyTVq$^cw6a gs&}#xj2n3K4 zLLdP`2qYw&$G!L3d+l?6d_TS)@AY2i7v+K^b3XT+_kE8!#+Z^bZidm>jaN=gPzo^5 z-TiH^h?EwulD(Mr%v;R1!cJ%^#$(92-??%omqy~ggX?q)H)fX~o^R@>=Fm@)tDo7o zn%8~pW*1(I*GF>MN6SZ7PXzZZ`%|pzoBErFgfkTTNB`}uAO!&;HPcdtC(IvmNDN6o zlX-*oJP#b`>0Ilh@_BW)zfa_6Cs&%+De(rJ)yIm8{$SVikYtn)i1V$kP8Kd!{a6oK z=SR@94~=XyB}ffmoR%F%UgU#|X-Ypz)Ko#au_T;r{-SUs9poz3$PZQr$<>W*m6r0H z^I*?j;r0dcN_AwK)Wa>)%eNG<6Q^KHFSi$xmhlC~AEFE+9CLoQ?C~2(@~Q6=bj&!8 z9{039+!YCOvOyFLO3_uz_$>}cWfmtpdPk}^6q)IQ@ZLWWk(cG2#N{1Wjdq3}&M&ZU zTd?%z5LuK*HL7$OXL*gPWGs5LrrDUlBr#~+iDM&0WrP}thwb#pi@YEQO?Pom4Tp5w z@FsF)859|Q$!Wy@SaJEMS2M<)d;w`!bRj$a*zpW!Ja4{YE~wjxTMa9ks___ju9a1| zQ39iMLkqSmaXgO{xTLgh09kI9)za TJSL@@0gnDz`uUlZ!=JKdV`D9$ZB?=^VuBU8UvWw+ZV+XB9G4 zy6v&)zCH_tP0O_tsvq^3mc56ajG%e`oo2-J85SBzSO|*R^~%@8V~kKq47}P)a*xRC z*Yrh|g?E2){FJFBl}snj#?(Q$9^zrp&fL}#SS~>_`I&gkP*g@Jzlnu+-kXY)ag1V8 zvg*u9!9m$u$qF|0fnXZB!HsyJFsij&r!d>~oTJkkKC-Qx`y3MJgW99%?%yw!SlAFq zV2(4r-#tpnNh#0(Wd_PPZp1dm#yXHA7F07fWq Fk)~*BP^V?q6)o)9lXWyRUa3lY(3EGS=D%IXGj#a*}icU-hiaC^}liF$a9c zGbUE8T!*zON)>6Yx%`uKr6lg$TCgxDuil&+uyB`oJx@*7bIPrTAY15hwV$d9O(o2* zZW=9CT!r6ZrY4NpI{WZj!F_YO zO>w8~kq1s)`B2zA3{LHTE-CM47AqL%9`3XB!kj4R8R1B_Rd?4N4wC7Xbt1k}w7;Dl zIj08m`o4Y_tv9GzGud0#tkmzqy0c(4v*tkx6$G6xFg_+M_;@|umQY0P=Ny!V`v3xh z8uKmf&|4GhS?HXN 63CFVz*syZr<*)#j-W!#cmNP(I;#?wlGjXOUc` zc*n5TXs^ycLO728Z8lF3JXayT*nJ&kT^qX(cLPQH!+=J}Ehr(JiuY~2-EI{_)b~3{ ztF5W9V48SLJnNo{gZnCbSd*t#@f)OCh6?R_IdD1paPxpY6uHO~}6{o;K6#*S)X% zaJOhyUG!ASJC}O`5S0^hdEv*T!PfPhLQ+k$Jm0I>$!McDqM-Ac7CVT$W?vK(Rfasd z$2K)D;V4_kPpo3Q^uDahy#`FZx})>iNEdgSXa0(CsIYKdq^l|Sq3@E&gP7FY^%2R4 zl$Y!ita_jL-8opv?|Ka7v>c*0iTVC$xq_F|D#VHxe0d<)DWcdShaP1wp^R?jJVPG{ zr^2Y?uK7$^n*{oy$(0MEQGZpO@3=EzpAD|SMsar65Xb7k@*`3!`par><~|BlbDZmR zUlxJY=2d*YSdW~@1D}%NT_*D{(tRcdo41Y>RDvJRCo;(8Rr-tLiUVuH;<~5SUapt^ z+5PZGvEBy$7Sch~v`Hv* g|8jRw(5edUbpGOn2>>oUg`f zej;93bh`g_w_*YH rmfzLBZ;MfvN!Id_;>MjJx4g_i8(Q@GE~iC(BRU;i~b zfLyI^C(@SN3fE>g`LmZsjRm%I*k~vuD&kGM$>RAl%GGqL&gFrcGm;`Z^C(F5@tV@F zgERibk5h-bb%tcqRo3f1wH~2wcE}{)kJA40v?8X%KL5z!WsFt)6zfGtbMop!s0(m= zOVR0SH$k62@UUc=q=%H9bA;lNxg5|due|)8__f%FyvI<)-66p?e=d7(U6fDPP|Mvd zFQZE1($*OOmmIk=WtO2<=m9<;*&6AA_d(nrawcjo5n7H2=`E>8hBb-_OXaOpseHNC zX(4)bfq+byTS*_XfaNxe`ZQ|$ig@YmigC}2s>n6ysvt#Cp}bN;FxKbYYDgo>={2q5 z>Aqul$gb=Nsu&^SHEy!cftaNG(vMKs`q63FOJsH3N1(cgICHybYEWhVaP!IJ#|p@q zvW=2!^6C7fq$3TRzgp4`$hF^0hjg>up;>ufvwFjuSo61q&539~s8h~HzEH{*Hpd`6 za%kI$F`FXfx@5n?QjJ0w;jZXS9!jDwaN&oWC8CKKl*XYtIxMh$WFsf%b3(=b(N9uJ zvT B<{gz|@pycA46 zB6sIYKG-ALgKWpydzkd%lnhQXE5e?>X1&Xp$i|}2ARo+PbBL#%kft6K%>_Y^XMZm0 zC|Yhf@FT(uI}sOakw-*VU3w9B+_U<={80w35IiuaV}LRfdGvq*p09rY g@$d^xXAdVd(yn0NVrrnsye}@{o?)5D*MA#QGJJd`vXmEiNKE|jO zQ>~^a*BD2Axg$$CD8qikvkY`?f >p?C5Cu;10+iH+|b!$Nr%Dj)>Q*)~yp;jQ| zn6B$n-!FJ7%QsubDdWLx#Bj?I_*914Bae4i^9_^yXDCS0kf62C&NVg9aAr|R9AWGe zm3ckh8cNCSq`F1DhcY3lOv0iUahcpANxEA?SgfXlvEKN665$%{mHF%IjblWqpc-?} zwAf-VW9H;rbDyr&SUTMuqLa%VM7Aq>JC2(YH`H)?VyM|hP+SNaAulWHm@DKtQgpQV znrdFSs65=MtEfW$i~gOSWw4nRd)ujn#F8n$W|fh!=PkB%CK;bs QJZq zI^kom)kd$87H0SdW!LZ49_3I;JPy<`O{_i#+=8aeZDD!)q20pbN;;v}H5FO*o&+Su zc(Z~J4mG#0y+`Iw*WtQq?u|J3sVZJD+h|VG&x50|j%i${!aT`J~NdibuXzv9Af+ zhfuIlK#3`s3SZDv9EC~HM+pH$uh)yaimor`-a|#CC5W+wOqd3=(%HIMuPZq#qj219 zzDigpC_SP+6b3TWHzZ0&9ep}xWVliAb<8iR@ESw77HeoCy0oZiFQqbJCc2zAX@;9k z5ES2F{>q>Reg)!c$N)Z8OL;Vln2j@MlAR@!4T@+V>rQ?3Q6Akm>IqHgkk7mUJ50w4 z{VTlMc>m(hi}w!_9c3AB5R~YSrusis^8sLJ6#U5;kq&lkvi$J|y8cCTxN_>nN%qJU z+RdB8hr;&$DYe_DsqgtdpBHU6MK?Y#rnZ94s zxp6{dvT(qA_R&AK@nL$Ha)GNu6{v%fA5QD6`~`TLAJ7o@&f(jy)GmzIe&HPfj>y^) z@*X#XQwM{W*hn3_pY%!$s;W)8cHcvW*WqoMn@y;_6=ST}aHrjmy85>nM|H>Rv?gKo z_W%1+WtIkPs-A@)2Qf~+WYt4K&kA+y54!)G<^{}Nr9*jC+>2DfTi%(h{5?fis{In% zD)L n2H@Gh zNh*P9kcz)^|11E;zUZw>eDrt7+~2bQ&L43vU)cPXof#d~dB{>FqW`1D{Qa-UUa6?r zx6h6T|JNLCyB`_%$KU4p3rOt0A@Bc_-RS@5B>iuC^LKg8$7VW`6Kx?dgJX&ix!;24 zUHgu;)es?Gvrd2$kJ7`hJMC&blhfEgjziltD4CLe7*@(}rN8Gu(Y+M?o_WBvCvv4- zDuC-#*Jzc?Y%aQ0c*?Ci{rt=0=g?MF@pOH50e69j!fC0pIbilyTSu~N_s6M8$MM;4 zyK47a &0RS^wr*y628FdDE>D@cn{Dn` &i8u(@~Bitol%lGrpNczzJ22zYBIMse5DW=J)SfSA+I z_ql^#!=P#B9+98RBVPIs$W0rS;VjR ma?a)D= z_J?n{gublazMX$2&oHzgZZT)5M&Cxg#Vg#eVdj_yccE&gmgJY%64x6@`CH5`^&SoU z{7g{yji|c$$k>3nj7{mq4JJjMz?^QEL}rH Os&Bdxl zGc^KdnwUL_%pM(E-IH4{9YZ!;EYU$88j M>1*8kr|L|IpjVTCO9GMM13z$j-AYE~o2zGnuc$AbnIV>+T zc*yR8klz6@&$nhV(&_5BuTGY~Jz`hdB;!APNtAb}Z6km|J}JaU3E#h8Ke@VcHS}hJ zl}XaOD^kJ-#5B*LnmDiQhzH!VVTDcFmuil`xuL>9v*)s1qr}7`7H);UEX~2VxP#9D zc72IGS(*jX|K?Q# !VMlDEv zu>9+bEXW*XZ*5=eEe(xgCGS6V>C%a?{&FV=g4fqlyQ&BMxdyXU_ziSs4-Hs)n@BGF z0kF)06o&F0L$|L|2`<2pU17YE?WfbtO(Njy8x({KYktu6 &T)$6%G&iRp>E}WQQkHbTet~!2L9WwLb zNou|qu=FknA5(BV-K))f)0p4J@+nt$`N$O9f8ul=NW^EwYql#5U%w11TnNhMv+!iY z=Qyp=VY1%FV%>Px5)FkjW{@#s=Pf YSex~Fb4 z7))4ZE+A&wk=dq+Hhvn~tN|+}*h=aJ3`adlMAfq`6&meP`)Q^C(-KB)K)U3+6m`z= zrOZE^{%s`Fc>Ph~HA1dOWiT{#P{nJ6x9Re!(@R)+sx=;5w`ie~RU7TWVO{yp!kKt* zEco-YHL^wNoy*GQaT8>S#Ab?|lXp0-Z{n#8(l&v|U2E5M>$|!u7}&)Q7bUz8xVpAD z?xri7h3ZU$?G_+xR-f6(nq+(sBtLz+ldugF%77@NjFV+7Ya{J|SHuI0x-Ln<$v$LZ z)FV8tZ*|V=G9;2(5G1soQ0+NppB=WcN7}0J&2J|m?B>coWhc=YV8^@LqV79-R|M-L z&?Fe*u89%qJ#UhAVb|Uxm$ AoWYq z7v`=)s{)oLt|^y!4_5|k2?)2jq&m6kdPO%a&t~9jogAbg+T`hFD5);Pw$|O^ITqc5 z4}i~2#^zfV7|&J>rT%%|xJ}H7afuuMprz|%C0Qs5pe`FhF}dlgUKeIMQq`x>aU(UJ z8Ot0YksHY!$z~WwbWmDaA**9Zry$sxk}B T*l%Y&=dj@j0|YxnQR;I-kewZpgiMLQ$i&WV^=X97lcBKL)1rR?u-2 zzQvpU+rIiJ(Qcsmn3~1a#j(cTO(8c*PgY@qZK|SE@tbNaU6YxQ5qkCE(!Jb)5?inW zW>tw$k3u8^op%rfg^Wn^h-Qxl#ybWq|0s-o0gX tl)MO;XZNr?$k2b|$qac0WwL z!n%F4>C(Z|OG}c%8IKNj9~W}%<9VI*Sb8P6$Nkb%!6tWIC(6KiGn`=W&nbK*q~1Sa z&%w5~rj0-|v5R(<`6`|RZKfsTAF)T` nFbhrYz9j zmW7HQqNe+)k4IM7jpLaUw<%$<7@aOT_>ZHu^?{Zi+hPSD6!n6(w4FXa!;9OI!)fw~ zM3EE9lLW9?6n-MPq#WBJ=ghREVX+4&coRic*g%2FaUj>n-86ZfB5&qI2p`~qwl0$f zD+g8xKBUS4j{=kA_ZcHK>ZCQomv=@IQ3Iu@nVjGce^ iNH WDtC=!9J$vZl6m;LD~U&fSmz>H=N)5V1D4!EOTk{o6A&7oU693ZlB4^RIFjH zTW@yZq;}>pTgQ7(lnzMfo^x(_n`|4~G~aVbnGftGXvB{9iHR-)v3aJFO|vuAjKZ{u zT|zrwD%y;ytV1WJk+X~)Zd-m$%g-AN+t?sefMYw+VdplOY@&euzIr>C%U>mcV_FMH z(X_IhLiIOqHZ|doZ^rsoWm~Bgn=fk4GEg{$OYq)OI|47Fa1Zuptxv}0`c!;#c+DaT zH_akKO|00uCs>a)Y{tq3lh@6-YYtTIIM#JMde70rrjHDppX_p(Ew#g!*v?(evjg?M zKMsxTe?toq#I3w4h2qFNVJhx@r_CVq8~rHw)?GVK9fJ7nYT|y;xm?tGzb(&wsk7Q+ zyg;@SI@@)5%I&t+x1CL49#Qa-n@GVk)Q7?+mCl`b`frXh&=xfo0l*Mr% S0Njz6;Rk<6{i{0-3_ zH$;@{?}z+Hwb8TY7{ShLokla%Zk-5SUy)i2Q0brLaaqb!BVTy!>tNHEdbJ(|gtcFJ z3`{`j1aH>5#%+|MuDyKjTNe>eFHGH|<*pfwfQ-B-*Kr8*;mSr{{o0ZI_|c0St9MpE ztSt=7GAX=yb0IL)q{7F<)9*MfQ7wPih!@T}j}3dM9DVQp{dBS>FdyA+q91Ny^>!V8 z_mK;!cCWB&9l`nGPH9B` D71+nvp$(g&N-{x(xLyn?+Mg?yVlZ z96Udu${h;8ul@|L8J32^?>5(sM>;=IO2YY4VV?tn=g`HJb^z+|fj}!qhI^HxI8Wtc z${co(>Qu}`)ptE{Q+d>uk&5H3Wu!4`+$Z%YS3-9&m2(1~NSg?KxlY9PPA42Ue!2{c?NI`ZlW)SW@r4N#Ia{sU08GqJ>4YZ(unxeTjN{GabL3PSa2C zSmf!6-ME>N9Ve=m4mqimOCtYL!*6As(haz78QB`yq~=FHRaqLe9!R(l`e}+(H_KLX zix7EX`6FrS{A}`BG|vyaF|-<)`&gJoQ+;QAR5tx?OhG4J@N9nmsi4-k2rT`Z;P)hX zTZIRx6A4Ljx4w#*$fh&DtrVWIM@I=&_kD@u_@YGqGrlG8A)sK nUfydv_Yx zVU(w$H8BuORagC5($bIPh>YdZ&(vPCX2S M4$nIlCO@OB;R zW4_FGO`E#BMTEMPki7KMEDP`|S8R=o+;zQTf>!8G^numY6CJ6tZY}ZRLaV3VXHYBV zE@# ( gss6qxY+H?#X(g5^GqYWM#5lQ_s#@RL 3P7JU)$^Z{ z{!t ZQ^7Ip8RcOgbOLL_CkZWXR(p1mrJKJ3=5nf|*!e1F#9 zRomMvEteLsa#uKiaXz4z$JPjx >Y{ZaxMeDMLLz3f=HQC#C1J K-Rs_uo&vPju)Hwcbg$hgV`3WgE?=tS} zc3}5tF&qib-&3KH(h_m}Ho3#EZ{-=b12!LKS^W?#L1FPsg^Ap|%}*|Txe;SkZBBZW z1Ekf2Lz0Fc9x^s^Sp7paliy-ZfF#mY;lZgsRnzk(Xg+huW6@f_Zc*N(jDg$YH#X^b ze;BSs_|npJqq_Lj3%-quYF3c{Y=Qojucd$Ld2BO?Js>unxQu8U@*$ZjZZqDZ|EwT1 zspSKKTDV