diff --git a/network-services-pentesting/pentesting-postgresql.md b/network-services-pentesting/pentesting-postgresql.md index 2f6e1def5..0606ad5cf 100644 --- a/network-services-pentesting/pentesting-postgresql.md +++ b/network-services-pentesting/pentesting-postgresql.md @@ -145,43 +145,45 @@ PostgreSQL is an open-source relational database management system (RDBMS) that ### Version Detection -To begin the pentesting process, it is crucial to identify the version of PostgreSQL running on the target system. This information can be obtained by sending a simple request to the server using the `pgping` utility or by querying the `version()` function in the database. +To begin the pentesting process, it is crucial to identify the version of PostgreSQL running on the target system. This information can be obtained by sending a simple query to the server: -### Service Discovery +```sql +SELECT version(); +``` -In addition to version detection, it is important to identify other services running on the same network as the PostgreSQL server. This can be done using tools like `nmap` or `netstat` to scan for open ports and identify potential attack vectors. +### User Enumeration + +Once the version is known, the next step is to enumerate the users present in the database. This can be achieved by querying the `pg_user` table: + +```sql +SELECT usename FROM pg_user; +``` + +### Database Enumeration + +After enumerating the users, the next step is to enumerate the databases present on the server. This can be done by querying the `pg_database` table: + +```sql +SELECT datname FROM pg_database; +``` ## Exploitation ### Default Credentials -One common vulnerability in PostgreSQL installations is the use of default or weak credentials. It is important to test for default usernames and passwords, such as `postgres:postgres`, and attempt to gain unauthorized access to the database. +One common vulnerability in PostgreSQL installations is the use of default or weak credentials. It is important to test for default usernames and passwords such as `postgres:postgres` or `admin:admin`. ### SQL Injection -SQL injection is a common attack vector in web applications that use PostgreSQL as the backend database. By injecting malicious SQL queries into user input fields, an attacker can manipulate the database and potentially gain unauthorized access or extract sensitive information. +SQL injection is a common vulnerability that can be exploited in PostgreSQL. It occurs when user-supplied input is not properly sanitized and is directly concatenated into SQL queries. By injecting malicious SQL code, an attacker can manipulate the query and potentially gain unauthorized access to the database. ### Privilege Escalation -Once access to the database has been gained, it is important to escalate privileges to gain further control over the system. This can be done by exploiting misconfigurations, vulnerabilities, or weak permissions within the database or the underlying operating system. - -## Post-Exploitation - -### Data Extraction - -After gaining access to the database, the next step is to extract valuable data. This can include sensitive information such as user credentials, financial data, or personal information. Tools like `pg_dump` or `COPY` commands can be used to export data from the database. - -### Persistence - -To maintain access to the system, it is important to establish persistence. This can be done by creating backdoors, adding new user accounts, or modifying existing user privileges to ensure continued access to the database. - -### Covering Tracks - -To avoid detection, it is important to cover tracks and remove any evidence of the attack. This can include deleting log files, modifying timestamps, or removing any traces of the attacker's presence on the system. +If a low-privileged user account is compromised, it is important to test for privilege escalation vulnerabilities. This involves identifying misconfigurations or vulnerabilities that could allow an attacker to elevate their privileges and gain administrative access to the database. ## Conclusion -Pentesting PostgreSQL installations is crucial for identifying and addressing potential vulnerabilities in web applications. By understanding the enumeration, exploitation, and post-exploitation techniques outlined in this chapter, pentesters can effectively assess the security of PostgreSQL installations and help organizations protect their data. +Pentesting PostgreSQL installations is an essential part of ensuring the security of web applications. By understanding the enumeration and exploitation techniques outlined in this guide, pentesters can effectively identify and mitigate vulnerabilities in PostgreSQL deployments. ``` DETAIL: FATAL: password authentication failed for user "name" ``` @@ -207,7 +209,7 @@ Infelizmente, não parece haver uma maneira de obter os detalhes da exceção de | rolconnlimit | Para funções que podem fazer login, isso define o número máximo de conexões simultâneas que essa função pode fazer. -1 significa sem limite. | | rolpassword | Não é a senha (sempre lida como `********`) | | rolvaliduntil | Tempo de expiração da senha (usado apenas para autenticação de senha); nulo se não houver expiração | -| rolbypassrls | A função ignora todas as políticas de segurança de nível de linha, consulte [Seção 5.8](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) para obter mais informações. | +| rolbypassrls | A função ignora todas as políticas de segurança em nível de linha, consulte [Seção 5.8](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) para obter mais informações. | | rolconfig | Valores padrão específicos da função para variáveis de configuração em tempo de execução | | oid | ID da função | @@ -265,45 +267,33 @@ CREATE ROLE u LOGIN PASSWORD 'lriohfugwebfdwrr' IN GROUP pg_read_server_files; ``` ### Tabelas -PostgreSQL databases consist of tables, which are used to organize and store data. Tables are made up of rows and columns, similar to a spreadsheet. Each row represents a single record, and each column represents a specific attribute or field of that record. +PostgreSQL databases consist of tables, which are used to organize and store data. Each table is made up of columns and rows. Columns define the type of data that can be stored in a table, while rows represent individual records or entries. -To view the tables in a PostgreSQL database, you can use the `\dt` command in the PostgreSQL command-line interface (CLI). This command will display a list of all the tables in the current database. +As a penetration tester, it is important to understand the structure and content of the tables in a PostgreSQL database. This knowledge can help you identify potential vulnerabilities and weaknesses that can be exploited during a penetration test. -```sql -\dt -``` +To gather information about the tables in a PostgreSQL database, you can use various techniques and tools. One common approach is to query the system catalog tables, such as `pg_tables` and `pg_class`, which store metadata about the tables in the database. -To view the structure of a specific table, you can use the `\d` command followed by the table name. This command will show the columns, data types, and constraints of the table. +Here are some techniques you can use to gather information about tables during a PostgreSQL penetration test: -```sql -\d table_name -``` +1. **Enumerating Tables**: Use SQL queries to enumerate the tables in the database. For example, you can use the following query to list all the tables in the current database: -To query data from a table, you can use the `SELECT` statement. This statement allows you to retrieve specific columns or all columns from a table based on certain conditions. + ```sql + SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'; + ``` -```sql -SELECT column1, column2 FROM table_name WHERE condition; -``` +2. **Extracting Table Data**: Use SQL queries to extract data from specific tables. For example, you can use the following query to retrieve all the data from a table named `users`: -To insert data into a table, you can use the `INSERT INTO` statement. This statement allows you to add new rows to a table with specified values for each column. + ```sql + SELECT * FROM users; + ``` -```sql -INSERT INTO table_name (column1, column2) VALUES (value1, value2); -``` +3. **Analyzing Table Structure**: Use SQL queries to analyze the structure of a table, including the column names, data types, and constraints. For example, you can use the following query to retrieve the column names and data types of a table named `users`: -To update existing data in a table, you can use the `UPDATE` statement. This statement allows you to modify the values of specific columns in one or more rows based on certain conditions. + ```sql + SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'users'; + ``` -```sql -UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition; -``` - -To delete data from a table, you can use the `DELETE FROM` statement. This statement allows you to remove one or more rows from a table based on certain conditions. - -```sql -DELETE FROM table_name WHERE condition; -``` - -Understanding how tables work in PostgreSQL is essential for effective database management and data manipulation. +By using these techniques, you can gain valuable insights into the tables in a PostgreSQL database and identify potential security issues that can be exploited during a penetration test. ```sql # Get owners of tables select schemaname,tablename,tableowner from pg_tables; @@ -339,7 +329,7 @@ Let's break down the syntax: - `CREATE FUNCTION`: This is the statement used to create a function. - `function_name`: The name of the function you want to create. -- `(parameter1 datatype, parameter2 datatype, ...)`: The input parameters of the function, if any. Each parameter is specified with a name and a data type. +- `(parameter1 datatype, parameter2 datatype, ...)`: The input parameters for the function, if any. Each parameter is specified with a name and a data type. - `RETURNS return_type`: The return type of the function. This specifies the data type of the value that the function will return. - `LANGUAGE language_name`: The programming language in which the function is written. PostgreSQL supports multiple languages, including SQL, PL/pgSQL, and others. - `AS`: This keyword is used to indicate the start of the function's code block. @@ -347,29 +337,37 @@ Let's break down the syntax: #### Example -Let's say we want to create a function that calculates the sum of two numbers. Here is an example of how to create such a function in PostgreSQL: +Here is an example of a simple function that calculates the square of a given number: ```sql -CREATE FUNCTION calculate_sum (num1 integer, num2 integer) +CREATE FUNCTION square(num integer) RETURNS integer - LANGUAGE plpgsql + LANGUAGE SQL AS $$ -BEGIN - RETURN num1 + num2; -END; + SELECT num * num; $$; ``` -In this example, we create a function called `calculate_sum` that takes two integer parameters (`num1` and `num2`) and returns an integer. The function's code block simply adds the two numbers together and returns the result. +In this example, the function is named `square` and takes an integer parameter `num`. It returns an integer value, which is the square of the input number. The function is written in SQL language and the code block simply performs the multiplication operation. -Once the function is created, you can call it like any other function in PostgreSQL. For example: +#### Calling Functions + +Once a function is created, you can call it by using its name and passing the required arguments. Here is the syntax for calling a function: ```sql -SELECT calculate_sum(5, 3); +SELECT function_name(argument1, argument2, ...) ``` -This will return the result `8`, which is the sum of `5` and `3`. +For example, to call the `square` function we created earlier and calculate the square of the number 5, you would use the following query: + +```sql +SELECT square(5); +``` + +This would return the result `25`, which is the square of 5. + +Functions are a powerful feature in PostgreSQL that allow you to encapsulate complex logic and reuse it in your queries. They can greatly enhance the functionality and maintainability of your database applications. ```sql # Interesting functions are inside pg_catalog \df * #Get all @@ -436,12 +434,16 @@ Você pode encontrar **mais funções** em [https://www.postgresql.org/docs/curr ### Escrita Simples de Arquivo -Apenas **super usuários** e membros de **`pg_read_server_files`** podem usar o comando copy para escrever arquivos. +Apenas **super usuários** e membros de **`pg_write_server_files`** podem usar o comando copy para escrever arquivos. + +{% code overflow="wrap" %} ```sql copy (select convert_from(decode('','base64'),'utf-8')) to '/just/a/path.exec'; ``` +{% endcode %} + {% hint style="warning" %} -Lembre-se de que, se você não é um super usuário, mas tem permissões de **`CREATEROLE`**, você pode **tornar-se membro desse grupo:** +Lembre-se de que se você não for um super usuário, mas tiver permissões **`CREATEROLE`**, você pode **tornar-se membro desse grupo:** ```sql GRANT pg_write_server_files TO username; ``` @@ -545,7 +547,7 @@ Ao testar isso, notei que isso só funcionará se o **arquivo da chave privada t Outro atributo no arquivo de configuração que é explorável é `archive_command`. -Para isso funcionar, a configuração `archive_mode` deve ser `'on'` ou `'always'`. Se isso for verdadeiro, então podemos sobrescrever o comando em `archive_command` e forçá-lo a ser executado por meio das operações de WAL (write-ahead logging). +Para isso funcionar, a configuração `archive_mode` deve ser `'on'` ou `'always'`. Se isso for verdade, então podemos sobrescrever o comando em `archive_command` e forçá-lo a ser executado por meio das operações de WAL (write-ahead logging). Os passos gerais são: @@ -641,7 +643,7 @@ LANGUAGE sql VOLATILE AS 'COPY public.shell_commands_results (data) FROM PROGRAM ANALYZE public.temp_table; ``` -Após executar a consulta de exploração SQL, a tabela `shell_commands_results` contém a saída do código executado: +Depois de executar a consulta de exploração SQL, a tabela `shell_commands_results` contém a saída do código executado: ``` uid=2345(postgres) gid=2345(postgres) groups=2345(postgres) ``` @@ -701,7 +703,7 @@ PERFORM dblink_disconnect(); … -Como [**explicado na documentação**](https://www.postgresql.org/docs/current/sql-createfunction.html), uma função com **SECURITY DEFINER é executada** com os privilégios do **usuário que a possui**. Portanto, se a função for **vulnerável a Injeção de SQL** ou estiver realizando alguma **ação privilegiada com parâmetros controlados pelo atacante**, ela poderá ser explorada para **elevar privilégios dentro do postgres**. +Como [**explicado na documentação**](https://www.postgresql.org/docs/current/sql-createfunction.html), uma função com **SECURITY DEFINER é executada** com os privilégios do **usuário que a possui**. Portanto, se a função for **vulnerável a Injeção de SQL** ou estiver realizando alguma **ação privilegiada com parâmetros controlados pelo atacante**, ela poderá ser abusada para **elevar privilégios dentro do postgres**. Na linha 4 do código anterior, você pode ver que a função possui a flag **SECURITY DEFINER**. ```sql @@ -713,7 +715,7 @@ E então **execute comandos**:
-### Passar por Burteforce com PL/pgSQL +### Passar Burteforce com PL/pgSQL PL/pgSQL, como uma **linguagem de programação completa**, permite um controle procedural muito maior do que o SQL, incluindo a **capacidade de usar loops e outras estruturas de controle**. Declarações SQL e gatilhos podem chamar funções criadas na linguagem PL/pgSQL.\ **Você pode abusar dessa linguagem para pedir ao PostgreSQL que faça força bruta nas credenciais dos usuários.**