3KR:dZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z ddl m Z ddlmZddlmZmZddlmZddlmZdd lmZmZdd lmZdd lmZmZdd lmZmZdd l m!Z!dZ"d\Z#Z$Z%d\Z&Z'Z(Z)Z*Z+dZ,dde*ddddde#ddddde+e,e$fe"zZ-dx\Z.Z/Z0ej1dej2Z3ee4Z5ee e5j6Z7Gd!d"e8Z9Gd#d$e8Z:Gd%d&e8Z;Gd'd(e<Z=Gd)d*e +Z>Gd,d-e>Z?Gd.d/e>Z@Gd0d1e>ZAGd2d3e>ZBGd4d5e>ZCGd6d7eCZDGd8d9e>ZEGd:d;e>ZFGd<d=e +ZGGd>d?eGZHGd@dAeGZIGdBdCeIZJGdDdEeIZKGdFdGeKZLGdHdIeKZMGdJdKeLZNGdLdMeGZOGdNdOeHZPGdPdQeGZQGdRdSeHZRGdTdUZSdedVZTdeUdWeVfdXZWdYeUdZeUdWeeeUeXffd[ZYdWeeUfd\ZZd]Z[d^eVfd_Z\d`Z]daeeUdWeeUfdbZ^dceUdWe_fddZ`dS)fz SecAuditLog parser N)ABCMetaabstractmethod)suppress)copy) CookieError SimpleCookie)product) getLogger)OptionalTuple)parse_qs)DAY rate_limit)USER_IDENTITY_FIELD user_identity) ModsecSensor)inbound_anomality_scoreoutbound_anomality_score)severityadvancedheaders)uri http_methodformquery attackers_ip status_code engine_modez User-AgentHosttransaction_idrulemsgmessage access_deniedvertagProducermodsec_versionvendor)cookie authorizationz((Inbound|Outbound) Anomaly Score.*?(\d+))periodceZdZdZdS) ParseErrorE log as logger.exception(*e.args) to avoid sentry duplicates N__name__ __module__ __qualname____doc__R/opt/imunify360/venv/lib/python3.11/site-packages/im360/subsys/modsec_audit_log.pyr.r.D Dr6r.ceZdZdZdS)_AmbiguousSeverityz to log as warning Nr0r5r6r7r:r:Lr8r6r:ceZdZdZdS)MalformedFileErrorr/Nr0r5r6r7r<r<Tr8r6r<ceZdZdS)_MiscDataNotInterestingN)r1r2r3r5r6r7r>r>\sDr6r>cNeZdZdZedZeedZdS)_SerialLogSectionParserNc\|js Jd|j|duS)Nzregex should be implemented)_IS_APPLICABLE_SINCE_REGEXmatchclslines r7is_applicable_sincez+_SerialLogSectionParser.is_applicable_sincecs6-LL/LLL--33D99EEr6cdS)z_ :return: name, value tokens :raise ValueError: if cannot parse string Nr5rDs r7parse_name_value_tokensz/_SerialLogSectionParser.parse_name_value_tokenshs  r6)r1r2r3rB classmethodrGrrIr5r6r7r@r@`s[!%FF[F  ^[   r6r@) metaclasscdeZdZejdZejdZedZdS)_SectionAParserz^-{2,3}\w+-{1,3}A--$z ^\[.*?\] (?P\S+) (?P\S+)c#K|j|}|s6tdt |t  t j|d}nJ#t$r=td|dt wxYwdt|fVd|dfVdS)Nz)--section-A--: cannot parse this line: %sipz5--section-A--: cannot use %s for IPv4 or IPv6 addressrr id) _PARSE_IP_REGEXrCloggerwarningreprr> ipaddress ip_addressgroup ValueErrorstr)rErFrC ipv4_or_ipv6s r7rIz'_SectionAParser.parse_name_value_tokensvs#))$// , NN;T$ZZ   *++ + ,$/ D0A0ABBLL , , , NNG A   *++ +  ,c,////// D 1 1111111s 'A>>ACN) r1r2r3recompilerBrRrJrIr5r6r7rMrMrsR!+,C!D!D bj!DEEO22[222r6rMcdeZdZejdZejdZedZdS)_SectionBParserz^-{2,3}\w+-{1,3}B--$z^(\S*): ?(.*)$c#K|j|}|rR|d|dpd}}t||\}}|rt||gfVdSdS |^}}} |rtj |rgt|fVtj |} t| jfVtjr#t"t%| jfVdSdSdSdS#t($rt+wxYw)NrP)_PARSE_NAME_VALUErCrX#obfuscate_if_sensitive_and_requiredHEADERSsplitisupperospathisabs HTTP_METHODurllibparseurlparseURIrSEND_ADDITIONAL_DATA QUERY_PARAMS obfuscaterrYr>) rErFrCnamevaluemaybe_obfuscated_value is_requiredmethodr_parseds r7rIz'_SectionBParser.parse_name_value_tokenss%++D11  0++a..%++a..*@D%D4D%@@ & >&<======= > > 0"&**,,a>>##D c(:(:D%v----#\22377Fv{****#8D*Ifl,C,CCCCCCC DDDD DD 0 0 0-/// 0s 2B-D''EN) r1r2r3r\r]rBrbrJrIr5r6r7r_r_sS!+,C!D!D" #45500[000r6r_cDeZdZejdZedZdS)_SectionCParserz^-{2,3}\w+-{1,3}C--$c#VKtjrtt|fVdSdSN)rro FORM_PARAMSrqrDs r7rIz'_SectionCParser.parse_name_value_tokenss8  , /y. . . . . . / /r6Nr1r2r3r\r]rBrJrIr5r6r7rzrzs@!+,C!D!D//[///r6rzcdeZdZejdZejdZedZdS)_SectionFParserz^-{2,3}\w+-{1,3}F--$z^HTTP/\d\.\d (\d+).*$c#K|j|}|stt|dfVdS)NrP)_STATUS_CODE_REGEXrCr> STATUS_CODErX)rErFrCs r7rIz'_SectionFParser.parse_name_value_tokenssQ&,,T22 .)++ +u{{1~~- - - - - -r6N) r1r2r3r\r]rBrrJrIr5r6r7rrsS!+,C!D!D#$<==..[...r6rc&eZdZejdZejdZejdZejdZejdZ ejdZ e dZ e dZ e d Ze d Zd S) _BaseSectionHParserz^-{2,3}\w+-{1,3}H--$z ([^=]*) (ModSecurity):\s+([^=]*)z(\[\w+ ".*?"\])zAccess denied with code \d+z\[(\w+) "(.*?)"\]z (\[\w+ ".*?$)c||\}}|dvr|g|||RS|dkr|||S|dkrt}|d}||fS)N)Message ModSecurityz Apache-Errorz Engine-Mode")_parse_name_value_parse_message_parse_apache_err ENGINE_MODEstrip)rErFrrrss r7rIz+_BaseSectionHParser.parse_name_value_tokenss++D11 e - - -9#,,UD9999 9 > ! !((55 5 = DKK$$EU{r6c|d\}}|ddkrtd|dd}||fS)z; :raise ValueError: if cannot parse string rPmaxsplit:zExpecting sort of "Name: value"N)rerY)rEsrrrss r7rz%_BaseSectionHParser._parse_name_valuesP ggqg)) e 8s??>?? ?9DU{r6c|j|}|r2|\}}}|g||dRSt )N)_PARSE_MESSAGE_APACHE_ERRORrCgroupsrr>)rEmsgvalrwrCrrmodsecs r7rz%_BaseSectionHParser._parse_apache_errsb/55f==  ,#llnnOAtV8#,,VR8888 8*++ +r6c|j|}d|}|}|D]*}||d}+|j|}|D]*}||d}+t |}|j|} | rd|d<|j |D]}| \} } | | } | b| dkr)td|tt!| t"s| gx} || <| | n0| d kr| g|| <n#| d kr| |d <| t'd |n| || <| d kr$t)| } || |g|RS)aB Parse string with format [key "val"] [key "val"] ... [key "val"] to dictionary {"key": "val", "key": "val", ...} In case when there is uncompleted value part e.g. '[key "val' with lost '"]' in the end it also returns incomplete part as string '[key "val'  r)r#Tr$NrzAmbiguous severity: %rr&rQr!z&rule field is None, modsec message: %sr")_PARSE_MESSAGE_REGEXfindalljoinreplacer_INCOMPLETE_MESSAGE_REGEXdict_PARSE_ACCESS_DENIED_CODEsearch_PARSE_MESSAGE_TOKENS_REGEXfinditerrgetrSrTr: isinstancelistappendthrottled_log_exceptionget_anomality_score_itemsupdate)rEraudit_log_line tokens_listtokensmsgtxttokenincomplete_partresultrCrrtextexistinganomality_score_itemss r7rz"_BaseSectionHParser._parse_messages.66v>> +&&  7 7E^^E2..4466FF7??GG$ 7 7E^^E2..4466FFf%%%-44V<<  +&*F? #4==fEE 5 5EJD$zz$''H#:%%NN#;^LLL,...!(D119/7j8Hvd|%%%% $vt !%v<+@& $t u}}(A$(G(G% 3444''''r6N)r1r2r3r\r]rBrrrrrrJrIrrrr5r6r7rrs!+,C!D!D","*+##&2:&899 * +I J J","*-A"B"B * +; < <  [   [ ,,[,2(2([2(2(2(r6rcJeZdZdZdedddZdZdZfdZxZ S)_SectionHParserz3 _BaseSectionHParser + DEF-2617 workaround rr)rrrsrcountcFd|_t|j|_dS)NF)_open_matched_stringr_INCOMPLETE_RESULT_incomplete_resultselfs r7__init__z_SectionHParser.__init__5s#$)!"&t'>"?"?r6c#Kg} t|}|jdrL|jd}|jd}|dxx|jdz cc<|||ft |dkr|d|d|d }}}|d krEd |vrA|dxx|z cc<|||ft |j|_ni||jd<||jd<||jd<d|jd<n@|d|d}}|||ft |j|_|d kod |v|_nO#t$rA|jd} | r | |j kr|jst| |jd|z|}|d dt |dkrq|jd |d|jd}|jd}|||ft |j|_nK|jd |d|d|jd<|jdxxdz cc<YnwxYw|D] \}}||fV d S#|D] \}}||fV wxYw) a In case with correct line e.g. Name: Message [key "val"] [key "val"] [key "val"] if there is no data in self._incomplete_result: returns result of _BaseSectionHParser.parse_name_value_tokens else returns name, value of self._incomplete_result and name, value of current line it is possible since this function is generator. In case with incomplete line e.g. Name: Message [key "val"] [key "val"] [key "val if there is no data in self._incomplete_result: collect name, value and incomplete part values that was got from _BaseSectionHParser.parse_name_value_tokens to self._incomplete_result and wait next line. returns empty list else: does the same but returns name, value of self._incomplete_result In case with non 'name: value' format: if there is no data in self._incomplete_result: raises else: Concatenate incomplete result of previous iteration with current line and parse it by _BaseSectionHParser._parse_message. if there is still incomplete line: it updates current self._incomplete_result and returns empty list else: returns name, value from collected data rrrrsr#rrrPrarz[MatchedStringN)superrIrrlenrrrrY_MAX_INCOMPLETE_MESSAGEr>rpopr) rrFr_res_name_valuerrrs incomplete_count __class__s r7rIz'_SectionHParser.parse_name_value_tokens9skB3 "7722488D2&w/ //709y!!!T%<=N%OO!!! ufo...4yyA~~*.q'47DGZe9$$)9T)A)A)$$$ 2$$$MM4-000.243J.K.KD++6:D+F3778D+G44"1gtAwe tUm,,,*.t/F*G*G' !>&6$&>  % %Y 6 6 6,W5F 4Vd&BBB041333&&'(9:TA4D GKK " " "4yyA~~'077Q@@@.v6/8 tUm,,,*.t/F*G*G'''077Q@@@=A!W'(9:'000A5000+ 6` & " " eEk!!!! " "v " " eEk!!!! "s*!E1E K1E J=:K<J==KK ) r1r2r3r4rrrrrI __classcell__)rs@r7rr(s    @@@U"U"U"U"U"U"U"U"U"r6rcDeZdZejdZedZdS)_SectionZParserz^-{2,3}\w+-{1,3}Z--$c td)Nz&Expecting this method never be called.NotImplementedErrorrDs r7rIz'_SectionZParser.parse_name_value_tokenss!"JKKKr6Nr~r5r6r7rrsE!+,C!D!DLL[LLLr6rcDeZdZejdZedZdS)_SectionNotInterestedInParserz^-{2,3}\w+-{1,3}[^ABHZ]--$ctr|)r>rDs r7rIz5_SectionNotInterestedInParser.parse_name_value_tokenss%'''r6Nr~r5r6r7rrs@!+,I!J!J(([(((r6rceZdZddeddDZedZdZe dZ e dZ d S) Parserrc#ZK|]&}t|dkt|V'dS)%N)chr).0cs r7 zParser.sD q66S== A ===r6 cdS)z :param bytes_: audit log line :return dict: for complete result and None for incomplete. See unit tests for result dict fields. :raise ParseError: Nr5rbytes_s r7feedz Parser.feeds  r6cdSr|r5rs r7flushz Parser.flushs r6c ||S#t$r)tj||jcYSwxYw)z6 apply fallback on UnicodeDecodeError )safe) decode_bytesUnicodeDecodeErrorrkrlquote_from_bytes_SAFE_UNQUOTED)rErs r7_adaptive_decode_byteszParser._adaptive_decode_bytessg  ##F++ +!   <00S/1    s0A  A c*|S)zD because cannot mock 'read-only' bstr.decode() attr )decode)rs r7rzParser.decode_bytess }}r6N) r1r2r3rrangerrrrrJr staticmethodrr5r6r7rrsWW    N  ^      [ \r6rc6eZdZdZgZddZdZdZdZdZ dS) _RevolverParser NcT||_||j|_dSzn :param str audit_logdir_path: audit log dir path for ModSecurity concurrent mode N)_audit_logdir_path_revolve_SKIP_FIRST_NUM_ERRORS_skip_first_num_errorsraudit_logdir_paths r7rz_RevolverParser.__init__s* #4 &*&A###r6c ||}|rd|_n-#t$r |jdkr|xjdzc_YdSwxYw|S)NrrP) _feed_implrrr.)rrrs r7rz_RevolverParser.feeds 0__V,,F||~~ 0/0+   *Q..++q0++tt   s3%AAc4|jSr|)_current_parserrrs r7rz_RevolverParser.flushs#))+++r6c8tdt|jdzD]s} |j|cS#t $rH}|t|jkr|nt d||Yd}~ld}~wwxYwdS)NrPz:Neither of available parsers is capable to parse this: %r )rr_available_parsersrrr.r)rrattemptes r7rz_RevolverParser._feed_implsQD$; < BBc|t|jdks Jdtd|jdj|jdj|jdd|jddz|_|jd}t }|j |j|d<|di||_dS) zExchange parser to the nextraz4Count of available_parsers should not be less than 2z Swap %s<->%srrPNrr5)rrrSinfor1rrr)rrE parser_kwargss r7rz_RevolverParser._revolves ' ( (A - - - A . - -   #A & /  #A & /     #ABB '$*A"1"*E E  %a(  " .151HM- ."s33]33r6r|) r1r2r3rrrrrrrr5r6r7rrsv BBBB$,,,   44444r6rc0eZdZdZdedefdZdZdZdS)_JsonLogParserBasec "i|_g|_dSr|)_accumulating_result_accumulating_linesrrws r7rz_JsonLogParserBase.__init__s$&!#%   r6datareturnctr|r)rrs r7parse_json_dataz"_JsonLogParserBase.parse_json_datas!###r6cv||}|r |j||t j||_|S#t$rYdSt$r}td|d||d}~wwxYwdS)N#Error occurs while parse json line , reason: ) rrstripr rrjsonloadsr rr> Exceptionr.rrrFrs r7rz_JsonLogParserBase.feed!s**6==??;;   (//555,0,@,@Jt$$--)zz||#*   tt    jttQQ    sAB B6 B6B11B6c| t|j|ji|_g|_S#i|_g|_wxYwN) debug_ctx)mk_modsec_indicent_listr r rs r7rz_JsonLogParserBase.flush2sX **)T5M)+D %')D $ $)+D %')D $ ) ) ) )s+;N)r1r2r3rrrrrr5r6r7r r sc&&&$D$T$$$$"*****r6r c"eZdZdZdedefdZdS)_JsonLogParserv2z&Parse ModSecurity v2 json log entries.rrchd}||stdi}|d}tj} t t j|d|t<n=#t$r0t d|dtwxYw| dd|d<g|t<|d d iD]<\}}t!||\}} | r"|t||g=|d d r|dd ^} } } | rut(j| rV| |t.<t0j| } | j|t6<|rt9| j|t<<|d d r8|r6t9d |dd |t@<|d  dr|d d|tB<|d drqtE|ddt r$tG|dd\}} ||d<n,|dd^}}tG|\}} ||d<||d<|d dr|dd|tH<|d drd|ddD|d<|S)a The contents of the log entry can be seen here https://github.com/SpiderLabs/ModSecurity/blob/v2/master/apache2/msc_logging.c#L644 Optional fields may be omitted due to SecAuditLogParts setting. Expected data (some unused keys are omitted): {'transaction': { 'time': str, 'transaction_id': str, 'remote_address': str, 'remote_port': int, 'local_address': str, 'local_port': int }, 'request': { 'request_line': str, # optional field 'body': [], # optional field 'headers': {}, # optional field }, 'response': { 'protocol': str, # optional field 'body': str, # optional field 'headers': {}, # optional field 'status': int, # optional field }, 'audit_data': { 'producer': str or [], # optional field 'messages': [], # optional field 'error_messages': [], # optional field 'engine_mode': str, # optional field } } >requestresponse audit_data transactionz)Not expected json data for ModSecurity v2r%remote_address&Cannot use %s for IPv4 or IPv6 addressr -r"r request_linebodyrr#statusr$producerr(r)rmessagescPg|]#}t|dd$S)rr)rr)rr"s r7 z4_JsonLogParserv2.parse_json_data..s=%%% ..sB77:%%%r6 MessageList)%issubsetkeysr.rrorZrVrW ATTACKERS_IPrYrSrTr>rrditemsrcrrerfrgrhrirjrkrlrmrnrqrrprr}rrget_producer_datar)rrexpected_data_keysrr%additional_data_is_requiredheaderrsrtrurvrrwrxversionmodsec_full_namevendorss r7rz _JsonLogParserv2.parse_json_data?sB    "**499;;77 JHII I=) &2&G# ,#&$[1A%BCC$$F<  , , , NN8,-   *++ +  , $/??3CS#I#I w!)_00B??EEGG I IMFE4FEBB & Iw&&0F'GHHH  ?  ~ . . C"9on=CCEEOFC!~~ CBGMM#$6$6 C&,{#..s33$ks .C+4V\+B+BF<(  ?  v & & N+F N"+BGGDOF4K,L,L"M"MF;      ) ) ="&z"28"> 3.tL/A*/MNN +2'((-1,-? -K* 7./?@@ #*x +2'(   ! !- 0 0 D"&|"4]"CF;    ! !* - - %% -j9%%%F= ! s /B:B<N)r1r2r3r4rrr5r6r7r r <sD00aDaTaaaaaar6r c,eZdZdZiZdZdedefdZdS)_KeyMappedJsonLogParserv3z&Parse ModSecurity v3 json log entries.ct|tr fd|DSt|trfd|DS|S)z9 Assume that *obj* is json serializeble. ci|]G\}}||dkr|n|HS)r)lower_to_lower_keys)rkvrs r7 z<_KeyMappedJsonLogParserv3._to_lower_keys..s_Aq ./ggii9.D.DD''***!r6c:g|]}|Sr5)rA)ritemrs r7r/z<_KeyMappedJsonLogParserv3._to_lower_keys..s'>>>$D''-->>>r6)rrr4r)robjs` r7rAz(_KeyMappedJsonLogParserv3._to_lower_keyss c4  IIKK   T " " >>>>#>>> >Jr6rrcj|jstdddi}||kr(tdt dh}||krt d||}i}|d}tj } ttj |d|t<n=#t$r0td|dt wxYw||jd d }|t d t||d <g|t <|d d iD]<\}} t%|| \} } | r"|t || g=|d d|t(<t*j|d d} | j|t2<|rt5| j|t8<|d dr%|r#t5|d d|t:<|d|jd|t<<|drb|dd|d<t?|dd\} }| |d<|d|jd|t@<|drg|d<|dD]}|d}t|!d|d<d|vr|dn|d|d<|d d }|d p|d!}||d"<|dd#k|d$<|dr(|"tG|d|d||S)%a Parse log entry data for JSON SecAuditLogFormat. https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecAuditLogFormat The contents of the log entry can be seen here https://github.com/SpiderLabs/ModSecurity/blob/v3/master/src/transaction.cc#L1622 Optional fields may be omitted due to SecAuditLogParts setting. Expected data: {'transaction': { 'client_ip': str, 'time_stamp': str, 'server_id': str, 'client_port': int, 'host_ip': str, 'host_port': int, 'unique_id': str, 'request': { 'http_version': str, 'method': str, 'uri': str, 'body': str, # optional field 'headers': {}, # optional field }, 'response': { 'body': str, # optional field 'headers': {}, # optional field 'http_code': int, }, # optional fields below 'producer': { 'components': [], 'connector': str, 'modsecurity': str, 'secrules_engine': str, }, 'messages': [{'details': {'accuracy': str, 'data': str, 'file': str 'lineNumber': str, 'match': str, 'maturity': str, 'reference': str, 'rev': '1', 'ruleId': str, 'severity': str, 'tags': [], 'ver': str}, 'message': str}]}} z7_KeyMappedJsonLogParserv3 misses KEYS_MAPPER definitionerrorz/ModSecurity was not compiled with JSON support.zRSecAuditLogFormat set to JSON, but ModSecurity was not compiled with JSON support.r%z/Not expected json data for Coraza/ModSecurityV3 client_ipr'r Nz=Missing unique id field in json data for Coraza/ModSecurityV3r"rrvrr*r#rr, componentsr) modsecurityr(secrules_enginer-r0detailsruleidr!r"r#rhosthostnameir$)$ KEYS_MAPPERrrSrTr>r2r.rArrorZrVrWr3rYrrdr4rcrrjrkrlrmrhrnrqrrpr}rr5rrrr)rr error_datar6rr%r7r r8rsrtrurxr9rwr"r#rrQs r7rz)_KeyMappedJsonLogParserv3.parse_json_datasb %I  F  :   NNB   *++ ++_ 99;;, , ,NOO O""4((=) &2&G# ,#&$[%=>>$$F<  , , , NN8K(   *++ +  ,%  - .    !O  $'~#6#6 w(377 2FFLLNN I IMFE4FEBB & Iw&&0F'GHHH))4X>{&&{9'=e'DEEks & ;#,V\#:#:F< y ! % %f - - L2M L"+K ,B6,J"K"KF; )*599  ] +  { ??: & & *:6|DF8 *J' 6JGQ(/F# $"-j"9"="= !23##F;  ??: & & 6$&F= !":. 6 6i."%gkk(&;&;"<"<"'3,,CJJCGGI4F4F&i0;";;v..E'++f2E2E&. #+1-+@C+G(;;u%%NNN#rrs r7rz_JsonPrettyLogParser.feed_s`**6==??;;  s{{+/1D,$B/$E  $ + +D 1 1 1s{{ 040D0D 2774+C#D#DEE11D- ::<<'.   44 $*44$/  {sAC D* D3D  DN)r1r2r3rr5r6r7r^r^^s#r6r^cHeZdZdZeeeeee e fZ dZ dZ dZdZdZdZdS) _NativeLogParsera audit log parser state machine Parse log entry ModSecurity 2 Data for Native audit log format. https://github.com/SpiderLabs/ModSecurity/wiki/ModSecurity-2-Data-Formats#Audit_Log More about ModSecurity log message format https://gerrit.cloudlinux.com/plugins/gitiles/defence360/+/refs/changes/73/111973/1/opt/DEF-21076-multiline-modsec-header-field-alert/README.txt Expected data: --2172df61-A-- [02/Feb/2018:11:49:22 +0000] WnRQQvAURie7wq9bOfH25AAAAAE ::1 57480 ::1 80 --2172df61-B-- POST /1/request?x=yxz&z=xy HTTP/1.1 User-Agent: Nessus Host: localhost Accept: */* cOOkIe: ABC=abc;SESSIONID=hash256 Content-Length: 9 Content-Type: application/x-www-form-urlencoded --2172df61-C-- bc=d123&cd=e&bc=a0 --2172df61-F-- HTTP/1.1 404 Not Found Accept-Ranges: bytes Transfer-Encoding: chunked Content-Type: text/html --2172df61-H-- Message: Warning. Matched phrase "nessus" at REQUEST_HEADERS:User-Agent. [file "/etc/apache2/conf.d/modsec_vendor_configs/imunify360_full_apache/103_Global_Agents.conf"] [line "17"] [id "210801"] [rev "2"] [msg "COMODO WAF: Request Indicates a Security Scanner Scanned the Site||localhost|F|2"] [data "nessus"] [severity "CRITICAL"] [tag "CWAF"] [tag "Agents"] Message: Warning. Pattern match "(?i:(?:^(?:microsoft url|user-Agent|www\.weblogs\.com|(?:jakart|vi)a|(google|i{0,1}explorer{0,1}\.exe|(ms){0,1}ie( [0-9.]{1,}){0,1} {0,1}(compatible( browser){0,1}){0,1})$)|\bdatacha0s\b|; widows|\\r|a(?: href=|d(?:sarobot|vanced email extractor ..." at REQUEST_HEADERS:User-Agent. [file "/etc/apache2/conf.d/modsec_vendor_configs/imunify360_full_apache/103_Global_Agents.conf"] [line "29"] [id "210831"] [rev "2"] [msg "COMODO WAF: Rogue web site crawler||localhost|F|4"] [data "Nessus"] [severity "WARNING"] [tag "CWAF"] [tag "Agents"] Message: Warning. Operator GE matched 5 at TX:incoming_points. [file "/etc/apache2/conf.d/modsec_vendor_configs/imunify360_full_apache/122_Outgoing_FiltersEnd.conf"] [line "35"] [id "214930"] [rev "1"] [msg "COMODO WAF: Inbound Points Exceeded|Total Incoming Points: 8|localhost|F|2"] [severity "CRITICAL"] [tag "CWAF"] [tag "FiltersEnd"] Apache-Handler: default-handler Stopwatch: 1517572162346260 98908 (- - -) Stopwatch2: 1517572162346260 98908; combined=33129, p1=737, p2=32228, p3=0, p4=0, p5=163, sr=0, sw=1, l=0, gc=0 Producer: ModSecurity for Apache/2.9.2 (http://www.modsecurity.org/); CWAF_Apache. Server: Apache Engine-Mode: "DETECTION_ONLY" --2172df61-Z-- c 0d|_i|_g|_dSr|) _state_parserr r rs r7rz_NativeLogParser.__init__s !$&!#%   r6c`|j|||Sr|)r rrrs r7rz_NativeLogParser.feeds+  ''///v&&&r6c6||sdS tfd|jD}|tur|S ||_dS#t$r|jtdYnwxYw| }|D]\}}|dkr/|j dg |:|dkr8d|j vr/|j dg |x|tkr4|j tg ||dkr||||j |<dS)Nc3FK|]}||VdSr|)rG)rparserrFs r7rz._NativeLogParser._feed_impl..sK--d33r6zNo parser for line %rrr0rr')rrnext_AVAILABLE_SUBPARSERSrrre StopIterationr.rIr  setdefaultrrd_parse_producer_filed)rr next_parsername_value_tokensrrrsrFs @r7rz_NativeLogParser._feed_impls**6==??;; 4 "8K o--zz||#. "-D 4  @ @ @!) !8$???*) @!88>>, 8 8KD%y  )44]BGGNN  %%!)BBB)44]BGGNN)44WbAAHHOOOO##**5111127)$//tsr:)rrFrs r7rIz(_NativeLogParser.parse_name_value_tokenss| *BB4HHII I , , ,SVV$$! +');<   III s&) A)AA)(A)c t|j|jd|_i|_g|_S#d|_i|_g|_wxYwr)rr r rers r7rz_NativeLogParser.flushsh **)T5M"&D (*D %')D $ $"&D (*D %')D $ ) ) ) )s 2A N)r1r2r3r4rMr_rzrrrrrkrrrrnrIrr5r6r7rcrcs))X %&&& '''---^:::"*****r6rcc6eZdZdZeeeeegZ e dZ dS)SerialLogParserrc |}t|d5}t|D]T\}} ||}||ccdddS.#t$r}t d||dz|d}~wwxYw dddn #1swxYwYt d||jj| S)zdo-it-all stylerbNz"Error in audit log file %r line %drPz Incomplete audit log file %r: %r) open enumeraterr.r<rSrIrr r)rEfilepathri filestreamlinenorrrs r7 parse_filezSerialLogParser.parse_files] (D ! ! Z"+J"7"7   #[[00F)%         *",<                    "  .   " 6   ||~~s:B A B B  A=#A88A==B  BBN) r1r2r3rr rUrcr[r^rrJr~r5r6r7rvrvsL [r6rvc&eZdZdZdZdZdZdS)ConcurrentLogParserc||_dSrrrs r7rzConcurrentLogParser.__init__8s #4r6c|j|zS)K :param str: token is expected to start with posixpath.sep rrrs r7 _normconcatzConcurrentLogParser._normconcat?s&..r6c||jtjz|tjdz|zS)rrP)r posixpathseprers r7_directadmin_concatz'ConcurrentLogParser._directadmin_concatEs>  #m kk)-((+ ,  r6c  |}td|D}ttjj|}t||j|j fD]%\}} d}||}tj |r|}n!tj |r|}t d ||ft|tt 5|rKtj|dkr(t$|cdddcSdddn #1swxYwY#t(t*f$rY#wxYwn#t,$rYnwxYwt/d|)Nc8g|]}|dS)z[]r)rts r7r/z,ConcurrentLogParser.feed..Xs"'L'L'L! 'L'L'Lr6zos.path.isfile({!r}) = {!r}rzNo audit log found in %r)rreversedrefilterrgrhrir rrisfilerSdebugformatboolrFileNotFoundErrorgetsizervr~UnicodeEncodeErrorrYrr.) rrstr_reversed_tokensfiltered_tokensr concat_funlog_path token_paths r7rzConcurrentLogParser.feedPsX H==??D ''L'Ltzz||'L'L'LMMO$RW]ODDO%,$"2D4L!M&& H H!zH#H!+E!2!2Jw~~j11)#-..)#(LL5<<'/h ""344HH#H(A(AA(E(E#2#=#=h#G#GHHHHHHHHHHHHHHHHHHHHHHHHH+J7D  H"    D @3V<<>F F F F $ F10F1N)r1r2r3rrrrr5r6r7rr7sP444///    #=#=#=#=#=r6rceZdZeegZdS)RevolverParserN)r1r2r3rvrrr5r6r7rrvs)+>?r6rceZdZGddeZedZedZedZedZ edZ edZ ed Z d S) _IncidentFixupListceZdZdZdS)"_IncidentFixupList.InvalidIncidentzh For incidents we cannot use data from, e.g. "Message: Rule processing failed." Nr0r5r6r7InvalidIncidentr{s  r6rc#`K|D]}||} |||||||||Vq#t j$r&d|dvr|||VYwxYwdS)Nz[msg r#)_fixup_camel_case_fixup_msg_inplace_fixup_host_tag_inplace_fixup_severity_inplace_fixup_useragent_inplacerr_fixup_unparsed_message)rE incidentsrincidents r7applyz_IncidentFixupList.applys! # #H,,X66H #&&x000++H555++H555,,X666%5 # # #hy111//999"NNN # # #sAA662B+*B+cddg|d<d|d<|ddd|d<dS)Nnoshowr&rr#z[msgra) partitionrErs r7rz*_IncidentFixupList._fixup_unparsed_messages?#* &y1;;FCCAFr6c>d|DS)zH make "Host" be in the same case as "msg", "rule", etc. c>i|]\}}||Sr5)r@rrBrCs r7rDz8_IncidentFixupList._fixup_camel_case..s&:::A 1:::r6)r4rs r7rz$_IncidentFixupList._fixup_camel_cases" ;:)9)9::::r6c|d||d}||d<|dd}|d|d<dS)Nr"r#z||rPrrrr)rrrre)rErr"partss r7rz%_IncidentFixupList._fixup_msg_inplacesl <<   &%%'' ',,u%%C"%HY IIdQI//E$QxHV   r6cBd|vr|d|d<dSdS)zR fixup 'user-agent' to 'useragent' to match agent sqlitedb naming z user-agent user_agentN)rrs r7rz+_IncidentFixupList._fixup_useragent_inplaces3 8 # #%-\\,%?%?H\ " " " $ #r6cd|vrgtd|titgDdrfd|dD|d<dSdSdS)zB remove "Host: %hostname%" field duplicate in tag r&c3,K|]\}}|dk |VdS)rNr5)rr8rss r7rz=_IncidentFixupList._fixup_host_tag_inplace..sA%'' (''' r6Nc&g|] }|dzk |S)zHost: %sr5)rr&rPs r7r/z>_IncidentFixupList._fixup_host_tag_inplace..s/###cZ$=N6N6NC6N6N6Nr6)rjrADVANCEDrd)rErrPs @r7rz*_IncidentFixupList._fixup_host_tag_inplaces H  )1h)C)C)G)G**  D #####+E?###    r6c Rddddddddd }|d }|d S t||d <d S#t$rYnwxYw |||d <d S#t$rDtd t |t tjYd SwxYw) a map modsec severity string <-> ossec modsec severity int, incident table expects int for severity and also consistent severity level is good for ML. github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#severity rrPrarrr) EMERGENCYALERTCRITICALERRORWARNINGNOTICEINFODEBUGrNz9Cannot measure severity level for %s literal in %s plugin) rintrYKeyErrorrSrIrUr PLUGIN_ID)rErmap_rs r7rz*_IncidentFixupList._fixup_severity_inplaces#  &<< ++   F #&x==HZ F    D  #'>HZ     LLKX\+,,       s": AA AA B&%B&N) r1r2r3 RuntimeErrorrrJrrrrrrrr5r6r7rrzs     ,    # #[ #GG[G ;;[;  ( ([ (@@[@[,++[+++r6rc g}dvr6ttdttg}dD]ފdt jd}tfdtD}||ttgi|t<ttfD]-}|r||t|<.|t|i| |gt||}|S)z unroll modsec audit log into incident list :param top_level_tokens: see how unit test describe this data structure :param debug_ctx: to be shown in sentry incident :return list: r0rINCIDENT)rv plugin_idc3K|]8}|vs|v ||p|fV9dSr|)r)rfieldmessage_enclosing_tokenstop_level_tokenss r7rz*mk_modsec_indicent_list..sw   444,,, ,00773'++E22-,,,  r6)rrr3rrdrrPICK_SECAUDITLOG_FIELDSrrrnrjrrrr) rr raw_incidentsuser_idr update_dictrrrs ` @r7rrsM(((  r 2 2 !%%gr22 3 3   )9(G + + $$)3H      5     K OOK ( ( (#*+;+?+?+L+L!MHX k) H H#''..H0@0GHX&u- OO0': ; ; ;   * * * * B!'' yAA BF Mr6rci}t|D]7\}}d|z}|tvs Jd|z|||<8|S)Nz%s_anomality_scorez'invalid anomality score key %s detected)_PARSE_SCORE_REGEXrr@ANOMALITY_SCORE_FIELDS)r"r score_typerskeys r7rr*ss F/77<< E"Z%5%5%7%77,,,, 5 ;-,,s Mr6rrrscNt||}||kp tj}||fS)zc Return value/obfuscated value if header is (not) sensitive and whether it is required )obfuscate_item_if_sensitiverro)rrrs result_valuerus r7rcrc5s0/tU;;L%'L<+LK + &&r6c|}|tkrt|n|tvrt |n|S)z| If header name is 'authorization' or 'cookie', then obfuscate it so as not to disclosure sensitive client info )r@_COOKIEobfuscate_cookie_SENSITIVE_HEADERSobfuscate_item)rrrss r7rrAsR ::<.Vs+MMM$!Q!^AG,,-MMMr6)rsortedr4rrZ)r*scrsrs r7rrPszN & ! !NM&:L:LMMM A Ls= A AA rci}|D]@\}}|D]8}||gt|9A|Sr|)r4rmrr)rrrBr4rFs r7_obfuscate_itemsrZso FJJLLBB5 B BD   a $ $ + +N4,@,@ A A A A B Mr6c:tt|Sr|)rr )rs r7rqrqbs HUOO , ,,r6rFcz|s|Sg}d}dddddd}t|}|t|kr||}t||vr/||t||dz }nt |r|}|t|krB||}t |sn|dz }|t|kB|}||z dkr|d n|d ||z z$t |r|}|t|krB||}t |sn|dz }|t|kB|}||z dkr|d n|d ||z z|||dz }|t|kd |S)Nrz[space]z[tab]z[LF]z[CR]z[NULL])r rrPz[chr]z [chr]{%d}z[digit]z [digit]{%d}r) rrordr2rrZisalpha isnumericr)rFobf_buffpos special_dictx start_posend_poss r7rrfsP  H C L ::D D // I q66\&&(( ( ( OOLQ0 1 1 1 1HCC1vv~~  CIIooS Aq66>>++1HC CIIoo i'A--OOG,,,,OOK7Y3F$GHHH1vv!!  CIIooS Aq66++--1HC CIIoo i'A--OOI....OOMWy5H$IJJJ OOA    1HCC D //F 778  r6rFcd}d}d|vr6|d^}}ttd|}n|}tjd|}|r|}||fS)N;c,|dS)Nz.| r)rs r7z#get_producer_data..sQWWU^^r6z \d\.\d\.\d)rermapr\rrX)rFr;rrr9rCs r7r5r5sGJ d{{ JJsOO's33W==>> ImW - -E #[[]] w r6r|)ar4rrVrgos.pathrr\ urllib.parserkabcrr contextlibrr http.cookiesrr itertoolsr loggingr typingr r r defence360agent.utils.commonrrdefence360agent.utilsrrim360.contracts.configrrSEVERITYrrdrnrjr}rpr3rrrrrwrr] IGNORECASErr1rS exceptionrrr.r:r<rr>r@rMr_rzrrrrrrrr r r=rUr[r^rcrvrrrrrZrrrrcrrrrqrtupler5r5r6r7rs   ''''''''22222222""""""""!!!!!!88888888DDDDDDDD//////@(GJF[+|\;          #$%&#>=  RZ/ 8  0**C0001ABB                             i            $22222-222200000-000>/////-/// . . . . .- . . .e(e(e(e(e(1e(e(e(Pf"f"f"f"f")f"f"f"RLLLLL-LLL((((($;(((*****w****ZH4H4H4H4H4fH4H4H4V * * * * * * * *Fddddd)dddNhhhhh 2hhhV04+BN*N*N*N*N*vN*N*N*b$$$$$o$$$N<=<=<=<=<=&<=<=<=~@@@@@_@@@||||||||~....b34 '  ' ' 8C=$  ' ' ' '     4---4#48C=4444nCEr6