본문으로 바로가기



안녕하세요, SATAz입니다.

이번 포스팅은 DOS/DDOS 공격 방식 중에서, Flooding 공격에 대해서 알아보려고 합니다.


IPTables를 이용해서 DDOS를 방어하는 방법을 포스팅 하기 전에, SYN Flooding 공격 방법에 대해서 설명드리려고 합니다.

공격 방법을 알아야지 방어 방법도 이해할 수가 있기 때문에, 이번 포스팅을 기획했습니다.



1. TCP vs UDP ?

UDP(User Datagram Protocol)와는 다르게, TCP(Transmission Control Protocol)는 연결의 신뢰성을 가진다는 장점이 있습니다.


UDP(사용자 데이터그램 프로토콜) : 어떠한 협상과정 없이 메시지를 실어서 보내기만 하고 받았는지 안받았는지는 신경쓰지 않습니다.

TCP(전송 제어 프로토콜) : 메시지를 보내기 전에, 3-way-handshake 과정을 통해서 메시지를 정상적으로 전달할 수 있는지 확인을 합니다.


연결을 확인하고 데이터를 보낸다는 점에서 TCP에게 신뢰성이라는 장점이 주어지는 것이죠.



2. "3-way-handshake"을 알아야, SYN Flooding 공격을 이해할 수 있다.

TCP는 세 차례의 패킷들을 주고받는 과정을 거쳐야만 TCP 연결(connection)이 성립(establish)됩니다. 패킷을 주고 받는 내용들은 아래와 같습니다.

① Client는 SYN 패킷(sequence number 포함)을 생성해서, Server에게 전달합니다. 일종의, "포트 열려있나요?" 라고 문을 두드리는 과정이라고 보면 됩니다.

② Server는 SYN 패킷(sequence number 포함)과 받은 SYN의 대답 격인 ACK 패킷(acknowledgement number 포함)을 Client에게 전달합니다. 그리고 Server는 Client의 접속을 받아들이기 위해, RAM(메모리)에 일정 공간을 확보해둡니다.

일종의, "네, 열려있습니다." 라고 대답하는 과정이라고 보면 되며, acknowledgement number의 값은, 방금 받은 SYN 패킷의 sequence number 값에 일정 값을 증가시켜서 보냅니다.

③ 그리고 다시 Client는 방금 받은 SYN의 대답 격인 ACK 패킷(acknowledgement number 포함)을 Server에게 전달합니다. 일종의, "그럼 들어가겠습니다~" 라고 대답하는 과정이라고 보시면 됩니다. 여기서도 마찬가지로 acknowledgement number의 값은, 방금 받은 SYN 패킷의 sequence number 값에 일정 값을 증가시켜서 보냅니다.


이렇게 Client는 Server에 Established 상태로 연결이 됩니다.

위 세 차례의 패킷을 주고 받는 과정은 일련의 협상을 타결하여 악수하는 모습과 같아서, 3-way-handshake(악수) 라는 이름을 사용하고 있습니다.


*참고 : 연결을 끊을 때에는 4-way-handshake 라는 방식으로 끊습니다.




3. SYN Flooding 공격은 무엇인가?

SYN Flooding은, 위 3-way-handshake의 ②번 과정에서 언급했던 내용에 집중하셔야 합니다.

"② Server는 SYN 패킷과 ACK 패킷을 Client에게 전달합니다. 그리고 Server는 Client의 접속을 받아들이기 위해, RAM(메모리)에 일정 공간을 확보해둡니다."

Client가 ①SYN 패킷만을 계속적으로 보내고 ③ACK 패킷을 안보내게 되면, Server는 Client의 연결을 받아들이기 위해 RAM(메모리) 공간을 점점 더 많이 확보해둔 상태에서 대기합니다.

그리고 Server의 RAM이 꽉 차게 되면 더이상 연결을 받아들일 수 없게되고, Server는 서비스를 서비스를 계속할 수가 없게 되죠.


3. SYN Flooding을 방어하는 방법은?

3-1. SYN Cookie

방화벽 단에서 SYN을 먼저 받고, SYN Cookie를 포함한 SYN+ACK를 보내는 방법이 있습니다. 일정 시간동안 SYN Cookie에 대한 정상적인 응답패킷이 들어오지 않으면 방화벽에서 차단해버리고, 정상적인 패킷이 들어오면 통신이 가능하게끔 해주는 방식이죠.

정상적인 패킷이 들어왔을 경우에는 아래와 같은 순서로 진행됩니다.


*용어 설명

 : SYN_C1 - SYN패킷/Client에서 생성됨/1번째 3-way-handshake

 : SYN_F1 - SYN패킷/Firewall에서 생성됨/1번째 3-way-handshake

 : ACK_F1 - ACK패킷/Firewall에서 생성됨/1번째 3-way-handshake

...


C는 Client에서 생성, F는 Firewall에서 생성, S는 Server에서 생성, 숫자는 몇번째 3-way-handshake 인지를 나타냅니다.

1) SYN이 들어오면, syn_cookie가 포함된 SYN+ACK을 보냅니다. 

2) 그리고 syn_cookie에 적절히 대응하는 정상적인 ACK 패킷이 들어오면, 세션을 새로 엽니다.


즉, 처음 방화벽과 3-way-handshake가 이루어진 것은 없는 셈 치고, 방화벽은 새로운 3-way-handshake 패킷을 서버에 연결시켜주는 것이죠.

따라서 Client는 첫 접속에 실패하는 것 처럼 보일 수도 있습니다. (Client의 재접속 요청은 순식간에 이루어지기 때문에, 사용자로서 체감상으로 느낄 수는 없을 것입니다)



3-1. SYN PROXY

방화벽 단에서 정상적인 3-way-handshake과정이 이루어지면, 그 연결을 다시 서버에게 재현시켜주는 방식입니다.입니다.

3-way-handshake 연결이 이루어지지 않은 경우에는 방화벽에서 쳐냅니다.(차단합니다)

SYN PROXY도 역시, syn_cookie를 이용해서 정상적인 3-way-handshake인지를 확인합니다.

syn_proxy는 세션을 새로 열 필요가 없습니다. client와 firewall 사이에 맺은 3-way-handshake를 firewall이 server에게 다시 재현해주기 때문에, 세션을 새로 맺을 필요가 없습니다.

Proxy Server를 중간에 하나 둔다고 생각하시면 편하지 않을까 합니다.



이 것으로, SYN Flooding 공격에 대해서 알아보았습니다.

다음 포스팅은 iptables를 이용하여, SYN Proxy를 구현하여 DDOS를 방어해보도록 하겠습니다.




댓글을 달아 주세요