【小迪安全】Day51代码审计-PHP框架MVC类上传断点调试
沙漠里的鲸
2022年01月29日 03:53
收录于文集
共92篇

【小迪安全】Day51代码审计-PHP框架MVC类上传断点调试

相关知识点

1.关键字搜索:(函数,键字,全局变量等)

---文件上传的相关函数:move_uploaded_file 等

---文件上传的关键字:在写上传的时候会有注释,如//上传

---全局变量$_FILES

---应用功能抓包:(任何可能存在上传的应用功能点),前台会员中心,后台新闻添加等可能存在上传的地方

2.MVC 开发框架类:

https://www.cnblogs.com/wsybky/p/8638876.html

3.Thinkphp 框架:

https://sites.thinkphp.cn/1556331

Beescms 无框架后台任意文件上传

1.进入靶场

---首页

---后端

---搜索关键字:上传(这里的结果太多了)

---搜索函数$_FILES(直接搜索没有,我把$去掉了)

---点击其中一个查看(这里是一个文件上传的处理过程)

---浏览器访问该文件

---上传一个doc文件抓包分析看传递的参数

---传递的参数:文件说明:file_info和uppic,传递的表单名为up

---在源代码里面查找这两个参数,出现下面的文件上传的代码段

---如果uppic的参数存在,就传递表单名up

---fl_html里面将传递的字符串利用htmlspecialchars将特殊字符转换为 HTML 实体

---explode 使用一个字符串分割另一个字符串,这里将$_type_file以|分割,前面有有一个$_type_file函数,将允许的文件格式以|分割)

---$_sys文件是一个数组,包含上传文件的大小,和文件类型

---is_uploaded_file()函数检查指定的文件是否是通过 HTTP POST 上传的。如果文件是通过 HTTP POST 上传的返回 TRUE,可以用来确保恶意的用户无法欺骗脚本去访问本不能访问的文件。

---$_FILES['up&#​39;]['tmp_name&#​39;]是is_uploaded_file()要检查的文件,up是要上传的表单名,tmp_name变量中的值就是文件在Web服务器中临时存储的位置(上传文件的临时保存文件)

---确定文件的大小限度(这里是系统设置的值)

--- up_file处理上传的文件,并且验证是否符合上传标准

---根据up_file返回值(返回的字典形式)确定文件的路径、扩展名、大小、时间

---最后在进行数据库的插入操作

---定位函数up_file(进行相关的验证)

---传递了三个参数:表单名,文件大小,文件类型

---确定文件的大小不超过系统设置的文件大小

---pathinfo() 函数以数组的形式返回关于上传的文件路径信息,如/testweb/test.txt,生成数组:[dirname] => /testweb;[basename] => test.txt;[extension] => txt;[filename] => test

---查看上传的文件的后缀名是不是在系统规定的后缀里面

---判断path=’’的话,就上传到upload/file/路径下(如果path没传参的话默认为空,有参数的话就是参数值)

---file_exists检查文件或者目录是否存在,不存在就创建目录

---再根据时间戳生成文件名

---这里的关键就是绕过pathinfo函数,让php文件的格式的能够最后检测

---在PHP的在线编辑平台测试(这里没办法绕过,匹配的最后一个)

---抓包用%00截断尝试绕过(%00要解码)

---发现没有上传成功(这个地方绕过不了)

2.更换一个$_FILES函数存在的文件(admin_pic_upload.php)

---网页访问文件

---抓包分析(这里上传了很多个变量,好几个表单名,)

---应该是图片的长宽高等等

---这里是处理传递的参数

---intval获取变量的整数值,判断图片宽度是否为空,是就用系统设置的值,不是就用传递的参数取整数(其它变量类似)

---foreach 语法结构提供了遍历数组的简单方式,仅能够应用于数组和对象。每次循环中,当前单元的值被赋给数组 $v

---$_FILES 是一个预定义的数组,用来获取通过 POST 方法上传文件的相关信息。如果为单个文件上传,那么 $_FILES 为二维数组;如果为多个文件上传,那么 $_FILES 为三维数组。(这里再次明确一下这个原理)

---这里将数组里面的值再传递了一下

---可以看到,处理图片上传的函数是up_img,还传递了一个数组,因该是允许上传文件的格式,定点查询这里函数

---is_uploaded_file() 函数检查指定的文件是否是通过 HTTP POST 上传的。如果文件是通过 HTTP POST 上传的,该函数返回 TRUE。

---判断图片的的大小

---pathinfo() 函数以数组的形式返回关于文件路径的信息。[dirname]: 目录路径;[basename]: 文件名;[extension]: 文件后缀名;[filename]: 不包含后缀的文件名(注意:这里没有检测[extension],之前检测了这里是无法绕过的)

---比对文件的类型是不是在允许上传的类型里面(只检测了$file[‘type’],也就是mime类型)

---然后构造文件路径名,并且比对是否重复

--- rand(1,10000)函数为在1-10000产生的随机数

---直接上传文件,判断pic_alt是否为空来对比判断,如果为空,就采取路径+时间戳+随机数+.+文件后缀名方式命名

---将临时文件上传到设置路径上

---抓包修改文件类型

---在上传目录查看(根据时间判断,发现上次成功。有个疑问,Rand产生的随机数自己并不知道,上传了马子又怎么知道文件名呢?)

PHPStorm+xdebu 断点调试演示

1.  进入phpstorm加载项目

---访问phpinfo确认版本,x86,v11

---下载xdebug

---下载xdebug后移动到php的扩展目录,修改php.ini文件

---重启phpStudy后,查看phpinfo(发现这里xdebug没有显示,我花了半天,从新尝试了好几次都行)

---直接配置PhpStorm,如果不行就算了

---修改配置

---点击debug发现跳转的是百度的首页,估计是之前的debug配置的问题,没有安装上,就先跳过了

---如果运行成功,url的路径会有xdebug的参数

---箭头向下是步入下一步,第二个是强制步入,箭头向上是跳出

---点击向下的箭头,会依次执行函数和文件(包括文件包含的文件的每一步)

#优点

---不需要看懂代码,就知道经历了那些函数,和涉及的参数

---这里的抓包是从代码层面

---主要运用在Java,因为Java框架比较多,很可能看不懂,在这里就需要运用到断点调试

#总结

---搜索$_FILES->后台中心->上传图像->跟踪代码->逻辑判断

Finecms 基于前台 MVC 任意文件上传

1.  进入靶场

---发现会员中心

---对头像上传进行抓包分析(上传test.jpg文件,这是一个基于MVc的框架的网站)

2.MVC简介:

---模型Model:管理大部分的业务逻辑和所有的数据库逻辑。模型提供了连接和操作数据库的抽象层。

---控制器Controller - 负责响应用户请求、准备数据,以及决定如何展示数据。

---视图View – 负责渲染数据,通过HTML方式呈现给用户

#一个典型的Web MVC流程:

---Controller截获用户发出的请求

---Controller调用Model完成状态的读写操作;

---Controller把数据传递给View

---View渲染最终结果并呈献给用户。

3.查找数据包访问的index文件

---没有看到接受参数如s&c等等参数的传递和处理

---典型的MVC的框架,即核心代码没有在指向文件里面,需要查看入口文件

---这里的入口文件:FCPPATH(后面有一个fineCMS的目录)和WEBPATH(这里感觉有点像定义全局变量的意思,只是定义的路径)

---包含了init.php文件(FCPPATH为定义的路径)

---点击fineCMS的目录(发现init.php文件和三个文件夹)

---查看init.php文件(system目录下就是框架的代码,dayrui是二次开发的代码)

---根据路由规则匹配参数(也就是传递参数的规则)

---s对应目录c对应文件名,m对应方法

---在MVC框架内的controller中,查找member目录,文件名为account,函数为upload(一般核心代码都在控制器里面)

---在controllers文件夹下查找account.php文件下的upload方法

---post传参,然后用将空替换为+,赋值为file

---preg_match:执行匹配正则表达式preg_match(  string $pattern,   string $subject,  array &$matches) pattern要搜索的模式,字符串类型。 subject

输入字符串。 matches如果提供了参数matches,它将被填充为搜索结果。 $matches[0]将包含完整模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。

---这里[0]是全部的数据,[1]是data,[2]是png(文件后缀名),[3]是base64

 

---将file进行正则式匹配,取第三个(这里应该是文件的路径+文件后缀名)

---然后将传参的值进行替换,解码,写入新文件(在这里没有存在任何的过滤)

---然后写入文件之后,再进行的过滤()

---直接上传文件,返回1

---文件查看(发现了四张图片)

---将目录文件删除,修改数据包的文件头为PHP格式

---返回报错(应该是后面的验证没有通过)

---但是文件夹有第一个文件的php

#总结

---业务功能分析->会员中心->上传图像->跟踪代码->逻辑判断

---存在逻辑漏洞,即先上传,后验证

Cltphp 基于前台 TP5 框架任意文件上传

1.  thinkPHP的概念

---thinkphp是以MVc框架开发的一个框架,是MVC的一个分支(相当于写爬虫的一个request模块,将功能封装在框架里面,一般在市面上的版本为5.0和3.23版本)

---thinkPHP5的入口文件

2.  进入靶场

#如何判断thinkphp:

---url输错路径,会在页脚显示thinkphp的框架

---在源代码的think目录下查看readme文件

---打开根目录的index.php文件(发现入口)

---这里定义了应用、插件、框架的目录全局变量

---进入会员中心的头像上传

---上传图片,抓包分析

---这里的上传的路径/user/upFiles/upload在源代码中并不存在

---查看thinkPHP5.0的官方开发手册(架构=>url访问)

---在这里,相当于MVC框架中,s对应目录c对应文件名,m对应方法

---s=user;s=upFiles;m=upload

---找到相应的文件上传目录(我刚开始还在public里面去找,最后发现在APP,注意:核心代码一定是在控制器下面)

---查看upload方法

---将request(自定义函数)的数据给file函数

--- array_keys返回包含数组中所有键名的一个新数组:

---将上传的临时文件移动到上传目录下(漏洞检测在move函数)

--- getSaveName()函数获取文件的上传名

---绕过思路:根据info的值来进行检测上传成功,但是下面没有验证。可以伪造info的值(因为move函数中的check函数要调用才会取检测,好像是这里没有调用check函数(有点迷啊))

---file()函数处理上传文件(在框架内调用的几乎没有漏洞)

---move函数移动文件(thinkphp自带的验证在check函数)(这里是核心绕过点!!!!!!!!)

#总结

---thinkphp的框架很安全,但是开发者的写法如果不按照标准规定来,那么验证的时候很可能就是自己的代码验证,从而产生了安全漏洞。

---绕过思路:1.看开发者写法规范性;2.针对thinkphp框架本身安全分析

 

---定位过滤函数check

---发现检测了大小,类型,后缀,图像文件等等

---直接上传PHP文件,发现报错,这里是前端的js验证(这里的致命错误应该是move函数没有调用到check函数)

---抓包修改绕过

----发现上传成功

 

 

 

BEESCMS4.0:这个CMS官网崩了,只有csdn上面有,如果没有会员的话建议某宝搜索csdn下载,比较经济实惠。注意安装的时候直接访问:ip+端口+installhttps://download.csdn.net/download/weixin_39841856/11290980

PhpStorm:https://www.jetbrains.com/phpstorm/(某宝花了5块钱激活)

Xdebug: https://xdebug.org/download/historical(csdn有结合phpStudy的安装博客)

FineCMS_v5.0.6: http://pan.lanzou.com/i0gd72d

Cltphp:https://download.csdn.net/download/weixin_38657835/13190726?spm=1003.2122.3001.6634.2(某宝)

Cltphp的搭建教程(这个比较麻烦,我的根目录不是在public,直接是根目录):https://www.cltphp.com/detail-196.html

注:这些CMS资源较难收集,望各位师傅们不负韶华。