-
-
[原创] 看雪.众安 2021 KCTF 秋季赛 - 签到题 身在何处 by 心学
-
发表于: 2021-11-15 13:54 2955
-
【1、工具】
IDA
【2、推导过程】
2.1、判断公式
(1)、F(用户名) xor HEX(序列号) = 52A1ED5A
(2)、G(52A1ED5A) = 13B88C77
2.2、经过动态跟踪:
F("01F845C5B7C52E56") = 744E1CC7
F("KCTF") = 5EE54F4C
2.3、最终要求出:
HEX(序列号) = 5EE54F4C xor 52A1ED5A = 0C44A216
序列号 = INT(0C44A216) = 205824534
【3、分析过程】
3.1、找到 字符串
双击该行,找到变量定义
双击该行,进入关键代码
3.2、找到 关键代码
3.3、分析 代码
v2 = sub_281260(name, nameLen)
此函数只对用户名做操作,建议不跟踪具体代码,我们可以通过调试来获取KCTF的对应值,该函数对应于前面提到的F
strspn(sn, "0123456789") == strlen(sn)
对序列号进行初步判断,感觉没啥用,估计是作者为了防止调试的时候,直接输入123456、1234567、……、123456789 等等,会直接跳出到错误提示对话框。
C 库函数 size_t strspn(const char str1, const char str2) 检索字符串 str1 中第一个不在字符串 str2 中出现的字符下标。
不匹配,那就是10,然后序列号的长度必须为9才行(加上终止符,就是10)
如果匹配了,假如开头部分相同,那就是序列号的长度,该条件通过
如果匹配了,但是开头部分不相同,比如序列号是1、12、123、此时,该条件不通过
snLen <= 10
需要小于等于10,考虑到终止符,那就是序列号长度小于等于9
v4 = sub_28307F(v3, (int)sn)
它只对 序列号 做处理,先放置,这个是关键。对应于前面提到的G
unknown_libname_13(v2 ^ v4, a1, 0x10)
这个方法具体做啥用,其实不用跟踪进去,我们跟踪时发现没啥用。
a1 = v2 ^ v4
sub_281260(a1, 8) == 0x13B88C77)
对a1处理之后的结果要等于 0x13B88C77
这个函数不用跟进去,我们只要使得之前计算出来的a1等于此时调试获得的值就行。这是有正确的序列号的好处,如果没有正确的序列号,代码运行到此处的a1值肯定是错误的,那么就需要跟踪此函数,了解其内部功能。
3.4、调试 与 分析
(1)、用正确的用户名和序列号跟踪
sub_281260(a1, 8) == 0x13B88C77)
a1 = 52A1ED5A
v4 = sub_28307F(v3, (int)sn)
这个v3是通过ecx传入进去的,应该是对象指针,不需要考虑,重点是后面的参数
v4 = sub_28307F((int)sn)
sn = "653259165"
v4 = 26EFF19D
字符串 转 整数对应的十六进制数?拿计算器算一算,猜测是正确的。
如果是错误的,那只能老老实实去跟踪代码了。
(2)、用正确的用户名KCTF和任意的序列号跟踪
v2 = sub_281260(name, nameLen)
v2 = 5EE54F4C
(3)、计算 v4
v2 = a1 ^ v4 => v4 = a1 ^ v2 = 52A1ED5A xor 5EE54F4C = 0C44A216
(4)、计算序列号
INT(0C44A216) = 205824534
为什么是 求其int值,这是通过调试代码出来的。前面已有分析过程,考虑到是签到题,不太可能是复杂的加密算法。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课