Featured image of post Automating with PowerShell: Shipping your logs

Automating with PowerShell: Shipping your logs

Wow! It’s been quite a while since I’ve blogged. I’ve been working on CIPP, and the CyberDrainCTF recently ended so all my time just disappeared trying to balance those two. Not that that’s over for a bit I have some time to teach about PowerShell again.

This time we’re going to use PowerShell to setup moving your logs to a centralized logging engine. This could be Graylog, ELK, etc, but it could also be your external SIEM/SOC product that you’re running. Storing your logs in a central location can help so much with troubleshooting, security issues, or auditability and accountability, so let’s get started.

We have three separate scripts available right now, because there’s 3 different options; all scripts are pretty simple and straight forward and mostly meant as an example on how you could do this, not how you should. I’m using some community examples in these scripts;

  • NXLog config generated by Poshim by Blumira
  • Winlogbeat config by jhochwald, but with edits as it’s no longer maintained for newer versions
  • Sysmon config by Olaf Hartong

First we install Sysmon, which allows us to monitor more information in the event log and has abilities to find stuff you would not normally find. After we install sysmon we get the choice to deploy either NXLog, or WinLogBeat. This is a case of personal preference.

Deploying Sysmon

Sysmon is the easiest in the equation; we download Sysmon, download the configuration, and set up the correct bitness version. As always I recommend to host these files yourself somewhere.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Invoke-WebRequest "https://raw.githubusercontent.com/olafhartong/sysmon-modular/master/sysmonconfig.xml" -OutFile sysmonlatest.xml -UseBasicParsing
Invoke-WebRequest "https://download.sysinternals.com/files/Sysmon.zip" -OutFile "sysmon.zip" -UseBasicParsing
Expand-Archive "sysmon.zip" -Force

if ([Environment]::Is64BitOperatingSystem) {
Copy-Item ".\sysmon64.exe" "C:\windows\system32\sysmon64.exe"
Start-Process "C:\Windows\system32\Sysmon64.exe" -ArgumentList "-accepteula -i sysmonlatest.xml"
Start-Process "C:\Windows\system32\Sysmon64.exe" -ArgumentList "-accepteula -c sysmonlatest.xml"
}
else {
Copy-Item ".\sysmon.exe" "C:\windows\system32\sysmon.exe"
Start-Process "C:\Windows\system32\Sysmon.exe" -ArgumentList "-accepteula -i sysmonlatest.xml"
Start-Process "C:\Windows\system32\Sysmon.exe" -ArgumentList "-accepteula -c sysmonlatest.xml"
}

Now that we’ve setup setup Sysmon, let’s move on to setting up NxLog

Setup NxLog

NxLog is one of the tools that actually ships the logs somewhere, in the case of our example we’ll setup a raw TCP connection to our target host. We’ve used Poshim to generate a basic configuration that picks up most common events, including our brand new setup of Sysmon.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
$LoggingServer = "1.1.1.1"
$LoggingServerPort = "514"


Invoke-WebRequest "https://nxlog.co/system/files/products/files/348/nxlog-ce-3.0.2272.msi" -OutFile 'nxlog-ce-3.0.2272.msi' -UseBasicParsing
Invoke-WebRequest "https://cyberdrain.com/wp-content/uploads/2022/03/nxlog.conf" -OutFile ".\nxlog.conf" -UseBasicParsing
#Script uses parts of Blumira's Poshim, with permission.
Start-Process -FilePath "msiexec.exe" -ArgumentList @("/i nxlog-ce-3.0.2272", "/qn") -Wait

