Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Monday, July 7, 2014

Ready, Set, Go.....Format, Encrypt, and Prepare a Removable USB Drive using BitLocker and PowerShell

In my line of work protecting customer data is extremely important, and with that in mind unfortunately some times there is just no way to retrieve data for analysis without using a USB Drive. This presents some important requirements for any removable drive used in this way and for me that includes regularly performing three main tasks:
  1. Format the drive (erase any previous customers data)
  2. Encrypt the drive
  3. Copy any tools etc back onto the drive
So recently I have been working on automating this with PowerShell, through the use of the BitLocker and Storage modules.

Introducing the USB Drive Wipe Prepare project.

What you will need:
  • PowerShell 3+
  • BitLocker Module (recommend at least Windows 8, Windows 2012)

While the complete script can be found here I will focus this post on the challenges I faced with building such solution so that if you are working on a similar project you can benefit from my hard work :)

The most challenging aspect of this was working with Bitlocker CmdLets, so they are my main focus.

The first step is to format the drive with Format-Volume.
$Result = Format-Volume -ObjectId $($Volume.ObjectId) -FileSystem $($Volume.FileSystem) -NewFileSystemLabel $($Volume.FileSystemLabel);

The next step is to encrypt the volume with BitLocker. This involves a number of steps.

  1. Firstly, due to my employers GPO setting (and a best practice) I must add a recovery password key to the drive.
    $Result = Add-BitLockerKeyProtector -MountPoint "$($Volume.DriveLetter):" -RecoveryPasswordProtector
    
    
  2. As part of this it is best practice to then make sure you have the Recovery Key saved off to a location. Earlier in the script I create a PSDrive to reference this location and simplify scripting.
    "Bitlocker Key for $($Volume.FileSystemLabel)`r`n `
    Identifier: $((Get-BitLockerVolume "$($Volume.DriveLetter):").KeyProtector.KeyProtectorId)`r`n `Key: $((Get-BitLockerVolume "$($Volume.DriveLetter):").KeyProtector.RecoveryPassword)" | Out-File -FilePath "BitLockerKeys:\$($Volume.FileSystemLabel).BitLockerKey.txt";
    
    
  3. Next I enable BitLocker on the Removable Drive with a Password (effectively using BitLocker2Go)
    $Result = Enable-BitLocker -MountPoint "$($Volume.DriveLetter):" -EncryptionMethod Aes256 -UsedSpaceOnly -Password $BitLockerPassword -PasswordProtector;
    
    
  4. As the encryption process can take some time the next part of my script checks the status of the protection with
    while ((Get-BitLockerVolume -MountPoint "$($Volume.DriveLetter):").EncryptionPercentage -lt 100)
    ....
    
    
After encrypting the drive my script then copies files/folders which I have stored in a common path on my laptop for use on most customer engagements. This is a specific need for my line of work however the functionality could be used for anything. I retrieve the path from a XML configuration file during the Begin block of the script, and if that file doesn't exist then it is created. The user can also supply a "-Setup" switch parameter to force the script to prompt for the configuration settings and rebuild the config XML file.

This script is provided "as is" however should you be performing similar operations around Encrypting removable drives this may help you towards your solution.

As mentioned above the complete script can be found on the CodePlex project https://usbdrivepreptool.codeplex.com/




Legal Stuff: As always the contents of this blog is provided “as-is”. The information, opinions and views expressed are those of the author and do not necessarily state or reflect those of any other company with affiliation to the products discussed. This includes any URLs or Tools. The author does not accept any responsibility from the use of the information or tools mentioned within this blog, and recommends adequate evaluation against your own requirements to measure suitability.
 

Monday, October 21, 2013

Tips for securing xp_cmdshell (when you really really have to use it)

If you have ever read anything about securing SQL server one of the most common threats that is called out is the use of xp_cmdshell. While it is generally accepted that this is a bad thing to enable within a production environment, there are some ligament cases where business, application, or probably more accurately legacy processes, require the use of xp_cmdshell. When we do enable this feature it is important to ensure that security is strictly locked down to prevent unwanted access to sensitive areas on the server or greater still, malicious actions on local and network components.

I was recently asked what my recommendations would be for securely implementing xp_cmdshell, and in my experience here are the steps to perform this:

Step 1
By default xp_cmdshell will execute under the context of the SQL Server service account, therefore the first step in reducing any risk is ensure that the account used for the SQL Server service is aligned to best practises. Such recommendations include the use of an account which:
    - Is not a local or domain administrator
    - Is a domain account where network resources may be required by aspects of the SQL environment (e.g. copying backup files to a network path)
    - Has minimal local and domain privileges
    - Has been configured using the SQL Server Configuration Manager

To completely secure the environment a separate account should also be used for the SQL Agent service with the same recommendations.

Step 2
Ensure that only the required users are members of the SQL Server SysAdmin server level role. Any members of this role will be able to execute xp_cmdshell and therefore allowed access to all aspects of the server that the SQL Service Account can access.

Step 3
Create a xp_cmdshell proxy account following the instructions at http://technet.microsoft.com/en-us/library/ms175046.aspx
This proxy account should be a unique domain user and separate to the SQL Server Service Account. It will be used when non-sysadmin SQL Logins execute xp_cmdshell and therefore an even restricted Access Control List (ACL) can be configured on the SQL Server and Network resources for that specific account. This will assist in significantly reducing the footprint area which is vulnerable to threat by xp_cmdshell.

Step 4
Grant the required permissions to specific non-sysadmin SQL Logins who require the ability to execute xp_cmdshell using the syntax: GRANT exec ON xp_cmdshell TO ''
This will ensure that only the SQL Logins which you have configured as either members of the SysAdmins built-in role, or explicitly granted execute permissions will be able to access the system via xp_cmdshell.
To view which SQL Logins have been granted permissions for xp_cmdshell run the following TSQL:












USE master;
GO
SELECT sys.schemas.name AS [schema_name]
, AllObjects.name AS [object_name]
, sys.database_permissions.permission_name
, sys.database_permissions.state_desc
, sys.database_principals.name AS [granted_to_principal_name]
FROM sys.database_permissions
INNER JOIN sys.database_principals ON sys.database_principals.principal_id = sys.database_permissions.grantee_principal_id
INNER JOIN (
        SELECT name, object_id, principal_id, schema_id, parent_object_id, type, type_desc, create_date, modify_date, is_ms_shipped, is_published, is_schema_published
        FROM sys.objects
        UNION
        SELECT name, object_id, principal_id, schema_id, parent_object_id, type, type_desc, create_date, modify_date, is_ms_shipped, is_published, is_schema_published
        FROM sys.system_objects
) AllObjects ON AllObjects.object_id = sys.database_permissions.major_id
LEFT JOIN sys.schemas ON sys.schemas.schema_id = AllObjects.schema_id
WHERE sys.schemas.name = 'sys'
AND AllObjects.name = 'xp_cmdshell'
ORDER BY sys.schemas.name
, AllObjects.name
, sys.database_principals.name
, sys.database_permissions.class;

 
Final Step
Start reviewing the processes, code, and reasons for using xp_cmdshell to determine if a more secure method could be used (e.g. PowerShell) to achieve the same outcome. Some might argue this should be the first step, but lets be realistic, you cannot always change an applications behavior especially if it is provided by a 3rd party so while this step definitely needs to be performed it may be the most difficult and longest of them all.



Legal Stuff: As always the contents of this blog is provided “as-is”. The information, opinions and views expressed are those of the author and do not necessarily state or reflect those of any other company with affiliation to the products discussed. This includes any URLs or Tools. The author does not accept any responsibility from the use of the information or tools mentioned within this blog, and recommends adequate evaluation against your own requirements to measure suitability.