`@ҠdZddlZddlZddlmZddlmZmZmZm Z ddl m Z m Z ddl mZmZddlmZddlmZGd d eZd ed ed efdZd ed ed efdZd ed ed efdZd ed ed efdZded efdZ d)dedededzdedzdedzdedzdedzdedzdedzdedzdedzfd Zd!eed eefd"Zd#efd$Z d ed efd%Z!d&edzd efd'Z"d edzfd(Z#dS)*a0Helper functions for WordPress CVE protection incidents. WordPress incidents are stored in a dedicated wordpress_incident table with plugin-specific data stored in the extra_info JSON field. This module provides helper functions to work with WordPress incidents. Available for both AV and IM360 modes. N) timedelta) CharField FloatField IntegerField TextField) JSONFieldfn)Modelinstance)apply_order_by)OrderBycReZdZdZeddZedZedZe dZ edZ edZ edZ edZedZeddZeddZedZGd d ZdS) WordpressIncidentz WordPress incident model for CVE protection. Uses dedicated wordpress_incident table created in migration 191. Unique constraint on (abuser, name, plugin, rule, severity, domain) allows deduplication similar to the aggregate plugin. T) primary_keynull)r country_id)r column_nameN)rdefaultc$eZdZejZdZdZdS)WordpressIncident.Metawordpress_incident)))abusernamepluginruleseveritydomainTN)__name__ __module__ __qualname__r dbdatabasedb_tableindexes]/opt/imunify360/venv/lib/python3.11/site-packages/defence360agent/model/wordpress_incident.pyMetar1s!;' r&r()rrr __doc__ridrrrr timestampretriesrrr descriptionrcountryrr extra_infor(r%r&r'rrs& $T 2 2 2B YD ! ! !F 9$   D %%%Il%%%G|&&&H 9$   D)&&&K YD ! ! !FiT|<<??  M%%j11  ]&&{33  }((77! "  )).99# $  1 12H I I% & =,,->??' (&)).99#%!%%j113   r&c |dpt|}t||}d|ddt|dddt |dd |d d ||d p|d |d|d S)a Build complete incident dict ready for database insertion. This is used for both single incident creation and bulk insertion. Args: incident_data: Dict with incident fields from PHP incident file site_info: Dict with site information (domain, site_path, username, user_id) Returns: Dict with all fields ready for Incident.create() or bulk insert message wordpressrule_idunknowntsrr8zWordPress CVE: r7Unknown REMOTE_ADDR attacker_ipr) rrr+r,rrr-rrr/)rXbuild_message_fallbackr\floatcalculate_severity)r0r1r^r/s r'build_incident_dictrjgs **.D//G"-;;J!!)Y77=,,T15566&}'8'8'@'@AAG-"3"3E9"E"EGG##M22,   ] + +--))   r&cDt||}tjdi|S)aD Create a WordPress incident in the wordpress_incident table. Args: incident_data: Dict with incident fields from PHP incident file site_info: Dict with site information (domain, site_path, username) Returns: WordpressIncident instance with WordPress fields populated in extra_info r%)rjrcreate)r0r1 incident_dicts r'create_wordpress_incidentrns*( yAAM  # 4 4m 4 44r&ct||}tjdi|tjtjtjtjtjtj gtj tj dztj |di t }t|dS)ai Insert or update a WordPress incident in the wordpress_incident table. If an incident with the same aggregate key (abuser, name, plugin, rule, severity, domain) exists, increment its retries counter and update timestamp. Otherwise, create a new incident with retries=1. This implements similar deduplication logic as the aggregate plugin. Args: incident_data: Dict with incident fields from PHP incident file site_info: Dict with site information (domain, site_path, username, user_id) Returns: WordpressIncident instance (either newly created or updated) rcr+)conflict_targetupdaterr%)rjrinsert on_conflictrrrrrrr,r+ returningexecutelist)r0r1rmresults r'upsert_wordpress_incidentrxs&( yAAM  11=11 !(!&!(!&!*!( ")+<+Dq+H!+];-G   $ % % # * <<?r&incidentc |j|j|j|j|j|j|j|j|j|j |j |j d S)z Convert a WordpressIncident model instance to a dictionary. Args: incident: WordpressIncident model instance Returns: Dictionary representation of the incident r*rrr+r,rrr-rr.rr/r{)rys r'wordpress_incident_to_dictr|sUk/ '#% +/#/)   r&limitoffsetr> by_abuser_ipby_country_code by_domainsearch site_searchsincetoorder_byc Ztttjdk} |6| t jtjd|k} |2| tj|} |#| tj |k} |2| tj |} || tj |tj |ztj |ztj|z} |6| t jtjd|k} |6| tj d|k} | 6| tj d| k} | pg} | D]T} t| t r(| t%j| ?| | Ut)| t| } n1| tj } | |} | |} d| DS)a Get WordPress incidents as dictionaries. Args: limit: Maximum number of incidents to return offset: Offset for pagination user_id: Filter by user ID (None = all) by_abuser_ip: Filter by abuser IP address (None = all) by_country_code: Filter by country code (None = all) by_domain: Filter by domain (None = all) search: Search in IP address, name, description, or domain (None = all) site_search: Filter by site path in extra_info (None = all) since: Filter by timestamp >= this value (unix timestamp, None = all) to: Filter by timestamp <= this value (unix timestamp, None = all) order_by: List of fields to order by (None = default order by timestamp desc). Can be either strings (e.g., ["timestamp+", "severity-"]) or OrderBy objects. Strings are automatically converted. Returns: List of incident dictionaries r_Nz $.user_idz $.site_pathREALc,g|]}t|Sr%r|.0incs r' z+get_wordpress_incidents..?s! G G G &s + + G G Gr&)rselectwhererr json_extractr/rcontainsr.rrr-r+cast isinstancestrappendr fromstringr rdescr~rru)r~rr>rrrrrrrrqueryconverted_order_byitems r'get_wordpress_incidentsrsD  $ $%6 7 7 = =  ![ 0  E O-8+ F F     -4==lKKLL" -5HII -4==iHHII   " + +F 3 3+44V<< =&//77 8 &//77 8   O-8- H H      -7<.Ws! > > > &s + + > > >r&)r insert_manyrtru)rrws r'bulk_create_wordpress_incidentsrBsV   %%n55 $ % %  ? >v > > >>r&dayscRtjt|z }ttjdktjd|kz }|S)N)rr_r) timer total_secondsrdeleterrr+rru)r cutoff_timedeleteds r'delete_old_wordpress_incidentsrZs)++ t 4 4 4 B B D DDK  ""   % 4 *//77+E G      Nr&cdg}|dr||d|dr||d|dr||d|dr||d|dr||dd|S)z=Build message if plugin didn't provide one (per spec format).z IM WP plugin:r`r7r:r;r8 )rXrjoin)r0partss r'rgrggs  E##/ ]9-...+ ]5)***  , ]6*+++##/ ]9-...  , ]6*+++ 88E??r&r8c&|dkrdS|dkrdSdS)z!Calculate severity based on mode.blockpassr%)r8s r'ririys# wq qqr&c`|dSt|tr|Stj|S)z>Serialize a value to JSON string if it's not already a string.N)rrjsondumps)values r'rWrWs3 }t% :e  r&) r}rNNNNNNNNN)$r)rrdatetimerpeeweerrrrplayhouse.sqlite_extrr defence360agent.modelr r $defence360agent.model.simplificationr "defence360agent.rpc_tools.validater rdictr\rjrnrxr|intrrvrrrrgrirWr%r&r'rsd  /.......11111111??????666666        >*D*T*d****Z t      F55$(55555"--$(-----`):t6#"& " ZHZH ZH ZH4ZZH* ZH 4Z ZH Tz ZH $JZHtZH :ZH d ZHTkZHZHZHZHz?J? $Z????0     $3$S4ZC3:r&