struct obj_str *aes_decrypt(UCHAR * cipher, int cipherlen, UCHAR * iv, char *key, int keylen) { UCHAR plaintext[AES_MSG_SIZE]; UCHAR digest[AES_KEY_SIZE]; aes_context aes_ctx; struct obj_str *plain = NULL; if (cipherlen % AES_BLOCK_SIZE != 0) { return NULL; } /* Setup AES context with the key and the IV */ aes_key_setup(digest, iv, key, keylen); if (aes_setkey_dec(&aes_ctx, digest, 256) != 0) { return NULL; } /* Decrypt message */ memset(plaintext, '\0', AES_MSG_SIZE); if (aes_crypt_cbc (&aes_ctx, AES_DECRYPT, cipherlen, iv, cipher, plaintext) != 0) { return NULL; } plain = str_init(plaintext, cipherlen); /* The decrypted message may be bigger than the original message, but * the bencode parser can handle that. */ return plain; }
QAesWrap::QAesWrap(const QByteArray & passwprd,const QByteArray & salt,AesBit bit):mbit(bit) { QByteArray data = QCryptographicHash::hash(passwprd,QCryptographicHash::Sha3_256); aes_key_setup((unsigned char *)data.data(),mpass,mbit); data = QCryptographicHash::hash(salt,QCryptographicHash::Sha3_256); memcpy(msalt,data.data(),AES_BLOCK_SIZE); }
static void pdf_init(pdf_ctx *pc, aes_int_key prf_key) { UINT8 buf[UMAC_KEY_LEN]; kdf(buf, prf_key, 0, UMAC_KEY_LEN); aes_key_setup(buf, pc->prf_key); /* Initialize pdf and cache */ memset(pc->nonce, 0, sizeof(pc->nonce)); aes_encryption(pc->nonce, pc->cache, pc->prf_key); }
struct obj_str *aes_encrypt(UCHAR * plain, int plainlen, UCHAR * iv, char *key, int keylen) { UCHAR ciphertext[AES_MSG_SIZE]; UCHAR digest[AES_KEY_SIZE]; UCHAR plain_padded[AES_MSG_SIZE]; UCHAR iv_local[AES_IV_SIZE]; aes_context aes_ctx; int plainlen_padded = 0; int i = 0; struct obj_str *cipher = NULL; /* Plaintext out of boundary */ if (plainlen <= 0 || plainlen > AES_MSG_SIZE) { return NULL; } /* Compute padded plaintext length */ i = plainlen % AES_BLOCK_SIZE; plainlen_padded = (i == 0) ? plainlen : plainlen - i + AES_BLOCK_SIZE; /* Plaintext out of boundary */ if (plainlen_padded <= 0 || plainlen_padded > AES_MSG_SIZE) { return NULL; } /* Store padded message */ memset(plain_padded, '\0', AES_MSG_SIZE); memcpy(plain_padded, plain, plainlen); /* Store iv locally because it gets modified by aes_crypt_cbc() later */ memcpy(iv_local, iv, AES_IV_SIZE); /* Setup AES context with the key and the IV */ aes_key_setup(digest, iv_local, key, keylen); if (aes_setkey_enc(&aes_ctx, digest, 256) != 0) { return NULL; } /* Encrypt message */ if (aes_crypt_cbc (&aes_ctx, AES_ENCRYPT, plainlen_padded, iv_local, plain_padded, ciphertext) != 0) { return NULL; } cipher = str_init(ciphertext, plainlen_padded); return cipher; }
//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); }
/* * Class: tv_fun_common_crypt_Funcrypt * Method: sha1 * Signature: (Ljava/lang/String;JI)[Ljava/lang/Object; */ JNIEXPORT jbyteArray JNICALL android_native_aes(JNIEnv *env, jclass clazz, jbyteArray jarray, jlong jtimestamp, jint jmode) { //check input data unsigned int len = (unsigned int) ((*env)->GetArrayLength(env, jarray)); if (len <= 0 || len >= MAX_LEN) { return NULL; } unsigned char *data = (unsigned char*) (*env)->GetByteArrayElements(env, jarray, NULL); if (!data) { return NULL; } //计算填充长度,当为加密方式且长度不为16的整数倍时,则填充,与3DES填充类似(DESede/CBC/PKCS5Padding) unsigned int mode = (unsigned int) jmode; unsigned int rest_len = len % AES_BLOCK_SIZE; unsigned int padding_len = ( (ENCRYPT == mode) ? (AES_BLOCK_SIZE - rest_len) : 0); unsigned int src_len = len + padding_len; //设置输入 unsigned char *input = (unsigned char *) malloc(src_len); memset(input, 0, src_len); memcpy(input, data, len); if (padding_len > 0) { memset(input + len, (unsigned char) padding_len, padding_len); } //data不再使用 (*env)->ReleaseByteArrayElements(env, jarray, data, 0); //设置输出Buffer unsigned char * buff = (unsigned char*) malloc(src_len); if (!buff) { free(input); return NULL; } memset(buff, src_len, 0); //set key & iv unsigned int key_schedule[AES_BLOCK_SIZE * 4] = { 0 }; //>=53(这里取64) aes_key_setup(AES_KEY, key_schedule, AES_KEY_SIZE); //执行加解密计算(CBC mode) if (mode == ENCRYPT) { aes_encrypt_cbc(input, src_len, buff, key_schedule, AES_KEY_SIZE, AES_IV); } else { aes_decrypt_cbc(input, src_len, buff, key_schedule, AES_KEY_SIZE, AES_IV); } //解密时计算填充长度 if (ENCRYPT != mode) { unsigned char * ptr = buff; ptr += (src_len - 1); padding_len = (unsigned int) *ptr; if (padding_len > 0 && padding_len <= AES_BLOCK_SIZE) { src_len -= padding_len; } ptr = NULL; } //设置返回变量 jbyteArray bytes = (*env)->NewByteArray(env, src_len); (*env)->SetByteArrayRegion(env, bytes, 0, src_len, (jbyte*) buff); //内存释放 free(input); free(buff); return bytes; }
int encrypt_memory(const unsigned char* buffer, size_t buffer_len, const unsigned char* key, unsigned char** encrypted_buffer, size_t* encrypted_buffer_len) { int was_successful = 0; unsigned int key_schedule[60] = {0}; do{ if(!buffer || !key || 0 >= buffer_len) break; *encrypted_buffer_len = buffer_len % 16; *encrypted_buffer_len = 16 - *encrypted_buffer_len; *encrypted_buffer_len += buffer_len; *encrypted_buffer = (unsigned char*) malloc(sizeof(unsigned char) * (*encrypted_buffer_len)); if(!(*encrypted_buffer)) break; memset(*encrypted_buffer, 0, *encrypted_buffer_len); const unsigned char* ptr_buffer = buffer; unsigned char* ptr_encrypted_buffer = *encrypted_buffer; aes_key_setup((unsigned char*)key, key_schedule, 256); int index = 0; int can_break = 0; do { unsigned char input[16]; unsigned char cipher[16]; memset(input, 0, 16); memset(cipher, 0, 16); if(buffer_len <= 0) break; if(buffer_len < 16) { memcpy(input, ptr_buffer + index, buffer_len); can_break = 1; } else { memcpy(input, ptr_buffer + index, 16); buffer_len -= 16; index += 16; } aes_encrypt(input, cipher, key_schedule, 256); memcpy(ptr_encrypted_buffer, cipher, 16); ptr_encrypted_buffer += 16; }while(!can_break); was_successful = 1; }while(0); if(!was_successful) { } return was_successful; }