Wins Security Information

보안 정보

앞 내용 보기 다음 내용 보기
취약점 정보[CVE-2017-3737] OpenSSL Error State 정보 유출 취약점
작성일 2018-03-08 조회 2368

 

 

 

 

이 취약점은 핸드 셰이크 중에 치명적인 오류가 발생한 후 응용 프로그램이 SSL_read () 또는 SSL_write ()를 잘못 호출 할 때 발생합니다. 
라이브러리가 응용 프로그램 계층에 암호화 또는 암호 해독없이 원시 데이터를 잘못 반환합니다.

 

원격 공격자는 취약한 버전의 OpenSSL 라이브러리를 잘못 사용하는 응용 프로그램에서이 취약점을 악용 할 수 있습니다. 


공격의 난이도가 높고, 실제 해당 취약점이 적용되는 사이트가 적어 공격으로 이어질 가능성은 높지 않습니다.
이 취약점을 성공적으로 악용하면 정보 유출로 이어질 수 있습니다.

 

 


► 공격 시나리오

 

1)취약한 SSL 클라이언트 또는 원격 SSL 서버를 암호화하지 않고 암호화 되지 않은 응용 프로그램 데이터를 보내도록 악용
2)SSL 핸드 쉐이크 중에 SSL_read 또는 SSL_write 함수가 "오류 상태(Error State)"를 처리 할 때 오류로 인해 발생
OpenSSL 1.0.2m ssl/s3_pkt.c:
3)"오류 상태(Error State)"는 OpenSSL 버전 1.0.2b부터 도입
4)"오류 상태(Error State)"는 SSL 핸드 셰이크가 계속되면 치명적인 오류가 발생하여 SSL 핸드 셰이크가 실패 할 때마다 OpenSSL을 오류 상태로 전환시키는 데 사용
5)SSL_read 또는 SSL_write 함수가 직접 호출되면 핸드 셰이크가 시작되지 않은 경우 SSL 핸드 셰이크 상태를 확인하고 새 SSL 핸드 셰이크를 자동으로 수행
6)SSL 핸드 셰이크 중에 치명적인 오류가 발생하면 OpenSSL은 "오류 상태(Error State)" 메시지를 호출자에게 반환
7)호출자가 오류 상태를 확인하지 않고 단순히 SSL_read 또는 SSL_write 함수를 다시 호출하면 문제가 발생
8)암호화없이 응용 프로그램 데이터를 전송 (SSL/TLS 레코드 계층 에서 직접 해독/암호화되지 않고 전달)

 

해당 취약점은 CVE-2017-3736, CVE-2017-3732 , CVE-2015-3193과 유사합니다.
OpenSSL 1.1.0h 버전을 설치해 패치가 가능합니다.

 

 

 

► 취약 버전

OpenSSL Project OpenSSL prior to 1.0.2n

 

 

 

► 위험도

Base 5.8 (AV:N/AC:M/Au:N/C:P/I:P/A:N)

 

 

 

► Code Sniffet

