今年多写文章,先把去年的清理一下

Harbor

Harbor是VMware公司开源的企业级Docker Registry项目,用来帮助用户迅速搭建一个企业级的Docker Registry服务。

它以Docker公司开源的registry为基础,提供了管理UI,基于角色的访问控制(Role Based Access Control),AD/LDAP集成、以及审计日志(Auditlogging) 等企业用户需求的功能,同时还原生支持中文。

历史漏洞

CVE-2019-16097

漏洞版本 1.7.0 to 1.7.5 and 1.8.0 to 1.8.2

Harbour 1.7.0 到 1.8.2 中的 core/api/user.go 允许非管理员用户通过 POST /api/users API 创建管理员帐户

相关代码,直接解析传来的数据

image-20221019141407512

正常注册数据

1
{"username":"test","email":"test123@gmai.com","realname":"noname","password":"Password1@11","comment":null}

非预期:

1
{"username":"test","email":"test123@gmai.com","realname":"noname","password":"Password1@11","comment":null,"has_admin_role":true}

has_admin_role 代表是否为管理员,直接创建管理员用户

修复代码:

image-20221019141923017

CVE-2019-16919

漏洞版本:1.8.0 to 1.8.3 and 1.9.0

该漏洞允许项目管理员使用 Harbor API 创建一个机器人帐户,该帐户对他们无权访问或控制的项目具有未经授权的推送或拉取访问权限。Harbor API 没有对 API 请求强制执行适当的项目权限和项目范围以创建新的机器人帐户。

src/core/api/robot.go对比,就是加了一个判断,需要管理员创建没啥说的image-20221019144856634

https://github.com/goharbor/harbor/commit/debf63bcbd17bbeacb4a354de0457684f4ecaa5a

CVE-2019-19023

漏洞版本 1.7.*, 1.8.*, < 1.9.3

该漏洞允许普通用户通过调用 API 来修改特定用户的电子邮件地址,从而获得管理员帐户权限。之后重置该电子邮件地址的密码并访问该帐户。

src/core/api/user.go修复前后对比

image-20221019163318792

修复前是先赋值,后将用户输入转换为 json,这时 userID 就会被覆盖修改为用户输入的 id,可控,这样就可以修改管理员的邮箱,之后再进行重置密码操作,登录管理员;

修复后是先转换,后赋值,userID还是当前登录用户的id,不可控;

cve-2019-xxx

CVE-2019-3990、CVE-2020-13794 非管理员可以进行用户名枚举,

CVE-2019-19025 没有 csrf 保护

CVE-2019-19030 未授权信息探测

