MS09-019 pwn2own 취약점 분석
이 글은 MS SRD 블로그의 MS09-019 (CVE-2009-1532): The "pwn2own" vulnerability를 번역한 것입니다.
MS09-019 업데이트는 CanSecWest pwn2own 대회에서 Nils가 공개한 IE8 취약점에 대한 패치를 담고 있습니다.
Nils는 인터넷 영역에 닷넷 어셈블리를 로딩하는 것을 허용하는 IE8 빌드 버전의 취약점을 익스플로잇 했습니다. IE8 최종 릴리스 버전은 닷넷 어셈블리 로딩을 허용하지 않습니다. 닷넷 어셈블리에 관련된 동작이 왜 중요하냐 하면, 이전에 발표된 Dowd/Sotirov ASLR+DEP 우회 기법에서 올바른 페이지 권한으로 알려진 위치에 정확하게 쉘코드를 박아넣는데 닷넷을 이용하고 있기 때문입니다.
비스타 이상의 버전에서 이 취약점이 실제로 공격당하지는 않을 것으로 예상됩니다. 첫번째로 IE8 릴리스 빌드 버전은 인터넷 영역으로부터 닷넷 어셈블리를 읽어오지 못하도록 하고 있으며, 두번째로, IE8은 DEP가 기본적으로 활성화되어 있기 때문입니다.
IE8의 다른 영역도 닷넷 어셈블리의 로딩 동작을 변경할 수 있습니다. 기본적으로 인터넷 영역은 닷넷 어셈블리 로딩을 허용하지 않지만, 인트라넷 영역은 허용합니다. 인트라넷 영역에서도 닷넷 어셈블리를 비활성화하려면 아래의 레지스트리 키를 3으로 바꾸시면 됩니다.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1\2005
인터넷 영역에서 닷넷 어셈블리를 로딩할 수 있도록 허용하려면, 레지스트리 키를 0으로 바꾸시면 됩니다.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\2005
만약 인터넷 영역에서 닷넷 어셈블리를 로딩할 수 있도록 허용한다면, 가급적 외부 공격에 오래 노출되지 않도록 하시기 바랍니다. 여러분의 응용 프로그램이 인터넷 영역에서 닷넷을 읽어와야 할 필요가 있다면, ClickOnce 배포 방식이나 WPF 기반으로 응용 프로그램을 변경하실 것을 권고합니다.
이번 취약점의 근본 원인은 개체를 삭제한 이후에도 사용하려고 시도한 것입니다. (EIP가 힙을 가리키게 됩니다.) 오류 코드를 제대로 점검하지 않았기 때문에 이미 해제된 개체를 호출하게 됩니다.
구체적으로 어떻게 취약점이 발생했는지 아래 코드를 살펴보겠습니다.
HRESULT CElementCollectionBase::VersionedGetDispID(BSTR bstrName, DWORD grfdex, __out DISPID *pdispidMember, __in IUnknown *pUnkContext, OMVersion version, OMVersionFlag versionFlags, __in PFNGETDISPID *pfnTearoffGetDispID)
{
HRESULT hr = S_OK;
if (!SecurityContextAllowsAccess())
return E_ACCESSDENIED;
// hr은 여러가지 이유로 개체가 사용할 수 없는 상태가 되었기 때문에 FALSE가 됩니다.
hr = THR(_pCollectionCache->EnsureAry(_lIndex));
// S_FALSE는 1이고 FALSE는 0인데,
if (hr) // 여기서 S_FALSE가 1인지 확인하기 때문에
goto Cleanup; // Cleanup으로 뛰지 않고 계속 진행하게 됩니다.
hr = DispatchGetDispIDCollection(this,
NULL,
_pCollectionCache,
_lIndex,
bstrName,
grfdex,
pdispidMember);
// we pass in NULL to the above and then handle this ourselves in a versioned fashion.
if ( hr || (!hr && *pdispidMember == DISPID_UNKNOWN) )
{
hr = super::VersionedGetDispID(bstrName, grfdex, pdispidMember, pUnkContext, version, versionFlags, NULL);
}
Cleanup:
RRETURN(hr);
}
IE7은 개체가 사용 불가능한 상황일 때 FALSE (0)가 아닌 S_FALSE (1)을 반환하게 되어 있습니다. 따라서 IE7의 경우에는 제대로 Cleanup 코드로 건너뛰게 되므로 아무런 문제가 없습니다.
이렇게 S_FALSE와 FALSE를 혼용해서 쓰는 경우 취약점이 발생할 수 있는데, 이번에 이런 취약점들을 분석할 수 있는 정적 분석 도구를 개발했습니다. 이후 다른 제품들을 개발할 때는 보안 테스트 단계에서 이 분석 도구를 활용할 것이므로 다시는 이런 실수가 발생하지 않을 것입니다.
by xeraph | 2009-06-30 13:53:09 | 미분류 | 트랙백 (1) | 덧글 (0)
Tracked from nchovy's me2DAY 2009-06-30 14:13:58
MS09-019 pwn2own 취약점 분석




