Skip to main content

Command Palette

Search for a command to run...

Using bash redirections to fetch from termbin.com

Updated
3 min readView as Markdown

Here I use bash redirections to fetch a text from termbin.com. It hosts a service to upload a text just like a pastebin using the nc command.

To start we are going to upload a text to termbin.com:

$ echo "A nice cup of hot tea" | nc termbin.com 9999
https://termbin.com/m3yj

You may notice that a link has returned. Following the link we can retrieve the text.

$ curl https://termbin.com/m3yj
A nice cup of hot tea

Nice isn't it?

The task is to use bash redirections to do the same thing. But special files /dev/protocol/hostname/port don't support TLS. So we use socat to redirect localhost:port to termbin.com:443 over SSL.

socat TCP-LISTEN:8080,fork,reuseaddr ssl:termbin.com:443,verify=0 &

We will use this to redirect stream from localhost:8080 to termbin.com:443 over SSL.

Now before we set up redirections we need a way to wait for socat to properly set itself up. I've found a novel way to do this: wait til the process status of socat to become 'S'.

# loop until socat's pid status becomes 'S'
while [[ -z $(ps -p $socat_pid -o stat --no-headers | grep 'S') ]]; do
    :
done

Now that socat is ready we can set up redirections.

exec 3<>/dev/tcp/localhost/8080

This opens /dev/tcp/localhost/8080 for read/write and assigns file descriptor 3.

We need to prepare our payload of GET request:

n1=$'\r\n'
request=$(cat <<END
GET /${url}/ HTTP/1.1
Host: termbin.com
Connection: close
$n1 
$n1
END
)

Then we send this GET request string to /dev/tcp/localhost/8080 flie via file descriptor 3 (that we have set up above).

echo "$request" >&3

Now all we need to do is to retrieve the response.

cat <&3 | awk 'NR>10{print}'

The awk part is to get rid of the HTTP response header (first 10 lines).

When the cat finish receiving the response, we need to do two things to clean up: kill socat process that is running, and close file descriptor 3 (since we've finished using it).

# if socat's pid status is 'S' then kill it
if [[ -n $(ps -p $socat_pid -o stat --no-headers | grep 'S') ]]; then
    kill -9 $socat_pid
fi

exec 3>&-

This works because when the fetch is done, the status of socat process becomes 'S' again.

Here is the complete code.

# fetch.sh
# fetch uploaded text from termbin.com
# Written by Logan Won-Ki Lee
# 30 July 2022
#
# Usage:
# fetch.sh [path]
#
# Eg.
# fetch.sh 9hc2k
# This fetches https://termbin.com/9hc2k

url=$1

# check if url is provided as argument
if [[ $# -lt 1 ]]; then
    echo "error: provide path" >&2
    echo >&2
    echo "Usage: fetch.sh [path]" >&2
    exit 1
fi

n1=$'\r\n'
request=$(cat <<END
GET /${url}/ HTTP/1.1
Host: termbin.com
Connection: close
$n1 
$n1
END
)
#echo "$request"

socat TCP-LISTEN:8080,fork,reuseaddr ssl:termbin.com:443,verify=0 &
socat_pid=$!

# loop until socat's pid status becomes 'S'
while [[ -z $(ps -p $socat_pid -o stat --no-headers | grep 'S') ]]; do
    :
done

exec 3<>/dev/tcp/localhost/8080
echo "$request" >&3
cat <&3 | awk 'NR>10{print}'

# if socat's pid status is 'S' then kill it
if [[ -n $(ps -p $socat_pid -o stat --no-headers | grep 'S') ]]; then
    kill -9 $socat_pid
fi

exec 3>&-

Let's use it to retrieve the text we uploaded at the beginning.

$ ./fetch.sh m3yj
A nice cup of hot tea

It worked!

If you have any questions, please leave a comment! (it appears termbin.com allows connection on port 80 lol -_-)

More from this blog

Linux and Web

31 posts