From 689b3c936da76b79ce314547742c8a58f3b58b23 Mon Sep 17 00:00:00 2001 From: Jenna Richardson Date: Tue, 21 Nov 2023 14:01:57 +0000 Subject: [PATCH] [PLGN612]- Remove grr plugin --- plugins/grr/.CHECKSUM | 23 - plugins/grr/.dockerignore | 9 - plugins/grr/Dockerfile | 25 - plugins/grr/Makefile | 53 -- plugins/grr/bin/icon_grr | 50 -- plugins/grr/extension.png | Bin 4467 -> 0 bytes plugins/grr/help.md | 368 -------- plugins/grr/icon.png | Bin 41211 -> 0 bytes plugins/grr/icon_grr/__init__.py | 1 - plugins/grr/icon_grr/actions/__init__.py | 4 - .../grr/icon_grr/actions/hunting/__init__.py | 2 - .../grr/icon_grr/actions/hunting/action.py | 307 ------- .../grr/icon_grr/actions/hunting/schema.py | 848 ------------------ .../grr/icon_grr/actions/labeling/__init__.py | 2 - .../grr/icon_grr/actions/labeling/action.py | 39 - .../grr/icon_grr/actions/labeling/schema.py | 69 -- .../grr/icon_grr/actions/listing/__init__.py | 2 - .../grr/icon_grr/actions/listing/action.py | 106 --- .../grr/icon_grr/actions/listing/schema.py | 86 -- plugins/grr/icon_grr/connection/__init__.py | 2 - plugins/grr/icon_grr/connection/connection.py | 31 - plugins/grr/icon_grr/connection/schema.py | 75 -- plugins/grr/icon_grr/tasks/__init__.py | 2 - plugins/grr/icon_grr/triggers/__init__.py | 1 - plugins/grr/icon_grr/util/__init__.py | 1 - plugins/grr/plugin.spec.yaml | 744 --------------- plugins/grr/requirements.txt | 11 - plugins/grr/setup.py | 14 - 28 files changed, 2875 deletions(-) delete mode 100644 plugins/grr/.CHECKSUM delete mode 100644 plugins/grr/.dockerignore delete mode 100755 plugins/grr/Dockerfile delete mode 100755 plugins/grr/Makefile delete mode 100755 plugins/grr/bin/icon_grr delete mode 100644 plugins/grr/extension.png delete mode 100644 plugins/grr/help.md delete mode 100644 plugins/grr/icon.png delete mode 100755 plugins/grr/icon_grr/__init__.py delete mode 100755 plugins/grr/icon_grr/actions/__init__.py delete mode 100755 plugins/grr/icon_grr/actions/hunting/__init__.py delete mode 100755 plugins/grr/icon_grr/actions/hunting/action.py delete mode 100755 plugins/grr/icon_grr/actions/hunting/schema.py delete mode 100755 plugins/grr/icon_grr/actions/labeling/__init__.py delete mode 100755 plugins/grr/icon_grr/actions/labeling/action.py delete mode 100755 plugins/grr/icon_grr/actions/labeling/schema.py delete mode 100755 plugins/grr/icon_grr/actions/listing/__init__.py delete mode 100755 plugins/grr/icon_grr/actions/listing/action.py delete mode 100755 plugins/grr/icon_grr/actions/listing/schema.py delete mode 100755 plugins/grr/icon_grr/connection/__init__.py delete mode 100755 plugins/grr/icon_grr/connection/connection.py delete mode 100755 plugins/grr/icon_grr/connection/schema.py delete mode 100644 plugins/grr/icon_grr/tasks/__init__.py delete mode 100755 plugins/grr/icon_grr/triggers/__init__.py delete mode 100755 plugins/grr/icon_grr/util/__init__.py delete mode 100644 plugins/grr/plugin.spec.yaml delete mode 100755 plugins/grr/requirements.txt delete mode 100755 plugins/grr/setup.py diff --git a/plugins/grr/.CHECKSUM b/plugins/grr/.CHECKSUM deleted file mode 100644 index eb06215b96..0000000000 --- a/plugins/grr/.CHECKSUM +++ /dev/null @@ -1,23 +0,0 @@ -{ - "spec": "d53a170fbcf5fb474d2b2f4ba102ebbb", - "manifest": "a7aac9416b3ee4df04233b0c0930b11a", - "setup": "99bfc64c1e65aa63e088373af6a1f0ba", - "schemas": [ - { - "identifier": "hunting/schema.py", - "hash": "9e8a4f8426034724815b8a52b26aa457" - }, - { - "identifier": "labeling/schema.py", - "hash": "e345981bfbca09434878fd8362d8a0e8" - }, - { - "identifier": "listing/schema.py", - "hash": "7dd79d69ed3a6993299305ab98c20b2a" - }, - { - "identifier": "connection/schema.py", - "hash": "8b7eb3cff059e9d92216c85554f1f03d" - } - ] -} \ No newline at end of file diff --git a/plugins/grr/.dockerignore b/plugins/grr/.dockerignore deleted file mode 100644 index 93dc53fb01..0000000000 --- a/plugins/grr/.dockerignore +++ /dev/null @@ -1,9 +0,0 @@ -unit_test/**/* -unit_test -examples/**/* -examples -tests -tests/**/* -**/*.json -**/*.tar -**/*.gz \ No newline at end of file diff --git a/plugins/grr/Dockerfile b/plugins/grr/Dockerfile deleted file mode 100755 index 1cb35b530d..0000000000 --- a/plugins/grr/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM komand/python-2-plugin:2 -# The three supported python parent images are: -# - komand/python-2-plugin -# - komand/python-3-plugin -# - komand/python-pypy3-plugin -# -# Update the tag to a full semver version - -# Add any custom package dependencies here -# NOTE: Add pip packages to requirements.txt - -# End package dependencies - -# Add source code -WORKDIR /python/src -ADD ./plugin.spec.yaml /plugin.spec.yaml -ADD . /python/src - -# Install pip dependencies -RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - -# Install plugin -RUN python setup.py build && python setup.py install - -ENTRYPOINT ["/usr/local/bin/icon_grr"] diff --git a/plugins/grr/Makefile b/plugins/grr/Makefile deleted file mode 100755 index cb85f96b6c..0000000000 --- a/plugins/grr/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# Include other Makefiles for improved functionality -INCLUDE_DIR = ../../tools/Makefiles -MAKEFILES := $(wildcard $(INCLUDE_DIR)/*.mk) -# We can't guarantee customers will have the include files -# - prefix to ignore Makefiles when not present -# https://www.gnu.org/software/make/manual/html_node/Include.html --include $(MAKEFILES) - -ifneq ($(MAKEFILES),) - $(info [$(YELLOW)*$(NORMAL)] Use ``make menu`` for available targets) - $(info [$(YELLOW)*$(NORMAL)] Including available Makefiles: $(MAKEFILES)) - $(info --) -else - $(warning Makefile includes directory not present: $(INCLUDE_DIR)) -endif - -VERSION?=$(shell grep '^version: ' plugin.spec.yaml | sed 's/version: //') -NAME?=$(shell grep '^name: ' plugin.spec.yaml | sed 's/name: //') -VENDOR?=$(shell grep '^vendor: ' plugin.spec.yaml | sed 's/vendor: //') -CWD?=$(shell basename $(PWD)) -_NAME?=$(shell echo $(NAME) | awk '{ print toupper(substr($$0,1,1)) tolower(substr($$0,2)) }') -PKG=$(VENDOR)-$(NAME)-$(VERSION).tar.gz - -# Set default target explicitly. Make's default behavior is the first target in the Makefile. -# We don't want that behavior due to includes which are read first -.DEFAULT_GOAL := default # Make >= v3.80 (make -version) - - -default: image tarball - -tarball: - $(info [$(YELLOW)*$(NORMAL)] Creating plugin tarball) - rm -rf build - rm -rf $(PKG) - tar -cvzf $(PKG) --exclude=$(PKG) --exclude=tests --exclude=run.sh * - -image: - $(info [$(YELLOW)*$(NORMAL)] Building plugin image) - docker build --pull -t $(VENDOR)/$(NAME):$(VERSION) . - docker tag $(VENDOR)/$(NAME):$(VERSION) $(VENDOR)/$(NAME):latest - -regenerate: - $(info [$(YELLOW)*$(NORMAL)] Regenerating schema from plugin.spec.yaml) - icon-plugin generate python --regenerate - -export: image - $(info [$(YELLOW)*$(NORMAL)] Exporting docker image) - @printf "\n ---> Exporting Docker image to ./$(VENDOR)_$(NAME)_$(VERSION).tar\n" - @docker save $(VENDOR)/$(NAME):$(VERSION) | gzip > $(VENDOR)_$(NAME)_$(VERSION).tar - -# Make will not run a target if a file of the same name exists unless setting phony targets -# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: default tarball image regenerate diff --git a/plugins/grr/bin/icon_grr b/plugins/grr/bin/icon_grr deleted file mode 100755 index 5e4f79ba1f..0000000000 --- a/plugins/grr/bin/icon_grr +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python -# GENERATED BY KOMAND SDK - DO NOT EDIT -import os -import json -from sys import argv - -Name = "Google Rapid Response" -Vendor = "rapid7" -Version = "3.0.1" -Description = "Organize and start threat hunts using GRR" - - -def main(): - if 'http' in argv: - if os.environ.get("GUNICORN_CONFIG_FILE"): - with open(os.environ.get("GUNICORN_CONFIG_FILE")) as gf: - gunicorn_cfg = json.load(gf) - if gunicorn_cfg.get("worker_class", "sync") == "gevent": - from gevent import monkey - monkey.patch_all() - elif 'gevent' in argv: - from gevent import monkey - monkey.patch_all() - - import komand - from icon_grr import connection, actions, triggers - - class ICONGrr(komand.Plugin): - def __init__(self): - super(self.__class__, self).__init__( - name=Name, - vendor=Vendor, - version=Version, - description=Description, - connection=connection.Connection() - ) - self.add_action(actions.Hunting()) - - self.add_action(actions.Labeling()) - - self.add_action(actions.Listing()) - - - """Run plugin""" - cli = komand.CLI(ICONGrr()) - cli.run() - - -if __name__ == "__main__": - main() diff --git a/plugins/grr/extension.png b/plugins/grr/extension.png deleted file mode 100644 index a5fcabf5227b6c3ce2295971dcc475213911c3b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4467 zcmV-(5sdDMP)3K;$JY9fuJ-=+=la*4_`g>A(~|t>#`2}2?~8`}<>cyGQ|L`a_p~bjT<`nb zs`0}S z|IzGbuT+hCUB4FU?T$u>t|w?1MAQ3&sF(N4U~r}pmIS~C8D^ti^VM{x`#Ke@3~Il0hUic!HtTa#5~xS%6IZ5g`+Ugc=X7U}y&` zsG~jx6RD1-%!A8?J&bCpOT&j?qAj%#3`ld;oZ64T#F-}Wm;A+|6wPXvh3J_mH`Of! zf_4_ga+ik4nOOG?Aavb{uMNXjU`Q(!!Gf2CsF@hp+?za(sO?s#KRi4f_B%~mBRoEg zM9jpSVUt6IZfHiYjr`PVyEm2&hKQBQ3r5QXj|f8g>%8ygdKxk)`btSe#7yK^B1od` z`}KNBpBoijUo9dcWg^QsO~ml$!9{7RqjaPEK8t)eM9D;gw!(H_dQH7&uO<;uGSQ(- zu#w=}2O5L1hSJIEC7z;VqC};dNJsI)dX20g5z#SGrmVFVAg6b>YB?tdkuhth>D3e)=k$Ug!(GQO(m}o=g zMBYUty0=G1M;qO+m!BVxaUSyGdbV24%FByUFoBb>%l@_7?UN_VLt(VFACQjYiRNSX)Z#f4$ED7G`W@k{3$9ULi~a5%E0s&R9-7e3{+= z1tzYGmdWhpWJ75+{1v{By}ljM>z<)#ok}miy3epQOpr-GNH5>id5v7-4;{OBFxSu8 zv>Y#G;@Zmd_p%k}wg5mMc8O8ljV})l^5(wy^3T3JxLn+e?RVY3<=Q?&B>`0?j&=*a zd)Yk-cZ-m?E^8EGW0(5?0az!3%ddEP33DM*QR{}F<(ec?wZKfATEe|-hq*^}__Wwd zY98Ac3WWD4J^5OTOQAq`RJ{29dYj+aI8#x2bN(M{OpJs?jHw8tp|X&PC1pCUB@3Ux zG<}TSivkg2)BWA&*AK-+V5l(Bed0JCi&HUx23uB`sFzcUfLEyz;dmZgD%6M=Q*qB- z^Dxj;+-LK?yJ+jq7r%+tTJjvBwf&77I><&C0m>#Qfw1ON0~9jlml6G;1r^R$rZv z@uR|aSgSJ8pqFjtCkX@Ub1P_&cL}75F-s+M8E>y(jZUBU_V%}Lo|s54zeD}v zF+)Tq^ZD}i>gx64G0Bj@cu-|}K8n}}hl6T1n=73W-pG!W3Ce3SEo*0cZ=>5idOpDc zhB;b<2}v7l048Sc@Q9LSYZqh$Hcn|SEGqZG@bLY0{*T9xG#42vuBhQB-_V92iO}W@ z*vgo=MMRiZ1I9tu$VCk5%Pxlrvguv1O+P~P@@^>QRY3pxi0^bdNoASN>4*=TiW0un z+8O1gR~X$TV*(k8!rd+Yd)+(uUnMi7iFv6pBQ|6If(kt~9 znD|KH<=X6nmQ7IRLc#=kuz0R2v?9eD$?e2I7F(9=2+YJOQk@0b3b^QEXT$=o><=Uo z{5blUQc&QZdgwOWyaYnMNws>3nLv*`*HML=u>xfSVG-Mqwdn_D0;wLx98ZB9bRZO1 zB>WN@=lEN5p~xcLV{dY=u49ufW?~zNc>ad__n?PT6lHK2z?*Bx`on`VaSfG|zcYdT ztGRl8fscFUAHU1LVg)t(9EpUlyjKxlVkUOMGIzOu?dZhhZbbno+aasi1-00_{5#BG zAIeUCCiUnJ^CM^%Kj9ZM(>k7NeI8m$F%#dwGP#l4^BqpG5NALz0L{8nmU<0%8?g8E4W5MN+vGmleqkcMDP%BlIiIcgRFz=W@v$0huFyXgg z(F~ffJ|XERSZ~!Fv|3FUm*kjEDG{pBP-qJbY5~1GY3YOp&h+zOr+}nV8Q4xYiWhq)e|4quWhKX6|U6=wTeqqPriVG$;3bc zX_m)0`#^vuwB5t!T=wffY1-<@U`wu^i?fIcyh0x z2~)8+8S7<6uGqWli&r)?(pH~FD5=TBGh--f_9(6O`-eH`8?pR?s4mGJSspzfEX08!1+v+my^ z6T%eWIgd10J`v{ApaU+fPau<>e={phA%Q_^%3(zoAL9!iKh%gR^qx?`ds^s%hC=K; zz3^&ExGE~x4m{gR$OJSLQo|P->r@k#p(`fH2e{#pz^4zII8k>ZvM94Xq9;A=+fYEY z6wHi!nQOdw8-R?7m_XHFQ*cijK?+0+4(VWui{-DXqk#d?T-ycbM zhy5ph;n#rhptBda-A*ph`o+B+un6hXW#i!5vi$#10rcUR3DT0Dj+vudOKo%sde;3L z*|$(LPGk1@6>9EC`^6NfKP`PZ`y7io@rmy6w#7_5TPoXelyZJ;k<>?%ZrRZ7Ght%C z$_x_HT}3Cz1^4lv@T3c@WT3=&GRda`Pr5)S3kikZ(S~ z(uzg2_%1!BO_}v`swqEnkJ28;bkja<*6|75x^@61yv}$VawcdYAEA`f(Fxv8f$dLI zMT+iXpWb9=Br4IW)mjNn(+o}%px=8BZt1Lk!8-AdO}X7>>cC8E-2**Slu7>lI^eov= zem7WivItqOlgHtqsnmeb6(9d%N@V#sDdZw8sjgQ2UtCFQW!PJ-dcIS)A>hJXECI+M z+ZVnuJ`wOm<;+{w_76_-p9fFCmm_PY&G2YGF3518b zbB3X>WQ?P|exN4*Ym>Y7qBT-V(EQAB zHYl3~Yv=7cJs`@Zj&s@w-h-|iL^FE9`=a(6RQzKWt)lw8$HR9joJ*%O$xG#fV>icJ znZ37FH?+i|ciSr*JMrnyzvlSe=P%x#KDlROPWEChd^)BK>!n_cILE)Z(450o`|Xei z@^_!z<6;XA#{WAy4OZPcf0!Q^>l_$+A)Bkfs1Jq*&VjMEmgs=Y?%b^v zto-ii4Ni%;-Q#gQFg4@04?d|9NZy~cX$5*cp53g6DPf<>#s2zaTC{evT z#?k@0y%w0{iLp570l^p%0W@QVY?P0oin`F-22O1JLYk!_+qZ>E2Q*{8&r2VEQ49`j zLwK4SY{p#H(Zw<9rG%R#5Y4QC0!H8_`50<&GG|k#$oC$@7mbFWfsP?U?h71d@hK{z zc9vKx!eL+M^QYJb)MhQ1|J%rbWe;w+h8r41VqJ7J=uGOXvm(&`uiT&9FYK*-lL7z-^(c z4L9R7ctohLw=4Z#uh$=z2C* zmx2u6(?32JhyUU5)im~f=3(y(0ejmKsM&g0+X1xQzz%j#?ZCEyUcGkr2?&T^IXyS_ zHP(HiWaHr`0ltQj2ypYnV-pbER}Jt4+ql^I0<7&EoZNu|+l{RP04H0ZfYCi&DP2!> zJ4Yw2AaA>8L3+<^f?RAAZ3R?S0QUow@C4lKe8GSKH&=Hbr2wG7U%E>8=j(1s0l;4n zUl*Xjzf2kH8UWNiyzKz@B;>?xr0+@rCx|1}oA1r%`f_4QPel!QPa5)fGl4{rxaX+=dvNhujg85war zgt$+jyDvCE+}%g;KNK|Vd~Cd(Jbj%!+yU1V!PXvrzCZyyr~iuJ=Bcau--O+L{!3AK zl}QGGJtd_jq$J(kuI2g*?c@8@?*C=ue}(pW9_VQ&`P9zG!_V6WKOgpj|3Sv-crJy0DCM~V00D7o!Pvh=A1vyPADGh0v zd;h`JcK7iGyW80PXKW|@*#F{cKK#GpDye(hfqgx^pL=+?{>KUo96fwJd>lPI0qW}4 zv#tQRr32X^7x(VT$tlR*y(cbfi&w*4 zTRUrUMH^`;aeMo__A-i6_KLD#8-f4AxBWjf_^+knd+?HY{)Zu@dtg~PyK6$$_Y@Vx zrKRN+#TD*K-xXH`D@fn9wYRgkleZI)#Iq=QZ9M;nG5x0tZ=u(Z|Lq$1#(z7Pojcy6 zyz#CB`jvzxAjqZG)=+yMFumFA;3L?ZE*wCZ{C->@^{buTSEIu}vDn#Kj+vA4v(^b$ zh?~7Xaw9hA(=#2JuQfN*>%8n4KwZxh6Ze{)H9r{rlJdgoH_4lZm7-zsCCiK>iOR zYX1ZBe-ioseK;gN5J?(oa3e_HXxH~Jx0JBybmAf)F>IDA1QRtDKXKpUVvaVyw0+%F z$y{H5g1&I$Wc|*%KVAvce+9EeP=h9JRW_&G(-lQh#5aVO`TUF%-?`KgJNPZk8pL0T zx^PfGo^4;BRxvL-bo{G8(BZ9!WD)&|o^?)=hS#Q3xwA={Y=J5Q>&A?0i4;vEHN2?- z`USU^M71z;Nx7wg!LM?9m+{)ftFjcvywbV;PRZP-(1lY&B@}7@V5h@a2o2I0g2$BG zR1Q5-Ejw4@E1CS`&{M>h@9-e$(Y5YTC0~R_9`6l4>NFwAN=12uqq+q^eDF{AtsTsF z;4#T3@;)~-%suoT6Na@~CO!KXMS+mvQPH!AXP*8Y5P;|sYJ?!^5IKL12tFVP z8JakWGrE~@*dYLs$xqZmPpAh2sh@7^p7<$e@x@=;8GS z%F2XBgIYt7rDjt#*QNzxgRy?3VB#goO8VaZI(7WVjz?y-VP~tuc`(J*LrVL|e7yVhhuy>A_F{?#edoXckUj~C%^AgjqjF*V=!iG-*s z_uwDDDvj}`3zMj(g~z;iva8ydCTZb~f~&x`=_AqW)_iPPcq@oO!H?Q|C(T!I6{Tit zi7H^k>)^YUv!Z5SS$(lwidD+5M8UVF*O5-k{zdXTKBjX5-haI(S)ji0oL6jzyu9y`*xUDAQTjRO zi^YHa4$mQDpz%B}IRtWQRJhSUddShjTO%a}S11$Ax%N*Gn<;@FcTsh1)_@#Y{CV$s z5RFX!xEu3dV_dK5%=+%n)n7I4(N4Ac#3Lzf_}z3V)nC4z^OI8tGxS%Ds&)ifx0Uef z%WRCzGW|u{s%f9%3;Evu;4LLJt%ZB|fGR1%a^gQUBQx>>BWJ{7f(F_HMktN{#-5*`3Fi{yF!;z_Kkt8KxvkDCw59%(w?n4Y1?+qK zQ5I6u;_Zunjb(&fWX%QOv;F6&CJnPe4^HgH9>1){le~71hxJ7{Hrf|{tS~J0aL%NG zWJ@{}ZyeXN%c8odDC$r$*YWN<5}r@HF8A-0`Py*WUW$k|PN-IRyEc)R%~sYF%n1D} zLK1hLaN#@J$S;osWUlttPn*-sv7pnu{5_Vx5?q17(8_FwLMU-2SAgFJdZQ2cFqChO zc_iB6mW}f-!E2*DPAZU3ipFcfCbRK)+N?T=avE0r{g;5GC_d^i20!(``>XT6l0~07xd=yYC^mFB>W|HxKLY< zZ|Hq^(Oz|c%Pw@;_T^b;#R~=6<_#$JW9bZ`w+*FtVba)Uh5l1_Ck+-FvpgOkX)&Qc zA=gqCM|^G4=GM8x;RDV51FMGqHFM+@II~Qr(g0T_gUG`znC`@>O7X6Mg=K!J@cGMY z51MTo?unhotXg=lczF-Myc+4-^}aey7u)-6JlYLFPkvL0o85OoqI6Q==5akUlp*A> zkN`r2s;apQa_d?Q<(WJA;iQ*6plVi4Bp>eX=uc&bn_`39D ziEU9xVEi%U*vnRzPg97?Z0HQIS<@3_(K#Vn=)$Yf8e!Dc@;8z>%y-I=wA=4x%g2I$ zXZJKI;T@TQq?w*Nv()2e;mHTC5I)OovmTAP_GyCHvV{%Z;O5vlzYjCw*LI+g6m#F= zl0gG&vdJr&-;TpvSfJdHOnN;~V2{~S<< z=iC=T1~Hu5$zsoMkjPVLH!^QSL&pk+V3J`tkRVuKW~fQ z>+XW|vcFNwoJzzQIf#C;YGX^ecIRsSR5@J6s? zE$Rj_-Z^0scS$7W7n}CT0iGg0!&dn>vMe93#g~_APl_^rO-0oS>Rd=w&f^63<|elA zu7HP+R7*Z0HePmR*(cE0b`O9Ex)iLKD5ycl8|1A6?Uub|L~x|%uBw$oS?B&%{4*Dm zAXPtFb;fJlUvP`$!}2tjUZ4wxd9LM^9oDuq;tv1qMDuau#b(-~a~_IZ@n;!37d*<@ zy`}8`D#QslQ{tTuJ0c+&n%EH7zv`qccCACsMU?|%2UDkwsapv8gGVE0E&xx-@UDuF z-J?=eGLU#QW)oN5B;;mLx2jq}+J1THd$H)-Oi)o~vX-O=2|}Bu=~{bN4*i{O?Z{8| z7Rp0!?uzWG=9fwqZ~EtNRYIRCIdsXkWB!ENEFT}^iwH@;k^E;8x$Ec?ls&)eE%_)r zLKq9fE<5r{wnpXqaiN2b0u-tSfwO~h-`umR&>#61~_V63nSdY9e{Ir(c zYX#e}LF?pVr^sW=BAP5Cs@Wba>Fp(CNU9TF7hW1`ZjE&itHi6(^;0ri73*bt8El+n zu1&MQjAM#&Ec6K)v*DpXkyN#~!D{%@SEBeZz4@@!<~!EZ~OkhtyqXgwh@ zeFGbMUpXk4%doC}6&!L_)Hr7Od&517>G(RX6|(3}^NQjM>Qs%V21AJr1LYS;mIhzD zdpwvGQ(Qc#^g9o((&_yh5b{6)a*f>sAz%8g?3e3LgnI5zXhvehhh8KfyBN=@E^gQ* zBh9cmYD0SN7z&fMYcGCAlmv(FWs5YN4D6|zG>B~_l@B$xQO(q$#@vXyWnlX794MSL(lIz+s);~ya(&*LGF)Km8(%6DiG3?D)|eqrIVOd zWcQXYZfkSkSdco( zcw^`#8D6^(Y44xjMSpOBgRm_orpg!t^y$%S_p4CkWn&s<(~L2T!e~z4hzirc$eVX1 zcsgZ)58T!cX7kvG1uZUMs$6_ohp#5fG?!W^mJ=xBGk{^r-S0B|B=G@m08B$PN&YRE zs_2gw+e=(5e8^pt;T*4=(2cMv?~|#>+DC()@n|2Zo1!gqNiRf?)K;p;As=vNDex9j zfw`nS(dhY2Lk2&zdYH&5m+#DIqU2LHyj_2um+&hS$C1=W8|sB}VVOV>2r^0Hg0xIh ztg~miv}EqF>SNT$e_(IEdo|~|Lbxvyqk7&s&|ENRG;^i+oS(>ne?r-pZEV-8vhx>k z*Xs{h9tVrsd|vNmm}$e4631K~SxFPmpDp*z=S-%$E_qr$H%^cu`^x_`wvv};au}82 za64&H5$6dw%{d1mo*UJDG{?vHUO{cqJlnbv77?A8caWq3iqMvbE*FKk^y^^%{5=6R znl!_KA1Z3(!MSf2ZLwWJ%C^x0pY{qnWN&DkxN=^eY=HTB7g#taqkL|ZX8XZF~Kw#~7|xSBN^AkB07?i|$8Z z6?+HOyL2tHx(xp4Ucs<*gW|>z z?L*&Gb2w@#~o}vjgQ6u{TL7yS+%NxEe+Cd$|mhqM##3k)``u+tGboJ zUGuoQT2gH#-`K&v%A@1X)f9-VQKV&1-7#(e?hl|BfKX#F2iOm-)G~8jm%j4nK4SRA zbPP%oCejx8@C@&GE))M0m1X!(_nre|&gZ~stz>Og%Z12h$`Uf18KDNY?@)JBTTW^3 zep0KMVt?MnYMt)}J`U-{zo!`SuS0eZ0JAZT-!W^+F1FngrKnf4vDW@2YH^)r1YQq4eXs`l!`ee+^0v~NS6co33DKO^2%se-5O;}-?qBJkL z4HaGbHCI5a^NJF6;0pT13o6Qy?mki0 z6*Wm$rd^o#yGBmT7IPhF*R^K=M2=Nd%NI9hq2Fb5WQhT_l#x4 ze&C`1Y+0tiNToL30J!-rO%YW{tI6pTQ2mHq`KS)?7GXtzyWtu90g`QEcyu zKE3~gc^;!!yk-w_dB|v6*o(ZgnMN~RQSjhp?+rnlevCpz89A_4#!&bhfgXpJ7cRO|`v`^H6{NM{U*2fPb=~H<$o4w>IX<&XG)z3dA0hXP6xDW*#d@T)T8DrtY6FPjx&z3j;u35QY zbtK?kO!qhtXRB%U3}4SsOY}6smh<%{uH2XPJfEd+x%v+!UNW+t)TQ`|*wRM>-dI|t z;J!!NdhDfAfrgEY(Lz|>rlUtBv-JJGfS@@`wSyC%&_^P$52YZ!V!u`qd9@whXID3d zZMla37G`AP8BoK#_eYY(Ce8Ln4-~+0l%7~?+(>on_rCZt%#&p&lS-5-NbM{Jh>Uj# z;XtqnfFvIZ4KhizKs=4)<5PbR#Un<&S1F#hNKQ{xd;~Ho;xwoTwet;ulpz%HA76EQ<(oGZU*tUbgO!A4`iLf{h2if(elqzTt9iAX^!JnqQyQ5T zD-N>_KCFrzeDmx&EvYTWr_ak86zv)bHqoXf(oZFCVPkL8VYvQ+R0ChOR~XV}uHApC zAHUqq9@LtfScqG=xZ8uCxW_OnG&B`XI&npCc@b_W*d}4=VYoVqGZV_vX`AAsMC^6A6@1aqp#1w})rKnWq- zE)=%%uW*;ZZA9n{=mNqjP4j74`(U=2Igj${ISd~@vZLB!22|mIby)q0vgkx6KE-By zX3s+fqjUvzt?tp1J- zU60Kz!Zcma`jP3Z*QNd|^XN*cZ)u8R`r^Ln&-CH}ApLnIh440LwQ6{cN@kmj7yln^ z`B{h4Iklx>e1dscPUdpSK(b|vRRpM-#S|ue@3X5t&$KIwOFST%o3@cmItkOCxN=(-GxG~)t|Spb`rZ1Z=h@o+jfXf^ znIB2MMJIMLNi;+hwA%pu<;nIVDkH@`7DdV!6!KmaBkSd%_5j^|cKck+Wl%y7K!O>( zys|pMJ-#vVQOSpY&{J~s=6IvyoKlv4R8NN5>7@tVgSdoloWp~of#0$j?~8NhgMv%e za;O9jrVS!rV5eK;lTV0XDyeD$bCC=?p|e*VeWm`xu14ev{6!A?O}PGYtErLk-fd#7 zIm|e=g}1B0enKgI_|t8+&z0$O9l?3G>dE0tx*D5JhWOgc(mE^e!D1MJ%oU04Y=w?n!r)Yn zcCUrjJEv{pNolt3?$nSPt8|hBYu+n`4Rh_1NQw(?@b}BnP|v27bD!cFj>;h&z$TE| zZzZfP2;p|yS89^6tg>kXsDICN^||SPg*m}ECtbkLv5Wf!_B}QAx=886JE}yH}f#} zhm36ym)n!A89E0xv53DM62zgH-R%Nmigi!y`g9>W=FY1@{dvX*#je?dEQe)D&<7 z+>uMU#pG%U*adI4^J+K=a)BlEQZdJ^_NVx7rE@4Ws0k#`9Fz~QjkoYoN$1}{SJ101 zY0H$UZ5DmL9F8=gt$k17u{cJF>3`80Ua9K1zCpK65=v`9a?~>ynI-{ZL%u_qQ@1)S z!9=ND$fITXwcR-E#mKv$}+RSu2FR<~uRJtDKx0 z`O#0e9YT35Jz^)}?gG9OO^Pm4;yxZii(UuCwl%ViW4&nEDd5KoGg0~6W2r2TZppe;J?GT(xIl)KV)nJVsLrQsxf7Xp)VMe z-l4h?Q=uV96*yVm4e=w2$RC)ny&&qr?h3L#dlavL=-k9{wAS%VDU_0&^)4n`JX`bRGbpIR!fnv$x0 z;ei^5ex8lIrI;GR2HTGHu>cvu?9k5fxp6_Wpu$G&;6W)6;p5hf6}RcB+wqYoMwm)W z;~E8ujniKt+ReXb8H&x%cx4m z)Kfy0Iwm{#Yk)5@@1iPEZP7k`EgUYCS=}K{f{)524LE09eFObR1*Aq48wtY8wSC$= z@$H&;4{L_7pj)!jYFjg@{Ji31ox%7Y@81UAYHK8*)txj(*Q0Edt;mBlr#c3j=|dt| zEOP?{2K`2SheBL2YKHaOBX7X5I(5j{wp#kZZ|D|P;EBWTQ?!%u%31jk5Vk}3IL7)9 zXa%32v(Im8g?y$p^=p22tY^z{9yfs#@KJN*YHNi(@d{k^^3(IkhIh?6Yz^9YB`xwW z)N>JwluujY_ty0Q2jJx6dkj!cZ~ApkPosWv)7{0&TX8@>43;d7FwmePZ&tT2DG^-^P5?Xjx) zI@Ub7t&KQq0R>cC3i*LKgNHrVI0MT@<$r=&Q0mlG z3(b#Lj2My0nji@7^er4#uM#{|&7{Qjz%^<>)#~Jo2fx`@Ko@F}A(kL@SOv90=(<)6 z7UV^5_CNX&DaubBameWV>lF9HY<813S-6Yktgwca7 zu{EUDs^Q$$(TW+WVlFOzAa}lT5|yYh-lVfe>QIh{kz@@NUxg3UjF(H(PF)wFlLIC{ zkIa3JO!x6?(DU<;wdnv`BE7Y305$Z%ni$`H=BXoBiJ#HU`}u2(F=*8ZpPmdmpb~!x zOob-#cz^UzxoKNx;o`$X?#8Pmt6XT#hGan5ZRf~jp3U%II_1A0;&*cthc80&xE)!~ zJ%-y*is47(IIkeI`hu*2C#v@se>aen^UP zM!VYF{Eo@cI9EzTmR$D6*ug+#6 z;a7g&)eQF;XuB1d<99V}K9^TM<58lE+NzN1ZnyhjG$huMJRh(^JSxS;uL-jt`KoW~ z_%riIv47}I)d$$UcjQ^a{W5H@*WY=2DyNL@~`IVpTTz)agUt5_Dm+tV>pjjkPD8eUx6K0W1&Yp z$@OMyyguYvQOWE{ULM{**mZHSK_KI&EXulSat?V^2$dMoO3R8=q`>jNt-v zY>anw`b;S~Y1NanAp#)W?jWy@(Md5y^D=CfhB_05wJ=iIUmfh)@K6J+jSk3PCntqA4Gy6ZB@NMj;(EgUIuYk?VRDCyU-XN-o4Q) zERda(yWtML-oLDSC0746=NAT(H$J`p)Hgseeo{LZTWs?z=P?74F|dbtJQAl_Fx@BN z{Yk5Is7=R{=f|6e3h}7yI2Gg7mUZ`tUyq&@>+*sFUHe=H*~-rWe2yCwpoz#>hn95y zi5!EF@4p18vvvmkTUU4FsgAQt4T4_{`;t7JOKW06$P+iSzLTw&+o1F+$$R;H17Qd4 z(luT&`^+yE3CMwGBwmng98)Y|6+tC*B17RQ4yyBL_)$$H1<(tG6MD@k_L|t$&)!j- z^;DuKXQ~AHSwlgMVaS@TQ;~^-xWf%_z!*S*-VdZ$RKJkXSksO0z*0I^On?z=&z`L5 z&0>*z35FiGb{WalZKz1qVk*qRlsL5(Y3_yZX$~J_koB!dl!x^v z%rcgahL;oEPddDTk3><+m%zAw46kt}!%e%CR>WaEf_#50SM>(`7t9*#h5w@HD= zhHAy|_8`bhAg7ucV`wVwqxbxyANF1CFwp2}EP!Inc->19U(fp>0-D0S9+GFn?xP-}Sg=PB&6T8f2sQpBg10RHJKJ zthP9ult|##RIH8GYn3RjS%VxhU%t+~aorc~Y6l%S=JZB%8ifc2sK$z|!MsPQZU8uQ z!J6<+B{_8D$J_q0kB+;tVrr$g$+cj46bR_a4`K#n9dt{-!hVajp|P)}YA^E_?t07H zS;(*@=sw2B3yo=}vG!xhey}FdTKl23yM@Cg*=bhC2J@Cd1muy7GFNVnzvs5j^TT>_ z2VYUq8}gUY<1%jGx(`$Cb&e?Qu&8gV+!gCDK7> z9ogk5%<^4uiFjHOsh3Q@KH%sLT{wV(wueQYN+sN}o1e{`?B>E(+YDXEKJ;r2uK##u z{dByK_o0!%T9D+6fa^m%-5uSP-4C~u6-)N3-EVmiEJ#4)UKz;X?_VU&vl~_n-^P(F z5Hg$uFE#P?7KJ1qnK7IW1NI9IZsGAi7$Q?owGQe=Oyw$)x>#T14KgwEg={y# zTi#ve>nNuKPlG6>Xn9}8?mgwvK-pr=lm?1sj$0r>9BVtH}gFSuO9s)&1RPU8c{l9x=g>m>a>XwA!!z6xJUc>vql2Zvy5hi2HLWZj~a z8<$ihLrSs{1}B-O(*y*no4h_pq56!dLaNSe2ZW|C9Q=6xNp93e*(FE0S=I$O7V7Cy;bEk zJDRuTzXuy){8}2KQsFJRAnmf1Id1A1uD;J5-6QUM&ywK{XlMxebN?q!>@DH&TY|}s<#Z>fc z1b&T~ty?NFeYN|iWb#U|UKOtOwWdcV>BjVhR>M@>(N)EToY0H7x7Hh-vM3sA3?jF)Wu^04^dr_!I^Ll&fWwHU`CoCSd zAA9;@?*Z7_jhi3TuOZjQ|H0tIKkYWKHRLPC_o!n>U!Wy+U4B-8h9 zHI1^8-S|l*sR@#Tzy+LFZ{?k6&AW9lc`=325oN`Q<=q%{ocCu?Y8I*H#@8w5&}`#q z{N86ye|d@*bKj;z;f82Vw2QGIYu_vA&{V$>hs~$BGU}hWBQHsgry;Lozcc+2Mu#z; z-k6?bfQ{XwNdEAt$aYJp(ssOje0K-;kywag4B($JYNtirk!DJ-9JsNFzeorag_e9S zKCvhQ=cpkS3*T!!QTrnEEQs8NYXeYu47XLQMBHc~x9*j(hA85~^5H`Pb>(xsi!^95 zRhqjeKD6NNVe6};-xp#-!qLmcW;^z73t6cCG)3V%P9W6^24?Qcl_xhI|CZ%7i4iG% zB*ES=4G*FSVb$1*ia~!;AZwGO{gken{p!U?pR9D`@Gp8oc?bU2Lrk|J`zsXhwy#Ny|{#0p`G!9$9-*q*%Khp8ifTQ1(;w0(hadxc;5 zpeJSYQ@i?)+Ng~b& zpcm|Cv&`j95~t+UAwqJxwCS)vOBW=?*fZlKa9UEwos|~Jhv{e9)M?Yqn->YB5#GOC5c$XKBpY@O!nBQ-0jV(BvuSu`8KF6z1YSOO12e$Lw#is8rPUTDPXYsTNGjW$PpYPJ^q# zpYQXNRke%o59Eda3X#^E9R*Je>`XDRr04bQKY$cD5Vb}bJj-4hg73Y|z2g#Jx>SniRe_8!OMA5i~Gi#(@ffXqBb$i>IBS;%C zMn}aY^ptA#%7MDX?pf7UY9%UKtbS|6G;An)fDSZZJK#EqKs}d%P>{5)pp!ER31!o$POtCyWgn$+&N ze}V_wbV7$`&DQEC4Lv-bNiN)7dIpBf{jwPbYaSbsQ5eZkC!kR?1rQzpWt!4?^ER zMfpZq$9D}2Q*KQya{R(GK8i`-&1 zbM%X=f+?EAcZyAc#x$}&NmXt5z22?@d9fqj>J^1;gWuJ8>$)~84sKHa+-hKUiUL8X ztDPK=EWh75`SmBBZN>A;)J*u+vvos7(3#y{0D`c-@ z;LA-Y#yz~xxtZ9^o?FOvOylx2{aF&zQM5>K5c~2lD|)lTZ}ZA#Gb*vi(X>)(ECKxa z-saCPt)C@z9zjn&ME~3lbwT8AC>)*F!_}m16o?Zyue6(152cfAIdE3WMKFt)yLm|6!vrXOR$DHSwd zs4fY}SBKHF&PNfK$5wSa7g@X%oRRf;yMa%V^=+-n1W99p)R;&43s1I<<5M-b_zyq_ z%0c);WH(dsgAPY^VSX+6CV$eZ1wlm!U4JL#g&I%at=OFOHtOX1Zi=uU8$`v)PvL&P zvu8n`*8CzukO($wx^`FD$`Ahh37Pkw4>#}-QL+eX#`K0|PrHA;=Ssu+nfa%Y0`Z)c z`13v$-XN$-2V#zRG5 zmn{W;$yC-TKDn4d*$eLxPzv|nB_qNTVo5Q3T}muMt@#N$r*l?&%=<(v`uc3_uL5a` z&^n_kUw@hcE0QZ(!b2{}NG=IGPw3{%+){E{*J#QGZ#lg8p*z*tyvm;JcxHH3>~9D~ z#{?wtV}xBQL=-5gnd)fN3+Pkob-BRXgpdtb;+F<;~a zd-UR<)<^hI=7|!l#2Si;=Qm!Qd+;9E-lkj%p5u)w20lFQSU;6ua^^;Ve}c>TR5(TD zf?@MKiWc|P5u4x08N>RENBp|D^2u3&Qs~~?aLax-RG^Kx;2v*qsFo#eV)g7S-9Br5 z@HGT3+jcQ*ukEBj9Jm=G$80m2RX3UcX-$P@?BpzZ7rGsZvIOb5n#NborUHE5D7p}h z%4Na_Z8QA_f-J}KAoP=^m5yNNUq%ehM#2QkA3{2x<|L)qU5abvRLF~wNk|=0xLWWvL(?5^Z!9R6(5oah34gn*XL=BwzXIJE_EZbaMIEmxb zS!4m8>u9-gr!PD`2!m*>i5od8MkEmHe4|Xvvr?7Hz96Sg?NWMiTRC!Kf#fWIj8E2& zNoiviCn!9T7^m2i?w~!}U!c@=Lp)?^3%|Ggszm^_%~@2y;?(mD;A5GpkZD9&RZmDQ z&TL;*W_GJP7H5*a%~sY1AHH9j((&@4_^&M4YC~Fu-K`XO)^;NRGWd_9O3J8GeuTir zut#yvJ0V6>#sNoLwZct*L{()?g%->Q4W1Pm za329|m=x)?8H18OLE1UtEYVi@mp7tNQ*Q#41ollDgWp=;9vLz6LgjR}l74NJGHVH^ zQ6}{Y9DYV!`eU}I@=H1@D?xLc#|4*f>R&`u=}SiTK*Psath>*0_uOQ54gALP!Ae+s zPg826Yr25T$tU=3QB=KT&Ryg9-M%(y#T;@Y&(>GLf$^)=KqKB?Z9kmTLJM_$Rd;Ya$=irf5eoByj zW1}#ZrOpnaVz~BlNqj)Gg^{uMMSBAIFpd%myrOz)RT_obC+QZ>G%ncaTT z^iNd6`+EvRE?(`NTxPeQN2{PWTvA>rdcys9SGfjlu2kW6E#djO6Ne?K%eR5v68b*? zI_?uz+?{DMCu_JTZ4cPHryP|LIE}KJn|;-sn~N>N8%-`07&KPYxEMD*Ku~0KDVVY*Xbe?s;BKbXM#@15tK8U@mpG<{0*?Cy<9f_QkKX=LHTTtX#ycz;M6rWGH_xvJ-1W{EW zTw=;?Ct%aICSj&G39b2|d37%SI>KN&WL}0_1jD!x=^%El+FJAme$#O>J&b z^F!SCCd{HSa)84}^)*HAepAMi)Y~?8PL!1q`?O>aur-{SUcCoGT9|yc#=aUj>P*HO zAu=s$)I)=qcvl=qwD-9`r1#g);x}UBp09HN*fGQ=3aCxpOkS1~nyKF)rmg&&{WN*Z z@LTW2Fxku9%ZyE$$6HY24ZY4h0IuNm9CMP3-ONFR(A%kp6d~{1LBpSn8F*fxH4s(O zaq3UY`?)B(pphS$F`yHQJtgUT00DM&bX#B;{eq>a)*tm`9xp91(NE=0WZQyiAB%oB zHeD%CUTuoEkQF^g^o5&KQ-0w6aa>9Fsdg`PWU-56^p*1n*U4}cV?}qYm{Ys<0mG8q zA6FK!`e~rQip`jCd&ONlN{vfKa>HKFR-jHXYgV^)dXS~9$!aOUr>e^51N_MBFi)g1 z&H+jA$^Tj3CY+aHmD#ZEI3&BqAlEDHr}4M?vOso#O#n~j{6%R)tiGVoz{zTJx{AEX zZ6?r}z(MH)NxIILq=?nhNfGk$yBS^zH)M+~{;{Y@RtON&k*E@?A&$?fk~s1+EA8aB z?Rp2V?03e6Ew?Tndr7Qh{z}jjKA1e6j;AmuD)ea^@E^uD)8emU{?6KdI8N!}e&b!k zsl~QBTA&`3OU>^DQN2>?+S`vy70Kcz~z;gIBvs&xfNQ z3-mV+f8*+!aHh`nLDlgWq@jOJ?S!mx6yn5w&C(fF=+{1YZ1H)YQ|ME(_hE<+|4QN` zh3{|)--e%64o*nBp#lGNeaei*?;!kZUYlqCG$I4X0$GDpZO62#|BTCU)}Z2V3;F&y zJrblg2O+B%hk>}vaiN%%I~k2GQ@qrn@qYgd`!5u~s3X)|qt$vKJ>ja_Pnvv6^!8<- ztR(ry$ehg!<@%K-A$8L=-#VOGNYw=}d!R!^uFGtL} zRKQ=~QCB80xIev==$3}Hh=RPlb0~n>!`@uuD*{99rM7l2SWl5~{~l38bLMaR6c{@r zKGu#&zp;-HXPVso9NZIaFO0^T>rGiomy2)6p-E5}e!X$muHHzUi2L_0Yx?P{A!B=S z-&*M5Y6DrrZBW?|=!#(Yp&)SE29#uEZs^~KODF)h<* z6A~^pBQMVjj0?!lk~1CXnD0axRY7#Pv}am*LzLUo-}oVJ)CEaDBsjU6C}Oj(zmCb+f; z_>`H_VBVv>1EF-VX}Y#cB850T`%yU|?$UHuN#e{k9&T}ciNr9i`*Ua~CcHk(Pmo0T z*DG~uusHwB<97yU7fR)}?Z^hLSN{(H??4d0)omar<#NxZ^oDB=x=_tQYRJtcOXWY$ zm(E!>_kT|NzwJDe$k|ECLQgB9A4f~Vrh9}_y_&I5AEB$qL-(Bd%+f%czPy3Sa(6=9(^ekoa~kjW?T`x;iR z@(pf;vh#O=a)woXzra9jAf{lE7bjC7GPI`9raSZ#f7p<|=)i2-NRB7Hcb4Gy?KFmBl0$b?93&c-H-dYH@-%z z6jVKUo<5yzE!xkr*snGO{A^9&UiX{a?pb}7oPp2_WmtQ^I_~r}hBcG`pT?a{>;6!U zXcP^*2%4;M<`Z;>^gw9&B(IyN>(=SIW?>M0vk09J*jsG+RG+t4BJ|%L2o9Opu`q4z zDpznXtW1tuRSVPF&cg_V*;S)zh4d4;pMxzCdQ~Vya$^|p8{yNq%vywgg;m|CONo7U z{h>{tu1`+a?@ref2(xD50G6lE+x-#WTg4K7YoYHzC^^yeRiVrkaUjR>e2=38CR}_T z`e2!lMfX~Sp3P@T#mt}QZp!6)nk@9e$U+}%kWY`=ZK214FKrJ$w$77?q30q}AAxoL z<>~q}4nZ?PSNl8M`;l{! zgq}?ceH3S44kR^b3ZGnsB8-NcP-thXw9s>x5IWaEy$V$$gic?78i${7dQehD|I9Mq zfd=b@(W*H19{%PQ-XH3)UAP}Tad7c;Ex=OWy<%VHBSOD}gE@)ADqL;V-2|c2tCQhVJLKB)%Gr@DnTWg$VjRzlyikj%T&h?U-m%bglT60=~NLFj&MeYo*S)Ckf_ z-?k8AYDJv2bb*qRH)Ug2?nhU&-hh;+K{VA`=>GpbPvN-;y(+me2137s`&}@3jC_w{ldTgW3Bmt~%56tMrtE!0yN ztbt7HEb6@;kA&=dvPtj_*#eV z?0($Fvv~(=W4B6Wi3hW?S&(o(invb$b~bJ(t1g?w)Q7!40&*|nT&U9HV)RAa(g>N; zLXXLOx84ucNSuUzezw|7le;ah8&9I>KL(Q)S`}s>p%tLy%M<=Zls>bI_GQ76t_GN ztO(ez!HePda};EL14_XLewRvkLafyV{u2nbQQek~AS!xY#v)Rmt~f*8E@w(0Z_l^! zQq9jGCkE=g-=&Dq-3Zx?$h>YOl@yo8I&=!5KD;J1przGW{rTuw(e2)Azm21d*v~%y zV+*yNBUS!CX0AF}Ekw^-gkC;JF3cW7nE5>#(rxJ&LU%BhJ_GA>16E@_Qw%#1V<7Y2 zpRO;g?4|0h^PW>)??i;Y*XVt2gwW~A+_%=olxrn)x~P+~(Bu01Rwc!q=W^#YsYT<( zR=St2eE^~N<9S`?LLY+G{RxEGG4}SBZs&gpde3P04vAmky$HRth<(69vlI_mZR2Na z*1Db>X+=K>+?Cls;B}@BLeEEB*l4GPz8wk9v=Mrx)s>{n-7L%xZe`L) z5!b>Y3XJh;mho@lE<%qIJe=Ln9$9G8v_q+)vTE5H>`>VVq3=hpX^ycl-keYPGuAz`wt;8WXJ!8`$fvA(O9V*>eh;o= zP2pbl)N!6THINku`A9LyokL1O{e;dr7QG-4uB*H%!;$s)21@O4i)CF}K$%PLlw0M~ zxF7Xazr7XWK08T#;7)D*T8-yh_`gL&3*D37i4 zk`Z%}Wj6~!_7&D6tG&X=dPC9J=(@+|LGW!MAW84p`@ys7v=tfzJJXP!vw_piYDJ5Z{pVX+awBsT5 zL`1la&)$edupbHbWebTytx!z*@wY~CJzFC5b1n2r<;%5Uk6F!GNObAFLbL9Vl)x1W zo#UQch=X+!a=0(EAn{G*lK z#(BFs7otBhR_Nv8q)G1oy$+KbgHZb28vi56{7yvXR-?QvR2UC_A79{g2hSt1##KED z3xl)@DNfWHhJZO~kkI3#xV1=0Xf{YPPUg(qUNaH;Rf?xSt3?R357E7=7XEK<;Q$^- zhjYU^E1uW`3+{7}`PaDa!3Mk}F7!S3;1@iDJ#ERBg9gYV2xKl&R;!VpeUXy4kM*-P zFtd;d?k=7|L4HbWo>u*x?fJGLSNvsUXrQ9?h7UeoM)AqkGbl3uhB7j5)_ ze8jqCt!WQhfKoDr12zv$S()ya@6&A@qL&x>PK{r+8p zLUh|gNlCSe;WV^(i^%XbEcM-t-IpR1(%bMdeFY2sF3w55&U@`%D~}WY)yi@6HEqGv zc&SQwwv#vmGgf^~bsuEtUC8@>5aKU51Mf0M=mp#d-~TtU_rJjTp0@g{mYmEzZ^WxQ zzHOyKn*^aBK>OIWkkOYmLhp|(vT+Ne>KY*k_E2BJ!#Zlw1{|_5;&42&FonzaDjQ>>;?|)h*j4tg`|EHT0N5?NAa^=3sc&%V4b@K{t!aUE%MJT%y{mtQ$gQ^aCb8Q z3y6LD0?&!iI?yAz4Y_d*O56+3(#z?&CNMJ>Y`P3|Z$>P)>aRKf(ULkMlfG z=l(y2;o#+&{}X3m;es=e_<2a8Y;7NcY}?M(_@>2b%!33u=bE*Djbtb@XMowyo7TD* zdXI&A(n)MQS?JY2uXhka!yvUo?2B2uy4O21gJ&%CH6OzN8^HVLQ1BREyB0_&))pvobyuX}G=gQJgAoTBW-VRK4=IzE2)-J5a@knvI3sN7uLYAc*`wSNPcmwzM5ajJ1i@)Ox{1WZ| zR9onA41GUZSH&dT@h}-fpN1eFOwg)j>)TR`uEnq^$8cSF)4c9lz%rg6?Q9c{39Ej3 z5|yiQSUE@7Q?3-;fs*HoV-Z){e9fgu38Yo#!k8Vz?pi44YvjHzgV5Op>mxj2X)bH+ zMyx{dWOvJ>I>?NzflnZR*kXAO=gTWV7NO8BwwchG*y{WLdUOW-ygtVMzuf?tlLuC? z_n%__FGRArCCY44G4z9o(2t`Bo)$vyi>#8-hzOI~EbYkh=UCXhbyjnSR$v_mZ^yzE zv0K<1wPM6Vo$4)Ey-s9rLGnlVd+iix{SaPHV2#|iP$_ZE!o2u;abRJ(-3wg%ik+=D zmvx>V96;IJwa^}R3j4U8y)_5x{3d?K2ax(R3;oO2+kDM_KJUX4e}a8KfzLjQGth|Q z>0a7*u*hFPiD`Mig(NKW0|>@#tPu-?L()R%{T8y^C$agGnvYI5)|OS@Cp;-aXSViO zWCcoaR(JS(Em=qqnzWGQldp3B<}4(}83YCi{bl5>%EKZ$Ip-Ob&QTC+_1K*Eb?nVy z$1AU`{lR21@5gH$fTFh7qO_6PDF|=M@?5F%UI7oga30E`{A91 z*n9!xzTU$9A78@_5V?n!yn^F%D6>P>SVOQ<#%r8^a#Z89nSC%=7yb={I_Q_Ox0&m&>> zGpxULZLdt=4W8W~_7lq$C$0AW11#?xjO1X^LS@LBg(T|jXy21RY8?d~_emdsjE~Pi zkA-GQ4{-)Rh2ot=XHUw0Cv(pm`3Dr**WiMdheDIG(Dx%UN!ut@_NS)M8%WrDz|7GV zXuLTKG5Ti54Tm9|?^x&!d@Mq*32PvsP3+$t2%*Uae&>LNOkfVUShdgx+hffiEKGvq zh}PX2pBRp_(P3#Rn3-j<~t>FwTS?$$A1q;b|(-x9jxi~OuJlg*=mfXyZeG7w! z+$#SSWWL@m?^IHR9$V-KDLc$;j6mVX{=`YT+}9!4-dc!j7n^)tC1{x*4}D^x3)h~> z)mbYkJ;$><#9kSTygBtemjZr=3mPWP9Yw;-_sR=cvhT4kmmu)io%Sj!hKw{5N;d;nLmO&yn|ONCH>LfXCh#u`=5O+ zp1~^r5prbS!r-P%5&Cfjp|ev^BOTb9P3ryFXe={IBBAU6oAh;s5FKsuH8C^$K0X6o zxXY4JH7jJaO#We^3@s0#z&KmKRUcPp+_17S#SETRoRD)1uk2^Ah0k&op$}k>u@&%L z{4O@knN0XTomg;>uD}v^q5K`zua=z}eBrmxbswZegQtk^#S_C;U@?(b%V=3 z_MxbKhv&Tm<&cVJF`<1l4!PNHp_FpXLJk&rB)0lvLx#jY5Un`rd9q3OhmE7&L-}Ee z+A}C7ZSNGBgn(j02|kFl#n3C=K^#HKrV5RAcw_JCB|Pk9J3EA;nTpDQh56MtAt3n%pJkpN?ZmXiyF*?G!otfcl?{p~8R0$q&1L>9>_ zkomSL%+m?TTgWM4vgQ*gnFH8c{R#aY_R%?;@jjzWbuEDkRvjYG)z7a;TR z@ctdXzn2C>wvh`jMTEX*XWfN|Dc-Pjhfm^_O=0Q{6I5F0Ozwy$6E%y_ixws(-Ga6| zj?ZvjiIi~lvy4aL`g7fk_PARr(-z#1B-DDW^kRzd1JA=zq_94RHR8hTFL?jKe%nG> zQ`EAp(6XeH@$7XAV}sWs3%Dm*_3#dd!=!cpv$NzelvP(;e}zK(orMI@`U)i$nHvH^4lvcCjabcn{+I;EQ|&|v@j~z724Y{9+C<}rE&isV(&AFkFNFC z7LsUJ(k5S%co@`Vm@vTJ)oE<^$X?vT5&3OKT3932%t5qjt*1;%Ss8|+GGw8qSzYAn z#|94Y9tdm-Wc~%7yL&?hI`rDvP0xw^C%i7<`^$E5jja^O&H>93_iz@R%so!cMnwZD zwz3<=HZ1U8LFPYz#MdJ4Me6o{QWpANg@w8gA}OToAu)c=vZN_|W;Qx##680rX3m1% z0>QQl{Wx&yhQn_$lM%Kf_Ad)^_OH{eOhLLAl0$4Z9%v8x}%-Y$sgE$Qd|@ z_WwGr$M^qx3!bT`kfo_dQiQ%^A(>()ve45AW<#24aDU|yAi3cT1cSkYXPDA zwakHJ7V-C0lb$>_p}iklh^;ZUeh;fZLxk?v<8g78p^?--U@gE(6ND1v`vSOQ4a%PH zc`xnsMl^R}#Z%^`y^Pigoeg51<7~$bpxDJR6G+PCzKff{_I_zijLSuCqG1b7V3JDg zV62HQsu?@mp{SYQM6F{Btwmo;1|`0Kj&R6n#ZFl0mA-AEoMtWq*W>5b8g;HDD6XGx{4=5=M zo$XJVG?T_|aRgfix)wQQXUD0YG`KnTBDc)~EI0Pk?rZXO^+(DH`wLIwdYPoCgr&v> z0QWmX8SFi4qM5iZ|v+)uIBW(P!mKa%}vl{K8b!E^dOh@5La%MYk0p@$rk*){}6T3s#iKnun` z+1vdjfz7gSVUo~}o$dP7Z0*^>R;7$*4Z&+5GH)JMEQD@Yv(0god=|{v7>pKkD|#Y= z=eSj?Ao`2WT}<95k@1B&K)*+hGFt;?RQ2vK{#Z97Hn|5y_r~CJ7?; z=742hi;+jh_ty-p_1o~+kl4p94Dw-zxBNL4e7-_J#zY=>my5e>aX`;5KG#CD-dpG! zziuIue-nRC`$MP|BNk>Luv1%_NWB#8ZI+;V2K&E*(3v-q`4Zn|j1lFC$XyFFXLBjL z=0OP5>Bx#ITI0QV99C{ozC2X`%u)b+ji0c8HhLbkqo6bMNe5F-((_eaWUnox?2 zPA7D)-uTwa;iis3(urC}7UGC>H&a_n3#rrc;n+!bR!br)nWao0A*9_RyJ4+Qsu%>J zU&mU;vr&Rm>xIaCbnllfl(vmV7CJ5Zp2%A7i7fVf#U3M}AKF>>I^WYm--jZ{j#rD= zo7x9Lk{r@+Ay=qBg%-L+3NU-7tU$5txQCInw#I~^EeMp#q@Ofsl(dT6N@ol`U-571 zaXp^c*%799VIj4e(EB2VWd`KFjg2g{9)9l^aQ`_(r9ZO1Ij*u;1)-PhY@D309E?PA zrvPKaBaWq%hek*e4DStAD5h!h%Elq8cnD0#O{Q!{DHREA!9si0p%iIs`3llwa@?SW zO!s;ToiQ4Yl6?oOsMSQ;hwGYyQsLSt6QWd8+}-OurEHI}A3gKD(%AScb%f4oRh~ik5=5D|WNW>X z+>lHhV;fkO+%;mwP}pu;aB(ifLTXjlxFQZ2-LFpM?)p_-dV8z`S_svGdn9)Wp~od@ zg3u1joN|Um48xdw&wM@F+JyB`NlI>OPRui*{ zH!UOyHk;53@HkB4T3+C53IA*$ChFV;N`fG?n>#q<%H=0ZWP2;*Yg&|Q#?P5BdT1S( z6xs|6eIv34-Q{~d81gASPcGLN zEtGJsnOyEyf-NOo19}f)+)J_6=9cm}2#=QZn*@n&3-=)pi`iZ7vu(Iek8yos<&eT5 zHuby+T@Zvi4ThqH93)PyOl$9U4$k6?3lVw^H|`ju&dllqOLrSsx}}}apCxQP`zHE` zS6a%Swc$Elk$8yDLCbu#6F0OV2raSDi?GP!_StEb^Q=Bvfg$q|+|+R;oXsHg5=eXv zYXg>Qe+nOX0R-;LT{7(Cl~k;mu5I@E{sbH9QKad%Vl(@pdjJK-pUpO`_3h~22!bF~ zD>t3QJ$62a*I`SqC)SNjHdty`DRCwVJqEj`t%1;nEOf?7W1NL8IaxQKbZg8dY^FDO z9f6Y5=sfnTkh9S6!S6fU(!RAYOoz40f*=Uhz+>nhJ9n?+thFZDw^0jyH6rtlly}W0 z)+_Z9@9TI-yX1h3(Jn&x#>f&;_YC9Y%9?Cx!Dk-oIx#x_`ogDJch zy&&38@VSp*O)n-y=$ym*GY-Ung{f$*P;l6F%>Ukf5IAcw86HuRoFE7n8E8F_RZij_ zJD-Jt(38T?dtza(fma%N?$Qbfy<>BRn)x6~uy9|4yrwM-3`y&Tb+UVG<*)$fx;we= zB=Gwget3iX;8yazHfXi|7COjn!V}?f^|vB)L8w_tHtUY0Qnv7R*>&AQ+&rJs&&wfU zYasNGFj_kLSv8x`8L#NIFiP}citopmg&xK0(CA)aQ#1& z+%->kwZF8oOX;J9In?#y#6lSxhu1iX-nWoYQfR?_$w$}u5ZB4t%tLJY6I0f^AXIC( z6krH2j?7;CM;&AlG9>9T{A`y@CRJ!~##vu|x z5YC<*=G%Cw>!+vd3oCourlZ#nFko0wvI7}%l#y%f$F;ck;U1Kiv}U%m1edc!mhsv( z@~f3D_dSr-v#rwzmUrETmPgM*QlM-51C*R~Yfp2RLUgUS@N5=vtsn6@E748m zI)ZQ!*^T4OJciYJ6LM`7Kf4R1ecnPM>_^K^6Q^Ft=KTN#()?DR1l*mVnC@|gFqeGZum zLN|j6rJq}Qf}+cb8OXIs5dAiY++Fa$SSX3jL6J|pLhR)2_2!S@eYgd=m{zd%e9=M@ zTvwr$gwA=iZ=vx`VDnE|Iuk4UEyVe0NqbY6*C4q@4nqa<>cJh#s6#55+NdeiO2x=K?GD z8kAu+*qVp6ORwAlzPF#UYb`=4@y~h}@6+sZcX_o0S^5(9RfOIo97p7^j#susl0>%ZHVFL~hoANDvlhBfwZg?+z#$&Q!DVN= zJ?xeDczy@6(1k9;AS_h3#=o+1O!*VYv8z0c{T9ZJl6dA|mA|pja(WPC#Qc?GYrPAe z^2QYxj#<88>7Btrql)9H-@`h816j4-O`EhG7CPh6i?GtOknzc>Xg9EyEi{Ko0&KQZ zf`#sX<1RMnsI{jX(-?#m%hq_%cf0M72m%QCHpu+XR<1jrv--k?{ZI@zagnb#K}K#} zezfGuWNU#N6vGyJw$DY1NSeVasuft~%yRE4!=u%m;+Tc#gt&?uzF(nfu;_wrM5c`3Tsy&g zIPW3I{2y3bZ6I{_63pVp@= zz_F@J&_-Wl6HP%oOk)?K-e{vASZIy|g=0i>XyDV+Us}($w5lT zO}OSEob~IF%OjTFiE0J|i{4U}L+^I$rtN9tVc7wpzqGPTc^D*_M)yw6LM*!v8v86h z?|g!PgE<6SP#TtSpqQZ2&Ve?r(A>i-^C8$*VABMlvoH=ab<6x;tsH6_vgY^9;8Zhu zp_cHV-{S3>?-%xLPCmS>Oxj6@;(rl zE79(a`ZLy_taURda*&Aw70UD;lzcY4$|ZQ+1^ixDAUqMyUG8(%`aT%7;>f~?)Tb~G zmt>*0PqVUUBYke!X(u`jLf-=ce{bdPM9pZr;v3ZaKu=o8w4Jl|HhAE;NO}~8aF}*X z5V8w*ao@xla~JzJP~O`;KxznQjr}i@oa>#B429cRvl$?B!tcii3*~-m*2T@Q+DYh# z*r0CZF2ce)%E*0lFTx`WapYZGLnDNCQDWIXG*Bn=LHxU62%mOg00)22LPtG%Dz?N6 zLIzQUqVBC+J!bv~obmA#d^S$0q+5AAL0K6m{BmO4gr$23OKhQU;=ZtU-(_*vdI{U< zazBhnokQr~;ZUWud@a_Php_RT$UF;`orx|Z=X$V*dvjo6TGJRT_Wm~AC%Oc$V-J<0 zXZgZHOWz|Cgmk0dLhbbzAo4%LLT_h76;{3YS$YNw)RW>?aL$sFF@reApWyo4BQa&^ z9cvxmpLLM@~bj zgIL?;e$T;D-vW8}K^VNpL1RZfK}aj;YJOs2a@wO5kohXkkGqrq3Q}K;l;xxpdFOx` z5c+2p2F;|kXFFTs(vbQHuZ5ajrHIg($vFm6cx34=W2@9~onRkW7=^lI$!A(Rp|61~ zU*X{OV72q`G3!4E!QjH+I~=+-5xS6ajDyVo8P@rA$f0(VmdlVIt(+A5SIEaTYfh;e zr^nrmWN=zRGUw2!RXf{AMueUM?1H2?(WnQOUKV-?_kz$rg<^6NZMY;|?=^L3v&wo z>2&=b3VAy-yJ-mc8Sy-npRDZZ`n#3g?nzqaeHOZNQjxi9+3<)S;C{I0;xF)AaJ;h! zJwzQf-g!D5Yi8lLAklre+w^pd-0_J>5b=gFk6@X93M+ji1)t4j-XhM+3k!)}NxRwIqxTp@{$H#dav0Chb99dQ9tzKU zcrFy$vvjre%ULKxSjTc#%4D?R)0p|rwy;j%a~8%84(b#LfW+Ji=Vj6*m9kH!c- zOECp|>Uv}avHKsJ<$N@`$AtEPl^ITCf5J*j&GjzMwG;WzFbYd#(+8YCKwecK-Po8kom599ftHF9=DWOLjo>b25ap zK{EdrE0?CVTkdgU7;|IX#r`)~=^qm$^g?t$9$1*`{vZR-l2aXBUcAD6`o)rKyDdU* zvZlI#4Lt`!xCTo!?HC2AKe8|(>Af|tq{0vUuOMwsfpd4_Z3wY;m!7x~<%GH%$lULb z$GtobwrFZZBQysm7W$Ikf(&ta@&u%QD+Ql12cp`9oOlY$^QnboucXii`7{OjbO+vv zEPxZ$mSB~?f~*rVK~(-Qe5?Hl}(GL&nLSp1q{N^4f=3 zlNoxJJCO(D2fWwJh>Q@rKd2QDI^(cT=GQI#?FcDEN+9rUY{peZDMx^d`vl zKndx!koCR<(%phKew5%rjcZa}!!P2H_E?BfbAnX64sTpqcLUFq&u|1*`wMt9*6^ys zD%7*jCSiTgg3RyZ^>fIOGz}c#h-43$eQV{c?dO(!(x~4T_mX+I!86-EcK!hODJx}a ztGHJ`!%BCL#;&$}HV8c)+_D61l`U1rE&XL|Jvb;+P)0cVbiqP$M>CSZ4spLYH@O#@ zdD;#xU4KUwT<||xa5pA7ctYqNlwftbMgAp-d{5C9wWeaoQ zn=xiIkBz^N`_m82d)iHAFd)gKg-+q%tE~=Yn;;P11fZK%!nhUGK#8pH!; z3V3}Hd1ctAImu9kkXThrC~dKz zQgnYuv5L?*-$UDcZ6QJKxCwuM3+n?cn$iECy)W%<<4Cd%fcqlu5@kxV7Rz?q?sm7| zo1U5X{{M$JGj6xt-eg+~B~hZdlj2T*#B&_p>kO1hnUn~ys&MZ)d8zPpV`KiB9E)-1cH{m-xCzaa}OBfs8t9ak+KN!)|N^HJ^|om##Z7Lw@}U9QGz4XC1oxBJ|17cmC%nFrv(L{8aO)tZm$1mc1W7Hl zP%&m?zZ3Zn5Pc5bLZJ8q5OJSkY-Rc1nOV|vH(9{{J*_FdZc@nO} zsu%=OeFai#b)biDhKIPWLSy%{wSG&r*7Jlato3^k*8c2QpsCM6xqFIrAwn-F=#jf) zDfM#(%AJ$e6o~6G&&wNc*zX5ev$Qh3GuRJyauKDA@-X#5F8bd78R#!4gIw5F$JQU#CyBJ;%p`MVBNleQp9$H1C|2O z@)j(|0KVy<(A@&5KgMTgFLp)0mJ4H0es4kfbj9w5rL?OdOIaLw%cVX90WE>dy|UTY zAoMxxyGo15$rTTP;*9d!Y1q zu zVeyh&YZ$F6Z@7oCj_a8em9_FCjz9)4u?_}d&0mE_hYC{-3RKNn zS5seTMipy_C0Kj#3`enloq#@pV*VZoeLAPsWhEnv4lsP(%|a%*yO^m~D=qpAOih~x znR~AJ-(lEHS#k2s55vBEjCuPG*17g(2M~JJ%AAEpHw-QRrWMBpPjX_@ge7SC?q*uF z_PLvugYc|?&}$I1lU9tXd{q#+69>D?O=C`1GV}Th_d1(v500>gu7R-G(w8+Q{5jpS zRP<=VigE5+$KII-0XZQ(1gXD(vfL`mmh~-ez_a0`ezzcGo{c-$z&t**l$I(o??6JY zKtO+MDL{^byi$HU!hs`95RG)y^z{@q*1~ z%~ICV*OxDq1JDynv`1cK zC_?XS3!QKwyoLqx5`tws2%RDb%0URf1AHHLXL|yIX$PUR#p833y3gr6uJ=HULj@#s z1Bu)Q@!SJ>ZwFFe!TQ<2;5mB@^S>iP|E(?XKp^&ESli=)yeB~Bv33B@%LfW9V-{dM z_?h{SmKuj_UC`QiQ%(1(rFN(!^!u3Cz5>oCi|??!>r!TqwW|1z2)zKHB|8U=Zy;=f zJb%ZyVA+JE3*V<=={&oR@78KUVNl!w$j$}W3lQ8k{(l$fH>^14be!h_kj<2(h?_r+l&EY=mE~qlN4?}^i zPrX>oBdn2C{JfO})DPvzy^!8r&W|rX#e5fOPI(-|_=BfVke)-v@TjX|LdRR^i`a18 zL5K`mF@m~cWweR#Y#=G+q! zbL_L2vJ`ziWhp9t3E!9Bn@Y`&CD%MtZjOS2z)=tPN8y^6brw5wb=mJ->71_~5DEj= zuE0|43rgrzn8({toO%l?OB$BaNVhFD3VDF>BS`(FrFs~xQ1E%2F@*W_x%DH9FL1qM z#VicA0Z*7KMLe!pK1Ci09ZKj1q5Bd-(*=&Z_wE(+y9{F!vs`O;7z@_kf(u)iSN2$E zgPdEI>TCBGeC=F;h1m^a+P2imjc4ndc%S!sLGUxToz^=o`R(v~dFT|y3X4<_S$35r zR~c#E8?GeukwEBIEXAk{<27CHlLaPolF2>{gqN185dLJTInWZGZL2>Ay-IGCdyYAS z;HC>IyAMF-t{8m-18l_v5&9`s`Vs{0B*=Wzejo9iH{o#-cwW{6Ql~XU%Wvm`Nxkt0 zKYI;QS_ne!BYcj2e7@lVuN_wI>xPGfmN&;vu+HgzXNA8=;B4zki+&Bizl*=!%5vRWIq!0Ko~=IP9fTZnOZ?9u z^Upx$Lj|2%mm|+C1ryFfUT5c0XXhgH->NokVk6RmqyXzJ(D$V^J{Ye3*4(M-xh0ow zD>uL)gcvQ7mzH{wGl<1E>Q#&=#5Yb6{uMhtH=LiHF7|;y)ct|f2g3beAnl%@?DUmXUR0rk zy#kTXS_-axiuaeS^#xBFmg0W=yxd*vJTt!!g0B{Eeq%dXdOKcX&Kt7GMd)V%3qOzm z{}aSGR?zR`!j*NKNg!K6^KEwn5}(s$OGRmXuBRY?{%R?Js*E7H#p94zlbQ-wEkpc# zkH33T@tR5??}jx8(;a0kO8wSaH%n-qmPp!DAX_OUgTr-QgeQins6``L4`&dA8xbKICd&`QM zHq#e2G~Mj`L153fd4sTA?3y*_{j>f&UADs|Tw7hIklUNAjm88aZ9 zqt&Zt{QIX>{HvUD|EBlK04Evu=6z+yZ9AV}ZLhc4avXtD%o4eO!MI;gnMJI^D)%Fd zpMs(!LKmT*8I3@Gu5sVA)Rk@0(z$w3Kw&xsE002-oyWSdadz8etw(ZV=eD(=d^GTR zu3@gn;2{|(xNz!3!YdoLEtNXnu#}GWEw1y{-i!p_4}&l^?!q$nGxI;;y`swKm~ZaK z7oMi}GhV;eG8Cb|i?#j=TKFV1-rH7Om$19DZv-ojXW2|~t6ky-UV#?A14Zf<=K2GS zzLF5SP;5ef3X*w(^~&sx4QqdTAzLZaGXERMeAPC)l{X5K@1E1{^$$+H+yza4drpmy-7nY)_>uvmuF?G|w1>rT6NssGTwd77`zlXc$>*?-kQ&ozOqPz9?#8o(c$k4fFd0l%|J}L+W!bLcdT_uVJwd8U3$o0B@T-|2_ndIjK8QK`Y$il9 z_n^1u82)#0<#1icT7L#|XOorPOZuE$SjSf_WqW)CQomDhGAA~nIQ;}N{}G0hAVP0BYL?0l z@;vJXH1{IRN97N!0e4&9f*0btrD*=W91uFaCEF0RtbM)=;&uhZ&lJ6}&i$Zl2|^Zi z5cUHQ$s~Yx^elXc^Y_A>@jCLB7R!eu)Z{2))C=W+Gc4 zmuV3C4NH~eirg^0eP>it%l9@d5Q-)sO=%HPM5-WybWm(mQ6K?A$IwAqkN}#1fTF&!ZPX7AZ&&)(1T)XjN9GE^d( zIu*#uLMx8fcpz6Mifj)r(IzwH3GPIE5po-UG1X>NsjiObiRw7a8=R<_YH?oVJyBxg z{H(59y&|}3M#h8cd@KU^!#B$si(`V74&Kh@5N5OhCI4uY7RVdMfkpZ0EEGc9^~9gV zSZaE-8D~3t5bO1*nT>pt&&t+#ZrtTwP+rJveky*d9OqVZZ%}6{M&QSIu+{GDl3IGv zn}~uR_%h1pL*pO%%!4~~RKXot`9SNh!UF(Jmm(+_ z9_!$OrC$HH-s%Hwsd-+3U)b783%P;$lhmd0B%7Z)_0@ zc^kCQqBbigYsO_Ma6^ZMn{-kxbSQuEdxT|CpUdm-`tC%;N~cNNoEdbZw8tX{?WOsK zU2Ai)sXm;^=zt@SQ+$LH&8T%`nL9+m=j-jKqTD83=9i9pCGR!B15bp{zl-lzOxGIz zGD>{Y?wFqFa&E`=uAl761qv>}0OZET)#C;3du-&R>tb2a%`X^!0kJ!xfh>5Lj2>Em zWr&?S#C)&%?oKhjKtGr#b-b(TSl7YZ6XMgG{)OnD3Hn~JV2nucLEUnE^@QC3FwA4a z7`HfPl1i9|jP|NS=*^X^3kF0nJI1kebiM8K3Z;Dfl4dn%{cJShUy@3wjJ?yx{Ds{T zMg2}^$Juj9drJJ5LxM%PtuRku5mk$dnM@ECk6+c3jhkCdrtZc*TdLQ*+7%|W@=Y9U zht8fmP>-{mO6%~m;fj=H4LN&m;{L`fLUR6_f!{ZwfUi(q2p@WM3<5h9-+2GCj!zs! zlRtB4yw4dupQs;4of~epZCeZqkic=Y$!F2^R^((c=MP?TjeN!L5^O`q%<*sJ39pO9 zo0NZWbwuhy4`b#PJ>M0RbW&U;C@CRrFUAJeuj~dgKsSjMNg@R%|4<~iL{IGt<_$)` zafeMT6osZVOFe(hF_7N3}JXef3Y<#wzbzf-h_e8{xTHDKk@71Ip2&a-*%JCL{o5o>dhF%6Cn}D6`Q%J%A}6t-0yanY*Y1Gsvu8kN z&z9#^b&c61a5_WDi)T_=$*`@Zhl;0CCD>0-Z}by;CjK1tTTouX3>4Yy)O!uq(AV9! zQ(pF0v0s2C#bj6RRuO8ZpFGW)ywpfnFXVq)0!n_EJAMz!08>Z41+(D?D+$#b|4MFE z@Eu4kyn%TSY78@H({Mc%Q8R`W8stOT-1w+S49kIx+#~5NTYMOF>rH>*b7p@?7NsDy zug7o+WY@C^Ri<3mVI%2UDw93IxaDd>pr>Hta5O&B{3)%N8|Mhp*ojA#H$Npzt6OEg zKZ$!xwD`U!s`t)1C_O#i|P#V*?ZqCtV}CH=0i9zyC8Q9LnuyG;QU zHbbw$rpY-~@R*MKO3+6t8#Yb4ZBFh+KWh0PZ82*|Pe-9KbTaZ!G9$(Q%+*aN>6+o` zFS4}?9~^bL0KPq920i#<(7JZH)WbU@H}JuT(wlg^ML+zo;CAsp%NZ?&%@fM>2c?QY z0pa-+3}blqX#B{nv-hZOUJY&q&CcW|7i#e|1NAU9J%=?D8@phsd8<5*E}-lZD^LFL(L| z=W;pj?x#;AZ-YY@zU%(jRk)}s3p%f0?*+?2CJm$!B+pJXF@B!l%PgJyAOTu-Xkke0 zKa!n1eejPe$M^3o)%I=g9I)mNr4QN?x$c!NAVQ)35xsi%V*-7*bg%WN`H2k1LbXsb-GIEt>#Zpw6(?mowDa!c+MO!%vU8 z(4MY9!6sL$59wI9lwVD6=HaJ3+1kigC@l_1FPU%E%Zhid48j=Z9Q!zQOfQ(#jTAes zXf0O$ESTRciB_fuZqka_LvAccZYg^eLY&gY^mp%dnBjLZX0{slY0OO}*M6|G%hxL3 zY!rXmKMe8}#vOy=B8GpadO4VHIIls8BYP#^4(qS@$RWI>p^^B!JHKxYj^9zbgjn}J zxOm`$N4n`}3qPyp+L&bSRGdY*8K`Pi47_w+7_6czHrNJSLo@{O?}U(FIejWv9Mz=etPM7&A`NWj|{Hr+loVz>U5u31`^0l%lV{dHv;qcdOD5%cNE= zty76k6G_8@XQjGsvfP4IPrQ8Q;uk75B~4PvO1LqJ;mT=WP?r8@%_*jTSz`j?Y8;S& z8uPP&Pi|GqEyY@do#0xLH%dRC+GyO&f$!zAhj~YT`TY2XX4JHOYCx~yk{DaH=EPkF zCksyh9Q`a0+_}^^%m3WjS2i!C*JzsTPL+-_Utg4wT!MlIG7ra+?ZpC%9_9de@tm%c zZoP}EsG@!VasKmL8SCB9$j741(}wINAqgmYq9yQ8Ruyqx)lZgamI|ExPJ}6 z$BS(yilCy*C$OJ&?Fbzi09fR?z7o{7k*^io?do7gU9L8JyQSG0 zzbh*#p}EYL%ejlM8uMDqYxZi2sTJqet`HtXO}T_MT@vqKnfR&2L@gp@wbxpc0j6Ym z!xM9550~?bxv=^bo~d_oB$@+6U8#bJHDibB&B(`QS>xuUk-_A>S6@qfw?gaFw_l|F zx!(`&vf};KW`p&BPfhC0--na5bOOAzAD$0l87ENlgA0xpdaV}ZLDvV3EvIiRiSgLL z$FM!ik!YVcSXH+kq+6Et1Do-#YfqtWb4r-kL?Bw-8;IO#rQQH=(>7=35#Hs$qJkIO z9jU4ew&){!*t%&F*4WH7)m~Tjn9thGWbEfp-fZrM*e`opQLqt~&XVsl<{Z7OA7jaD z7Q2VR;8W$@uC52&K=6|^LuwbK%5QA0iI`uMZYJBpHXnKUrjK!UeUymm9W5H7$ikNt z0VN9}^$NTooTdgZKlej^x2UryGde=jvFnk@4f>g)uq!a>tkQ93@#&+_JhG$o*aG8|J^k)k{2H7e4+o0Y#w*@ksG78 zB;@|7u3M&3oAyTAzeg@Ea;03?m8FAs09v;Ozj>dm0Kt}K`l%9=w4Me~5%D>2Ha3qn zA*p6X*zmy1UFAdzbJH*Rnu62oPpcB6P%h#Iv5VweZ*N^ahH9L$G_udfO$=Y+^_U0WBEBLP~et<0HAAxZ;Y#BJpAxS$k_JtY;C`IbmAdLq8j+m9Quw zJY}#W`Ys{w#!|DUkJ4agq;C$_TWsxTr)*PfExU%R{iW2hAqe@!EnaI_7UKR`RM>%B z(uwQk@&wKwVe^a&72&+{ejz*LvIpdhp?gLOJGsLuk=tLlA$pYSVhS$9C6S;2x50!7 z%2cC)L%;H=Y;GZl^d|>By?8uV(Qeh$>Pg8hHBR~?IA2~_gfw)wn4l7p%ut9Pkz{*s zE_Y=uuRXh`Xl#TjF0F3iR@SZsNu=cW$J$>c^3*RkiP?QYs-c!qg%lIMOJe|4+ zAC{n)4|%08S`nRFlH(^t@(y?m910&)SwOS7RtoxGhDr1invyV_RHE*!;_euOhQ)6HA`I^V)+`cp#KN`7VU(~g4K zF83WyBah7H^=g7B;skzg2o_|sfCD4l&w0WmxwNG(K){9rYQMYa%vFSjCO=>Gbe$t)o!5x@5zY3S z^{U{3PRArj^!~Ixdl1XDAV&KPVu@E3$W~sR2SY z){&UFvO`g_{k6Y}&c_+S8U>HddS9Gk_TJ~qNGJKVSBQEo(VGQdG|ue7;Qb*BS0Kuj zwFd!NxGFUK*}WekY@X6K&rlJ)XSn6IW~8VJ!HKsUAOT+l`n3IBI|Us6fvZ32eN<^l zZTqGr_R4a~)TSE{SO;_M#8QKv1_rjx=@nwg)$2HU`7-X2YiFA#wyKuPFOIv>#K;E; zkt5V!R?N^hWK{mhm`yjB>sbvsU&2B5Yqao0)Y5(s8JCYs`woo{1Un*>U4o6+4=-Ce zzOJcQW{$yZMq-=4os-gkFZ0DQxQZ+9ZiTnj_f;3L8SnmHT%_=)<~R>&frYYvze3g~ zzY$7y4DHn91xlUtkkW_+%Oq8i_b=fA?-TXzy=x@0tF)T7y@+U!HBs2AXp&4h0JwS; z*$595LVzEJz@F=}bd!VB^XN0@A~cJt#~wApDnhh00I)Wud$R9AmVkn9;#`Vc( z*WMnBaS)p^@~`dY8HXg4Hi=f$J@SL{$+-^cO-AOIn8=H2V!x zH!Q^seqGH`l{&qs5ErXzLVGC=1ujE}l<`-QOWS&*HQ3)CmST-Sv?M|s8vX$6iTyoQ zK7(j^ha4Z+ND%lFIwcXOC8*>a6qc7OF7V77`!>U0(T-t&OVIXwxLPk`W z09bO1Wwyh@aZnc8YvjElR!gI+Ib9C6Es?eK&|5sWl@S=Kbq1es>-G{)`51(T;;hRk znuI7m?aw`JK2)&1l)@9}Zk@Y2k>w__MrTai|VlV?Q~XvDm?ZneovWgQ^kFY z8sg9e?Nl|fw&kqLeVS?O4tXm;as__l#LJExLPVQ%INI_(g=UL*Z!8(;L%&y_ORDtR zD#)I%(Hvs+KFB*v5X-D7i7dCvmAsW5;TQ#*dhb=(7|{^+k8pts>6vrJ!`lu}!2d}= zCRH|Z`M)`!6wF@N%)h!g#B1^|tW=<0$Xaid>ipyxsbC`aGu0h18R`R`XmZ-&Aky(A zkhzuHh-}J8J}*=YD~064F{S(H5Q;M@VebWD>!u|J@ZSthITMO~+>g9-IyQsQ-BTPz zC7)0QszQ>yY@~2UCRgpGQUD0MjJj%~?Ky!Yi!;%CexEi0&I>;o_i=+=5KB8vqUA2V z^lIV@)Gr>@K4^5sbr2ghqYwn$yTtEV(dY2AW6|)h@edUe)yt|Ze9Xp24_ia8s>9oJ z`%Grg?W#zezb^&%HAhRACADUwN79@!EKRTO*XS)C=pS8Cs(e2Y_^0kXIr9-sux2Qh z-iNUFNtoA5{g~Ggs_*Wb*D|9Q`KioXCbu=P>j}>7=!Rewj2r2GKEzR5I6AooEX|UQ zk*cjBjfmg3s)0!v&_k+aVH@(}4J_H4x8t#X0ADeX^C`+Gyp#ZY8KXbxo0B-Re>UdW zc)RYIa+GgZ*Xf-TtP}RQ9wC;;zijB3*FFM(*v8~e?Cd^7`t4NLvlvB);QF5IU_To# zL7jD9{Z7xCD4FLa+e04;y7rL}g93N49Xg7gem%#2K z-afqj>p}`x6+S7ReI$^AsOT7yFKcxpy{-Oi1T5)e(64|Ms12`~W4hloY781sp}$Y5 zSw&I32S$8y(!ap$t{!MH`Yi&_ea?8K%P4`_=v5S% z`huT=RsM6GSxw#pj!>5;p}+|m0o&BX ze~2t_sw|sb_CLgLj36H8Cl{r$k&pxGqn+D(LT?)+a1TwLrWjG_*+`4Wv`i6r~(D8C2ySIG~d()NHW@juCmJuUoqXK;_2Ul z4)JyyE4zaujzRkh`J$BY9~WdO+Bzs8k78-t=RUO(Pz>lK=X=s9H>vt$lO{86@$tSo zKU4KGN{?cIY7wZGhm%bEjaA23?=Zpw(EDd59hk8+$B9+=rN?q$pe8YtqtY!H%C;F$ z*c@9Z$dI@E6qtJ`9@!uvSld5xH~SU=bH^FtieY)yKV)$tx-JT1Lks44VwTDe7yzgO zQ&9X7Z*BAVmAsAjg_R*r1DZ{VGxWFnKVAgYCdxcQFe_jqtJLKQFVj2KPpT9^)(#K} z+qaUcZ+#}>mga8?0RY8G*Jqx%<@_2u8C}Kgi|&TlUQ+DN_q$%HF#>5^p`F4mo*b!W z9SEC@A@tg<4^=LvUenC1s!8v)sFm1z_t_FKrUv!$Rq{sH+TvjwSiNE6=Yd|6QLDms z?ZqXQ2N`mk;W%brM(7VC;coM#w7d~~(3r*j6#0vxQcv`uA3o<@M4xRRwA&f=k>Q)X zb8sPUyt{Xjxr%|P;rO#XI~CmYf!5SOEBk%>rhB@@O>#{}l`fanUOqvu;tecNS17X# z2<`=Y`I?QY&tC!qGP$U9d*yPRFUz1-cW($Nz8*q5F*6$96r`Tff<^?8QB&j~+`?(K zz>3*8-Q1QB4_}<7p`*%r!&XZBg`BcAi)xGx%kY)3G)S>U^oQn7M*+4XP6OfM-wky{ zi&Vry1A~YdkNHChbL>QOd_c`<-)S(z%&R3oym9UMyZk`DZQ!b07D^Yq9R_hxJLomx zss4>Ftp(`|R`*|9>Vgv|21VCRmBn#webZH(MomH9!uLT%5VyD|P+f_WT?Sv~TYtTn zk zaH(Axpbb~1LGaoFaZ@}0s($HB50QvX_kSX;v@JV{n$j#@;4h+JMpTxCO9eGw8-7?g zy=w|vuk&y4llkf+L>Kuyqksc6DjJPg9HiW(aoqbQFM*^2x9iI|38pF(a_#bQx;-oV zR8hDOI&>m^{ZbGjP$vR^U?%AonJIUz{a}@H8ZBRohTc3uTc?S$8zeSVpn82nlCRv+ z0+Mwi3lISfn>c>ztYgy7owinX9Y4kY?8uQsXFvZz z`k*eO2c_|R+^o1&b_au2?W_`y+f{-pbEdi0icI=NH?%Qq7W^dOfsMBEFRRn-gfFo7 z{4rem?<=}tNBKM+w?HsHU#aQIm#-!2m{}`noK}%$Kf($g9!=>=ZV4mA@3-!-GXF9$ zO-5ynnidwDNp7{Mg)$WntV(+7cRXi01(f)*0jmcC3c10>{h+@sz_0_2zjOTU1R%cu z_WdQ<1)4X2xq&9IK7X6h3V*x)YU=+x@_%0Pza#(mCI6qNbJsj-U}9w=Dv?JoL}1LB Pfai{(>5Y5?N8JAb*{_|& diff --git a/plugins/grr/icon_grr/__init__.py b/plugins/grr/icon_grr/__init__.py deleted file mode 100755 index bace8db897..0000000000 --- a/plugins/grr/icon_grr/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT diff --git a/plugins/grr/icon_grr/actions/__init__.py b/plugins/grr/icon_grr/actions/__init__.py deleted file mode 100755 index c5340cbdf2..0000000000 --- a/plugins/grr/icon_grr/actions/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .hunting.action import Hunting -from .labeling.action import Labeling -from .listing.action import Listing diff --git a/plugins/grr/icon_grr/actions/hunting/__init__.py b/plugins/grr/icon_grr/actions/hunting/__init__.py deleted file mode 100755 index 1572358856..0000000000 --- a/plugins/grr/icon_grr/actions/hunting/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import Hunting diff --git a/plugins/grr/icon_grr/actions/hunting/action.py b/plugins/grr/icon_grr/actions/hunting/action.py deleted file mode 100755 index 58b17e900f..0000000000 --- a/plugins/grr/icon_grr/actions/hunting/action.py +++ /dev/null @@ -1,307 +0,0 @@ -import komand -from .schema import HuntingInput, HuntingOutput - - -# Custom imports below - - -class Hunting(komand.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="hunting", - description="Looks for exposed secrets in the git commit history and branches", - input=HuntingInput(), - output=HuntingOutput(), - ) - self.grr_api = None - - def run(self, params={}): - self.grr_api = self.connection.grr_api - flow_name = params.get("flow_name") - administrative = ["Interrogate", "KeepAlive", "OnlineNotification"] - browser = ["CacheGrep", "ChromeHistory", "FirefoxHistory"] - collectors = ["ArtifactCollectorFlow", "DumpACPITable", "DumpFlashImage"] - filesystem = ["FileFinder", "GetMBR", "ListVolumeShadowCopies"] - registry = ["CollectRunKeyBinaries", "RegistryFinder"] - if flow_name in administrative: - self.administrative(flow_name) - if flow_name in browser: - self.brower(flow_name) - if flow_name == "CheckRunner": - self.checks(flow_name) - if flow_name in collectors: - self.collectors(flow_name) - if flow_name in filesystem: - self.filesystem(flow_name) - if flow_name == "Netstat": - self.network(flow_name) - if flow_name == "ListProcesses": - self.processes(flow_name) - if flow_name in registry: - self.registry(flow_name) - - def administrative(self, flow_name, params={}): - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - if flow_name == "Interrogate": - flow_args.lightweight = True - self.hunter_args() - if flow_name == "KeepAlive": - duration = params.get("duration") - flow_args.duration = duration - self.hunter_args() - if flow_name == "OnlineNotification": - email = params.get("email") - flow_args.email = email - self.hunter_args() - - def browser(self, flow_name, params={}): - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - if flow_name == "CacheGrep": - check_chrome = params.get("check_chrome") - check_firefox = params.get("check_firefox") - data_regex = params.get("data_regex") - grep_users = params.get("grep_users") - pathtype = params.get("pathtype") - if check_chrome: - flow_args.check_chrome = True - if check_firefox: - flow_args.check_firefox = True - flow_args.path_type = pathtype - flow_args.data_regex = data_regex - flow_args.grep_users = grep_users - self.hunter_args() - if flow_name == "ChromeHistory": - get_archive = params.get("get_archive") - history_path = params.get("history_path") - path_type = params.get("pathtype") - username = params.get("username") - flow_args.get_archive = get_archive - flow_args.username = username - flow_args.history_path = history_path - flow_args.path_type = path_type - self.hunter_args() - if flow_name == "FirefoxHistory": - get_archive = params.get("get_archive") - history_path = params.get("history_path") - path_type = params.get("pathtype") - username = params.get("username") - flow_args.get_archive = get_archive - flow_args.username = username - flow_args.history_path = history_path - flow_args.path_type = path_type - self.hunter_args() - - def checks(self, flow_name, params={}): - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - if flow_name == "CheckRunner": - max_findings = params.get("max_findings") - only_cpe = params.get("only_cpe") - only_label = params.get("only_label") - only_os = params.get("only_os") - restrict_checks = params.get("restrict_checks") - flow_args.restrict_checks = restrict_checks - flow_args.only_os = only_os - flow_args.only_label = only_label - flow_args.only_cpe = only_cpe - flow_args.max_findings = max_findings - self.hunter_args() - - def collectors(self, flow_name, params={}): - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - if flow_name == "ArtifactCollectorFlow": - apply_parsers = params.get("apply_parsers") - artifact_list = params.get("artifact_list") - dependencies = params.get("dependencies") - ignore_interpolation_errors = params.get("ignore_interpolation_errors") - knowledge_base = params.get("knowledge_base") - max_file_size = params.get("max_file_size") - on_no_results_error = params.get("on_no_results_error") - split_output_by_artifact = params.get("split_output_by_artifact") - use_tsk = params.get("use_tsk") - if ignore_interpolation_errors: - flow_args.ignore_interpolation_errors = ignore_interpolation_errors - if apply_parsers: - flow_args.apply_parsers = apply_parsers - if on_no_results_error: - flow_args.on_no_results_error = on_no_results_error - if split_output_by_artifact: - flow_args.split_output_by_artifact = split_output_by_artifact - if use_tsk: - flow_args.use_tsk = use_tsk - flow_args.dependencies = dependencies - flow_args.artifact_list = artifact_list - flow_args.knowledge_base = knowledge_base - flow_args.max_file_size = max_file_size - self.hunter_args() - if flow_name == "DumpACPITable": - component_version = params.get("component_version") - logging = params.get("logging") - table_signature_list = params.get("table_signature_list") - flow_args.component_version = component_version - flow_args.table_signature_list = table_signature_list - flow_args.logging = logging - self.hunter_args() - if flow_name == "DumpFlashImage": - chunk_size = params.get("chunk_size") - component_version = params.get("component_version") - log_level = params.get("log_level") - notify_syslog = params.get("notify_syslog") - if notify_syslog: - flow_args.notify_syslog = notify_syslog - flow_args.chunk_size = chunk_size - flow_args.component_version = component_version - flow_args.log_level = log_level - self.hunter_args() - - def filesystem(self, flow_name, params={}): - if flow_name == "list_volume_shadow_copies": - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - if flow_name == "FileFinder": - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - action = params.get("action") - conditions = params.get("conditions") - follow_links = params.get("follow_links") - paths = params.get("paths") - pathtype = params.get("pathtype") - process_non_regular_files = params.get("process_non_regular_files") - xdev = params.get("xdev") - if action: - flow_args.action = action - if conditions: - flow_args.conditions = conditions - if follow_links: - flow_args.follow_links = follow_links - if paths: - flow_args.ClearField("paths") - flow_args.paths.append(paths) - if pathtype: - flow_args.pathtype = pathtype - if process_non_regular_files: - flow_args.process_non_regular_files = process_non_regular_files - if xdev: - flow_args.xdev = xdev - self.hunter_args() - if flow_name == "length": - length = params.get("length") - flow_args.ClearField("length") - flow_args.length.append(length) - - def hunter_args(self, params={}): - hunt_name = params.get("hunt_name") - description = params.get("description") - priority = params.get("priority") - notification_event = params.get("notification_event") - queue = params.get("queue") - cpu_limit = params.get("cpu_limit") - network_bytes_limit = params.get("network_bytes_limit") - client_limit = params.get("client_limit") - expiry_time = params.get("expiry_time") - client_rate = params.get("client_rate") - crash_alert_email = params.get("crash_alert_email") - hunt_runner_args = self.grr_api.types.CreateHuntRunnerArgs() - if hunt_name: - hunt_runner_args.hunt_name.append(hunt_name) - if description: - hunt_runner_args.description.append(description) - if priority: - hunt_runner_args.ClearField("priority") - hunt_runner_args.priority.append(priority) - if notification_event: - hunt_runner_args.notification_event.append(notification_event) - if queue: - hunt_runner_args.ClearField("queue") - hunt_runner_args.queue.append(queue) - if cpu_limit: - hunt_runner_args.cpu_limit.append(cpu_limit) - if network_bytes_limit: - hunt_runner_args.network_bytes_limit.append(network_bytes_limit) - if client_limit: - hunt_runner_args.ClearField("client_limit") - hunt_runner_args.client_limit.append(client_limit) - if expiry_time: - hunt_runner_args.ClearField("expiry_time") - hunt_runner_args.expiry_time.append(expiry_time) - if client_rate: - hunt_runner_args.client_rate.append(client_rate) - if crash_alert_email: - hunt_runner_args.ClearField("crash_alert_email") - hunt_runner_args.crash_alert_email.append(crash_alert_email) - self.output_plugins(hunt_runner_args) - rule = self.hunt_runner_args.client_rule_set.rules.add() - self.foreman(rule) - rule.rule_type = rule.LABEL - - def foreman(self, rule, params={}): - pass - - def output_plugins(self, hunt_runner_args, params={}): - plugin_name = params.get("output_plugin_name") - output_plugin = hunt_runner_args.output_plugin - if plugin_name: - output_plugin.plugin_name = plugin_name - plugin_args = output_plugin.plugin_args - if plugin_name == "EmailOutput": - email_address = params.get("email_address") - emails_limit = params.get("emails_limit") - if email_address: - plugin_args.email_address.append(email_address) - if emails_limit: - plugin_args.ClearField("emails_limit") - plugin_args.emails_limit.append(emails_limit) - if plugin_name == "BigQueryOutput": - convert_values = params.get("convert_values") - export_files_contents = params.get("export_files_contents") - export_files_hashes = params.get("export_files_hashes") - follow_urns = params.get("follow_urns") - annotations = params.get("annotations") - if convert_values: - plugin_args.ClearField("convert_values") - plugin_args.convert_values.append(convert_values) - if export_files_contents or export_files_hashes or follow_urns or annotations: - export_options = plugin_args.export_options - if follow_urns: - export_options.ClearField("follow_urns") - export_options.follow_urns.append(follow_urns) - if export_files_contents: - export_options.ClearField("export_files_contents") - export_options.export_files_contents.append(export_files_contents) - if export_files_hashes: - export_options.ClearField("export_files_hashes") - export_options.export_files_hashes.append(export_files_hashes) - for annotation in annotations: - export_options.annotations.append(annotation) - return hunt_runner_args - - def network(self, flow_name, params={}): - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - listening_only = params.get("listening_only") - if listening_only: - flow_args.listening_only = listening_only - - def processes(self, flow_name, params={}): - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - if flow_name == "list_processes": - connection_states = params.get("connection_states") - fetch_binaries = params.get("fetch_binaries") - filename_regex = params.get("filename_regex") - if connection_states: - flow_args.connection_states = connection_states - if fetch_binaries: - flow_args.fetch_binaries = fetch_binaries - if filename_regex: - flow_args.filename_regex = filename_regex - - def registry(self, flow_name, params={}): - if flow_name == "CollectRunKeyBinaries": - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - if flow_name == "RegistryFinder": - flow_args = self.grr_api.types.CreateFlowArgs(flow_name) - conditions = params.get("conditions") - key_paths = params.get("key_paths") - if conditions: - flow_args.conditions = conditions - if key_paths: - flow_args.key_paths = key_paths - - def test(self): - return {} diff --git a/plugins/grr/icon_grr/actions/hunting/schema.py b/plugins/grr/icon_grr/actions/hunting/schema.py deleted file mode 100755 index 47ed78e42a..0000000000 --- a/plugins/grr/icon_grr/actions/hunting/schema.py +++ /dev/null @@ -1,848 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import komand -import json - - -class Component: - DESCRIPTION = "Start a hunt on clients" - - -class Input: - ACTION = "action" - ANNOTATIONS = "annotations" - APPLY_PARSERS = "apply_parsers" - ARTIFACT_LIST = "artifact_list" - ATTRIBUTE_REGEX = "attribute_regex" - BYTES_AFTER = "bytes_after" - BYTES_BEFORE = "bytes_before" - CH_USERNAME = "ch_username" - CHECK_CHROME = "check_chrome" - CHECK_FIREFOX = "check_firefox" - CHECK_IE = "check_ie" - CHUNK_SIZE = "chunk_size" - CLIENT_LIMIT = "client_limit" - CLIENT_RATE = "client_rate" - COMPONENT_VERSION = "component_version" - CONDITIONS = "conditions" - CONNECTION_STATES = "connection_states" - CONVERT_VALUES = "convert_values" - CPU_LIMIT = "cpu_limit" - CRASH_ALERT_EMAIL = "crash_alert_email" - DATA_REGEX = "data_regex" - DEPENDENCIES = "dependencies" - DESCRIPTION = "description" - DURATION = "duration" - EMAIL = "email" - EMAIL_ADDRESS = "email_address" - EMAILS_LIMIT = "emails_limit" - EXPIRY_TIME = "expiry_time" - EXPORT_FILES_CONTENTS = "export_files_contents" - EXPORT_FILES_HASHES = "export_files_hashes" - FETCH_BINARIES = "fetch_binaries" - FF_USERNAME = "ff_username" - FIELD = "field" - FILEFINDER_REGEX = "filefinder_regex" - FILENAME_REGEX = "filename_regex" - FLOW_ARGS = "flow_args" - FLOW_NAME = "flow_name" - FOLLOW_LINKS = "follow_links" - FOLLOW_URNS = "follow_urns" - GET_ARCHIVE = "get_archive" - GREP_USERS = "grep_users" - HISTORY_PATH = "history_path" - HUNT_NAME = "hunt_name" - IGNORE_INTERPOLATION_ERRORS = "ignore_interpolation_errors" - INTEGER = "integer" - KNOWLEDGE_BASE = "knowledge_base" - LABEL = "label" - LENGTH = "length" - LIGHTWEIGHT = "lightweight" - LISTENING_ONLY = "listening_only" - LITERAL = "literal" - LOG_LEVEL = "log_level" - LOGGING = "logging" - MATCH_MODE = "match_mode" - MAX_FILE_SIZE = "max_file_size" - MAX_FINDINGS = "max_findings" - MAX_LAST_ACCESS_TIME = "max_last_access_time" - MAX_LAST_INODE_CHANGE_TIME = "max_last_inode_change_time" - MAX_LAST_MODIFIED_TIME = "max_last_modified_time" - MAX_SIZE = "max_size" - MIN_FILE_SIZE = "min_file_size" - MIN_LAST_ACCESS_TIME = "min_last_access_time" - MIN_LAST_INODE_CHANGE_TIME = "min_last_inode_change_time" - MIN_LAST_MODIFIED_TIME = "min_last_modified_time" - MODE = "mode" - NETWORK_BYTES_LIMIT = "network_bytes_limit" - NOTIFICATION_EVENT = "notification_event" - NOTIFY_SYSLOG = "notify_syslog" - ON_NO_RESULTS_ERROR = "on_no_results_error" - ONLY_CPE = "only_cpe" - ONLY_LABEL = "only_label" - ONLY_OS = "only_os" - OPERATING_SYSTEM = "operating_system" - OPERATOR = "operator" - OUTPUT_PLUGIN_NAME = "output_plugin_name" - OVERSIZED_FILE_POLICY = "oversized_file_policy" - PATHS = "paths" - PATHTYPE = "pathtype" - PRIORITY = "priority" - PROCESS_NON_REGULAR_FILES = "process_non_regular_files" - QUEUE = "queue" - REGEX = "regex" - RESOLVE_LINKS = "resolve_links" - RESTRICT_CHECKS = "restrict_checks" - SPLIT_OUTPUT_BY_ARTIFACT = "split_output_by_artifact" - START_OFFEST = "start_offest" - START_OFFSET = "start_offset" - TABLE_SIGNATURE_LIST = "table_signature_list" - UPLOAD_TOKEN = "upload_token" - USE_EXTERNAL_STORES = "use_external_stores" - USE_TSK = "use_tsk" - VALUE = "value" - XDEV = "xdev" - XOR_IN_KEY = "xor_in_key" - XOR_OUT_KEY = "xor_out_key" - - -class Output: - RESULTS = "results" - - -class HuntingInput(komand.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "action": { - "type": "string", - "title": "Action", - "description": "Use an action", - "enum": [ - "STAT", - "HASH", - "DOWNLOAD" - ], - "order": 36 - }, - "annotations": { - "type": "array", - "title": "Annotations", - "description": "Annotations to add to exported data. This field can be used to differentiate sets of exported data inside a particular exported type. e.g. data collected by users vs. data collected by cronjob", - "items": { - "type": "string" - }, - "order": 95 - }, - "apply_parsers": { - "type": "boolean", - "title": "Apply Parsers", - "description": "If 1, apply any relevant parser to the collected data. If 0, return the raw collected data e.g Files or Registry Keys", - "order": 21 - }, - "artifact_list": { - "type": "string", - "title": "Artifact List", - "description": "A list of Artifact class names", - "order": 22 - }, - "attribute_regex": { - "type": "string", - "title": "Attribute Regex", - "description": "The regular expression", - "order": 83 - }, - "bytes_after": { - "type": "integer", - "title": "Bytes After", - "description": "Include this many bytes after the hit", - "order": 49 - }, - "bytes_before": { - "type": "integer", - "title": "Bytes Before", - "description": "Include this many bytes before the hit", - "order": 48 - }, - "ch_username": { - "type": "string", - "title": "Chrome History Username", - "description": "The user to get Chrome history for. If history_path is not set this will be used to guess the path to the history files", - "order": 14 - }, - "check_chrome": { - "type": "integer", - "title": "Check Chrome", - "description": "Checks Chrome", - "order": 6 - }, - "check_firefox": { - "type": "integer", - "title": "Check Firefox", - "description": "Checks Chrome", - "order": 7 - }, - "check_ie": { - "type": "boolean", - "title": "Check IE", - "description": "Checks Internet Explorer", - "order": 8 - }, - "chunk_size": { - "type": "integer", - "title": "Chunk Size", - "description": "A heartbeat will be emitted every chunk_size.This could be reduced in case the process times out", - "order": 33 - }, - "client_limit": { - "type": "integer", - "title": "Client Limit", - "description": "Maximum number of clients participating in the hunt. Best practice is for all hunts to use a limit to start with and remove it only when client impact has been assessed by looking at hunt stats. Note that this limit can be overshot by a small number of clients if there are multiple workers running ", - "order": 75 - }, - "client_rate": { - "type": "integer", - "title": "Client Rate", - "description": "The maximum number of clients to engage per minute. A rate of 0 means to schedule clients as fast as possible", - "order": 77 - }, - "component_version": { - "type": "string", - "title": "Component Version", - "description": "Version of Chipsec component to be used", - "order": 30 - }, - "conditions": { - "type": "string", - "title": "Conditions", - "description": "These conditions will be applied to all files that match the path arguments", - "enum": [ - "MODIFICATION_TIME", - "ACCESS_TIME", - "INODE_CHANGE_TIME", - "SIZE", - "CONTENTS_REGEX_MATCH", - "CONTENTS_LITERAL_MATCH", - "EXT_FLAGS" - ], - "order": 37 - }, - "connection_states": { - "type": "array", - "title": "Connection States", - "description": "Network connection states to match. If a process has any network connections in any status listed here, it will be considered a match", - "items": { - "type": "string" - }, - "enum": [ - "UNKNOWN", - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECV", - "ESTABLISHED", - "FIN_WAIT1", - "FIN_WAIT2", - "CLOSE_WAIT", - "CLOSING", - "LAST_ACK", - "TIME_WAIT", - "DELETE_TCB", - "NONE", - "CLOSE" - ], - "order": 65 - }, - "convert_values": { - "type": "boolean", - "title": "Convert Values", - "description": "If true, convert values for export-friendly format", - "order": 94 - }, - "cpu_limit": { - "type": "integer", - "title": "CPU Limit", - "description": "A limit on the client CPU seconds used by this flow", - "order": 73 - }, - "crash_alert_email": { - "type": "string", - "title": "Crash Alert Email", - "description": "An email address to send mails to when a client crashes during execution of this hunt", - "order": 78 - }, - "data_regex": { - "type": "string", - "title": "Data Regex", - "description": "A regular expression to search for", - "order": 9 - }, - "dependencies": { - "type": "string", - "title": "Dependencies", - "description": "Specifies how dependencies should be handled. Use the knowledgebase as a cache. If knowledgebase isn't present, a new one will be populated", - "default": "USE_CACHED", - "enum": [ - "USE_CACHED", - "IGNORE_DEPS", - "FETCH_NOW" - ], - "order": 23 - }, - "description": { - "type": "string", - "title": "Description", - "description": "The description of this hunt", - "order": 69 - }, - "duration": { - "type": "integer", - "title": "Duration", - "description": "Until when should the client stay in the fast poll mode", - "default": 3600, - "order": 4 - }, - "email": { - "type": "string", - "title": "Email", - "description": "Email address to send to. If not set, mail will be sent to the logged in user", - "order": 5 - }, - "email_address": { - "type": "string", - "title": "Email Address", - "description": "The email address that messages will be sent to", - "order": 89 - }, - "emails_limit": { - "type": "integer", - "title": "Emails Limit", - "description": "The emails limit", - "order": 90 - }, - "expiry_time": { - "type": "integer", - "title": "Expiry Time", - "description": "Expiry time for the hunt", - "order": 76 - }, - "export_files_contents": { - "type": "boolean", - "title": "Export Files Contents", - "description": "If this is true, open files and export their full or partial contents. Note: this may require additional datastore roundtrips and slow down the export process, also exporting file contents may significantly increase size of the exported data", - "order": 91 - }, - "export_files_hashes": { - "type": "boolean", - "title": "Export Files Hashes", - "description": "If this is true, export hashes when dealing with file-related values. The files won't be hashed during the export, hashes will only be exported if they were collected before the export. This option affects exporting VFSFile and StatEntry RDFValues. This is true by default even though it requires extra datastore roundtrips because it's very useful and users expect the hashes to be there", - "order": 93 - }, - "fetch_binaries": { - "type": "boolean", - "title": "Fetch Binaries", - "description": "Fetches Binaries", - "order": 66 - }, - "ff_username": { - "type": "string", - "title": "Firefox History Username", - "description": "The user to get FireFox history for. If history_path is not set this will be used to guess the path to the history files", - "order": 15 - }, - "field": { - "type": "string", - "title": "Field", - "description": "Field Specification", - "default": "UNSET", - "enum": [ - "UNSET", - "USERNAMES", - "UNAME", - "FQDN", - "HOST_TIPS", - "CLIENT_NAME", - "CLIENT_DESCRIPTION", - "SYSTEM", - "MAC_ADDRESSES", - "KERNEL_VERSION", - "OS_VERSION", - "OS_RELEASE", - "CLIENT_LABELS", - "INSTALL_TIME", - "CLIENT_VERSION", - "LAST_BOOT_TIME", - "CLIENT_CLOCK" - ], - "order": 84 - }, - "filefinder_regex": { - "type": "string", - "title": "FileFinder Regex", - "description": "The regular expression which will be used to search", - "order": 46 - }, - "filename_regex": { - "type": "string", - "title": "Filename Regex", - "description": "Regex used to filter the list of processes", - "order": 67 - }, - "flow_args": { - "type": "boolean", - "title": "Regex Checks", - "description": "Enable high signal regex checks", - "default": false, - "order": 2 - }, - "flow_name": { - "type": "string", - "title": "Flow Name", - "description": "The name of the Flow you want to use", - "enum": [ - "Interrogate", - "KeepAlive", - "OnlineNotification", - "CacheGrep", - "ChromeHistory", - "FirefoxHistory", - "CheckRunner", - "ArtifactCollectorFlow", - "DumpACPITable", - "DumpFlashImage", - "FileFinder", - "GetMBR", - "ListVolumeShadowCopies", - "Netstat", - "ListProcesses", - "CollectRunKeyBinaries", - "RegistryFinder" - ], - "order": 1 - }, - "follow_links": { - "type": "boolean", - "title": "Follow links", - "description": "Should symbolic links be followed in recursive directory listings", - "order": 60 - }, - "follow_urns": { - "type": "boolean", - "title": "Follow URNs", - "description": "If this is true, follow urns and try to export not only the urns themselves, but also the data they are pointing to. Note: this may require additional datastore roundtrips and slow down the export process", - "order": 92 - }, - "get_archive": { - "type": "boolean", - "title": "Get Archive", - "description": "Gets Archived History as well (3 months old)", - "order": 12 - }, - "grep_users": { - "type": "string", - "title": "Grep Users", - "description": "A list of users to check. Default all users on the system", - "order": 10 - }, - "history_path": { - "type": "string", - "title": "History Path", - "description": "Path to a profile directory that contains a History file", - "order": 13 - }, - "hunt_name": { - "type": "string", - "title": "Hunt Name", - "description": "The name of the class implementing the hunt to run", - "order": 68 - }, - "ignore_interpolation_errors": { - "type": "boolean", - "title": "Ignore Interpolation Errors", - "description": "If true, don't die if %%users.homedir%% and similar fail to expand. It's common on windows for some user attributes to be missing if users have never logged in. Enable this when you have multiple artifacts or paths and want to report partial results", - "order": 24 - }, - "integer": { - "type": "boolean", - "title": "Integer", - "description": "Integer to trigger this hunt", - "order": 85 - }, - "knowledge_base": { - "type": "string", - "title": "Knowledge Base", - "description": "An optional knowledge base to use, if not specified we retrieve one from the client object", - "order": 25 - }, - "label": { - "type": "array", - "title": "Label", - "description": "Label that triggers this hunt", - "items": { - "type": "string" - }, - "order": 80 - }, - "length": { - "type": "integer", - "title": "Length", - "description": "How far (in bytes) into the file to search or the length of the MBR to read", - "order": 51 - }, - "lightweight": { - "type": "boolean", - "title": "Lightweight", - "description": "Performs a light weight version of the interrogate", - "order": 3 - }, - "listening_only": { - "type": "boolean", - "title": "Listening Only", - "description": "If set, only listening connections are returned", - "order": 64 - }, - "literal": { - "type": "string", - "title": "Literal", - "description": "Search for this literal string", - "order": 52 - }, - "log_level": { - "type": "integer", - "title": "Log Level", - "description": "Set the log level. If set, the log returned will include additional information reported by Chipsec", - "order": 34 - }, - "logging": { - "type": "boolean", - "title": "Logging", - "description": "If the logging is set to true, the client sends log, including Chipsec's log", - "order": 31 - }, - "match_mode": { - "type": "string", - "title": "Match Mode", - "description": "Match mode to trigger this hunt", - "enum": [ - "MATCH_ALL", - "MATCH_ANY" - ], - "order": 79 - }, - "max_file_size": { - "type": "string", - "title": "Max File Size", - "description": "The maximum size of files we will download in bytes, 500MB by default", - "order": 26 - }, - "max_findings": { - "type": "integer", - "title": "Maximize Findings", - "description": "Summarize checks with more than N individual findings", - "order": 16 - }, - "max_last_access_time": { - "type": "integer", - "title": "Min Last Access Time", - "description": "File must be accessed before this time", - "order": 42 - }, - "max_last_inode_change_time": { - "type": "integer", - "title": "Max Last Inode Change Time", - "description": "File's must be changed before this time", - "order": 44 - }, - "max_last_modified_time": { - "type": "integer", - "title": "Max Last Modified Time", - "description": "File must be modified before this time", - "order": 40 - }, - "max_size": { - "type": "integer", - "title": "Max Size", - "description": "The maximum size of files", - "order": 56 - }, - "min_file_size": { - "type": "integer", - "title": "Min File Size", - "description": "Minimum file size in bytes", - "order": 45 - }, - "min_last_access_time": { - "type": "integer", - "title": "Min Last Access Time", - "description": "File must be accessed after this time", - "order": 41 - }, - "min_last_inode_change_time": { - "type": "integer", - "title": "Min Last Inode Change Time", - "description": "File's inode must be changed after this time", - "order": 43 - }, - "min_last_modified_time": { - "type": "integer", - "title": "Min Last Modified Time", - "description": "File must be modified after this time", - "order": 39 - }, - "mode": { - "type": "string", - "title": "Mode", - "description": "When should searching stop? Stop after one hit or search for all", - "enum": [ - "FIRST_HIT", - "ALL_HITS" - ], - "order": 47 - }, - "network_bytes_limit": { - "type": "integer", - "title": "Network Bytes Limit", - "description": "A limit on the total traffic used by this flow", - "order": 74 - }, - "notification_event": { - "type": "string", - "title": "Notification Event", - "description": "An event name for an event listener. An event will be published to this listener once the flow finishes", - "order": 71 - }, - "notify_syslog": { - "type": "boolean", - "title": "Notify Syslog", - "description": "If true, a message will be written by the client to the syslog before running the action. This can be used for debugging in case the client crashes ", - "order": 35 - }, - "on_no_results_error": { - "type": "boolean", - "title": "Oh No Results Error", - "description": "The maximum size of files we will download in bytes, 500MB by default", - "order": 27 - }, - "only_cpe": { - "type": "string", - "title": "Only CPE", - "description": "Limit checks to hosts with cpe strings", - "order": 17 - }, - "only_label": { - "type": "string", - "title": "Only CPE", - "description": "Limit checks to hosts with label strings", - "order": 18 - }, - "only_os": { - "type": "string", - "title": "Only OS", - "description": "Limit checks to hosts of OS type(s) [Linux|OSX|Windows]", - "order": 19 - }, - "operating_system": { - "type": "string", - "title": "Operating System", - "description": "Type of operating system to trigger this hunt", - "enum": [ - "Os_windows", - "Os_linux", - "Os_darwin" - ], - "order": 81 - }, - "operator": { - "type": "string", - "title": "Operator", - "description": "Operator", - "enum": [ - "EQUAL", - "LESS_THAN", - "GREATER_THAN" - ], - "order": 86 - }, - "output_plugin_name": { - "type": "string", - "title": "Output Plugin Name", - "description": "The name of the output plugin", - "enum": [ - "EmailOutput", - "BigQueryOutput" - ], - "order": 88 - }, - "oversized_file_policy": { - "type": "string", - "title": "Max Size", - "description": "What should GRR do with files that are larger than max_size", - "enum": [ - "SKIP", - "HASH_TRUNCATED", - "DOWNLOAD_TRUNCATED" - ], - "order": 57 - }, - "paths": { - "type": "string", - "title": "Paths", - "description": "A path to glob that can contain %% expansions", - "order": 38 - }, - "pathtype": { - "type": "string", - "title": "Path Type", - "description": "Type of path access to use", - "enum": [ - "UNSET", - "OS", - "TSK", - "Registry", - "Memory", - "TMPFILE" - ], - "order": 11 - }, - "priority": { - "type": "string", - "title": "Priority", - "description": "The priority used for this flow", - "enum": [ - "LOW_PRIORITY", - "MEDIUM_PRIORITY", - "HIGH_PRIORITY" - ], - "order": 70 - }, - "process_non_regular_files": { - "type": "boolean", - "title": "Process Non Regular Files", - "description": "Look both into regular files and non-regular files (devices, named pipes, sockets). NOTE: This is very dangerous and should be used with care", - "order": 61 - }, - "queue": { - "type": "string", - "title": "Queue", - "description": "The queue to use for the hunt", - "order": 72 - }, - "regex": { - "type": "boolean", - "title": "Regex", - "description": "Use a regular expression to trigger this hunt", - "order": 82 - }, - "resolve_links": { - "type": "boolean", - "title": "Resolve links", - "description": "If true, the action will yield stat information for link targets, if false, the stat for the link itself will be returned", - "order": 59 - }, - "restrict_checks": { - "type": "string", - "title": "Restrict Checks", - "description": "Only run checks with the specified check_ids", - "order": 20 - }, - "split_output_by_artifact": { - "type": "boolean", - "title": "Split Output by Artifact", - "description": "If True, use output as a directory and write a separate collection for each artifact collected", - "order": 28 - }, - "start_offest": { - "type": "integer", - "title": "Start Offset", - "description": "Start searching at this file offset", - "order": 50 - }, - "start_offset": { - "type": "integer", - "title": "Start offset", - "description": "Start searching at this file offset", - "order": 53 - }, - "table_signature_list": { - "type": "string", - "title": "Table Signature Lists", - "description": "Signature of ACPI tables to be dumped", - "order": 32 - }, - "upload_token": { - "type": "boolean", - "title": "Upload Token", - "description": "An upload token to use with the direct upload functionality. This token contains the hmac authenticated policy that determines for how long the client is allowed to upload files to the server. This is comparable to the policy document used by GCS: https://cloud.google.com/storage/docs/xml-api/post-object#policydocument", - "order": 63 - }, - "use_external_stores": { - "type": "boolean", - "title": "Use External Stores", - "description": "If true, look in any defined external file stores for files before downloading them, and offer any new files to external stores. This should be true unless the external checks are misbehaving", - "order": 58 - }, - "use_tsk": { - "type": "boolean", - "title": "Use TSK", - "description": "Whether raw filesystem access should be used", - "order": 29 - }, - "value": { - "type": "integer", - "title": "Value", - "description": "Value", - "order": 87 - }, - "xdev": { - "type": "string", - "title": "Xdev", - "description": "Behavior when ecountering device boundaries while doing recursive searches", - "enum": [ - "NEVER", - "ALWAYS", - "LOCAL" - ], - "order": 62 - }, - "xor_in_key": { - "type": "integer", - "title": "XOR in Key", - "description": "When searching memory we need to ensure we dont hit on our own process. This allows us to obfuscate the search string in memory to avoid us finding ourselves", - "order": 54 - }, - "xor_out_key": { - "type": "integer", - "title": "XOR in Key", - "description": "When searching memory we need to ensure we dont hit on our own process. This allows us to obfuscate the search string in memory to avoid us finding ourselves", - "order": 55 - } - }, - "required": [ - "flow_name" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class HuntingOutput(komand.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "results": { - "type": "string", - "title": "Results", - "description": "Issues found with TruffleHog", - "order": 1 - } - } -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/grr/icon_grr/actions/labeling/__init__.py b/plugins/grr/icon_grr/actions/labeling/__init__.py deleted file mode 100755 index 8156476cce..0000000000 --- a/plugins/grr/icon_grr/actions/labeling/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import Labeling diff --git a/plugins/grr/icon_grr/actions/labeling/action.py b/plugins/grr/icon_grr/actions/labeling/action.py deleted file mode 100755 index 2801307103..0000000000 --- a/plugins/grr/icon_grr/actions/labeling/action.py +++ /dev/null @@ -1,39 +0,0 @@ -import komand -from .schema import LabelingInput, LabelingOutput - - -# Custom imports below - - -class Labeling(komand.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="labeling", - description="Looks for exposed secrets in the git commit history and branches", - input=LabelingInput(), - output=LabelingOutput(), - ) - self.grrapi = None - - def run(self, params={}): - self.grrapi = self.connection.grrapi - query = params.get("query") - label = params.get("label") - label = [str(x) for x in label] - search_results = self.grrapi.SearchClients(query) - try: - for client in search_results: - type_client = type(client) - if type(client) is not type_client: - return {"result": "No clients found with the given query"} - client.AddLabels(label) - except Exception as e: - self.logger.error(e) - return {"results": "All clients have been labeled"} - - def test(self): - self.grrapi = self.connection.grrapi - if self.grrapi: - return {"results": "Ready to label"} - if not self.grrapi: - return {"results": "Not ready. Please check your connection with the GRR Client"} diff --git a/plugins/grr/icon_grr/actions/labeling/schema.py b/plugins/grr/icon_grr/actions/labeling/schema.py deleted file mode 100755 index a02961c789..0000000000 --- a/plugins/grr/icon_grr/actions/labeling/schema.py +++ /dev/null @@ -1,69 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import komand -import json - - -class Component: - DESCRIPTION = "Label clients based on search" - - -class Input: - LABEL = "label" - QUERY = "query" - - -class Output: - RESULTS = "results" - - -class LabelingInput(komand.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "label": { - "type": "array", - "title": "Label", - "description": "Label's clients", - "items": { - "type": "string" - }, - "order": 2 - }, - "query": { - "type": "string", - "title": "Query", - "description": "Search for clients", - "order": 1 - } - }, - "required": [ - "label", - "query" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class LabelingOutput(komand.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "results": { - "type": "string", - "title": "Results", - "description": "Labeling complete", - "order": 1 - } - } -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/grr/icon_grr/actions/listing/__init__.py b/plugins/grr/icon_grr/actions/listing/__init__.py deleted file mode 100755 index 169dcda7dc..0000000000 --- a/plugins/grr/icon_grr/actions/listing/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .action import Listing diff --git a/plugins/grr/icon_grr/actions/listing/action.py b/plugins/grr/icon_grr/actions/listing/action.py deleted file mode 100755 index 3e506ffcdb..0000000000 --- a/plugins/grr/icon_grr/actions/listing/action.py +++ /dev/null @@ -1,106 +0,0 @@ -import komand -from .schema import ListingInput, ListingOutput - -# Custom imports below -import json -from google.protobuf.json_format import MessageToJson - - -class Listing(komand.Action): - def __init__(self): - super(self.__class__, self).__init__( - name="listing", - description="Looks for exposed secrets in the git commit history and branches", - input=ListingInput(), - output=ListingOutput(), - ) - self.grrapi = None - self.query = None - self.result = {} - - def run(self, params={}): - self.grrapi = self.connection.grrapi - if params.get("hunts"): - self.hunts() - if params.get("hunt_approvals"): - self.hunt_approvals() - if params.get("grr_binaries"): - self.grr_binaries() - if params.get("clients"): - query = params.get("query").encode("utf-8", "ignore") - self.clients(query) - return {"result": self.result} - - def hunts(self): - try: - list_hunts = self.grrapi.ListHunts() - result = {} - count = 0 - for hunt in list_hunts: - data = hunt.data - data = MessageToJson(data) - result["hunt%s" % count] = json.loads(data) - count += 1 - self.result = komand.helper.clean(result) - except Exception as e: - self.logger.error(e) - - def hunt_approvals(self): - # Still testing, need to create a hunt to see the hunt approval and how the data comes out - try: - hunt_approvals = self.grrapi.ListHuntApprovals() - self.logger.info(hunt_approvals.data) - count = 0 - result = {} - for item in hunt_approvals: - data = item.data - data = MessageToJson(data) - result["approval%s" % count] = json.loads(data) - count += 1 - self.result = komand.helper.clean(result) - except Exception as e: - self.logger.error(e) - - def clients(self, query): - try: - search_results = self.grrapi.SearchClients(query) - result = {} - count = 0 - if not search_results: - return {"results": "No clients found"} - for client in search_results: - data = client.data - data = MessageToJson(data) - result["client%s" % count] = json.loads(data) - count += 1 - if result == {}: - self.logger.error("No clients found with provided query.") - return {"results": "No clients have been found"} - self.result = komand.helper.clean(result) - except Exception as e: - self.logger.error(e) - - def grr_binaries(self): - # Havn't tested it, but based on the other functions behaving similarly and the source code - # I am going to assume this works until tested - try: - binaries = self.grrapi.ListGrrBinaries() - count = 0 - result = {} - for x in binaries: - data = x.data - data = MessageToJson(data) - result["binary%s" % count] = json.loads(data) - count += 1 - self.result = komand.helper.clean(result) - except Exception as e: - self.logger.error(e) - self.logger.error("No GRR Binaries") - return {"results": "No GRR Binaries have been found"} - - def test(self): - self.grrapi = self.connection.grrapi - if self.grrapi: - return {"results": "Ready to list"} - if not self.grrapi: - return {"results": "Not ready. Please check your connection with the GRR Client"} diff --git a/plugins/grr/icon_grr/actions/listing/schema.py b/plugins/grr/icon_grr/actions/listing/schema.py deleted file mode 100755 index 75d77e2a4b..0000000000 --- a/plugins/grr/icon_grr/actions/listing/schema.py +++ /dev/null @@ -1,86 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import komand -import json - - -class Component: - DESCRIPTION = "List client information based on search" - - -class Input: - CLIENTS = "clients" - GRR_BINARIES = "grr_binaries" - HUNT_APPROVALS = "hunt_approvals" - HUNTS = "hunts" - QUERY = "query" - - -class Output: - RESULT = "result" - - -class ListingInput(komand.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "clients": { - "type": "boolean", - "title": "Clients", - "description": "Search clients", - "order": 5 - }, - "grr_binaries": { - "type": "boolean", - "title": "GRR Binaries", - "description": "List GRR binaries", - "order": 4 - }, - "hunt_approvals": { - "type": "boolean", - "title": "Hunt Approvals", - "description": "List hunt approvals", - "order": 3 - }, - "hunts": { - "type": "boolean", - "title": "Hunts", - "description": "List hunts", - "order": 2 - }, - "query": { - "type": "string", - "title": "Query", - "description": "Query to search for (e.g. 'host:suspicious.corp.com')", - "order": 1 - } - }, - "required": [ - "query" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class ListingOutput(komand.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "result": { - "type": "object", - "title": "Result", - "description": "Listing results", - "order": 1 - } - } -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/grr/icon_grr/connection/__init__.py b/plugins/grr/icon_grr/connection/__init__.py deleted file mode 100755 index a515dcf6b0..0000000000 --- a/plugins/grr/icon_grr/connection/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .connection import Connection diff --git a/plugins/grr/icon_grr/connection/connection.py b/plugins/grr/icon_grr/connection/connection.py deleted file mode 100755 index 9fc8679110..0000000000 --- a/plugins/grr/icon_grr/connection/connection.py +++ /dev/null @@ -1,31 +0,0 @@ -import komand -from .schema import ConnectionSchema - -# Custom imports below -from grr_api_client import api - - -class Connection(komand.Connection): - def __init__(self): - super(self.__class__, self).__init__(input=ConnectionSchema()) - - self.grrapi = None - self.api_endpoint = None - self.username = None - self.password = None - - def connect(self, params): - self.logger.info("Connect: Connecting...") - self.api_endpoint = params.get("api_endpoint") - self.username = params.get("credentials").get("username") - self.password = params.get("credentials").get("password") - ssl_verify = params.get("ssl_verify") - try: - self.grrapi = api.InitHttp( - api_endpoint=self.api_endpoint, - auth=(self.username, self.password), - verify=ssl_verify, - ) - except Exception as e: - self.logger.error("Please provide valid options to connect to the GRR API endpoint") - raise e diff --git a/plugins/grr/icon_grr/connection/schema.py b/plugins/grr/icon_grr/connection/schema.py deleted file mode 100755 index d7ca55725b..0000000000 --- a/plugins/grr/icon_grr/connection/schema.py +++ /dev/null @@ -1,75 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import komand -import json - - -class Input: - API_ENDPOINT = "api_endpoint" - CREDENTIALS = "credentials" - SSL_VERIFY = "ssl_verify" - - -class ConnectionSchema(komand.Input): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "api_endpoint": { - "type": "string", - "title": "API Endpoint", - "description": "The GRR API Endpoint to connect to", - "order": 1 - }, - "credentials": { - "$ref": "#/definitions/credential_username_password", - "title": "Username and Password", - "description": "Username and password", - "order": 2 - }, - "ssl_verify": { - "type": "boolean", - "title": "SSL Verify", - "description": "Verify server's SSL/TLS certificate", - "default": true, - "order": 3 - } - }, - "required": [ - "api_endpoint", - "credentials", - "ssl_verify" - ], - "definitions": { - "credential_username_password": { - "id": "credential_username_password", - "type": "object", - "title": "Credential: Username and Password", - "description": "A username and password combination", - "properties": { - "password": { - "type": "string", - "title": "Password", - "displayType": "password", - "description": "The password", - "format": "password", - "order": 2 - }, - "username": { - "type": "string", - "title": "Username", - "description": "The username to log in with", - "order": 1 - } - }, - "required": [ - "username", - "password" - ] - } - } -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/grr/icon_grr/tasks/__init__.py b/plugins/grr/icon_grr/tasks/__init__.py deleted file mode 100644 index 7020c9a4ad..0000000000 --- a/plugins/grr/icon_grr/tasks/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT - diff --git a/plugins/grr/icon_grr/triggers/__init__.py b/plugins/grr/icon_grr/triggers/__init__.py deleted file mode 100755 index bace8db897..0000000000 --- a/plugins/grr/icon_grr/triggers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT diff --git a/plugins/grr/icon_grr/util/__init__.py b/plugins/grr/icon_grr/util/__init__.py deleted file mode 100755 index bace8db897..0000000000 --- a/plugins/grr/icon_grr/util/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT diff --git a/plugins/grr/plugin.spec.yaml b/plugins/grr/plugin.spec.yaml deleted file mode 100644 index 89c5f9a331..0000000000 --- a/plugins/grr/plugin.spec.yaml +++ /dev/null @@ -1,744 +0,0 @@ -plugin_spec_version: v2 -extension: plugin -products: [insightconnect] -name: grr -title: Google Rapid Response -description: Organize and start threat hunts using GRR -version: 3.0.1 -vendor: rapid7 -support: community -status: [obsolete] -resources: - source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/grr - license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE - vendor_url: http://www.google.com -tags: -- incident response -- google -- grr -- hunt -- label -- list -hub_tags: - use_cases: [threat_detection_and_response] - keywords: [incident response, google, grr, hunt, label, list] - features: [] -enable_cache: true -connection: - api_endpoint: - title: API Endpoint - type: string - description: The GRR API Endpoint to connect to - required: true - credentials: - title: Username and Password - type: credential_username_password - description: Username and password - required: true - ssl_verify: - title: SSL Verify - type: boolean - description: Verify server's SSL/TLS certificate - default: true - required: true -actions: - listing: - title: Listing - description: List client information based on search - input: - query: - title: Query - description: Query to search for (e.g. 'host:suspicious.corp.com') - type: string - required: true - hunts: - title: Hunts - description: List hunts - type: boolean - required: false - hunt_approvals: - title: Hunt Approvals - description: List hunt approvals - type: boolean - required: false - grr_binaries: - title: GRR Binaries - description: List GRR binaries - type: boolean - required: false - clients: - title: Clients - description: Search clients - type: boolean - required: false - output: - result: - title: Result - type: object - description: Listing results - required: false - labeling: - title: Labeling - description: Label clients based on search - input: - query: - title: Query - description: Search for clients - type: string - required: true - label: - title: Label - description: Label's clients - type: '[]string' - required: true - output: - results: - title: Results - type: string - description: Labeling complete - required: false - hunting: - title: Hunting - description: Start a hunt on clients - input: - flow_name: - title: Flow Name - description: The name of the Flow you want to use - type: string - required: true - enum: - - Interrogate - - KeepAlive - - OnlineNotification - - CacheGrep - - ChromeHistory - - FirefoxHistory - - CheckRunner - - ArtifactCollectorFlow - - DumpACPITable - - DumpFlashImage - - FileFinder - - GetMBR - - ListVolumeShadowCopies - - Netstat - - ListProcesses - - CollectRunKeyBinaries - - RegistryFinder - flow_args: - title: Regex Checks - description: Enable high signal regex checks - type: boolean - required: false - default: false - lightweight: - title: Lightweight - description: Performs a light weight version of the interrogate - type: boolean - required: false - duration: - title: Duration - description: Until when should the client stay in the fast poll mode - type: integer - required: false - default: 3600 - email: - title: Email - description: Email address to send to. If not set, mail will be sent to the - logged in user - type: string - required: false - check_chrome: - title: Check Chrome - description: Checks Chrome - type: integer - required: false - check_firefox: - title: Check Firefox - description: Checks Chrome - type: integer - required: false - check_ie: - title: Check IE - description: Checks Internet Explorer - type: boolean - required: false - data_regex: - title: Data Regex - description: A regular expression to search for - type: string - required: false - grep_users: - title: Grep Users - description: A list of users to check. Default all users on the system - type: string - required: false - pathtype: - title: Path Type - description: Type of path access to use - type: string - required: false - enum: - - UNSET - - OS - - TSK - - Registry - - Memory - - TMPFILE - get_archive: - title: Get Archive - description: Gets Archived History as well (3 months old) - type: boolean - required: false - history_path: - title: History Path - description: Path to a profile directory that contains a History file - type: string - required: false - ch_username: - title: Chrome History Username - description: The user to get Chrome history for. If history_path is not set - this will be used to guess the path to the history files - type: string - required: false - ff_username: - title: Firefox History Username - description: The user to get FireFox history for. If history_path is not set - this will be used to guess the path to the history files - type: string - required: false - max_findings: - title: Maximize Findings - description: Summarize checks with more than N individual findings - type: integer - required: false - only_cpe: - title: Only CPE - description: Limit checks to hosts with cpe strings - type: string - required: false - only_label: - title: Only CPE - description: Limit checks to hosts with label strings - type: string - required: false - only_os: - title: Only OS - description: Limit checks to hosts of OS type(s) [Linux|OSX|Windows] - type: string - required: false - restrict_checks: - title: Restrict Checks - description: Only run checks with the specified check_ids - type: string - required: false - apply_parsers: - title: Apply Parsers - description: If 1, apply any relevant parser to the collected data. If 0, - return the raw collected data e.g Files or Registry Keys - type: boolean - required: false - artifact_list: - title: Artifact List - description: A list of Artifact class names - type: string - required: false - dependencies: - title: Dependencies - description: Specifies how dependencies should be handled. Use the knowledgebase as a cache. If knowledgebase isn't present, a new one will be populated - type: string - default: USE_CACHED - required: false - enum: - - USE_CACHED - - IGNORE_DEPS - - FETCH_NOW - ignore_interpolation_errors: - title: Ignore Interpolation Errors - description: If true, don't die if %%users.homedir%% and similar fail to expand. - It's common on windows for some user attributes to be missing if users have - never logged in. Enable this when you have multiple artifacts or paths and - want to report partial results - type: boolean - required: false - knowledge_base: - title: Knowledge Base - description: An optional knowledge base to use, if not specified we retrieve - one from the client object - type: string - required: false - max_file_size: - title: Max File Size - description: The maximum size of files we will download in bytes, 500MB by - default - type: string - required: false - on_no_results_error: - title: Oh No Results Error - description: The maximum size of files we will download in bytes, 500MB by - default - type: boolean - required: false - split_output_by_artifact: - title: Split Output by Artifact - description: If True, use output as a directory and write a separate collection - for each artifact collected - type: boolean - required: false - use_tsk: - title: Use TSK - description: Whether raw filesystem access should be used - type: boolean - required: false - component_version: - title: Component Version - description: Version of Chipsec component to be used - type: string - required: false - logging: - title: Logging - description: If the logging is set to true, the client sends log, including - Chipsec's log - type: boolean - required: false - table_signature_list: - title: Table Signature Lists - description: Signature of ACPI tables to be dumped - type: string - required: false - chunk_size: - title: Chunk Size - description: A heartbeat will be emitted every chunk_size.This could be reduced - in case the process times out - type: integer - required: false - log_level: - title: Log Level - description: Set the log level. If set, the log returned will include additional - information reported by Chipsec - type: integer - required: false - notify_syslog: - title: Notify Syslog - description: 'If true, a message will be written by the client to the syslog - before running the action. This can be used for debugging in case the client - crashes ' - type: boolean - required: false - action: - title: Action - description: Use an action - type: string - required: false - enum: - - STAT - - HASH - - DOWNLOAD - conditions: - title: Conditions - description: These conditions will be applied to all files that match the - path arguments - type: string - required: false - enum: - - MODIFICATION_TIME - - ACCESS_TIME - - INODE_CHANGE_TIME - - SIZE - - CONTENTS_REGEX_MATCH - - CONTENTS_LITERAL_MATCH - - EXT_FLAGS - paths: - title: Paths - description: A path to glob that can contain %% expansions - type: string - required: false - min_last_modified_time: - title: Min Last Modified Time - description: File must be modified after this time - type: integer - required: false - max_last_modified_time: - title: Max Last Modified Time - description: File must be modified before this time - type: integer - required: false - min_last_access_time: - title: Min Last Access Time - description: File must be accessed after this time - type: integer - required: false - max_last_access_time: - title: Min Last Access Time - description: File must be accessed before this time - type: integer - required: false - min_last_inode_change_time: - title: Min Last Inode Change Time - description: File's inode must be changed after this time - type: integer - required: false - max_last_inode_change_time: - title: Max Last Inode Change Time - description: File's must be changed before this time - type: integer - required: false - min_file_size: - title: Min File Size - description: Minimum file size in bytes - type: integer - required: false - filefinder_regex: - title: FileFinder Regex - description: The regular expression which will be used to search - type: string - required: false - mode: - title: Mode - description: When should searching stop? Stop after one hit or search for - all - type: string - required: false - enum: - - FIRST_HIT - - ALL_HITS - bytes_before: - title: Bytes Before - description: Include this many bytes before the hit - type: integer - required: false - bytes_after: - title: Bytes After - description: Include this many bytes after the hit - type: integer - required: false - start_offest: - title: Start Offset - description: Start searching at this file offset - type: integer - required: false - length: - title: Length - description: How far (in bytes) into the file to search or the length of the - MBR to read - type: integer - required: false - literal: - title: Literal - description: Search for this literal string - type: string - required: false - start_offset: - title: Start offset - description: Start searching at this file offset - type: integer - required: false - xor_in_key: - title: XOR in Key - description: When searching memory we need to ensure we dont hit on our own - process. This allows us to obfuscate the search string in memory to avoid - us finding ourselves - type: integer - required: false - xor_out_key: - title: XOR in Key - description: When searching memory we need to ensure we dont hit on our own - process. This allows us to obfuscate the search string in memory to avoid - us finding ourselves - type: integer - required: false - max_size: - title: Max Size - description: The maximum size of files - type: integer - required: false - oversized_file_policy: - title: Max Size - description: What should GRR do with files that are larger than max_size - type: string - required: false - enum: - - SKIP - - HASH_TRUNCATED - - DOWNLOAD_TRUNCATED - use_external_stores: - title: Use External Stores - description: If true, look in any defined external file stores for files before - downloading them, and offer any new files to external stores. This should - be true unless the external checks are misbehaving - type: boolean - required: false - resolve_links: - title: Resolve links - description: If true, the action will yield stat information for link targets, - if false, the stat for the link itself will be returned - type: boolean - required: false - follow_links: - title: Follow links - description: Should symbolic links be followed in recursive directory listings - type: boolean - required: false - process_non_regular_files: - title: Process Non Regular Files - description: 'Look both into regular files and non-regular files (devices, - named pipes, sockets). NOTE: This is very dangerous and should be used with - care' - type: boolean - required: false - xdev: - title: Xdev - description: Behavior when ecountering device boundaries while doing recursive - searches - type: string - required: false - enum: - - NEVER - - ALWAYS - - LOCAL - upload_token: - title: Upload Token - description: 'An upload token to use with the direct upload functionality. - This token contains the hmac authenticated policy that determines for how - long the client is allowed to upload files to the server. This is comparable - to the policy document used by GCS: https://cloud.google.com/storage/docs/xml-api/post-object#policydocument' - type: boolean - required: false - listening_only: - title: Listening Only - description: If set, only listening connections are returned - type: boolean - required: false - connection_states: - title: Connection States - description: Network connection states to match. If a process has any network - connections in any status listed here, it will be considered a match - type: '[]string' - required: false - enum: - - UNKNOWN - - CLOSED - - LISTEN - - SYN_SENT - - SYN_RECV - - ESTABLISHED - - FIN_WAIT1 - - FIN_WAIT2 - - CLOSE_WAIT - - CLOSING - - LAST_ACK - - TIME_WAIT - - DELETE_TCB - - NONE - - CLOSE - fetch_binaries: - title: Fetch Binaries - description: Fetches Binaries - type: boolean - required: false - filename_regex: - title: Filename Regex - description: Regex used to filter the list of processes - type: string - required: false - hunt_name: - title: Hunt Name - description: The name of the class implementing the hunt to run - type: string - required: false - description: - title: Description - description: The description of this hunt - type: string - required: false - priority: - title: Priority - description: The priority used for this flow - type: string - required: false - enum: - - LOW_PRIORITY - - MEDIUM_PRIORITY - - HIGH_PRIORITY - notification_event: - title: Notification Event - description: An event name for an event listener. An event will be published - to this listener once the flow finishes - type: string - required: false - queue: - title: Queue - description: The queue to use for the hunt - type: string - required: false - cpu_limit: - title: CPU Limit - description: A limit on the client CPU seconds used by this flow - type: integer - required: false - network_bytes_limit: - title: Network Bytes Limit - description: A limit on the total traffic used by this flow - type: integer - required: false - client_limit: - title: Client Limit - description: 'Maximum number of clients participating in the hunt. Best practice - is for all hunts to use a limit to start with and remove it only when client - impact has been assessed by looking at hunt stats. Note that this limit - can be overshot by a small number of clients if there are multiple workers - running ' - type: integer - required: false - expiry_time: - title: Expiry Time - description: Expiry time for the hunt - type: integer - required: false - client_rate: - title: Client Rate - description: The maximum number of clients to engage per minute. A rate of - 0 means to schedule clients as fast as possible - type: integer - required: false - crash_alert_email: - title: Crash Alert Email - description: An email address to send mails to when a client crashes during - execution of this hunt - type: string - required: false - match_mode: - title: Match Mode - description: Match mode to trigger this hunt - type: string - required: false - enum: - - MATCH_ALL - - MATCH_ANY - label: - title: Label - description: Label that triggers this hunt - type: '[]string' - required: false - operating_system: - title: Operating System - description: Type of operating system to trigger this hunt - type: string - required: false - enum: - - Os_windows - - Os_linux - - Os_darwin - regex: - title: Regex - description: Use a regular expression to trigger this hunt - type: boolean - required: false - attribute_regex: - title: Attribute Regex - description: The regular expression - type: string - required: false - field: - title: Field - description: Field Specification - type: string - required: false - default: UNSET - enum: - - UNSET - - USERNAMES - - UNAME - - FQDN - - HOST_TIPS - - CLIENT_NAME - - CLIENT_DESCRIPTION - - SYSTEM - - MAC_ADDRESSES - - KERNEL_VERSION - - OS_VERSION - - OS_RELEASE - - CLIENT_LABELS - - INSTALL_TIME - - CLIENT_VERSION - - LAST_BOOT_TIME - - CLIENT_CLOCK - integer: - title: Integer - description: Integer to trigger this hunt - type: boolean - required: false - operator: - title: Operator - description: Operator - type: string - required: false - enum: - - EQUAL - - LESS_THAN - - GREATER_THAN - value: - title: Value - description: Value - type: integer - required: false - output_plugin_name: - title: Output Plugin Name - description: The name of the output plugin - type: string - required: false - enum: - - EmailOutput - - BigQueryOutput - email_address: - title: Email Address - description: The email address that messages will be sent to - type: string - required: false - emails_limit: - title: Emails Limit - description: The emails limit - type: integer - required: false - export_files_contents: - title: Export Files Contents - description: 'If this is true, open files and export their full or partial - contents. Note: this may require additional datastore roundtrips and slow - down the export process, also exporting file contents may significantly - increase size of the exported data' - type: boolean - required: false - follow_urns: - title: Follow URNs - description: 'If this is true, follow urns and try to export not only the - urns themselves, but also the data they are pointing to. Note: this may - require additional datastore roundtrips and slow down the export process' - type: boolean - required: false - export_files_hashes: - title: Export Files Hashes - description: If this is true, export hashes when dealing with file-related - values. The files won't be hashed during the export, hashes will only be - exported if they were collected before the export. This option affects exporting - VFSFile and StatEntry RDFValues. This is true by default even though it - requires extra datastore roundtrips because it's very useful and users expect - the hashes to be there - type: boolean - required: false - convert_values: - title: Convert Values - description: If true, convert values for export-friendly format - type: boolean - required: false - annotations: - title: Annotations - description: Annotations to add to exported data. This field can be used to - differentiate sets of exported data inside a particular exported type. e.g. - data collected by users vs. data collected by cronjob - type: '[]string' - required: false - output: - results: - title: Results - type: string - description: Issues found with TruffleHog - required: false diff --git a/plugins/grr/requirements.txt b/plugins/grr/requirements.txt deleted file mode 100755 index 718a6919e6..0000000000 --- a/plugins/grr/requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -# List third-party dependencies here, separated by newlines. -# All dependencies must be version-pinned, eg. requests==1.2.0 -# See: https://pip.pypa.io/en/stable/user_guide/#requirements-files -ConfigParser==3.5.0 -grr-response-proto==3.2.3.post2 -cryptography==2.0.3 -ipython==5.0.0 -protobuf==3.3.0 -requests==2.20.0 -Werkzeug==0.11.3 -grr-api-client==3.2.3.post2 diff --git a/plugins/grr/setup.py b/plugins/grr/setup.py deleted file mode 100755 index f12dc2500d..0000000000 --- a/plugins/grr/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT -from setuptools import setup, find_packages - - -setup(name="grr-rapid7-plugin", - version="3.0.1", - description="Organize and start threat hunts using GRR", - author="rapid7", - author_email="", - url="", - packages=find_packages(), - install_requires=['komand'], # Add third-party dependencies to requirements.txt, not here! - scripts=['bin/icon_grr'] - )