Understanding the TFTP Protocol
Trivial File Transfer Protocol, and you
There is nothing trivial about TFTP let me assure you. It is actually a pretty neat protocol with some distinctive features. This protocol also happens to be a favorite of malicious hackers for the purpose of sending over, or retrieving files. TFTP is also quite quick, but more on the speed of TFTP a little later on. Much like other application layer protocols this one is ferried about by IP, and in turn uses UDP for its transport protocol.
Now TFTP itself has five different message types that it can use. They are as follows;
- RRQ, which breaks out as Read Request
- WRQ, which breaks out as Write Request
- ACK, which breaks out as Acknowledgement
- ERROR, which breaks out as Error message
- DATA, which breaks out as, to read or write the next chunk of data
Now if you happen to capture any TFTP packets on the wire you will see these message types in the packet itself as noted in the packet further down below. (I have underlined it) TFTP also has a series of error codes, which can be found here. If you recall from our discussion of HTTP and SMTP these protocols also had status and error codes. These codes are required to build a coherent exchange of data, which will at times experience error conditions. Courtesy of these codes, whether they be status or error, are various conditions communicated between the client and server in question.
Typical usage of the TFTP protocol is for the storage and retrieval of Cisco IOS and Catalyst switch configuration files. I also alluded to earlier, that this protocol is heavily favored by hackers as a means of retrieving and storing files on compromised computers. You are not restricted to simply transferring ascii content either, you can also transfer binary files as well. Due to this use of TFTP by malicious hackers you should always be suspicious of any TFTP traffic on your network.
On with the show!
I have said it before, and I will say it again. There is nothing like “hands on practical” to cement lessons learned. With that in hand let’s take a look at some TFTP traffic. You will see below a small snippet, and I shall comment directly beneath the packet in question.
10:43:20.926155 IP (tos 0x0, ttl 128, id 69, offset 0, flags [none], length:
44) 192.168.1.102.1029 > 192.168.1.101.69: [udp sum ok] 16 RRQ "example"
0x0000: 4500 002c 0045 0000 8011 b660 c0a8 0166 E..,.E.....`...f
0x0010: c0a8 0165 0405 0045 0018 833b 0001 6578 ...e...E...;..ex
0x0020: 616d 706c 6500 6f63 7465 7400 0000 ample.octet...
This traffic was collected using a different version of windump, and has thereby resulted in a slightly different look than what you may be used to. In the packet directly above us we have a read request for the file “example”. The read request is seen in the RRQ, which is underlined above. Following that, in brackets, is the file that is being requested from the TFTP server located at 192.168.1.101, on its port 69. Port 69 is the port associated with TFTP, and is also in the reserved port range of 0 to 1024. We can also see that “octet” follows the file name example.
Octet signifies that the data will be transferred in eight bit bytes, unlike the other transfer mode of “netascii”. If it were netascii, then TFTP would interpret the file example as being lines of ascii text, and has slightly more overhead to it which I won’t cover here. Lastly I will point out that the 16 seen before the RRQ relates to the amount of TFTP data that is sent in this packet. If we do the math it works out. We have an overall packet length of 44 as seen in the header. The IP header accounts for 20 bytes, while the UDP header accounts for 8 bytes. The remaining 16 bytes of TFTP data fill out the packet size to the noted overall size of 44 bytes. Now because of the size difference between TCP and UDP it is clear why UDP is faster ie: it has 12 bytes less of header information to send. That makes for some quick file transfers.
10:43:20.977012 IP (tos 0x0, ttl 64, id 8683, offset 0, flags [DF], length:
130) 192.168.1.101.32768 > 192.168.1.102.1029: [bad udp cksum 424c!] UDP,
0x0000: 4500 0082 21eb 4000 4011 9464 c0a8 0165 [email protected]@..d...e
0x0010: c0a8 0166 8000 0405 006e 849b 0003 0001 ...f.....n......
0x0020: 5468 6520 6265 7374 2077 6179 2074 6f20 The.best.way.to.
0x0030: 6c65 6172 6e20 6162 6f75 7420 7468 696e learn.about.thin
0x0040: 6773 2069 7320 746f 200a 6163 7475 616c gs.is.to..actual
0x0050: 6c79 2064 6f20 6974 2079 6f75 7273 656c ly.do.it.yoursel
0x0060: 662e 204d 7563 6820 6c69 6b65 2077 6861 f..Much.like.wha
0x0070: 740a 4920 616d 2064 6f69 6e67 206e 6f77 t.I.am.doing.now
0x0080: 210a !.
Now what we see above is the TFTP server located at 192.168.1.101 sending the requested file “example”. We can see within the ascii portion of the packet, that the contents of the file example are simply me saying that the best way to learn is to actually do it yourself.
10:43:20.979434 IP (tos 0x0, ttl 128, id 70, offset 0, flags [none], length:
32) 192.168.1.102.1029 > 192.168.1.101.32768: [udp sum ok] UDP, length: 4
0x0000: 4500 0020 0046 0000 8011 b66b c0a8 0166 E....F.....k...f
0x0010: c0a8 0165 0405 8000 000c f7af 0004 0001 ...e............
0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............
Note that this packet above is actually an acknowledgement packet. Rather odd isn’t it as this is UDP and not TCP. Why are we seeing an acknowledgement packet then? Well this actually is part of the TFTP protocol itself, and the Opcodes that come with it. Where in the packet above is the Opcode you say? Good question! We know that our IP header ends at bytes 0165, as these are the last two octets of the destination IP address. Starting at bytes 0405 then is the UDP header, which in turn ends at bytes f7af.
We now know then that bytes 0004 are actually representing the Opcode for this packet. In this case the value is four, and that breaks out ACK, or Acknowledgement. After this Opcode value is the block number of 0001. This block number is also seen in the actual packet transferring the contents of the file “example”. Pretty neat eh? So in a way you are getting a connection oriented session even though it is UDP based. That though is courtesy of the TFTP Opcodes.
If you would like to play with the TFTP protocol then I encourage you to download a freeware one located here. The good folks at Solarwinds have been good enough to offer up this excellent win32 based TFTP server for free. Kudos to them! Once you have this installed on your win32 operating system, start to experiment with ferrying files back and forth by using the “GET” and “PUT” commands. You should also be sniffing your connection while doing this, so that you can then look at the resulting traffic. Well that’s it folks for our discussion of the TFTP protocol. I sincerely hope you enjoyed it. Till next time!