※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


회사에서 업무하다가 갑자기 Slowloris DoS 공격 툴 이야기가 나왔다. perl 스크립트로 짜여져있다고 하는데 전체적으로 코드 생김새를 보니까 조금만 하면 분석할 수 있을 것 같다는 생각이 들어서 한번 분석해봤다. perl 스크립트를 시작하는 좋은 연습이 되겠다!!


우선 Slowloris에 대한 wikipedia 검색 결과를 보자.

Slowloris is a piece of software written by Robert "RSnake" Hansen which allows a single machine to take down another machine's web server with minimal bandwidth and side effects on unrelated services and ports.[1]

Slowloris tries to keep many connections to the target web server open and hold them open as long as possible. It accomplishes this by opening connections to the target web server and sending a partial request. Periodically, it will send subsequent HTTP headers, adding to—but never completing—the request. Affected servers will keep these connections open, filling their maximum concurrent connection pool, eventually denying additional connection attempts from clients.

출처 : http://en.wikipedia.org/wiki/Slowloris


위에서 언급했듯이 Slowloris perl 스크립트로 작성된 HTTP/HTTPS DoS 공격 툴이다. 다른 DoS 툴과 두드러진Slowloris만의 특징은 최소한의 자원으로 DoS를 수행한다는 점이다. , 해당 툴을 사용했을 경우 일반 DoS 증상처럼 다수의 트래픽이 탐지되거나 혹은 트래픽 양이 순간적으로 급증하지는 않는다. 그렇지만 각각의 Connection을 오래 유지하고 있으므로써 최종적으로 웹서버가 다룰 수 있는 최대한의 Connection 개수를 초과하여 DoS 공격을 성공시킨다.

 

Slowloris의 여러가지 옵션을 통해 다양하게 사용할 수 있다. Slowloris에서 사용할 수 있는 옵션은 아래와 같다.


Slowloris은 아래와 같은 방법으로 사용할 수 있다.


예시./slowloris.pl -dns www.example.com -port 443 -timeout 30 -num 500 –https


위의 공격은 www.example.com이라는 443포트를 사용하는 서버의 timeout 30초로 변경하여 매 30초마다 500개의 패킷을 보낸다는 뜻이다.


우선 전체적인 프로그램의 구조를 살펴본 후 조금 더 상세하게 분석해볼 생각이다. 사용하는 변수와 전체적인 스크립트의 흐름은 아래와 같다.

 

## 프로그램에서 사용될 변수 선언


위의 그림을 보면 스크립트 수행 시 사용될 옵션명과 그 옵션을 스크립트 내에서 접근할 변수명이 GetOptions{};에 모두 정의되어있다. 그 밑에 있는 unless문은 사용자가 스크립트를 수행할 때 옵션을 명시하지 않을 경우 해당 옵션들이 설정되는 기본값이다. 실제 수행되는 스크립트는 아래의 구조로 되어있다.

 

## 스크립트 수행 부분

위의 구문 중 if($test)부분은 실제로 test 용이다. Slowloris 스크립트 수행 시 test를 수행하고 싶을 때 test옵션을 넣을 수 있는데 그 때 if($test)부분으로 들어간다. else문은 multithread 가능여부에 따라 가능하면 domultithreading 함수 콜을 하고 그렇지 않으면 doconnections 수행한다.

 

살짝 집고 넘어가자 test 옵션이 있을 경우와 그렇지 않을 경우의 가장 큰 차이는 생성되는 소켓의 개수이다. Test 옵션이 있을 경우는 한 개만 생성해서 말 그대로 test 용도로 패킷을 만들어 보내는 것이고 test 옵션이 없을 경우는 실제로 다량의 소켓을 생성해서 다량의 패킷을 보내서 DoS 공격을 수행하게 된다.

 

전체적으로 구조를 보았으니 else문에서 수행되는 doconnections domultithreading 함수를 자세하게 분석해보면 아래와 같다.

 

## doconnections


위의 코드에서 두 개의 foreach문을 볼 수 있다. 두번째 foreach문에서 하는 역할은 정확히 말하면 아래와 같다.

두번째 foreach문에서는 print $handle “X-a; b\r\n” 함수를 if문 안에서 수행한다. 그렇다면 첫번째 foreach문에서 만든 패킷을 알아보자. 아래와 같다.

my $primarypaload = … 에서 볼 수 있지만, Content-Length: 42\r\n후에 \r\n가 한 개 더 있어야 하는데 없다. 게다가 두 번째 foreach문에 의해 헤더 요청이 엉뚱하게 X-a: b \r\n과 같이 들어오게 된다. 이 부분은 Slowloris 공격툴의 많은 특성을 보여주는데 이 내용은 조금 후에 다룰 예정이다.

 

## domultithreading

$num보다 작을 때까지 지속적으로 Thread를 생성하는 간단한 코드이다. 전체적으로 동작방식은 doconnections함수와 비슷하다. 실제로 threads->create로 생성하는 thead 역시 doconnections이다.


위에서 언급했듯이, Slowloris는 최소한의 트래픽으로 DoS 공격을 수행한다. 또한 단 한대의 PC만 있으면 언제든지 공격이 가능하다.


