首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 偽造 HTTP Referer 突破防盜鏈實戰技術詳解

     編輯:PHP 相關知識

背景知識:防盜鏈原理

防盜鏈通常通過檢查 HTTP 請求頭中的 Referer 字段實現:只有來自授權域名的請求才返回資源(圖片、視頻、下載鏈接等)。惡意網站通過 `` 盜用流量,服務器端判斷 Referer 非授權域名則返回 403 或跳轉。

方案一:Socket 手工構造請求(底層控制)

創建代理文件 file.php,接收目標 URL 參數,偽造 Referer 轉發請求:

<?php
// file.php?url=https://example.com/video.mp4
$targetUrl = isset($_GET['url']) ? $_GET['url'] : '';
if (empty($targetUrl)) die('缺少 url 參數');

// 解析 URL
$parsed = parse_url($targetUrl);
$host = $parsed['host'];
$path = isset($parsed['path']) ? $parsed['path'] : '/';
if (isset($parsed['query'])) $path .= '?' . $parsed['query'];
$port = isset($parsed['port']) ? $parsed['port'] : 80;

// 建立 Socket 連接
$fp = @fsockopen($host, $port, $errno, $errstr, 10);
if (!$fp) die("連接失敗: $errstr ($errno)");

// 構造 HTTP 請求頭(關鍵:偽造 Referer)
$out = "GET $path HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Referer: https://$host/\r\n";  // 偽造為目標站內部引用
$out .= "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\n";
$out .= "Connection: Close\r\n\r\n";

fwrite($fp, $out);

// 讀取響應
$response = '';
while (!feof($fp)) {
    $response .= fgets($fp, 1024);
}
fclose($fp);

// 簡單分離頭部與體
list($header, $body) = explode("\r\n\r\n", $response, 2);

// 檢查狀態碼
if (stripos($header, '200 OK') !== false) {
    // 直接輸出內容(可根據 Content-Type 設置 Header)
    echo $body;
} elseif (preg_match('/Location:\s*(\S+)/i', $header, $matches)) {
    // 302 重定向:獲取真實地址並跳轉
    header('Location: ' . trim($matches[1]));
} else {
    echo "請求失敗,響應頭:
$header
"; } ?>

方案二:cURL 封裝(推薦,功能更強)

<?php
function fetchWithFakeReferer($url, $fakeReferer = '') {
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS => 5,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => false, // 僅測試環境,生產請配置 CA
        CURLOPT_HTTPHEADER => [
            'Referer: ' . ($fakeReferer ?: $url), // 默認偽造為自身
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        ],
    ]);
    $content = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err) return ['error' => $err];
    return ['code' => $httpCode, 'content' => $content];
}

// 使用示例
$result = fetchWithFakeReferer('https://target.com/protected.jpg', 'https://target.com/page.html');
if (isset($result['error'])) {
    echo "錯誤: {$result['error']}";
} else {
    // 直接輸出圖片(需設置正確 Content-Type)
    header('Content-Type: image/jpeg');
    echo $result['content'];
}
?>

方案三:Stream Context(輕量級)

<?php
$url = 'https://target.com/video.mp4';
$opts = [
    'http' => [
        'method' => 'GET',
        'header' => "Referer: https://target.com/\r\n" .
                    "User-Agent: Mozilla/5.0\r\n",
        'timeout' => 10,
        'ignore_errors' => true, // 獲取非 2xx 響應體
    ]
];
$context = stream_context_create($opts);
$content = file_get_contents($url, false, $context);

// 從 $http_response_header 獲取狀態碼
// 直接輸出或轉存
?>

進階應用:隱藏真實資源地址

結合上述技術,可構建資源代理下載系統:

  1. 前端請求 /download.php?id=123
  2. 後端查詢數據庫獲取真實 URL
  3. 服務端代理下載並流式輸出給用戶
  4. 用戶瀏覽器只見代理地址,真實存儲位置(如 OSS、CDN 簽名鏈接)完全隱藏
<?php
// download.php 簡化邏輯
$id = (int)($_GET['id'] ?? 0);
$resource = getResourceById($id); // 從 DB 獲取 {url, filename, mime}
if (!$resource) die('資源不存在');

$ch = curl_init($resource['url']);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => false, // 直接輸出
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTPHEADER => ['Referer: ' . parse_url($resource['url'], PHP_URL_HOST)],
    CURLOPT_WRITEFUNCTION => function($ch, $data) {
        echo $data; // 流式輸出到瀏覽器
        return strlen($data);
    },
]);
// 設置下載 Header
header('Content-Type: ' . $resource['mime']);
header('Content-Disposition: attachment; filename="' . $resource['filename'] . '"');
curl_exec($ch);
curl_close($ch);
?>

法律與道德邊界

⚠️ 重要提醒:
  • 僅用於合法授權的資源訪問(如自身 CDN 域名切換、多域名部署)
  • 繞過他站防盜鏈盜用帶寬屬於盜鏈行為,違反《網絡安全法》及服務條款,可能承擔法律責任
  • 尊重 robots.txt、版權聲明,建立正規業務合作獲取授權

防禦建議(站在被盜鏈方視角)

  1. Referer 白名單 + 空 Referer 放行/攔截策略(配合業務場景)
  2. 簽名鏈接(帶時間戳、IP、防盜鏈 Token):如 /video.mp4?sign=xxx&t=123456,服務端驗證簽名有效性
  3. User-Agent 二次校驗:雖可偽造,但能攔截低級爬蟲
  4. Nginx/Apache 模塊級防盜鏈:valid_referers + if ($invalid_referer) { return 403; }
  5. CDN 防盜鏈:阿里云/騰訊云/七牛等提供控制台配置,邊緣節點攔截,減輕源站壓力

總結

PHP 通過 Socket、cURL、Stream Context 均可實現 Referer 偽造。cURL 方案功能最全、錯誤處理最佳,推薦生產環境使用。技術本身中性,關鍵在於使用場景合法合規。作為開發者,更應掌握防禦體系,保護自身資源不被濫用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved