├── LICENSE ├── README.md ├── diff └── ar-diff.ps1 ├── normalize └── ar-normalize.ps1 └── parsers ├── elsa ├── autoruns └── autoruns.sql └── ossec └── local_decoder.xml /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Josh Brower 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### **Pertinax** 2 | _Latin: “Persistent, Stubborn”_ 3 | 4 | The ability to remain active on a target system even after reboots is a key component of a long-term successful compromise. Unfortunately, there are a number of ways for a threat actor to persist in Windows across reboots, and it can be very difficult to comprehensively identify these areas without specialized software. This is where [Sysinternals' Autoruns](https://technet.microsoft.com/en-us/sysinternals/bb963902.aspx?f=255&MSPPError=-2147217396) (AR) come into play. Autoruns is a Sysinternals’ tool that has been widely used in the industry to help bring to light the many different areas in Windows used for persistence. 5 | 6 | The purpose of Pertinax is succinctly thus: 7 | 8 | _To further enhance the host-level capabilities of Security Onion by integrating Sysinternals Autoruns’ logs into the Security Onion ecosystem, and making this data available for OSSEC rulesets as well as ELSA queries._ 9 | 10 | -------------------------------------------------------------------------------- /diff/ar-diff.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Original Author: Josh Brower, Josh@DefensiveDepth.com 3 | Version: 2016.06.02-Rev1 4 | 5 | This script is licensed under the terms of the MIT license. 6 | 7 | This script compares Sysinternals' AutoRunsc CSV Logs with 8 | a previously run log from the same system, filters out any 9 | autoruns' entries that were removed, and outputs to a .csv 10 | file in a format that the AR-Normalize script can understand. 11 | 12 | Tested with Autorunsc v13.51 13 | 14 | Logs must be generated with the CSV output with TAB delimeter, 15 | and the resulting log should be named according to the system it 16 | came from. For example: 17 | 18 | autorunsc.exe -ct > $Hostname.csv 19 | 20 | #> 21 | 22 | #Loop through the ToDiff folder for all CSV files 23 | (Get-ChildItem .\ToDiff\*.csv) |%{ 24 | 25 | #Sets the Paths for ArchiveItem & NormalizeItem 26 | $ArchiveItem = Join-Path -Path ".\Archive" -ChildPath $_.name 27 | $ToNormItem = Join-Path -Path ".\ToNormalize" -ChildPath $_.name 28 | 29 | #Checks to see if a logfile of the same name exists in the Archive folder 30 | If ( (Test-Path -Path $ArchiveItem) ) 31 | { 32 | #Since the log exists in Archive, we can go ahead and compare it. PassThru shows the entire line that is different. 33 | Compare-Object -ReferenceObject (Import-Csv -Delimiter "`t" -Encoding Unicode $ArchiveItem) -DifferenceObject (Import-Csv -Delimiter "`t" -Encoding Unicode $_.fullname) -Property SHA-1 -PassThru | 34 | 35 | #Filters out removed entries 36 | ? {$_ -NotMatch "<="} | 37 | 38 | #Converts the data to CSV with no Type header 39 | ConvertTo-Csv -NoTypeInformation | 40 | 41 | #Removes the quotes that Powershell adds 42 | % { $_ -replace '","', '|'} | 43 | 44 | #Removes more quotes that Powershell adds 45 | % { $_ -replace '^"(.*)"$', '$1'} | 46 | 47 | #Writes the remaining data to the Normalize folder with the original filename 48 | Out-File -Encoding unicode -FilePath $ToNormItem 49 | 50 | #Moves the consumed logfile to the Archive folder 51 | Move-Item -Path $_.fullname -Destination $ArchiveItem -Force 52 | } 53 | 54 | Else { 55 | #Since the log does not exist it Archive, it must be a new client 56 | 57 | #Copy log to the Archive 58 | Copy-Item $_.fullname $ArchiveItem -Force 59 | 60 | #Move log to the Normalize folder 61 | Move-Item -Path $_.fullname -Destination $ToNormItem -Force 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /normalize/ar-normalize.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Original Author: Josh Brower, Josh@DefensiveDepth.com 3 | Version: 2016.05.23-Rev1 4 | 5 | This script is licensed under the terms of the MIT license. 6 | 7 | This script formats Sysinternals' AutoRunsc CSV Logs in a 8 | way that Security Onion can consume and parse using OSSEC & ELSA. 9 | 10 | Tested with Autorunsc v13.51 11 | 12 | Logs must be generated with the CSV output with TAB delimeter, 13 | and the resulting log should be named according to the system it 14 | came from. For example: 15 | 16 | autorunsc.exe -ct > $Hostname.csv 17 | 18 | #> 19 | 20 | (Get-ChildItem *.csv) |%{ 21 | 22 | #Store the name of the file & date 23 | $SystemName = $_.Basename 24 | $FileDate = $_.CreationTime 25 | 26 | #Skips the header row and prepends the following to each message: Unique Identifer, System Name, Date 27 | (Get-Content -Encoding Unicode $_.fullname | Select-Object -Skip 1) -replace "^","AR-LOG|$SystemName|$FileDate|"| 28 | 29 | #Replaces the TAB delimeter with a Pipe delimeter (Syslog-NG does not support TAB) 30 | Foreach-Object {$_ -replace ' ','|'} | 31 | 32 | #Removes Autoruns' Subheaders 33 | ? { $_ -notmatch "\|\|\|\|\|\|\|\|\|\|" } | 34 | 35 | #Appends the resulting message in ascii (OSSEC Windows Client does not support Unicode logs) 36 | Out-File -Append -Encoding ascii -FilePath ar-normalized.log 37 | 38 | #Deletes the consumed logfile 39 | Remove-Item $_.fullname 40 | } 41 | -------------------------------------------------------------------------------- /parsers/elsa/autoruns: -------------------------------------------------------------------------------- 1 | 2 | ossec_archive 3 | 4 | 5 | 6 | 7 | @NUMBER::@@ESTRING::(@@ESTRING::)@ @IPv4::@->@ESTRING::AR-LOG|@@ESTRING:s0:|@@ESTRING::|@@ESTRING::|@@ESTRING::|@@ESTRING:s1:|@@ESTRING::|@@ESTRING:s2:|@@ESTRING:s3:|@@ESTRING::|@@ESTRING:s4:|@@ESTRING::|@@ESTRING:s5:|@ 8 | 9 | 10 | 11 | 2016 May 20 16:39:21 (DD-COLLECT-PROD) 192.168.160.18->ar-normalized.log AR-LOG|DD-RE2|05/20/2016 12:39:00|4/8/2016 4:42 PM|HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run|Skype|enabled|Logon|DD-RE2\ddadmin|Skype |Skype Technologies S.A.|c:\program files (x86)\skype\phone\skype.exe|7.22.85.109|""C:\Program Files (x86)\Skype\Phone\Skype.exe"" /minimized /regrun|1DBD44E4C19F6EC1665A89ABC884DF56|ADC1CF4AD8C6F944E31E4649BE16B186EE19D793|BCC10DF9F36B1727DBA310827CC2A6AC5C9B0D4D|1DA131F21C1A7BAF8C70272FCE5E4288E021CB434D12A28784344E02CBEA3BFA|169D5B005368A12B6F499F7B655540884BD47D872D74AAD73CD035356DA148A9|A9159194FEF672CA050D5D2DC9E64017 12 | 13 | DD-RE2 14 | 15 | Skype 16 | 17 | Logon 18 | 19 | DD-RE2\ddadmin 20 | 21 | Skype Technologies S.A. 22 | 23 | c:\program files (x86)\skype\phone\skype.exe 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /parsers/elsa/autoruns.sql: -------------------------------------------------------------------------------- 1 | use syslog; 2 | 3 | /* Creates AUTORUNS Class & associated fields */ 4 | 5 | INSERT INTO classes (id, class) VALUES (10678, "AUTORUNS"); 6 | 7 | /* Add new fields: (only if they don't exist already) */ 8 | 9 | INSERT IGNORE INTO fields (field, field_type, pattern_type) VALUES ("hostname","string", "QSTRING"); 10 | 11 | INSERT IGNORE INTO fields (field, field_type, pattern_type) VALUES ("entry","string", "QSTRING"); 12 | 13 | INSERT IGNORE INTO fields (field, field_type, pattern_type) VALUES ("category","string", "QSTRING"); 14 | 15 | INSERT IGNORE INTO fields (field, field_type, pattern_type) VALUES ("profile","string", "QSTRING"); 16 | 17 | INSERT IGNORE INTO fields (field, field_type, pattern_type) VALUES ("company","string", "QSTRING"); 18 | 19 | INSERT IGNORE INTO fields (field, field_type, pattern_type) VALUES ("path","string", "QSTRING"); 20 | 21 | 22 | /* Add mappings to the fields_classes_map */ 23 | 24 | INSERT IGNORE INTO fields_classes_map (class_id, field_id, field_order) VALUES ((SELECT id FROM classes WHERE class="AUTORUNS"), (SELECT id FROM fields WHERE field="hostname"), 11); 25 | 26 | INSERT IGNORE INTO fields_classes_map (class_id, field_id, field_order) VALUES ((SELECT id FROM classes WHERE class="AUTORUNS"), (SELECT id FROM fields WHERE field="entry"), 12); 27 | 28 | INSERT IGNORE INTO fields_classes_map (class_id, field_id, field_order) VALUES ((SELECT id FROM classes WHERE class="AUTORUNS"), (SELECT id FROM fields WHERE field="category"), 13); 29 | 30 | INSERT IGNORE INTO fields_classes_map (class_id, field_id, field_order) VALUES ((SELECT id FROM classes WHERE class="AUTORUNS"), (SELECT id FROM fields WHERE field="profile"), 14); 31 | 32 | INSERT IGNORE INTO fields_classes_map (class_id, field_id, field_order) VALUES ((SELECT id FROM classes WHERE class="AUTORUNS"), (SELECT id FROM fields WHERE field="company"), 15); 33 | 34 | INSERT IGNORE INTO fields_classes_map (class_id, field_id, field_order) VALUES ((SELECT id FROM classes WHERE class="AUTORUNS"), (SELECT id FROM fields WHERE field="path"), 16); 35 | -------------------------------------------------------------------------------- /parsers/ossec/local_decoder.xml: -------------------------------------------------------------------------------- 1 | 15 | 16 | 17 | AR-LOG 18 | 19 | 20 | 21 | autorunsc 22 | \|\.+\|\.+\|\.+\|\.+\|(\S+)\|\.+\|(\S+)\|\S+\|\.+\|\.+\|(\.+)\| 23 | id,action,url 24 | 25 | --------------------------------------------------------------------------------