View difference between Paste ID: wFUdByV7 and mFb1r5Tz
SHOW: | | - or go back to the newest paste.
1
/*
2
3-
  ______ ___ _____ ___.______ ________   _______ _________   ______  _____ ___.
3+
  ______ ___ _____ ___.______ ________	 _______ _________   ______  _____ ___.
4-
 /  ___/(  /_\    \\  :      \\   __ /_ _\ ___ //    _   /__/  ___/__\    \\  :
4+
 /  ___/(  /_\	  \\  :	     \\	  __ /_ _\ ___ //    _	 /__/  ___/__\	  \\  :
5-
_\  _/  |\/ //   . \  |    _   \   _   \\   .  /_____/__/  _\  _/   |    . \  |
5+
_\  _/	|\/ //	 . \  |	   _   \   _   \\   .  /_____/__/  _\  _/   |	 . \  |
6-
\       |   /    :    |    /    \  /    \   :    |    \_   \        |    :    |
6+
\	|   /	 :    |	   /	\  /	\   :	 |    \_   \	    |	 :    |
7
 \______:__//____|____|_________/_______/   |____:__________\_______:____|____|
8-
                                      /_____|           
8+
				      /_____|
9
10
11
  KLPD Cybercrime Challenge 2013 -- Alternative solution for IRC C&C
12
13
  Instead of fishing the /passphrase/ from the memorydump, this utility
14
  searches for the raw 256bit key in memory. It simply treats every 32-
15
  byte block as a key, decrypts the given ciphertext and checks if the
16
  deciphered block consists of pure 7bit ascii characters. This is a
17
  pretty effective way to find "candidates" for possibly correct keys.
18
  To thwart some more false candidates we do a basic entropy check on
19
  the candidate key before letting it pass.
20
21
  This might sound quite expensive, but it churns to through the
22
  entire 512 megabyte memorydump within 2 minutes on an average desktop
23
  computer. Leaving you with only one candidate that matches all of
24
  the given basic constraints: the correct AES key :-)
25
26
  This AES key can be used to encrypt/decrypt any further messages!
27
28
  -- EINDBAZEN / 2013-03-31
29
30
31
  sample run:
32
  $ gcc -o keyfinder keyfinder.c -lcrypto
33
  $ time ./keyfinder memory.raw \
34
    `echo dfI8J5hkgaQ6vtYtKK2d7Qlou650S9m1FZ697bZ01TCOTnCTWtyCzqyZe9UV4bBHZN9nkm4j/2Py|base64 -d`
35
  1ca16c00..
36
37
  FOUND POSSIBLE KEY: 6c99160e2cdd68f68b9e09938453fc499ca6ab9df2eed14399663e1cb2461b40 --> 'supported comman'
38
  20000000..
39
  real	1m46.199s
40
  user	1m44.187s
41
  sys	0m1.004s
42
43
*/
44
#include <stdio.h>
45
#include <string.h>
46
#include <stdlib.h>
47-
#include <unistd.h> 
47+
#include <unistd.h>
48
#include <sys/types.h>
49
#include <sys/stat.h>
50
#include <openssl/aes.h>
51
52
int decrypt(unsigned char *k, unsigned char *d, int dlen) {
53
	AES_KEY aes_key;
54
	unsigned char iv[0x10], plaintext[0x20], ent_buf[256];
55
	int i;
56
57
	memset(iv, 0, 16);
58
59
	AES_set_decrypt_key(k, 256, &aes_key);
60
	AES_cbc_encrypt(d, plaintext, 0x20u, &aes_key, iv, AES_DECRYPT);
61
62
	// all plaintext 7bit ascii?
63
	for(i = 0; i < 16; i++) {
64
		if (plaintext[i] < 0x20 || plaintext[i] > 0x7e)
65
			return -1;
66
	}
67
68-
	// somewhat legit entropy?
68+
69
	printf("\n\nFOUND POSSIBLE KEY: ");
70
	for(i=0;i<32;i++) {
71
		printf("%02x", k[i]);
72-
		ent_buf[ k[i] ]++;
72+
73
74
	printf(" --> '");
75-
	for (i=0;i<256;i++) {
75+
76-
		if (ent_buf[i] > 2)
76+
77
		printf("%c", plaintext[i]);
78
	}
79
80
	printf("'\n");
81
82
	return 0;
83
}
84
85
int main(int argc, char *argv[]) {
86
	unsigned char *blob;
87
	FILE *fp;
88
	struct stat st;
89
	int pos=0, i, nonrandom=0;
90
	unsigned char ent_buf[256];
91
92
	if (stat(argv[1], &st) < 0) {
93
		perror("stat");
94
		return -1;
95
	}
96
97
	fp=fopen(argv[1], "rb");
98
99
	blob = malloc(st.st_size);
100
	fread(blob, st.st_size, 1, fp);
101-
	int pos=0;
101+
102
103
	memset(ent_buf, 0, 256);
104
	for(i=0;i<32;i++) {
105
		if (++ent_buf[blob[i]] == 3) ++nonrandom;
106
	}
107
108
	while(pos < st.st_size) {
109
		if (!nonrandom) {
110
			decrypt(blob+pos, (unsigned char*)argv[2], 32);
111
		}
112
		for(i=0;i<4;i++) {
113
			if (ent_buf[blob[pos]]-- == 3) --nonrandom;
114
			if (++ent_buf[blob[pos + 32]] == 3) ++nonrandom;
115-
		decrypt(blob+pos, (unsigned char*)argv[2], 32);
115+
			++pos;
116-
		pos += 4;
116+
117
		if ((pos % (1024)) == 0) {
118
			printf("%08x..\r", pos);
119
			fflush(stdout);
120
		}
121
	}
122
123
	free(blob);
124
125
	return 0;
126
}