$logList = @(
    "Windows PowerShell"
    "System"
    "Security"
    "Application"
    "Setup"
    "Operational"
    "Network Isolation Operational"
    "Microsoft-Windows-WinRM/Operational"
    "Microsoft-Windows-WindowsUpdateClient/Operational"
    "Microsoft-Windows-Windows Defender/WHC"
    "Microsoft-Windows-Windows Defender/Operational"
    "Microsoft-Windows-User Profile Service/Operational"
    "Microsoft-Windows-TerminalServices-RDPClient/Operational"
    "Microsoft-Windows-TaskScheduler/Operational"
    "Microsoft-Windows-Sysmon/Operational"
    "Microsoft-Windows-PrintService/Operational"
    "Microsoft-Windows-PrintService/Admin"
    "Microsoft-Windows-PowerShell/Operational"
    "Microsoft-Windows-PowerShell/Admin"
    "Microsoft-Windows-NTLM/Operational"
    "Microsoft-Windows-NetworkProfile/Operational"
    "Microsoft-Windows-LSA/Operational"
    "Microsoft-Windows-Kernel-PnP/Configuration"
    "Microsoft-Windows-GroupPolicy/Operational"
    "Microsoft-Windows-CodeIntegrity/Operational"
    "Microsoft-Windows-CertificateServicesClient-Lifecycle-System/Operational"
    "Microsoft-Windows-CAPI2/Operational"
    "Microsoft-Windows-Bits-Client/Operational"
    "Microsoft-Windows-AppLocker/Packaged app-Execution"
    "Microsoft-Windows-AppLocker/Packaged app-Deployment"
    "Microsoft-Windows-AppLocker/MSI and Script"
    "Microsoft-Windows-AppLocker/EXE and DLL"
    "Microsoft-Windows-Application-Experience/Steps-Recorder"
    "Microsoft-Windows-Application-Experience/Program-Telemetry"
    "Microsoft-Windows-Application-Experience/Program-Inventory"
    "Microsoft-Windows-Application-Experience/Program-Compatibility-Troubleshooter"
    "Microsoft-Windows-Application-Experience/Program-Compatibility-Assistant"
    "Microsoft-Windows-Hyper-V-Hypervisor-Operational"
    "Microsoft-Windows-Hyper-V-Hypervisor-Admin"
    "Microsoft-Windows-SMBServer/Security"
    "Microsoft-Windows-SMBServer/Operational"
    "Microsoft-Windows-SMBServer/Connectivity"
    "Microsoft-Windows-SMBServer/Audit"
    "Microsoft-Windows-WinHttp/Operational"
    "Microsoft-Windows-WinHTTP-NDF/Diagnostic"
    "Microsoft-Windows-RRAS/Operational"
)
Write-Host "Enabling Windows Firewall Logging for both allowed and blocked attempts"
Set-NetFirewallProfile -LogFileName %SystemRoot%\System32\LogFiles\Firewall\pfirewall.log -LogMaxSizeKilobytes 4096 -LogBlocked True -LogAllowed true -LogIgnored False
Write-Host "Checking list of available event logs, and enabling them with 64MB Circular size."
$Logs = $LogList | ForEach-Object {
    $logSource = Get-WinEvent -ListLog $_
    if (!$logSource.IsEnabled) {
        $logSource.MaximumSizeInBytes = 64MB
        $logSource.LogMode = "Circular"
        $logSource.isEnabled = $true
        $logSource.SaveChanges()
    }
}
Write-Host "Setting NXLog config to $($LoggingServer) on port $($LoggingServerPort)"
(Get-Content '.\nxlog.conf') -Replace 'A.B.C.D', $LoggingServer -replace "SIEMPORT", $LoggingServerPort | Set-Content '.\nxlog.conf'
Write-Host "Copying NXLog config to new location"
Copy-Item -Path '.\nxlog.conf' -Destination  "C:\Program Files (x86)\nxlog\conf\nxlog.conf" -Force
Restart-Service -Name "nxlog"

NxLog is cool, but some tools work better with Beats, such as the ELK stack. Beats are log collectors that process data in a specific way. For our next example, we’ll use WinLogBeat.

Setup WinLogbeat

For WinLogBeat it’s the same approach we took as the NxLog configuration; the difference being we have more output types as options.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$LoggingServer = "1.1.1.1"
$LoggingServerPort = "514"
$OutputType = "logstash" #allowed: logstash, kafka, redis, elasticsearch

Expand-Archive winlogbeat.zip -Force
Invoke-WebRequest "https://cyberdrain.com/wp-content/uploads/2022/03/winlogbeat.zip" -OutFile ".\winlogbeat.zip" -UseBasicParsing
Write-Host "Enabling Windows Firewall Logging for both allowed and blocked attempts"
Set-NetFirewallProfile -LogFileName %SystemRoot%\System32\LogFiles\Firewall\pfirewall.log -LogMaxSizeKilobytes 4096 -LogBlocked True -LogAllowed true -LogIgnored False
Write-Host "Installing Winlogbeat Service"
Expand-Archive -Path WinLogBeat.zip -DestinationPath "$($PROGRAMDATA)" -Force

# Create the new service.

New-Service -Name winlogbeat-drmm ` -DisplayName Winlogbeat-drmm`
-BinaryPathName "`"C:\Programdata\winlogbeat\winlogbeat.exe`" --environment=windows_service -c `"C:\Programdata\winlogbeat\winlogbeat.yml`" --path.home `"C:\Programdata\winlogbeat`" --path.data `"$PROGRAMDATA\winlogbeat`" --path.logs `"$PROGRAMDATA\winlogbeat\logs`" -E logging.files.redirect_stderr=true"

# Attempt to set the service to delayed start using sc config.

Try {
Start-Process -FilePath sc.exe -ArgumentList 'config winlogbeat start= delayed-auto'
}
Catch {
Write-Host "An error occured setting the service to delayed start."
}

Write-Host "Setting WinLogBeat config to $($LoggingServer) on port $($LoggingServerPort)"
(Get-Content 'C:\Programdata\winlogbeat\winlogbeat.yml') -Replace 'A.B.C.D', "$($LoggingServer):$LoggingServerPort" -replace "outputtype", $OutputType | Set-Content 'C:\Programdata\winlogbeat\winlogbeat.yml'
Write-Host "Starting WinLogBeat"
& C:\Programdata\winlogbeat\winlogbeat.exe test config -c C:\Programdata\winlogbeat\winlogbeat.yml -e
Start-Service 'winlogbeat-drmm'

And that’s it! WinlogBeat is now configured and sending logs to your output service.

Closing remarks

These are just examples on how you could configure log shipping, I’d advise anyone to ship their logs to a central location for all the reasons mentioned above; even if you’re not super security focused this should help you in getting to the next level. When you set this up, you should also start monitoring the services involved like Sysmon, Nxlog, or Winlogbeat.

As always, Happy PowerShelling. 🙂

All blogs are posted under AGPL3.0 unless stated otherwise
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy