Path: blob/master/lib/metasploit/framework/login_scanner/directadmin.rb
31165 views
require 'metasploit/framework/login_scanner/http'12module Metasploit3module Framework4module LoginScanner56class DirectAdmin < HTTP78DEFAULT_PORT = 4439PRIVATE_TYPES = [ :password ]101112# Checks if the target is correct13#14# @return [false] Indicates there were no errors15# @return [String] a human-readable error message describing why16# this scanner can't run17def check_setup18login_uri = normalize_uri("#{uri}/CMD_LOGIN")19res = send_request({'uri'=> login_uri})2021if res && res.body.include?('DirectAdmin Login')22return false23end2425'Unable to locate "DirectAdmin Login" in body. (Is this really DirectAdmin?)'26end272829# Returns the latest sid from DirectAdmin Control Panel30#31# @return [String] The PHP Session ID for DirectAdmin Web Control login32def get_last_sid33@last_sid ||= lambda {34# We don't have a session ID. Well, let's grab one right quick from the login page.35# This should probably only happen once (initially).36login_uri = normalize_uri("#{uri}/CMD_LOGIN")37res = send_request({'uri' => login_uri})3839return '' unless res4041cookies = res.get_cookies42@last_sid = cookies.scan(/(session=\w+);*/).flatten[0] || ''43}.call44end454647# Actually doing the login. Called by #attempt_login48#49# @param username [String] The username to try50# @param password [String] The password to try51# @return [Hash]52# * :status [Metasploit::Model::Login::Status]53# * :proof [String] the HTTP response body54def get_login_state(username, password)55# Prep the data needed for login56sid = get_last_sid57protocol = ssl ? 'https' : 'http'58peer = "#{host}:#{port}"59login_uri = normalize_uri("#{uri}/CMD_LOGIN")6061res = send_request({62'uri' => login_uri,63'method' => 'POST',64'cookie' => sid,65'headers' => {66'Referer' => "#{protocol}://#{peer}/#{login_uri}"67},68'vars_post' => {69'username' => username,70'password' => password,71'referer' => '%2F'72}73})7475unless res76return {:status => Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, :proof => res.to_s}77end7879# After login, the application should give us a new SID80cookies = res.get_cookies81sid = cookies.scan(/(session=\w+);*/).flatten[0] || ''82@last_sid = sid # Update our SID8384if res.headers['Location'].to_s.include?('/') && !sid.blank?85return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.to_s}86end8788{:status => Metasploit::Model::Login::Status::INCORRECT, :proof => res.to_s}89end909192# Attempts to login to DirectAdmin Web Control Panel. This is called first.93#94# @param credential [Metasploit::Framework::Credential] The credential object95# @return [Result] A Result object indicating success or failure96def attempt_login(credential)97result_opts = {98credential: credential,99status: Metasploit::Model::Login::Status::INCORRECT,100proof: nil,101host: host,102port: port,103protocol: 'tcp',104service_name: ssl ? 'https' : 'http'105}106107begin108result_opts.merge!(get_login_state(credential.public, credential.private))109rescue ::Rex::ConnectionError => e110# Something went wrong during login. 'e' knows what's up.111result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e.message)112end113114Result.new(result_opts)115end116117end118end119end120end121122123