일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- webhacking
- 시스템해킹
- reversing
- network
- 소프트웨어보안
- 드림핵
- ftz
- dreamhack
- Web
- 웹해킹
- 리버싱
- XSS
- WarGame
- bee-box
- TCP
- 알고리즘
- 비박스
- 네트워크
- 모의해킹
- 네트워크보안
- 소프트웨어
- CodeEngn
- 워게임
- 웹
- 순서도
- 해킹
- 시스템
- hacking
- System
- Webhaking
- Today
- Total
Without a Break
Attacks on the TCP protocol 본문
TCP Client Program
Step 1. 소켓 생성
- TCP: SOCK_STREAM 사용
- UDP: SOCK_DGRAM 사용
Step 2. 서버에 연결
- TCP 연결 시작
Step 3. 데이터 전송
TCP Server Program
Step 1. 소캣 생성
Step 2. 주소 bind
App에서 호스트 컴퓨터에 포트 번호 등록
-> 패킷이 호스트에 도착하면 운영체제가 어떤 앱이 포트 번호에 기반된 수신자인지 알 수 있음.
-> 서버는 운영체제에 사용 중인 포트가 무엇인지 알려야 할 필요가 있음.
Step 3. connection 대기 (listen)
App이 listen()을 호출하여 OS에 App이 클라이언트를 수락할 준비가 되었음을 알림
-> 연결 요청이 수신되면, OS가 3-way handshake를 거침
-> 연결이 설정 -> queue에 배치
-> App 실행(수락)하기를 기다림
Step 4. connection 요청 수락 (accept)
queue에서 첫 번째 connect 요청 추출
-> 새 'connection' 소켓 생성
-> 소켓 디스크립터 반환
Step 5. 데이터 교환
일단 연결이 설정되고 승인되면 양쪽 모두 새 소켓을 사용하여 데이터를 송수신할 수 있음
다중 연결
다중 연결 수락을 위해서 fork() 시스템 콜로 복제해서 새 프로세스 만듦
-> 성공 시, 부모 프로세스는 자식 프로세스의 프로세스 ID가 반환되고, 자식 프로세스는 0 반환
TCP Data Transmission
- 연결 수립 시, 각 OS가 두 buffer를 할당 (송신, 수신)
- 데이터 전송 시, 패킷을 직접 생성하지 않고 buffer에 쓰기만 함
- 각 octet(순서번호 단위, Byte)은 sequence number를 가지며 TCP header에는 payload의 첫 번째 octet의 sequence number를 표기함 -> 수신 측에서 receive buffer 내 순서를 맞추는데 사용 + Acknowledgement
- 수신 buffer에 도착한 패킷들은 순서가 정렬된 후, data system(no boundary) 형태로 application으로 전달
- 수신 buffer에 데이터가 충분하지 못한 경우 또는 waiting time 이전에는 block 상태로 application의 접근을 막음 => 수신 buffer는 데이터 도착 후 바로 unlock 되지 않고 충분한 data를 기다리거나 일정 waiting time이 지난 후 application을 unblock 함 (성능 상의 이유)
TCP Header
TCP Segement: TCP Header + Data
Acknowledgment number: 어디까지 데이터를 전송받았다는 것을 수신인이 송신인한테 알려주기 위해 보냄
Header length(4 bits) : TCP header의 length는 32-bit(4byte)
Reserved: 향후 사용을 위해 보존해놓은 필드 (현재는 사용 X)
Code bits: SYN, FIN, ACK, RST, PSH, URG
Window size: 0일 경우, 송신인이 알아서 송신 속도를 줄임. flow control 위해 사용 (Window size는 MSS랑은 완전히 다르다.)
SYN Flooding Attack
TCP 3-way handshake: SYN (seq=x) -> SYN(seq=y)+ACK(=x+1) -> ACK(=y+1) (seq=x+1)
1. SYN Packet
- 클라이언트는 임의로 생성된 숫자 x를 sequence number로 사용하여 SYN 패킷이라는 특수 패킷을 서버로 전송
2. SYN-ACK Packet
- 수신 시 서버는 임의로 생성된 자신의 숫자 y를 sequence number로 사용하여 응답 패킷을 전송
3. ACK Packet
- 클라이언트가 ACK 패킷을 전송하여 handshake 를 완료
- 서버는 초기 SYN 패킷을 받으면 TCB(Transsmission Control Block)이라고 불리는 data structure를 사용하여 연결에 대한 정보를 저장 (아직 연결이 완료된 경우는 아님, half-open connection. 즉, 클라이언트->서버 방향만)
- 서버는 TCB를 half-open connection queue에 저장 -> 클라이언트로부터 ACK 받은 후에 queue에서 제거
- ACK가 도착하지 않으면 SYN+ACK 패킷을 재전송 -> ACK가 기다려도 도착하지 않으면 TCB를 버림
Dos Attack
일반적으로 Dos Attack에서 공격자는 서버보다 자원이 모자람
=> 공격자는 서버의 Achilles' heel을 찾아 자원을 집중할 필요가 있음
: 모든 half-open connection은 서버의 queue에 저장되는데, 이 queue를 가득 채워 더 이상 새로운 half-open connection에 대한 TCB를 저장할 공간을 제거하자. => 서버가 새로운 SYN 패킷을 받아들이지 못하도록 하자.
Step 1. 서버에 많은 SYN 패킷을 지속적으로 전송 => TCB 레코드를 삽입하여 대기열의 공간이 소모
Step 2. handshake의 3번째 step이 끝나지 않음. => TCB 레코드의 dequeue
TCB dequeue 조건
- 3-way handshake를 정상적으로 마침
- Time out 시간 동안 queue에 계속 머물러 있음
- Half-open connection에 대해 RST 패킷을 수신
주의할 점
대상 서버를 플러딩할 때 공격자는 임의의 소스 IP 주소를 사용해야 한다. 그렇지 않으면 공격이 방화벽에 의해 차단될 수 있다.
- 위조된 IP 주소를 컴퓨터에 할당할 수 없기 때문에 서버에서 보낸 SYN+ACK 패킷이 삭제될 수 있음. 기존 시스템에 도달하면(임의로 만든 IP 주소에 대한 기기가 존재할 경우) RST 패킷이 전송되고 TCB가 대기열에서 dequeue됨
- 두 번째 옵션이 발생할 가능성이 낮기 때문에 TCB 레코드는 대부분 대기열에 남아 있음. 이로 인해 SYN 플러딩 공격이 발생
대책
나쁜 대책
- 백로그 대기열 크기 증가
- 시간 초과 감소
좋은 대책 : SYN 요청을 저장하지 않기
- Accept된 연결만 저장 (3-handshake 프로토콜이 끝난 후에)
- Queue가 없어서 flooding 못함
- 보안 측면에서는 작동하지 않음
• SYN 요청이 저장되지 않으므로 ACK 패킷의 유효성을 확인할 수 없음
• Accept-Queue 플러딩하기 위한 스푸핑된 ACK 패킷 전송
대책: SYN Cookies
1. 서버가 SYN 패킷을 수신한 후, 서버에만 알려진 비밀 키를 사용하여 패킷의 정보로부터 키가 있는 해시(H)를 계산
– 이 해시(H)는 서버에서 ISN(inital sequence number)로 클라이언트에 전송 => SYN Cookie
- IP 주소, 포트 번호 및 시퀀스 번호
– 서버가 반쯤 열린 연결을 대기열에 저장하지 않음
2. 클라이언트가 공격자인 경우 H는 공격자에게 도달하지 않음
3. 클라이언트가 공격자가 아닌 경우 ACK 필드에 H+1을 전송
– 서버는 쿠키를 다시 계산하여 ACK 필드의 숫자가 유효한지 확인
+) replay attack 방어
: H secret이 무엇인지 알 수 없어도 x가 무엇이고 y가 무엇인지는 패킷을 통해 알 수 있음
TCP Reset Attack
목적: 호스트 A와 B 사이의 TCP 연결을 끊기
스푸핑된 RST 패킷: 소스 IP 주소, 소스 포트, 목적지 IP 주소, 목적지 포트, 시퀀스 번호(수신기 윈도우 내) 필드를 올바르게 세팅해야 한다.
Using Reset flag : 호스트 중 한 호스트라도 RST 패킷을 보내면 즉시 연결이 끊김
=> 제 3 호스트가 두 호스트 중 하나라고 속이고 RST 보내면 강제 종료
Man-in-the-middle or sniffer
스푸핑된 RST 패킷에 올바른 TCP 서명이 있어야 함
- 소스 IP 주소
- 소스 포트
- 목적지 IP 주소
- 목적지 포트
- 시퀀스 번호 (효율적으로 추정할 수 있어야 함)
Captured TCP Connection Data
목적: 사용자와 서버 간의 Telnet 연결 끊기
Step 1. 공격자의 기기에서 Wireshark를 사용하여 트래픽을 sniff
Step 2. 목적지 포트, 소스 포트, 시퀀스 번호를 검색
on SSH connection
- 네트워크 계층에서 암호화가 수행되면 헤더를 포함한 전체 TCP 패킷이 암호화되므로 스니핑이나 스푸핑이 불가능
=> 그러나 SSH가 전송 계층에서 암호화를 수행할 때 TCP 헤더는 암호화되지 않은 상태로 유지
=> 따라서, RST 패킷에는 헤더만 필요하므로 공격이 성공합니다.
on Video-Streaming Connection
Telnet과 다르게 시퀀스 번호가 빠르게 증가해서 Network 78 tool을 사용해야 함.
$ sudo netwox 78 --filter "src host 10.0.2.18"
- RST 패킷이 서버로 지속적으로 전송되는 경우 동작이 의심스러우며 사용자에 대해 수행된 일부 징벌적 조치를 트리거할 수 있음
Guessing the Sequence Number (with sniffing)
1. 공격의 성공은 시퀀스 번호에 매우 민감
2. 스푸핑된 패킷에 입력한 번호는 서버가 대기하는 번호와 정확히 일치해야 한다.
- 번호가 너무 작으면, 작동하지 않음
- 번호가 너무 크면, RFC 793에 따라 그것이 rcv.wnd 내에 있는 한 유효해야 하지만 우리는 그것을 알 수 없음
- 더 큰 숫자를 사용할 경우 연결에 영향이 없음. 즉, 수신자가 RST 패킷을 폐기하는 것처럼 보임
3. 가능한 최대 시퀀스 넘버는 2^32(약 43억)
4. 같은 네트워크상황에 있으면 쉽게 유추 가능
5. 외부에서 공격한다면 랜덤으로 유추해야 함(추측하는 시퀀스 넘버와 비슷하면 됨)
TCP Session Hijacking Attack
- 목적: 설정한 연결에 데이터 주입
- Spoofed TCP Packet: 소스 IP 주소, 소스 포트, 목적지 IP 주소, 목적지 포트, 시퀀스 번호(수신기 윈도우 내) 필드를 올바르게 세팅
Step 1. 사용자는 서버의 telnet 연결과 설정
Step 2. 트래픽을 감지하기 위해 공격자의 기기로 Wireshark 사용
Step 3. 목적지 포트, 소스 포트, 시퀀스 번호를 검색
실행하기 위해 사용하는 명령
$ nc -lv (port#)
$ cat (path) > (path)
Telnet 연결의 하이재킹에 의해, 임의의 명령을 서버에서 실행할 수 있다.
- 비밀을 얻기 위해, 우리는 서버 머신에서 공격자의 머신으로 비밀을 보낼 수 있도록 TCP 서버 프로그램을 실행
- ">" 명령은 출력을 공격자에게 리디렉션
Creating Reverse shell
- 연결을 가로챈 후 실행하는 가장 좋은 명령은 역 셸 명령을 실행하는 것
- 서버에서 /bin/bash와 같은 셸 프로그램을 실행하고 공격자가 제어할 수 있는 입력/출력 장치를 사용
- 셸 프로그램은 TCP 연결의 한 쪽 끝을 입출력에 사용하고 다른 쪽 끝은 공격자 기계에 의해 제어
- 역방향 셸은 공격자에게 다시 연결되는 원격 시스템에서 실행되는 셸 프로세스
- 해킹에 사용되는 매우 일반적인 기술
Reverse Shell
- 셸은 상호적이어야 함
- 셸의 출력 장치(stdout)가 10.0.2.70의 포트 9090으로 TCP 연결로 리디렉션
- 파일 설명자 2는 표준 오류(stderr)를 나타냄. 이 경우 오류 출력이 TCP 연결인 stdout으로 리디렉션
Defending Against Session Hijacking
1. 공격자가 패킷을 스푸핑하기 어렵게 함
– 소스 포트 번호 랜덤화
– 초기 시퀀스 번호 랜덤화 => 로컬 공격에 효과적이지 않음
2. 암호화되지 않은 payload
- IPSec
TCP FIN-WAIT2 Flooding Attack
1. TCP가 FIN_WAIT 2 상태를 유지하는 시간에는 제한이 없음
- 공격: 서버와 많은 수의 연결을 만듦 -> 서버에서 강제로 연결을 닫은 다음 CLOSE_WAIT 후 연결을 무시
=> 메모리 소모 공격 발생
2. 애플리케이션이 연결을 종료했기 때문에 메모리 소진은 애플리케이션이 아닌 커널(TCP 스택)에서 발생
대책
– FIN-WAIT2 상태 기간 제한 적용 => FIN이 도착하지 않으면 연결을 중단합니다.
– 사용자 공간을 제어하지 않고 연결 수 제한 적용 과정
– 최대 진행 중인 연결 수 설정
TCP Amplication Attack
: 증폭 분산 서비스 거부(DDoS) 공격
- 일반적으로 UDP 기반
TCP 및 리플렉션
– TCP에 증폭 취약성이 있음
TCP Optimistic ACK Attack
: 아직 수신되지 않은 데이터를 ACK하여 전송률을 높임
- 무조건적인 ACK를 보냄으로써 failure issue가 없는 것처럼 속임
- 혼잡제어는 전송이 성공할수록 한 번에 전송하는 패킷 량이 증가하도록 함
- 수신자가 받지 못해도 계속해서 전송이 성공했다고 여기도록 함
'Network > 네트워크보안과프로그래밍' 카테고리의 다른 글
Firewall (0) | 2022.12.02 |
---|---|
BSD Sockets API-based Network Programming (0) | 2022.11.06 |
TCP Connection Establishment and Termination (0) | 2022.10.07 |
TCP: Transmission Control Protocol (0) | 2022.09.30 |
UDP: User Datagram Protocol (0) | 2022.09.30 |