171105 逆向-上海CTF(cLemency)

来源:互联网 发布:js实现的字幕滚动 编辑:程序博客网 时间:2024/05/23 05:10

1625-5 王子昂 总结《2017年11月5日》 【连续第401天总结】
A. 上海CTF-Misc-cLemency
B.

Misc

cLemency

查询得知这个词是DEF CON CTF2017上拿出来的新的架构程序,特点有一字节9位、中端序存储等
在官方链接https://blog.legitbs.net/2017/07/the-clemency-architecture.html下到官方给出的调试器,通过它可以运行题目文件clemency.bin
github上有很多IDA的反汇编脚本,我用的这个https://github.com/cseagle/ida_clemency
将脚本放入文件夹下,重新打开进行反汇编即可。注意处理器要选择提供的Clemency,而不是默认的MetaPC。
这里写图片描述

然后就可以得到反汇编的程序了:
刚才的下载链接里有官方文档,讲解各个命令、和通讯等等
模拟器在linux下使用,-d可以调试,调试状态下输入?可以得到各个操作的指令,与gdb基本类似:
这里写图片描述

直接运行提示需要flag文件,于是在同目录下创建flag文件,向其中写入内容
模拟器自动将其作为输入接收,送入clemency程序

t单步执行
逐步跟踪,花了好久最后发现,程序中对输入没有进行任何操作,而是直接在5b06处将输入转存入DataSent,即发送区
放入发送区后,emu模拟器会将其通过stdout输出
这里写图片描述
调试器跟踪可以看到地址(db表示以字节形式Dump内存):
这里写图片描述
R02就是DataSent,字节方式可以看到内容不变
最前面那一段乱码就是输出内容

但是模拟器输出的却并不是flag文件中的内容
问题在于字节转换:
可以看到,字节方式存储都是031,在原来的8位字节前补了一个0
dt(表示以trix形式Dump内存)可以看到clemency的内存:

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

以a,b,c为例,生成原理如下:
这里写图片描述

这样子生成clemency下的3个字节,作为x86架构下则是3个字节+3位,最后一个比特不变,第二个比特最后补上了一个0,第一个比特最后则补上了两个0
十六进制表示时由于每个字符表示8位,所以最左边还多出了3位,由第一比特的高位决定值是0或1

按照这个思路可以得到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))[2:], )print(s1)s2 = ""for i in range(len(s1)//9):        s1 = s1[1:]        s2 += (chr(int(s1[:8], 2)))        s1 = s1[8:]print(s2)

醒来看到大佬的WP就傻了
其实github上的IDA脚本里面为了反汇编所以已经做了clemency的字节和端序转换,因此用IDA直接打开flag.enc就能得到flag……
这里写图片描述

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

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

虽然绕了个超级大的远路,不过逆这个程序还是挺有意思的
理论上来说,逆clemency-emu应该也能得到字节转换的代码,它是ELF格式的,IDA可以反编译出来

不过太大了又没找到关键入口,所以放弃了
从文档中参考资料,再加上猜测和验证才得到了转换算法
(我做逆向怎么都靠猜233333,因为太菜了TmT)

最后加上这个题目打到了第12名~
从七月份参加i春秋的国赛一题都做不出来,到现在基本Re都能吃下来,感觉成长了不少~很满足=w=

C. 明日计划
算法学习

原创粉丝点击