|
[CVE-2017-7546] PostgreSQL non-libpq Client Policy 침해사고분석팀 2017.09.01 |
|
개요PostgreSQL Database에 보안 우회 취약점이 존재한다. 해당 취약점은 libpq를 사용하지 않는 사용자 계정에 빈 패스워드가 있는 경우를 제대로 검증하지 않아 발생한다. [CVE 정보]
CVE-2017-7546
[취약한 버전]
PostgreSQL PostgreSQL 9.6.x prior to 9.6.4
PostgreSQL PostgreSQL 9.5.x prior to 9.5.8 PostgreSQL PostgreSQL 9.4.x prior to 9.4.13 PostgreSQL PostgreSQL 9.3.x prior to 9.3.18 PostgreSQL PostgreSQL 9.2.x prior to 9.2.22 [취약한 함수]
md5_crypt_verify()
확인 내역해당 취약점은 사용자 계정에 빈 패스워드가 존재함으로 발생한다. 이를 확인 하기 위해선, PostgreSQL 통신 절차를 살펴 볼 필요가 있다.
1. Client -> Server : Startup Message
먼저, PostgreSQL 세션을 맺기 위해선 클라이언트에서 Startup Message를 보냄으로 세션이 처음 시작되게 된다. Startup Message 구조 및 예제는 다음과 같다.
[Startup Message]
Offset Length Description (Bytes) (Bytes) -------------------------------------- 0x00 0x04 Length 0x04 0x04 Protocol Version 0x08 N Parameter1 Name 0x08+N 0x01 Delimiter (0x00) 0x08+N+1 M Parameter1 Value 0x08+N+M+1 0x01 Delimiter, (0x00) ... ... ... Length-1 0x01 Final Delimiter (0x00) [예제] x00x00x00x00 x00x03x00x00 userx00example_userx00 databasex00example_databasex00 application_namex00psqlx00 client_encodingx00UTF8x00x00 Startup Message 바로 뒤에 나오는 Message 구조는 다음과 같다.
[Subsequent Message]
Offset Length Description (Bytes) (Bytes) -------------------------------------- 0x00 0x01 Message Type 0x01 0x04 Message Length 0x05 N Message Contents 2. Server -> Client : Authentication Request Message
Startup Message 를 받은 서버에서는 Authentication Request Message를 클라이언트에 보내게 된다.
[Authentication Request Message]
Offset Length Description (Bytes) (Bytes) -------------------------------------- 0x00 0x01 0x52 ("R") 0x01 0x04 Message Length 0x05 0x04 Authentication Method 0x09 N Additional Parameters (optional) 여기에서 Authentication Method 필드는 클라이언트를 인증하기 위해 사용되는 것으로, 이번 취약점과 관련된 Method는 2가지가 존재한다.
1) Plaintext password(0x00000003) 2) MD5 password (0x00000005)
Authentication Method가 MD5 password로 설정 된 경우, Additional Parameters 필드에 무작위로 생성된 4byte salt 값이 포함 된다.
3. Client -> Server : Password Message
Authentication Request 메시지를 받은 클라이언트는, 이에 해당하는 Response Message를 보내게 된다. 여기에서 Method 필드가 위에서 설명한 2개 중 하나가 설정 되어 있는 경우 응답 메시지로 Password Message를 보내게 된다.
[Password Message]
Offset Length Description (Bytes) (Bytes) -------------------------------------- 0x00 0x01 0x70 ("p") 0x01 0x04 Message Length 0x05 N Passowrd 0x05+N 0x01 Delimiter (0x00) Password 필드 값은 클라이언트의 plaintext password 또는 이전에 전송 된 salt 값, 사용자 이름, 사용자 비밀번호를 사용하여 계산 된 MD5 hash 값으로 구성된다.
여기에서 MD5 hash 값을 구하는 계산 절차는 다음과 같다.
initial_hash = md5(password + username).hexdigest()
final_hash = 'md5' + md5(initial_hash + salt).hexdigest() 통신 절차를 확인 하였으므로, 이제 실제로 공격 패킷을 통해 취약점이 어떻게 발생하는지 살펴보도록 하자.
공격 예시는 Plain Text password의 경우에 대해서만 살펴보도록 하겠다.
![]() [그림1] Plain Text Password의 경우
위 패킷의 파란색 부분을 Password Message 구조에 맞춰서 작성해보면 다음과 같다.
x70
x00x00x00x05 x00 여기에서 우리는 패스워드 값이 설정되어 있지 않는 것을 확인 할 수 있다.
대응방안해당 벤더사에서 제공한 보안 권고문을 참고하여, 취약한 버전에 대해 패치를 진행 한다.
https://www.postgresql.org/about/news/1772/
참고https://www.postgresql.org/about/news/1772/ http://www.securityfocus.com/bid/100278 http://securitytracker.com/id?1039142 |
