
\section{Exercise 2 - Task 1}
\subsection{Rep:2.a}
In order to use scapy we need to convert out pcap-ng dump to pcap.
\begin{verbatim}
$ tshark -r team15_ex21.pcapng -w team15_ex21.pcap -F pcap
\end{verbatim}

We are only interested in flows with more (or equal) than 400 packets, each exported as a separate pcap file.

\begin{verbatim}
$ ./somefilter.py | sh
\end{verbatim}

./somefilter.py
\begin{redframe}\begin{scriptsize}\begin{verbatim}
#!/usr/bin/env python

from scapy.all import *

def somefilter(pcapfile):
    flows = dict()
    for p in PcapReader(pcapfile):
        if IP in p:
            src = p[IP].src
            dst = p[IP].dst

            if (src,dst) in flows:
                flows[(src,dst)] +=1
            else:
                flows[(src,dst)] = 1

    for flow,cnt in flows.items():
        if cnt >= 400:
            print 'tshark -r '+pcapfile+' -w "flow_'+flow[0]+'_'+flow[1]+'.pcap" -F pcap ' \
                   + '\'ip.src == '+flow[0]+' and ip.dst == '+flow[1]+'\''

if __name__ == "__main__":
    somefilter("team15_ex21.pcap")
\end{verbatim}\end{scriptsize}\end{redframe}

With Wireshark we poked around and exported the flows to csv to further investigate.

While poking around we came across an unexpected value of srcport.
\begin{verbatim}
$ ./srcfeat_power.py --input flow_114.176.157.191_221.72.61.209.csv --feature srcport
# 114.176.157.191,541,2,1.5469339647025981
\end{verbatim}
There seemed to be 2 different srcports, occuring nearly equally often.
We looked into it with Rapidminer and found a suspiciously alternating srcport jumping between \emph{\textbf{5950}} and \emph{\textbf{5960}}.

\includegraphics[width=0.6\columnwidth,keepaspectratio]{content/e21_flow_114_176_157_191_221_72_61_209_srcport.png}


\subsection{Rep:2.b}
The message is \emph{\textbf{Data acquired. Key for message (len=42 \& pkts>200): nSa123 (Scott)}}

\begin{redframe}\begin{scriptsize}\begin{verbatim}
#!/usr/bin/env python

import csv
import binascii

def somedecode(filename):
  with open(filename, 'rb') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
    header = None
    bits = ""

    for row in spamreader:
      if header is None:
        header = row
        continue

      if row[2] == '114.176.157.191' and row[10] == '5950':
        bits += "0"
      if row[2] == '114.176.157.191' and row[10] == '5960':
        bits += "1"

    bits = bits[:-(len(bits)%8)]
    print binascii.unhexlify('%x' % int(bits, 2))

if __name__ == "__main__":
    somedecode("flow_114.176.157.191_221.72.61.209.csv")
\end{verbatim}\end{scriptsize}\end{redframe}


\section{Exercise 2 - Task 2}
\subsection{Rep:2.c}
The message will be \emph{\textbf{rc4}} encrypted using the key \emph{\textbf{nSa123}}. Decrypt with:
\begin{verbatim}
$ openssl enc -d -rc4 -nosalt -k nSa123 -in stream.enc -out stream.txt
\end{verbatim}


\subsection{Rep:2.d}
Redo initial conversion like in the previous task, but also apply a filter to \emph{\textbf{only retain packets of length 42}}.

\begin{verbatim}
$ tshark -r team15_ex22.pcapng -w team15_ex22.pcap -F pcap 'frame.len == 42'
\end{verbatim}

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.

\begin{verbatim}
$ ./somefilter.py | sh
\end{verbatim}

./somefilter.py
\begin{redframe}\begin{scriptsize}\begin{verbatim}
#!/usr/bin/env python                                                                                                                                               
                                                                                                                                                                    
from scapy.all import *                                                                                                                                             
                                                                                                                                                                    
