我一直在尝试使用CRC的第一个字节和加密标头的最后一个字节来暴力破解ZipCrypto的Key2,看看需要多长时间,但我得到了超过2000的有效密钥。 从APPNOTE中,Key2用于解密字节,Key2是CRC32的结果,这意味着它是一个32位值,应该在2147483648到2147483648范围内找到*2.
此测试流的密码是
1234
CRC 是
77D7DCDE
然后直播:
50 4B 03 04 14 00 01 00 08 00 68 99 6D 58 DE DC D7 77 CB 82 07 00 0F B1 0A 00 09 00 00 00 6B 65 79 73 30 2E 74 78 74 50 3F 83 D5 C7 D4 69 6E 9B B9 E9 F2 DD 16 D5 EA 5B 41 F9 BC 59 6E 34 E8 2F 2B 49 4E DD 90 3E D8 65 5E 21 42 E6 8C 8C AD 8E
这是代码示例:
#ifdef LINUX
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
typedef pthread_t thread;
typedef pthread_mutex_t mutex;
static inline void mutex_init(mutex *m)
{
int res = pthread_mutex_init(m, NULL);
assert(res == 0);
}
static inline void mutex_lock(mutex *m)
{
int res = pthread_mutex_lock(m);
assert(res == 0);
}
static inline void mutex_unlock(mutex *m)
{
int res = pthread_mutex_unlock(m);
assert(res == 0);
}
static thread spawn_thread(void *(f)(void *), void *arg)
{
thread t;
int res = pthread_create(&t, NULL, f, (void *)arg);
if (res != 0)
return (thread)NULL;
return t;
}
static void join_thread(thread t)
{
pthread_join(t, NULL);
}
static size_t num_threads(void)
{
return (size_t)sysconf(_SC_NPROCESSORS_ONLN);
}
static uint64_t get_time(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}
#endif
unsigned char decrypt_byte(size_t Key2) {
uint32_t dkey = Key2;
unsigned short temp = dkey | 2;
return (temp * (temp ^ 1)) >> 8;
}
static bool bytecheck(const unsigned char dat)
{
unsigned char targ = 0x77;//first byte of my Checksum
if(dat == targ)
{
return true;
}
return false;
}
struct info
{
unsigned char buffer;
size_t start;
size_t end;
};
// Stop when a thread finds a solution.
static volatile bool stop = false;
static void *worker(void *arg);
static thread spawn_worker( size_t start, size_t end, unsigned char buffer)
{
struct info *info = (struct info *)malloc(sizeof(struct info));
assert(info != NULL);
info->start = start;
info->end = end;
info->buffer = buffer;
thread t = spawn_thread(worker, info);
if (t == (thread)NULL)
{
fprintf(stderr, "error: failed to spawn thread");
exit(EXIT_FAILURE);
}
return t;
}
static void *worker(void *arg)
{
struct info *info = (struct info *)arg;
size_t start = info->start;
size_t end = info->end;
unsigned char buf = info->buffer;
free(info);
for(size_t i =start; i < end+1; i++)
{
if (stop)
return NULL;
unsigned char res = decrypt_byte(i);
unsigned char C = buf ^ res;
if (bytecheck(C))
{
printf("%zu\n",i);
stop = true;
return NULL;
}
}
}
//gcc ben.c -pg --std=gnu99 -lz -lm -lpthread -o zipcr
int main()
{
size_t NUM_WORKERS = num_threads();
printf("threads = %lu\n", NUM_WORKERS);
uint64_t t0 = get_time();
size_t tap = 2147483648;
size_t port = tap / NUM_WORKERS;
thread ts[NUM_WORKERS];
for (size_t i = 0; i < NUM_WORKERS; i++)
{
size_t start = tap+ (i*port);
size_t end = start+port;
unsigned char buffer = 0xF2;
ts[i] = spawn_worker(start, end,buffer);
}
for (size_t i = 0; i < NUM_WORKERS; i++)
join_thread(ts[i]);
uint64_t t1 = get_time();
printf("\ntime = %lums\n", t1 - t0);
return 0;
}
为什么我收到这么多误报,我的代码出了什么问题?
所有这些都归结为:
#include <stdio.h>
int main(void) {
size_t tap = 2147483648;
for (size_t i = tap; i < 2 * tap + 1; i++) {
unsigned short temp = i | 2;
unsigned char ch = 0xf2 ^ ((temp * (temp ^ 1)) >> 8);
if (ch == 0x77)
printf("%zu\n", i);
}
return 0;
}
除了我删除了“停止”,以便打印所有结果。 (顺便说一句,这在我的机器上运行大约两秒钟,所以我不明白所有线程的意义是什么。)
这会打印 8388608 个结果,这是迭代次数的 1/256(减一)。正是您在检查随机生成的一个字节时所期望的。这里没有什么奇怪的。你在期待什么?
然而,在 231 情况下运行它(由于某种原因加上 1 个)是没有意义的,因为查询的输入只有 16 位(短)!或者在
| 2
之后实际上只有 15 位。您只需要 32768 次迭代即可探索函数的整个域。