Pen testers should be concerned about the security of their own machines, especially those machines that contain sensitive information, passwords, reports, and so forth. Pen testers are prime target for adversaries, and I know pen testers that were compromised by real-world adversaries.
Additionally, if you have ever participated in a red versus red operation, you will notice that many of the discussion topics and ideas for tools in this chapter will probably sound familiar. This chapter will highlight a few custom tools and techniques that you can employ to have better insights and protection, or at least hopefully steer some discussions to implement improvements. It is expected that you have knowledge around the operating systems mentioned in this chapter and are familiar with scripting and software engineering skills. A lot of the content in his chapter is not for beginners as it might require debugging and troubleshooting.
After reading this chapter, you will have a good understanding of how auditing works on various operating systems. You will know how to audit and alert for malicious file access to build traps for adversaries in case they compromise your machines. In addition, you will know how to implement a Windows Service as well as a custom Audit Dispatcher Plugin on Linux.
The following topics will be covered in this chapter:
The examples in this chapter cover multiple operating systems, and in order to follow them all Windows, Linux, and macOS are needed. We also will use Visual Studio Community Edition to build a Windows Service. Other than that, the majority of examples will leverage built-in operating system features. There is a lot of information in the second part of the book, some debugging and troubleshooting might be required; the content is not for beginners.
The code for this chapter can be found at https://github.com/PacktPublishing/Cybersecurity-Attacks-Red-Team-Strategies/tree/master/Chapter11.
The creation of digital traps (frequently referred to as canary tokens, honeypots, or honeytokens) is a useful technique that a mature blue team deploys to trick adversaries and red teamers. The red team should leverage the same tactic to defend assets. Interesting although outdated or fake information, such as passwords, keys, documents, and pen test reports, is deployed in the environment to trick adversaries to access it. When the item or assets are accessed, security events and notifications are triggered. This is an important technique that a red team that operates for a longer time must consider, due to the amount of sensitive information and collateral the team aggregates.
In this chapter, we will explore a range of options that can be leveraged. The idea is for pen testers who might not be as well-versed in blue team and monitoring topics to dive into these aspects and gain a better understanding of how deceptions can be leveraged.
On Windows, a good way to implement canary tokens and decoy files is via Audit ACLs. In Windows, every object can have a security descriptor, and there is even a language called the security descriptor definition language (SDDL) that articulates them.
The security descriptor basically contains a discretionary access control list (DACL) and an optional SACL. The former contains various Access Control Entries (ACEs) that contain information such as which account/group owns the resource and which account can read, write, and modify a particular resource.
The SACL (which is the lesser known aspect of the security descriptor) can be used for auditing purposes. This is an ACL that allows us to monitor an object for access. Using SACLs is perfect for sentinel objects and honeytokens. This is what we are going to do next.
As we mentioned previously, SACLs are used for auditing. Let's create a honeypot file and configure access monitoring using the following steps:
C:sharesecretsPROD> echo "it_admin:P@$$W0rd1!" > .passwords.txt
A curious adversary might be tempted to open the PROD password file. This is what we are looking for, in order to catch them!
The above screenshot shows that the Permissions, which are the DACLs that have been set for the object. The area we are interested in, however, is the Auditing tab.
In the preceding user interface, select Read and Read & execute to configure auditing for the password.txt file accordingly.
PS C:> Get-EventLog -LogName Security -Newest 10
The command might return a lot of secrutiy events, and there are options to limit the number of results, for instance using the -Newest parameter
The following screenshot shows the output of running the preceding command:
The preceding screenshot shows the various events in the security event log and that the very first entry is Auditing settings on object were changed. To explore the details of an event log entry, you can select certain properties of an event, for instance, the Message property:
PS C:> Get-EventLog -LogName Security -Index 14626 | Select-Object Message | Format-List
For comparison, the same event, when viewed in Event Viewer, looks as follows:
The preceding screenshot also shows the SDDL that was set (notice the Auditing Settings entry and New Security Descriptor that was applied).
What we want to do next is access the file and observe the creation of audit events.
What we are going to do now is read the file and make sure that auditing for read access is working correctly. To do that, let's open the file in Notepad to see if it triggers an audit event:
PS C:> notepad.exe notepad sharedsecretsPRODpasswords.txt
If you refresh the event log, however, you will see that there is still no audit entry being created for access to the file. Why is that?
In order to enable file and registry auditing for the local machine system, the local security policy has to be updated. This can be done via the following steps:
PS C:> notepad.exe notepad sharedsecretsPRODpasswords.txt
To get a detailed XML representation of the information, switch to the Details view:
Interestingly, we can observe that I didn't use notepad.exe and used the UI instead, which is denoted by ProcessName pointing to explorer.exe.
So far, we've learned how to configure auditing on Windows and how to set audit entries so that Windows emits event log entries whenever someone reads an audited file. Next, we are going to look at how to create notifications when such events occur.
We covered this topic when we walked through monitoring for successful and failed logon events. Like the logon notification Sentinel that we built in the previous chapter, it's possible to build out a file audit Sentinel with notifications by subscribing to new Audit ACL events and notifying the user when an interesting one is generated.
The following steps show the code/commands in PowerShell to do so:
$watcher = New-Object System.Diagnostics.Eventing.Reader.EventLogWatcher("Security")
$watcher.Enabled = $true
$OnEventWritten =
{
$e = $event.sourceEventArgs.EventRecord
if ($e.Id -eq 4656)
{
if ($e.FormatDescription() -like "*passwords.txt*")
{
Add-Type -AssemblyName System.Windows.Forms
$notification = New-Object System.Windows.Forms.NotifyIcon
$notification.Icon = [System.Drawing.SystemIcons]::Warning
$notification.Visible = $true
$notification.ShowBalloonTip(10000, "[Sentinel] – Honeypot file accessed!", "Review the Security Event Log for more details", [System.Windows.Forms.ToolTipIcon]::Warning)
}
}
}
This method receives the input events and compares whether the incoming event matches the audit event ID. If that is the case, it checks whether the description contains the word passwords.txt—remember that this is the name of the decoy file. If that is the case, we create a simple balloon popup.
Important Note
To improve the user experience around the notification, you can leverage BurntToastNotifications (https://github.com/Windos/BurntToast). This allows you to make more customizations for notifications. Feel free to review the previous chapter again for more details regarding BurntToastNotifications, as well as examples.
Register-ObjectEvent -InputObject $watcher -EventName EventRecordWritten -Action $OnEventWritten -SourceIdentifier SentinelNotify
Unregister-Event -SourceIdentifier SentinelNotify
That's it. The preceding commands showed how to set up monitoring as well as simple alerting using PowerShell.
Important Note
To run this Watcher continuously, it needs to be launched at startup and as a scheduled task. However, this is not ideal since if it crashes, it would stop working without the user knowing. There are two solutions to this problem.
The first is to run the task more frequently, such as once per minute, and add a check to see if the script is running already. If it's not, then launch it.
The arguably better second approach is to create a Windows Service. In case you have never created your own Windows Service, we will walk through creating a Homefield Sentinel Windows Service later in this chapter.
Another helpful thing is to add notifications when someone accesses a file or triggers audit events. There are a couple of ways to go about this. One way is to use the PowerShell COM Outlook automation scenario we walked through in the previous chapter. That approach has one fundamental drawback, which is that the user has to be logged in at the time.
For a notification scenario, it's better to use the PowerShell Send-MailMessage command, as follows:
Send-MailMessage -From "Sentinel Notifictaion <[email protected]>" -To "Sentinel Notification <[email protected]" -Subject "[Sentinel Notification] Honeypot file accessed." -Body $e.FormatDescription() -Priority High -DNO onSuccess, onFailure -SmtpServer "smtp-mail.outlook.com" -UseSSL -Credential $creds
In order to have the credentials available in a service or scheduled task, we can store them in the Credential Manager (of the account that runs the script) and then retrieve them when needed.
The following example script shows how to store a password in the Windows Credential Manager (you can either store the content in a file and execute it, or run the commands individually in PowerShell):
[void][Windows.Security.Credentials.PasswordVault, Windows.Security.Credentials, ContentType=WindowsRuntime]
$vault = New-Object Windows.Security.Credentials.PasswordVault
$credential = Get-Credential
$cred = New-Object Windows.Security.Credentials.PasswordCredential(
"Sentinel", $credential.GetNetworkCredential().Username, $credential.GetNetworkCredential().Password)
$vault.Add($cred)
The following screenshot shows what adding credentials looks like when being performed in PowerShell. The Get-Credential command is used to prompt the user to enter an account name and a password:
The preceding screenshot shows how to add a new credential to the Windows Credential Vault. In order to retrieve the stored credential, we can use the Retrieve method:
$vault.Retrieve("Sentinel","[email protected]")
Windows uses its data protection capabilities to encrypt the password. This means the password can only be decrypted using the same account that stored the secret in the Credential Manager.
The following screenshot shows retrieving the clear text password:
Using these APIs, we are equipped to run the script from a scheduled task, without having to store the password for the email account in clear text in the script. Let's look at how we can leverage a Scheduled Task to invoke the PowerShell script.
Previously, we leveraged EventLogWatcher to inspect logon events. The following script puts these various concepts together, including reading and decrypting the password to send email notifications.
What we will do in this section is create a PowerShell script that implements the Watcher and notifications, and then create a scheduled task to continuously run. Let's get started:
$watcher = New-Object
System.Diagnostics.Eventing.Reader.EventLogWatcher("Security")
$watcher.Enabled = $true
$OnEventWritten =
{
### Configuration Settings
$logfile = "$env:USERPROFILEsentinel.log"
$searchfilter = "*passwords.txt*"
$email = "[email protected]"
$smtp_server = "smtp-mail.outlook.com"
$subject = "[Sentinel Notification] Honeypot file accessed".
$e = $event.sourceEventArgs.EventRecord
if ($e.Id -eq 4656)
{
try
{
if ($e.FormatDescription() -like $ searchfilter)
{
### write a log entry
$e.FormatDescription() >> $logfile
[void][Windows.Security.Credentials.PasswordVault,
Windows.Security.Credentials,
ContentType=WindowsRuntime]
$vault = New-Object Windows.Security
.Credentials.PasswordVault
$emailpwd = ($vault.Retrieve("Sentinel",$email)
.Password) | ConvertTo-SecureString
-AsPlainText -Force
$emailcreds = New-Object System.Management
.Automation.PsCredential($email,
$emailpwd)
Send-MailMessage -From $email -To $email
-Subject $subject -Body $e.FormatDescription()
-Priority High -SmtpServer $smtp_server – Port
587 -UseSSL- Credential $emailcreds
}
}
Important Note
As can be seen in the preceding code, we leverage the password that we stored in the Credential Vault earlier.
catch
{
$_ >> $logfile
}
}
}
### Register the Event Handler
Register-ObjectEvent -InputObject $watcher -EventName EventRecordWritten -Action $OnEventWritten -SourceIdentifier SentinelNotify
SCHTASKS /CREATE
/SC ONSTART
/TN "Sentinel Schedule"
/RL Highest
/TR "powershell -ExecutionPolicy bypass
-WindowStyle Hidden -NoExit
%userprofile%sentinel.ps1"
/RU %username%
/RP
This will schedule a startup task that invokes the PowerShell script. /RP will request the password for the account specified via /RU. This is needed so that the script runs even if the user is not logged in. This is especially important in case the workstation reboots and the user does not log in.
SCHTASKS /RUN /TN "Sentinel Schedule"
If you prefer working with the user interface of Task Scheduler, launch it by typing Task Scheduler in the Windows search bar. This will show Task Scheduler, as shown in the following screenshot:
That's it. Now, you can manually launch the task or reboot the machine and it will start by itself. To improve reliability (without using a Windows Service), we could launch the task more frequently and check whether it is running already. If not, we launch the script.
As soon as someone reads the honeypot file in the c:sharedPRODsecretspasswords.txt file, we will receive a notification email. The following screenshot shows what such an email will look like:
As shown in the preceding screenshot, we have all the details of the specific event available in an email. This can be customized to your needs, including having less or more details in the email.
Although this works, and it was a good exercise to understand SACLs, scheduled tasks, and how to leverage PowerShell in a scheduled task, this solution has some limitations. For instance, if it crashes, it will not start again automatically. Another solution is to implement an actual Windows Service. This is what we will tackle next.
There is one flaw with the Scheduled Task solution that we've discussed so far. If someone kills the task or it crashes, it won't be started again automatically. This can be worked around by launching the task more often and querying whether the process is running, and if not, launching it.
There is another approach that can be taken on Windows, which includes the creation of a proper Windows Service. Since building a Windows Service can be quite handy at times (as well as to establish persistence during red teaming), the following section provides a walk-through on how to create a honeypot service that does some basic monitoring. A more advanced version of the Homefield Sentinel can be found at https://github.com/wunderwuzzi23/Sentinel. The goal of this section is to understand how to scaffold the basic service so that you know how to build your own deceptions or detections for scenarios.
You can use the free Visual Studio Community Edition to build and improve it.
To get started, download the latest version of Visual Studio Community Edition. At the time of writing, the download links are located at https://visualstudio.microsoft.com/downloads/.
When you're asked what Workloads to install, make sure to select Windows – .NET Desktop Development. That will ensure the proper libraries and tools are installed. Feel free to install more components if you would like to explore other features. Installation might take a little time.
After the installation has finished, launch Visual Studio. Go ahead and create a New Project. As the project type, we'll find the Windows Service project template. In this example, we will use C# to create the service, which basically includes all the scaffolding needed for a Windows Service.
The following screenshot shows the New Project dialog (the screen might look different depending on the version of Visual Studio being used):
After entering all the necessary information, click OK. Visual Studio will create all the code needed for a basic Windows Service.
In this section, we will create the basic outline for a Windows Service that will watch for file audit events. The goal of this exercise is to learn about the basics of a Windows Service so that you can extend it with other auditing functionality as you see fit. After creating the project as we did in the previous section, we can start adding functionality to it:
Feel free to inspect the file. At this point, nothing exciting is happening, besides some initialization.
The code of TheSentinel.cs contains three core methods:
The following steps show the implementation that looks for audit events for the password.txt file.
Let's walk through the details of defining these methods:
class TheSentinel
{
SmtpClient smtpClient;
EventLogWatcher logWatcher;
Logger log;
//event log query to retrieve event id 4656 (Audit ACLs)
EventLogQuery logQuery = new EventLogQuery("Security", PathType.LogName, "*[System/EventID=4656]");
public void StartWatching()
{
try
{
log = new Logger("sentinel.log");
log.WriteLine("Starting...");
this.smtpClient = new SmtpClient( "smtp-mail.outlook.com", 587);
this.logWatcher = new EventLogWatcher(logQuery);
this.logWatcher.EventRecordWritten +=
this.logWatcher_EventRecordWritten;
this.logWatcher.Enabled = true;
this.smtpClient.EnableSsl = true;
//project on github encrypts the credentials
this.smtpClient.Credentials = new NetworkCredential(
"youremail", "youremail");
log.WriteLine("Started.");
}
catch (Exception e)
{
log.WriteLine( " Error during startup: " + e.ToString());
}
}
private void logWatcher_EventRecordWritten(object sender,
EventRecordWrittenEventArgs e)
{
if (e.EventRecord.Id == 4656)
{
//Is this for the file of interest
if (e.EventRecord.FormatDescription().Contains("passwords.txt"))
{
try
{
log.WriteLine("Honeypot file accessed");
log.WriteLine(e.EventRecord.FormatDescription());
log.WriteLine("*********************************");
string email =
((NetworkCredential)this.smtpClient.Credentials).UserName;
MailMessage mail = new MailMessage(email, email);
mail.Subject = "[Sentinel Notification] Honeypot file accessed.";
mail.Body = e.EventRecord.FormatDescription();
mail.Priority = MailPriority.High;
mail.IsBodyHtml = false;
smtpClient.Send(mail);
}
catch (Exception ex)
{
log.WriteLine(
"Error OnEventWritten: " + ex.ToString());
}
}
}
}
public void StopWatching()
{
this.logWatcher.Enabled = false;
log.WriteLine("Stopped.");
}
}
At a high level, the preceding steps implement the Watcher. Whenever it is triggered, the code will write the notification to the log file as well as sending an email. In order to update the email configuration, please change the code accordingly to reflect the desired account.
Important Note
This is a simple implementation of a basic Watcher service. The project that you can find on GitHub at https://github.com/wunderwuzzi23/Sentinel has a lot more configuration options.
using System.Net.Mail;
using System.Diagnostics.Eventing.Reader;
using System.Net;
namespace Homefield.Sentinel
{
public partial class SentinelService : ServiceBase
{
TheSentinel sentinel; public SentinelService()
{
InitializeComponent();
/// create the sentinel
sentinel = new TheSentinel();
}
protected override void OnStart(string[] args)
{
sentinel.StartWatching();
}
protected override void OnStop()
{
sentinel.StopWatching();
}
}
}
using Homefield.Sentinel;
So far, we have created the code for the core service as well as the specific Sentinel class. What we will do next is add logging functionality.
Since a Windows Service does not typically interact with the user interface, it's a good practice to write all errors and interesting messages to a log file. In order to do this, we will implement a Logger class. Let's get started:
namespace Homefield.Sentinel
{
class Logger
{
StreamWriter writer;
public Logger(string filename)
{
writer = File.CreateText(filename);
}
public void WriteLine(string text)
{
string now = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss");
lock (writer)
{
writer.WriteLine(now + ": " + text);
writer.Flush();
}
}
}
}
using System.IO;
This class will allow the Sentinel to write information to a log file. At this point, we are basically done with creating the scaffold of the Homefield Sentinel. What we are still missing is allowing configurations to be driven by a config file and creating an installer to register the service with Windows Service Control Manager. These two things are what we are going to do next.
For simplicity, the code provided in this book does not encrypt the password and the parameters are not configurable. However, a prototype of the project can be found on GitHub, which contains code you can use to encrypt the password at rest in a configuration file so that it is not in source code in clear text. The project is located at https://github.com/wunderwuzzi23/Sentinel.
Feel free to explore and extend the Homefield Sentinel as you see fit.
The final step we are missing is creating a proper installer for the service. We need to do this in order to register the service with Windows. This is straightforward when using Visual Studio:
The preceding screenshot shows the changes to serviceProcessInstaller1. Those of you who are security minded will notice that running the entire service with such high privileges is not desirable. However, for this basic service, we'll keep the solution straightforward.
Make sure to right-click and specify Run as administrator. This will open an administrative shell that has the right path variables set to find the .NET-specific developer tools that we will use. The following screenshot shows the Developer Command Prompt being run as an Administrator:
sc.exe queryex "Homefield Sentinel"
The following screenshot shows running the command and its output:
As we can see, the service was stopped.
Similar to installing the service, we can use the installutil.exe tool and specify /u to uninstall the Homefield Sentinel service:
installutil.exe /u Homfield.Sentinel.exe
After running this command (as an Administrator), the service will be removed from the system again.
In this section, we made a quick detour to learn more about Windows Services and how to leverage them to implement a basic monitoring service for a machine. We provided a walk-through of Visual Studio regarding how to scaffold, implement, extend, install, and uninstall a Windows Service.
The Homefield Sentinel service is available on GitHub. The version that's been published there includes more features, such as email notifications and installation configuration, so make sure to check it out if you are interested in exploring this more: https://github.com/wunderwuzzi23/Sentinel.
The next section will focus on options for creating and monitoring access to trap files and honeypot files on Linux and macOS.
In Linux, there are a couple of ways to go about implementing decoy files to alert the red team of suspicious activities on hosts. The simplest way is probably using the inotifywait utility. Its use cases in this regard are limited. In this section, we will explore both inotifywait and auditd. The latter provides a lot of capabilities. First, let's create some credentials that might trick an adversary.
A good deception tactic to trick adversaries or other red teamers is to create fake SSH key files (something such as prod_rsa). This might trick someone to promptly try to inspect the file as it might appear to give access to production assets. Consider placing the file in a user's ~/.ssh folder because this is where adversaries will look for credentials.
The following screenshot shows how to use ssh-keygen to create a keypair:
The preceding screenshot highlights the creation of an RSA key to use as a decoy token on red team hosts. Next, let's explore options regarding how to monitor access to the file. We will look at two scenarios: inotifywait and auditd.
The simplest and quickest way to receive notifications for file reads on Linux is to use inotify. However, it has limitations, which we will highlight in this section. If inotifywait is not installed, install it with the following command:
$ sudo apt install inotify-tools
To set up a Watcher, use inotifywait. The following is an example that monitors for open and read access to the prod_rsa key that we created earlier:
$ inotifywait -m -e open,access ~/.ssh/root_rsa
The following screenshot shows running the command:
The preceding screenshot shows how inotifywait is now watching for access. Now that it is running, go to another shell and simulate malicious access to the file:
root@shadowbunny:~$ cat /home/wuzzi/.ssh/prod_rsa
The following screenshot shows the output of inotifywait after gaining file access:
The preceding screenshot shows the OPEN and ACCESS notifications. What is missing in this case is any context around which user opened the file, or what program accessed the file. Although inotify does have its valid use cases, for these scenarios, there are better, more versatile solutions.
On Linux, a good way to gain insights into what happens on a machine is by leveraging the Linux auditing framework. It's highly configurable via audit rules. To get started, make sure that auditd is installed on your machine:
$ sudo apt install auditd
To quickly understand and see what kind of auditing auditd provides by default, go ahead and run the following command:
$ sudo ausearch -r | more
This will show the audit events that were already recorded in their raw output form:
The preceding screenshot shows the raw audit content that is displayed by ausearch -r.
Information note
Auditd is configured via /etc/audit/auditd.conf. One setting to look at is log_group so that you can understand which users can access logs by default. If your account is not a member of this group, you might have to run the ausearch command as root.
For a better readable version, you can leverage --format text or --format CSV as options as well using the following command-line option:
$ sudo ausearch --format text
The following screenshot shows some example output of running the preceding command:
The preceding screenshot shows how the user ran commands as root and so forth.
As an exercise, perform a failed sudo command with an incorrect password or simulate a failed su command with an incorrect password and look at the audit log using ausearch --format text.
Can you find the relevant entries in the audit log?
More specifically, you can limit/filter searches via command-line arguments, as follows:
$ sudo ausearch -m USER_AUTH
As an example, this is what a failed su logon attempt looks like:
type=USER_AUTH msg=audit(1510830195.079:149): pid=6145 uid=1000 auid=1000 ses=5 msg='op=PAM:authentication acct="mallory" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/2 res=failed'
Those of you who are observant have probably already noticed how auditd can also be leveraged to solve some of the earlier challenges around monitoring for logons to a host. However, for this exercise, we want to focus on auditing and alerting suspicious access to honeypot files.
What we need to do now is create a Watcher for the decoy file that we created earlier. This can be done by updating the auditd configuration. This is what we will do next.
The prod_rsa file is not being watched by the auditing infrastructure just yet. This means that we will not receive an audit event when someone accesses it. In this case, we want to watch for access to the prod_rsa key file. Audit rules are configured in the audit.rules file.
The following steps show how to update the audit configuration:
$ sudo nano /etc/audit/rules.d/audit.rules
-w /home/wuzzi/.ssh/prod_rsa -p rwxa -k Sentinel
The following screenshot highlights adding the Watcher to audit.rules:
$ sudo service auditd restart
This will load the new rules accordingly.
# auditctl -l
The following screenshot shows the rules as a listing:
# auditctl -W /home/wuzzi/.ssh/prod_rsa -p rwxa -k Sentinel
The following points provide a quick explanation of the preceding auditctl command:
a) -w means a new entry for a file Watcher.
b) -p defines the access mode. In our case, we want to look for read (other options include w for write, x for execute, and a for attribute).
c) -k allows us to add a custom string that can be used to tag audit events. In our case, we use the string Sentinel. Afterward, we can search for that keyword easily. This is quite useful.
$ cat /home/wuzzi/.ssh/prod_rsa
# ausearch -k Sentinel
[…]
time->Sat Feb 9 17:13:01 2019
type=CONFIG_CHANGE msg=audit(1549761181.508:786): auid=1000 ses=3 op=add_rule key="Sentinel" list=4 res=1
----
time->Sat Feb 9 17:13:29 2019
type=PROCTITLE msg=audit(1549761209.485:787): proctitle=636174002F686F6D652F77757A7A692F2E7373682F70726F645F727361
type=PATH msg=audit(1549761209.485:787): item=0 name="/home/wuzzi/.ssh/prod_rsa" inode=1052502 dev=08:01 mode=0100644 ouid=1000 ogid=1000 rdev=00:00 nametype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=CWD msg=audit(1549761209.485:787): cwd="/home/wuzzi"
type=SYSCALL msg=audit(1549761209.485:787): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7ffd0974d7ea a2=0 a3=0 items=1 ppid=7292 pid=7438 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=3 comm="cat" exe="/bin/cat" key="Sentinel"
$
$ echo 636174002F686F6D652F77757A7A692F2E7373682F70726F645F727361 | xxd -r -p
What is the result?
There are a lot of commands and features that are available. For instance, it's possible to directly search for entries that are only relevant to the prod_rsa file, as follows:
# ausearch -f prod_rsa
# aureport -f
File Report
===============================================
# date time file syscall success exe auid event
===============================================
1. 2/9/2019 16:20:25 /home/wuzzi/.ssh/prod_rsa 257 yes /bin/cat 1000 296
2. 2/9/2019 17:19:47 /home/wuzzi/.ssh/prod_rsa 257 yes /bin/nano 1000 486
3. 2/9/2019 17:19:47 /home/wuzzi/.ssh/ 257 yes /bin/nano 1000 487
So far, we have explored some of the basics of auditing on Linux. There are many more features to explore and leverage to provide a holistic auditing experience for pen test machines. At the same time, these exercises can be quite useful for red teamers to better understand what techniques are used by blue teams to catch them.
The missing piece is to set up automated notifications, such as receiving an email upon someone accessing our honeypot file or even live notifications on the desktop. This can be done via audisp, which is an event multiplexer that allows us to invoke commands when certain events occur.
Unfortunately, there is no built-in audisp plugin that enables such scenarios.
Important Note
This section is for advanced users. We will create our own custom audit dispatcher and then integrate it with auditd. If you are familiar with C and do not mind compiling the code and setting up a config file for the plugin, then this is straightforward and provides the best experience for notifications.
There is a blog post by Steve Grubb from Red Hat showing how to implement custom audisp plugins. It also includes examples of how to extend them with sendmail functionality. The blog posts are located here for your reference: http://security-plus-data-science.blogspot.com/2017/04/sending-email-when-audisp-program-sees.html.
This blog post is the basis of the audisp-sentinel prototype that we will discuss now. It is a slightly modified version that allows us to pass an email recipient as an argument. To create and install audisp-sentinel, follow these steps:
gcc -o audisp-sentinel audisp-sentinel.c -lauparse -laudit
The preceding screenshot shows the configuration file of the newly created auditd plugin, including the additional argument for the mail recipient of the notifications.
$ sudo service auditd restart
Make sure that the audit rules (for example, the file Watcher) are still in in place, as well as that sendmail has been configured correctly. We walked through these steps earlier in this chapter. Feel free to go back and review this.
$ cat /home/wuzzi/.ssh/prod_rsa
The following screenshot shows the email being received by the email program:
In this section, we looked at creating custom audit dispatchers, which allow us to integrate with an audit daemon to create notifications. This is one of the best techniques to use as it is very versatile and allows for plenty of customizations. In the next section, we will look at how to achieve file access monitoring on macOS.
On macOS, there are a couple of ways to monitor file access. There is OpenBSM. The Basic Security Module (BSM) was originally created by Sun Microsystems and can be used for auditing. There are also tracing utilities such as fs_usage. In this section, we will explore multiple ways to monitor access to decoy files.
To get started, go ahead and create two decoy files with interesting names that might trick an adversary who is poking around your machines:
$ echo "S3cr3tP@$$W0Rd!" > /Users/john/password.txt
$ echo "S3cr3tP@$$W0Rd!" > /tmp/password.txt
The preceding commands will create two decoy files. We will set up monitoring for read access to these files later and trigger notifications when the file is being accessed. Now, let's explore how we can monitor access to these files. To get started, let's explore the fs_usage tool.
The fs_usage utility is a tool that allows you to monitor for various system events, including observing filesystem access. The good thing about fs_usage compared to other tracing utilities on macOS is that it works even when System Integrity Protection is enabled.
The following steps show you how to use it for monitoring access to the decoy file:
$ sudo fs_usage | grep "open.*password.txt"
$ sudo cat /Users/john/password.txt
After accessing the file, the terminal we launched fs_usage in will report the file open requests as seen in the following screenshot:
The preceding screenshot highlights how the decoy file, password.txt, was opened using cat and nano, as well as the mdworker daemon. You can also apply other high-level filters using the -f command. fs_usage allows you to filter for filesystems, networks, processes, and other events.
That's how simple it is to get some basic access monitoring in place. The next step is to have the script run in the background and whenever an event is triggered, notify the main user. In this case, we will use a desktop notification. To achieve that, we can use a LaunchDaemon, which is what we will do next.
A LaunchDaemon is a job that macOS will run at certain times, much like cron jobs. For our monitoring solution, let's call it the Audit Sentinel. The Audit Sentinel should begin monitoring when the machine starts up. To do that, we have to create a bash script that we will run when the machine starts up and runs the Audit Sentinel.
The following steps show how to create and set up a LaunchDaemon to run the Audit Sentinel:
#!/bin/sh
echo "Homefield Sentinel!"
#Search pattern to look for
PATTERN="open.*password.txt"
#Account to notify
ACCOUNT="bob"
fs_usage | while read line; do
if [[ «$line» =~ $PATTERN ]]; then
echo «Sentinel: $line»
su -l $ACCOUNT -c "osascript -e 'display notification "Honeypot file accessed. Review logs." with title "[Sentinel Notification]"'"
fi
done
echo "Done."
The preceding script does the following:
a) Configures a variable for PATTERN, that reflects the regular expression pattern we are looking for in events.
b) Configures a variable for ACCOUNT, which is the account that will receive a notification on the desktop.
c) The script waits for events using fs_usage.
d) For each event, we compare the incoming $line with the defined regular expression, $PATTERN, to see if they contain the open and password.txt keywords.
e) Whenever we have such a hit, we launch osascript to send a notification to the defined $ACCOUNT. In this example, this is the user account bob. We leverage su before running the command.
# chmod 700 auditsentinel.sh
The preceding screenshot shows the launch daemon plist configuration. Feel free to type the configuration in by hand. Alternatively, you can copy one of the other LaunchDaemons and then update the plist file accordingly.
$ sudo launchctl load /Library/LaunchDaemons/auditsentinel.plist
As with the scenarios we've covered already, sending an email is probably also a good idea (for example, via sendmail, as we did in the previous chapter). This is the most straightforward way to implement file read access monitoring on macOS. Next, we'll look at the OpenBSM auditing system in more detail.
BSM was originally created by Sun Microsystems, and it is available on macOS as well, in the form of OpenBSM.
Audit events are streamed to /dev/auditpipe. The event stream is in a binary format. Using a utility called praudit, we can parse the events in text and XML:
$ sudo praudit -xl /dev/auditpipe | more
We can force praudit to write the output per event in one line using the -l command. If you prefer parsing XML, that is possible using -x. The following screenshot shows the output of running this command:
The preceding screenshot shows the audit events being displayed as XML with the praudit utility. If you prefer parsing or investigating past data, the audit files are located at /var/audit/. The active audit file in that folder has a symlink called current.
Let's explore how to configure OpenBSM in more detail.
Now that we've covered some basics, let's explore configuration details. What operations are audited can be configured via /etc/security/audit_control.
In order to log file operations, we add fr (file read) to the flags line in the configuration file. The following steps explain how to set up file access monitoring and how to create notifications as well:
$ sudo nano /etc/security/audit_control
The following screenshot shows the file opened in the nano editor with the file read flag added:
The preceding command will synchronize the settings and the audit configuration.
$ sudo praudit -lx /dev/auditpipe | grep password.txt
Important Note
There is an alternative called supraudit that has more and better features and improvements. It is a custom download that can be found at http://newosxbook.com/tools/supraudit.html.
supraudit works much better compared to praudit. It allows color output and shows the process name that accessed the file. It also appears to be more reliable when it comes to capturing audit events. For the remainder of this chapter, we will be using supraudit.
As can be seen in the preceding screenshot, the output of supraudit is much cleaner compared to praudit. It offers features such as printing in color or JSON. Note that it shows the process that opened the decoy file (in this case, cat and nano).
Using the -F option, supraudit allows us to filter for certain events, such as network, file, or process operations. Going forward, we will use supraudit, but you can also follow along using praudit. In particular, we will be using -S (for SuperAudit records, which seem to be more reliable compared to praudit).
Now that we have the audit framework monitoring file read access, we can create LaunchDaemon to continuously watch for anyone opening the decoy file, as we did earlier. This is the same approach that we used with fs_usage, which we walked through earlier in this section. This is what the script that invokes supraudit looks like:
As you can see, it is the same script that we used with fs_usage; we just replaced the call to fs_usage with supraudit to filter for events.
Important Note
There are other ways to monitor file operations; for instance, WatchPaths in LaunchAgents. These can be configured to run commands when certain files change on the system. Read up on Launch Agent configuration files and the WatchPaths setting to learn more.
In this section, we discussed useful techniques and ideas for event auditing and how to leverage built-in operating features. One core aspect that we have focused on so far is that all our monitoring, alerting, and notifications were happening on the machine itself. This is sort of a guerilla-style type of monitoring, which fits a red team well.
Although having better insights at scale is an important part of a good strategy to protect the pen test assets, it is also beneficial to offload monitoring and audit logs as soon as possible from the machine to another system. This topic is the focus of the next chapter.
In this chapter, we looked at the important aspects of actively protecting pen testing assets by using decoy files and explored other related deception ideas.
We looked at various operating systems and explored how to implement decoy files. We also highlighted the benefits and trade-offs of various solutions. Decoy files might trick an adversary who attempts to gain access to your machine by opening interesting looking files. For notifications, we leveraged pop-up notifications on the desktop, emails, as well as logging to files and security event logs.
For Windows, we learned how to build a Windows Service that uses a System Access Control List to audit important files and alert us when they are accessed.
Additionally, we learned how to use OpenBMS on macOS and auditd on Linux to help monitor and audit access. For those who wanted to try out more advanced tasks, we looked at the creation of auditd plugins, which can be leveraged to integrate and customize the auditing infrastructure on Linux.
In the next chapter, we will learn about common off-the-shelf blue team tools. Knowing about these is beneficial for red teamers for two reasons. First, you might consider protecting your own fleet with them, and second, knowing the blue team tools will allow you to bypass or attack them.
3.14.70.203