Yamato-Security/hayabusa-rules

Incomplete field conversion in `process_creation` rules

fukusuket opened this issue · 7 comments

Describe the bug
process_creation rules are automatically converted to EventID: 4688 (Security) and EventID: 1 (Sysmon) rules.
However, due to imperfect field conversion, rules are created that cannot be detected.

Currently, logsource_mapping.py does only the following field conversions.

fieldmappings:
Image: NewProcessName
ParentImage: ParentProcessName
Details: NewValue
#CommandLine: ProcessCommandLine # No need to map, as real name of ProcessCommandLine is already CommandLine
LogonId: SubjectLogonId

Actual behavior
Undetectable rules are created.
For example, the rule below uses field ParentCommandLine,IntegrityLevel that does not exist in EventID: 4688 (Security)

process_creation:
EventID: 4688
Channel: Security
selection:
CommandLine|endswith: '"\system32\cleanmgr.exe /autoclean /d C:'
ParentCommandLine: C:\Windows\system32\svchost.exe -k netsvcs -p -s Schedule
IntegrityLevel:
- High
- System
condition: process_creation and selection

Expected behavior
Undetectable rules are not created.

  • If there are fields that can be converted, convert the fields correctly
  • If there are no fields that can be converted, don't create post-conversion rules

Additional context
The field check script in the Sigma repository lists the following fields:

Channel: Security, EventID: 4688
"SubjectUserSid", 
"SubjectUserName", 
"SubjectDomainName", 
"SubjectLogonId", 
"NewProcessId", 
"NewProcessName", 
"TokenElevationType", 
"ProcessId", 
"CommandLine", 
"TargetUserSid", 
"TargetUserName", 
"TargetDomainName", 
"TargetLogonId", 
"ParentProcessName", 
"MandatoryLabel"
Channel: Microsoft-Windows-Sysmon/Operational, EventID: 1
"RuleName",
"UtcTime",
"ProcessGuid", 
"ProcessId", 
"Image", 
"FileVersion", 
"Description", 
"Product", 
"Company", 
"OriginalFileName", 
"CommandLine", 
"CurrentDirectory", 
"User", 
"LogonGuid", 
"LogonId", 
"TerminalSessionId", 
"IntegrityLevel", 
"Hashes", 
"ParentProcessGuid", 
"ParentProcessId", 
"ParentImage", 
"ParentCommandLine", 
"ParentUser"

@fukusuket This is a good issue! If the process creation rule is looking for fields that don't exist in security 4688 then we shouldn't create that rule as it will just slow things down. There is also a small chance that someone could create a rule that looks for a field in Security 4688 but does not exist in Sysmon 1 so we should probably check for that and not create a sysmon 1 rule in that case.

Thank you for your comment :)
Yes, it also improves performance if unnecessary rules are not created! I will try to implement the check function💪

I implemented the check and it looks like the 3811 - 3321 = 490 rule has incomplete field.

main

[INFO:logsource_mapping.py:376] [3811] files created successfully. Created files were saved under [./converted_sigma_rules].
[INFO:logsource_mapping.py:377] Script took [10.26] seconds.

#445

[INFO:logsource_mapping.py:410] [3321] files created successfully. Created files were saved under [./converted_sigma_rules].
[INFO:logsource_mapping.py:411] Script took [9.70] seconds.

I tried investigating the fields of the incomplete rule...
There were 395 incomplete rules containing field OriginalFileName (with Sec:4688)

...
[WARNING:logsource_mapping.py:196] This rule has incompatible field.{'process_creation': {'EventID': 4688, 'Channel': 'Security'}, 'selection_img': [{'NewProcessName|endswith': '\\cmd.exe'}, {'OriginalFileName': 'Cmd.Exe'}], 'selection_parent': {'ParentProcessName|endswith': '\\sqlservr.exe'}, 'condition': 'all of selection_*'}. skip conversion.
...
fukusuke@fukusukenoAir Desktop % cat warn.txt | grep OriginalFileName | wc -l
     395

@fukusuket

Sec4688 and Sysmon1 difference

For the logic, if a process_creation rule has one of the following fields, we should not make a sysmon 1 rule:

SubjectUserSid
TokenElevationType
TargetUserSid
TargetUserName
TargetDomainName
TargetLogonId

(The red ones in the picture)

If a process_creation rule has one of the following fields, we should not make a security 4688 rule:

RuleName
UtcTime
ProcessGuid
FileVersion
Description
Product
Company
OriginalFileName
CurrentDirectory
LogonGuid
TerminalSessionId
Hashes
ParentProcessGuid
ParentCommandLine
ParentUser

Image gets mapped to NewProcessName, ParentImage to ParentProcessName and LogonId to SubjectLogonId.

ProcessId and ParentProcessId can be mapped to NewProcessId and ProcessId, however, we need to convert the decimal PID to hex.

IntegrityLevel maps to MandatoryLabel but the following conversion needs to be done in the data portion:
Low -> S-1-16-4096
Medium -> S-1-16-8192
High -> S-1-16-12288
System -> S-1-16-16384

Note: sometimes in sigma rules, it will be written System but other times SYSTEM so we need to check the integrity level case in-sensitive.

What do you think?

@YamatoSecurity
I implemented #443 (comment) :) 5d386c9 , then I have a question!

When checking the 5d386c9 results , I noticed that..
In the new impl, the following rule has an OriginalFileName, so it will be treated as an error in the Security:4688 rule,

process_creation:
EventID: 4688
Channel: Security
selection:
- NewProcessName|endswith:
- \powershell.exe
- \pwsh.exe
- OriginalFileName:
- PowerShell.EXE
- pwsh.dll

However, since it is an OR condition, it is a useful rule when detecting with NewProcessName ... 🤔
Should these rules be treated as correct rules if there is at least one correct field in the OR condition?

@fukusuket Thanks alot!
That is an interesting edge case that I did not think of. Yes, if there is an OR condition like this and one contains a valid field in 4688 (like NewProcessName) then we should create a 4688 rule as well.

@YamatoSecurity
Thank you for your comment :) I'll add a new check logic for OR conditions! !💪