-
-
[原创] KCTF 2019 Q3 第十三题 Writeup by Nu1L & 没做出来的题目的分析
-
发表于: 2019-9-22 23:04 3368
-
check在 0x407f30
看到了熟悉的大整数计算
拆 partA KXCTFXXXX partB
partB 十六进制数 0-9A-F 长度大于8
partA 就是username这个字符串
对partB + cdeae8b5b9e9d5d4 + deadbeefcafec0de + cdeae8b5b9e9d5d4cdeae8b5b9e9d5d4
做了一个sha1
这里的+是连接
sha1字符串后面又放了一个KXCTF19Q3
对几个东西都sha1了一下,都是固定的,可以提出来
其中下标为1的是username这个字符串的sha1,看出来作者是想做一队一密的
还有几个常数,提取一下
逆向过程有点痛苦
整理一下算法
其中有一个F函数比较迷,单独拿出来看
整体流程大概这样
https://github.com/aleaxit/gmpy/blob/master/src/gmpy_mpz_lucas.c
翻了一整篇gmp的文档,经过一些运算性质的判定和测试,确定F函数求的是Lucas序列
https://en.wikipedia.org/wiki/Lucas_sequence
返回值是(Ux, Vx, V(x-1))
然后要处理一下,化简一下这个里面的那些神奇的运算
现在已经知道
其中P和Q是Lucas序列的参数,k是需要求第k项,n是模数,U(k)和V(k)是Lucas U序列和V序列的第k项
首先,因为在模n的有限域里面,所以所有大于n的数都可以等价为模n
显然x等价于1
设flag=e,等价于flag_num+sha1s[0]
那么后面涉及的Lucas序列就都是P=flag Q=1的
F函数操作一下之后,获得了两个K=shas的序列值
设sha1(flag) = 0xSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
设取反是0xRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
显然对于每一个十六进制位,Si+Ri=0xF
那么得到了k1,k2是
那么xx,yy可以得到
下面看这一波运算
ps数组里面都是1,暂时不管
看一下前两个式子
U序列和V序列都有一些运算性质的
根据性质
可得第一个式子在算U(2k)
然后根据
这里Q刚好是个1,所以就是第二个式子
所以这一个循环就是把U和V的k值乘了2
一共循环了72次,就是乘了2的72次方,也就是左移72位,就是9个字节
跑完了以后,现在k1和k2相当于
看上去有趣了起来
然后继续看下面的运算
根据之前的式子可以看出来f是一个模d的除2操作
所以实际上是
然后Lucas序列又有如下性质
其中
显然,就是上面那个式子的形式
那么这时候z就是V(k1+k2)
k1和k2之前知道了
然后又因为两个sha1是按位取反的关系,所以任意Si+Ri=0xF
这一加起来就是
SHA1消掉了!
算了这么多,到现在就是一个式子
继续往下算
给z加了一个sha1s[1]
这里x=d+1,所以w可以算,也是d+1
然后算了P=z Q=1 模数为d的lucas序列的第w-1项,就是第d项
实际上就是
最后加上一个sha1s[3],模d看是否等于sha1s[2]
所以总结一下,流程是这样
可以看到实际上就是算了两个式子,真实
那么问题就转化为
已知Q=1,k,n,以及V(k),求P
是Q=1的Lucas序列,可能有一些特殊性质,去找一找资料
读论文
http://informatika.stei.itb.ac.id/~rinaldi.munir/Kriptografi/2012-2013/Makalah2-2013/Makalah2Kripto2013-015.pdf
这个是一种基于Lucas序列的公钥加密体制
完全分解N的情况下可以求私钥
这个题N不大,可以分解
逆!
32字符flag 字母数字
读进去转成64进制数字
作为opcode
整理一下VM功能表
不断的循环跑这32字节的bytecode,直到r0=128算跑一遍
一共跑128遍
这能逆?
猜一下,源数组和目标数组里面都是0-127全来了一遍,一般的运算凑不出来,可能是代换/置换盒,这几个运算里面能简单做代换的就异或
14524627489 4624527489 452462749 00
但是好像不对
作为置换盒的话,连续置换几次是会回去的,感觉可能是个突破口
带混淆的安卓
https://bbs.pediy.com/thread-253533.htm
https://github.com/GeT1t/deollvm/blob/master/cfg.py
是控制流平坦化+指令替换+虚假控制流
发现了NISLFILE,根据特征找到这个文章
http://www.xjishu.com/zhuanli/55/201810446991.html
两个virtualprotect,更改前后如下
文件头被改了,文件头:
事先把保留字给改成了一个地址,然后执行fld,将这个地址放入st0,不知道在干什么,先拿出来备用
又把这玩意拿出来了,stackbase和stacklimit,两个地址,做差,算了一个size,地址以4(Dword对齐),放回dos头里,就是算了线程栈的大小然后把线程栈里面的东西复制到wtf中,备份esp,ebp.
前面就是因为start没什么内存,先是用没用的dos头存数据,然后把栈迁移到另外的一个地址,备份esp,ebp,开始脱壳.试一下esp定律,下了个硬件断点,好像ida炸了
过了一个指令异常,前一堆rdtsc,后面下断,找到一个call eax,东西在这里面
有地址随机化
跟进eax,还是壳的部分,按照脱壳的套路来,有上跳就下断,然后好几处call eax,估计在循环解码,有常量加密
一次567000一次其他的地址,运算全部带有常量混淆,以及所有的指令都是jmp这种,正好和控制流平坦化相反了,这玩意流程是一个纵向的
一堆rdtsc好像没什么影响,OD可以直接过反调试,rdtsc对OD无效
下了个puts(好像是)的断点,在最后打印的时候,看到了结尾左右的逻辑,popad后进行判断然后跳转,最后打印后执行Terminal
调吧 = =,好像并没有发现什么指令集的转换,都是一些很无聊的跳转加上循环
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!