Skip to content

Commit

Permalink
Land #10964, add initial golang modules for enumerating owa/o365
Browse files Browse the repository at this point in the history
  • Loading branch information
busterb committed Dec 4, 2018
2 parents eb4b6a6 + 3d8ec17 commit 55a9a12
Show file tree
Hide file tree
Showing 14 changed files with 940 additions and 198 deletions.
21 changes: 21 additions & 0 deletions documentation/modules/auxiliary/scanner/msmail/exchange_enum.md
@@ -0,0 +1,21 @@
OWA (Outlook Webapp) is vulnerable to time-based user enumeration attacks.
This module leverages all known, and even some lesser-known services exposed by default
Exchange installations to enumerate email.

Error-based user enumeration for Office 365 integrated email addresses

## Verification

- Start `msfconsole`
- `use auxiliary/scanner/msmail/exchange_enum`
- `set (`EMAIL` or `EMAIL_FILE`)`
- `run`
- `creds`

*Results should look something like below if valid users were found:*

```
host origin service public private realm private_type
---- ------ ------- ------ ------- ----- ------------
<ip> <ip> 443/tcp (owa) chris@somecompany.com
```
42 changes: 42 additions & 0 deletions documentation/modules/auxiliary/scanner/msmail/host_id.md
@@ -0,0 +1,42 @@
OWA (Outlook Webapp) is vulnerable to time-based user enumeration attacks.
This module leverages all known, and even some lesser-known services exposed by default
Exchange installations to enumerate users. It also targets Office 365 for error-based user enumeration.

**Identify Command**
- Used for gathering information about a host that may be pointed towards an Exchange or o365 tied domain
- Queries for specific DNS records related to Office 365 integration
- Attempts to extract internal domain name for onprem instance of Exchange
- Identifies services vulnerable to time-based user enumeration for onprem Exchange
- Lists password-sprayable services exposed for onprem Exchange host

**Note:** Currently uses RHOSTS which resolves to an IP which is NOT desired, this is currently being fixed

## Verification

- Start `msfconsole`
- `use auxiliary/scanner/msmail/host_id`
- `set RHOSTS <target>`
- `run`

*Results should look like below:*

```
msf5 > use auxiliary/scanner/msmail/host_id
msf5 auxiliary(scanner/msmail/host_id) > set RHOSTS <host>
RHOSTS => <host>
msf5 auxiliary(scanner/msmail/host_id) > run
[*] Running for <ip>...
[*] Attempting to harvest internal domain:
[*] Internal Domain:
[*] <domain>
[*] [-] Domain is not using o365 resources.
[*] Identifying endpoints vulnerable to time-based enumeration:
[*] [+] https://<host>/Microsoft-Server-ActiveSync
[*] [+] https://<host>/autodiscover/autodiscover.xml
[*] [+] https://<host>/owa
[*] Identifying exposed Exchange endpoints for potential spraying:
[*] [+] https://<host>/oab
[*] [+] https://<host>/ews
```
25 changes: 25 additions & 0 deletions documentation/modules/auxiliary/scanner/msmail/onprem_enum.md
@@ -0,0 +1,25 @@
OWA (Outlook Webapp) is vulnerable to time-based user enumeration attacks.
This module leverages all known, and even some lesser-known services exposed by default
Exchange installations to enumerate users. It also targets Office 365 for error-based user enumeration.

- Error-based user enumeration for on premise Exchange services

**Note:** Currently uses RHOSTS which resolves to an IP which is NOT desired, this is currently being fixed

## Verification

- Start `msfconsole`
- `use auxiliary/scanner/msmail/onprem_enum`
- `set RHOSTS <target>`
- `set (`USER` or `USER_FILE`)
- `run`
- `creds`

*Results should look something like below if valid users were found:*

```
host origin service public private realm private_type
---- ------ ------- ------ ------- ----- ------------
10.1.1.1 10.1.1.1 443/tcp (owa)
10.1.1.1 10.1.1.1 443/tcp (owa) chris
```
36 changes: 36 additions & 0 deletions lib/msf/core/module/external.rb
Expand Up @@ -119,8 +119,44 @@ def process_report(m, mod)
}) })


invalidate_login(**cred) invalidate_login(**cred)

when 'credential_login'
handle_credential_login(data, mod)
else else
print_warning "Skipping unrecognized report type #{m.params['type']}" print_warning "Skipping unrecognized report type #{m.params['type']}"
end end
end end
end end

#
# Handles login report that does not necessarily need to include a password
#
def handle_credential_login(data, mod)
# Required
service_data = {
address: data['address'],
port: data['port'],
protocol: data['protocol'],
service_name: data['service_name'],
module_fullname: self.fullname,
workspace_id: myworkspace_id
}

# Optional
credential_data = {
origin_type: :service,
username: data['username']
}.merge(service_data)

if data.has_key?(:password)
credential_data[:private_data] = data['password']
credential_data[:private_type] = :password
end

login_data = {
core: create_credential(credential_data),
last_attempted_at: DateTime.now,
status: Metasploit::Model::Login::Status::SUCCESSFUL,
}.merge(service_data)
create_credential_login(login_data)
end
17 changes: 14 additions & 3 deletions lib/msf/core/modules/external/bridge.rb
Expand Up @@ -142,7 +142,7 @@ def harvest_process
elsif Process.kill('TERM', self.wait_thread.pid) && self.wait_thread.join(10) elsif Process.kill('TERM', self.wait_thread.pid) && self.wait_thread.join(10)
self.exit_status = self.wait_thread.value self.exit_status = self.wait_thread.value
else else
Procoess.kill('KILL', self.wait_thread.pid) Process.kill('KILL', self.wait_thread.pid)
self.exit_status = self.wait_thread.value self.exit_status = self.wait_thread.value
end end
end end
Expand Down Expand Up @@ -197,8 +197,19 @@ def self.applies?(module_name)


def initialize(module_path, framework: nil) def initialize(module_path, framework: nil)
super super
gopath = ENV['GOPATH'] || '' default_go_path = ENV['GOPATH'] || ''
self.env = self.env.merge({ 'GOPATH' => File.expand_path('../go', __FILE__) + File::PATH_SEPARATOR + gopath}) shared_module_lib_path = File.dirname(module_path) + "/shared"
go_path = File.expand_path('../go', __FILE__)

if File.exist?(default_go_path)
go_path = go_path + File::PATH_SEPARATOR + default_go_path
end

if File.exist?(shared_module_lib_path)
go_path = go_path + File::PATH_SEPARATOR + shared_module_lib_path
end

self.env = self.env.merge({'GOPATH' => go_path})
self.cmd = ['go', 'run', self.path] self.cmd = ['go', 'run', self.path]
end end
end end
Expand Down
195 changes: 0 additions & 195 deletions lib/msf/core/modules/external/go/src/metasploit/module.go

This file was deleted.

0 comments on commit 55a9a12

Please sign in to comment.