mysql日志getshell_某团购CMS的GETSHELL操作代码审计

0x00 写点废话

在渗透测试中,获取一个webshell应该是我们不屑的追求,今天要通过这个CMS从代码的角度看一下可利用的getshell的方法。这一次的代码审计需要借助工具来定位可能存在的漏洞点,选择Seay源代码审计系统。步入正题。

0x01文件上传getshell

9e6318974fe8eaa22c74b2cb4ca799e0.png

1、/kindupload.php:通过获取文件最后一个扩展名进行白名单匹配,且添加随机数命名新文件名,应该不存在文件上传漏洞

1f82b7f6fb89f8006886231d0289e470.png

2、/upload.php:此文件属于测试文件

41898a55cd2c5947443f0d8527648e99.png

3、include/function/common.php:关于$image变量的来源有两个,为null时强制转换jpg格式,当对有图片项目进行编辑时,$image变量就是之前上传的文件地址,这样的话想进行任意文件上传应该就没有可能了。。。。。。

3782f2cf86c500f7d71e4d9bb3658966.png

0x02文件写入+文件包含getshll:

在进行任意文件删除/读取/修改漏洞审计时发现支付日志位置可以向日志文件写入任意内容:漏洞位置:/alifast/alipay.function.php

c604d84f135c21512f106f0456668b17.png

根据定位,可以找到logResult函数:

72ba45166ecd6a7df551420cfb9eb163.png

可以看到其中的$word变量未经过任何check便写入到log.txt文件中(此处写入文件可能比较鸡肋,但如果可以找到任意文件包含,便可以直接getshell)而其中$word变量来源于对函数的引用,我们全局搜索一下看有哪些地方调用了logResult函数:

dca6dc56c8c106c6eb7d65e9ec59ab8b.png

可以找到一处调用,在/alifast/lib/alipay_notify_class.php文件中:

74c6947265674279fa1a6eb6fa9d9291.png

通过verifyNotify函数,当POST数据不为空时就会调用logResult函数进行日志写入,那之后就转到查找何处调用了verifyNotify函数,找到一处调用:/alifast/returnadd_url.php

fac34ce0c53e0271990a2bdb7c1a4c28.png

c32f51de5169f662cd14c2c38b316367.png

而且可以发现此处文件应该不需要登录便可以直接访问:

ad14667f44570cd88d378bc2e86b1cba.png

之后我们传入一个payload,然后开启DEBUG调试一下,看一下参数传递:

0a4ae3224569cfb8dc091dde9a928a07.png

feb6ec6fe347f4fa38b469d252bdc943.png

最后可以看一下log.txt文件,成功写入payload:

3806abe4b1ae829de7b8a74ebf0b5710.png

这需要结合文件读取漏洞才能利用,否则写入到txt文件属于鸡肋,之后便通过对扫描到的可能存在文件包含漏洞的点进行验证,未发现可利用的文件包含漏洞,上面这个任意写入真的鸡肋了。

6bedb38c2f0f22262b337db5dcbbf427.png

不过作为一个搞信息安全的弱鸡,我是不会放弃的。

c2dd3627fe31fb73fd8fab17f6a2e375.png

0x03后台通过修改模板getshell

感觉模板渲染位置最容易存在代码执行漏洞了,之前审计一些其他的CMS也在类似模板渲染位置发现了漏洞,导致getshell。因为系统存在很多模板,便只举一个模板当作栗子。

此处漏洞位置:/include/function/template.php

05b97b77793a947b0bd0ff60d6b15db7.png

在__parse函数中存在preg_replace函数通过e参数进行代码执行。

我们先看在哪些地方对__parse函数进行了调用:

2ebf69583abc389cf75330916fb36844.png

在同文件下58行,通过__tempate函数进行调用。

056d75f338dd5d016fe0a7b5187e85dd.png

再搜索有哪些地方对__template函数进行了调用:

5c210f7fa03550a89b807b8b0337a427.png

在/include/function/common.php文件下存在对__template函数的调用:

cb7515667b998f12724490641c37e712.png

最后就是看有哪些地方调用了template函数:

68fae0bf43d80db3b1af054648da01ae.png

这些调用基本都是进行模板加载的位置,我们先随便找一处:(团购信息提交)

dc5c732f179900c994d2d4fb735b8885.png

接下来还是要开启debug,然后跟踪一下程序执行的逻辑:

1、 访问链接,触发模板解析函数:注意此处采用的include的方式进行模板加载。

d0a17dce113186a66d2fcf0f0115b81d.png

2、进入template函数之后,会根据传递的参数加载不同的模板。

0ab99ba80a18721ac9de39488ad4a289.png

3、当进入__template函数之后要先根据传递的参数加载模板的绝对位置,这里注意,存在一个模板和一个编译后的模板,模板是.html文件,而编译后的模板是.php文件,程序在此处将模板文件路径存在变量$tfile,编译后的模板文件路径存在变量$cFile,之后会利用filemtime函数来比较两个文件的修改时间,如果模板的修改时间小于编译后的模板文件,那说明已经对模板进行过编译,直接返回编译后的模板文件路径。反之才会调用__parse函数对模板进行重新编译。

61419f7c26acf944e0472634c550bb7d.png

根据上面的分析,我们要找到可以修改模板的功能点,不然此处漏洞便无法利用,因为无法满足文件修改时间的检查,除非站长刚好改了模板文件。不过一般站点都提供了模板修改功能,这个CMS也不例外:

0b5f42ba7ca265d6b559d70f71ad4a3d.png

