-
-
[原创]CTF 2019 第一题 流浪者
-
发表于: 2019-3-10 18:25 2146
-
用x64dbg打开程序,查找字符串:
可以找到错误提示和正确提示字符串。
双击“错了”字符串,可以找到弹出错误提示的函数:
搜索命令:“call 0x004017B0”,找到调用的地方:
往上翻看,可以看到关键代码:
可见程序调用了一个函数来验证注册码。
分析算法可知,程序中有一个字符串常量s = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ",程序首先对输入的注册码进行处理,计算出一个相同长度的数组a,对i从0到len(a) - 1,所有s[a[i]]构成了一个新字符串,最后判断新字符串是否等于“KanXueCTF2019JustForhappy”。如果相等的话就弹出正确提示,否则就弹出错误提示。以上过程可用c语言描述:
但是此时还不清楚数组a是怎么来的,于是查找命令"call 0x004017F0",来到验证函数的调用处:
往上看,可以看到数组a的生成过程。
分析算法可知,程序先检测输入的字符是否是小写字母、大写字母或数字,如果不是则直接提示错误。对用户输入的每一个字符input[i],
(1)若 input[i]
为小写字母,则a[i] = input[i] - 0x57;
(2)若
input[i]
为大写字母,
则a[i] = input[i] - 0x1d;
(3)若
input[i]
为数字,则a[i] = input[i] - 0x30.
知道了以上算法,我们便可从最终的"
KanXueCTF2019JustForhappy
"逆推出数组a的内容,然后进一步逆推出注册码。
计算注册码的c语言程序如下所示:
#include <stdio.h> #include <string.h> int main() { char mask[] = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"; char dest[] = "KanXueCTF2019JustForhappy"; for (int i = 0; i < 25; ++i) { for (int j = 0; j < strlen(mask); ++j) { if (mask[j] == dest[i]) { if (j <= 9) { printf("%c", j + '0'); } else if (j >= 10 && j <= 35) { printf("%c", j + 0x57); } else { printf("%c", j + 0x1d); } } } } printf("\n"); return 0; }
最终算出的注册码为:j0rXI4bTeustBiIGHeCF70DDM.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [原创]看雪CTF2019 第六题 Repwn 2773
- [原创]看雪CTF2019 第十题 初入好望角 2775
- [原创]CTF 2019 第一题 流浪者 2147
谁下载
无
看原图
赞赏
雪币:
留言: