HTTP2Shell is a lightweight HTTP API server written entirely in Bash and powered by socat.
It allows you to expose simple REST-like endpoints over HTTP for remote command execution and system introspection.
The tool is designed for internal automation, DevOps tasks, red-team labs, CTF environments, and self-hosted admin utilities.
It is not intended for public internet exposure.
This tool was inspired by the article on Habr https://habr.com/ru/articles/796731/ . I created this tool to solve a limitation I faced while automating Bug Bounty workflows in n8n. n8n does not allow saving shell command outputs larger than 1 MB when running commands directly. Previously, I had to first save the output to a file and then read it with another n8n node, which was inconvenient. Thanks to the insights from the article, I found a way to handle this problem more efficiently.
This tool will also be used in my other project, which is designed to work with n8n: https://github.com/solo10010/Hacker-Toolbox
Key features:
bashsocatjqtimeoutddsha256sumuptime, lsblk, etc.)Debian / Ubuntu
apt install socat
pacman -S socat
yum install socat
git clone https://github.com/yourusername/http2shell.git
cd http2shell
chmod +x http2shell.sh
./http2shell.sh
### Available options
-h, --help Show help
-ip, --ip <ip> Listen IP (default: 127.0.0.1)
-port, --port <port> Listen port (default: 8007)
-u, --user <user> Basic auth user (default: rest)
-p, --pass <pass> Basic auth password (default: api)
-s, --shell <path> Shell for command execution (default: auto-detect)
--no-exec Disable /exec and /execf endpoints
-e, --endpoint <uri> <command> Add custom POST endpoint
--no-color Disable colored logs
--cmd-timeout <sec> Timeout for xcmd execution (default: 20)
--body-timeout <sec> Timeout for reading request body (default: 10)
Uptime
curl -u rest:api http://127.0.0.1:8007/api/uptime
Disk info
curl -u rest:api http://127.0.0.1:8007/api/disk
Remote command execution
curl -u rest:api -X POST http://127.0.0.1:8007/exec \
-d "id"
Disable remote execution
./http2shell.sh --no-exec
Add custom endpoint
./http2shell.sh --endpoint /api/hello "ps aux"
Call it:
curl -u rest:api -X POST http://127.0.0.1:8007/api/hello
Use custom shell
./http2shell.sh --shell /bin/zsh
Set custom timeouts
./http2shell.sh --cmd-timeout 30 --body-timeout 15
Disable colored output
./http2shell.sh --no-color
This guide explains how to send commands to shell2http from n8n via HTTP requests.
POSThttp://shell2http.offsec.pw/execrestapitext/plain
ls -la[
{
"data": "total 32\ndrwxr-xr-x 4 root root 4096 Dec 14 20:47 .\ndrwxr-xr-x 19 root root 4096 Dec 14 20:43 ..\ndrwxr-xr-x 7 root root 4096 Dec 14 20:43 .git\ndrwxr-xr-x 2 root root 4096 Dec 14 21:36 assets\n-rwxr-xr-x 1 root root 6242 Dec 14 21:21 http2shell.sh\n-rw-r--r-- 1 root root 4103 Dec 14 21:37 readme.md"
}
]
Next, you can parse the output through the n8n node βCode in JavaScriptβ example of how to parse a command ls -la
const raw = items[0].json.data;
// Split output into separate lines
const lines = raw.split('\n');
// Remove the "total" line and empty lines
const files = lines.filter(l => l && !l.startsWith('total'));
return files.map(line => ({
json: {
line
}
}));
/execf β File-backed execution (HTTP2Shell)/execf/execf is an execution endpoint designed to work with large text inputs
(lines, lists, URLs, words, etc.) that need to be processed by standard Unix tools.
It is useful when:
grep, awk, sed, sort, uniq, waybackurls/execf worksThese strings are written line-by-line into a temporary file:
/tmp/http2shell-<sha256>.txt
The file path is exported to the command as an environment variable:
$textfile
xcmd HTTP headerPOST
/execf
| Header | Description |
|---|---|
xcmd |
Shell command that uses $textfile |
Example:
cat $textfile | grep test
Recommended format β array of strings
["line one", "line two", "test", "another line"]
Also supported β nested JSON
[
{
"linesArray": ["one", "two", "three"],
"count": 3
}
]
All string elements found inside JSON arrays are written one per line into $textfile.
{
"textfile": "/tmp/http2shell-acde1234.txt",
"stdout": "command output\n",
"stderr": "",
"code": 0
}
| Field | Description |
|---|---|
textfile |
Path to temporary file |
stdout |
Standard output of the command |
stderr |
Standard error output |
code |
Command exit code |
curl -u rest:api \
-X POST http://127.0.0.1:8007/execf \
-H 'Content-Type: application/json' \
-H 'xcmd: cat $textfile | grep test' \
--data-binary '["one","two","test","three"]'
curl -u rest:api \
-X POST http://127.0.0.1:8007/execf \
-H 'Content-Type: application/json' \
-H 'xcmd: sort -u $textfile' \
--data-binary '["b","a","b","c"]'
curl -u rest:api \
-X POST http://127.0.0.1:8007/execf \
-H 'Content-Type: application/json' \
-H 'xcmd: wc -l < $textfile' \
--data-binary '["a","b","c"]'
http://127.0.0.1:8007/execfrest / api)Content-Type: application/jsonxcmd: cat $textfile | grep testRawapplication/json
const text = `one
two
three
test
four`;
const lines = text
.split('\n')
.map(s => s.trim())
.filter(Boolean);
return [{
json: {
lines,
count: lines.length
}
}];
The server enforces time limits:
| Parameter | Description | Default | Command-line option |
|---|---|---|---|
BODY_TIMEOUT |
Request body read timeout | 10s | --body-timeout <sec> |
CMD_TIMEOUT |
Command execution timeout | 20s | --cmd-timeout <sec> |
Examples:
# Set longer timeouts for heavy operations
./http2shell.sh --cmd-timeout 60 --body-timeout 30
# Set shorter timeouts for fast responses
./http2shell.sh --cmd-timeout 5 --body-timeout 3
xcmd must be ASCII-only (HTTP header limitation)/execf is intended for trusted environments only?exec=ls) β the server only reads the POST request body.401 Unauthorized error.shell2http is better than standard n8n shell nodes, as it has no 1 MB output limit.