HSCCTF RE WP
0x00.前言
打了整整两天,re也是ak了,不容易
总榜11,可惜了没进前十,前十有纸质证书来着
0x1.TEA
这题误导我了,我一直在纠结htoi函数是加密方式
刚开始对输入进行判断,前几位是否是flag{然后就是把flag的内容由-进行分段,所以flag的形式大概是flag{1111-2222}这样
然后这样输入去动调看密文
密文有两段,第一段有一个数组进行索引,index的下标是3,1,0,2,然后一位一位地去加进去,最后得到的密文是0xb805d767
第二段密文可以直接动调拿到: 0x63c174c3
然后就是一个简单的tea加密,秘钥2234
直接上脚本:
1 |
|
0x2.ROULRTTE
游戏题最简单的做法就是keypatch
通过shitf+f12看到了字符串有一个hscctf,然后题目说八次通过,所以就定位到了我们要的输出flag的位置
找到了这个函数,然后直接在main函数找一个地方直接jmp到这里就行了,我用的是jnz和jz改变条件
改这里的,直接keypatch 随便改一改指令然后call sub_E95990
原理大概如此,keypatch可以解决90%的问题。剩下的百分之10%是ce修改器
0x3.THE_WOLF_SONG
找到关键加密函数,魔改rc4,也加了很多的异或
1 | import urllib.parse |
0x4.NO_PY
做过原题,python反编译的源代码是一个sm4的加密函数,但是找了半天也没什么进展,后来发现是在打包的库函数里面加了一个异或
pycdc解析一下ezpython.pyc,sercrt得到原码和密文
1 | from gmssl import sm4 |
在SM4代码中发现他的key异或了一个102,我们手动将key异或回去就可以了,直接赛博厨子嗦了
0x5.VM_RE
这个题目也是让我学到了很多的知识,第一次做vm,竟然爆出来了
函数非常的整洁,就一个vm的加密函数
跟进vm的加密函数,这个函数变成了一个完整的switch case语句,刚开始我去硬分析,一个一个去找逻辑,但是实在是太麻烦了
于是在网上找到了一个插件可以来getflag
pence插件,下面这篇文章跟本题差不多
设置好两个断点,分别用于进行符号化和爆破flag
下面是第一个断点,用来获取输入
第二个断点,用来爆破flag
然后就开动调,输入33个1到达第一个断点,右击栈窗口存储刚刚输入的数据地址,选择jump in hex跟随16进制,找到左边红色框中16进制输入信息存储的地址
右击第一个1,右击如下:或者快捷键ctrl+shift+M快捷键,但是我的我的快捷键不太好使
将输入的部分转化成符号,可以在汇编窗口找地址会更方便一点
然后f9跳转到判断flag正确与否的部分,也就是第二个断点
这里就是函数判断和密文是否相同的地方,左边的是正确的flag的函数,会继续验证下一位,右边是错误的flag,会直接错误然后跳出 然后右击如下,就得到了第一个flag的f
之后复制左边下一个函数的eip,修改栈窗口的eip,让程序继续执行 (原理会在下面进行解释
大概的操作是这样的,现在我输入flag{111111111111111111111111111}
在确定前五位的情况下进行往后的爆破,一位一位爆就拿到了flag
大概原理我猜是用的angr进行模拟执行程序,从0开始爆破一直爆破到当前位数会跳转到flag正确走法时,才会结束当前位数的爆破
然后通过修改eip的方式强制让程序走flag输入正确的代码然后继续爆破下一位
ps:我做的时候不知道为什么不能一直爆破,我只能一位一位地来爆破…..
flag{as2f8v9sd67239c7s5d8901d76d}、
这个方法貌似不适用全部的vm,也没有什么手撕vm的技巧,只能做题的时候遇到vm试试这样的操作吧,如果爆不出来(比如ida一直在执行指令)那只好see you 垃圾桶了
0x6.ANDROID
java端没有什么信息,就是对一个图片和输入传入了libmidand里面
看一下so的jni函数
密文就是dat部分,直接提取出来
73 1E 13 3E F7 6A 5C D1 EF 96 26 A9 94 7C F4 A4 6C E2 37 B7 0D 49 05 E9 21 E3 5E 2E 7D 7A 1A 74
然后可以来hook一下murmur3_32的函数来获取v9的数值,v19的前16位拿来第一次加密,后面的16位拿来加密第二次、
so的hook和java层的hook差不多,只不过java层可以直接拿函数名字来hook(没有混淆的情况下)
so层就要先通过函数名来找到该函数的地址,然后以地址为基准进行hook
1 | var func_addr = Module.findExportByName("libmidand.so" , "_Z10murmur3_32PKcjj"); |
hook一下地址
得到了地址,然后就可以直接hook了
完整的注释代码如下:
1 | // 查找名为 "libmidand.so" 的库中导出函数名为 "_Z10murmur3_32PKcjj" 的函数,并将函数地址赋值给 func_addr 变量 |
跟进encode_fun,看到里面是一个标准的sm4算法,并且是ECB/Nopadding模式
特征挺明显,直接拿去赛博厨子解密吧
第一次解密:
第二次解密:
两次的结果:
fad1c7e27ec411ee.8¬ô).r.dÊ{Äâ..C
..®..\XCN¿qAºb’Ýbe3a3e4419a1b3cc
第一段的前16位和第二段的后16位进行拼接,得到flag
flag{fad1c7e27ec411eebe3a3e4419a1b3cc}
总结:一般来说,如果是简单的so层hook的话,直接套函数进行hook然后输出hexdump就可以拿到想要的返回值了,有点类似于动调的作用了。(因为本人电脑不知为何,so总是动调不起来,所以只能hook了)
如果要实现更灵活的hook,类似于修改hex的值或主动调用等功能还是需要继续学习继续进步!