Skip to content

Commit

Permalink
Support OpenSSL3 and run Ubuntu 22.04 in test matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
adfoster-r7 committed Aug 3, 2022
1 parent 6c2cf58 commit 23d0d33
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 38 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
/usr/bin/docker-compose build
test:
runs-on: ubuntu-18.04
runs-on: ${{ matrix.os }}
timeout-minutes: 40

services:
Expand All @@ -66,8 +66,15 @@ jobs:
ruby:
- 2.6
- 2.7
- 3.0.3
- 3.1.1
- 3.0
- 3.1
os:
- ubuntu-18.04
- ubuntu-22.04
exclude:
- { os: ubuntu-22.04, ruby: 2.6 }
- { os: ubuntu-22.04, ruby: 2.7 }
- { os: ubuntu-22.04, ruby: 3.0 }
test_cmd:
- bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"
- bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content"
Expand Down
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ source 'https://rubygems.org'
# spec.add_runtime_dependency '<name>', [<version requirements>]
gemspec name: 'metasploit-framework'

# gem 'ruby_smb', github: 'adfoster-r7/ruby_smb', branch: 'run-ubuntu-22.04-in-test-matrix'
# gem 'hrr_rb_ssh', github: 'adfoster-r7/hrr_rb_ssh', branch: 'investigate-openssl3-support'
# gem 'openssl-ccm', github: 'adfoster-r7/openssl-ccm', branch: 'add-support-openssl-3'
# gem 'openssl-cmac', github: 'adfoster-r7/openssl-cmac', branch: 'add-support-for-openssl3'
# gem 'metasploit-credential', github: 'adfoster-r7/metasploit-credential', branch: 'add-support-for-openssl3'

# separate from test as simplecov is not run on travis-ci
group :coverage do
# code coverage for tests
Expand Down
10 changes: 5 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ GEM
activemodel (~> 6.0)
activesupport (~> 6.0)
railties (~> 6.0)
metasploit-credential (5.0.7)
metasploit-credential (5.0.8)
metasploit-concern
metasploit-model
metasploit_data_models (>= 5.0.0)
Expand Down Expand Up @@ -287,8 +287,8 @@ GEM
octokit (4.25.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
openssl-ccm (1.2.2)
openssl-cmac (2.0.1)
openssl-ccm (1.2.3)
openssl-cmac (2.0.2)
openvas-omp (0.0.4)
packetfu (1.1.13)
pcaprub
Expand Down Expand Up @@ -429,7 +429,7 @@ GEM
ruby-progressbar (1.11.0)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.5)
ruby_smb (3.1.6)
ruby_smb (3.1.7)
bindata
openssl-ccm
openssl-cmac
Expand Down Expand Up @@ -519,4 +519,4 @@ DEPENDENCIES
yard

BUNDLED WITH
2.1.4
2.2.22
14 changes: 14 additions & 0 deletions config/openssl.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1
29 changes: 29 additions & 0 deletions documentation/modules/auxiliary/scanner/ssl/openssl_heartbleed.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,35 @@ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -node
If you receive `gethostbyname failure` error in `openssl`, add the client (metasploit)
IP and hostname to your hosts file.

### Using docker

Using the environment created by [vulhub](https://github.com/vulhub/vulhub/tree/master/openssl/CVE-2014-0160)

First create a new docker-compose file:

```
version: '2'
services:
nginx:
image: vulhub/openssl:1.0.1c-with-nginx
ports:
- "8080:80"
- "8443:443"
```

Then run `docker-compose up` and verify that the service is running with:

```
$ curl https://localhost:8443 -k
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.11.13</center>
</body>
</html>
```

## Verification Steps

1. Install a vulnerable OpenSSL, start the service
Expand Down
29 changes: 21 additions & 8 deletions lib/msf/core/exploit/remote/http/typo3/login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,28 @@ def typo3_admin_cookie_valid?(cookiestring)
# @param password [String] The clear text password to encrypt
# @return [String] the base64 encoded password with prefixed 'rsa:'
def typo3_helper_login_rsa(e, n, password)
key = OpenSSL::PKey::RSA.new
exponent = OpenSSL::BN.new e.hex.to_s
modulus = OpenSSL::BN.new n.hex.to_s
if key.respond_to?(:set_key)
# Ruby 2.4+
key.set_key(modulus, exponent, nil)
# OpenSSL 3.0+
if OpenSSL::PKey.respond_to?(:generate_key)
exponent = OpenSSL::BN.new e.hex
modulus = OpenSSL::BN.new n.hex
asn1 = OpenSSL::ASN1::Sequence(
[
OpenSSL::ASN1::Integer(modulus),
OpenSSL::ASN1::Integer(exponent),
]
)
key = OpenSSL::PKey::RSA.new(asn1.to_der)
else
key.e = exponent
key.n = modulus
key = OpenSSL::PKey::RSA.new
exponent = OpenSSL::BN.new e.hex.to_s
modulus = OpenSSL::BN.new n.hex.to_s
if key.respond_to?(:set_key)
# Ruby 2.4+
key.set_key(modulus, exponent, nil)
else
key.e = exponent
key.n = modulus
end
end
enc = key.public_encrypt(password)
enc_b64 = Rex::Text.encode_base64(enc)
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/core/exploit/remote/kerberos/client/as_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def build_as_pa_time_stamp(opts = {})
time_stamp = opts[:time_stamp] || Time.now
pausec = opts[:pausec] || 0
etype = opts[:etype] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
key = opts[:key] || ''
key = opts[:key] || OpenSSL::Random.random_bytes(16)

pa_time_stamp = Rex::Proto::Kerberos::Model::PreAuthEncTimeStamp.new(
pa_time_stamp: time_stamp,
Expand Down
7 changes: 7 additions & 0 deletions lib/msf/core/modules/loader/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ def load_module(parent_path, type, module_reference_name, options={})
causal_message: 'invalid module filename (must be lowercase alphanumeric snake case)'
))
return false
rescue => e
load_error(module_path, Msf::Modules::Error.new(
module_path: module_path,
module_reference_name: module_reference_name,
causal_message: "unknown error #{e.message}"
))
return false
end


