Executing shell commands via HTTP server

Overview

shell2http

GoDoc Build Status Coverage Status Report Card Docker Pulls Homebrew formula exists Snap Status

HTTP-server to execute shell commands. Designed for development, prototyping or remote control. Settings through two command line arguments, path and shell command. By default bind to :8080.

Usage

shell2http [options] /path "shell command" /path2 "shell command2" ...
options:
    -host="host"      : host IP for http server (default bind to all interfaces)
    -port=NNNN        : port for http server, 0 - to receive a random port (default 8080)
    -form             : parse query into environment vars, handle uploaded files
    -cgi              : run scripts in CGI-mode:
                        - set environment variables with HTTP-request information
                        - write POST|PUT|PATCH-data to script STDIN (if is not set -form)
                        - parse headers from script (eg: "Location: URL\n\n")
    -export-vars=var  : export environment vars ("VAR1,VAR2,...")
                        by default export PATH, HOME, LANG, USER, TMPDIR
    -export-all-vars  : export all current environment vars
    -no-index         : don't generate index page
    -add-exit         : add /exit command
    -log=filename     : log filename, default - STDOUT
    -shell="shell"    : shell for execute command, "" - without shell (default "sh")
    -cache=N          : caching command out for N seconds
    -one-thread       : run each shell command in one thread
    -show-errors      : show the standard output even if the command exits with a non-zero exit code
    -include-stderr   : include stderr to output (default is stdout only)
    -cert=cert.pem    : SSL certificate path (if specified -cert/-key options - run https server)
    -key=key.pem      : SSL private key path
    -basic-auth=""    : setup HTTP Basic Authentication ("user_name:password"), can be used several times
    -timeout=N        : set timeout for execute shell command (in seconds)
    -no-log-timestamp : log output without timestamps
    -version
    -help

