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;
}
相关推荐
予昊5 小时前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
一池秋_5 小时前
arm低配linux设备,桌面应用冷启动提速方法
linux·运维·arm开发
惜离殇5 小时前
从零开始的敲代码生活--Linux应用软件(文件操作基础1)
linux·c语言·文件操作·标准io
上海云盾-小余7 小时前
流量攻击复盘:为什么 WAF 完好,业务依旧瘫痪
运维·服务器·网络
戴西软件7 小时前
戴西iDWS.3DViz Suite数据轻量化可视化软件,从传统桌面软件向云端协同的重大突破
大数据·运维·网络·人工智能·机器学习·3d
芯盾时代7 小时前
《金融业网络安全管理办法(征求意见稿)》全条款深度拆解(三)
网络·安全·网络安全
米饭不加菜7 小时前
ESP-01S通过TCP直接与手机建立通信
网络·tcp/ip·智能手机
Huathy-雨落江南,浮生若梦8 小时前
Caddy 学习笔记 - 反向代理与 IP 封禁
笔记·学习·tcp/ip
闲云野鹤在人间8 小时前
OpenStack架构介绍和安装流程
linux·网络·架构·openstack
我命由我123458 小时前
Linux - Linux/POSIX 路径斜杠折叠规则
linux·运维·服务器·android studio·android jetpack·android-studio·android runtime