GitLab远程代码执行漏洞分析 -【CVE-2018-14364】
漏洞公告
2018年7月17日,Gitlab官方发布安全更新版本,修复了一个远程命令执行漏洞,CVE ID为CVE-2018-14364,该漏洞由长亭研究人员发现,并在hackerone平台提交
影响版本:>= 8.9.0
修复版本:11.0.4, 10.8.6, and 10.7.7
漏洞分析
以版本11.0.3为例。根据版本源码对比
从CHANGELOG.md中得知为Fix symlink vulnerability in project import
主要修改的代码文件为lib/gitlab/import_export/file_importer.rb
主要关注一下extracted_files
。
当我们import一个项目时,会进入到file_import.rb
。然后调用第17行的:
remove_symlinks
用于删除导入文件中存在的符号链接。此前gitlab就因为符号链接的问题爆出过多个RCE问题,因此在这里做了检查:
而extracted_files
定义在61行,这个方法用于列出解压出来的所有文件。
在ruby中,关于正则表达式的符号定义如下:
也就是说%r{.*/\.{1,2}$}
这个正则表达式最后的$
只能匹配到一行的末尾(Matches end of line),而不是整个字符串的末尾(Matches end of string)。
根据POSIX 标准,对于文件名(filename)除了slash character/
和null byte NULL
外,其余字符均可以:
所以只要创建一个名字以\n
开头的符号链接文件,就无法被extracted_files
列出。
回到版本源码对比,在测试文件file_importer_spec.rb里:
因此构建测试环境:
可以看到原本的正则表达式是无法检测到\nevil
文件的:
利用过程
提供一下压缩包生成脚本:
key.pub里保存公钥。其余文件见文末附件压缩包。
创建项目project ,选择Import project
后选择Import an exported GitLab project
待导入成功后,如下图:
注意此时的项目名为test
,同时右下角有一个Remove project
,点击删除掉project,然而此时在gitlab的目录下,test
还没有被删除。
新建一个project,仍然采用Import an exported GitLab project
,然后上传第二个压缩包
第二个压缩包的内容如下,\nevil
是目录名
gitlab在解压第二个压缩包时,会尝试往目录\nevil
里写入.ssh/authorized_keys
,而由于上一步的符号链接\nevil
没有删除,所以实际写入的目录是/var/opt/gitlab/.ssh/authorized_keys
可以看到authorized_keys
已经被写入了公钥。此后用用户名git和公钥对应的私钥直接ssh连接服务器即可。