V2EX = way to explore
V2EX 是一个关于分享和探索的地方
APIKey 你的 API 密钥
。kill -9 $(cat server.pid)
。#!/bin/bash
function server {
read il
echo "recv_il: $il" >&2
method=$( echo "$il" | cut -d" " -f1)
path=$( echo "$il" | cut -d" " -f2)
proto=$( echo "$il" | cut -d" " -f3)
echo "method: $method" >&2
echo "path: $path" >&2
echo "proto: $proto" >&2
declare -A hdr
while read line; do
sline=`echo $line | tr -d '[\r\n]'`
[ -z "$sline" ] && break
echo "recv_hdr: $line" >&2
hdr_k=$(echo $line | cut -d":" -f1)
hdr_v=$(echo $line | cut -d":" -f2- | cut -c2- | tr -d '[\r\n]')
hdr[$hdr_k]="$hdr_v"
done
echo "recv_hdr_end" >&2
relpath=$(realpath "$(pwd)$path")
if [[ "$relpath" != "$(pwd)"* ]]; then
echo "possible path traversal attack: $relpath" >&2
echo "pwd: $(pwd)" >&2
echo "relpath: $relpath" >&2
echo -ne "HTTP/1.1 403 Forbidden\r\n"
echo -ne "\r\n"
echo -ne "possible path traversal attack: $relpath"
exit 0
fi
echo "relpath: $relpath" >&2
if [ $method = "GET" ]; then
if [ ! -f "$relpath" ]; then
echo -ne "HTTP/1.1 404 Not Found\r\n"
echo -ne "\r\n"
echo -ne "not found: $relpath"
exit 0
fi
echo -ne "HTTP/1.1 200\r\n"
echo -ne "\r\n"
cat "$relpath"
exit 0
fi
if [ $method != "POST" ]; then
echo -ne "HTTP/1.1 405 Method Not Allowed\r\n"
echo -ne "\r\n"
exit 0
fi
if [ "${hdr[Authorization]}" != "APIKey $KEY" ]; then
echo -ne "HTTP/1.1 401 Unauthorized\r\n"
echo -ne "\r\n"
exit 0
fi
body_file=$(mktemp)
body_len=0
if [ ! -z "${hdr[Content-Length]}" ]; then
echo "hdr_cl > body_len" >&2
body_len="${hdr[Content-Length]}"
fi
echo "body_len: $body_len" >&2
echo "body_file: $body_file" >&2
dd of=$body_file bs=1 count=$body_len
mkdir -p $(dirname "$relpath") >&2
cp -v $body_file "$relpath" >&2
echo -ne "HTTP/1.1 201 Created\r\n"
echo -ne "\r\n"
echo -ne "created: $relpath\r\n"
rm -rvf $body_file >&2
}
if [ -z "$PORT" ]; then
PORT=3000
fi
if [ -z "$KEY" ]; then
KEY=$(uuidgen)
fi
if [ "$EXEC" = "server" ]; then
server
exit 0
fi
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
PID=$$
PIDFILE="$SCRIPT_DIR/server.pid"
if [[ -f "$PIDFILE" && -d "/proc/$(cat $PIDFILE)" ]]; then
echo "one instance is running, refuse to start another"
exit 1
fi
if [ -f "server.sh" ]; then
echo "DO NOT START SERVER WHEN CURRENT WORKING DIRECTORY IS SAME AS SCRIPT DIRECTORY"
echo "THIS MAY CAUSE UNEXPECTED OVERWRITING SERVER AND RCE"
echo "EXITING"
exit 1
fi
echo "PID=$PID"
echo $PID > $PIDFILE
echo "PIDFILE=$PIDFILE"
echo "KEY=$KEY"
while true; do
nc -vlp $PORT -c "EXEC=server KEY=$KEY $0"
done
1 trepwq 2 小时 29 分钟前 via iPhone 1nc 换成 socat ,可以端口复用 |
3 sagaxu 2 小时 3 分钟前python -m http.server $PORT |
5 sagaxu 1 小时 16 分钟前@baobao1270 大部分 Linux 发行版依赖 Python ,不用另外安装。以前写 web 服务的时候,直接用 linux 自带的 inetd 监听端口,收到请求时调用 CGI 调用处理程序,CGI 可以是任何语言写的,只要这个语言能读 stdio 和环境变量以及写入 stdout 。像 Ubuntu 标准版自带的 busybox 也自带了一个 httpd ,可以提供 CGI 转发。 |
8 w568w 7 分钟前cool ,这才是真正的 shell 另有一些语法风格上的建议: 1. function 关键字是兼容一些远古 shell 给出的。既然指定了 bash ,用 server() {} 就好了; 2. 函数内的变量最好用 local 声明,否则作用域会泄漏到函数外; 3. 可以用 shellcheck 过一遍,可能有其他忽略的点 |