PHP代码审计 -- 文件上传

工具&环境

工具:Seay源代码审计系统,文本编辑器一个
环境:phpstudy,网站源码是 zbzcms

步骤

1, 将zbzcms网站源码放入phpstudy,根据网站安装引导完成网站搭建;
2,打开Seay,新建项目 --> 选择网站源码 --> 自动审计,审计完成后点击 漏洞描述对审计结果进行排序,方便结果查看:
在这里插入图片描述3,审计完成,关注存在文件上传这一类,对结果进行观察,一般存在文件上传的地方存在upload,include,up等关键词,然后再看,发现也有文件上传在admin目录下的,这种我们可以猜测是需要登录以后进行上传的,所以首先关注非admin目录下的文件上传点:
在这里插入图片描述4,这里以/cms/cms/include/up.php这个文件为例,首先双击这条结果,进入up.php存在文件上传的地方:
在这里插入图片描述
可以先对这个页面进行访问:
在这里插入图片描述
提示参数有误,说明需要进行传参,然后观察函数,move_uploaded_file,这是一个php函数,直接查看php手册,对于函数,主要观察三个点,函数的功能是什么,函数需要传入什么参数,函数返回的结果:

move_uploaded_file( string $filename, string $destination):
	功能:move_uploaded_file — 将上传的文件移动到新位置
	参数:$filename 文件名, $destination 文件移动的最终位置
	返回结果:true 或者 false

通过php手册可知,这个函数在这里的功能就是将文件名为 $tmp_name的文件,移动到路径为$path的路径下;
因此,对$tmp_name 和 $path 进行全文追踪,查看这两个变量从哪里来的,并且是否可控,全文追踪:选中变量 -->鼠标右键 --> 全文追踪:
在这里插入图片描述

通过全文追踪结果可以看到,$tmp_name 来自一个数组$arr[‘tmp_name’],进而追踪数组 arr 是在foreach 遍历赋值中,通过 $_FILES 产生的,而 $_FILES 是个全局变量,再次查看php手册:

全局变量 $_FILES 包含有所有上传的文件信息。数组的内容来自以下范例表单。我们假设文件上传字段的名称如下例所示,为 userfile。名称可随意命名。 
$_FILES['userfile']['name']
客户端机器文件的原名称。 
$_FILES['userfile']['type']
文件的 MIME 类型,如果浏览器提供此信息的话。一个例子是"image/gif"。不过此 MIME 类型在 PHP 端并不检查,因此不要想当然认为有这个值。 
$_FILES['userfile']['size']
已上传文件的大小,单位为字节。 
$_FILES['userfile']['tmp_name']
文件被上传后在服务端储存的临时文件名。 
$_FILES['userfile']['error']

简单来说,$_FILES是一个全局数组,用于存放上传文件的临时文件名,文件类型,文件大小等重要字段,并且要为POST上传

通过php手册可以得知,我们可以POST以方式上传文件,对$_FILES数组产生影响,进入影响$tmp_name
接下来对$path 进行全文追踪:
在这里插入图片描述

通过全文追踪可以看到,$path 是通过$_GET全局变量获取的,而$_GET全局变量就是从url中get传参获取的,因此$path这个变量是可控的;
代码再往上,我们可以看到有一个if判断,只有 $run 的值为file ,才能进入文件上传,再进行全文追踪查看$run ,可以发现$run 变量是从GET传参获取的:
在这里插入图片描述至此,总结审计流程,进行利用:

* move_uploaded_file() 具有文件移动功能,需要提供$tmp_name ,$path 两个参数;
* $tmp_name可以通过post方式上传文件,影响$_FILES,进而影响$tmp_name,因此需要本地构建一个POST方式的文件上传表单,可控;
* $path为 文件上传路径,通过get 传参 path获取,可控;
* $run 是通过get传参获得,并且值一定要为 file 才能执行文件上传,可控;
* 在审计过程中还发现,如果$path的值,也就是路径在目标上不存在,则会创建新的目录;
* $filename 通过get传参获得,并且它的值会影响文件上传之后的文件名,为1时不更改文件名,为 0时会将时间戳拼接进文件名,
因此还需要将 $filename的值置为 1,方便文件上传之后的访问,可控;

利用:
本地构造文件上传表单,将run置为file使得程序进入上传功能,path设置为当前文件夹,也就是上传到当前文件夹下,filename置为1不更改上传之后的文件名,提交方式为post,enctype=“multipart/form-data”上传文件一定要写:

<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>

<form action="http://zbzcms.com/cms/cms/include/up.php?run=file&filename=1&path=./" method="post" enctype="multipart/form-data">
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

构造完成后直接双击浏览器打开,上传一个1.php, 内容为<?php phpinfo(); ?>:
在这里插入图片描述此时访问1.php,显示出当前php版本等信息即上传成功:
在这里插入图片描述(文末声明:仅供学习参考)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值