Expand Down
1 change: 1 addition & 0 deletions lib/msf/util/windows_crypto_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def decrypt_lsa_data(policy_secret, lsa_key)
(60...policy_secret.length).step(16) do |i|
aes.reset
aes.padding = 0
aes.iv = "\x00" * 16
decrypted_data << aes.update(policy_secret[i,16])
end

Expand Down
5 changes: 5 additions & 0 deletions lib/msfenv.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Use bundler to load dependencies
#

# Enable legacy providers such as blowfish-cbc, cast128-cbc, arcfour, etc
ENV['OPENSSL_CONF'] = File.expand_path(
File.join(File.dirname(__FILE__), '..', 'config', 'openssl.conf')
)

# Override the normal rails default, so that msfconsole will come up in production mode instead of development mode
# unless the `--environment` flag is passed.
ENV['RAILS_ENV'] ||= 'production'
Expand Down
32 changes: 24 additions & 8 deletions lib/rex/proto/rfb/cipher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,30 @@ def self.encrypt_ard(username, password, generator, key_length, prime_modulus, p

user_struct = username + ("\0" * (64 - username.length)) + password + ("\0" * (64 - password.length))

dh_peer = OpenSSL::PKey::DH.new(key_length * 8, generator)
dh_peer.set_key(peer_public_key, nil)

dh = OpenSSL::PKey::DH.new(dh_peer)
dh.set_pqg(prime_modulus, nil, generator)
dh.generate_key!

shared_key = dh.compute_key(dh_peer.pub_key)
# OpenSSL 3.0+
if OpenSSL::PKey.respond_to?(:generate_key)
dh = OpenSSL::PKey::DH.new(
OpenSSL::ASN1::Sequence(
[
OpenSSL::ASN1::Integer(prime_modulus),
OpenSSL::ASN1::Integer(generator),
]
).to_der
)
dh = OpenSSL::PKey.generate_key(dh)

shared_key = dh.compute_key(peer_public_key)
else
dh_peer = OpenSSL::PKey::DH.new(key_length * 8, generator)
dh_peer.set_key(peer_public_key, nil)
dh_peer_pub_key = dh_peer.pub_key

dh = OpenSSL::PKey::DH.new(dh_peer)
dh.set_pqg(prime_modulus, nil, generator)
dh.generate_key!

shared_key = dh.compute_key(dh_peer_pub_key)
end

md5 = OpenSSL::Digest.new('MD5')
key_digest = md5.digest(shared_key)
Expand Down
33 changes: 20 additions & 13 deletions modules/auxiliary/scanner/ssl/openssl_heartbleed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -648,23 +648,30 @@ def get_factors(data, n)

# Generates the private key from the P, Q and E values
def key_from_pqe(p, q, e)
# Returns an RSA Private Key from Factors
key = OpenSSL::PKey::RSA.new()
key.set_factors(p, q)

n = key.p * key.q
phi = (key.p - 1) * (key.q - 1 )
n = p * q
phi = (p - 1) * (q - 1 )
d = OpenSSL::BN.new(e).mod_inverse(phi)

key.set_key(n, e, d)

dmp1 = key.d % (key.p - 1)
dmq1 = key.d % (key.q - 1)
iqmp = key.q.mod_inverse(key.p)
dmp1 = d % (p - 1)
dmq1 = d % (q - 1)
iqmp = q.mod_inverse(p)

key.set_crt_params(dmp1, dmq1, iqmp)
asn1 = OpenSSL::ASN1::Sequence(
[
OpenSSL::ASN1::Integer(0),
OpenSSL::ASN1::Integer(n),
OpenSSL::ASN1::Integer(e),
OpenSSL::ASN1::Integer(d),
OpenSSL::ASN1::Integer(p),
OpenSSL::ASN1::Integer(q),
OpenSSL::ASN1::Integer(dmp1),
OpenSSL::ASN1::Integer(dmq1),
OpenSSL::ASN1::Integer(iqmp)
]
)

return key
key = OpenSSL::PKey::RSA.new(asn1.to_der)
key
end

#
Expand Down
6 changes: 6 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# -*- coding: binary -*-

# Enable legacy providers such as blowfish-cbc, cast128-cbc, arcfour, etc
ENV['OPENSSL_CONF'] = File.expand_path(
File.join(File.dirname(__FILE__), '..', 'config', 'openssl.conf')
)

require 'stringio'
require 'factory_bot'
require 'rubocop'
Expand Down

0 comments on commit 23d0d33

Please sign in to comment.