时间:2020-7-3来源:本站原创作者:佚名

引子:钻研技术,发现问题

ThinkPHP框架是国内著名的PHP开源框架,因其灵活和功能强大拥有众多用户。俗话说树大招风,前几年修复了若干严重的漏洞,如远程代码执行(RCE)、本地文件包含(LFI)和SQL注入等等。先森一直在ThinkPHP框架的门口观望,没有系统地学习过,于是打算这些天好好补补这方面。这不正好学到SQL操作的章节,借此可以好好研究TP框架的SQL注入与防御。于是写了一个简单的SQL语句,尝试调试查看TP底层最终处理后的语句,当然TP框架也内置了功能,如在\tp\config\app.php里开启”app_debug”和”app_trace”选项实现应用调试及追踪、在\tp\config\database.php里开启”debug”选项实现记录SQL操作等。光这些还不够,为了更简便操作,至少还要配合MySQL语句监控工具等。这里我习惯使用“Seay代码审计系统”的“Mysql监控”插件,它可以记录MySQL上用户执行的所有SQL操作,该工具原理是基于数据库中的general_log功能,将监控到的SQL语句转存到mysql.general_log表中然后再按需筛选出来。这里我写了一个非常简单的demo,该脚本的功能是通过查询指定id来返回用户的所有信息,TP底层最终执行的语句应该是”select*fromthink_userwhereid=xxx”。在浏览器里按TP框架的访问方式,依次填入指定的模块、控制器、方法和参数访问后,浏览器按预定想法回显了我们数据,框架内置的调试器也显示执行了两条查询,但是我的“神器”却无任何有意义的回显。于是我诧异地跑到MySQL的管理工具里执行这个查询操作,这次确实可以监控到执行的SQL语句,所以排除了该工具存在故障的可能性。这就有些颠覆了我对MySQL数据库和ThinkPHP框架的认知,要知道MySQL中general_log功能的作用就是记录用户的所有操作,堂堂一个Oracle公司不可能出这种问题吧?!于是找到几位搞技术的朋友请教一下这个情况,他们对此也感到奇怪。但忙于工作和其他事情,无暇研究这个问题…俗话说自己动手丰衣足食,加之对逆向工程越来越有浓厚兴趣了(后面会有对工具的逆向过程),便开始了这场刨根问底的行动。索性将TP框架中的增删改查的方法都试了一遍,连朋友提到的TP两种的原生执行SQL的方法也是这样,发现真的都不行。我简单的追溯了下TP底层是如何处理数据库操作。从query函数出发-经由核心功能think\Query.php中的query方法-经由核心功能think\Collection.php中的query方法,发现最终是被PDO的prepare方法处理,简而言之就是经由SQL预处理了。所以问题是不是可能出在预处理上了?为了更好的验证这个猜测,我写了一个mysqli下的预处理查询脚本,功能是查询think_user表中id为3的用户信息。通过浏览器的回显可以认定这三种查询方式是完全没问题的,但是Mysql监控工具的回显结果却不尽人意。所以综上,我们可以推测出是SQL编译预处理环节的问题。

上面部分内容可以说只是一个引子,文中咱们简单提过general_log日志但并未作过多探讨。之前发过的几篇文章里或多或少有提到过MySQL取证,但未系统地介绍,说到MySQL取证,大致可以分为MySQL日志分析、MySQL数据恢复和仿真MySQL环境,其中仿真那部分我在上一篇的《大项目》里详细的提到了,这里只对日志分析和数据恢复做一番探讨和一下小小的总结。(这部分主要是让大家简单系统地了解MySQL日志的构成和相关知识,能力有限,想具体深入地分析请看文章底部的参考来源。成文匆忙,若发现纰漏请及时告知,谢谢)

我们先来探讨MySQL日志

根据我的实战经验以及网友分享的文章,MySQL的日志主要体现在记录SQL操作的general日志(注Linux下本机操作还会有.mysql_history)、变更日志binlog(主要用于备份和数据恢复)、以hostname.err格式存放的错误日志和用于优化目的的slow日志。

一、通用查询日志(generalquerylog)

通用查询日志用于记录MySQL上所有用户执行的SQL命令(但不记录返回结果),该功能类似Linux系统下的.bash_history,无论用户执行的命令和语法是否正确都将被记录。默认情况下MySQL不会开启该功能,这是因为数据库本身就占用服务器大量的读写操作,开启后会不断进行写入操作,这将大大地增加系统开销,对企业而言这也是一个不必要的负担;但是另一方开启该功能可以方便数据库管理员审计和分析MySQL中可能存在的问题,提高服务的安全性和可靠性。

查看general_log是否开启及配置信息。执行SQL命令:showvariableswherevariable_namelike"%general_log%"orvariable_name="log_output";,意思是通过MySQL环境变量来查看general_log是否开启、日志的保存方式及位置。其中日志的存放方式分为两种(file和table)、方案分为三种(file、table和filetable),若是file型则以文件的形式默认存放在data目录,若是table型则将所有SQL记录转存至mysql库中的general_log表中。

general_log的表结构。该表主要由6个字段构成,分别是用于记录时间的event_time、记录连接者IP和主机名的user_host、识别每次操作线程号的thread_id、区分主从(猜测)的server_id、记录操作类型的
转载请注明原文网址:http://www.helimiaopu.com/cksc/7752.html

------分隔线----------------------------