1.7.*, 1.8.*, 1.9.*, <2.0.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/api/chartrepo/{repo}/prov (POST)
/api/chartrepo/{repo}/charts (GET, POST)
/api/chartrepo/{repo}/charts/{name} (GET, DELETE)
/api/chartrepo/{repo}/charts/{name}/{version} (GET, DELETE)
/api/labels?name={name}&scope=p (GET)
/api/repositories?project_id={id} (GET)
/api/repositories/{repo_name}/ (GET, PUT, DELETE)
/api/repositories/{repo_name}/tags (GET)
/api/repositories/{repo_name}/tags/{tag}/manifest?version={version} (GET)
/api/repositories/{repo_name/{tag}/labels (GET)
/api/projects?project_name={name} (HEAD)
/api/projects/{project_id}/summary (GET)
/api/projects/{project_id}/logs (GET)
/api/projects/{project_id} (GET, PUT, DELETE)
/api/projects/{project_id}/metadatas (GET, POST)
/api/projects/{project_id}/metadatas/{metadata_name} (GET, PUT)

CVE-2019-19026

漏洞版本: 1.7.*、<1.8.6、<1.9.3

Harbor API的配额部分中存在SQL注入漏洞。经过身份验证的管理员可以通过GET参数排序发送巧尽心思构建的SQL负载,从而允许从数据库中提取敏感信息。

Ps : 官方版本说的根本不对,quota_usage 这个文件 1.9.0 才出现

git checkout v1.9.0

src/common/dao/quota.go

image-20221024105920943

Payload

1
https://xxxxxx/api/quotas?reference=project&page=1&page_size=15&sort=used.count%27%7C%7C(case+when+version()like+%27Postgre%25%27+then+1+else+(select+1+union+select+2)+end)%7C%7C%27

CodeQL

生成数据库codeql database create ./harbor1.9.0 -s /Users/yhy/Documents/CloudNative/harbor/code/harbor/src --language=go ps: 要指定源文件为 src 目录下,虽然上级目录有 makefile,但生成时没有运行 makefile,导致生成后的数据库有问题,sink 点缺失很多。

还有就是 Harbor 使用的是beego框架,该框架有两个版本,Codeql 中的BeegoOrm只写了一种,在go/ql/lib/semmle/go/frameworks/BeegoOrm.qll添加如下代码:

image-20221201200001309

使用官方的ql/src/Security/CWE-089/SqlInjection.ql查询规则,sink 和 source 单独都能跑出来,但是结合到一起,无法找出注入点,经分析大概是因为...造成数据流中断

image-20221025221621454

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
* @Auth Chris Smowton
*/

private predicate isVarargsParam(Parameter p) {
exists(ParameterDecl pd, FuncTypeExpr tp | pd = tp.getAParameterDecl() |
p.getDeclaration() = pd.getANameExpr() and
pd.getTypeExpr() instanceof Ellipsis
)
}

class TaintConfig extends TaintTracking::Configuration {
TaintConfig() { this = "taint-configuration" }

override predicate isAdditionalTaintStep(DataFlow::Node source, DataFlow::Node sink) {
exists(Parameter p, DataFlow::ArgumentNode an, int idx |
an = source and
p = an.getCall().getACallee().getAParameter() and
isVarargsParam(p) and
not an.getCall().hasEllipsis() and
an.argumentOf(_, idx) and
idx >= p.getIndex() and
sink.asParameter() = p
)
}
}

这样虽然可以跟踪隐式数组,但只有当数组本身为污染源才行,对其内的某个元素不起作用。

CVE-2019-19029

漏洞版本: 1.7.*、<1.8.6、<1.9.3

具有项目管理能力的用户可以利用和利用SQL注入从底层数据库读取机密或执行权限提升。

src/core/auth/authproxy/auth.go

image-20221026105816087

src/common/dao/group/usergroup.go

image-20221026110058779

这个问题看代码是当用户验证为AuthProxy/OIDC时,控制请求返回值构造 sql 注入

CVE-2020-13788

漏洞版本: 1.8.*、1.9.*、<2.0.1

一个有限的服务器端请求伪造 (SSRF),它允许 Harbor 项目所有者扫描 Harbor 服务器内部网络上主机的 TCP 端口。

src/common/utils/registry/repository.goimage-20221026154810093

codeql 可以跑出来

当创建项目后,添加 webhook 需要指定Endpoint URL导致的有限 SSRF

CVE-2020-29662

漏洞版本: 2.0.0> x <2.0.5、<2.1.2

api 权限绕过,/v2/_catalog 本意需要管理员权限,但正则写的有问题导致可以使用 /v2/_catalog/ 绕过

image-20221026155946894

image-20221026160127001

修复image-20221026160301763

CVE-2022-xxx

CVE-2022-31667 机器人权限可以被无权访问的用户关闭 PUT /robots/{robot_id}

CVE-2022-31669 更新标签不变性策略时,没有验证用户权限 PUT /projects/{project_name_or_id}/immutabletagrules/{immutable_rule_id}

CVE-2022-31670 更新标签保留策略时,没有验证用户权限 PUT /retentions/{id}

CVE-2022-31666 查看/更新/删除 Webhook时,没有验证用户权限 GET/PUT/DELETE /projects/{project_name_or_id}/webhook/policies/{webhook_policy_id}

CVE-2022-31671 更新/查看P2P preheat execution 日志没有验证用户权限 GET /projects/{project_name}/preheat/policies/{preheat_policy_name}/executions/{execution_id}/tasks/{task_id}/logs

PUT /projects/{project_name}/preheat/policies/{preheat_policy_name}

这。。。。。。