PHP-代码审计项目-梦想CMS-后台注入

本文最后更新于 2024年10月22日 下午

前言:俺开始学代码审计了,之前一直在黑盒方面学习,黑盒漏洞挖掘,没有接触过白盒,于是开始学习代码审计。【PHP代码审计项目】系列是一些用来学习练手的CMS的审计笔记,写的不好,但是也是一个记录吧,多年之后再看也是会感慨万千吧哈哈,最后学习完了代码审计我会写一个总结性的文章,还望各位大佬师傅轻喷,欢迎随时指教小弟……

审计环境

  • phpstudy 2018
  • php-5.4.45 + Apache
  • phpstrom 2018
  • CMS源码:梦想CMS-v1.4

审计过程

image

  1. 根据提示,找到目标文件 BookAction.class.php

image

image

  1. 其中,”获取回复数据”的代码段,肯定涉及了数据库操作,并且使用GET或者POST方式接收参数id,也就是说id可控!但是需要进一步跟进代码,看怎么执行的sql语句,中途是否有过滤?

image

  1. 跟进getReply(),跳转到它的函数声明

image

对数组参数$id做了一些处理,implode()把数组参数id转换为以逗号分隔的字符串$id,再把$id拼接”uid in ()”之中,赋值给$param,作为SQL语句中的WHERE 子句的字符串,调用父类方法selectModel(),把$param传入。到此$id被传入了selectModel()中,且还未被过滤

  1. 继续跟进selectModel()

image

接收$param空数组,如果设置了field键就把当前对象的field属性赋值为传入的对应值,调用父类中的数据库查询方法selectDB(),传入三个参数,应该是三个查询条件,$this->tab[‘0’] 取出表名,$this->field 某个字段值,$param 来自于$id。到此$id还是没有被过滤,被传入了selectDB()中

  1. 继续跟进selectDB()

image

只关注$param数据流向,$param被传入到where()中,赋值给了$sqlStr变量,最终$sqlStr变量直接被拼接到了$sql语句中,仍然没有任何过滤,就直接进行数据库查询!

  1. 但是还不知道where(),函数是怎么处理$param的,继续跟进where()

image

可以看到,还是没有进行任何过滤,只是获取了把$param数组的一些字段值赋给了一些变量,用来在$sql语句中拼接查询

  1. 到此,$id没有进行任何过滤处理,且可控,直接被改入了$sql语句查询,sql注入漏洞产生,添加一句
1
echo $sql;

输出sql执行语句,方便调试

image

漏洞复现

  1. 构造url
1
http://localhost/cms/lmxcms1.4/admin.php?m=Book&a=reply&id=111
  1. 回显显示,id可控

image

  1. 开始注入,有数据回显!
1
admin.php?m=Book&a=reply&id=1)%20union%20select%201,2,3,user(),5,6,7,8,9--%20+

image