ip-guard网络通信加解密

ip-guard官网:https://www.e-dlp.com/tuzhijiamixitong/index.html?msclkid=e207d5eb8fe21d7b6d80bfe10f1c416d&utm_source=bing&utm_medium=cpc&utm_campaign=%E7%AB%9E%E5%93%81001&utm_term=IP-guard&utm_content=%E5%93%81%E7%89%8C%E8%AF%8D%E8%AE%A1%E5%88%92

主要基于des和aes-cbc-128算法。主要的坑:

  1. aes解密后头部16字节完全无用被丢弃。
  2. deflate解压。从头部2字节0x7801看出,压缩时的参数为速度最快算法。
  3. des密钥"ocularv3"
  4. aes密钥为: des解密后的包头第8字节开始的16字节,iv为16字节的0串。cbc算法会根据aes解密结果更新iv,所以iv会发生变化、但是无需干涉。

废话不说,上干货。

代码使用openssl库中的evp接口解密。

cpp 复制代码
int __stdcall TcpClient(string ip,int port) {

	int ret = 0;

	SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (s == INVALID_SOCKET) {
		perror("socket\r\n");
		return -1;
	}

	sockaddr_in sa = { 0 };
	sa.sin_family = AF_INET;
	sa.sin_addr.S_un.S_addr = inet_addr(ip.c_str());
	sa.sin_port = ntohs(port);

	ret = connect(s, (sockaddr*)&sa, sizeof(sockaddr_in));
	if (ret < 0) {
		perror("connect\r\n");
		return -1;
	}
	int bufsize = 0x1000000;
	char* sendbuf = new char[bufsize];

	char* recvbuf= new char[bufsize];

	DES_key_schedule key_schedule;
	DES_cblock deskey;

	memcpy((char*)deskey, "ocularv3", 8);
	DES_set_key_unchecked(&deskey, &key_schedule);

	unsigned char decryptbuf[0x1000] = { 0 };

	unsigned char encryptbuf[0x1000] = { 0 };

	int recvLen = 0;

	char packetbuf[0x1000];
	int packlen = makeFakePacket(packetbuf);

	DWORD zipsize = packlen * 16;
	unsigned char* zipbuf = new unsigned char[packlen + 1024];
	ret=zcompress((Bytef*)packetbuf, packlen, zipbuf, (uLong*)&zipsize);

	memcpy((Bytef*)sendbuf + 16 + sizeof(OCP_HEADER), zipbuf, zipsize);

	int sendsize = zipsize+16;
	
	OCP_HEADER* hdr = (OCP_HEADER*)sendbuf;

	memset(hdr, 0, sizeof(OCP_HEADER));
	for (int i = 0; i < 16; i++) {
		sendbuf[8 + i] = 'A';
	}
	for (int i = 0; i < 16; i++) {
		sendbuf[32 + i] = 'B';
	}
	hdr->tag = 0x4d4f;
	hdr->payloadLen = sendsize;
	hdr->flag = 0x4000|0x8000;
	hdr->cmd = 0xc600;
	
	const char* key = "ocularv3";
	
	unsigned char iv[16] = { 0 };
	char* indata = 0; 
	char* outdata = 0;

	AESCBC128Encryptor aes_enc((unsigned char*)&hdr->field8, iv);
	unsigned char aes_enc_buf[0x1000];
	int aes_enc_len = aes_enc.update((unsigned char*)sendbuf + sizeof(OCP_HEADER), hdr->payloadLen, aes_enc_buf);
	int aes_enc_last_len = aes_enc.final((unsigned char*)aes_enc_buf + aes_enc_len);
	memcpy(sendbuf + sizeof(OCP_HEADER), aes_enc_buf, aes_enc_last_len + aes_enc_len);

	sendsize = aes_enc_last_len + aes_enc_len;
	hdr->payloadLen = aes_enc_last_len + aes_enc_len;

	indata = (char*)&hdr->field8;
	outdata = (char*)encryptbuf;
	for (int i = 0; i < 3; i++) {
		DES_ecb_encrypt((const_DES_cblock*)indata,
			(DES_cblock*)outdata,
			&key_schedule,
			DES_ENCRYPT);
		indata += 8;
		outdata += 8;
	}

	memcpy((char*) & hdr->field8, encryptbuf, 24);

	indata = (char*)encryptbuf;
	outdata = (char*)decryptbuf;
	for (int i = 0; i < 4; i++) {
		DES_ecb_encrypt((const_DES_cblock*)indata,
			(DES_cblock*)outdata,
			&key_schedule,
			DES_DECRYPT);
		indata += 8;
		outdata += 8;
	}
	AESCBC128Decryptor aes_dec((unsigned char*)decryptbuf, iv);
	unsigned char aes_dec_buf[0x1000];
	int aes_dec_len = aes_dec.update((unsigned char*)sendbuf + sizeof(OCP_HEADER), sendsize, aes_dec_buf);
	int aes_dec_last_len = aes_dec.final((unsigned char*)aes_dec_buf + aes_dec_len);

	ret = send(s, (char*)sendbuf, sendsize+sizeof(OCP_HEADER), 0);
	
	recvLen = recv(s, recvbuf, bufsize-1, 0);
	if (recvLen > 0 && recvLen < bufsize) {
		recvbuf[recvLen] = 0;

		int procLen = 0;
		char* procBuf = recvbuf;
		unsigned char* dstbuf = decryptbuf;
		while(procLen < recvLen){
			OCP_HEADER* hdr = (OCP_HEADER*)(procBuf);
			if (hdr->flag & 0x4100) {
				char* indata = (char*)&hdr->field8;
				char* outdata = (char*)dstbuf + 8;
				memcpy(dstbuf, procBuf, 8);
				for (int i = 0; i < 3; i++) {
					DES_ecb_encrypt((const_DES_cblock*)indata,
						(DES_cblock*)outdata,
						&key_schedule,
						DES_DECRYPT);
					indata += 8;
					outdata += 8;
				}

				hdr = (OCP_HEADER*)dstbuf;
				if (hdr->payloadLen) {
					AESCBC128Decryptor aes_dec((unsigned char*)dstbuf + 8, iv);
					unsigned char aes_dec_buf[0x1000];
					int aes_dec_len = aes_dec.update((unsigned char*)procBuf + sizeof(OCP_HEADER), hdr->payloadLen, aes_dec_buf);
					int aes_last_dec_len = aes_dec.final((unsigned char*)aes_dec_buf + aes_dec_len);

					procLen += hdr->payloadLen;
				}
				procLen += sizeof(OCP_HEADER);
				procBuf += procLen;
				dstbuf += procLen;
			}
		}
	}
	
	closesocket(s);

	delete [] sendbuf;

	delete[] recvbuf;
	
	return 0;
}
相关推荐
Bobolink_1 分钟前
面向欧美用户实时直播场景的网络时延优化实践
网络·网络优化·跨境网络·跨境直播·直播网络
拾贰_C12 分钟前
【python | installation 】python 安装 | Windows | 命令使用
linux·数据库·ubuntu
IpdataCloud13 分钟前
遭遇DDoS攻击后如何快速分析攻击源?用IP离线库+威胁情报定位异常IP
网络·tcp/ip·游戏·智能路由器·ddos
机汇五金_14 分钟前
影响交换机箱体使用寿命的几个关键因素
运维·服务器·网络·python
zhangjw3416 分钟前
第18篇:Java网络编程零基础详解,IP、端口、TCP、UDP、Socket通信、实战文件传输
java·网络·tcp/ip
无限进步_20 分钟前
Linux进程终止——退出码、exit与_exit
linux·运维·服务器
编程大师哥21 分钟前
最高效的 IO 并发方案
linux·网络·python
酣大智23 分钟前
BGP选路原则--下一跳IGP Metric小的(8)
网络·华为·路由·bgp
炘爚36 分钟前
phase1:基础框架——编译 + MySQL + 登录/注册
linux·c++
齐鲁大虾1 小时前
如何彻底解决从公网HTTP页面请求私有HTTP资源跨域问题
网络·网络协议·http