既然后台可以修改模板文件,那就保证模板文件修改时间大于编译后的模板文件,这样就会进入重新编译环节。

6dd62ee9e4558c474142702761e0e5fe.png

我们通过第20行的preg_replace来进行分析:

21c0c356c119c0df2576d598028626b5.png

这个正则表达式会怎么匹配不太好说,直接举一下编译前和编译后的栗子出来就能明白了:

25a300938de82a385017747b45ae4f9a.png

4aad312b62055844bc1c4d26363d0764.png

上面那个正则是如何处理的应该就清楚了。接下来还是继续debug,跟踪模板渲染的具体逻辑:

0bc5d9d2ee79d7d702b7c4256168f967.png

通过正则表达式将模板进行渲染,然后通过file_put_content函数将内容全部写入到渲染后的模板,写入成功则返回true。

56c4e33efa5059dbeec80bfbb73c258e.png

值得注意的是最后返回的是渲染后的模板的物理路径,然后通过include方式加载模板,此时可以看到模板已经通过正则全部替换为php代码。

1dd46eaee14479659e6d79f4abf05922.png

在这个地方存在一个之前的想法错误,其实并不是通过preg_replace来进行代码执行,因为通过/e参数调用的函数是__replace方法,只进行了简单的替换,最后还是通过文件包含的方法来包含存在恶意代码的模板。

a8487749ac689e839720eb29bed3d0df.png

188b3902600930ea0babc674556e6863.png

既然已经清楚模板渲染的流程,接下来尝试getshell操作,首先将模板修改成如下形式:记得闭合双引号,括号等等。

b07d7015bf38dbf40bc794d88b38926b.png

通过编译函数之后模板应该是下面这个样子的:

6f83a8e8d7e0aeda753c04e0ad722ef3.png

最后通过include包含这个含有恶意代码的模板:

da3ea92f65d93cdeec652989881cdc7e.png

0x04数据库备份getshell

在一般系统中通常会存在数据库备份的功能,在渗透测试中利用数据库备份getshell也是常用操作,在这个CMS系统中同样发现了数据库备份与还原功能。

01859bd15ff20381b7b10bf1f113603f.png

但是此处数据库备份的文件是默认的用户不可控的,未发现将恶意代码备份到.php文件当中的操作:

7b5477394ad2e09cf873d88f7030e3db.png

但是在之后对从本地文件恢复数据库的功能进行审计发现,此处存在任意SQL语句执行,相当于给我们提供了一个执行任意SQL语句的接口,那么便可以尝试通过SQL命令导出文件getshell和MySQL日志getshell。先来看一下程序逻辑:

在数据库恢复功能提供了从本地文件恢复的功能:

1e4698c563e458634a9462b74a3eb1ad.png

当本地文件上传到服务器,会通过一个backup_import的函数执行文件内的SQL语句:

4cd89091f0c6c7c3500e7e28d54dd1dd.png

我们跟踪一下这个函数:

9895e892046aaf6eb1b6a277d3309bc2.png

可以看到从文件中读取到SQL语句之后只去掉了几个特殊符号,便通过DB::Query方法直接执行,其中可以再看一下Query方法:未经过任何处理,直接执行SQL语句。

a90133671b9d63a4aca607aa11611a0c.png

已经明白程序的运行逻辑,那么我们便只要构造可以getshell的SQL语句,然后通过备份还原的功能执行SQL语句便能够成功getshell。

上面说MySQL有两种常用的方法getshell:文件导出和日志记录。因为新版的MySQL添加了secure_file_priv参数对文件导入导出进行了限制,这个参数需要修改数据库配置文件,利用困难。

64367b3986cfa842c907cdc3fd4b32b2.png

所以为了提高成功率优先选择利用日志功能getshell。这里还是先介绍一下利用log日志getshell。在MySQL日志功能中:

1、 General_log 指的是日志保存状态,一共有两个值(ON/OFF)ON代表开启 OFF代表关闭。

2、 General_log_file 指的是日志的保存路径。

3、 关于开启general_log参数的作用:

a) 开启它可以记录用户输入的每条命令,会把其保存再general_log_file指定的目录下,就是日志文件。这个参数是可以直接通过mysqld进行设置。

b) 我们的利用的思路是开启general_log之后把general_log_file的值修改为我们网站默认路径下一个自定义的php文件中,然后我们通过log日志进行写入一句话后门到上面去,然后再进一步利用。

通过上面的介绍我们知道要实现日志getshell,要做的以下三步:开启日志功能,重定义日志输出文件(需要绝对路径),执行恶意SQL语句写入日志,具体SQL语句如下:

47b5479d404dda42705e5e0f56438aa5.png

之后上传文件执行SQL语句,然后在之前设置的日志路径下便可以看到带有恶意payload的日志文件了:

bcd49c7c9eacb61426ace36db49c3043.png

4c6e2bfb79098de640bbe96d50106085.png

访问一下链接,成功getshell

ab4b06b6e59416ffd8e678c8d9acb138.png

0x05 收尾

还是来点骚话收尾,上述只是我找到的一些getshell的操作,肯定还会有其他getshll的操作没有被我发现。但是用代码审计的方式从代码角度去看待漏洞形成的原因对漏洞的理解还是有很大帮助的,还是那句话,代码审计一时爽,一直审计一直爽,大家也可以加入代码审计的大军,有兴趣和我这个菜鸡一起成长进步。

声明:作者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关。

合天网安实验室相关实验推荐--代码审计利器-Seay源代码审计系统

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值