0%

容器上传绕过总结

搭建漏洞服务

还是先搭一个漏洞的服务吧:新建一个~/Desktop/php/upload文件夹,文件夹下存在如下结构的文件和文件夹:

1
2
3
4
5
6
$ tree
.
├── files
└── upload.php

1 directory, 1 file

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
<html>
<body>

<form action="upload.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>

</body>
</html>
<?php
if ($_FILES["file"]["error"] > 0) {
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else {
// 判断当期目录下的 upload 目录是否存在该文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
if (file_exists("files/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
}
else
{
echo "PWD: " . `pwd` . "<br />";
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
$file_path = "files/" . $_FILES["file"]["name"];
$success = move_uploaded_file($_FILES["file"]["tmp_name"], $file_path);
echo "Stored in: " .$file_path."<br/>";

if(file_exists($file_path)){
$str = file_get_contents($file_path);//将整个文件内容读入到一个字符串中
$str = str_replace("\r\n","<br />",$str);
$str = htmlspecialchars($str);
echo "File Contents: $str";
}
}
}
?>

Nginx

1.php%001.jpg,Nginx在%00截断,例如:

用%00截断过狗:

1544361917866

防御

设置上传目录不被php解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 80;
listen [::]:80;

server_name test.com;
root /home/repersp/Desktop/php;

index test.php;

location ~ \/upload\/files\/.* {
root /home/repersp/Desktop/php;
}

location ~ \.php$ {
include snippets/fastcgi-php.conf;

# With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# With php7.0-fpm:
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}

文件名后缀黑名单:

1
2
3
if(in_array($ext, ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'])) {
exit('bad file');
}

Apache

2.4.0以前

1.php.xxxApache从后往前解析,直到能解析。

2.4.0-2.4.29

1.php%0A因为代码中不能用$_FILES["file"]["name"]获取文件名,所以利用条件苛刻。

IIS

6.0

  • /xx.asp;.jpg IIS不解析;后面的内容
  • /1.asp/1.jpg IIS将.asp文件夹下的所有文件解析

7.5

php.jpg/.php 要开启cgi.fix_pathinfo=1