1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include<WinSock2.h>
typedef union {
int16_t s16[8];
uint16_t u16[8];
int32_t s32[4];
} result_t;
typedef union {
int64_t s64;
int32_t s32[2];
uint32_t u32[2];
int16_t s16[4];
} var_t;
uint32_t portBlacklist[64] =
{
0xffffffff, 0xffffffff, 0xf0f6bfbb, 0xbb5a5ff3,
0xf3977011, 0xeb67bfbf, 0x5f9bfac8, 0x34d88091,
0x1e2282df, 0x573402c4, 0xc0000084, 0x03000209,
0x01600002, 0x00005000, 0x801000c0, 0x00500040,
0x000000a1, 0x01000000, 0x01000000, 0x00022a20,
0x00000080, 0x04000000, 0x40020000, 0x88000000,
0x00000180, 0x00081000, 0x08801900, 0x00800b81,
0x00000280, 0x080002c0, 0x00a80000, 0x00008000,
0x00100040, 0x00100000, 0x00000000, 0x00000000,
0x10000008, 0x00000000, 0x00000000, 0x00000004,
0x00000002, 0x00000000, 0x00040000, 0x00000000,
0x00000000, 0x00000000, 0x00410000, 0x82000000,
0x00000000, 0x00000000, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000008, 0x80000000
};
#define IS_PORT_BLACKLISTED(x) (1 << ((x >> 5) & 0x1F)) & portBlacklist[x >> 10]
/* NB: the portgen() function below is endian-dependent, and reverse-engineered
for a little-endian (e.g. x86, VAX, Alpha, etc.) machine. Changes will be
required for the array offsets in the unions to run on a big-endian (e.g. most
SPARC, Power(PC), MIPS, etc.) machine. Other than the endian issue, this
implementaiton should be portable. */
int portgen(int ip, result_t *res, int week)
{
var_t v;
int64_t KONST = 0x15A4E35;
int i;
memset(res, 0, sizeof(result_t));
v.s32[0] = ~ip;
/* Generate fixed ports */
do {
do {
v.s64 = KONST * v.u32[0] + 1;
res->s16[0] ^= v.s16[2];
for (i=1; i < 10; i++) {
v.s64 = KONST * v.u32[0] + 1;
res->s16[(i%2)*2] ^= v.s32[1] >> i;
}
} while (IS_PORT_BLACKLISTED(res->s32[0]));
} while (IS_PORT_BLACKLISTED(res->s32[1]) || res->s32[0] == res->s32[1]);
v.s32[0] = week ^ v.s64;
/* Generate week-dependent ports */
do {
do {
v.s64 = KONST * v.u32[0] + 1;
res->s16[4] ^= v.s16[2];
for (i=1; i < 10; i++) {
v.s64 = KONST * v.u32[0] + 1;
res->s16[(i%2)*2 + 4] ^= v.s32[1] >> i;
}
} while (IS_PORT_BLACKLISTED(res->s32[2]));
} while (IS_PORT_BLACKLISTED(res->s32[3]) || res->s32[2] == res->s32[3] ||
res->s32[0] == res->s32[2] || res->s32[1] == res->s32[2] ||
res->s32[0] == res->s32[3] || res->s32[1] == res->s32[3]);
return v.s64;
}
int main(int argc, char** argv) {
int a1,a3;
result_t res;
int i, rc;
if (argc != 3) {
printf("usage: conficker_ports <ip addr> <epoch week>\n");
exit(0);
}
a1 = inet_addr(argv[1]);
a3 = atoi(argv[2]);
rc=portgen(a1, &res, a3);
printf("ports are TCP (fixed), UDP (fixed), TCP (week-dependent), UD (week-dependent)\n");
for (i=0;i<8;i++) {
if (res.u16[i])
printf("%d\t", res.u16[i]);
}
printf("\n");
return 0;
}
|