Skip to content

Latest commit

 

History

History
77 lines (46 loc) · 2.73 KB

MS17-010.md

File metadata and controls

77 lines (46 loc) · 2.73 KB

MS17-010

1. 개요

MS17-010 취약점은 EternalBlue에 사용된 취약점으로, Windows SMBv1 서버가 특정한 리퀘스트를 처리할 때의 결함을 바탕으로 동작한다.

2. 취약점 설명

File Extended Attributes(FEA)를 처리하는 과정에서 잘못된 처리로 인해 Non-Paged Pool Memory에서 Buffer Overflow가 발생할 수 있다. 취약한 함수는 Srv.sys 드라이버 내부의 kernel function이다.

  1. SrvOs2FeaListSizeToNt()가 FEA List size를 계산하여 받은 FEA List size를 업데이트한다.
  2. 이 때 계산과정에서의 잘못된 WORD cast로 인해 FEA List size는 실제 사이즈보다 크다.
  3. FEA List를 NTFEA List로 변환하기 위해 iteration하는 과정에서, 잘못된 사이즈 측정에 의한 overflow가 발생한다.

3. 취약점 세부

  1. SrvSmbOpen2() 함수 호출

이때 NT trans Request로 보낸 데이터 (이하 IN-DATA)의 실제 size와 함수 실행 결과 변환된 FEA List size를 확인해보면 아래와 같다.

  • IN-DATA size : 000103d0 (66512)
  • FEA List size : 00010000 (65536)
  1. SrvOs2FeaListSizeToNt() 함수 호출됨

IN-DATA size의 크기가 FEA List size의 크기보다 크므로 FEA List size의 크기를 업데이트해야 한다.

이 과정에서 문제가 발생한다.

함수를 pseudo code로 나타내면 아래와 같다.

SrvOs2FeaListSizeToNt(feaList)
{
    outputLen = 0;
    foreach (fea in feaList) {
        if (IsFeaDataOutOfBound(fea, feaList)) {
            (WORD) feaList.SizeOfListInBytes = Pos(fea) - Pos(feaList);
            return outputLen;
        }
        outputLen += GetNtLengthForFea(fea);
    }
    return outputLen;
}

fealist.SizeOfListInBytes 를 업데이트하는 것을 확인할 수 있다. 이 때 fealist의 structure는 다음과 같다.

struct FEALIST {
  FEA list[];
  DWORD SizeOfListInBytes;
}

여기서 잘못된 type casting을 확인할 수 있다. DWORD 크기인 SizeOfListInBytes를 WORD로 캐스팅하였기 때문에 HIDWORD가 변하지 않는다.

따라서 SizeOfListInBytes = 0x0001_0000 이 0x0001_xxxx로 업데이트된다. (의도한 값은 0x0000_xxxx)

한편, outputLen 값은 0x000_xxxx을 기준으로한 NTFEA LIST의 크기가 된다.

  1. SrvOs2FeaToNt() 함수 호출

실제로 FEA List를 NTFEA List로 변환하는 iteration 과정이 수행된다.

이때 allocate된 NTFEA List의 크기보다 FEA List의 크기가 크므로, 오버플로우가 발생한다.

따라서 iteration과정에서 다른 pool, SRVNET.sys에 침범하게 된다.


references

http://blog.trendmicro.com/trendlabs-security-intelligence/ms17-010-eternalblue/

https://github.com/worawit/MS17-010/