In the -form mode, variables are available for shell scripts:

  • $v_NNN -- data from query parameter with name "NNN" (example: http://localhost:8080/path?NNN=123)
  • $filepath_ID -- uploaded file path, ID - id from <input type=file name=ID>, temporary uploaded file will be automatically deleted
  • $filename_ID -- uploaded file name from browser

To setup multiple auth users, you can specify the -basic-auth option multiple times. The credentials for basic authentication may also be provided via the SH_BASIC_AUTH environment variable. You can specify the preferred HTTP-method (via METHOD: prefix for path): shell2http GET:/date date

Install

MacOS:

brew tap msoap/tools
brew install shell2http
# update:
brew upgrade shell2http

Using snap (Ubuntu or any Linux distribution with snap):

# install stable version:
sudo snap install shell2http

# install the latest version:
sudo snap install --edge shell2http

# update
sudo snap refresh shell2http

Notice: the snap-package has its own sandbox with the /bin, /usr/bin directories which are not equal to system-wide PATH directories.

Download binaries from: releases (OS X/Linux/Windows/RaspberryPi)

Docker users:

docker pull msoap/shell2http

Build from source (minimum Go version is 1.12):

go get -u github.com/msoap/shell2http
# set link to your PATH if needed:
ln -s $(go env GOPATH)/bin/shell2http ~/bin/shell2http

Examples

shell2http /top "top -l 1 | head -10"
shell2http /date date /ps "ps aux"
shell2http -export-all-vars /env 'printenv | sort' /env/path 'echo $PATH' /env/gopath 'echo $GOPATH'
shell2http -export-all-vars /shell_vars_json 'perl -MJSON -E "say to_json(\%ENV)"'
shell2http -export-vars=GOPATH /get 'echo $GOPATH'
HTML calendar for current year
shell2http /cal_html 'echo "<html><body><h1>Calendar</h1>Date: <b>$(date)</b><br><pre>$(cal $(date +%Y))</pre></body></html>"'
Get URL parameters (http://localhost:8080/form?from=10&to=100)
shell2http -form /form 'echo $v_from, $v_to'
CGI scripts
shell2http -cgi /user_agent 'echo $HTTP_USER_AGENT'
shell2http -cgi /set 'touch file; echo "Location: /another_path\n"' # redirect
shell2http -cgi /404 'echo "Status: 404"; echo; echo "404 page"' # custom HTTP code
Upload file
shell2http -form \
    GET:/form 'echo "<html><body><form method=POST action=/file enctype=multipart/form-data><input type=file name=uplfile><input type=submit></form>"' \
    POST:/file 'cat $filepath_uplfile > uploaded_file.dat; echo Ok'

Testing upload file with curl:

curl -i -F [email protected]/file/path 'http://localhost:8080/file'
Simple http-proxy server (for logging all URLs) Setup proxy as "http://localhost:8080/"
shell2http -log=/dev/null -cgi / 'echo $REQUEST_URI 1>&2; [ "$REQUEST_METHOD" == "POST" ] && post_param="[email protected]"; curl -sL $post_param "$REQUEST_URI" -A "$HTTP_USER_AGENT"'
Test slow connection (http://localhost:8080/slow?duration=10)
shell2http -form /slow 'sleep ${v_duration:-1}; echo "sleep ${v_duration:-1} seconds"'
Proxy with cache in files (for debug with production API with rate limit) get `http://api.url/` as `http://localhost:8080/get?url=http://api.url/`
shell2http -form \
    /form 'echo "<html><form action=/get>URL: <input name=url><input type=submit>"' \
    /get 'MD5=$(printf "%s" $v_url | md5); cat cache_$MD5 || (curl -sL $v_url | tee cache_$MD5)'
Remote sound volume control (Mac OS)
shell2http /get  'osascript -e "output volume of (get volume settings)"' \
           /up   'osascript -e "set volume output volume (($(osascript -e "output volume of (get volume settings)")+10))"' \
           /down 'osascript -e "set volume output volume (($(osascript -e "output volume of (get volume settings)")-10))"'
Remote control for Vox.app player (Mac OS)
shell2http /play_pause 'osascript -e "tell application \"Vox\" to playpause" && echo ok' \
           /get_info 'osascript -e "tell application \"Vox\"" -e "\"Artist: \" & artist & \"\n\" & \"Album: \" & album & \"\n\" & \"Track: \" & track" -e "end tell"'
Get four random OS X wallpapers
shell2http /img 'cat "$(ls "/Library/Desktop Pictures/"*.jpg | ruby -e "puts STDIN.readlines.shuffle[0]")"' \
           /wallpapers 'echo "<html><h3>OS X Wallpapers</h3>"; seq 4 | xargs -I@ echo "<img src=/img?@ width=500>"'
Mock service with JSON API
curl "http://some-service/v1/call1" > 1.json
shell2http -cgi /call1 'cat 1.json' /call2 'echo "Content-Type: application/json\n"; echo "{\"error\": \"ok\"}"'
Windows example

Returns value of var for run in Windows cmd (http://localhost:8080/test?var=value123)

shell2http.exe -form /test "echo %v_var%"
With HTTP headers

Send custom HTTP headers:

shell2http -cgi / 'echo "Content-Type: application/javascript\n"; echo "{\"error\": \"ok\"}"'

On Windows:

shell2http.exe -cgi / "echo Content-Type: application/javascript& echo.& echo body"

More examples ...

Run from Docker-container

Example of test.Dockerfile for server for get current date:

FROM msoap/shell2http
# may be install some alpine packages:
# RUN apk add --no-cache ...
CMD ["/date", "date"]

Build and run container:

docker build -f test.Dockerfile -t date-server .
docker run --rm -p 8080:8080 date-server

Mirror docker repository: quay.io/msoap/shell2http:latest

SSL

Run https server:

shell2http -cert=./cert.pem -key=./key.pem ...

Generate self-signed certificate:

go run $(go env GOROOT)/src/crypto/tls/generate_cert.go -host localhost

See also

  • Emergency web server - spark
  • Share your terminal as a web application - gotty
  • Create Telegram bot from command-line - shell2telegram
  • A http daemon for local development - devd
  • Turn any program that uses STDIN/STDOUT into a WebSocket server - websocketd
  • The same tool configurable via JSON - webhook
Comments
  • exec error: exit status 1

    exec error: exit status 1

    C:\Selva\software\shell2http>shell2http -form /starttest "C:\Selva\software\shell2http\script.bat" 2020/03/02 14:17:56 register: /starttest (C:\Selva\software\shell2http\script.bat) 2020/03/02 14:17:56 register: / (index page) 2020/03/02 14:17:56 listen http://:8080/ 2020/03/02 14:18:05 localhost:8080 [::1]:55677 GET /starttest "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" 2020/03/02 14:18:05 exec error: exit status 1

    Getting above error when we tired an api for executing a bat file http://localhost:8080/starttest

    question windows 
    opened by selvakumar7991 18
  • Inconsistent permissions on shell command

    Inconsistent permissions on shell command

    When running the program like so

    shell2http -port=80 / "tail /root/server/logs/logfile.log"
    

    it gives the following output when a request is received

    tail: cannot open '/root/server/logs/logfile.log' for reading: Permission denied
    2020/04/01 13:09:57 exec error:  exit status 1
    

    but the command

    tail /root/server/logs/logfile.log
    

    can be executed normally outside shell2http.

    OS Ubuntu 18.04 The program is being executed by the root user. The file and directories and are owned by user and group root. The permissions are as follows: root: 700 server: 775 logs: 644 logfile.log: 644

    I've managed to make shell2http execute the command by setting permissions 744 on the "logs" folder but I'm confused for the reason that it's working. From what I understood while searching for the answer, directories must have the "x" permission to allow acessing it's files (StackExchange/AskUbuntu), so theoretically my shell is wrong for letting me access the contents of the logs folder, unless there is something special about the root user.

    Shouldn't the 2 situations execute the command in the same way?

    It may be that this question is more Ubuntu/Linux than about shell2http, so please let me know if here is the appropriate place for it.

    question snap 
    opened by flaviotsales 9
  • Unable to query mysql

    Unable to query mysql

    Hi, I am trying to create mysql heartbeat on http using this tool. So I want to execute something as below:

    shell2http /showStatus '/var/lib/snapd/snap/bin/mysql.client --user=root --password=root -h 127.0.0.1 -e "select 1+1"'

    I installed sudo snap install --beta mysql as well but couldn't figure out. Can you please help. Note: actual database in on same instance.

    question 
    opened by shashank-google 8
  • -form doesn't seem to work

    -form doesn't seem to work

    Hi, I really like you implementation. this simple yet powerful shell can really help me. I'm having trouble with the "-form" option.

    no matter what i try the $v_xx doesn't work.

    shell2http -form /test "echo $v_xx" running this with the URL "http://localhost:8080/test?xx=123" the output I get is "$v_xx"

    any ideas ?

    question windows 
    opened by silverBull3t 7
  • Cannot Set Response Header in Windows

    Cannot Set Response Header in Windows

    in my Arch Linux environment, i have run.sh with content below:

    #!/usr/bin/env bash
    export HTML_INDEX="site/index.html"
    export MAIN_JS="site/main.js"
    
    shell2http -export-all-vars -cgi -form / "cat $HTML_INDEX" \
    /echo 'echo "$v_msg"' \
    /call2 'echo "Content-Type: application/json";echo ;echo "{\"error\": \"ok\"}"' \
    /main.js 'echo "Content-Type: application/javascript";echo ;cat $MAIN_JS' 
    

    in the script above i can set correct Content-Type response header of the /main.js path. it works correctly in browser.

    now, i want to replicate script above in Windows environment (Windows 8.1) with run.bat below:

    @echo OFF
    
    set HTML_INDEX=site\index.html
    set MAIN_JS=site\main.js
    set TYPE=Content-Type: application/javascript
    
    shell2http.exe -cgi / "type %HTML_INDEX%" ^
    /main.js "echo %TYPE% & type %MAIN_JS%"
    

    the problem is, the Content-Type not set in Response Header, but included in Response Body output of /main.js

    Content-Type: application/javascript
    alert('Hello World') <-- content inside `site\main.js`
    

    i've tried adding \n\n and echo. to add newline

    /main.js "echo %TYPE%\n\n & type %MAIN_JS%"
    /main.js "echo %TYPE% & echo. & type %MAIN_JS%"
    

    the Content-Type always included inside the Response Body.

    but of course, if i only using this command below:

    /main.js "type %MAIN_JS%"
    

    the main.js script executed by the browser successfully, but with Content-Type: text/plain.

    How to make the Response Header setting works in windows?

    windows 
    opened by pamubay 6
  • Windows: Passed parameters executes differently than hardcoded parameters

    Windows: Passed parameters executes differently than hardcoded parameters

    Awesome program, but I am having a problem in Windows. I am trying to have shell2http run a console executable that requires parameters and uses libraries (dll) in the same directory as the executable. If I use the below to start shell2http: shell2http -form /Test "C:\Test\Test.exe Arg1 Arg2 Arg3" and http://localhost:8080/Test It works fine.

    But

    If I use the below to start shell2http: shell2http -form /Test "C:\Test\Text.exe %v_arg1% %v_arg2% %v_arg3%" and http://localhost:8080/Test/Text.exe?arg1=Arg1&arg2=Arg2&arg3=Arg3

    then I get an error that the library dlls cannot be found (even though C:\Test is in the PATH environment variable.

    Am I doing something wrong?

    Thank you for your help!

    bug windows 
    opened by NickE37 6
  • Crashes on launch on Apple Silicon

    Crashes on launch on Apple Silicon

    When I got my shiny new MacMini with the M1 chip, migration assistant transferred my entire homebrew installation from my Intel mac. Somewhat surprisingly, it almost all "just worked" under Rosetta. The only exception I have found so far is shell2http.

    Workaround: Build a native M1 version of go according to the instructions here. Then in this directory, do:

    make build
    codesign -s - ./shell2http
    

    Voila!

    macos 
    opened by chetstone 5
  • config

    config "command:" in docker-compose possibel?

    HI

    i have the following docker-compose file , but don't get multiple commds to run ...

    version: '3.7'
    
    networks:
     proxy-net:
       external: true
       
    services:
      shell2http_swarm_master:
        image: bpmspace/docker_bpmspace_base:shell2http
        **command: /bin/sh "/app/shell2http -form /date date /ps "ps aux" /form 'echo $v_from, $v_to'"**
        hostname: shell2http_swarm_master
        deploy:
          labels:
            - traefik.enable=true
            - traefik.http.routers.shell2http_swarm_master.rule=Host(`shell2http_swarm_master.bpmspace.net`)
            - traefik.http.services.shell2http_swarm_master-service.loadbalancer.server.port=8080
          mode: replicated
          replicas: 1
          placement:
            constraints:
              - node.role == manager
        networks:
          - proxy-net   
    
      shell2http_swarm_node:
        image: bpmspace/docker_bpmspace_base:shell2http
        hostname: shell2http_swarm_node
        deploy:
          labels:
            - traefik.enable=true
            - traefik.http.routers.shell2http_swarm_node.rule=Host(`shell2http_swarm_node.bpmspace.net`)
            - traefik.http.services.shell2http_swarm_node-service.loadbalancer.server.port=8080
          mode: replicated
          replicas: 2
          placement:
            constraints:
              - node.role == worker
        networks:
          - proxy-net   
    

    The error messages is " task: non-zero exit (1)"

    When I start the service again without the "command" line it works! BUT i only have 1 command "/date" since my Dockerfile is your test.Dockerfile

    Do you have any hint how to "add" new commands via compose file? My image is created via GITHUB -> webhooks -> dockerhub ... so it is no option to add all the commands i need in in the Dockerfile and in a DockerSwarm the "build:" in docker-compose is not supported ....

    thanks rob

    PS when i try to execute the command in the sh of the container it tells me:

    / # ./app/shell2http -form /date date /ps "ps aux" /form 'echo $v_from, $v_to' 2020/01/05 15:30:40 register: /date (date) 2020/01/05 15:30:40 register: /ps (ps aux) 2020/01/05 15:30:40 register: /form (echo $v_from, $v_to) 2020/01/05 15:30:40 register: / (index page) 2020/01/05 15:30:40 listen tcp :8080: bind: address already in use

    question docker 
    opened by BPMspace 5
  • I receive the error

    I receive the error "command not found", but actually exists

    When I run this command I get this error message:

    shell2http -export-all-vars -shell="bash" -form /unblock-ip "csf -g $v_ip"
    
    [[email protected] ~]# shell2http -export-all-vars -shell="bash" -form /unblock-ip "csf -g $v_ip"
    2021/03/17 14:26:29 register: /unblock-ip (csf -g )
    2021/03/17 14:26:29 register: / (index page)
    2021/03/17 14:26:29 listen http://localhost:8080/
    2021/03/17 14:26:31 /unblock-ip - 404
    bash: csf: command not found
    

    I can affirm that this command exists.

    question snap 
    opened by felinto-dev 4
  • quotes are messed up

    quotes are messed up

    Hi,

    I have a script that fails and that's ok, I'm getting following:

    /bin/mkdir: cannot create directory ‘/a/b/c’: No such file or directory
    /bin/ln: failed to create symbolic link ‘/c/b’ -> ‘’: No such file or directory
    /bin/ln: failed to create symbolic link ‘/c/b’ -> ‘’: No such file or directory
    

    The issue in here are quotes... instead of ASCII shell2http returns unicode's quote (U+2019) what is wrong

    Is there any quick fix for this?

    opened by stanislavrudenko-okta 4
  • How to start shell2http?

    How to start shell2http?

    Currently my bash script is #!/bin/bash PWD=/root SHELL=/bin/bash PATH=some path variables cd $PWD shell2http -port=80 -export-all-vars and my commands

    Well. I actually dont understand how shell2http work with enviroment vars. What does -export-all-vars do?

    question 
    opened by ghost 4
  • support async call on windows

    support async call on windows

    While a long time running task be dispatched with a flag such as #async on windows, shell2http return immediately.

    set chrome="C:\Progra~2\Google\Chrome\Application\chrome.exe"
    D:\bin\shell2http\shell2http -host=127.0.0.1 -port=8081 -no-index -log=access.log -form ^
      /html2pdf#async  "echo OK && %chrome% --headless --disable-gpu --print-to-pdf-no-header --print-to-pdf=%%v_file%% %%v_url%%"
    
    windows feature request 
    opened by Hi-Alan 2
  • Create new shell2http binaries to solve CVE-2016-2183

    Create new shell2http binaries to solve CVE-2016-2183

    Current version of shell2http binaries are build with old go version which cause our security tooling to report CVE-2016-2183.

    This seems to be solved with a new go version: link

    Could you please create a new version of shell2http binaries by triggering github-action to publish the compiled code (like was done with last version link )

    Thanks for your help

    opened by jlvrhee 3
  • Any way to detach executed process?

    Any way to detach executed process?

    It seems that shell2http waits for any child process that is spawned to finish. For example if your un script.py that will spawn another child process script2.py and exits, it will still wait for script2.py to finish. Even thou _script.py has exited. I have tried using & and & disown when starting the script it still seems to be attached to the process and every child process.

    question 
    opened by vegetablesalad 1
  • Support socket activation with launchd and systemd

    Support socket activation with launchd and systemd

    This would allow shell2http to be used with inetd-like scenarios, eg. Systemd Socket activation, or Launchd socket activation.

    This is especially useful if you want your application to bind to a privileged port (eg. 80), but don't want the application to run as root, but also don't want to set up a separate proxy process to proxy 80 -> 8080.

    So in that case you would have a managing process (like launchd, systemd) open the socket on the privileged port and have it passed to the process instead.

    Launchd: https://en.wikipedia.org/wiki/Launchd#Socket_activation_protocol https://github.com/sstephenson/launch_socket_server/blob/master/src/launch_socket_server.go

    Systemd: http://0pointer.de/blog/projects/socket-activation.html https://www.darkcoding.net/software/systemd-socket-activation-in-go/ https://github.com/coreos/go-systemd/tree/master/examples/activation/httpserver

    I am open to doing a PR if you would find the idea compatible with shell2http.

    opened by reegnz 4
  • Live output / flush

    Live output / flush

    For longer running commands, such as wget or pv with progress indication, is it possible to flush output and make it visible to the webbrowser while running?

    enhancement 
    opened by amenk 7
Releases(v1.14.2)
Owner
Sergey Mudrik
𐄁𐄁𐄁𐄁 𐄁 𐄁𑁋𐄁𐄁 𐄁𑁋𐄁𐄁 𑁋𑁋𑁋
Sergey Mudrik
Gsshrun - Running commands via ssh on the server/hosting (if ssh support) specified in the connection file

Gsshrun - Running commands via ssh on the server/hosting (if ssh support) specified in the connection file

Məhəmməd 2 Sep 8, 2022
OliveTin is a web interface for running Linux shell commands.

OliveTin OliveTin is a web interface for running Linux shell commands. Some example use cases; Give controlled access to run shell commands to less te

OliveTin 890 Dec 29, 2022
Helps you to send ssh commands to target machine in your local network from outside via gRPC

rpc-ssh In case, you don't want to make your ssh port accessible from outside local network. This repository helps you to send ssh commands to target

Berkay Akyazı 2 Nov 16, 2022
Lightweight rest api that allows users to run Powershell commands over HTTP.

Powershell Proxy Lightweight rest api that allows users to run Powershell commands over HTTP. Requests require a valid JWT and responses are returned

Thomas Sampson 4 Mar 18, 2022
A golang library about socks5, supports all socks5 commands. That Provides server and client and easy to use. Compatible with socks4 and socks4a.

socks5 This is a Golang implementation of the Socks5 protocol library. To see in this SOCKS Protocol Version 5. This library is also compatible with S

chenhao zhang 40 Nov 22, 2022
Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.

Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH. Single executable including both client and server. Written in Go (golang). Chisel is mainly useful for passing through firewalls, though it can also be used to provide a secure endpoint into your network.

Jaime Pillora 8.4k Jan 1, 2023
grpc-http1: A gRPC via HTTP/1 Enabling Library for Go

grpc-http1: A gRPC via HTTP/1 Enabling Library for Go This library enables using all the functionality of a gRPC server even if it is exposed behind a

StackRox 89 Dec 17, 2022
viagh.NewHTTPClient returns a *http.Client that makes API requests via the gh command.

viagh viagh.NewHTTPClient returns a *http.Client that makes API requests via the gh command. Why viagh? When writing a GitHub CLI extension, the exten

Ken’ichiro Oyama 1 Dec 24, 2021
View, edit, and save text files via http to the file system.

go-wiki View, edit, and save text files via http to the file system. (DONE) https://golang.org/doc/articles/wiki/ Instructions go run main.go In a web

Clint Vidler 0 Nov 25, 2021
Go-http-sleep: Delayed response http server, useful for testing various timeout issue for application running behind proxy

delayed response http server, useful for testing various timeout issue for application running behind proxy

guessi 0 Jan 22, 2022
Echo-server - An HTTP echo server designed for testing applications and proxies

echo-server An HTTP echo server designed for testing applications and proxies. R

Erik Cavalcanti 6 Dec 20, 2022
“Dear Port80” is a zero-config TCP proxy server that hides SSH connection behind a HTTP server!

Dear Port80 About The Project: “Dear Port80” is a zero-config TCP proxy server that hides SSH connection behind a HTTP server! +---------------------

Abbas Gheydi 6 Jun 29, 2022
Automatically spawn a reverse shell fully interactive for Linux or Windows victim

Girsh (Golang Interactive Reverse SHell) Who didn't get bored of manually typing the few lines to upgrade a reverse shell to a full interactive revers

null 286 Dec 14, 2022
A pure Unix shell script implementing ACME client protocol

An ACME Shell script: acme.sh An ACME protocol client written purely in Shell (Unix shell) language. Full ACME protocol implementation. Support ACME v

acme.sh 29.8k Jan 2, 2023
Golang Reverse Shell

goReverseShell First ever GO project aimed to learn GO basics. PoC of a GO reverse shell, not expected to be used in real conditions. Undetected by AV

null 4 Jul 21, 2022
Simple reverse shell to avoid Windows defender and kaspersky detection

Windows-ReverseShell Simple reverse shell to avoid Windows defender, kaspersky d

赵公子 14 Oct 19, 2022
A simple Chat software from within the Shell

directChat A simple Chat software from within the Shell Usage Build The client a

Lorenzo 1 Dec 24, 2021
Reverse Shell in Golang and PowerShell Fud (27/04/2022)

ShellPwnsh Spanish: Generador de Backdoor en Golang, usando Reverse Shell en PowerShell, con formato de variables en el codigo para Bypass de AMSI y c

Black$hell256 10 Nov 9, 2022
Go Library to Execute Commands Over SSH at Scale

vSSH Go library to handle tens of thousands SSH connections and execute the command(s) with higher-level API for building network device / server auto

Yahoo 882 Dec 9, 2022