ThinkPHP是一个高效、兼容且简单的轻量级PHP开发框架,支持Windows/Unix/Linux服务器环境,正式版本要求PHP5.0或更高版本,并兼容MySql、PgSQL、Sqlite多种数据库以及PDO扩展。佳哥在i 春秋论坛分享了自己学习ThinkPHP3.2.3漏洞分析过程的完整记录,内容适合初学者,未经许可,严禁转载。本文将详细解析ThinkPHP3.2.3中的几个常见漏洞:where注入、exp注入、bind注入、find/select/delete注入、order by注入和缓存漏洞。在控制器中使用字符串方式作为where参数时,存在where注入漏洞。通过在变量user处设置断点并使用PHPSTROM F7进入,可以看到I方法获取了传入的参数。重点在于过滤函数,首先使用htmlspecialchars过滤参数,然后利用think_filter过滤常规SQL函数。在where方法中,将$where的值放入到$options["where"]数组中。继续跟进查看find方法,最终生成完整SQL语句。关键在于parseWhere方法的执行,进而解析出具体的注入payload。exp注入漏洞中,使用全局数组进行传参,可以激活漏洞。直接在$user处设置断点,F7跟进,跳过where方法,继续跟进find、select、buildSelectSql、parseSql和parseWhere方法。在跟进parseWhereItem方法时,参数$val为数组形式,{‘exp’,‘sql注入exp’}。此时,当$exp满足exp时,参数与值进行拼接,最终payload为sql注入exp。bind注入漏洞中,使用save方法进行演示。生成SQL语句在update方法中,在parseSet方法中,传入的参数被替换成:0。在bindParam方法中,将参数值包裹在冒号(:)中。继续跟进parseWhere和parseWhereItem方法,当exp为bind时,参数值前面会加上冒号(:)。由于SQL语句中已有冒号,因此在excute方法中,:0被替换成了第二个参数的值,最终payload为。find注入中,当传入id[where]=1p时,导致不能执行_parseType方法转化数据。继续跟进select、buildSelectSql、parseSql和parseWhere方法,传入的$where为字符串,直接执行了if语句。当传入id=1p时,无法执行注入,原因在于find、_parseOptions、_parseType方法将传入的参数强转化为整形。select和delete注入的原理与find方法相似,但delete方法多了一个判断是否为空的步骤。order by注入漏洞中,首先在控制器中编写漏洞演示代码。在user变量处设置断点,F7跟进find、select、buildSelectSql和parseSql方法。当$options['order']参数不为数组时,直接返回order by + 注入payload,最终payload为。缓存漏洞中,ThinkPHP3.2提供F方法和S方法用于缓存操作。S方法通过set方法写入缓存,然后使用filename方法获取写入文件的路径,保存在../Application/Runtime/Temp目录下。最后,将S传入的name进行md5值作为文件名,通过file_put_contents函数将内容写入文件。总结,本文详细解析了ThinkPHP3.2.3的几个重要漏洞,并提供了具体的实现步骤和payload示例。为了确保安全,开发者应仔细审查代码,确保参数安全过滤,并在开发过程中遵循最佳实践。实际操作中,尝试复现这些漏洞,并在安全环境中进行验证,可以加深对ThinkPHP框架及其安全性的理解。