上周日给Real World CTF 2018出了一道forensics题ccls-fringe,向解出此题的31支队伍表达祝贺。
上一次出题已是2016年,一直没有人教我pwn、reverse、web所以只能从平常接触的东西里勉强抽出要素弄成题目。
kelwya找我来出题,他说forensics也可以,阻止了我说另请高明。另外也想给自己的项目打广告,萌生了从ccls的cache弄一道forensics的想法,因为惰性拖了两个星期没有动手。之前一次LeetCode Weekly前在和一个学弟聊天,就想把他的id嵌入了flag。LeetCode第一题Leaf-Similar Trees没有叫成same-fringe,所以我的题目就带上fringe字样“科普”一下吧。
下载ccls-fringe.tar.xz
后解压得到.ccls-cache/@home@flag@/fringe.cc.blob
。这是存储的cache文件。
这里体现了ccls和cquery的一个不同点。ccls默认使用"cacheFormat":"binary"
了,这个自定义的简单序列化格式,cquery仍在使用JSON。
写段程序读入文件,用ccls::Derialize
反序列化成IndexFile
,用ToString
可以转成JSON字串,阅读可以发现其中一个变量int b
:
1 | { |
clang -fparse-all-comments
会把非Doxygen注释也嵌入AST,注释暗示了我们应该找和它类似的变量。spell
差不多表示spelling
SourceRange,第80列很奇怪。写一段程序收集位于80列的其他单字符变量,按行号排序:
1 |
|
Makefile
指定编译选项和链接选项,除了LLVM只有rapidjson一个依赖了。
1 | CCLS := $(HOME)/Dev/Util/ccls |
编译成ccls.so
,让ccls
吐出flag:
1
2% LD_PRELOAD=./ccls.so ~/Dev/Util/ccls/Debug/ccls
blesswodwhoisinhk
这只是这人用的id的一个子串,他教育我要多做Codeforces,是很好玩的(可惜我依然这么菜,呜呜😭😭😿😿)。
把same-fringe problem写成coroutine形式也是为了纪念一个去New York City的同学,他在Stanford读研期间,给一门课当助教时曾让我校对一个课程实验Cooperative User-Level Threads。
1 |
|
假如你用clang trunk (>=7),ccls可以检索macro replacement-list中的引用。某些限定条件下template instantiation得到的引用也能索引。
代码
https://github.com/MaskRay/RealWorldCTF-2018-ccls-fringe
ccls的xref功能可以看https://github.com/MaskRay/ccls/wiki/Emacs里的截图。Vim/NeoVim用户也强烈建议看看Emacs能达到什么效果。最近也加了一个vscode-ccls,但我不用VSCode因此没有精力维护。