Name: Alan Tu Answer 1: 00:25:00:fe:07:c4 Answer 2: AppleTV/2.4 Answer 3a: h Answer 3b: ha Answer 3c: hac Answer 3d: hack Answer 4: Hackers Answer 5: http://a227.v.phobos.apple.com/us/r1000/008/Video/62/bd/1b/mzm.plqacyqb..640x278.h264lc.d2.p.m4v Answer 6: Sneakers Answer 7: $9.99 Answer 8: iknowyourewatchingme Description: Network Forensics Contest #3 Narrative Alan Tu January 30, 2010 We write a script, http_analysis.pl, that takes advantage of Wireshark/tshark's HTTP dissection capability. This script outputs the following information for each HTTP request or HTTP response identified by Wireshark: frame.number: the number of the frame in the PCAP file frame.time: the timestamp of the frame tcp.stream: the TCP stream index, used to group together packets from the same TCP session ip.src, tcp.srcport, ip.dst, tcp.dstport: self-explanatory http.request.method: GET, POST, etc, see RFC 2616 http.request.uri: the URI specified in the HTTP request line http.host: the Host: header in the HTTP request http.user_agent: the User-Agent: header http.response.code: HTTP response status code (200, 404, etc) http.content_type: the MIME content type of a response or HTTP POST http.content_encoding: the encoding type, for example gzip or compress http.content_length: the length of the content, after encoding if applicable $ ./http_analysis.pl evidence03.pcap > evidence03_http.csv The output is in chronological order. A snippet follows: frame.number, frame.time, tcp.stream, ip.src, tcp.srcport, ip.dst, tcp.dstport, http.request.method, http.request.uri, http.host, http.user_agent, http.response.code, http.content_type, http.content_encoding, http.content_length 307, 2009/12/28 04:08:36.049280000, 11, 192.168.1.10, 49168, 8.18.65.67, 80, GET, /WebObjects/MZStore.woa/wa/viewMovie?id=333441649&s=143441, ax.itunes.apple.com, AppleTV/2.4 312, 2009/12/28 04:08:36.132055000, 11, 8.18.65.67, 80, 192.168.1.10, 49168, , , , , 200, text/xml, gzip, 2278 315, 2009/12/28 04:08:36.184591000, 11, 192.168.1.10, 49168, 8.18.65.67, 80, GET, /WebObjects/MZStore.woa/wa/relatedItemsShelf?ct-id=3&id=333441649&storeFrontId=143441&mt=6, ax.itunes.apple.com, AppleTV/2.4 326, 2009/12/28 04:08:36.321550000, 11, 8.18.65.67, 80, 192.168.1.10, 49168, , , , , 200, text/xml, gzip, 879 1181, 2009/12/28 04:09:28.969360000, 22, 192.168.1.10, 49176, 8.18.65.67, 80, GET, /WebObjects/MZStore.woa/wa/viewMovie?id=283963264&s=143441, ax.itunes.apple.com, AppleTV/2.4 1186, 2009/12/28 04:09:29.043905000, 22, 8.18.65.67, 80, 192.168.1.10, 49176, , , , , 200, text/xml, gzip, 2586 1190, 2009/12/28 04:09:29.096721000, 22, 192.168.1.10, 49176, 8.18.65.67, 80, GET, /WebObjects/MZStore.woa/wa/relatedItemsShelf?ct-id=3&id=283963264&storeFrontId=143441&mt=6, ax.itunes.apple.com, AppleTV/2.4 1194, 2009/12/28 04:09:29.172462000, 22, 8.18.65.67, 80, 192.168.1.10, 49176, , , , , 200, text/xml, gzip, 907 The script also summarizes the unique MAC address/IP/user agent triples seen for all HTTP requests. Summary of sources: eth.src, ip.src, http.user_agent, http.request 00:25:00:fe:07:c4, 192.168.1.10, AppleTV/2.4, 116 We see that MAC address 00:25:00:fe:07:c4 is the only address recorded making HTTP requests, and that the only user agent is AppleTV/2.4. We see the following URI that were requested: /WebObjects/MZSearch.woa/wa/incrementalSearch?media=movie&q=h /WebObjects/MZSearch.woa/wa/incrementalSearch?media=movie&q=ha /WebObjects/MZSearch.woa/wa/incrementalSearch?media=movie&q=hac /WebObjects/MZSearch.woa/wa/incrementalSearch?media=movie&q=hack So the first incremental search was h, ha, hac, hack. By inspection, the first GET request after the incremental search is at frame 307. The first movie's information is located at http://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewMovie?id=333441649&s=143441. The response, however, is gzip compressed. Wireshark does decode the XML which can be inspected. Alternatively, one can extract the XML file from the TCP stream. We use stream.pl, which has been updated from contest #2 with better output and error handling. $ ./stream.pl -s 11 evidence03.pcap Disabling dissector http in /home/alan/.wireshark/disabled_protos Writing file 192.168.1.10.49168-8.18.65.67.80, length 650 bytes, MD5 hash de2f1a19ee5b41e0a39952472aebe24b Writing file 8.18.65.67.80-192.168.1.10.49168, length 5398 bytes, MD5 hash 3dbeffe5a99a05af910e5910f774b176 There are two HTTP requests and responses in the same TCP stream. We use another script, http_rx.pl (Response eXtract) to isolate each response message: $ ./http_rx.pl 8.18.65.67.80-192.168.1.10.49168 Writing file 8.18.65.67.80-192.168.1.10.49168.1, length 13327 bytes, MD5 hash 09d532262a52a32accaa66fef3db0313 Writing file 8.18.65.67.80-192.168.1.10.49168.2, length 6171 bytes, MD5 hash da03b2e3635846efdf4be8f50c1c5637 We see from frame number 312 that the first response is the one we want. Therefore we inspect file 8.18.65.67.80-192.168.1.10.49168.1. Two XML keys of interest: titleHackers preview-urlhttp://a227.v.phobos.apple.com/us/r1000/008/Video/62/bd/1b/mzm.plqacyqb..640x278.h264lc.d2.p.m4v We do a similar procedure for the second movie. By inspection we see that tcp.stream 22 (frame 1186) has the response we want. $ ./stream.pl -s 22 evidence03.pcap Disabling dissector http in /home/alan/.wireshark/disabled_protos Writing file 192.168.1.10.49176-8.18.65.67.80, length 650 bytes, MD5 hash 8ade3cb503dea8166739d9c27aee481b Writing file 8.18.65.67.80-192.168.1.10.49176, length 5785 bytes, MD5 hash 5c580df12eb9d1f07713fa5449ce9a8f $ ./http_rx.pl 8.18.65.67.80-192.168.1.10.49176 Writing file 8.18.65.67.80-192.168.1.10.49176.1, length 13672 bytes, MD5 hash b691ac4cd39002987891b62c9c633a34 Writing file 8.18.65.67.80-192.168.1.10.49176.2, length 6206 bytes, MD5 hash 77d077e66051e56e97668d8028c227b7 The first response is the one we want so we inspect 8.18.65.67.80-192.168.1.10.49176.1. titleSneakers price-display$9.99 Finally, the last incremental search had the URI /WebObjects/MZSearch.woa/wa/incrementalSearch?media=movie&q=iknowyourewatchingme The search term was i know you're watching me. A few notes about the scripts used for this contest submission: 1. http_analysis.pl has three optional switches: -R passes a display filter to tshark using tshark's -R switch -d tells tshark to decode traffic to the specified TCP port as http, ie if http_analysis.pl -d PORT is specified, the script runs tshark with tshark -d tcp.port==PORT,http -w is a courtesy function that creates a new PCAP with only the packets in the specified tcp.stream index The $TSHARK variable must be set to the path of the tshark executable, but the script will tell you to do this if the variable points to a non-existent file. 2. stream.pl This has the same functionality as stream.pl for contest #2. The #! line has been made Unix-friendly, the timestamp and IP information for each stream now consistently reflects the first packet captured, error output was slightly improved, and the timestamps are friendlier. The $TSHARK variable must be set to the path of the tshark executable, but the script will tell you to do this if the variable points to a non-existent file. The $WIRESHARK_DISABLED_PROTOS variable must point to the directory where the disabled_protos file can be created or already exists. The directory must exist but the disabled_protos file exist need not. 3. http_rx.pl This simple script takes raw TCP stream data as output (from stream.pl). There are assumed to be one or more HTTP response objects in the input file. The script looks for a content-length field. If no content-length is found or if the HTTP response is a 304 not modified, the script can only assume there is just one HTTP response message. The script uses Perl's HTTP::Response module to parse and decode the content.