纯 sh + telnet 中的 HTTP POST 文件:没有 curl,没有 wget

Posted

技术标签:

【中文标题】纯 sh + telnet 中的 HTTP POST 文件:没有 curl,没有 wget【英文标题】:HTTP POST file in pure sh + telnet : no curl, no wget 【发布时间】:2020-09-07 08:09:45 【问题描述】:

我正在使用旧的 android 设备(如果您想知道,wiko 可以升级 4G Android 5.1),唯一真正有效的是 telnet(busybox 中的 wget 只有 --post-data(没有 --post -file),curl 似乎无法安装(我花了几个小时尝试安装它))

我正在尝试通过 http POST 将 screen.png 发送到 http 服务器。

我使用下面的代码在纯 telnet 中为小文本或 json 文件工作(也花了几个小时)。

但是当我处理更大的文件时,比如 png 图像或 hexdump。这不起作用。

我怀疑这是由文件中存在的特殊字符引起的。我认为这可能会迫使 telnet 退出

这个问题很棘手,我被困住了,但我希望你们中的一个人愿意接受这个挑战,http post png image over telnet

这是我用于测试的示例服务器端代码: https://gist.github.com/taterbase/2688850

FILE_TO_UPLOAD="./file.txt"
BOUNDARY=$((  RANDOM % 99999 ))
HOST="server.com"
POST_PATH="/upload.php"
FIELD_NAME="uploaded_file"
TLNET_CONTENT="-----------------------------$BOUNDARY
Content-Disposition: form-data; name=\"$FIELD_NAME\"; filename=\"$(basename $FILE_TO_UPLOAD)\"

$(cat $FILE_TO_UPLOAD)
-----------------------------$BOUNDARY--"
TLNET_HEADERS="POST $POST_PATH HTTP/1.1
Host: $HOST
Content-Type: multipart/form-data; boundary=---------------------------$BOUNDARY
Content-Length: $(($(expr length "$TLNET_CONTENT") + 100 ))
Connection: keep-alive"

TELNET_ALL="$TLNET_HEADERS

$TLNET_CONTENT

"

telnet $HOST 80 <<AREALEOF
$TELNET_ALL
AREALEOF

谢谢你,托马斯。

【问题讨论】:

【参考方案1】:

HTTP 要求请求行、标头行和将标头与正文分开的空白行以 CR/LF 对结束,而不仅仅是换行。

FILE_TO_UPLOAD="./file.txt"
BOUNDARY=$((  RANDOM % 99999 ))
HOST="server.com"
POST_PATH="/upload.php"
FIELD_NAME="uploaded_file"

CONTENT=$(printf '%s\n' \
    "-----------------------------$BOUNDARY" \
    "Content-Disposition: form-data; name=\"$FIELD_NAME\"; filename=\"$(basename $FILE_TO_UPLOAD)\""

   cat "$FILE_TO_UPLOAD"

   printf '%s\n' "-----------------------------$BOUNDARY--"
)


  printf '%s\r\n' \
    "POST $POST_PATH HTTP/1.1" \
    "Host: $HOST" \
    "Content-Type: multipart/form-data; boundary=---------------------------$BOUNDARY" \
    "Content-Length: $(($(expr length "$CONTENT") + 100 ))" \
    "Connection: keep-alive" \
    "";

  printf '%s\n' "$CONTENT"
 | telnet $HOST 80 

【讨论】:

$(cat $FILE_TO_UPLOAD) 是不必要的吗? 对不起,它只是在摆脱变量的洗牌中迷路了。 与在标题中指定内容长度的能力一样;也已恢复。【参考方案2】:

我终于成功地传输了文件。我用过网猫。 如果有一天你在一个非常有限的系统上,很可能你至少有 netcat

在接收端你必须执行 nc -l -p 1234&gt; out.file

这将开始侦听端口 1234 并将所有内容存储在 out.file 注意你的防火墙规则

在发送方 nc -w 3 [hostname / ip] 1234 &lt;file_to_send.ext

将允许您发送文件。

有了它,我不再需要使用 TELNET。

但是,有人可能会发现其他答案很有用。 非常感谢

【讨论】:

【参考方案3】:

谢谢, 我不得不编辑您的建议以使其在 android 设备上运行,但是

FILE_TO_UPLOAD="./screen.png"
BOUNDARY=$((  RANDOM % 99999 ))
HOST="server.com"
POST_PATH="/upload.php"
FIELD_NAME="uploaded_file"

TLNET_CONTENT=$(printf '%s\n' \
    "-----------------------------$BOUNDARY" \
    "Content-Disposition: form-data; name=\"$FIELD_NAME\"; filename=\"$(basename $FILE_TO_UPLOAD)\"" \
    "";
   cat "$FILE_TO_UPLOAD"
   printf '%s\n' "-----------------------------$BOUNDARY--"
)



    printf '%s\n' \
    "POST $POST_PATH HTTP/1.1" \
    "Host: $HOST" \
    "Content-Type: multipart/form-data; boundary=---------------------------$BOUNDARY" \
    "Content-Length: $(($(expr length "$CONTENT") + 100 ))" \
    "Connection: keep-alive" \
    "";
    printf '%s\n' "$TLNET_CONTENT"
 | telnet $HOST 80

它仍然适用于 file.txt

但是我仍然有许多来自 telnet 的这些消息,因为 png 文件不起作用

    Console escape. Commands are:

     l      go to line mode
     c      go to character mode
     z      suspend telnet
     e      exit telnet
    continuing...

    Console escape. Commands are:

     l      go to line mode
     c      go to character mode
     z      suspend telnet
     e      exit telnet
    continuing...

    Console escape. Commands are:

     l      go to line mode
     c      go to character mode
     z      suspend telnet
     e      exit telnet

【讨论】:

以上是关于纯 sh + telnet 中的 HTTP POST 文件:没有 curl,没有 wget的主要内容,如果未能解决你的问题,请参考以下文章

C# - 向 Telnet 服务器发送命令(纯文本)

sh viaproxy“socks5 127.0.0.1 1080”telnet some-host

alpine安装telnet等工具

网络故障札记

FTP、ssh、http、telnet、https

sh git log纯文本