CTF Re Mo writeup

2017看雪秋季CTF--第三题分析笔记

2017-11-18  本文已影响19人  SueLyon

这道题使用了三种加密:

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法 ,基本原理是ASCII值的8 * 3变6 * 4

Morse code是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母、数字和标点符号,它的代码包括五种: 点、划、点和划之间的停顿、每个字符间短的停顿(在点和划之间)、每个词之间中等的停顿以及句子之间长的停顿

国密SM3密码杂凑算法 对长度为l(l < 2^64) 比特的消息m, SM3杂凑算法经过填充和迭代压缩,生成杂凑值,杂凑值长度为256比特

打开题目:


题目

点击验证序列号,没反应,它并没有给什么提示
直接上IDA String:
发现很多有趣的字符串


string1.png

好像有散列和base64


anti-debug .png anti-debug 2.png

好多常用分析调试工具的名字和窗口名称呀!
这里猜测程序有反调试~还好我用的静态分析
再看看导入函数:


imports.png
发现有窗口和读取字符,我们跟进GetDlgItemTextA,然后F5
main.png

简单跟进几个sub看看,梳理一下逻辑

读取输入的字符串保存在String,sub_42D267处理String并存为v16
v16再次经过sub_42D267处理并存为v14
v14又经过sub_42D96A修改了值
sub_42DA78处理的v14,存为局部变量v11,之后print v11为16进制格式
v5给的是末尾地址,memcmp比较内存区域buf1和buf2的前count个字节,也就是比较原输入String末尾v6长度的值与v10的值是否一致,之后进入sub_42D9AB继续判断,若布尔值为1,弹窗ok

接下来重点看这几个调用在干什么

进sub_42D267


decode.png

看到函数在循环提取byte_48B0FD(查看值为base64范围内的值),并且关于4在做不同处理,程序在解密base64,把6 * 4变8 * 3,并且不能出现等号

关于sub_42D96A,
String发现有字符 "." "-" "*" ,仔细看发现已经是标准的Morsecode


morse.png

点进0049B2A4,找到表0049B2A0处的数据表,

对应a~z:
.-**
-...
-.-.
-..*
.***
..-.
--.*
....
..**
.---
-.-*
.-..
--**
-.**
---*
.--.
--.-
.-.*
...*
-***
..-*
...-
.--*
-..-
-.--
--..

并且一路向上找,发现确实是sub_42D96A在调用,那就确定了

进sub_42DA78,三个调用,逐一跟进, 看上去好像做了个hash运算,三个步骤init,do,finalize.
又发现String窗口也有


string .png

init中找hash常量


百度得知,此常量为国密SM3密码杂凑算法,并切从调用出发现处理的是v14前三个字符

最后还有 sub_42D9AB,


看到对传入的指针a2进行判断,若为空格(ASCII 32)则结束操作返回1+9,若为z,l,q,p则有相对应的操作,并且指针a2循环提出数组v13的值
返回观察另外一个传入的值a1为unk_49B000的首地址,在unk_49B000看到数据值为0或1(均为4字节),回到算法里

先观察内部if判断,发现都类似于提取 * (基地址a1+40 * v3+4 * v4) ,两个局部变量v3v4权重差10倍,另一个if判断也是以10为边界,超过10函数返回
想到了可能是由10 * 10的01矩阵构成的迷宫图,看了unk_49B000范围也大于10 * 10 * 4,观察算法可发现v4作为列,v3作为行,z、l、q、p分别对应向下右上左走,0可走1不可走,且(3,8)为死点不能走,起始点为左上角,路线的末尾必须有一个空格,表示结束

迷宫图:
0 1 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 0 0 0
1 0 0 0 0 0 1 0 1 1
1 1 1 1 1 0 1 0 x 1
1 0 0 0 1 0 1 0 0 1
1 0 1 0 0 0 1 0 1 1
1 0 1 1 1 1 1 0 0 1
1 0 0 0 0 1 1 1 0 0
1 1 1 1 0 0 0 0 1 0
1 1 1 1 1 1 1 0 0 0
走法:
z    下
l    右
q    上
p    左

那么逻辑就清楚了:

走法是
zlzllllzzzppqppzzzlllzlllzllqqpqpqqqqqllq
然后转成摩尔斯编码(加“/   ”表示空格):
--.. .-.. --.. .-.. .-.. .-.. .-.. --.. --.. --.. .--. .--. --.- .--. .--. --.. --.. --.. .-.. .-.. .-.. --.. .-.. .-.. .-.. --.. .-.. .-.. --.- --.- .--. --.- .--. --.- --.- --.- --.- --.- .-.. .-.. --.-/ 
--.的hash:
b92a72497b685c31013347a7276f371f8cf91085ab8322009bfed2df41d94f94
做两层base64:(去=)
TFMwdUxpQXVMUzR1SUMwdExpNGdMaTB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDMHRMaTRnTFMwdUxpQXVMUzB1SUM0dExTNGdMUzB1TFNBdUxTMHVJQzR0TFM0Z0xTMHVMaUF0TFM0dUlDMHRMaTRnTGkwdUxpQXVMUzR1SUM0dExpNGdMUzB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDNHRMaTRnTGkwdUxpQXRMUzR0SUMwdExpMGdMaTB0TGlBdExTNHRJQzR0TFM0Z0xTMHVMU0F0TFM0dElDMHRMaTBnTFMwdUxTQXRMUzR0SUM0dExpNGdMaTB1TGlBdExTNHRMeUE
后面加上hash得到答案:
TFMwdUxpQXVMUzR1SUMwdExpNGdMaTB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDMHRMaTRnTFMwdUxpQXVMUzB1SUM0dExTNGdMUzB1TFNBdUxTMHVJQzR0TFM0Z0xTMHVMaUF0TFM0dUlDMHRMaTRnTGkwdUxpQXVMUzR1SUM0dExpNGdMUzB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDNHRMaTRnTGkwdUxpQXRMUzR0SUMwdExpMGdMaTB0TGlBdExTNHRJQzR0TFM0Z0xTMHVMU0F0TFM0dElDMHRMaTBnTFMwdUxTQXRMUzR0SUM0dExpNGdMaTB1TGlBdExTNHRMeUEb92a72497b685c31013347a7276f371f8cf91085ab8322009bfed2df41d94f94
ok.png

关于SM3 hash:有现成的py库
https://github.com/siddontang/pygmcrypto

三行py
from gmcrypto.sm3 import SM3
m ="--."
print SM3(m).hexdigest()

关于反调试

程序到处都有,随便找张图

关于bug
其实不算走迷宫
只要不踩1就成功了,也没有长度限制,没有判断一定要从左上角走到右上角,只是判断了输入的位置不能为1
所以注册码只要一个'z'就成功了
而且sm3 hash还能从内存中找到
sn:TFMwdUxpOGcb92a72497b685c31013347a7276f371f8cf91085ab8322009bfed2df41d94f94

总结:自己对加解密的具体实现还不了解,继续努力

上一篇 下一篇

猜你喜欢

热点阅读