def somefilter(pcapfile):                                                                                                                                           
    flows = dict()                                                                                                                                                  
    for p in PcapReader(pcapfile):                                                                                                                                  
        if IP in p:                                                                                                                                                 
            src = p[IP].src                                                                                                                                         
            dst = p[IP].dst                                                                                                                                         
                                                                                                                                                                    
            if (src,dst) in flows:                                                                                                                                  
                flows[(src,dst)] +=1                                                                                                                                
            else:                                                                                                                                                   
                flows[(src,dst)] = 1                                                                                                                                
                                                                                                                                                                    
    for flow,cnt in flows.items():                                                                                                                                  
        if cnt >= 200:                                                                                                                                              
            print 'tshark -r '+pcapfile+' -w "flow_'+flow[0]+'_'+flow[1]+'.pcap" -F pcap ' \                                                                        
                   + '\'ip.src == '+flow[0]+' and ip.dst == '+flow[1]+'\''                                                                                          
            print 'tshark -n -r "flow_'+flow[0]+'_'+flow[1]+'.pcap" -Eheader=y -Eseparator=, -Equote=d -Tfields '\                                                  
                   + '-e frame.number -e _ws.col.Time -e ip.src -e ip.dst -e _ws.col.Protocol -e frame.len '\                                                       
                   + '-e _ws.col.Info -e _ws.col.dscp -e _ws.col.ipid -e _ws.col.cs -e _ws.col.srcport '\                                                           
                   + '-e _ws.col.dstport -e _ws.col.proto > flow_'+flow[0]+'_'+flow[1]+'.csv'                                                                       
                                                                                                                                                                    
                                                                                                                                                                    
if __name__ == "__main__":                                                                                                                                          
    somefilter("team15_ex22.pcap")                                                                                                                                  
\end{verbatim}\end{scriptsize}\end{redframe}

We examined the dumps and suspected the covert channel to be in the IPID fields.\\
After exporting the bytes into separate files we were stuck at decrypting the decoded bytes.

\begin{verbatim}
$ ./decode\_ipid.py
$ openssl enc -d -rc4 -nosalt -k nSa123 -in stream\_encrypted -out stream\_decrypted
\end{verbatim}

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.

\begin{verbatim}
$ ./autocorr_all.sh _ws.col.ipid
\end{verbatim}

./autocorr\_all.sh
\begin{redframe}\begin{scriptsize}\begin{verbatim}
#!/bin/bash                                                                                                                                                         
                                                                                                                                                                    
for f in *.csv ; do                                                                                                                                                 
    sed -e 's/,"0x[a-fA-F0-9]\{4\} (\([0-9]\+\))",/,"\1",/' -e 's/,"UDP"$/,"17"/' \
        -e 's/,"ICMP"$/,"1"/' $f > ${f}.dehexed                                           
    echo "$f, $1: $(../../autocorr.py --input ${f}.dehexed --field ${1})"                                                                                           
done                                                                                                                                                                
\end{verbatim}\end{scriptsize}\end{redframe}

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.\\

After trying to extract and decode the Proto-field we finally came across the solution.

\begin{verbatim}
$ ./somedecode.py | openssl enc -d -rc4 -nosalt -k nSa123
\end{verbatim}

./somedecode.py
\begin{redframe}\begin{scriptsize}\begin{verbatim}
#!/usr/bin/env python                                                                                                                                            
                                                                                                                                                                 
import csv                                                                                                                                                       
import binascii                                                                                                                                                  
                                                                                                                                                                 
def somedecode(filename):                                                                                                                                        
  with open(filename, 'rb') as csvfile:                                                                                                                          
    spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')                                                                                               
    header = None                                                                                                                                                
    bits = ""                                                                                                                                                    
                                                                                                                                                                 
    for row in spamreader:                                                                                                                                       
      if header is None:                                                                                                                                         
        header = row                                                                                                                                             
        continue                                                                                                                                                 
                                                                                                                                                                 
      if row[12] == 'ICMP':                                                                                                                                      
        bits += "0"                                                                                                                                              
      if row[12] == 'UDP':                                                                                                                                       
        bits += "1"                                                                                                                                              
                                                                                                                                                                 
#    print bits                                                                                                                                                  
    #bits = bits[:-(len(bits)%8)]                                                                                                                                
    print binascii.unhexlify('%x' % int(bits, 2))                                                                                                                
                                                                                                                                                                 
if __name__ == "__main__":                                                                                                                                       
    somedecode("flow_204.10.110.7_187.10.25.137.csv")                                                                                                            
\end{verbatim}\end{scriptsize}\end{redframe}

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}\\
This does not happen with the {\tt PcapRawReader}, so we rewrote the script.\\

Another fail was our fixation on ip.id. We tried to decode that field without looking at other possibilities.


\subsection{Rep:2.e}
The message is \emph{\textbf{Agent South was captured! Aborting operation. (Agent Scott)}}.


\section{Lessons learned}
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.
