2 \section{Exercise 2 - Task 1}
4 In order to use scapy we need to convert out pcap-ng dump to pcap.
6 $ tshark -r team15_ex21.pcapng -w team15_ex21.pcap -F pcap
9 We are only interested in flows with more (or equal) than 400 packets, each exported as a separate pcap file.
12 $ ./somefilter.py | sh
16 \begin{redframe}\begin{scriptsize}\begin{verbatim}
19 from scapy.all import *
21 def somefilter(pcapfile):
23 for p in PcapReader(pcapfile):
28 if (src,dst) in flows:
33 for flow,cnt in flows.items():
35 print 'tshark -r '+pcapfile+' -w "flow_'+flow[0]+'_'+flow[1]+'.pcap" -F pcap ' \
36 + '\'ip.src == '+flow[0]+' and ip.dst == '+flow[1]+'\''
38 if __name__ == "__main__":
39 somefilter("team15_ex21.pcap")
40 \end{verbatim}\end{scriptsize}\end{redframe}
42 With Wireshark we poked around and exported the flows to csv to further investigate.
44 While poking around we came across an unexpected value of srcport.
46 $ ./srcfeat_power.py --input flow_114.176.157.191_221.72.61.209.csv --feature srcport
47 # 114.176.157.191,541,2,1.5469339647025981
49 There seemed to be 2 different srcports, occuring nearly equally often.
50 We looked into it with Rapidminer and found a suspiciously alternating srcport jumping between \emph{\textbf{5950}} and \emph{\textbf{5960}}.
52 \includegraphics[width=0.6\columnwidth,keepaspectratio]{content/e21_flow_114_176_157_191_221_72_61_209_srcport.png}
56 The message is \emph{\textbf{Data acquired. Key for message (len=42 \& pkts>200): nSa123 (Scott)}}
58 \begin{redframe}\begin{scriptsize}\begin{verbatim}
64 def somedecode(filename):
65 with open(filename, 'rb') as csvfile:
66 spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
70 for row in spamreader:
75 if row[2] == '114.176.157.191' and row[10] == '5950':
77 if row[2] == '114.176.157.191' and row[10] == '5960':
80 bits = bits[:-(len(bits)%8)]
81 print binascii.unhexlify('%x' % int(bits, 2))
83 if __name__ == "__main__":
84 somedecode("flow_114.176.157.191_221.72.61.209.csv")
85 \end{verbatim}\end{scriptsize}\end{redframe}
88 \section{Exercise 2 - Task 2}
90 The message will be \emph{\textbf{rc4}} encrypted using the key \emph{\textbf{nSa123}}. Decrypt with:
92 $ openssl enc -d -rc4 -nosalt -k nSa123 -in stream.enc -out stream.txt
97 Redo initial conversion like in the previous task, but also apply a filter to \emph{\textbf{only retain packets of length 42}}.
100 $ tshark -r team15_ex22.pcapng -w team15_ex22.pcap -F pcap 'frame.len == 42'
103 After conversion apply a modified version of ./somefilter.py as it is pretty time consuming to manually create csv files. Especially if we keep changing parameters or fields.
106 $ ./somefilter.py | sh
110 \begin{redframe}\begin{scriptsize}\begin{verbatim}
111 #!/usr/bin/env python
113 from scapy.all import *
115 def somefilter(pcapfile):
117 for p in PcapReader(pcapfile):
122 if (src,dst) in flows:
127 for flow,cnt in flows.items():
129 print 'tshark -r '+pcapfile+' -w "flow_'+flow[0]+'_'+flow[1]+'.pcap" -F pcap ' \
130 + '\'ip.src == '+flow[0]+' and ip.dst == '+flow[1]+'\''
131 print 'tshark -n -r "flow_'+flow[0]+'_'+flow[1]+'.pcap" -Eheader=y -Eseparator=, -Equote=d -Tfields '\
132 + '-e frame.number -e _ws.col.Time -e ip.src -e ip.dst -e _ws.col.Protocol -e frame.len '\
133 + '-e _ws.col.Info -e _ws.col.dscp -e _ws.col.ipid -e _ws.col.cs -e _ws.col.srcport '\
134 + '-e _ws.col.dstport -e _ws.col.proto > flow_'+flow[0]+'_'+flow[1]+'.csv'
137 if __name__ == "__main__":
138 somefilter("team15_ex22.pcap")
139 \end{verbatim}\end{scriptsize}\end{redframe}
141 We examined the dumps and suspected the covert channel to be in the IPID fields.\\
142 After exporting the bytes into separate files we were stuck at decrypting the decoded bytes.
146 $ openssl enc -d -rc4 -nosalt -k nSa123 -in stream_encrypted -out stream_decrypted
149 After the hint \quote{Use the toooools!} we adapted the autocorr.py tool to not require the output parameter and wrote a shell wrapper to loop through all csv files for a given field name.
152 $ ./autocorr_all.sh _ws.col.ipid
156 \begin{redframe}\begin{scriptsize}\begin{verbatim}
160 sed -e 's/,"0x[a-fA-F0-9]\{4\} (\([0-9]\+\))",/,"\1",/' -e 's/,"UDP"$/,"17"/' \
161 -e 's/,"ICMP"$/,"1"/' $f > ${f}.dehexed
162 echo "$f, $1: $(../../autocorr.py --input ${f}.dehexed --field ${1})"
164 \end{verbatim}\end{scriptsize}\end{redframe}
166 After autocorr\_all'ing all available fields ip.proto produced an exception on one csv file. The investigation led to the addition of two new sed replace rules above.\\
168 After trying to extract and decode the Proto-field we finally came across the solution.
171 $ ./somedecode.py | openssl enc -d -rc4 -nosalt -k nSa123
175 \begin{redframe}\begin{scriptsize}\begin{verbatim}
176 #!/usr/bin/env python
181 def somedecode(filename):
182 with open(filename, 'rb') as csvfile:
183 spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
187 for row in spamreader:
192 if row[12] == 'ICMP':
198 #bits = bits[:-(len(bits)%8)]
199 print binascii.unhexlify('%x' % int(bits, 2))
201 if __name__ == "__main__":
202 somedecode("flow_204.10.110.7_187.10.25.137.csv")
203 \end{verbatim}\end{scriptsize}\end{redframe}
205 It turned out that scapy is not really suited to handle our decoding task as it would discard the frame.len information. \url{http://stackoverflow.com/questions/21752576/whole-packet-length-scapy}\\
206 This does not happen with the {\tt PcapRawReader}, so we rewrote the script.\\
208 Another fail was our fixation on ip.id. We tried to decode that field without looking at other possibilities.
212 The message is \emph{\textbf{Agent South was captured! Aborting operation. (Agent Scott)}}.
215 \section{Lessons learned}
216 Basically we have two semi-independent solutions for every task as the both of us had slightly different ways of doing things, but both wanted to learn how things work.