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:
- Pure Bash implementation (no frameworks)
- HTTP Basic Authentication
- Default and custom endpoints
- Optional remote command execution
- Uses system shell by default (or user-defined)
- Colored logs with optional disable
- Minimal dependencies
bashsocatjqtimeoutddsha256sum- Standard Unix utilities (
uptime,lsblk, etc.)
Debian / Ubuntu
apt install socatpacman -S socatyum install socatgit clone https://github.com/yourusername/http2shell.git
cd http2shell
chmod +x http2shell.sh./http2shell.sh- Listens on 127.0.0.1:8007
- Uses rest:api for Basic Auth
- Enables /exec endpoint
- Uses system shell ($SHELL β bash β sh fallback)
-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/uptimeDisk info
curl -u rest:api http://127.0.0.1:8007/api/diskRemote command execution
curl -u rest:api -X POST http://127.0.0.1:8007/exec \
-d "id"Disable remote execution
./http2shell.sh --no-execAdd custom endpoint
./http2shell.sh --endpoint /api/hello "ps aux"Call it:
curl -u rest:api -X POST http://127.0.0.1:8007/api/helloUse custom shell
./http2shell.sh --shell /bin/zshSet custom timeouts
./http2shell.sh --cmd-timeout 30 --body-timeout 15Disable colored output
./http2shell.sh --no-colorThis guide explains how to send commands to shell2http from n8n via HTTP requests.
- Method:
POST - URL:
http://shell2http.offsec.pw/exec - Authentication:
- Credential type β Basic Auth
- Username:
rest - Password:
api
- Request Parameters: DISABLED
- Request Headers: DISABLED
- Request Body: ENABLED
- Content type: "Raw"
- Content type value:
text/plain - Body example (your command):
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 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:
- The input data is large (hundreds or thousands of lines)
- Passing data directly as command arguments is inconvenient or impossible
- You want to use tools like
grep,awk,sed,sort,uniq,waybackurls
-
Client sends a POST request with a JSON body
-
Server extracts all string values from JSON arrays
-
These 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 -
The server executes the command provided in the
xcmdHTTP header -
The server returns a JSON response with execution results
POST
/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"]'- Method: POST
- URL:
http://127.0.0.1:8007/execf - Authentication: Basic Auth (
rest/api) - Headers:
Content-Type: application/jsonxcmd: cat $textfile | grep test
- Body:
- Type:
Raw - Content-Type:
application/json - Value:
{{ $json.lines }}
- Type:
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> |
- Body timeout β HTTP 408
- Command timeout β HTTP 504
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 3xcmdmust be ASCII-only (HTTP header limitation)- Temporary file is removed after execution (current implementation)
/execfis intended for trusted environments only
- Do not use query parameters (e.g.,
?exec=ls) β the server only reads the POST request body. - Make sure to use Basic Auth, otherwise you will get a
401 Unauthorizederror. - For commands producing large output,
shell2httpis better than standard n8n shell nodes, as it has no 1 MB output limit.
- Run HTTP2Shell only in trusted environments. Never expose it directly to the public internet without additional protections (firewall, VPN, reverse proxy, IP filtering).


