代码里很多这种结构:
000000014005FE4C | 53 | push rbx
000000014005FE4D | 50 | push rax
000000014005FE4E | 50 | push rax
000000014005FE4F | 9C | pushfq
000000014005FE50 | E8 00000000 | call kctf.14005FE55
000000014005FE55 | 58 | pop rax
000000014005FE56 | 48:35 38BA0900 | xor rax,9BA38
000000014005FE5C | 48:894424 10 | mov qword ptr ss:[rsp+10],rax
000000014005FE61 | 9D | popfq
000000014005FE62 | 58 | pop rax
000000014005FE63 | C3 | ret |
实际就是jmp到014005FE55 xor 9BA38的地方
全部处理替换一下,再调试虽然还有些其它的垃圾代码,基本可以忍受了
从ReadFile断点开始得到读取输入的地方,从运行库返回走一段就能看到比较输入长度的地方:
0000000140083333 | 48:83F8 54 | cmp rax,54
慢慢调试看到大概是44进制的操作,输入转换表是"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%=":
00000001400BA991 | 48:69C0 2A000000 | imul rax,rax,2A
输入转换存到一个数组里:
00000001400787FE | 48:8984CC C00E0000 | mov qword ptr ss:[rsp+rcx*8+EC0],rax
能看到有个判断要求输入是从很小到大排列的
后面算法不复杂,只是花代码比较多,耐心慢慢调试就可以了
大概逻辑就是输入的84个字符,有一半是索引从小到大做间隔,剩下一半42个数值需要满足相同索引间距的两两数值之差必须各不相同。
最后会看到strncmp "02152S3X4Z5Q6C7T819/ADB%C*DL",比较输入的前三分之一
解法还是可以用递归实现,得到完整序列号:02152S3X4Z5Q6C7T819/ADB%C*DLEIFUG3HRIHJ6K7L0MBNKOJPPQ=RNS+TEUOVWWGXYYMZ9+4-8*F/-%V=A
DWORD genmap(BYTE a[128][64], BYTE *x, int n)
{
DWORD rv = 1;
int i,j;
int u,v;
for (i=0;i<n;i++)
{
for (j=i+1;j<n;j++)
{
v = x[j] - x[i];
u = j - i;
if (a[64+v][u] == 1)
{
return 0;
}
a[64+v][u] = 1;
}
}
return rv;
}
DWORD chkmap(BYTE a[128][64], BYTE *x, int n)
{
DWORD rv = 1;
int i;
int u,v;
for (i=0;i<n-1;i++)
{
v = x[n-1] - x[i];
u = n - 1 - i;
if ((v == 0) || (a[64+v][u] == 1))
{
return 0;
}
}
return rv;
}
DWORD loop(BYTE m[128][64], BYTE *x, int n)
{
DWORD rv = 0;
BYTE t[128][64];
int i;
if (n >= 42)
{
char *s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%=";
for (i=0;i<42;i++)
{
printf("%c", s[i]);
printf("%c", s[x[i]]);
}
printf("\n");
return 1;
}
for (i=0;i<42;i++)
{
x[n] = i;
if (chkmap(m, x, n+1))
{
memset(t, 0, sizeof(t));
genmap(t, x, n+1);
loop(t, x, n+1);
}
}
return rv;
}
void cr06()
{
int i,j;
BYTE x[64];
BYTE m[128][64] = {0};
for (i=0;i<14;i++)
{
for (j=0;j<42;j++)
{
if ("02152S3X4Z5Q6C7T819/ADB%C*DL"[2*i+1] == "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%="[j])
{
x[i] = j;
break;
}
}
}
genmap(m, x, 14);
loop(m, x, 14);
}
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界