The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Checking for mailboxes with weak passwords

Discussion in 'Workarounds and Optimization' started by Stefaans, Aug 10, 2012.

  1. Stefaans

    Stefaans Well-Known Member

    Mar 5, 2002
    Likes Received:
    Trophy Points:
    Vancouver, Canada
    In recent weeks our servers have been under constant attack from spammers that sniff out mailboxes with weak passwords. It is amazing to see how often the password for is merely "info" or even "password" :eek:

    Nowadays WHM has an option to set a password policy. Years ago, however, there was no such feature and users could set up mailboxes with weak passwords. We needed a way to check older mailboxes for weak passwords.

    I wrote the PHP script below to check all mailboxes on a server for weak passwords. The script checks the following passwords:
    * The username, e.g. "info" for the mailbox
    * The domain, e.g. "domain" for the mailbox
    * A configurable list of common passwords. I took the top five that were published for 2011.

    The script is made to be run from the shell as root:
    php checkmailboxes.php
    Modify the $conf variable for a options. By default the script echoes its basic progress on the screen; if you enable the 'debug' configuration variable, more in-depth information is displayed. The script also writes a list of vulnerable mailboxes found in a log file weakmailboxes.log.

    There is obviously a lot more one could add to this script (e.g. automatically set a new password for each vulnerable mailbox, send the account owner a notification email etc.) but I am not going to bother at this time.

     * Find mailboxes with weak passwords
     * Created by Stephen @ ANNO.COM
     * Revisions:
     * ---------
     * 2012/08/10
     *  Initial release.
    $conf = array(
      'users_exclude'   => array('virtfs', 'cpanel_src', 'lost+found', 'cpanel_logs', 'cpeasyapache', 'apache_logs', 'logs', 'MySQL-install'),
      // Directories in /home that are not real users
      'domains_exclude' => array('cur', 'new', 'tmp', 'courierimaphieracl', 'courierimapkeywords'), // System directories in mail that are not domains
      'mailboxes_exclude' => array('cur', 'new', 'tmp', 'courierimapkeywords'), // System directories in domain directory that are not mailboxes
      'check_common_passwords' => TRUE,   // Set to TRUE to check the following passwords as well
      'common_passwords' => array('password', '123456', '12345678', 'qwerty', 'abc123'), // Allegedly the most popular passwords in 2011
      'debug' => FALSE, // Set to TRUE to display more verbose output
    $mailboxes = array(); // Array of mailboxes
    $weak_mailboxes_found = FALSE;
    // IMAP config for fastest possible connection
    imap_timeout(IMAP_OPENTIMEOUT, 1);
    imap_timeout(IMAP_READTIMEOUT, 1);
    // Create log file
    $log = fopen('weakmailboxes.log', 'w');
    fwrite($log, "List of mailboxes with weak passwords\n");
    fwrite($log, 'Checks ' . ($conf['check_common_passwords'] ? '' : 'do not ') . "include common passwords\n");
    fwrite($log, 'Report on ' . date('Y-m-d H:i') . "\n");
    fwrite($log, "----------------------------------------------------------------------\n");
    // Start screen output
    echo "\n\n----------------------------------------------------------------------\n";
    echo "Weak mailbox password check\n";
    // Loop through cPanel users in home directory
    if ($h_home = opendir('/home')) {
      echo "Building list of mailboxes:\n";
      if ($conf['debug']) {
        echo "(Directory handle: $h_home)\n";
      while (FALSE !== ($user = readdir($h_home))) {
        if (is_dir("/home/$user/mail") && !in_array($user, $conf['users_exclude']) && (strpos($user, '.') === FALSE)) {
          $users[] = $user;
    // Loop through user's domains
          echo "Looping through domains for user $user...\n";
          if ($h_user = opendir("/home/$user/mail")) {
            if ($conf['debug']) {
              echo "\t(User handle: $h_user)\n";
            while (FALSE !== ($domain = readdir($h_user))) {
              if (is_dir("/home/$user/mail/$domain") && !in_array($domain, $conf['domains_exclude']) && ($domain[0] != '.')) {
                $domains[] = $domain;
    // Loop through domain's mailboxes
                echo "\tLooping through mailboxes for domain $domain...\n";
                if ($h_domain = opendir("/home/$user/mail/$domain")) {
                  if ($conf['debug']) {
                    echo "\t(Domain handle: $h_domain)\n";
                  while (FALSE !== ($mailbox = readdir($h_domain))) {
                    if (is_dir("/home/$user/mail/$domain/$mailbox") && !in_array($mailbox, $conf['mailboxes_exclude']) && ($mailbox[0] != '.')) {
                      $mailboxes["$domain with user $mailbox"] = array(
                        'user' => $mailbox,
                        'domain' => $domain,
                      echo "\t\t$mailbox@$domain\n";
                    } // End if value mailbox
                    else {
                      if (!in_array($domain, array('.', '..'))) {
                        if ($conf['debug']) {
                          echo "\t\tSkipping $mailbox\n";
                  } // End while loop for mailboxes
                } // End if domain dir can be read
              } // End if valid domain
              else {
                if (!in_array($domain, array('.', '..'))) {
                  if ($conf['debug']) {
                    echo "\tSkipping $domain\n";
            } // End while loop for domains
          } // End if user dir can be read
        } // End if valid user
        else {
          if ($conf['debug']) {
            echo "Skipping $user\n";
      } // End while loop for users
    } // End if home dir can be read
    // Sort the mailboxes for alphabetic processing (for easy indication of progress)
    // Perform login checks
    echo "\n\nChecking mailbox logins:\n";
    $no_mailboxes = sizeof($mailboxes);
    $no_passwords = ($conf['check_common_passwords'] ? sizeof($conf['common_passwords']) : 0) + 2;
    echo "Checking $no_mailboxes mailboxes for $no_passwords passwords will take about " . ceil(($no_mailboxes * $no_passwords)/60) . " minutes\n";
    foreach ($mailboxes as $index => $mailbox) {
      $logged_in = FALSE;
      $username = $mailbox['user'] . '@' . $mailbox['domain'];
      $local_passwords = array( $mailbox['user'], substr($mailbox['domain'], 0, strpos($mailbox['domain'], '.')) ); // User and the domain without extension
      if ($conf['check_common_passwords']) { // Optionally include common passwords in checks
        $passwords = array_merge($local_passwords, $conf['common_passwords']);
      else {
        $passwords = $local_passwords;
      echo "$username...";
      foreach ($passwords as $password) {
        if ($conf['debug']) {
          echo "\n\tchecking password $password";
        $imap_login = imap_open('{localhost:143/imap/novalidate-cert/debug}INBOX', $username, $password, OP_HALFOPEN);
        if ($imap_login) {  // Weak password found
          imap_close($imap_login); // Close IMAP connection if it could be opened
          $logged_in = TRUE;
          $weak_mailboxes_found = TRUE;
          echo " logged in as user $username with password $password -- NOT GOOD!\n";
          fwrite($log, "$username with password $password\n");
      if (!$logged_in) {
        echo "good\n";
    // Close log file
    if (!$weak_mailboxes_found) {
      fwrite($log, "No weak mailbox passwords found!\n");

    PS: Be patient while the script runs... It will take about one second per login attempt. In other words, allow at least the number of mailboxes multiplies by the number of passwords in seconds for it to complete its checks.

    I hope you find this useful ;)
  2. Alejandro P

    Alejandro P Well-Known Member

    Apr 6, 2007
    Likes Received:
    Trophy Points:
    cPanel Access Level:
    Root Administrator
    Thanks for sharing Stefaans, I have found some weak passwords with your script.
  3. chriscory

    chriscory Member

    Oct 3, 2010
    Likes Received:
    Trophy Points:
    Excellent Script, I didn't know it was possible, Thank you for sharing.

Share This Page