祥云杯
比赛时间:2020.11.21 9:00 - 2020.11.22 21:00
比赛形式:CTF
签到题
ZmxhZ3txcV9ncm91cF84MjY1NjYwNDB9
目测base64
加密,解密得到flag
还是原来的 Ping ?
网上稍微查查可以发现ping
的命令绕过,这就是个命令绕过题
先试试输入127.0.0.1|ls
有回显
接着试错过滤字符,<space>
、&
、>
、cat
、'
、flag
等等被过滤了,但是"
、%
、\
并没有被过滤
那就构造127.0.0.1|ca"t"<./sou.js
有回显
接下来需要寻找flag
,基本命令就是
|
|
空格可以用%09
进行绕过({}
也被过滤了,无法使用{IFS}
),比较难解决的就是flag
了,在flag
掺杂"
、/
、\
均无法绕过,看来不是单纯的字符检测,那就使用base64
试试
将上面的基本命令用base64
加密得ZmluZCAvIC1uYW1lICIqZmxhZyoi
构造如下payload
进行尝试
|
|
基本原理就是利用管道符|
将echo
命令的值传给base64
命令,base64
对base64内容解密并传给bash
命令
可以说我就是在这里卡住了,因为没有任何输出信息
后来朋友提示了我说把
payload
放到url
输入试试,结果惊奇发现有了回显,才反应过来浏览器自动对特殊字符进行了url
编码,而linux
并不会自动将%25
自动替换成%
或者将%7C
自动替换成|
之类的,这就导致了无回显
回显如下(我手动对齐了一下)
|
|
/etc/.findflag/flag.txt
便是flag
所在位置了,先记下来
既然对flag
过滤了,那么接下来cat
也需要使用base64
进行构造
执行命令为
|
|
base64
加密得Y2FcdCAvZXRjLy5maW5kZlxsYWcvZlxsYWcudHh0
最终payload
为
|
|
取得flag
Result:flag{9f1a16d4-5f5c-4104-8e18-6c73621531ef}
flaskbot
这是一道SSTI
题
SSTI: Server-Side Template Injection
试着输入username
: iyume
试着输入num
: 777
会出来一个 html 纯文本页面
|
|
二分法逼近,数字肯定无法胜利,寻找别的方法
首先是信息搜集,利用debugger
的栈查看上下文,尝试input num type error
、404
、username error
,分别出现三个报错页面,如下图
-
input num type error
信息点:对输入的
username
进行了base64
加密并储存在cookie:user
内,然后访问的时候会取得cookie:user
内的值进行解密并储存在name
这个内部变量 -
404
信息点:有一个
render_template_string()
,极大可能是注入点,它的传参是使用%s
获取的,因此可以注入模板,guessNum()
应该就是猜数字的函数,传参为num
和name
,name
就是在上一个信息点得知的username
,但是显然他并没有打印出任何与name
相关的东西,比如iyume vs bot
之类的,有可能是在人胜利时才会输出 -
username error
信息点:有一个
render_template()
,但这个调用模板的函数并不像render_template_string()
,它的传参是变量取值的形式,任何字符都无法注入,硬要说注入的话只可能是第一个参数(但一般没有人会去让用户控制网页名吧),因此这只能当作一个无用信息点
根据第二点,试着把cookie:user
改成比如e3syKjd9fQ==
(base64decode={{2*7}})
因为是render_template()
输出的这个页面,payload
的回显合乎情理
另寻途径
Python 中有一种空值类型(float)NaN
,可以通过 float('nan')
得到
float('inf')
得到无限大,负的则为无限小
NaN 与任何数进行任何比较都会返回 false
,那试着在数字框输入 NaN
|
|
看来这里是我赢了,但是可能payload
中有特殊字符被过滤了
把cookie:user
的值换成e3syfX0=
(decode={{2}})
|
|
输出了我的胜利,并且\{\{2\}\}
成功被渲染成了2
至此,SSTI
注入点确定
接下来有两种思路
- 直接寻找
flag
并读取 - 收集系统信息生成
pin
码hack shell
Pin 码 Getshell
先讲讲第二种,因为我没能成功
-
生成
pin
所需系统信息(算法不贴了)- username
- modname
- app.__class__.’__name__'
- app_path
- eth0_mac
- machine-id
在报错页面已经取得了信息2
、3
、4
基本构造
|
|
成功得到回显
|
|
信息1
应该就是guest
了
接着构造
|
|
得到回显00:16:3e:03:ee:c0
在python shell
执行print(0x00163e03eec0)
即可获取信息5
接着构造
|
|
返回debugger
提示No Such file or dir
,又试了试/var/lib/dbus/machine-id
,还是没有此文件,后来去列了一下目录,发现根本没有这个文件,看来是被动了手脚…以 失败 告终
直接寻找 flag
构造
|
|
被过滤了
排查后发现被过滤的字符是os
,那就替换成'o'+'s'
|
|
成功得到回显
|
|
显然super_secret_flag.txt
就是 target 了
但它也对flag
进行了过滤
那么构造如下payload
|
|
得到回显
|
|
成功取得flag
注意点
- 模板对
system
关键字进行了过滤,因此继承类''.__class__.__mro__[2].__subclasses__()[71]
下调用os.system
是没用的,目前没有绕过方案
总结
祥云杯的水份还是挺高的,题目共有 31 道
- Misc 6
- Crypto 6
- PWN 6
- Reverse 7
- Web 6
除了签到题,基本每道题都非常难,也非常有意思(
Misc 有一道题目叫做进制反转
,我的基本思路是CRC 修复
然后解压文件进行二进制按位取反?正拿着python
提取了16进制
数据,又听大佬说硬解 au 原始数据导入倒放 x.5 然后搜歌词
,我就停手了(菜死了
比赛过程还学了一下RSA
加密原理,虽然最后还是不会解题(
对了,这个比赛的积分制度是一血
(没有额外奖励)、以及动态积分模式
(根据解出题目的队伍数减少相应的分值)
关于组队,因为我也没加入协会(还没开始纳新),然后就个人参赛了。此外我们学校我所知的还有很多队伍,第一的那队解题数量11
,排名好像是省内高校14
,但省内高校出赛名额只有3
个,所以我们学校也没有队伍晋级线下赛。
至于我的排名,解题数量4
,积分179
,我只知道是校内第5
,省内高校估计排到80
多的样子
校内赛的预赛已经过了,决赛形式是CTF
+AWD
,还没开始,因此做保留
还想到别的什么再作补充
校赛
比赛时间:2020-12-06 9:00-11:30, 14:00-15:30
比赛形式:CTF + AWD
其实只有 CTF 可以讲,AWD 完全不会玩。
而且题目名称很多都忘了…就随便写了
Not only base64
7JJ3vECw1FBbqNxmQrcrd8toHvUiY
听题目名字就知道这是 base 系的加解密
目测没什么特征,一个一个试,最终是用 base58 解出来了
|
|
base58 很多人可能不知道这是什么,因为在日常生活确实不常见,但并不代表它用处不大,实际上比特币的钱包地址和私钥都是 base58 加密生成的。
Web 第二题
就是一道基础题,直接 hackbar 都可以解决,没有环境不讲了
Web 第三题
有时候阅读文档是一件很重要的事情
由于出题人的锅,这题端口号给错了,导致我以为这是一道 0day,搞了好半天。后来比赛结束了直接就去问了出题人,他也是才发现端口给错了。不过后来用正确的端口号为我们讲解了一下题目。
没有环境,我就随便说说算了。
网页中提示我们去看文档,并且给了个 GET 参数,值是一个函数。提交这个参数会调用对应的函数。那就需要一个可以返回所有函数的函数,这时候去读文档,可以发现 get_defined_functions 这个函数可以满足需求,于是直接 GET,只返回了一个函数,就是获取 flag 的函数,再调用一次就拿到了 flag
Misc 1
给了个 jpg 图片,查看属性-详细信息,描述里就写着 flag
Misc 2
给了个 jpg 图片,直接点开发现是不支持的格式,直接改后缀 zip,里面有 50 张二维码图片,扫码试试得不到 flag,但是发现了一张体积异常的图片,解压出来查看属性-详细信息,得到 base64 字符串,解密得 flag
Misc 3 / 4
这两题异曲同工,都是 zip 伪加密、高级伪加密,binwalk 一梭子解决。
好吧,其实我不是这么解的。我的解法很蠢。
用 010 Editor 打开 zip,把 Misc 3 的目录加密位、文件加密位改掉就可以直接打开了。把 Misc 4 的伪加密也全部去掉,但是并不能打开,直接手动提取 16 进制,把第二个文件 Tips.txt 解压了出来可以直接打开,但是第一个文件 flag.txt 还是有加密无法打开,后来发现是我漏了一处伪加密没有去掉。
Tips.txt 写了字频统计,那就对 flag.txt 进行字频统计呗。这里其实最好使用自己的脚本,因为在线的大多不支持长字符串。
Misc 5 同样也是伪加密,全部去掉解压,可以发现 flag.txt 里面写了一些描述,我记得有86
、QQMusic
、给我一杯牛奶
之类的,是一道社工题,打开 QQ 音乐搜就是了,一般就是第 86 号里写的那个评论。
Reverse
想什么呢。我不会逆向,连 IDA 都没装。
AWD
为了准备 AWD 比赛,我甚至自己搭建了一个环境分享给学长一起来玩。
地址: https://github.com/mo-xiaoxi/AWD_CTF_Platform
实际到比赛的时候,我也挺傻的,我在比赛结束前 10min 才发现每队的 root 账密就在大屏幕上写着,因为整个比赛就 1h30min,因为我太傻就基本都在划水…只能看着别的队伍拿分,还在想对方到底是怎么通过那个 Web 服务拿到 shell 的
Web 服务有个注入漏洞,进入管理页面可以发现很明显的文件包含漏洞。不过发现的时候,已经比赛快结束了。
以及,比赛服务器太弱鸡了,全场都没怎么快过。