void HMACSHA256Final(HMACSHA256CTX* context, uint8_t digest[HMACSHA256_DIGEST_LENGTH]) { uint8_t hash[HMACSHA256_DIGEST_LENGTH]; SHA256Final(&context->ictx, hash); SHA256Update(&context->octx, hash, HMACSHA256_DIGEST_LENGTH); SHA256Final(&context->octx, digest); zeroize((void*)hash, sizeof hash); }
void HMAC_SHA256_Init(HMAC_SHA256_CTX *ctx, const u_int8_t *key, u_int key_len) { u_int8_t k_ipad[SHA256_BLOCK_LENGTH]; int i; if (key_len > SHA256_BLOCK_LENGTH) { SHA256Init(&ctx->ctx); SHA256Update(&ctx->ctx, key, key_len); SHA256Final(ctx->key, &ctx->ctx); ctx->key_len = SHA256_DIGEST_LENGTH; } else { bcopy(key, ctx->key, key_len); ctx->key_len = key_len; } bzero(k_ipad, SHA256_BLOCK_LENGTH); bcopy(ctx->key, k_ipad, ctx->key_len); for (i = 0; i < SHA256_BLOCK_LENGTH; i++) k_ipad[i] ^= 0x36; SHA256Init(&ctx->ctx); SHA256Update(&ctx->ctx, k_ipad, SHA256_BLOCK_LENGTH); bzero(k_ipad, sizeof k_ipad); }
void SHA256(const char *src, unsigned char *dest, unsigned int len) { SHA256Context ctx; SHA256Init(&ctx, NULL); SHA256Update(&ctx, (unsigned char *)src, len); SHA256Final(&ctx, dest); }
void HMACSHA256Init(HMACSHA256CTX* context, const uint8_t* key, size_t key_length) { size_t i; uint8_t pad[SHA256_BLOCK_LENGTH]; uint8_t key_hash[SHA256_DIGEST_LENGTH]; if (key_length > SHA256_BLOCK_LENGTH) { SHA256Init(&context->ictx); SHA256Update(&context->ictx, key, key_length); SHA256Final(&context->ictx, key_hash); key = key_hash; key_length = SHA256_DIGEST_LENGTH; } SHA256Init(&context->ictx); memset(pad, 0x36, SHA256_BLOCK_LENGTH); for (i = 0; i < key_length; i++) pad[i] ^= key[i]; SHA256Update(&context->ictx, pad, SHA256_BLOCK_LENGTH); SHA256Init(&context->octx); memset(pad, 0x5c, SHA256_BLOCK_LENGTH); for (i = 0; i < key_length; i++) pad[i] ^= key[i]; SHA256Update(&context->octx, pad, SHA256_BLOCK_LENGTH); zeroize((void*)key_hash, sizeof key_hash); }
hash_digest sha256_hash(data_slice first, data_slice second) { hash_digest hash; SHA256CTX context; SHA256Init(&context); SHA256Update(&context, first.data(), first.size()); SHA256Update(&context, second.data(), second.size()); SHA256Final(&context, hash.data()); return hash; }
void HMAC_SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], HMAC_SHA256_CTX *ctx) { u_int8_t k_opad[SHA256_BLOCK_LENGTH]; int i; SHA256Final(digest, &ctx->ctx); bzero(k_opad, SHA256_BLOCK_LENGTH); bcopy(ctx->key, k_opad, ctx->key_len); for (i = 0; i < SHA256_BLOCK_LENGTH; i++) k_opad[i] ^= 0x5c; SHA256Init(&ctx->ctx); SHA256Update(&ctx->ctx, k_opad, SHA256_BLOCK_LENGTH); SHA256Update(&ctx->ctx, digest, SHA256_DIGEST_LENGTH); SHA256Final(digest, &ctx->ctx); bzero(k_opad, sizeof k_opad); }
hash_digest sha256_hash(const data_chunk& first_chunk, const data_chunk& second_chunk) { hash_digest hash; SHA256CTX context; SHA256Init(&context); SHA256Update(&context, first_chunk.data(), first_chunk.size()); SHA256Update(&context, second_chunk.data(), second_chunk.size()); SHA256Final(&context, hash.data()); return hash; }
void SHA256(const char *src, char *dest, int len, const char* hxc, const unsigned int* ikey = NULL) { // Generate the hash unsigned char bytehash[SHA256_DIGEST_SIZE]; SHA256Context ctx; SHA256Init(&ctx, ikey); SHA256Update(&ctx, (unsigned char *)src, (unsigned int)len); SHA256Final(&ctx, bytehash); // Convert it to hex for (int i = 0, j = 0; i < SHA256_DIGEST_SIZE; i++) { dest[j++] = hxc[bytehash[i] / 16]; dest[j++] = hxc[bytehash[i] % 16]; dest[j] = '\0'; } }
int sha256_file(const char *fname, unsigned char *hash) { int fd; if (fname) fd = open(fname, O_RDONLY); else fd = STDIN_FILENO; if (fd < 0) { fprintf(stderr, "Can't open file: %s\n", strerror(errno)); goto out_error; } ssize_t ret; unsigned char buffer[BLOCKSIZE]; SHA256Context ctx; SHA256Init(&ctx); while (1) { ret = read(fd, buffer, BLOCKSIZE); if (ret < 0) { if (errno == EINTR) continue; fprintf(stderr, "Unable to read file: %s\n", strerror(errno)); goto out_error; } if (ret == 0) break; SHA256Update(&ctx, buffer, ret); } SHA256Final(&ctx, hash); close(fd); return 1; out_error: close(fd); return 0; }
std::string SHA256Hash(const char *src, int len) { // Generate the hash unsigned char bytehash[SHA256_DIGEST_SIZE]; SHA256Context ctx; SHA256Init(&ctx); SHA256Update(&ctx, (unsigned char *)src, (unsigned int)len); SHA256Final(&ctx, bytehash); // Convert it to hex const char* hxc = "0123456789abcdef"; std::string hash = ""; for (int i = 0; i < SHA256_DIGEST_SIZE; i++) { hash += hxc[bytehash[i] / 16]; hash += hxc[bytehash[i] % 16]; } return hash; }
char * SHA256End(SHA2_CTX *ctx, char *buf) { int i; u_int8_t digest[SHA256_DIGEST_LENGTH]; static const char hex[] = "0123456789abcdef"; if (buf == NULL && (buf = malloc(SHA256_DIGEST_STRING_LENGTH)) == NULL) return (NULL); SHA256Final(digest, ctx); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { buf[i + i] = hex[digest[i] >> 4]; buf[i + i + 1] = hex[digest[i] & 0x0f]; } buf[i + i] = '\0'; explicit_bzero(digest, sizeof(digest)); return (buf); }
//http://articles.sysprogs.org/kdvmware/kdcom.shtml //http://j00ru.vexillium.org/?p=405 //http://visi.kenshoto.com/static/apidocs/vstruct.defs.kdcom-module.html //https://code.google.com/p/reactos-mirror/source/browse/trunk/reactos/include/reactos/windbgkd.h int main(int argc, char* argv[]){ //printKD_PACKET((KD_PACKET_HEADER*)(unciphered_go+8)); //exit(0); //TODO: move this ! initCallBack(); int i; #if DEBUG printf("controlKey :\n"); for(i=0; i<32; i++){ printf("%02x ", controlKey[i]); } printf("\n"); #endif //Expand controlKey aes_key_setup(controlKey, controlW, 256); #if DEBUG printf("hmacKey :\n"); for(i=0; i<32; i++){ printf("%02x ", hmacKey[i]); } printf("\n"); #endif //Generate hmacKey from controlKey for(i=0; i<32; i++){ hmacKey[i] = controlKey[i]^0xFF; } if(argc == 2){ kd_server(); } // // //All my tests ! //--------------------- printf("\nPoke :\n"); //KDNET_PACKET_HEADER* poke_pkt = (KDNET_PACKET_HEADER*)poke; //printKDNET_PACKET(poke_pkt); BYTE* tmp = cbc_decrypt(poke+6, 0x160, controlW, poke+sizeof(poke)-16); uint8_t arf[2096]; memset(arf, 0, 2096); for(i=0; i<6; i++){ arf[i] = poke[i]; }; for(i=0; i<0x160-16; i++){ arf[i+6] = tmp[i]; } printf("\n\n"); for(i=0; i<0x166; i++){ printf("%02x ", arf[i]); if(i%16 == 15){ printf("\n"); } } printf("\n"); BYTE tmpSHA[32]; hmacSHA256Context myHmacSHA256Context; hmacSHA256Init(&myHmacSHA256Context, hmacKey, 32); hmacSHA256Update(&myHmacSHA256Context, arf, 0x166); hmacSHA256Final(&myHmacSHA256Context, tmpSHA); printf("\nChecksum:\n"); for(i=0; i<16; i++){ printf("%02x ", tmpSHA[i]); } printf("\n\n"); printf("\nPoke response :\n"); BYTE* unciphered_poke_resp = cbc_decrypt(poke_resp+6, sizeof(poke_resp)-6-16, controlW, poke_resp+sizeof(poke_resp)-16); BYTE dataKey[32]; SHA256Context mySHA256Context; SHA256Init(&mySHA256Context); SHA256Update(&mySHA256Context, controlKey, 32); SHA256Update(&mySHA256Context, unciphered_poke_resp+8, 322); SHA256Final(&mySHA256Context, dataKey); aes_key_setup(dataKey, dataW, 256); printf("\ndataKey :\n"); for(i=0; i<32; i++){ printf("%02x ", dataKey[i]); } printf("\n"); pcap_t *handle; char errbuf[PCAP_ERRBUF_SIZE]; //not sure what to do with this, oh well handle = pcap_open_offline("/home/arfarf/git/samples/debug_trace.pcap", errbuf); //call pcap library function const u_char *packet; // The actual packet struct pcap_pkthdr header; // The header that pcap gives us int pkt_num = 1; while ((packet = pcap_next(handle,&header))) { u_char *debug_pkt = (u_char *)packet+42; //cast a pointer to the packet data int debug_pkt_len = header.caplen-42; if(debug_pkt[5] == 0){//Only Data Packet BYTE *unciphered_debug_pkt = cbc_decrypt(debug_pkt+6, debug_pkt_len-6-16, dataW, debug_pkt+debug_pkt_len-16); KD_PACKET_HEADER* tmp = (KD_PACKET_HEADER*)(unciphered_debug_pkt+8); //if(tmp->ApiNumber == DbgKdContinueApi2){ if(pkt_num == 680 || pkt_num == 681){ printf("%d.\n", pkt_num); printHexData(unciphered_debug_pkt, debug_pkt_len-6-16); printKD_PACKET(tmp); printf("\n"); } } pkt_num++; } exit(0); printf("\nConnection Check :\n"); cbc_decrypt(conncheck+6, sizeof(conncheck)-6-16, dataW, conncheck+sizeof(conncheck)-16); printf("\nConnection Check response:\n"); cbc_decrypt(conncheck_resp+6, sizeof(conncheck_resp)-6-16, dataW, conncheck_resp+sizeof(conncheck_resp)-16); //... printf("\nPOKE (repeat):\n"); cbc_decrypt(poke_repeat+6, 0x160, controlW, poke_repeat+sizeof(poke_repeat)-16); //... printf("\n[!] Break :\n"); BYTE *unciphered_break = cbc_decrypt(break_data+6, sizeof(break_data)-6-16, dataW, break_data+sizeof(break_data)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_break+8)); printf("\n[!] Wait State :\n"); BYTE *unciphered_wait_state = cbc_decrypt(wait_state+6, sizeof(wait_state)-6-16, dataW, wait_state+sizeof(wait_state)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_wait_state+8)); printf("\n[!] Reset:\n"); BYTE *unciphered_reset = cbc_decrypt(reset+6, sizeof(reset)-6-16, dataW, reset+sizeof(reset)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_reset+8)); printf("\n[!] Reset ACK:\n"); BYTE *unciphered_reset_ack = cbc_decrypt(reset_ack+6, sizeof(reset_ack)-6-16, dataW, reset_ack+sizeof(reset_ack)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_reset_ack+8)); printf("\n[!] Wait State 2:\n"); BYTE *unciphered_wait_state2 = cbc_decrypt(wait_state2+6, sizeof(wait_state2)-6-16, dataW, wait_state2+sizeof(wait_state2)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_wait_state2+8)); printf("\n[!] Get Version API REQ :\n"); BYTE *unciphered_get_version_api_req = cbc_decrypt(get_version_api_req+6, sizeof(get_version_api_req)-6-16, dataW, get_version_api_req+sizeof(get_version_api_req)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_get_version_api_req+8)); printf("\n[!] Get Version API RESP :\n"); BYTE *unciphered_get_version_api_resp = cbc_decrypt(get_version_api_resp+6, sizeof(get_version_api_resp)-6-16, dataW, get_version_api_resp+sizeof(get_version_api_resp)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_get_version_api_resp+8)); exit(0); printf("\n[!] Read Virtual Memory API REQ\n"); BYTE *unciphered_read_virtual_memory_api_req = cbc_decrypt(read_virtual_memory_api_req+6, sizeof(read_virtual_memory_api_req)-6-16, dataW, read_virtual_memory_api_req+sizeof(read_virtual_memory_api_req)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_read_virtual_memory_api_req+8)); printf("\n[!] Read Virtual Memory API REQ ACK\n"); BYTE *unciphered_read_virtual_memory_api_req_ack = cbc_decrypt(read_virtual_memory_api_req_ack+6, sizeof(read_virtual_memory_api_req_ack)-6-16, dataW, read_virtual_memory_api_req_ack+sizeof(read_virtual_memory_api_req_ack)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_read_virtual_memory_api_req_ack+8)); printf("\n[!] Read Virtual Memory API RESP\n"); BYTE *unciphered_read_virtual_memory_api_resp = cbc_decrypt(read_virtual_memory_api_resp+6, sizeof(read_virtual_memory_api_resp)-6-16, dataW, read_virtual_memory_api_resp+sizeof(read_virtual_memory_api_resp)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_read_virtual_memory_api_resp+8)); uint32_t tmp_checksum = checksumKD_PACKET((KD_PACKET_HEADER*)(unciphered_read_virtual_memory_api_resp+8), sizeof(read_virtual_memory_api_resp)-6-16); printf("Checksum test : 00001ce3 %08x\n", tmp_checksum); printf("\n[!] Read Virtual Memory API RESP ACK\n"); BYTE *unciphered_read_virtual_memory_api_resp_ack = cbc_decrypt(read_virtual_memory_api_resp_ack+6, sizeof(read_virtual_memory_api_resp_ack)-6-16, dataW, read_virtual_memory_api_resp_ack+sizeof(read_virtual_memory_api_resp_ack)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_read_virtual_memory_api_resp_ack+8)); printf("\n[!] Next\n"); BYTE *unciphered_next = cbc_decrypt(next+6, sizeof(next)-6-16, dataW, next+sizeof(next)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_next+8)); exit(0); printf("Get Register RESP\n"); BYTE* unciphered_get_register_resp = cbc_decrypt(get_register_resp+6, sizeof(get_register_resp)-6-16, dataW, get_register_resp+sizeof(get_register_resp)-16); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_get_register_resp+8)); //unciphered_break_ack = cbc_decrypt(cmd_data+6, sizeof(cmd_data)-6-16, dataW, cmd_data+sizeof(cmd_data)-16); //printKD_PACKET((KD_PACKET_HEADER*)(unciphered_break_ack+8)); return 0; }
/** * * Main KDNET server main * */ void kd_server(){ //struct sockaddr_in Debuggee_sa; socket_fd = socket(PF_INET, SOCK_DGRAM, 0); if(socket_fd < 0){ printf("socket call failed"); exit(0); } memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr("192.168.0.11"); sa.sin_port = htons(50000); //TODO: create poke from scratch ! //Send POKE pkt_number++; sendto(socket_fd, poke, sizeof(poke), 0, (struct sockaddr *)&sa,sizeof(sa)); //Receive POKE_RESP uint8_t buffer[2048]; int n=recvfrom(socket_fd, buffer, sizeof(buffer), 0, NULL, NULL); BYTE *unciphered_poke_resp = cbc_decrypt(buffer+6, n-6-16, controlW, buffer+n-16); //Compute the data canal key with POKE_RESP BYTE dataKey[32]; SHA256Context mySHA256Context; SHA256Init(&mySHA256Context); SHA256Update(&mySHA256Context, controlKey, 32); SHA256Update(&mySHA256Context, unciphered_poke_resp+8, 322); SHA256Final(&mySHA256Context, dataKey); aes_key_setup(dataKey, dataW, 256); //TODO: create conn_check from scratch ! uint8_t connection_check[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xa8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; sendDataPkt(connection_check, sizeof(connection_check)); //Get CONN_RESP_PACKET ! n=recvfrom(socket_fd, buffer, sizeof(buffer), 0, NULL, NULL); printf("Packet received : %d bytes \n", n); //Here the connection is established ! //Get next_packet ! while(1){ n=recvfrom(socket_fd, buffer, sizeof(buffer), 0, NULL, NULL); printf("\n\n[!] Packet received : %d bytes >>>>>>\n", n); BYTE *unciphered_pkt = cbc_decrypt(buffer+6, n-6-16, dataW, buffer+n-16); printHexData(unciphered_pkt, n-6-16); printf("<<<<\n"); printKD_PACKET((KD_PACKET_HEADER*)(unciphered_pkt+8)); handleKD_PACKET((KD_PACKET_HEADER*)(unciphered_pkt+8)); } exit(0); }
static int __archive_libc3_sha256final(archive_sha256_ctx *ctx, void *md) { SHA256Final(md, ctx); return (ARCHIVE_OK); }