위에서 분석한 Slowloris 소스 코드의 특징을 한 마디로 정리하면, 사용자가 원하는 개수의 connection을 최대한 오래 지속시키거나 한계치를 초과시켜서 서버를 다운시키는 공격이 된다. 아래의 코드에서 확인할 수 있다.

위 그림에서 아래부분을 보면 my $primarypayload에서 전송할 패킷을 소켓에 write하는 과정에서 찾아볼 수 있다. 위와 같이 전송되면 생성된 소켓마다 아래와 같은 payload가 생성될 것이다.


GET / HTTP/1.1\r\n

Host: $sendhost\r\n

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)\r\n

Content-Length: 42\r\n


\r\n CRLF에서 LF Line Feed이다. 이는 헤더의 line terminator이다.  HTTP 헤더 같은 경우 헤더를 끝낼 때 LF 두 개가 연속으로 나오는 \r\n\r\n과 같은 문자열이 있어야 헤더를 끝낼 수 있다위의 예시를 보면 Slowloris가 작성하고 있는 헤더는 LF가 하나 부족한 것을 알 수 있다. 절대 두 개 연속의 LF를 생성하여 헤더 작성을 끝내지 않는다.


위와 같이 패킷을 작성한 후 open되어있는 각각의 소켓에 X-a: b\r\n와 같은 비정상적인 헤더를 write하게 된다. 이 때 역시 LF는 하나만 작성하여 connection을 지속적으로 열어놓는다.이제 다시 doconenction 함수의 전체적인 구조를 보자.

소켓을 생성하고 전송하는 두 개의 foreach문이 while(1)이라는 무한 루프 안에 있는 것을 확인할 수 있다. , 사용자가 강제로 종료하기 전까지는 멈추지 않고 소켓을 생성하여 불완전한 헤더를 요청하고 서버로 하여금 connection open하게 만든다. 이와 같은 방법으로 공격을 하면 유입되는 이벤트의 양은 그다지 많지 않을 수 있다. 왜냐하면 foreach문의 내용을 보면 소켓이 생성되어 있지 않는 경우에만 소켓을 생성하는 특정 작업이 수행되기 때문에 이미 생성되어 있는 소켓에 대한 추가적인 작업은 없다.

 

Slowloris의 또 하나의 특징은 공격이 실패하기 전까지는 웹서버가 로그를 남기지 못 한다는 것이다. Connection이 지속적으로 열려있게 되기 때문에 서버입장에서는 로그를 남기고 싶어도 남길 수가 없다.


이러한 공격은 어떻게 탐지할 수 있을까? 


일반적으로 X-a: b \r\n 문자열을 탐지하여 Slowloris 공격툴 사용 여부를 탐지하곤 한다. 하지만 개인적으로 잘못된 방법이라고 생각한다. Slowloris는 개인 PC에서도 얼마든지 간단하게 돌아가는 스크립트 툴이기 때문에 X-a: b \r\n은 얼마든지 바꿔서 공격을 시도할 수 있다. 게다가 Slowloris 공격은 웹서버의 자원을 많이 사용하여 다운시키는 유형이 아니기 때문에 트래픽으로 탐지하는 것도 바람직한 방법은 아니다.

 

해당 스크립트는 Layer7을 기반으로 동작하는 스크립트 툴이기 때문에 Layer7과 그 이하의 어느정도 방어가 가능하다. 가장 대표적으로 할 수 있는 것은 웹서버의 설정 값 중에서 Timeout 값을 적절하게 설정하는 것이다. 또한 iptable에서 하나의 출발지 IP connection 개수를 제한하는 방법도 가능하다. (L3 단에서의 방어)


진짜 오랜만에 포스팅을 했다. 내가 게을러서라기보다는 올릴만한 성과물이 없었다. 사실 위에 분석해놓은 Slowloris는 진작에 해놨던 것인데 이제서야 써서 올리는 것이다. 그렇게 따지면 포스팅이 오랜만에 올라온 것이 나의 게으름일 수도 있겠다. 사실 근 1달간 커널과 exploitation 공부로 싸우고 있었다. 아직 해결하지 못 한 구석구석이 많다. exploit 진짜 재밌더라. 그래서 내가 Maybe 인원들에게 제안을 했지... exploit 공부해보자고. 모두들 쿨하게 OK 해서 공부를 하려고 하는데 아직 적당한 방법이 떠오르지 않는다. 내일쯤 관련해서 확실하게 연락해보고 의견받아보고 해야겠다.


기존의 블로그를 보면 어딘가에 앞으로 커널에 관한 포스팅이 많이 올라올 것이라는 이야기가 있을 것이다. 반만 듣고 반은 흘려보내주셔라. exploit 공부하고 포스팅할지도 모를 것 같다. 아무튼 다음 포스팅까지 안녕히...

'Vulnerability' 카테고리의 다른 글

[Vul] CVE-2012-1823 Vulnerability  (1) 2014.01.21
[Vul] Shellcode Execution  (4) 2013.12.30
[Vul] Format String Vulnerability  (1) 2013.11.23
[Vul] DEDECMS SQL Injection  (1) 2013.08.12
시작하며...  (0) 2013.08.12
Posted by 빛나유
,