Skip to content

Instantly share code, notes, and snippets.

@ilmoeuro
Last active August 29, 2015 14:00
Show Gist options
  • Select an option

  • Save ilmoeuro/11177476 to your computer and use it in GitHub Desktop.

Select an option

Save ilmoeuro/11177476 to your computer and use it in GitHub Desktop.
CGI-PHP aware, simple, slow Web server. Requires ncat (in nmap package). HORRIBLY INSECURE, use only at your own risk, and NEVER expose outside!
#/bin/sh
VERSION=1.0
ROOT=`pwd`
PORT=8080
EXEC_NAME="$0"
WORKER=
IFS=`echo -en "\n\b"`
get_ip() {
ifconfig | grep inet | grep -v inet6 | awk '{print $2}' | tail -n1
}
setup() {
request_body=`mktemp`
}
cleanup() {
rm $request_body
}
setup_cgi() {
SERVER_SOFTWARE="httpd.sh/$VERSION" export SERVER_SOFTWARE
SERVER_NAME="`get_ip`" export SERVER_NAME
HTTP_HOST="`get_ip`" export HTTP_HOST
GATEWAY_INTERFACE="CGI/1.1" export GATEWAY_INTERFACE
SERVER_PROTOCOL="HTTP/1.1" export SERVER_PROTOCOL
SERVER_ADDR="`get_ip`" export SERVER_ADDR
SERVER_PORT="$PORT" export SERVER_PORT
REQUEST_METHOD="$method" export REQUEST_METHOD
REQUEST_URI="$fullpath" export REQUEST_URI
PATH_INFO="$pathinfo" export PATH_INFO
PATH_TRANSLATED="$fullpath" export PATH_TRANSLATED
SCRIPT_NAME="$path" export SCRIPT_NAME
QUERY_STRING="$querystring" export QUERY_STRING
REMOTE_HOST="" export REMOTE_HOST
REMOTE_ADDR="" export REMOTE_ADDR
AUTH_TYPE="" export AUTH_TYPE
REMOTE_USER="" export REMOTE_USER
REMOTE_IDENT="" export REMOTE_IDENT
CONTENT_TYPE="$content_type" export CONTENT_TYPE
CONTENT_LENGTH="$content_length" export CONTENT_LENGTH
SCRIPT_FILENAME="$filepath" export SCRIPT_FILENAME
REDIRECT_STATUS=1 export REDIRECT_STATUS
}
run_php() {
setup_cgi
tempfile=`mktemp`
php-cgi $filepath <$request_body >$tempfile
line="NOT_EMPTY"
while [ -n "$line" ]; do
if [ -z "$statusline" ]; then
statusline=`echo $line | sed -ne 's/Status: \(.*\)/\1/p'`
fi
read line
done <$tempfile
if [ -n "$statusline" ]; then
echo -ne "HTTP/1.1 $statusline\r\n"
else
echo -ne "HTTP/1.1 200 OK\r\n"
fi
cat $tempfile
rm "$tempfile"
}
err404() {
echo -ne "HTTP/1.1 404 Not Found\r\n\r\n\x04"
cleanup
exit 0
}
err405() {
echo -ne "HTTP/1.1 405 Method Not Allowed\r\n\r\n\x04"
cleanup
exit 0
}
init_headers() {
content_type=
content_length=
}
parse_header() {
if [ -n "`echo $1 | grep 'Content-Type:'`" ]; then
content_type=`echo "$1" \
| sed -ne 's/Content-Type: \(.*\)\r/\1/p'`
elif [ -n "`echo $1 | grep 'Content-Length:'`" ]; then
content_length=`echo "$1" \
| sed -ne 's/Content-Length: \(.*\)\r/\1/p'`
else
var_name=`echo "$1" | cut -d: -f1 | tr 'a-z' 'A-Z' | tr '-' '_' | tr -cd 'A-Z_'`
eval "HTTP_$var_name=\"`echo $1 | sed -ne 's/.*: \(.*\)\r/\1/p'`\" export HTTP_$var_name"
fi
}
parse_request_line() {
method="`echo $request_line | cut -d\ -f1`"
fullpath="`echo $request_line | cut -d\ -f2`"
querystring="`echo $fullpath | cut -d? -f2`"
pathinfo="`echo $fullpath | sed -e 's/^.*\.php//' | cut -d? -f1`"
if [ -n "`echo $fullpath | grep '\.php\/'`" ]; then
path="`echo $fullpath | sed -e 's/\.php.*$//'`.php"
else
path="`echo $fullpath | cut -d? -f1`"
fi
filepath=`realpath -ms $ROOT$path`
rootlen=`expr length "$ROOT"`
if [ "`echo $filepath | head -c$rootlen`" != "$ROOT" ]; then
# Tried to break jail
echo "$filepath doesn't start with $ROOT" >&2
exit 1
fi
}
serve() {
setup
read request_line
parse_request_line
echo "`date -R` $request_line" >&2
init_headers
line=""
while [ "$line" != `echo -ne '\r'` ]; do
read line
parse_header "$line"
done
if [ -n "$content_length" ]; then
dd count=$content_length bs=1 of=$request_body 2>1 >/dev/null
fi
if [ "$method" = "GET" -o "$method" = "POST" ]; then
if [ -d "$filepath" ]; then
if [ -e "$filepath/index.html" ]; then
filepath="$filepath/index.html"
elif [ -e "$filepath/index.php" ]; then
filepath="$filepath/index.php"
else
err404
fi
fi
if [ ! -e "$filepath" ]; then
err404
else
if [ -e "$filepath" -a -n "`echo $filepath | grep '\.php$'`" ]
then
run_php
elif [ $method != "POST" ]; then
if [ -n "`echo $filepath | grep '\.css$'`" ]; then
ft="text/css"
elif [ -n "`echo $filepath | grep '\.js$'`" ]; then
ft="application/javascript"
else
ft=`file -bi "$filepath"`
fi
echo -ne "HTTP/1.1 200 OK\r\n"
echo -ne "Content-Type: $ft\r\n"
echo -ne "Content-Length: `stat -c'%s' $filepath`\r\n"
echo -ne "Connection: close\r\n"
echo -ne "\r\n"
cat $filepath
else
err405
fi
fi
else
if [ -e "$filepath" -a -n "`echo $filepath | grep '\.php$'`" ]; then
run_php
else
err405
fi
fi
cleanup
}
while [ -n "$1" ]; do
if [ "$1" = "-w" ]; then
WORKER=true
shift
elif [ "$1" = "-d" ]; then
shift
ROOT=`realpath -m "$1"`
shift
elif [ "$1" = "-p" ]; then
shift
PORT=$1
shift
else
echo "Usage: $EXEC_NAME [-w] [-d dir] [-p port]"
exit 1
fi
done
if [ "$WORKER" = true ]; then
serve
else
ncat -c "$EXEC_NAME -w -p $PORT -d $ROOT" -klp $PORT
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment