0x00 起源
从零学习php,最终目的实现代码审计入门,软件采用sublime text,环境使用phpstudy搭建,需要有简单的html基础和php基础,跟随流沙前辈视频学习记录。
国庆放假摆烂几日,奖励自己好多把亚索,嘿嘿嘿,今日继续对php基础学习。
0x01 文件包含的简单例子
文件包含是高危漏洞,如果代码处理不好,就有可能对网站产生隐患。之前也对该漏洞作出记录。但现阶段目的是实现php代码审计入门,所以在原有基础上进一步理解原理。
文件包含漏洞使用特定函数把别的文件包含进来。
include 包含过程出错,报错但继续执行
include_once() 不会二次包含
require() 包含过程出错,直接退出不继续执行
require_once() 不会二次包含
代码一 2-9.php
<?php //PHP 文件管理操作一-文件包含
$conn = array(
"host" => "localhost",
"mysql" => "localhost",
"port" => "3306",
"database" => "testdb"
);
代码二 t3.php
<?php
echo "www.baidu.com<br/>";
include '2-7.php'; //注意,此处2-7.php文件是不存在的,让它报错;这里先测试require
//include、require函数可以理解为调用,等价于把代码一的$coon那一段代码调用到此处
$host = $conn["port"]; //输入port数据,正常为3306,但是此处文件是2-7.php
echo $host;
echo "xxaadqawd"; //下面添加回显内容,用于对比include和require
测试include可以看到使用include包含2-7.php,虽然2-7.php不存在导致过程出错,但还是正常执行下面的echo命令
测试require发现不错但不继续执行,这两者的区别就再此处体现
0x02 文件上传的简单例子
开始前要做的准备
1.首先是有关目录创建的小栗子,下面代码的核心逻辑为判断当前目录是否存在,不存在自己创建
//创建目录的代码段
<?php
//echo __DIR__. "<br/>"; //输出当前路径
//echo dirname(__DIR__); //输出上级目录
//现在我们有一个情况,在上级目录下新建路径/uploads/images
define("PATH",dirname(__DIR__));
$path = PATH."/"."uploads"."/images"; //定义path,判断上级目录是否为uploads/images 等价于 ../uploads/images
$dir1 = date("Ym"); //年月
$dir2 = date("d"); //日
$fullPath = $path."/".$dir1.$dir2; //拼接完整路径
if(is_dir($fullPath)){ //判断指定的文件是否是目录
echo "yes"; //是输出yes
}else{
// echo "no"; 不是目录,使用mkdir函数创建路径
mkdir($fullPath,0777,true); //创建路径,赋予文件权限
}
首先自己先创建uploads/images路径,上传的图片都会上传到这个路径,可以看到正常情况下是空的。
但是当代码判断为否时,会在images路径根据当前年月日创建文件夹
2.结合1实现上传代码,文件上传要用到函数 move_uploaded_file,该函数用来移动图片路径
<?php
header("Content-type:text/html;charset=utf-8"); //因为下面有中文,不输入可能会存在问题
if(empty($_FILES)){
echo "请上传文件";
}else{
//echo $_FILES["picture"]["name"]."<br/>";
//echo $_FILES["picture"]["tmp_name"];
define("PATH",dirname(__DIR__));
$path = PATH."/"."uploads"."/images";
$dir1 = date("Ym");
$dir2 = date("d");
$fullPath = $path."/".$dir1.$dir2;
if(is_dir($fullPath)){
echo "yes";
}else{
// echo "no";
mkdir($fullPath,0777,true);
}
$fileName = rand(10000,99999); //上传的图片文件名给予5位随机数,从10000-99999
$fileType = strrchr($_FILES["picture"]["name"],".");
$fileName = $fileName.$fileType;
move_uploaded_file($_FILES["picture"]["tmp_name"],$fullPath."/".$fileName);
//把html表单上传的文件移动到所需的目录;类比把客户端输入的图片移动到服务器
}
3.前端的上传代码实现
<!DOCTYPE htnl> <!--文件上传表单-->
<html>
<head>
<meta charset="utf-8">
<title>测试文件上传</title>
</head>
<body>
<form action="t3.php" method="post" enctype="multipart/form-data"> <!--文件上传需要加上enctype="multipart/form-data"-->
<input type="file" name="picture"/>
<input type="submit"/>
</form>
</body>
</html>
在html页面上传1.jpg,最终实现的上传到图片服务器的为随机数20126.jpg,当然实际网站不可以这样写。
0x03 文件管理
unlink() 删除文件
realpath(".") 等价于__dir__输出当前路径
file_get_contents() 从文件中读取内容
file_put_contents() 向文件中写入内容
file_get_contents读取文件内容小例子
<?php
header("Content-type:text/html;charset=utf-8");
$str = file_get_contents("t5.php");
var_dump($str);
使用递归思想的小栗子
<?php
header("Content-type:text/html;charset=utf-8");
/*
$path 目录
$lev 层级
*/
function showDir($path,$lev=0){
$fh = opendir($path);
while($row = readdir($fh)){
//如果目录为.和..就跳过
if(($row=='.') || ($row=='..')){
continue;
}
echo str_repeat(" ",$lev),$row,'<br/>';
//如果目录里面还有目录,就继续往下读取目录
if(is_dir($path.'/'.$row)){
showdir($path.'/'.$row,$lev+1);
}
}
closedir($fh);
}
showDir('.'); //输出当前目录下的文件