南邮re writeup

writeup-南邮攻防平台RE练习

RE300 第一题

拖进IDA里面看一下:

易知flag长度为24,大致思路是输入flag,输入的flag经过sub_4005B6这个函数处理,处理之后看flag和dword_601060这个里面存的数据一致(涉及数据类型的转换)。

为了便于分析,修改了一下变量名,加了些注释:

进入 flag处理函数看一下。

有图可知是读取特定数据段中的数据元素,根据数据元素的值进行switch case操作,看循环便知道要进行5000次的循环,而且每个循环都是根据那个特定数据段中的5000个不同的数据来进行的不同的操作,动态调试的可能性几乎为0,只能静态分析,要是能提取出那个数据段中的15000个数据,逆向的进行循环操作就达到解密的操作了。
感谢杜神指点,才知道ida有一个专门的导出特定的数据的功能,不然这题我是没法做的,还是太菜。

注意到:

这个是dword数据,我逆的时候,没注意,改变了它的数据类型,写了错的解密程序,然后刚了一会汇编:

读到画圈的地方才恍然大悟,flag经过处理之后的结果要和这个601060数据段中以doubleword大小读取的前24个元素一致。这个crackme一共要导出两次数据。

下面进入15000的那个数据段,导出数据。一般情况下都是进去先把它根据情况设置为合适的数据类型,恰好这里就是字节型的,所以不用设置了。然后再把这些数组生成一个数组(右键,选着arry)

出现如图所示的直接确定就行,毕竟我对ida也不熟。
设为数组之后,按shif+e把他导出:

我是以16进制形式把他导出的。(ida会把这个这个数组以c语言声明定义数组的形式给导出到一个txt文件中)
另外一个数组同理可导出。

然后写一个解密的小程序就行,当时python不熟,用的c写的辣鸡小程序

程序源文件和keygen打包

密码:as5r

RE300 第二题

占位等下写

RE500

这题还是有趣,学到了新技能:正则表达式

我的分析过程:

使用ida打开大致看看

打开后,转换到graph模式
打开后如图:
ida graph显示

可以看到结构当中的显眼的红字:Sorry, this node is too big to display

鼠标点一下,按空格,转换为文本模式,如图:
ida文本模式
手动下滑,当时被吓住了,滑动栏走得太慢了,一气呵成,拖到底,大致算了下,有60万条汇编指令…

回过神来,看了些汇编指令,发现绝大多数的指令都是再往几个变量里面赋值和异或什么的,大约有几十万条,明显就是在混淆

当时的思路就是,去其糟粕取其精华

ida f5大法好啊

指令太多,不适合刚,所以使用f5大法看看,由于有一部分的代码有60万之多,所以f5的时候,一度卡住了,造成了ida被日的假象,去问兔师傅被怼,要对ida有信心!
所以等了十分钟左右,显示出了可爱的类C代码,如图:
f5大法好啊

可以看到类似这样的语句:

dword_6941B4 ^= dword_6941B0; 与某个变量异或
dword_694150 = -1304438312; 将一些值赋给变量

往下使劲拖,发现事情开始变得简单

关键之处

用re菜鸡的直觉感觉到了,这就是flag经过前面混淆部分的代码处理后,最终和目标进行比较

发现重要的东西只有byte_694100-byte_694119,这是flag存储的位置,和dword_694060
这时我有一个大胆的想法,就是混淆语句都是处理的694119以后的,所以只要去除和694119以后位置的语句就行

所以事情变得简单了:
只要去除混淆代码,真相就大白了。

去除混淆代码

俗话说,魔高一丈,道高一尺:

办法总比困难多。ctr + c复制到notepad++
开始处理。
可以看到:
相似
有很多类似的语句怎么处理呢?

问了下兔师傅,兔师傅说用正则,于是花了些时间,学了下notepad的正则表达式,在查找里面打开正则表达式,查找到相应的大致语句,然后替换就行

这里有两个可以参靠的学习notepad++的正则的资料:

正则语法

正则使用学习例子

使用

dword_6941[^0-1][0-9A-F]\s\^= dword_6941[^0-1][0-9A-F]\;

就可以去除上面相似中的语句。

使用:

dword_6941[^0-1][0-9A-F]\s=\s\d+;
匹配赋值语句

然后就是将byte_6941xx类的东西整理成相应的数组变量。
使用:

byte_6941([0-2][0-9A-F])

去匹配这些内容
,然后自己替换成:

flag[0x\1]

ps:这时候这个下标时16进制,后续还要处理,不过这个处理简单,不用正则就行,这个就不说了。

然后变得越来越清晰了。

实际上就是**将flag的位进行加减或者异或,只要逆序并且+变-,-变+,++变–,–变++
就能写出kegen了

写keygen

替换之后,然后将操作逆向替换就行+变-,-变+,++变–,–变++)
最后就是将语句逆向了,排列了,问了下小伙伴,可以c语言用字符串数组数组实现也可以用c++的std流(好像是),我自己用的是py,py大法好啊
然后再逆过来即可