whklhh 发表于 2017-11-6 01:01

某CTF大赛赛题cLemency逆向笔记

本帖最后由 whklhh 于 2017-11-6 11:31 编辑

刚结束的比赛,热乎乎的WP233333
re50没有发的价值,re200有人发过了,re300是OpenRisc的逆向,查了一下貌似是嵌入式开发板什么的…完全不会-0-

这个题目的分类其实是Misc(杂项),为什么会作为逆向发52呢,因为我傻了……

题目只给出了一个bin文件和flag.enc密文
bin刚开始看了一下不是已知的ELF/PE文件,于是去查题目“clemency”

它是DEF CON CTF 2017上出的题目:
一个新的自定义的架构的程序,不同于以往8位/字节和大小端序的方法,它的特性是9bit/Byte,中端序存储方法
据说可以平衡工具的利用,毕竟大家面对的都是同一个新的处理器的程序嘛233

在官方链接https://blog.legitbs.net/2017/07/the-clemency-architecture.html下到官方给出的调试器,通过它可以运行题目文件
clemency.bin

github上有很多IDA的反汇编脚本,我用的这个https://github.com/cseagle/ida_clemency
将脚本放入文件夹下,重新打开进行反汇编即可。
注意处理器要选择提供的Clemency,而不是默认的MetaPC。
http://img.blog.csdn.net/20171106002842856?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
然后就可以得到反汇编的程序了:
刚才的下载链接里有官方文档,讲解各个命令、和通讯等等模拟器在linux下使用,-d可以调试,调试状态下输入?可以得到各个操作的指令,与gdb基本类似:
http://img.blog.csdn.net/20171106002918483?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
直接运行提示需要flag文件,于是在同目录下创建flag文件,向其中写入内容
模拟器自动将其作为输入接收,送入clemency程序

t单步执行逐步跟踪,进行了一堆转存
花了好久最后发现,程序中对输入没有进行任何操作,而是直接在5b06处将输入转存入DataSent,即发送区

放入发送区后,emu模拟器会将其通过stdout输出
http://img.blog.csdn.net/20171106003018632?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
调试器跟踪可以看到地址(db表示以字节形式Dump内存):


http://img.blog.csdn.net/20171106003109135?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


R02就是DataSent,字节方式可以看到内容不变

最前面那一段乱码就是输出内容
但是模拟器输出的却并不是flag
文件中的内容问题在于字节转换:

可以看到,字节方式存储都是031,在原来的8位字节前补了一个0

dt(表示以trix形式Dump内存)可以看到clemency的内存:


http://img.blog.csdn.net/20171106003131994?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


就是将31转成二进制后前补0,成为clemency的一个字节(9位),然后按照中端序存储方式(9-18作为第一字节,0-9作为第二字节,18-27作为第三字节)存储

以a,b,c为例,生成原理如下:
http://img.blog.csdn.net/20171106004139557?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


这样子生成clemency下的3个字节,作为x86架构下则是3个字节+3位,最后一个比特不变,第二个比特最后补上了一个0,第一个比特最后则补上了两个0

十六进制表示时由于每个字符表示8位,所以最左边还多出了3位,由第一比特的高位决定值


按照这个思路可以得到clemency的内存表示,然后输出的时候将它们化成二进制,每8位做一个byte进行chr()

说到底就是每个比特前补0,然后重新分组输出

逆向脚本就简单多了,直接每9位读一次,刨掉第一位然后转字符即可:
f = open("flag.enc", "rb")
cipher = f.read()

s1 = ""
for i in cipher:
    s1 += "{:0>8}".format(bin((i)), )
print(s1)

s2 = ""
for i in range(len(s1)//9):
      s1 = s1
      s2 += (chr(int(s1[:8], 2)))
      s1 = s1

print(s2)




后来---


醒来看到大佬的WP就傻了

其实github上的IDA脚本里面为了反汇编所以已经做了clemency的字节和端序转换,因此用IDA直接打开flag.enc就能得到flag……
http://img.blog.csdn.net/20171106004210818?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


杂项题硬生生被做成了逆向题OTZ

不过话是这么说,如果给出的bin里对输入进行了变换,这种方法就解不出flag了嘛
所以逆bin还是挺有必要的

虽然绕了个超级大的远路,不过参考文档一步一步学习新架构的汇编,调试这个程序挺有意思的~
感谢i春秋和主办方提供的题目(°∀°)ノ很好玩

理论上来说,逆clemency-emu应该也能得到字节转换的代码,
它是ELF格式的,IDA可以反编译出来

不过太大了又没找到关键入口,所以放弃了
从文档中参考资料,再加上猜测和验证才得到了转换算法

(我做逆向怎么都靠猜233333)
(因为太菜了TmT)

附件中包含了DEF CON官方提供的emu模拟器(需在linux下运行)、文档,和CTF提供的赛题clemency.bin、flag.enc
(DEF CON相关的东西在最上方的连接中都能找到~)



whklhh 发表于 2017-11-20 21:30

往事也加 发表于 2017-11-20 19:19
安装版的ida pro 才能集成 https://github.com/cseagle/ida_clemency

我自己的就是6.8绿色版的哦 正常使用

whklhh 发表于 2017-11-6 11:37

Poner 发表于 2017-11-6 10:49
什么大赛?单片机的题能站内PM给我看看?
{:301_983:}我没找到怎么发消息。。。
上海网络安全赛,OpenRisc的题

Poner 发表于 2017-11-6 10:49

什么大赛?单片机的题能站内PM给我看看?

gxkyrftx 发表于 2017-11-6 18:51

等我知道这个比赛的时候,已经快该结束了。。。。。。

wekabc 发表于 2017-11-7 15:07

现在CTF都搞这种非标了啊{:1_909:}

whklhh 发表于 2017-11-7 15:58

wekabc 发表于 2017-11-7 15:07
现在CTF都搞这种非标了啊

{:301_1009:}外国的CTF还是厉害啊 直接做一个新架构出来…

tigershine 发表于 2017-11-7 17:23

顶楼主………………

都同学 发表于 2017-11-8 00:30

膜,伏地膜~

Loopher 发表于 2017-11-8 09:15

厉害,新的架构

a371569963 发表于 2017-11-8 15:09

不明觉厉,膜拜大佬
页: [1] 2
查看完整版本: 某CTF大赛赛题cLemency逆向笔记