Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wazuh rule exclusion #194

Merged
merged 10 commits into from
Apr 21, 2024
Merged
13 changes: 13 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,39 @@
"apexchart",
"arcticons",
"CARBONBLACK",
"cmdline",
"colord",
"commonmark",
"datejs",
"datetimesec",
"DFIR",
"echarts",
"epss",
"eventchannel",
"Eventdata",
"falsepositives",
"firedtimes",
"flourite",
"forgotpassword",
"Healthcheck",
"healthchecks",
"Indicies",
"Logsource",
"majesticons",
"mimecast",
"mynaui",
"ntime",
"ochin",
"Osquery",
"picocolors",
"popconfirm",
"redoc",
"rushstack",
"Shiki",
"signin",
"Socfortress",
"sparkline",
"Sysmon",
"taze",
"timerange",
"uvicorn",
Expand Down
2 changes: 2 additions & 0 deletions backend/app/connectors/wazuh_indexer/schema/indices.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class IndexConfigModel(BaseModel):
".kibana": True,
"praeco": True,
"filebeat": True,
".tasks": True,
".task": True,
},
description="A dictionary containing index names to be skipped and their skip status.",
)
Expand Down
27 changes: 14 additions & 13 deletions backend/app/connectors/wazuh_manager/routes/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from app.db.db_session import get_db

# from app.connectors.wazuh_manager.schema.rules import RuleExclude
# from app.connectors.wazuh_manager.schema.rules import RuleExcludeResponse
from app.connectors.wazuh_manager.schema.rules import RuleExcludeResponse

# from app.connectors.wazuh_manager.services.rules import exclude_rule

Expand Down Expand Up @@ -156,15 +156,16 @@ async def enable_wazuh_rule(


# ! TODO: Implement this endpoint - Maybe use OpenAI?
# @wazuh_manager_rules_router.post(
# "/rule/exclude",
# response_model=RuleExcludeResponse,
# description="Retrieve recommended exclusion for a Wazuh Rule",
# )
# async def exclude_wazuh_rule(rule: RuleExclude) -> RuleExcludeResponse:
# logger.info(f"rule: {rule}")
# recommended_exclusion = await exclude_rule(rule)
# if recommended_exclusion:
# return recommended_exclusion
# else:
# raise HTTPException(status_code=404, detail="Was not able to exclude rule")
@wazuh_manager_rules_router.post(
"/rule/exclude",
response_model=RuleExcludeResponse,
description="Retrieve recommended exclusion for a Wazuh Rule",
)
async def exclude_wazuh_rule() -> RuleExcludeResponse:
raise HTTPException(status_code=501, detail="Feature not yet ready")
return RuleExcludeResponse(
wazuh_rule="<group name=\"windows, sysmon, sysmon_event1, windows_sysmon_event1\">\n<rule id=\"100126\" level=\"1\">\n<if_sid>100125</if_sid>\n<field name=\"win.eventdata.user\">NT AUTHORITY\\\\SYSTEM</field>\n<field name=\"win.eventdata.originalFileName\">Wmiprvse.exe</field>\n<field name=\"win.eventdata.image\">C:\\\\Windows\\\\System32\\\\wbem\\\\WmiPrvSE.exe</field>\n<field name=\"win.eventdata.parentCommandLine\">C:\\\\Windows\\\\system32\\\\svchost.exe -k DcomLaunch -p</field>\n<description>Exclusion rule for specific system processes and parent commands.</description>\n</rule>\n</group>",
explanation="This rule is designed to exclude specific system processes identified by their user, original filename, image path, and parent command line. It triggers based on the presence of these attributes, which are commonly associated with legitimate system activities as defined in the payload. The rule is set to level 1 as a basic exclusion without generating an alert. It inherits from a previous rule with ID 100125. The exclusion is based on matching the exact strings for the user, original file name, process image, and parent command line execution parameters.",
message="This is a test",
success=True,
)
9 changes: 3 additions & 6 deletions backend/app/connectors/wazuh_manager/schema/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ class RuleExclude(BaseModel):


class RuleExcludeResponse(BaseModel):
success: bool
wazuh_rule: str
explanation: str
message: str
recommended_exclusion: str = Field(
...,
description="The recommended exclusion for the rule",
example="C:\\\\Windows\\\\ServiceState\\\\EventLog\\\\Data\\\\lastalive1\.dat",
)
success: bool
13 changes: 9 additions & 4 deletions backend/app/threat_intel/routes/socfortress.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from app.threat_intel.schema.socfortress import SocfortressThreatIntelRequest
from app.threat_intel.services.socfortress import socfortress_threat_intel_lookup
from app.utils import get_connector_attribute
from app.middleware.license import get_license, is_feature_enabled

# App specific imports

Expand Down Expand Up @@ -44,7 +45,6 @@ async def ensure_api_key_exists(session: AsyncSession = Depends(get_db)) -> bool
)
return True


@threat_intel_socfortress_router.post(
"/socfortress",
response_model=IoCResponse,
Expand All @@ -54,7 +54,7 @@ async def ensure_api_key_exists(session: AsyncSession = Depends(get_db)) -> bool
async def threat_intel_socfortress(
request: SocfortressThreatIntelRequest,
session: AsyncSession = Depends(get_db),
_key_exists: bool = Depends(ensure_api_key_exists),
#_key_exists: bool = Depends(ensure_api_key_exists),
):
"""
Endpoint for SocFortress Threat Intel.
Expand All @@ -69,7 +69,12 @@ async def threat_intel_socfortress(
Returns:
- IoCResponse: The response model containing the results of the SocFortress threat intelligence lookup.
"""
logger.info("Running SOCFortress Threat Intel")
await is_feature_enabled("THREAT INTEL", session=session)
logger.info("Running SOCFortress Threat Intel. Grabbing License")

socfortress_lookup = await socfortress_threat_intel_lookup(request, session=session)
socfortress_lookup = await socfortress_threat_intel_lookup(
lincense_key=(await get_license(session)).license_key,
request=request,
session=session,
)
return socfortress_lookup
16 changes: 9 additions & 7 deletions backend/app/threat_intel/services/socfortress.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ async def invoke_socfortress_threat_intel_api(


async def get_ioc_response(
license_key: str,
request: SocfortressThreatIntelRequest,
session: AsyncSession,
) -> IoCResponse:
Expand All @@ -156,12 +157,8 @@ async def get_ioc_response(
Returns:
IoCResponse: The response object containing the IoC data and success status.
"""
api_key = await get_socfortress_threat_intel_attributes(
"connector_api_key",
session,
)
url = await get_socfortress_threat_intel_attributes("connector_url", session)
response_data = await invoke_socfortress_threat_intel_api(api_key, url, request)
url = "https://intel.socfortress.co/search"
response_data = await invoke_socfortress_threat_intel_api(license_key, url, request)

# Using .get() with default values
data = response_data.get("data", {})
Expand All @@ -172,6 +169,7 @@ async def get_ioc_response(


async def socfortress_threat_intel_lookup(
lincense_key: str,
request: SocfortressThreatIntelRequest,
session: AsyncSession,
) -> IoCResponse:
Expand All @@ -185,4 +183,8 @@ async def socfortress_threat_intel_lookup(
Returns:
IoCResponse: The response object containing the threat intelligence information.
"""
return await get_ioc_response(request, session)
return await get_ioc_response(
license_key=lincense_key,
request=request,
session=session,
)
Loading
Loading