(1) ssl3_write_bytes ()는 SSL_write 함수에 의해 호출되어 응용 프로그램 데이터를 전송합니다. 필요한 경우 SSL 핸드 셰이크 상태를 확인하고 SSL 핸드 셰이크를 수행합니다.
638     int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
639     {
640         const unsigned char *buf = buf_;
641         int tot;
642         unsigned int n, nw;
643     #if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
644         unsigned int max_send_fragment;
645     #endif
646         SSL3_BUFFER *wb = &(s->s3->wbuf);
647         int i;
648     
649         s->rwstate = SSL_NOTHING;
650         OPENSSL_assert(s->s3->wnum <= INT_MAX);
651         tot = s->s3->wnum;
652         s->s3->wnum = 0;
653     
654         if (SSL_in_init(s) && !s->in_handshake) { //checks to see if the SSL handshake state is initiated. The state will be SSL_ST_INIT the first time.
655             i = s->handshake_func(s);  //performs a new SSL handshake if no handshake has been initiated.
656             if (i < 0)
657                 return (i);
658             if (i == 0) {
659                 SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
660                 return -1;
661             }
662         }

 

(2) 테스트 중에 취약한 SSL 클라이언트를 대상으로 사용했습니다. SSL 핸드 셰이크 중 공격자가 제어하는 SSL 서버에서 조작 된 서버 hello 메시지를 받았습니다. 이 서버 hello 메시지를 처리하기 위해 ssl3_get_server_hello ()가 호출되고 치명적인 오류가 발생하여 OpenSSL이 s-> state를 SSL_ST_INIT에서 SSL_ST_ERR로 설정하여 오류 상태로 이동합니다.
OpenSSL 1.0.2m ssl/s3_clnt.c:
898     int ssl3_get_server_hello(SSL *s)
899     {
900         STACK_OF(SSL_CIPHER) *sk;
901         const SSL_CIPHER *c;
902         CERT *ct = s->cert;
903         unsigned char *p, *d;
904         int i, al = SSL_AD_INTERNAL_ERROR, ok;
....
1077        if (i < 0) {
1078            /* we did not say we would use this cipher */
1079            al = SSL_AD_ILLEGAL_PARAMETER;
1080            SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
1081            goto f_err;  //a fatal error occurs
1082        }
....
1170     f_err:
1171        ssl3_send_alert(s, SSL3_AL_FATAL, al); //sends an SSL alert packet
1172     err:
1173        s->state = SSL_ST_ERR; //moves into an error state
1174        return (-1);
1175    }

 

(3) 취약한 SSL 클라이언트가 오류 상태를 확인하지 않고 SSL_write 함수를 호출하여 응용 프로그램 데이터를 다시 보내면 ssl3_write_bytes ()가 호출되고 SSL_in_init ()을 사용하여 핸드 셰이크 상태를 다시 확인합니다.
OpenSSL 1.0.2m ssl/s3_pkt.c:
638     int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
639     {
640         const unsigned char *buf = buf_;
641         int tot;
642         unsigned int n, nw;
643     #if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
644         unsigned int max_send_fragment;
645     #endif
646         SSL3_BUFFER *wb = &(s->s3->wbuf);
647         int i;
648     
649         s->rwstate = SSL_NOTHING;
650         OPENSSL_assert(s->s3->wnum <= INT_MAX);
651         tot = s->s3->wnum;
652         s->s3->wnum = 0;
653     
654         if (SSL_in_init(s) && !s->in_handshake) { // SSL_in_init is called again to check the state

 

(4) 이번에 검사가 실패하면 SSL 핸드 셰이크가 무시되고 응용 프로그램 데이터가 암호화없이 전송됩니다.
include/openssl/ssl.h:1749
    # define SSL_in_init(a)                  (SSL_state(a)&SSL_ST_INIT) //s->state is now SSL_ST_ERR, and check returns are false.

 

(5) 이 공격 중에 공격자는 취약한 SSL 클라이언트가 악의적 인 SSL 서버에 연결하도록 유도합니다. 
SSL 클라이언트는 핸드 셰이크 프로세스를 생략하고 암호화없이 응용 프로그램 데이터를 보낼 수 있습니다. 
SSL_read 또는 SSL_write 함수를 직접 호출하면 SSL 서버에서도 동일한 취약점이 발생할 수 있습니다.
참고 : 인증은 이 취약점을 악용 할 필요가 없습니다

 

 

 

► Sniper 제품군 대응방안

Sniper-IPS 

[4123] OpenSSL Handshake Error State Information Disclosure

Sniper-UTM

[805374457]OpenSSL Handshake Error State Information Disclosure

 

 

 

► 참조사이트

첨부파일 첨부파일이 없습니다.
태그   CVE-2017-3737  OpenSSL Error State