# HWSCTF
没有官方 WP💢😠
出了一道 animals, 另外两道是赛后看大佬 WP 复现的,一道安卓一道流量分析 主要是太摆了…
# Animals
去花指令
[+] Dump 0x608090 - 0x60809F (16 bytes) :
[0xDD, 0xB2, 0x6D, 0xF3, 0xE6, 0x0A, 0xC7, 0x83, 0x4A, 0x93, 0x50, 0xB4, 0xA4, 0x59, 0xAB, 0x0E]
魔改哈希算法
#include <memory.h> | |
#include "md5.h" | |
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
void MD5Init(MD5_CTX *context) | |
{ | |
context->count[0] = 0; | |
context->count[1] = 0; | |
context->state[0] = 0xEFCDAB89; | |
context->state[1] = 0x67452301; | |
context->state[2] = 0x10325476; | |
context->state[3] = 0x98BADCFE; | |
} | |
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen) | |
{ | |
unsigned int i = 0,index = 0,partlen = 0; | |
index = (context->count[0] >> 3) & 0x3F; | |
partlen = 64 - index; | |
context->count[0] += inputlen << 3; | |
if(context->count[0] < (inputlen << 3)) | |
context->count[1]++; | |
context->count[1] += inputlen >> 29; | |
if(inputlen >= partlen) | |
{ | |
memcpy(&context->buffer[index],input,partlen); | |
MD5Transform(context->state,context->buffer); | |
for(i = partlen;i+64 <= inputlen;i+=64) | |
MD5Transform(context->state,&input[i]); | |
index = 0; | |
} | |
else | |
{ | |
i = 0; | |
} | |
memcpy(&context->buffer[index],&input[i],inputlen-i); | |
} | |
void MD5Final(MD5_CTX *context,unsigned char digest[16]) | |
{ | |
unsigned int index = 0,padlen = 0; | |
unsigned char bits[8]; | |
index = (context->count[0] >> 3) & 0x3F; | |
padlen = (index < 56)?(56-index):(120-index); | |
MD5Encode(bits,context->count,8); | |
MD5Update(context,PADDING,padlen); | |
MD5Update(context,bits,8); | |
MD5Encode(digest,context->state,16); | |
} | |
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) | |
{ | |
unsigned int i = 0,j = 0; | |
while(j < len) | |
{ | |
output[j] = input[i] & 0xFF; | |
output[j+1] = (input[i] >> 8) & 0xFF; | |
output[j+2] = (input[i] >> 16) & 0xFF; | |
output[j+3] = (input[i] >> 24) & 0xFF; | |
i++; | |
j+=4; | |
} | |
} | |
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len) | |
{ | |
unsigned int i = 0,j = 0; | |
while(j < len) | |
{ | |
output[i] = (input[j]) | | |
(input[j+1] << 8) | | |
(input[j+2] << 16) | | |
(input[j+3] << 24); | |
i++; | |
j+=4; | |
} | |
} | |
void MD5Transform(unsigned int state[4],unsigned char block[64]) | |
{ | |
unsigned int a = state[0]; | |
unsigned int b = state[1]; | |
unsigned int c = state[2]; | |
unsigned int d = state[3]; | |
unsigned int x[64]; | |
MD5Decode(x,block,64); | |
FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */ | |
FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */ | |
FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */ | |
FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */ | |
FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */ | |
FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */ | |
FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */ | |
FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */ | |
FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */ | |
FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */ | |
FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ | |
FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ | |
FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ | |
FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ | |
FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ | |
FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ | |
/* Round 2 */ | |
GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */ | |
GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */ | |
GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ | |
GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */ | |
GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */ | |
GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */ | |
GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ | |
GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */ | |
GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */ | |
GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ | |
GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */ | |
GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */ | |
GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ | |
GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */ | |
GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */ | |
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ | |
/* Round 3 */ | |
HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */ | |
HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */ | |
HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ | |
HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ | |
HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */ | |
HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */ | |
HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */ | |
HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ | |
HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ | |
HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */ | |
HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */ | |
HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */ | |
HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */ | |
HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ | |
HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ | |
HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */ | |
/* Round 4 */ | |
II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */ | |
II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */ | |
II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ | |
II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */ | |
II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ | |
II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */ | |
II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ | |
II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */ | |
II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */ | |
II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ | |
II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */ | |
II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ | |
II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */ | |
II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ | |
II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */ | |
II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */ | |
state[0] += a; | |
state[1] += b; | |
state[2] += c; | |
state[3] += d; | |
} | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "md5.h" | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <string.h> | |
void main( void ) | |
{ | |
int read_len; | |
int i ; | |
char temp[8]={0}; | |
unsigned char digest[16]; // 存放结果 | |
char hexbuf[128]={0}; | |
int len =0; | |
for(int i=0;i<6;i++){ | |
for(int j=0;j<6;j++){ | |
for(int k=0;k<6;k++){ | |
for(int l=0;l<6;l++){ | |
for(int ii=0;ii<6;ii++){ | |
for(int jj=0;jj<6;jj++){ | |
for(int kk=0;kk<6;kk++){ | |
for(int ll=0;ll<6;ll++){ | |
for(int iii=0;iii<6;iii++){ | |
int len=0; | |
char hexbuf[128]={0}; | |
switch (i) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (j) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (k) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (l) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (ii) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (jj) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (kk) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (ll) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} switch (iii) { | |
case 0: | |
hexbuf[len++]='c'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='t'; | |
break; | |
case 1: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='g'; | |
break; | |
case 2: | |
hexbuf[len++]='f'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='x'; | |
break; | |
case 3: | |
hexbuf[len++]='p'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='d'; | |
hexbuf[len++]='a'; | |
break; | |
case 4: | |
hexbuf[len++]='d'; | |
hexbuf[len++]='r'; | |
hexbuf[len++]='a'; | |
hexbuf[len++]='g'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
break; | |
case 5: | |
hexbuf[len++]='m'; | |
hexbuf[len++]='o'; | |
hexbuf[len++]='n'; | |
hexbuf[len++]='k'; | |
hexbuf[len++]='e'; | |
hexbuf[len++]='y'; | |
break; | |
default: | |
printf("Invalid choice\n"); | |
break; | |
} unsigned char decrypt[16]={0}; | |
unsigned char decrypt32[64]={0}; | |
MD5_CTX md5c; | |
int a; | |
MD5Init(&md5c); // 初始化 | |
read_len = strlen(hexbuf); | |
MD5Update(&md5c,(unsigned char *)hexbuf,read_len); | |
unsigned char ccmp[16]={0xDD, 0xB2, 0x6D, 0xF3, 0xE6, 0x0A, 0xC7, 0x83, 0x4A, 0x93, 0x50, 0xB4, 0xA4, 0x59, 0xAB, 0x0E}; | |
MD5Final(&md5c,decrypt); | |
if((decrypt[0]==ccmp[0])&&(decrypt[1]==ccmp[1])&&(decrypt[2]==ccmp[2])&&(decrypt[3]==ccmp[3])&&(decrypt[4]==ccmp[4])&&(decrypt[5]==ccmp[5])&&(decrypt[6]==ccmp[6])&&(decrypt[7]==ccmp[7])&&(decrypt[8]==ccmp[8])&&(decrypt[9]==ccmp[9])&&(decrypt[10]==ccmp[10])&&(decrypt[11]==ccmp[11])&&(decrypt[12]==ccmp[12])&&(decrypt[13]==ccmp[13])&&(decrypt[14]==ccmp[14])&&(decrypt[15]==ccmp[15])){ | |
printf("%s",hexbuf); | |
exit(0); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
return; | |
} |
安卓
jadx 打开没看到 main 突发奇想用查壳看看 (好像有什么不对 感觉很多混淆都被识别成加固了?)
32 位的
https://github.com/CodingGay/BlackDex/releases
脱了之后看不懂
好像不是这样做?
大佬说直接看 so 文件的加密然后解密就是 flag 我测
直接看到 sm4 了…
再根据安装 APP 跳出的两个字符串直接解密 SM4 就行
赛后研究一下 SM4 加密
# USB 流量包分析
USB
tshark -r misc1.pcapng -T fields -e usb.capdata > usbdata.txt |
大佬的脚本得到键盘的输入的字符
import sys, argparse, os | |
class kbpaser: | |
def __init__(self): | |
#tshark 导出文件 | |
self.datafile="kbdatafile.txt" | |
self.presses= [] | |
#Keyboard Traffic Dictionary | |
self.normalKeys = {"04":"a", "05":"b", "06":"c", "07":"d", "08":"e", "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j", "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o", "13":"p", "14":"q", "15":"r", "16":"s", "17":"t", "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y", "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4", "22":"5", "23":"6","24":"7","25":"8","26":"9","27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"} | |
#Press shift | |
self.shiftKeys = {"04":"A", "05":"B", "06":"C", "07":"D", "08":"E", "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J", "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O", "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T", "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y", "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$", "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"","34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"} | |
def tshark_do(self, pcapfile, filterfield, fieldvalue): | |
if os.name == "nt": | |
if filterfield is not None: | |
command = f"tshark -r {pcapfile} -Y {filterfield} -T fields -e {fieldvalue} > {self.datafile}" | |
else: | |
command = f"tshark -r {pcapfile} -T fields -e {fieldvalue} > {self.datafile}" | |
try: | |
os.system(command) | |
print("tshark执行语句:" + command) | |
print("[+] Found : tshark导出数据成功") | |
except: | |
print("tshark执行语句:" + command) | |
print("[+] Found : tshark导出数据失败") | |
elif os.name == "posix": | |
#sed '/^\s*$/d' 主要是去掉空行 | |
if filterfield not in None: | |
command = f"tshark -r {pcapfile} -Y {filterfield} -T fields -e {fieldvalue} | sed '/^\s*$/d' > {self.datafile}" | |
else: | |
command = f"tshark -r {pcapfile} -T fields -e {fieldvalue} | sed '/^\s*$/d' > {self.datafile}" | |
try: | |
os.system(command) | |
print("tshark执行语句:" + command) | |
print("[+] Found : tshark导出数据成功") | |
except: | |
print("tshark执行语句:" + command) | |
print("[+] Found : tshark导出数据失败") | |
#筛掉无用数据,改变数据格式 | |
def formatkbdata(self): | |
formatfile = open("formatKbdatafile.txt","w") | |
with open(self.datafile, "r") as f: | |
for i in f: | |
# if len(i.strip("\n")) == 8: | |
# Bytes = [i[j:j+2] for j in range(0, len(i.strip("\n")), 2)] | |
# data = ":".join(Bytes) | |
# formatfile.writelines(data+"\n") | |
if len(i.strip("\n")) == 16: | |
Bytes = [i[j:j+2] for j in range(0, len(i.strip("\n")), 2)] | |
data = ":".join(Bytes) | |
formatfile.writelines(data+"\n") | |
formatfile.close() | |
def jiemi(self): | |
print("\n-----开始解密Tshark导出的键盘数据-----\n") | |
# 读取数据 z | |
with open("formatKbdatafile.txt", "r") as f: | |
for line in f: | |
self.presses.append(line[0:-1]) #去掉末尾的 \n | |
# 开始处理 | |
result = [] | |
for press in self.presses: | |
if press == '': | |
continue | |
#thark 版本原因,导出数据格式不同 | |
if ':' in press: | |
Bytes = press.split(":") | |
else: | |
#两两分组 | |
Bytes = [press[i:i+2] for i in range(0, len(press), 2)] | |
print(Bytes) | |
if Bytes[0] == "00": | |
if Bytes[2] != "00" and self.normalKeys.get(Bytes[2]): | |
result.append(self.normalKeys[Bytes[2]]) | |
# print(result) | |
elif int(Bytes[0],16) & 0b10 or int(Bytes[0],16) & 0b100000: # shift key is pressed. | |
if Bytes[2] != "00" and self.normalKeys.get(Bytes[2]): | |
# result.append(self.normalKeys[Bytes[2]]) | |
result.append(self.shiftKeys[Bytes[2]]) | |
else: | |
print("[-] Unknow Key : %s" % (Bytes[0])) | |
print("[+] USB_Found : %s" % (result)) | |
# print(type(result)) | |
flag = 0 | |
for i in range(len(result)): | |
try: | |
a = result.index('<DEL>') | |
del result[a] | |
del result[a - 1] | |
except: | |
pass | |
for i in range(len(result)): | |
try: | |
if result[i] == "<CAP>": | |
flag += 1 | |
result.pop(i) | |
if flag == 2: | |
flag = 0 | |
if flag != 0: | |
result[i] = result[i].upper() | |
except: | |
pass | |
# print ('\n [+] 键盘数据 output :' + "".join (result)) | |
# 删除提取数据文件 | |
rm_stat = eval(input(f"-----是否删除tshark导出的文件 \"{self.datafile}\", 1 or 0-----\n")) | |
if rm_stat == 1: | |
os.remove(self.datafile) | |
if __name__ == "__main__": | |
#我的 vscode 工作区的原因,需要切换到当前目录 | |
pwd = os.path.dirname(__file__) | |
os.chdir(pwd) | |
BANNER = r""" | |
// / / // ) ) // ) ) | |
// / / (( //___/ / ___ __ ___ ___ / ___ | |
// / / \\ / __ ( // ) ) // ) ) // ) ) // ) ) //\ \ | |
// / / ) ) // ) ) // // // / / // // \ \ | |
((___/ / ((___ / / //____/ / ((____ // ((___( ( ((____ // \ \ | |
@MAY1AS | |
""" | |
print(BANNER) | |
argobject = argparse.ArgumentParser(prog="UsbKbCracker", description="""This is a script for decrypt UsbKeyboardData | |
""") | |
argobject.add_argument('-f', "--pcapfile", required=True, help="here is your capturedata file") | |
argobject.add_argument('-e', "--fieldvalue", required=True, help="here is your output_format") | |
argobject.add_argument('-Y', "--filterfield", help="here is your filter") | |
arg = argobject.parse_args() | |
kbparser = kbpaser() | |
# tshark 导出数据,存储在 usbdatafile.txt 内 | |
kbparser.tshark_do(pcapfile=arg.pcapfile, fieldvalue=arg.fieldvalue, filterfield=arg.filterfield) | |
kbparser.formatkbdata() | |
kbparser.jiemi() |
得到键盘输入后解 base85