New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port msmailprobe(Nick Powers) + Cleanup for GO bridge #10964

Merged
merged 7 commits into from Dec 4, 2018

Conversation

@clee-r7
Copy link
Contributor

clee-r7 commented Nov 14, 2018

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 (EMAILorEMAIL_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

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

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 (USERorUSER_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
@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Nov 20, 2018

The .md file is in a path where not only does it not actually work in Metasploit, but the module actually fails to load. Please move it to the path with all other documentation files are (2 other PRs have landed in the same way; people need to please start using the info -d command to test documentation).

@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Nov 20, 2018

The side-effect of putting the .md file where it is is this in the log:

[11/20/2018 10:09:41] [e(0)] core: /Users/bcook/projects/metasploit-framework/modules/auxiliary/scanner/msmail/exchange_enumerator.md failed to load due to the following error:
Errno::ENOENT
@jmartin-r7

This comment has been minimized.

Copy link
Contributor

jmartin-r7 commented Nov 21, 2018

Jenkins test this please.

@@ -142,7 +142,7 @@ def harvest_process
elsif Process.kill('TERM', self.wait_thread.pid) && self.wait_thread.join(10)
self.exit_status = self.wait_thread.value
else
Procoess.kill('KILL', self.wait_thread.pid)
Process.kill('KILL', self.wait_thread.pid)

This comment has been minimized.

@busterb

busterb Nov 30, 2018

Contributor

oops!

Transport: tr,
}
req, err := http.NewRequest("GET", URI, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1")

This comment has been minimized.

@cblack-r7

cblack-r7 Nov 30, 2018

This should probably be a MSF configured parameter

This comment has been minimized.

@acammack-r7

acammack-r7 Nov 30, 2018

Contributor

That's sorta a WIP thing: #9228

This comment has been minimized.

@busterb

busterb Dec 3, 2018

Contributor

ah right!

"time"
)

func WebRequestCodeResponse(URI string) int {

This comment has been minimized.

@cblack-r7

cblack-r7 Nov 30, 2018

I'll try and loop back on a patch on this, but realistically this should probably return an http.Response and error instead of an integer.

Transport: tr,
}
req, err := http.NewRequest("GET", urlToHarvest, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36")

This comment has been minimized.

@cblack-r7

cblack-r7 Nov 30, 2018

This also seems like it should be MSF defined, but it does switch to a "desktop" UA. I talked to Nick and he says that this was to simulate the "real devices" for the devices that normally hit then endpoints (ie a phone generally only accesses the ActiveSync)

This comment has been minimized.

@busterb

busterb Dec 3, 2018

Contributor

We have an old PR of mine that's supposed to cleanup UA handling and make it work properly for external modules. I should go back and finish it up. Don't think it blocks this though.


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

## Verification

This comment has been minimized.

@busterb

busterb Nov 30, 2018

Contributor

replace these with some redacted test runs, so someone looking at the docs later would see what the output of this module should look like

"protocol": protocol,
"fullname": "auxiliary/scanner/msmail/msmail_enum",
}
module.ReportCredentialLogin(user,"", opts)

This comment has been minimized.

@busterb

busterb Nov 30, 2018

Contributor

shouldn't gofmt pick up spacing things like this?

This comment has been minimized.

@clee-r7

clee-r7 Nov 30, 2018

Contributor

why yes - I'm not sure why IDE doesn't auto run this

}.merge(service_data)

if data.has_key?(:password)
print_warning "In pass"

This comment has been minimized.

@mkienow-r7

mkienow-r7 Nov 30, 2018

Contributor

Is this a debug statement from development?

This comment has been minimized.

@clee-r7

clee-r7 Nov 30, 2018

Contributor

bwhaha - thanks

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

This comment has been minimized.

@mkienow-r7

mkienow-r7 Nov 30, 2018

Contributor

Consider using File.join for this:

shared_module_lib_path = File.join(File.dirname(module_path), 'shared')
go_path = go_path + File::PATH_SEPARATOR + shared_module_lib_path
end

self.env = self.env.merge({ 'GOPATH' => go_path})

This comment has been minimized.

@mkienow-r7

mkienow-r7 Nov 30, 2018

Contributor

Minor: space after {, however, no space before }.

"service_name": service,
"address": ip,
"protocol": protocol,
"fullname": "auxiliary/scanner/msmail/msmail_enum",

This comment has been minimized.

@mkienow-r7

mkienow-r7 Nov 30, 2018

Contributor

Is there a way to determine the fullname programmatically?

This comment has been minimized.

@clee-r7

clee-r7 Nov 30, 2018

Contributor

if you figure it out let me know :)

This comment has been minimized.

@acammack-r7

acammack-r7 Nov 30, 2018

Contributor

The report method should not need this. The Msf::Module::External mixin has access to this info and should be the one using it

"protocol": protocol,
"fullname": "auxiliary/scanner/msmail/msmail_enum",
}
module.ReportCredentialLogin(user,"", opts)

This comment has been minimized.

@acammack-r7

acammack-r7 Nov 30, 2018

Contributor

This type of interface makes it impossible to report just a username vs a valid login with an empty password.

msfLog(message, "error")
}

func msfLog(message string, level string) {

This comment has been minimized.

@mkienow-r7

mkienow-r7 Dec 3, 2018

Contributor

This method should behave more like the log method in lib/msf/core/modules/external/python/metasploit/cli.py, otherwise, all callers become responsible for adding the leading log status indicators ([*], [!], [+], etc) to the actual messages themselves. This could result in many inconsistencies in the log.

This comment has been minimized.

@busterb

busterb Dec 3, 2018

Contributor

I think the 'level' string makes metasploit display the correct character at the beginning of the message already. So this should be fine.

This comment has been minimized.

@busterb

busterb Dec 3, 2018

Contributor

cli.py is something that interprets the output of the message that comes from a module like this, so it's a different thing.

This comment has been minimized.

@mkienow-r7

mkienow-r7 Dec 3, 2018

Contributor

I was unsure of that since there are plenty of locations in this PR where module.LogInfo is being called with a leading indicator in the message string.

This comment has been minimized.

@busterb

busterb Dec 4, 2018

Contributor

Yep, you are right.

This comment has been minimized.

@busterb

busterb Dec 4, 2018

Contributor

also, all of the 'mux.Lock/Unlock' code needs to be fixed

@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Dec 3, 2018

I think this is good to go, we can continue improving in the tree. Thanks all!

Also, oops, hit the wrong button!

@busterb busterb closed this Dec 3, 2018

@busterb busterb reopened this Dec 3, 2018

@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Dec 3, 2018

Shouldn't auxiliary/scanner/msmail/exchange_enum just have an 'RHOSTS' with a default value of the normal target? Seems silly to force the user to set a value since there actually is one it uses. Also, unregistering or even never registering datastore values is possible. You might just have to declare a new template type though.

clee-r7 added some commits Dec 4, 2018

@busterb

busterb approved these changes Dec 4, 2018

@busterb busterb self-assigned this Dec 4, 2018

@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Dec 4, 2018

sorted out above comment offline, going to land and iterate from there

@busterb busterb merged commit 3d8ec17 into rapid7:master Dec 4, 2018

2 checks passed

Metasploit Automation - Test Execution Successfully completed all tests.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

busterb added a commit that referenced this pull request Dec 4, 2018

msjenkins-r7 added a commit that referenced this pull request Dec 4, 2018

@acammack-r7

This comment has been minimized.

Copy link
Contributor

acammack-r7 commented Dec 4, 2018

@busterb, there was still a lot that needs to be fixed. Are we keeping track of that anywhere besides this PR?

@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Dec 4, 2018

@clee-r7 are you going to do that? @mkienow-r7 has some valid points that I missed in time.
The mux code here should all be moved into the library as well.

@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Dec 4, 2018

Chatted with @clee-r7 , he'll take care of the additional issues. Thanks!

@busterb

This comment has been minimized.

Copy link
Contributor

busterb commented Dec 19, 2018

Release Notes

This adds additional support for modules written in Go, specifically adding auxiliary scanner and reporting functionality. It also adds three modules for enumerating users with Microsoft Exchange and Office 365.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment