Slow Read Attack

아재발자·2024년 6월 3일
1

제가 2018년 1월부터 2021년 9월까지, 총 3년 9개월을 다녔던 회사에서 근무하면서 직접 경험한 내용을 바탕으로 공부하고 알게된 지식을 간단하게 정리하는 글입니다.

아래의 글을 참고하시면 이해하시는데 도움이 됩니다.


Slow Read Attack

참고!
TCP Window Size는 패킷을 전송하는 사람이 보낼 수 있는 최대 Size를 의미합니다.

Slow Read 공격은 HTTP 공격의 일종으로 TCP Window Size 등을 조작하여 서버에게 데이터를 천천히 보내고, 응답을 천천히 읽어 TCP 연결을 지연시키는 공격 기법입니다.

공격자는 TCP Window Size 를 작게 조작하고, 데이터 처리율을 감소시킨 상태에서 HTTP 패킷을 송신하여, 웹 서버가 정상적으로 응답하지 못하게 함으로써 Dos 상태를 유발시킵니다.

공격 대상이 된 서버는 공격자와의 데이터 전송이 완료될 때 까지 Connection 자원을 점유하게 되기 때문에, 대량 발생할 경우 Connection 자원이 고갈되어 장애가 발생합니다.


PHP-FPM과 Slow Read Attack

PHP-FPM 특성 상 Slow Read Attack 공격을 받으면 아래의 문제가 발생하게 됩니다.

  1. 모든 Worker 프로세스가 해당 공격을 처리하기 위해 사용되면서 정상적인 요청을 처리할 수 없는 상태로 만듭니다.
  2. 그리고 외부 서비스와 연결하기 위해 생성된 TCP 소켓으로 인해 LocalPort가 고갈되기 쉽습니다.
    이 과정에서 외부 서비스의 Connection도 점유하여 장애를 전파시킬 수 있습니다.

실제 공격이 들어온 사례

{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 99.557, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 163.487, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (Android 11; Mobile; rv:68.0) Gecko/68.0 Firefox/82.0"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 78.148, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (Android 11; Mobile; rv:68.0) Gecko/68.0 Firefox/82.0"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 91.221, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (Android 11; Mobile; rv:68.0) Gecko/68.0 Firefox/82.0"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 76.058, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_15_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/29.0 Mobile/15E148 Safari/605.1.15"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 85.225, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (iPod; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/86.0.4240.93 Mobile/15E148 Safari/604.1"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 86.266, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (Linux; Android 10; SM-A205U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 124.046, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 163.626, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (iPad; CPU OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/86.0.4240.93 Mobile/15E148 Safari/604.1"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 163.414, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/86.0.4240.93 Mobile/15E148 Safari/604.1"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 126.826, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (iPod touch; CPU iPhone 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1"}
{"time": "2020-11-08T13:31:48+09:00", "request_host": "http://도메인은비공개.com", "request_uri": "http://도메인은비공개.com/", "body_bytes_sent": 0, "request_time": 163.380, "status": 408, "request": "GET / HTTP/1.1", "request_method": "GET", "referrer": "-", "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/86.0.4240.93 Mobile/15E148 Safari/604.1"}
...
profile
안녕하세요. 아재 개발자입니다. 공부한 내용을 기록하고 잘못된 부분에 대해서 조언을 받기 위해 velog를 시작했습니다. :)

0개의 댓글