I came across a piece of interesting vulnerable script from a thread on V2EX. A bash function in it named __curl as a simple alternative for command curl or wget, works in scenarios where no such utilities available.

function __curl() {
read proto server path <<<$(echo ${1//// })
DOC=/${path// //}
[[ x"${HOST}" == x"${PORT}" ]] && PORT=80

exec 3<>/dev/tcp/${HOST}/$PORT
echo -en "GET ${DOC} HTTP/1.0\r\nHost: ${HOST}\r\n\r\n" >&3
(while read line; do
[[ "$line" == $'\r' ]] && break
done && cat) <&3
exec 3>&-

The function involves certain less known features of Linux and Bash language.

First is communicating over TCP through files. Linux employs a design of “everything are files”. Certain devices are exposed as files which could be accessed under directory /dev. For example, one could manipulate a TCP socket connected to ${HOST}:${PORT} through device file /dev/tcp/${HOST}/${PORT}. The line exec 3<>$FILENAME opens file $FILENAME under read-write mode and binds it to descriptor 3. The next line composes HTTP message manually and writes out to &3, which is in fact sending a request to the URL. Reading from the same file should then retrieve the response content. The trick serves as a primitive workaround for retrieving web contents.

Another one is parameter substitution in Bash. The syntax ${var//PATTERN/REPL} globally replaces all occurrences of PATTERN in var into REPL. If REPL omitted, the matched substrings are deleted. For example, in this script, ${1//// } would replace all slashes / into white spaces in variable $1.


  1. Parameter Substitution