史上最强国际顶尖战队集结5大洲、15个国家地区、20支战队。近5年共计获得150次CTF全球冠军。100名最强CTF选手,48小时不间断赛制。12月1-2日,中国郑州、长亭科技,首届Real World国际CTF网络安全大赛,线下总决赛,大幕开启!
我也好想去郑州啊😭
In November, I created a forensics/reversing challenge "rwext5" for Real World CTF 2018 Finals.
kelwya找我来出题,他说可以forensics。因为很久没有做题,在ccls-fringe出完后感觉又陷入了出题困难的尴尬状态QAQ。因为我对文件系统有一点兴趣,就盘算着是否找个成熟的fs,稍微修补下使得和正常行为不同,然后制作一个磁盘格式化为该fs,塞入藏匿的flag和其他辅助解密的线索。
It is about the hypothetical filesystem "ext5", which is obviously based on ext4. Actually, I patched lwext4 a bit to make it different from a standard ext4 filesystem. Contestants were supposed to reverse engineer rwext5-mkfs
and rwext5-import
and find the nuance.
|
|
After successful deobfuscation, the following files can be found in rwext5.img
:
|
|
flag、hint and other files
The image includes some form of the flag file, a copy of lwext4 (as a hint that the two distributed tools rwext5-mkfs
rwext5-import
should be reversed and compared with standard ones). It would be interesting to put some other stuff (also served as market promotion purpose for my project and the LSP ecosystem :)
镜像里除了flag
文件和一整套lwext4源码lwext4
(提示需要改什么),还得有点其他东西起到迷惑作用,因此我塞了下面这些东西:
另外也想给自己的项目打广告,萌生了从ccls的cache弄一道forensics的想法,因为惰性拖了两个星期没有动手。之前一次LeetCode Weekly前在和一个学弟聊天,就想把他的id嵌入了flag。LeetCode第一题Leaf-Similar Trees没有叫成same-fringe,所以我的题目就带上fringe字样“科普”一下吧。
lwext4/.ccls-cache
:.ccls-cache
is the default cache directory of ccls.- 5
.patch
files have been uploaded (and merged) after the contest https://github.com/gkostka/lwext4/pull/43~47 .config/nvim/init.vim
: language clients of Vim/NeoVim:ale, coc.nvim, LanguageClient-neovim, vim-lsp。.config/Code/User/settings.json
: VSCode configuration of ccls
Create a file flag
of 1111 blocks (512 bytes per block) filled with random bytes and place the plaintext flag in the 555th block. Encrypt it with openssl enc -aes-128-cbc -pass pass:filesystem -in flag.plain -out flag
.
至于bin/{clang,lld,llvm-objcopy}
,因为我对这些工具分别有50+,90+,10+ commits(努力学习📚),而且觉得用他们继续藏匿🏁挺好玩就加进去啦。
|
|
|
|
flag
encrypted by openssl
was split by llvm-objcopy into two halves: flag.0.o
and flag.1.o
.
openssl加密后的flag
拆成两部分用llvm-objcopy简单处理得到flag.0.o
和flag.1.o
。这两个文件放在.config/doom/modules/private/my-cc/
(.config/doom/
是放置Doom Emacs个人定制的目录)。
lwext4 obfuscation
I modified ext4_ext_find_goal
(lwext4 uses a first-fit algorithm to find the first free block) so that it would return a random block, otherwise the extent block tended to be continuous and the contestants wouldn't need to decrypt the metadata to recover the two object files.
|
|
The struct members of superblock inode are reordered a bit:
|
|
Two tools compiled from the obfuscated lwext4 are provided:
rwext5-mkfs
: used to create a ext5 filesystemrwext5-import
: used to import files into the filesystem
Fill rwext5.img
with dd if=/dev/urandom
, run rwext5-mkfs
, and then populate it with flag.0.o
, flag.1.o
, lwext4 and other files. The final rwext5.img
was distributed among teams.
By reversing the two programs contestants can figure out how struct members are reordered. They may write an export tool (I wrote a rwext5-export
) to copy the two object files out or assemble extent blocks by hand. Both object files have the section with a weird name ".openssl_aes-128-cbc_pass:filesystem". A linker concatenates the section contents and llvm-objcopy may be used to dump the section. It is straightforward to decrypt the contents with openssl and get the plaintext flag:
|
|
逆向以上两个程序即可发现fields打乱的方式。可以自行编写导出工具(我写了一个rwext5-export
)或者手工查找组成flag.0.o
flag.1.o
的extents,恢复出来后用lld拼接,用llvm-objcopy dump被openssl加密的section,按照section名提示的密钥解密后读出明文flag。
|
|
Code
https://github.com/MaskRay/RealWorldCTF-2018-ccls-fringe-and-rwext5
Thanks to gkostka for the lwext4 project (I should really learn more about ext4), and ngkaho1234 for the help to modify lwext4!