본문 바로가기
NSLog(@"%@", dailyLog)

자원 고갈 공격 SYN 플러딩 (SYN Flooding)

by 틴디 2020. 7. 27.
728x90
반응형

  소프트웨어 개발 보안 설계시 고려해야 하는 자원 고갈 공격 중 SYN 플러딩이 있다. 이는 TCP 프로토콜의 구조적인 문제를 이용하여 공격을 시도한다. SYN 플러딩에 의해 시스템 자원이 고갈 되면서 정상 요청에 대해 대응하지 못하게 된다. 우선 이에 대해 자세히 알기 위해서는 위에서 말한 TCP 프로토콜의 구조적인 동작 원리를 알아두면 이해가 쉽다.

 

정상적인 클라이언트-서버와의 연결

웹 페이지가 있다고 하자. 이때 클라이언트가 정보를 얻기 위해 웹 페이지로 접근한다. 즉 쉽게 말해 클라이언트란 서비스를 요구하는 쪽이다. 서버는 이 웹 페이지를 통해 정보나 서비스를 클라이언트에게 제공한다. 클라이언트는 우리가 직접 마주하고 있는 단말 기기나 컴퓨터라 생각하고 서버는 서비스를 제공해주는 업체의 컴퓨터라 생각하면 이해가 쉽다.

 

1. 우선 기존의 방식은 3 way 핸드쉐이크 방식을 사용한다고 한다. 3 way handshake 방식은 아래에서 설명하는 것이 더 효과적이어서 아래에 설명한다. 

2. 클라이언트는 서버에 연결 요청을 시도하기 위해 서버에다가 SYN를 보낸다. 여기서 SYN란 연결 요청을 위해 보내는 프로토콜을 의미한다.

3. 클라이언트로 부터 날라온 메시지인 SYN를 서버가 받게 된다. 서버는 SYN 데이터를 받은 뒤 상태를 SYN_RCV로 변경한다. 

4. 상태가 변경된 서버는 응답 데이터인 ACK와 클라이언트에게 포트를 열어 줄 것을 요구하기 위해 SYN 데이터를 보내게 된다. 즉 서버는 ACK와 SYN를 클라이언트에게 전송한다.

5. 클라이언트에서 ACK와 SYN를 받으면 포트 연결 상태를 뜻하는 ESTABLISHED 상태로 변경하게 되고 요청을 받았다는 응답을 위해 ACK를 전송한다. 

6. 클라이언트로 부터 서버에 ACK 메시지가 도착하면 서버 또한 연결 상태를 뜻하는 ESTABLISHED 상태로 변경한 뒤 클라이언트와 서버는 정상적인 연결이 이루어 진다. 

 

3 way handshake 란?

(1) 위에서 클라이언트가 서버에 SYN 메시지를 보내고 (2)서버는 응답과 연결 요청을 원하는 ACK+SYN를 클라이언트에게 보내는 과정 (3) 다시 클라이언트가 서버에 응답 프로토콜 ACK를 보내는 과정이 3번의 신호를 주고 받는 과정이 일어나기 때문에 3 way handshake라고 한다.

 

그렇다면 위 구조를 이용한 SYN 플러딩이란 무엇일까?

 

SYN Flooding 

위에서 알 수 있듯이 정상적인 연결이 이루어 질려면 클라이언트가 SYN를 보내는 것으로 부터 시작해서 최종적으로 서버에 ACK 메시지가 도착하는 것을 통해 이루어진다(중간과정 생략). 이때 서버에는 동시에 수용 가능한 사용자 수가 있고, 공격자는 이 수용가능 량 만큼 서버에 SYN 패킷만 보내어 서버를 점유하게 된다. 이렇게 되면 서버는 클라이언트(사용자)에 대한 응답을 위해 ACK + SYN를 보내지만 클라이언트는 ACK를 보내지 않고 SYN만 계속 보내므로 새로운 연결 요청만 있을 뿐 할당 된 자원은 해지 되지 않으므로 자원 고갈이 되는 것이다. 

요약: 

-  공격자가 서버에 수용 가능한 수에 SYN 패킷을 보냄 -> 공격자는 ACK를 보내지 않고 계속 새로운 연결 요청을 하는 SYN 패킷을 서버에 요청 -> 서버가 자원 할당 해지 X -> 자원 소비 -> 고갈 -> 다른 사용자 서버가 사용 불가능

 

SYN Flooding 대응 반응

1. Backlog Queue를 늘려준다.

2. Syncookie 기능을 활성화 해준다.

3. TCP 연결 타임아웃을 짧게 하여 연결 요청에 대한 대기 시간을 줄여 준다. 

 

Backlog Queue

스택과 큐 할때 그 큐이다. 백로그를 저장할 때 큐 구조로 저장하게 된다. 만약 스택과 큐를 처음 듣는 다면 프링글스 통을 생각해 보자. 프링글스에 감자칩을 담을 때 먼저 담은 감자칩은 제일 마지막에 나오게 된다. 반면 큐는 휴지심과 같은 구조이다. 이 휴지심 한쪽 구멍에 넣은 것은 반대쪽으로 바로 나온다. 즉 먼저 넣은 것이 먼저 나오고 마지막에 넣은 것은 마지막에 나온다(선입선출).  

우선 백로그 큐에는 구조적으로 두 개의 큐가 존재한다. 하나는 SYN큐(SYN Backlog), 다른 하나는 Accept 큐(Listen Backlog)이다. 

SYN 큐는 수신한 SYN큐를 저장하게 된다. 이때 서버는 클라이언트가 요청을 받았다는 의미의 ACK 패킷을 보낼 때까지 큐에 저장해 두고 ACK 응답으로 인해 연결이 되면 SYN 큐에서 제거한 뒤 Accept 큐에 추가 하게 된다. 그렇기 때문에 만약 Backlog Queue를 늘려준 다면 SYN Flooding 공격에서 보내온 SYN 패킷을 수용하여 저장하게 되는 것이다. 

하지만 굳이 공격에 쓰인 SYN 패킷을 저장하는 것은 비효율 적이다. 따라서 백로그 큐를 지나치게 크게 하는 것은 그리 좋은 방법이 아니다.

 

Syncookie

  SYN Flooding 공격에 대응하는 방법 중 하나이다. 평소에는 정상적으로 동작하다가 SYN Flooding 공격이라 생각되는 시점에(SYN 백로그가 가득찰 때) Syncookie 기능이 활성화 된다. 이때는 클라이언트가 보내온 SYN를 SYN 큐에 저장하지 않는다. SYN 큐가 가득 차지 않기 때문에 정상적인 통신이 가능하게 되는 것이다.

  ISN이라고 하는 것은 '초기 순서번호'라고도 부르는데 랜덤 수를 상대방에게 전송하는 것을 말한다. 클라이언트가 보내온 SYN에 대해 서버는 SYN + ACK를 보낼 때 ISN을 만들어 보낸다. 이때 클라이언트가 보내온 ACK에 자신이 보냈던 랜덤 수를 Sequence Number로 부터 추출해서 그 값이 맞는지 확인하게 된다. 정상적인 클라이언트와 패킷이 맞다면 위에서 설명한 Accept 큐에 넘기게 된다. 

  이 방법 또한 단점이 존재할 수 있는데 Syncookie를 만들어 보내고 그 값을 검증하면서 느려질 수 있다. 하지만 정상적인 통신을 위해 이 방법이 사용되기도 한다.

 

 

 

참고 사이트 : 

 

tcp_syncookies는 어떻게 동작하는가?

Linux Network Internal | 오늘 다룰 내용은  tcp_syncookies입니다. 조금은 어렵고 복잡한 이야기를 다룰  예정이고요, 아마도 제가 잘못 조사한 내용이 있을 수도 있으니 잘못된 부분이 있으면 댓글로 알

brunch.co.kr

 

느낀점 : SYN를 얼마나 많이 차고 넘치도록 보내 주길레 flooding이라는 단어를 쓸까.. 하는 생각이 들었다. 세상은 넓고 공부할 것과 읽을 것은 많다. 말로 표현되지 않으면 모르는 것과 같은것 같다. 더욱더 열심히 공부해서 언젠가 내가 아는 지식으로 강의 해보고 싶다.

 

728x90
반응형

댓글