Skip to content
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

Add Maven creds module #8831

Merged
merged 10 commits into from Sep 7, 2017
Merged

Add Maven creds module #8831

merged 10 commits into from Sep 7, 2017

Conversation

elenoir
Copy link
Contributor

@elenoir elenoir commented Aug 14, 2017

Some Artifactory or Nexus credentials are often stored in the Maven settings.xml configuration file.
Example in a settings.xml :

<server>
  <id>server-nexus-snapshot</id>
  <username>deploytonexus</username>
  <password>password</password>
</server>

This allows application to reference this server and deploy file automatically to it.
This modules scans all settings.xml on the file system, gathers these credentials and store them as loot.

Verification

List the steps needed to make sure this thing works

  • Start msfconsole
  • use use post/multi/gather/maven_creds
  • set SESSION <id>
  • run

Output example

Finding user directories
Unix OS detected
Looting 15 files
Downloading /home/user/settings.xml
Reading settings.xml file from /home/user/settings.xml
Collected the following credentials:
Id: server-nexus-snapshot
Username: deploytonexus
Password: password
Saved credentials to /home/user/.msf4/loot/20170814145812_default_127.0.0.1_maven.credential_408780.txt

Loot output

msf post(maven_creds) > loot
Host : 127.0.0.1
Service type : maven.credentials
Name : settings.xml
Content : text/plain
Info : Maven credentials from /home/user/settings.xml and id server-nexus-snapshot
Path : /home/user/.msf4/loot/20170814145812_default_127.0.0.1_maven.credential_351922.txt


def gathernix
print_status("Unix OS detected")
return cmd_exec('locate settings.xml').split("\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the system doesn't have locate? I think it would fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, do you think I should handle this case by using enum_user_directories in case "locate" does not exist?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think enum_user_directories is a good approach.

Is it possible to have that setting.xml somewhere else? for example /opt/something/setting.xml ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it can be install anywhere on the FS.

I submit a new version in which I downgrade to enum_user_directories if locate is not installed ;)

end

def gatherwin
print_status("Windows OS detected")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you consider checking windows registry? Maybe it's more efficient for rare installation cases...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure to understand what you say about the registry? You're talking about Maven registry keys or...?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess when you install the software some registry keys are created. You can search them using metasploit functions.
For example: https://github.com/rapid7/metasploit-framework/blob/master/modules/post/windows/gather/credentials/mdaemon_cred_collector.rb#L60

If no registry key is created and/or no useful information is stored on them, you can ignore this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, no registry key are stored with this software, all is in the settings.xml file.

@elenoir
Copy link
Contributor Author

elenoir commented Aug 15, 2017

@bcoles : I just added the doc to my module ;)

# Handle case where locate does not exist (error is returned in first element)
if files.length == 1 && !directory?(files.first)
files = []
paths = enum_user_directories.map {|d| d}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works with a 'shell' and 'meterpreter'?
Have you tried both?

I think it would be useful if the docs would have evidence of both.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it works on both, doc is edited

if sysinfo
if sysinfo['OS'].include? "Windows"
files = gatherwin
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this work on other OS? Mac OS X? Android? Either case, I would suggest using if, elsif (as many times and needed) and else (unexpected cases or a catch all for the reminding issues).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, will use a switch instead

username = sub.elements['username'].text rescue "<unknown>"
password = sub.elements['password'].text rescue "<unknown>"

print_status("Collected the following credentials:")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have more than "servers/server" in the XML?

Even if not, I would suggest removing from the each the last lines (there's no need to include them inside a loop)

print_status("Reading settings.xml file from #{target}")
data = ""
if session.type == "shell"
type = :shell
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this variable is not being used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

type = :shell
data = session.shell_command("cat #{target}")
else
type = :meterp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@elenoir
Copy link
Contributor Author

elenoir commented Aug 22, 2017

As @jmartin-r7 mentionned in #8774 , I transformed the loots into credentials.

module_fullname: self.fullname,
filename: target,
service_name: 'maven',
realm_value: id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the realm it would be nice to parse out the url from the repository or mirror tag that id is referencing.

Per the maven settings.xml spec for the server tag

id: This is the ID of the server (not of the user to login as) that matches the id element of the repository/mirror that Maven tries to connect to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I implemented the cross action with these tags !

@busterb busterb self-assigned this Sep 7, 2017
@busterb
Copy link
Member

busterb commented Sep 7, 2017

I verified that this worked fine yesterday. Thanks @elenoir

@busterb busterb merged commit a806707 into rapid7:master Sep 7, 2017
busterb pushed a commit that referenced this pull request Sep 7, 2017
Merge remote-tracking branch 'upstream/pr/8831' into upstream-master
@busterb busterb removed the needs-docs label Sep 7, 2017
@busterb
Copy link
Member

busterb commented Sep 7, 2017

Release Notes

This adds a post-exploitation module for extracting Artifactory or Nexus credentials are often stored in the Maven settings.xml configuration file.

@tdoan-r7 tdoan-r7 added the rn-enhancement release notes enhancement label Sep 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature module rn-enhancement release notes enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants