Python: module tftp

tftp | index /build/dshell/src/dshell/decoders/tftp/tftp.py

`TFTP Decoder
In short:
Goes through UDP traffic, packet by packet, and ties together TFTP file
streams. If the command line argument is set (--tftp_rip), it will dump the
files to a directory (--tftp_outdir=<DIR>)
In long:
Goes through each UDP packet and parses out the TFTP opcode. For read or
write requests, it sets a placeholder in unsetReadStreams or unsetWriteStreams,
respectively. These placeholders are moved to openStreams when we first see
data for the read request or an ACK code for a write request. The reason for
these placeholders is to allow the server to set the ephemeral port during
data transfer.
When it sees a DATA packet, it stores the data under the IP-port-IP-port
openStream key as 'filedata'. Each of these data packets has an ordered block
number, and the file data is stored under that block number. It is reassembled
later. When we consider a stream finished (either the DATA packet is too short
or there are no more packets), we rebuild the file data, print information
about the stream, dump the file (optional), and move the information from
openStreams to closedStreams.
Example:
Running on sample pcap available here: https://wiki.wireshark.org/TFTP
With default values, it will display transfers performed
Dshell> decode -d tftp ~/pcap/tftp_*.pcap
tftp 2013-05-01 08:24:11 192.168.0.253:50618 -- 192.168.0.10:3445 ** read rfc1350.txt (24599 bytes) **
tftp 2013-04-27 05:07:59 192.168.0.1:57509 -- 192.168.0.13:2087 ** write rfc1350.txt (24599 bytes) **
With the --tftp_rip flag, it will generate the same output while reassembling
the files and saving them in a defined directory (./tftp_out by default)
Dshell> decode -d tftp --tftp_rip --tftp_outdir=./MyTFTP ~/pcap/tftp_*.pcap
tftp 2013-05-01 08:24:11 192.168.0.253:50618 -- 192.168.0.10:3445 ** read rfc1350.txt (24599 bytes) **
tftp 2013-04-27 05:07:59 192.168.0.1:57509 -- 192.168.0.13:2087 ** write rfc1350.txt (24599 bytes) **
Dshell> ls ./MyTFTP/
rfc1350.txt rfc1350.txt_01
Note: The two files have the same name in the traffic, but have incremented
filenames when saved`

Modules
`` |  |
dpkt | dshell | os | struct

Classes
`` |  | dshell.IPDecoder(dshell.Decoder) DshellDecoder
class DshellDecoder(dshell.IPDecoder)
`` | `Primary decoder class`
| Method resolution order: DshellDecoder dshell.IPDecoder dshell.Decoder __builtin__.object Methods defined here: __init__(self, **kwargs) packetHandler(self, ip=None) `Handles each UDP packet. It checks the TFTP opcode and parses accordingly.` postModule(self) `cleanup any unfinished streams` preModule(self) `if needed, create the directory for file output` Data and other attributes defined here: ACK = 4 DATA = 3 ERROR = 5 OACK = 6 RRQ = 1 WRQ = 2 Methods inherited from dshell.IPDecoder: IPHandler(self, addr, pkt, ts, **kwargs) `called if packet is IPv4/IPv6 check packets using filterfn here` ipdefrag(self, pkt) `ip fragment reassembly` rawHandler(self, pktlen, pkt, ts, **kwargs) `takes ethernet data and determines if it contains IP or IP6. defragments IPv4 if 6to4, unencaps the IPv6 If IP/IP6, hands off to IPDecoder via IPHandler()` Data and other attributes inherited from dshell.IPDecoder: IP_PROTO_MAP = {0: 'IP', 1: 'ICMP', 6: 'TCP', 17: 'UDP', 41: 'IP6', 58: 'ICMP6'} Methods inherited from dshell.Decoder: __repr__(self) __super__(self) `convenience function to get bound instance of superclass` alert(self, *args, **kw) `sends alert to output handler typically self.alert will be called with the decoded data and the packet/connection info dict last, as follows: self.alert(alert_arg,alert_arg2...,alert_data=value,alert_data2=value2....,**conn/pkt.info()) example: self.alert(decoded_data,conn.info(),blob.info()) [blob info overrides conn info] this will pass all information about the decoder, the connection, and the specific event up to the output module if a positional arg is a dict, it updates the kwargs if an arg is a list, it extends the arg list else it is appended to the arg list all arguments are optional, at the very least you want to pass the **pkt/conn.info() so all traffic info is available. output modules handle this data as follows: - the name of the alerting decoder is available in the "decoder" field - all non-keyword arguments will be concatenated into the "data" field - keyword arguments, including all provided by .info() will be used to populate matching fields - remaining keyword arguments that do not match fields will be represented by "key=value" strings concatenated together into the "extra" field` cleanConnectionStore(self) `cleans connection store of all information, flushing out data` cleanup(self, ts) `if cleanup interval expired, close connections not updated in last interval` close(self, conn, ts=None) `for connection based decoders close and discard the connection object` debug(self, msg) `logs msg at debug level` decode(self, *args, **kw) `# we get the raw output from pcapy as header, data` dump(self, *args, **kw) `write packet data (probably to the PCAP writer if present)` error(self, msg) `logs msg at error level` find(self, addr, state=None) getASN(self, ip, db=None, notfound='--') `Get ASN associated with an IP. Requires GeoIP library (geoip2) and data files.` getGeoIP(self, ip, db=None, notfound='--') `Get country code associated with an IP. Requires GeoIP library (geoip2) and data files.` log(self, msg, level=20) `logs msg at specified level (default of INFO is for -v/--verbose output)` parseArgs(self, args, options={}) `called to parse command-line arguments and cli/config file options if options dict contains 'all' or the decoder name as a key class members will be updated from value` parseOptions(self, options={}) `option keys:values will set class members (self.key=value) if key is in optiondict` postFile(self) preFile(self) stop(self, conn) `stop following connection handlers will not be called, except for connectionCloseHandler` track(self, addr, data=None, ts=None, offset=None, **kwargs) `connection tracking for TCP and UDP finds or creates connection based on addr updates connection with data if provided (using offset to reorder) tracks timestamps if ts provided extra args get passed to new connection objects` warn(self, msg) `logs msg at warning level` write(self, obj, **kw) `write session data` Data descriptors inherited from dshell.Decoder: __dict__ `dictionary for instance variables (if defined)` __weakref__ `list of weak references to the object (if defined)`

Data
`` |  | dObj = tftp udp rip=None outdir=None