UEFI 스터디 12차 - 로직 개선하기.
Published:
sink 탐색 로직 개선해보기
기존 로직의 문제
가장 많이 쓰이는 edk2의 gbs -> allocatepool 래퍼함수 allocatepool을 사용할것을 감안. 인자가 하나인 함수에 들어갈 경우 잡도록 하였다.
그러나 이것의 문제는
- 타 edk2 래퍼 함수
- gbs -> allocatepool 서비스
- 벤더 자체의 래퍼함수 를 잡지 못한다.
함수간 오염분석으로 실제 gbs->allocatepool 서비스를 찾아 잡을 수도 있겠지만 대부분이 allocatepool 래퍼함수이라서
(실제 드라이버도 그랬으므로)
패턴 매칭의 케이스 몇개만 추가하면 해결될 듯하여, 이 직감을 믿고 밀고 나가보기로했다.
edk2 함수들 살펴보기
모든 함수마다 cve에서 예시가 있는지 찾기엔 시간이 부족하니, 직접함수들을 보고 문제가 생길만한지 판단해보고, 추후 함수별
예상 못한 취약점 보고서를 마주치게 되는 경우 이를 보완하도록 방향성을 잡도록하자.
일단 인자가 한개인 녀석들은 탐지 가능하니 제외한다.
1. AllocateCopyPool (AllocationSize, *Buffer)
allocationSize크기의 버퍼를 할당후, Buffer의 내용을 복사해오는 방식이다.
CVE의 케이스를 고려하면 Allocationsize는 오염됨(오버플로우나서 매우작은 수) Buffer는 로고 픽셀값과 관련된 정보가 있을 것이라고 생각 가능하다. (allocatepool + 값 대입까지)
만약 Buffer의 끝까지 복사해 가져온다면 바로 메모리가 오염될것이다. 과연 그럴까?
버퍼의 내용을 복사하는 부분까지 함수를 타고 들어가보자.

EDK2의 allocatepool 내부 구현의 함수까지 들어가게되는데,
- Length = 오버플로난 작은 사이즈
- source = Buffer
- dest = 새로할당한 버퍼
근데 오버플로난 작은 길이만큼 값을 복사해오므로 문제는 없다. 즉 메모리 오염은 발생안한다. => 안전!
2. ReallocatePool (OldSize, NewSize, *OldBuffer)
newsize로 버퍼크기를 확장시켜주는 함수다.
그럼 이 함수는 실행 시키기만해도 메모리 오염이 발생할까?
CVE의 케이스 처럼 NewSize에서 오버플로우가 나서 작은값이 있다고하자.

구현 내부를 보면 newsize가 작다고 해도, Oldsize 사이즈로 할당하게 안전장치를 마련해뒀다.
근데 아마 저사이즈로 확장된 버퍼를 마련받았다면, 이미지 관련 데이터를 넣으려 할것.
기존 allocatepool 케이스처럼, 이미지를 넣으면 터진다. => 위험!
3. AllocateAlignedpool(Size, align)
라이브러리에서 처음본 함수고, 작동자체는 Allocatepool(Size)와 동일하므로 위험하나. 지금까지 못본것도 있고, 특별한 경우빼곤 거의 안쓴다고한다.
그래서 패스!
그럼 추가로 edk2의 Reallocatepool, gBS -> allocatepool의 경우만 잡으면된다!
벤더 자체의 래퍼함수는?
지금 거의 다잡았는데, 얘때문에 함수간 오염분석을 하기엔 아깝다고 생각한다.
그래서 찾아보니 벤더 자체 래퍼함수는 주로 바로 해당 함수안에서 gbs -> allocatepool을 요청하는 형태라고한다!
=> depth 1로만 함수간 오염분석을 하자.
케이스 나눠서, 테스트케이스 만들기.
- gbs -> allocatepool
- edk2 ReallocatePool
- 벤더 자체 래퍼 함수 (일단임시로 인자는 2개, 래퍼함수 내부에 바로 gbs-> allocatepool이 위치.)
기존에서 바꿔야 하는 것들


다음에 이를 에이전트로 자동화할때 참고하려고 적어두기…
