BUUCTF-REVER-CrackMe3
0x1 查看信息
32位 要求输入正确的注册码
0x2 来咯来咯动调分析
因为输入了点击按钮,没有任何反馈,报错,弹窗都没有。所以获取输入下断
断下,观看堆栈第一个地址发现是用户领空,说明断对了
观察地址是哪里获取了
0x3 ida分析
地址函数过去发现了一个算法,看了开头好像是RC4的变异加密
看一下哪里调用了这个加密
这里有一个判断,动调的时候是可以发现 这里v6==6的判断是判断长度,可以确定是关键位置
观察了两个算法地址,开始编写脚本,就是rc4密钥扩展完加在一起要等于0x2979
0x4 编写脚本
#include<stdio.h>
unsigned char buf2[128] = { 0xF4, 0x12, 0x9D, 0x60, 0x45, 0xF8,0x20, 0x6A, 0x6F, 0x67,
0x04, 0x71, 0xC0, 0x9B, 0x0C, 0x5A, 0x1D, 0x18, 0x6C, 0x96,
0x69, 0x01, 0x1C, 0xF4, 0x7F, 0x28, 0x5A, 0xFB, 0x29, 0x07,
0x40, 0x8B, 0xD3, 0xE1, 0xB1, 0x12, 0xFB, 0xCA, 0x7C, 0x89,
0xB9, 0x5A, 0x30, 0x70, 0x9D, 0x95, 0x2B, 0x95, 0x3C, 0x8D,
0x2E, 0x45, 0xEF, 0x70, 0xC6, 0xA3, 0xB9, 0xB2, 0x5A, 0x63,
0x5F, 0x03, 0x33, 0xB8, 0x64, 0x4A, 0x8F, 0xBC, 0xF7, 0x91,
0x69, 0x6A, 0x56, 0x2E, 0xD4, 0x6E, 0x82, 0x93, 0xE9, 0x76,
0xDC, 0xA3, 0x6C, 0x5E, 0x6B, 0x72, 0x64, 0x37, 0xE7, 0x15,
0x17, 0xAC, 0x64, 0x78, 0xD5, 0x4A, 0x60, 0x2D, 0xF0, 0x54,
0xA6, 0xF3, 0xE8, 0xE0, 0xE0, 0xB9, 0x8F, 0x85, 0x90, 0xE4,
0xEA, 0xD6, 0xBB, 0xB7, 0x15, 0x9E, 0x2A, 0x44, 0xE7, 0x31,
0x63, 0xAC, 0x80, 0x6C, 0x34, 0x82, 0xE9, 0xCF
};
unsigned char buf3[128];
void rc4(const unsigned char* key, int len)
{
int i, j, k;
unsigned char m[256];
unsigned char a;
for (i = 0; i < 256; i++)
{
m[i] = (unsigned)i;
}
j = k = 0;
for (i = 0; i < 256; i++)
{
a = m[i];
j = (unsigned char)(j + a + key[k]);
m[i] = m[j];
m[j] = a;
if (++k >= (int)len)
k = 0;
}
unsigned char* y = &m[255];
unsigned char* x = m;
for (i = 0; i < 128; i++)
{
buf3[i] = buf2[i] ^ (*x + *y);
x++; y--;
}
}
int main()
{
char buf[8] = { 0 };
for (int i = 100000; i < 999999; i++)
{
sprintf(buf, "%06d", i);
rc4((unsigned char*)buf, 6);
int s = 0;
for (int j = 0; j < 128; j++)
{
s += buf3[j];
}
if (s == 0x2979)
{
printf("%s", buf);
}
}
}
这里的想法是直接爆破,6位数带进去。
flag{771535}
0x5 总结
又巩固了一手rc4加密原理,直接照ida的反汇编 写一遍爆破脚本,照葫芦画瓢