
The still widely used Flash Player from Adobe is notorious for its security. Regularly becoming aware of another zero-day vulnerability in Flash, used by hackers in the APT campaigns. The year 2015 was particularly fruitful for such vulnerabilities. A large proportion of critical RCE vulnerabilities were caused by incorrect memory handling: it was possible to write to the freed memory on the Flash process heap.
In this article, we investigated the security of Adobe Flash and found out that many of its “security holes” are chronic, and they can only be solved by rewriting the code from scratch, while the developers put a patch on the patch, which, of course, does not improve security. And we will demonstrate some of the vulnerabilities we have found and that are not currently closed!
Sensational Vulnerabilities
In February-March 2015, similar Use-After-Free vulnerabilities CVE-2015-0313 and CVE-2015-0311 were discovered in the ActionScript class ByteArray (you can read about them
here and
here ). An object of type ByteArray, marked as domainMemory for performing fast and low-level read-write operations in memory, did not notify domainMMory storing a pointer to it when the pointer to its buffer was changed.
In CVE-2015-0313, the object was deleted in another thread; in CVE-2015-0311, it was unsuccessfully unpacked using zlib. This made it possible to write to the freed memory of other objects and modify them, breaking class invariants.
')
In July 2015, public exploits to the zero-day vulnerabilities
CVE-2015-5119 ,
CVE-2015-5122 , leaked from the hacked archives of the Italian company Hacking Team, made a lot of noise. ActionScript assignment statements to a cell of a ByteArray object by index (in CVE-2015-5119) and the opaqueBackground field setting operator in the TextLine class (in CVE-2015-5122) were vulnerable.
The expected value for such assignments is numeric. If you pass a custom class object with the overloaded valueOf method as the assignment value to the ByteArray element / opaqueBackground field, an implicit coercion of this object to a numeric type will occur, with the overloaded valueOf being called. If in the valueOf method, prior to the above assignment, to free the resources of the ByteArray object / TextLine object, the memory becomes available, but a pointer to it is saved, and it will be written to the freed memory on the heap.
In general, the Use-After-Free vulnerabilities in Flash are still a headache for Adobe, since they appear quite often.
Vulnerabilities in TextField and MovieClip from Google Project Zero
Such vulnerabilities sometimes contain entire groups of ActionScript class methods. For example, the set of vulnerabilities in the ActionScript 2 methods of MovieClip and TextField detected by the Google Project Zero team allowed the object to free up memory before attempting to use it. Some vulnerable methods are:
1.
CVE-2015-8412 : The mc object is freed before use with an implicit call of valueOf in the duplicateMovieClip method:
this.createEmptyMovieClip("mc", 1); mc.duplicateMovieClip( "mc",{valueOf : func}); function func(){ trace("in func"); mc.removeMovieClip();
2.
CVE-2015-8044 : The triangle_mc object is freed before use when implicitly calling valueOf in the lineStyle method:
this.createEmptyMovieClip("triangle_mc", this.getNextHighestDepth()); var o = {toString: func}; triangle_mc.lineStyle(5, 0xff00ff, 100, true, o, "round", "miter", 1); function func(){ triangle_mc.removeMovieClip(); return "none"; }
The situation is similar with TextField class ActionScript 2 methods (CVE-2015-7652, CVE-2015-8046, CVE-2015-8423, CVE-2015-8424, CVE-2015-8425, CVE-2015-8427, CVE-2015- 8428, CVE-2015-8429, CVE-2015-8430, etc.)
Seeing such a mess, we decided to find out if things are really so bad with the security of Flash? And ... yes, everything is bad!
Vulnerabilities in the class BitmapData
We decided to look at the situation in other ActionScript Flash classes. It turned out that a set of similar Use-After-Free vulnerabilities was also present in the ActionScript 2 class BitmapData. At the time of the study of this class, the latest version of Flash was version 18.0.0.209. Part of the vulnerabilities (regardless of us) was later identified by other researchers, some remained unclosed until the release of version 20.0.0.228.
To free up memory before using the BitmapData object, the same trick was used with overloading the valueOf method of the custom class. This method is implicitly called when it is necessary to convert a class object to the Number type. This happens, for example, during the preliminary calculation of the arguments of functions or methods.
import flash.geom.Point; import flash.geom.Rectangle; import flash.display.BitmapData; class MyClass { static var bitmap1:BitmapData, bitmap2:BitmapData, bitmap3:BitmapData; public function MyClass() { } static function vof() { trace("in valueOf.."); bitmap2.dispose(); return 1; } static function expl() { trace("in expl"); MyClass.prototype.valueOf = MyClass.vof; var array:Array = new Array(256); for(var i:Number= 0; i < 256; i++) { array[i] = 0xaaddddaa; } array[0xFF] = new MyClass(); var o = new MyClass(); var rect:Rectangle = new Rectangle(10, 11, 2, 2); var pt:Point = new Point(12, 12); bitmap1 = new BitmapData(100, 100, true, 0xaabbccdd); bitmap2 = new BitmapData(100, 100, true, 0xaabbccdd); bitmap3 = new BitmapData(100, 100, true, 0xaabbccdd);
Now we call the vulnerable method of the BitmapData class:
Bitmap2.hitTest(pt, 1, bitmap1, new Point(0, 0), o);
In this case, the vulnerable method BitmapData.hitTest is called with a parameter of the type MyClass (_loc3_ [255]), which is implicitly reduced to integer form by calling the vof function. Inside the function, the memory of the myBitmapData2 object is freed before using the pointer to it. In the heap, where the BitmapData data structure is stored, the pointer to the pixel buffer (also in the heap) is reset.
Not only the BitmapData.hitTest method is vulnerable. Here is a list of vulnerable methods found by us in Adobe Flash version 18.0.0.209, along with the vulnerable part of the code.
BitmapData.draw bitmap2.draw(bitmap1, new Matrix(0.5, array[0xFF], 0.5, 0.5));
BitmapData.copyChannel bitmap2.copyChannel(bitmap1, rect, pt, o, 4); bitmap1.copyChannel(bitmap2, rect, pt, o, 4);
BitmapData.copyPixels bitmap2.copyPixels(bitmap1, new Rectangle(10, 11, 2, array[0xFF]), pt, bitmap3); bitmap1.copyPixels(bitmap2, new Rectangle(10, 11, 2, array[0xFF]), pt, bitmap3);
BitmapData.paletteMap bitmap2.paletteMap(bitmap1, rect, pt, array); bitmap1.paletteMap(bitmap2, rect, pt, array);
BitmapData.floodFill bitmap2.floodFill(10, 10, o);
BitmapData.pixelDissolve bitmap2.pixelDissolve(bitmap1, new Rectangle(10, 11, 2, 2), new Point(0, 0), 1245, o); bitmap1.pixelDissolve(bitmap2, new Rectangle(10, 11, 2, 2), new Point(0, 0), 1245, o);
BitmapData.merge bitmap2.merge(bitmap1, rect, pt, 1, 1, 1, o); bitmap1.merge(bitmap2, rect, pt, 1, 1, 1, o);
BitmapData.getColorBounds var z:Rectangle = bitmap2.getColorBoundsRect(array[0xFF], 0xffffffff);
BitmapData.scroll bitmap2.scroll(o, 13);
Each of these methods causes memory dereferencing near zero when reading and, accordingly, the collapse of Adobe Flash version 18.0.0.209. Some of the methods cause the collapse of all versions up to and including 19.0.0.245, which should fix them all!
The fact that whole ActionScript classes have security problems is already alarming. But that is not all. It turns out that there are vulnerabilities in the Adobe world, which are then closed, then re-opened in the latest version!
Bug or feature?
One of the above vulnerabilities, in the BitmapData.merge method, was closed in version 18.0.0.232. It remained closed until version 19.0.0.245, however, starting with the release of 20.0.0.228, it was unclosed again! The following code causes memory dereferencing near zero and Flash to fall in the specified versions:
bitmap2.merge(bitmap1, rect, pt, 1, 1, 1, o);


If now the source object is removed in the valueOf method, not the receiver object, then such a swf file will cause a crash of all Flash versions in general, including the latest for today (21.0.0.182):
bitmap1.merge(bitmap2, rect, pt, 1, 1, 1, o);
Let's see what happens in the Flash code before it crashes. For this we use the disassembler IDA Pro and x86-decompiler Hex-Rays. The sub_12FDF50 function is called several times when calculating the parameters of the BitmapData.merge function, and in the latest Flash version, the BitmapData object is pre-deleted and the memory cell is reset to the address [esi + 0xC8] in the sub_122DD40 function (.text tag: 0122DD82 in the disassembled code, line 19) decompiled code):

After calculating the parameters, the procedure sub_1230D10 is called:


Please note that the ecx register at the time of calling sub_1230D10 contains the same address, the value of which was previously reset when calculating the parameters of the BitmapData.merge function and zeroing the bitmap2 receiver object in the valueOf method.
In the sub_1230D10 function, memory is dereferenced next to the address in the cell [ecx + 0xC8]. As you can see, this is the address, the value of which was previously reset to zero when the BitmapData receiver object was deleted. The result is a Flash crash:

It is unclear what makes Adobe reopen previously patched vulnerabilities.
CVE-2015-?
Finally, we give another vulnerability we found. It is not related to the use of memory after release, but is a very clear example of vulnerable code.
The vulnerability was found in debug versions of Flash for Windows (including browser plugins) in conjunction with the Adobe Flex Debugger (FDB). It consists in an incorrect search for the value of the linked list in the Flash code and works in the debug version of Flash when the FDB debugger is running.
The swf file main.swf generated by us in ActionScript 3 code loads another swf file inside itself, expressInstall_.swf in ActionScript 2 code that refers to the external address:


For the analysis again we will use IDA Pro and Hex-Rays. When the Flex Debugger is active (for example, while debugging ActionScript code), Flash, when running the swf generated by us, generates an error message:

In the sub_C57769 function, a string is calculated, which will be output by the sub_B8E6D9 function in the error message after the word “Base”.

To calculate in a loop on the linked list v4, we look for a cell with certain properties (* (* (v4 + 24) + 252) == 98). The cycle is terminated in three cases:
- if the desired cell is encountered (* (v6 + 252) == 98
- if we did not find the desired cell in the list in 256 steps (v5> = 256)
- if the list is over (v4 == 0)
After exiting the loop, the final cell is used in further calculations. There is an error on the generated swf file: there are no cells with the necessary property in the list, and the cycle ends at the end of the list. Adobe Flash crashes after exiting the loop with v4 == 0:

As you can see, the exit code from the loop is vulnerable. Potentially, the formation of such a condition in which the v4 will be controlled by the attacker address. This is possible if the list is longer than 256 values, and the first 256 will not satisfy the property (* (* (v4 + 24) + 252) == 98). Then the while loop finishes by the condition (v5> = 256), and in v4, the address of the next cell is found.
What else can you say?
Just recently, Adobe released another patch covering 23 vulnerabilities in Flash, including critical ones. Reportedly, one of them is already being used in narrowly targeted attacks.
You can definitely say that Flash technology, due to chronic security problems, will sooner or later be finally pushed out of browsers, and maybe even from desktops, whatever Adobe says about it. Youtube has been successfully working on HTML5 for a long time. In Mozilla, Flash has already been removed from the standard Firefox distribution. Now it is the turn of other players on the market - it is not beneficial for anyone to lower the safety of their product in comparison with competitors. So, Flash, come on, bye!