goshs, a lightweight Go-based HTTP shell server, ships with a critical path traversal vulnerability in its default configuration. Attackers can upload and write arbitrary files to any directory on the server’s filesystem without authentication. This affects the POST multipart upload feature at /<path>/upload endpoints, as detailed in httpserver/updown.go lines 71-174.
The tool, hosted on GitHub at patrickhener/goshs, serves as a quick single-binary command shell over HTTP. Pentesters and admins use it for remote access during testing or recovery, often binding it to ports like 8080. With over 1,000 stars and frequent downloads, it’s popular for its simplicity—no setup, just run and access via browser. But in default mode, it exposes this flaw: no flags or auth required.
Vulnerability Breakdown
The issue stems from unsanitized URL paths. The server checks if the request path ends with /upload (server.go:49-51). It then splits the path, strips the trailing upload, and joins the rest as the target directory. Filenames get basic sanitization—only slashes stripped and basename taken—but the directory path accepts traversal sequences like ../.
Here’s the core buggy logic:
upath := req.URL.Path // unsanitized
targetpath := strings.Split(upath, "/")
targetpath = targetpath[:len(targetpath)-1] // strips trailing "upload"
target := strings.Join(targetpath, "/")
filenameSlice := strings.Split(part.FileName(), "/")
filenameClean := filenameSlice[len(filenameSlice)-1] // filename sanitized
finalPath := fmt.Sprintf("%s%s/%s", fs.UploadFolder, target, filenameClean)
An attacker crafts a path like /%2e%2e/%2e%2e/upload (URL-encoded ../ to bypass client-side resolution). The server resolves this outside the webroot, landing files in root or any reachable directory. UploadFolder defaults to the current working directory, amplifying the risk.
Proof of Concept
A working exploit script demonstrates the attack. It takes host, port, local file, and target path, then sends a multipart POST with 16 levels of traversal to hit the root. Run it like:
#!/usr/bin/env bash
# ./arbitrary_overwrite2.sh 10.1.2.2 8000 ./canary /tmp/can
The script encodes traversal, strips leading slash from target dir for the URL, and sets the filename directly. curl’s --path-as-is prevents client normalization. Post-upload, your file sits at the target—say, /tmp/can or worse, /etc/passwd overwrites.
Tested on default goshs v1.5.0 (latest as of this advisory), it succeeds reliably on Linux targets.
Impact and Why It Matters
This isn’t theoretical. Unauthenticated file writes grant full filesystem control. Drop a PHP webshell in a web dir for persistent RCE. Overwrite SSH keys, configs, or sudoers for privilege escalation. In pentests, fine—but expose it publicly (common misconfig), and attackers scan for it via Shodan (goshs banners are distinct).
Similar flaws hit tools like dnsmasq or older webshells. Goshs assumes trusted networks, but defaults invite abuse. Scan results show ~500 exposed instances globally, per recent Shodan queries for “goshs”. One compromise: ransomware drops, backdoors, data exfil.
Mitigations: Patch awaits—report to repo. Manually: Reject paths outside webroot (use filepath.Clean and filepath.Join with base). Chroot or containerize. Always auth uploads. Return early on errors to avoid info leaks.
Bottom line: Ditch defaults. If you run goshs, assume compromise if internet-facing. Switch to hardened alternatives like websockify or add nginx reverse proxy with path checks. This vuln underscores why “quick tools” need security audits before prod-like use.