Monday, May 19, 2014

Modifying MAC properties with PowerShell

Laziness is the demise of Red Team engagements. Whether it is writing PsExec to a user's desktop or writing other arbitrary binaries to disk, not being careful can lead to being discovered. One of the competitors of this year's National CCDC mentioned to me that his team focused on discovering files created during the competition. If we were all being careful, that shouldn't work. Linux has the ability to modify file attributes with the "Touch" utility. Meterpreter has TimeStomp which works on Windows and makes it easy to blend your files with files around it by modifying the MACE attributes.

After a request to add the capability to PowerSploit, I wanted to figure out how to do it (I do prefer avoiding writing anything to disk, but there are times when it is unavoidable). I always thought that TimeStomp was black magic, but then I noticed the capability in Cobalt Strike's Beacon. I asked Raphael and he pointed me to a well-documented part of the Windows API. So naturally I headed over to pinvoke.net to check out the C# sample. It didn't take long to have a working function, but I got curious and found a .Net class to simplify the code. Armed with two working functions, I boarded the plane after ShowMeCon and wondered if it were possible to accomplish the task in a more "PowerShelly" (technical term) way.

Lets explore with Get-Member:


Wow, we can set the modified, accessed and created properties with Get-Item. That means we can simply run:

PowerShell.exe -com {$file=(gi c:\demo\test.txt);$date='01/03/2006 12:12 pm';$file.LastWriteTime=$date;$file.LastAccessTime=$date;$file.CreationTime=$date}
view raw gistfile1.ps1 hosted with ❤ by GitHub

Nothing novel, but cool nonetheless. Some people would prefer a more "Touch" like capability, so I wrapped it all up in a function called Set-MacAttributes which will be added to PowerSploit soon:

function Set-MacAttribute {
<#
.SYNOPSIS
Sets the modified, accessed and created (Mac) attributes for a file based on another file or input.
PowerSploit Function: Set-MacAttribute
Author: Chris Campbell (@obscuresec)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
Version: 1.0.0
.DESCRIPTION
Set-MacAttribute sets one or more Mac attributes and returns the new attribute values of the file.
.EXAMPLE
PS C:\> Set-MacAttribute -FilePath c:\test\newfile -OldFilePath c:\test\oldfile
.EXAMPLE
PS C:\> Set-MacAttribute -FilePath c:\demo\test.xt -All "01/03/2006 12:12 pm"
.EXAMPLE
PS C:\> Set-MacAttribute -FilePath c:\demo\test.txt -Modified "01/03/2006 12:12 pm" -Accessed "01/03/2006 12:11 pm" -Created "01/03/2006 12:10 pm"
.LINK
http://www.obscuresec.com/2014/05/touch.html
#>
[CmdletBinding(DefaultParameterSetName = 'Touch')]
Param (
[Parameter(Position = 1,Mandatory = $True)]
[ValidateNotNullOrEmpty()]
[String]
$FilePath,
[Parameter(ParameterSetName = 'Touch')]
[ValidateNotNullOrEmpty()]
[String]
$OldFilePath,
[Parameter(ParameterSetName = 'Individual')]
[DateTime]
$Modified,
[Parameter(ParameterSetName = 'Individual')]
[DateTime]
$Accessed,
[Parameter(ParameterSetName = 'Individual')]
[DateTime]
$Created,
[Parameter(ParameterSetName = 'All')]
[DateTime]
$AllMacAttributes
)
Set-StrictMode -Version 2.0
#Helper function that returns an object with the MAC attributes of a file.
function Get-MacAttribute {
param($OldFileName)
if (!(Test-Path $OldFileName)){Throw "File Not Found"}
$FileInfoObject = (Get-Item $OldFileName)
$ObjectProperties = @{'Modified' = ($FileInfoObject.LastWriteTime);
'Accessed' = ($FileInfoObject.LastAccessTime);
'Created' = ($FileInfoObject.CreationTime)};
$ResultObject = New-Object -TypeName PSObject -Property $ObjectProperties
Return $ResultObject
}
#test and set variables
if (!(Test-Path $FilePath)){Throw "$FilePath not found"}
$FileInfoObject = (Get-Item $FilePath)
if ($PSBoundParameters['AllMacAttributes']){
$Modified = $AllMacAttributes
$Accessed = $AllMacAttributes
$Created = $AllMacAttributes
}
if ($PSBoundParameters['OldFilePath']){
if (!(Test-Path $OldFilePath)){Write-Error "$OldFilePath not found."}
$CopyFileMac = (Get-MacAttribute $OldFilePath)
$Modified = $CopyFileMac.Modified
$Accessed = $CopyFileMac.Accessed
$Created = $CopyFileMac.Created
}
if ($Modified) {$FileInfoObject.LastWriteTime = $Modified}
if ($Accessed) {$FileInfoObject.LastAccessTime = $Accessed}
if ($Created) {$FileInfoObject.CreationTime = $Created}
Return (Get-MacAttribute $FilePath)
}
view raw gistfile1.ps1 hosted with ❤ by GitHub


I think its a prime example of why you should start by exploring cmdlets, then check out .Net and finally the API. It can save you a lot of time when you are building PowerShell tools. Obviously this won't stand up to forensic scrutiny like TimeStomp will, but it will definitely serve the purpose of hiding files in plain sight.

-Chris



Sunday, May 18, 2014

Dirty PowerShell WebServer

I was recently asked why there wasn't a PowerShell entry in this great list of web-server one-liners. Of course it is possible, but not as easy as with other scripting languages. Web-servers are dangerous in the wrong hands, but testers use them all the time (not always safely). I have seen people upload utilities like Mongoose to accomplish serving static files, but it can  be accomplished with PowerShell and the .Net httplistener class. The goal of the one-liners was to serve static files from the present working directory on port 8000. Since we know the goal is to have a small and dirty script, we can skip error-handling and use aliases:

 
$Hso = New-Object Net.HttpListener
$Hso.Prefixes.Add("http://+:8000/")
$Hso.Start()
While ($Hso.IsListening) {
$HC = $Hso.GetContext()
$HRes = $HC.Response
$HRes.Headers.Add("Content-Type","text/plain")
$Buf = [Text.Encoding]::UTF8.GetBytes((GC (Join-Path $Pwd ($HC.Request).RawUrl)))
$HRes.ContentLength64 = $Buf.Length
$HRes.OutputStream.Write($Buf,0,$Buf.Length)
$HRes.Close()
}
$Hso.Stop()

So that wasn't painful, but not too helpful. How did we get here? Lets pipe the created object to Get-Member and explore the relevant properties and methods.


Now that we can put together a basic usage of the httplistener object, lets explore some of the properties of the request. Specifically, we need to know what part of the request we can use to find the name of the file. We can use the debugger that comes with the ISE to catch our loop and use the console to enumerate each of the properties until we find the one we want:


Now that we have everything put together, we just need roll it into a one-liner and encode it:



Finally, we have our encoded one-liner which will statically serve files from the present working directory.


We will need to have admin rights to grab a port, but otherwise it is pretty handy.


Thanks for reading about the basics of the httplistener class, maybe you will find it useful.

-Chris