Class: Metasploit::Framework::LoginScanner::SyncoveryFileSyncBackup

Inherits:
HTTP
  • Object
show all
Defined in:
lib/metasploit/framework/login_scanner/syncovery_file_sync_backup.rb

Constant Summary collapse

DEFAULT_PORT =

HTTP=8999; HTTPS=8943

8999
PRIVATE_TYPES =
[ :password ].freeze
LOGIN_STATUS =

Shorter name

Metasploit::Model::Login::Status

Constants inherited from HTTP

HTTP::AUTHORIZATION_HEADER, HTTP::DEFAULT_HTTP_NOT_AUTHED_CODES, HTTP::DEFAULT_HTTP_SUCCESS_CODES, HTTP::DEFAULT_REALM, HTTP::DEFAULT_SSL_PORT, HTTP::LIKELY_PORTS, HTTP::LIKELY_SERVICE_NAMES, HTTP::REALM_KEY

Instance Attribute Summary

Attributes inherited from HTTP

#digest_auth_iis, #evade_header_folding, #evade_method_random_case, #evade_method_random_invalid, #evade_method_random_valid, #evade_pad_fake_headers, #evade_pad_fake_headers_count, #evade_pad_get_params, #evade_pad_get_params_count, #evade_pad_method_uri_count, #evade_pad_method_uri_type, #evade_pad_post_params, #evade_pad_post_params_count, #evade_pad_uri_version_count, #evade_pad_uri_version_type, #evade_shuffle_get_params, #evade_shuffle_post_params, #evade_uri_dir_fake_relative, #evade_uri_dir_self_reference, #evade_uri_encode_mode, #evade_uri_fake_end, #evade_uri_fake_params_start, #evade_uri_full_url, #evade_uri_use_backslashes, #evade_version_random_invalid, #evade_version_random_valid, #http_password, #http_success_codes, #http_username, #keep_connection_alive, #kerberos_authenticator_factory, #method, #ntlm_domain, #ntlm_send_lm, #ntlm_send_ntlm, #ntlm_send_spn, #ntlm_use_lm_key, #ntlm_use_ntlmv2, #ntlm_use_ntlmv2_session, #uri, #user_agent, #vhost

Instance Method Summary collapse

Methods inherited from HTTP

#authentication_required?, #send_request

Instance Method Details

#attempt_login(credential) ⇒ Result

Attempts to login to Syncovery File Sync & Backup Software. This is called first.

Parameters:

Returns:

  • (Result)

    A Result object indicating success or failure

[View source] [View on GitHub]

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/metasploit/framework/login_scanner/syncovery_file_sync_backup.rb', line 102

def (credential)
  result_opts = {
    credential: credential,
    status: Metasploit::Model::Login::Status::INCORRECT,
    proof: nil,
    host: host,
    port: port,
    protocol: 'tcp'
  }

  begin
    result_opts.merge!((credential.public, credential.private))
  rescue ::Rex::ConnectionError => e
    # Something went wrong during login. 'e' knows what's up.
    result_opts.merge!(status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: e.message)
  end

  Result.new(result_opts)
end

#check_setupBoolean

Checks if the target is Syncovery File Sync & Backup Software. The login module should call this.

Returns:

  • (Boolean)

    TrueClass if target is Syncovery, otherwise FalseClass

[View source] [View on GitHub]

16
17
18
19
20
21
22
23
24
25
# File 'lib/metasploit/framework/login_scanner/syncovery_file_sync_backup.rb', line 16

def check_setup
   = normalize_uri("#{uri}/")
  res = send_request({ 'uri' =>  })

  if res && res.code == 200 && res.body.include?('Syncovery')
    return true
  end

  false
end

#get_login_state(username, password) ⇒ Hash

Actually doing the login. Called by #attempt_login

Parameters:

  • username (String)

    The username to try

  • password (String)

    The password or token to try

Returns:

  • (Hash)
    • :status [Metasploit::Model::Login::Status]

    • :proof [String] the HTTP response body or the session token

[View source] [View on GitHub]

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/metasploit/framework/login_scanner/syncovery_file_sync_backup.rb', line 49

def (username, password)
  # Prep the data needed for login
  if username.present?
    # use username:password
    res = send_request({
      'uri' => normalize_uri("#{uri}/post_applogin.php"),
      'vars_get' => {
        'login' => username.to_s,
        'password' => password.to_s
      },
      'method' => 'GET'
    })
    unless res
      return { status: LOGIN_STATUS::UNABLE_TO_CONNECT }
    end

    # After login, the application should give us a new token
    # session_token is actually just base64(MM/dd/yyyy HH:mm:ss) at the time of the login
    json_res = res.get_json_document
    token = json_res['session_token']
    if token.present?
      return { status: LOGIN_STATUS::SUCCESSFUL, proof: token.to_s }
    end

    return { proof: res.to_s }
  else
    # no username => token is used as password
    res = send_request({
      'uri' => normalize_uri("#{uri}/profiles.json"),
      'vars_get' => {
        'recordstartindex' => '0',
        'recordendindex' => '0'
      },
      'method' => 'GET',
      'headers' => {
        'token' => password
      }
    })
    unless res
      return { status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: res.to_s }
    end
    if !res.body.to_s.include? 'Session Expired'
      return { status: LOGIN_STATUS::SUCCESSFUL, proof: res.body.to_s }
    end

    return { proof: res.body.to_s }
  end
end

#get_versionString

Gets the Syncovery version.

Returns:

  • (String)

    version if version was found, otherwise FalseClass

[View source] [View on GitHub]

30
31
32
33
34
35
36
37
38
39
40
# File 'lib/metasploit/framework/login_scanner/syncovery_file_sync_backup.rb', line 30

def get_version
  globals = normalize_uri("#{uri}/get_global_variables")
  res = send_request({ 'uri' => globals })
  if res && res.code == 200
    json_res = res.get_json_document
    version = json_res['SyncoveryTitle']&.scan(/Syncovery\s([A-Za-z0-9.]+)/)&.flatten&.first || ''
    return version
  end

  false
end