diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/apache_couchdb.pp b/modules/vulnerabilities/unix/http/apache_couchdb/apache_couchdb.pp new file mode 100644 index 000000000..3de080a1e --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/apache_couchdb.pp @@ -0,0 +1,7 @@ +# begining of puppet code execution +contain apache_couchdb::install +contain apache_couchdb::couchdb +contain apache_couchdb::configure +Class['apache_couchdb::install'] +-> Class['apache_couchdb::couchdb'] +-> Class['apache_couchdb::configure'] diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/files/couchdb_3.2.1_buster_amd64.deb b/modules/vulnerabilities/unix/http/apache_couchdb/files/couchdb_3.2.1_buster_amd64.deb new file mode 100644 index 000000000..1f94d2822 Binary files /dev/null and b/modules/vulnerabilities/unix/http/apache_couchdb/files/couchdb_3.2.1_buster_amd64.deb differ diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/manifests/configure.pp b/modules/vulnerabilities/unix/http/apache_couchdb/manifests/configure.pp new file mode 100644 index 000000000..866e6fe4b --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/manifests/configure.pp @@ -0,0 +1,32 @@ +class apache_couchdb::configure { + $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file) + $database = 'couchdb' + $user = $secgen_parameters['leaked_username'][0] + $password = $secgen_parameters['leaked_password'][0] + $jsondb = 'sampledata' ##TODO secgen + $strings_to_leak = $secgen_parameters['strings_to_leak'] + $leaked_filenames = $secgen_parameters['leaked_filenames'] + $user_home = "/home/${user}" + + Exec { path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin'] } + + #create database + #exec { 'create-database': + # command => "curl -X PUT http://localhost:34023/${database} -u \"${username}:${password}\"", + # logoutput => true + #}-> + #exec { 'import_data': + # cwd=> '/usr/bin/', + # command => "curl -d @${jsondb}.json -H \"Content-type: application/json\" -X POST http://127.0.0.1:34023/${database}/_bulk_docs -u \"${username}:${password}\"", + # logoutput => true + #} + + ::secgen_functions::leak_files { 'couchdb-flag-leak': + storage_directory => $user_home, + leaked_filenames => $leaked_filenames, + strings_to_leak => $strings_to_leak, + owner => $user, + mode => '0644', + leaked_from => 'apache_couchdb', + } +} diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/manifests/couchdb.pp b/modules/vulnerabilities/unix/http/apache_couchdb/manifests/couchdb.pp new file mode 100644 index 000000000..518d59366 --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/manifests/couchdb.pp @@ -0,0 +1,67 @@ +class apache_couchdb::couchdb { + $secgen_parameters=secgen_functions::get_parameters($::base64_inputs_file) + $username = $secgen_parameters['leaked_username'][0] + $password = $secgen_parameters['leaked_password'][0] + $host ='127.0.0.1' + $docroot = '/opt/couchdb' + $database_dir = '/var/lib/couchdb' + $uid = fqdn_uuid('localhost.com') + $port = $secgen_parameters['port'][0] + + Exec { path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin'] } + #create user + #create system user + user { $username: + ensure => present, + shell => '/bin/bash', + password => pw_hash($password, 'SHA-512', 'mysalt'), + } + #set folder permissions + -> exec { 'chown-couchdb': + command => "chown -R ${username}:${username} ${docroot}", + logoutput => true + } + -> exec { 'chmod-couchdb': + command => "chmod -R 770 ${docroot}", + logoutput => true + } + #configuration file + -> file { "${docroot}/etc/local.ini" : + ensure => file, + content => template('apache_couchdb/local.ini.erb'), + } + # add vm.args files + -> file { "${docroot}/etc/vm.args": + ensure => file, + content => template('apache_couchdb/vm.args.erb'), + notify => Exec['restart-couchdb'], + } + + #restart couch db + exec {'restart-couchdb': + command => 'systemctl restart couchdb', + logoutput => true, + notify => Exec['wait-apache-couchdb'], + } + + exec { 'wait-apache-couchdb': + command => 'sleep 4', + logoutput => true, + notify => Exec['chown-uri-file'], + } + + exec { 'chown-uri-file': + command => "chown -R ${username}:${username} /var/run/couchdb/", + logoutput => true, + } + -> exec { 'chmod-uri-file': + command => 'chmod -R 770 /var/run/couchdb/', + logoutput => true, + } + -> service { 'epmd-restart': + name => 'epmd', + restart => '', + flags => '-port 1337', + } +} + diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/manifests/install.pp b/modules/vulnerabilities/unix/http/apache_couchdb/manifests/install.pp new file mode 100644 index 000000000..298088377 --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/manifests/install.pp @@ -0,0 +1,38 @@ +class apache_couchdb::install { + $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file) + $responsefile = 'installresponse' + $packagename = 'couchdb_3.2.1_buster_amd64' + $jsondb = 'sampledata.json' + $password = $secgen_parameters['leaked_password'][0] + + Exec { path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin'] } + + ensure_packages(['build-essential', + 'pkg-config', + 'erlang', + 'libicu-dev', + 'libmozjs-60-dev', + 'libcurl4-openssl-dev', + 'gnupg']) + + # copy archive + file { "/usr/local/src/${packagename}.deb" : + ensure => file, + source => "puppet:///modules/apache_couchdb/${packagename}.deb", + } + -> file { "/usr/bin/${responsefile}" : + ensure => file, + content => template("apache_couchdb/${responsefile}.erb"), + } + -> file { "/usr/bin/${jsondb}.json" : + ensure => file, + content => template("apache_couchdb/${jsondb}.erb"), + } + #install couch db from deb file + -> package {'couchdb-install': + name => $packagename, + provider => dpkg, + source => "/usr/local/src/${packagename}.deb", + responsefile => $responsefile, + } +} diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/secgen_metadata.xml b/modules/vulnerabilities/unix/http/apache_couchdb/secgen_metadata.xml new file mode 100644 index 000000000..597a781ce --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/secgen_metadata.xml @@ -0,0 +1,71 @@ + + + Apache CouchDB Unauthenticated RCE + Sofia Markusfeld + James Davis + Apache v2 + + Apache CouchDB versions 3.2.1 and below default installation settings are vulnerable to an + Earling RCE exploit. + + + remote + user_rwx + remote + linux + low + + port + known_username + known_password + strings_to_leak + strings_to_preleak + leaked_filenames + + + + + + + + + + + + + + + + couchdb + + + + + + + + + CVE-2022-24706 + 9 + AV:N/AC:L/Au:N/C:C/I:C/A:C + https://www.exploit-db.com/exploits/50914 + + https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/multi/http/apache_couchdb_erlang_rce.rb + Apache CouchDB + Apache + + + This exploit is based off on 1F98D's Erlang Cookie - Remote Code Execution + + + update + + + + \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/templates/installresponse.erb b/modules/vulnerabilities/unix/http/apache_couchdb/templates/installresponse.erb new file mode 100644 index 000000000..85b99fdd3 --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/templates/installresponse.erb @@ -0,0 +1,8 @@ +<%= @packagename %> couchdb/mode select standalone +<%= @packagename %> couchdb/mode seen true +<%= @packagename %> couchdb/bindaddress string 127.0.0.1 +<%= @packagename %> couchdb/bindaddress seen true +<%= @packagename %> couchdb couchdb/adminpass password ${<%= @password %>} +<%= @packagename %> couchdb couchdb/adminpass seen true +<%= @packagename %> couchdb couchdb/adminpass_again password ${<%= @password %>} +<%= @packagename %> couchdb couchdb/adminpass_again seen true diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/templates/local.ini.erb b/modules/vulnerabilities/unix/http/apache_couchdb/templates/local.ini.erb new file mode 100644 index 000000000..426e5784a --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/templates/local.ini.erb @@ -0,0 +1,106 @@ +; CouchDB Configuration Settings + +; Custom settings should be made in this file. They will override settings +; in default.ini, but unlike changes made to default.ini, this file won't be +; overwritten on server upgrade. + +[couchdb] +max_document_size = 4294967296 ; bytes +os_process_timeout = 5000 +database_dir = <%= @database_dir %> +default_security = admin_only +file_compression = snappy +max_dbs_open = 100 +single_node = true +uri_file = /var/run/couchdb/couchdb.uri +users_db_suffix = _users +util_driver_dir = /usr/lib/couchdb/erlang/lib/couch-1.5.0/priv/lib +uuid = <%= @uid %> +view_index_dir = /var/lib/couchdb + + +[couch_peruser] +; If enabled, couch_peruser ensures that a private per-user database +; exists for each document in _users. These databases are writable only +; by the corresponding user. Databases are in the following form: +; userdb-{hex encoded username} +;enable = true +; If set to true and a user is deleted, the respective database gets +; deleted as well. +;delete_dbs = true +; Set a default q value for peruser-created databases that is different from +; cluster / q +;q = 1 + +[chttpd] +port = <%= @port %> +bind_address = <%= @host %> +; Options for the MochiWeb HTTP server. +;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] +; For more socket options, consult Erlang's module 'inet' man page. +;socket_options = [{sndbuf, 262144}, {nodelay, true}] + +[httpd] +; NOTE that this only configures the "backend" node-local port, not the +; "frontend" clustered port. You probably don't want to change anything in +; this section. +; Uncomment next line to trigger basic-auth popup on unauthorized requests. +;WWW-Authenticate = Basic realm="administrator" + +; Uncomment next line to set the configuration modification whitelist. Only +; whitelisted values may be changed via the /_config URLs. To allow the admin +; to change this value over HTTP, remember to include {httpd,config_whitelist} +; itself. Excluding it from the list would require editing this file to update +; the whitelist. +;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] + +[chttpd_auth] +; If you set this to true, you should also uncomment the WWW-Authenticate line +; above. If you don't configure a WWW-Authenticate header, CouchDB will send +; Basic realm="server" in order to prevent you getting logged out. + require_valid_user = false + +[ssl] +;enable = true +;cert_file = /full/path/to/server_cert.pem +;key_file = /full/path/to/server_key.pem +;password = somepassword +; set to true to validate peer certificates +;verify_ssl_certificates = false +; Set to true to fail if the client does not send a certificate. Only used if verify_ssl_certificates is true. +;fail_if_no_peer_cert = false +; Path to file containing PEM encoded CA certificates (trusted +; certificates used for verifying a peer certificate). May be omitted if +; you do not want to verify the peer. +;cacert_file = /full/path/to/cacertf +; The verification fun (optional) if not specified, the default +; verification fun will be used. +;verify_fun = {Module, VerifyFun} +; maximum peer certificate depth +;ssl_certificate_max_depth = 1 +; +; Reject renegotiations that do not live up to RFC 5746. +;secure_renegotiate = true +; The cipher suites that should be supported. +; Can be specified in erlang format "{ecdhe_ecdsa,aes_128_cbc,sha256}" +; or in OpenSSL format "ECDHE-ECDSA-AES128-SHA256". +;ciphers = ["ECDHE-ECDSA-AES128-SHA256", "ECDHE-ECDSA-AES128-SHA"] +; The SSL/TLS versions to support +;tls_versions = [tlsv1, 'tlsv1.1', 'tlsv1.2'] + +; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to +; the Virual Host will be redirected to the path. In the example below all requests +; to http://example.com/ are redirected to /database. +; If you run CouchDB on a specific port, include the port number in the vhost: +; example.com:5984 = /database +[vhosts] +;example.com = /database/ + +; To create an admin account uncomment the '[admins]' section below and add a +; line in the format 'username = password'. When you next start CouchDB, it +; will change the password to a hash (so that your passwords don't linger +; around in plain-text files). You can add more admin accounts with more +; 'username = password' lines. Don't forget to restart CouchDB after +; changing this. +[admins] +<%= @username %> = <%= @password %> \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/templates/sampledata.json.erb b/modules/vulnerabilities/unix/http/apache_couchdb/templates/sampledata.json.erb new file mode 100644 index 000000000..571a7ae7c --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/templates/sampledata.json.erb @@ -0,0 +1,43 @@ +{ + "docs": [ + { + "id": 1, + "pantone_value": "11-0103", + "name": "egret", + "hex": "#f3ece0" + }, + { + "id": 2, + "pantone_value": "11-0602", + "name": "snow-white", + "hex": "#f2f0eb" + }, + { + "id": 3, + "name": "true red", + "year": 2002, + "color": "#BF1932", + "pantone_value": "19-1664" + }, + { + "id": 4, + "name": "aqua sky", + "year": 2003, + "color": "#7BC4C4", + "pantone_value": "14-4811" + }, + { + "id": 5, + "year": 2004, + "color": "#E2583E", + "pantone_value": "17-1456" + }, + { + "id": 6, + "name": "blue turquoise", + "year": 2005, + "color": "#53B0AE", + "pantone_value": "15-5217" + } + ] +} \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/apache_couchdb/templates/vm.args.erb b/modules/vulnerabilities/unix/http/apache_couchdb/templates/vm.args.erb new file mode 100644 index 000000000..3eb659fca --- /dev/null +++ b/modules/vulnerabilities/unix/http/apache_couchdb/templates/vm.args.erb @@ -0,0 +1,96 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +# Each node in the system must have a unique name. These are specified through +# the Erlang -name flag, which takes the form: +# +# -name nodename@ +# +# or +# +# -name nodename@ +# +# CouchDB recommends the following values for this flag: +# +# 1. If this is a single node, not in a cluster, use: +# -name couchdb@127.0.0.1 +# +# 2. If DNS is configured for this host, use the FQDN, such as: +# -name couchdb@my.host.domain.com +# +# 3. If DNS isn't configured for this host, use IP addresses only, such as: +# -name couchdb@192.168.0.1 +# +# Do not rely on tricks with /etc/hosts or libresolv to handle anything +# other than the above 3 approaches correctly. They will not work reliably. +# +# Multiple CouchDBs running on the same machine can use couchdb1@, couchdb2@, +# etc. +-name couchdb@<%= @host %> + +# All nodes must share the same magic cookie for distributed Erlang to work. +# Comment out this line if you synchronized the cookies by other means (using +# the ~/.erlang.cookie file, for example). +-setcookie monster + +# Tell kernel and SASL not to log anything +-kernel error_logger silent +-sasl sasl_error_logger false + +# Use kernel poll functionality if supported by emulator ++K true + +# Start a pool of asynchronous IO threads ++A 16 + +# Comment this line out to enable the interactive Erlang shell on startup ++Bd -noinput + +# Force use of the smp scheduler, fixes #1296 +-smp enable + +# Set maximum SSL session lifetime to reap terminated replication readers +-ssl session_lifetime 300 + +## TLS Distribution +## Use TLS for connections between Erlang cluster members. +## http://erlang.org/doc/apps/ssl/ssl_distribution.html +## +## Generate Cert(PEM) File +## This is just an example command to generate a certfile (PEM). +## This is not an endorsement of specific expiration limits, key sizes, or algorithms. +## $ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem +## $ cat key.pem cert.pem > dev/erlserver.pem && rm key.pem cert.pem +## +## Generate a Config File (couch_ssl_dist.conf) +## [{server, +## [{certfile, ""}, +## {secure_renegotiate, true}]}, +## {client, +## [{secure_renegotiate, true}]}]. +## +## CouchDB recommends the following values for no_tls flag: +## 1. Use TCP only, set to true, such as: +## -couch_dist no_tls true +## 2. Use TLS only, set to false, such as: +## -couch_dist no_tls false +## 3. Specify which node to use TCP, such as: +## -couch_dist no_tls \"*@127.0.0.1\" +## +## To ensure search works, make sure to set 'no_tls' option for the clouseau node. +## By default that would be "clouseau@127.0.0.1". +## Don't forget to override the paths to point to your certificate(s) and key(s)! +## +#-proto_dist couch +#-couch_dist no_tls \"clouseau@127.0.0.1\" +#-ssl_dist_optfile +-couch_ini <%= @docroot %>/etc/default.ini <%= @docroot %>/etc/local.ini diff --git a/scenarios/examples/vulnerability_examples/apache_couchdb.xml b/scenarios/examples/vulnerability_examples/apache_couchdb.xml new file mode 100644 index 000000000..16ba23b10 --- /dev/null +++ b/scenarios/examples/vulnerability_examples/apache_couchdb.xml @@ -0,0 +1,16 @@ + + + + + + couchdb + + + + + + + + \ No newline at end of file