Skip to content

Commit

Permalink
Land #16381, add chocolatey enumerator module
Browse files Browse the repository at this point in the history
  • Loading branch information
space-r7 committed Apr 1, 2022
2 parents bef0c9b + 79df619 commit fc18093
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## Vulnerable Application

This module will enumerate all installed applications on a Windows system that
are installed with Chocolatey.

## Verification Steps
1. Start msfconsole
2. Get meterpreter or shell session
3. Do: `use post/windows/gather/enum_chocolatey_applications`
4. Do: `set SESSION <session id>`
5. Do: `run`

## Options

### ChocoPath

This is here for the incredibly rare cases where chocolatey is not on the
system path. It allows you to set the path of the chocolatey executable
ahead of time. Unless this is changed, it assumes to use chocolatey from
the path.

## Scenarios

### Windows 10 Pro (21H2 Build 19044.1586).

```
msf6 exploit(multi/handler) > [*] Meterpreter session 12 opened (192.168.56.1:4444 -> 192.168.56.112:49906 ) at 2022-03-27 15:57:39 -0400
msf6 exploit(multi/handler) > use post/windows/gather/enum_chocolatey_applications
msf6 post(windows/gather/enum_chocolatey_applications) > set SESSION 12
SESSION => 12
msf6 post(windows/gather/enum_chocolatey_applications) > run
[*] Enumerating applications installed on DESKTOP-LB04G7R
[*] Targets Chocolatey version: 1.0.0
[*] Getting chocolatey applications.
[+] Successfully grabbed all items
Installed Chocolatey Applications
=================================
Name Version
---- -------
GoogleChrome 99.0.4844.82
SQLite 3.38.1
chocolatey 1.0.0
chocolatey-core.extension 1.3.5.1
notepadplusplus 8.3.3
notepadplusplus.install 8.3.3
sublimetext3 3.2.2
[+] Results stored in: /home/rad10/.msf4/loot/20220327160034_default_192.168.56.112_host.application_704988.txt
[*] Post module execution completed
```
100 changes: 100 additions & 0 deletions modules/post/windows/gather/enum_chocolatey_applications.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework

class MetasploitModule < Msf::Post
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather Installed Application Within Chocolatey Enumeration',
'Description' => ' This module will enumerate all installed applications on a Windows system with chocolatey installed ',
'License' => MSF_LICENSE,
'Author' => ['Nick Cottrell <ncottrellweb[at]gmail.com>'],
'Platform' => ['win'],
'Privileged' => false,
'SessionTypes' => %w[meterpreter shell],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => []
}
)
)
register_advanced_options(
[
OptString.new('ChocoPath', [false, 'The path to the chocolatey executable if it\'s not on default path', 'choco.exe']),
]
)
end

def chocopath
if chocolatey?(datastore['ChocoPath'])
return datastore['ChocoPath']
elsif chocolatey?(cmd_exec('where.exe', 'choco.exe'))
return cmd_exec('where.exe', 'choco.exe')
elsif chocolatey?(cmd_exec('where.exe', 'chocolatey.exe'))
return cmd_exec('where.exe', 'chocolatey.exe')
end

nil
end

def chocolatey?(path)
!!(cmd_exec(path, '-v') =~ /\d+\.\d+\.\d+/m)
rescue Rex::Post::Meterpreter::RequestError
false
end

def run
# checking that session is meterpreter and session has powershell
choco_path = chocopath
fail_with(Failure::NotFound, 'Chocolatey path not found') unless choco_path

print_status("Enumerating applications installed on #{sysinfo['Computer']}") if session.type == 'meterpreter'

# getting chocolatey version
choco_version = cmd_exec(choco_path, '-v')
print_status("Targets Chocolatey version: #{choco_version}")

# Getting results of listing chocolatey applications
print_status('Getting chocolatey applications.')

# checking if chocolatey is 2+ or 1.0.0
data = if choco_version.match(/^[10]\.\d+\.\d+$/)
# its version 1, use local only
cmd_exec(choco_path, 'list -lo')
elsif choco_version.match(/^(?:[2-9]|\d{2,})\.\d+\.\d+$/)
# its version 2 or above, no need for local
cmd_exec(choco_path, 'list')
else
fail_with(Failure::UnexpectedReply, "Failed to get chocolatey version. Result was unexpected: #{choco_version}")
end
print_good('Successfully grabbed all items')

# making table to better organize applications and their versions
table = Rex::Text::Table.new(
'Header' => 'Installed Chocolatey Applications',
'Indent' => 1,
'Columns' => %w[
Name
Version
]
)

# collecting all lines that match and placing them into table.
items = data.scan(/^(\S+)\s(\d+(?:\.\d+)*)\r?\n/m)
items.each do |set|
table << set
end
results = table.to_s

# giving results
print_line(results.to_s)
report_note(
host: session.session_host,
type: 'chocolatey.software.enum',
data: items,
update: :unique_data
)
end
end

0 comments on commit fc18093

Please sign in to comment.