# authoritative release of tianyan laboratory: dns tunnel coding analysis of xshell backdoor

Xshellghost transmits the data through DNS tunnel, analyzes the coding algorithm and decrypts the data.

Encoding analysis

The coding algorithm of DNS tunnel is first encoded by algorithm 1 as shown in the figure below, as shown in the figure below:

The single byte of the data to be encoded and the 1,2,3,4 bytes of a DWORD constant calculated every 4 times are encoded by single byte operation, as follows:

The data encoded by algorithm 1 is as follows:

Then the conversion method of converting the result to visible character is to add 'J' to the high bit and 'a' to the low bit of each byte, and split one byte into two visible characters, thus wasting one byte:

The decryption algorithm is the inverse operation of the encryption algorithm, and the decryption algorithm flow is as follows:

The hex of the decrypted single data is as follows:

According to some open traffic data on the Internet,

The decryption code is as follows:

```int DecodeSecond(int a1, unsigned char* a2, int a3, int a4, unsigned char* szOut) { char v4; // [email protected] int v5; // [email protected] unsigned char* v6; // [email protected] byte v7= {0}; // [email protected] char v8; // [email protected] int v10; // [sp+4h] [bp-10h]@1 int v11; // [sp+8h] [bp-Ch]@1 int v12; // [sp+Ch] [bp-8h]@1 int v13; // [sp+10h] [bp-4h]@1 v4 = 0; v5 = 0; v10 = a1; v11 = a1; v12 = a1; v13 = a1; int i = 0; if ( a3 > 0 ) { v6 = a2 - a4; do { if ( v5 & 3 ) { switch ( v5 & 3 ) { case 1: v11 = 0xBFD7681A - 0x7DB1F70F * v11; v4 = (*((byte *)&v11  + 2) ^ (*((byte *)&v11 + 1) + (*((byte *)&v11) ^ v4))) - *((byte *)&v11 + 3); v8 = v4 ^ *(byte *)(v6 + v5++ + a4); v7[i] = v8; i++; break; case 2: v12 = 0xE03A30FA - 0x3035D0D6 * v12; v4 = (*((byte *)&v12  + 2) ^ (*((byte *)&v12 + 1) + (*((byte *)&v12) ^ v4))) - *((byte *)&v12 + 3); v8 = v4 ^ *(byte *)(v6 + v5++ + a4); v7[i] = v8; i++; break; case 3: v13 = 0xB1BF5581 - 0x11C208F * v13; v4 = (*((byte *)&v13  + 2) ^ (*((byte *)&v13 + 1) + (*((byte *)&v13) ^ v4))) - *((byte *)&v13 + 3); v8 = v4 ^ *(byte *)(v6 + v5++ + a4); v7[i] = v8; i++; break; } } else {         v10 = 0x9F248E8A - 0x2F8FCE7E * v10; v4 = (*((byte *)&v10 + 2) ^ (*((byte *)&v10 + 1) + (*((byte *)&v10 ) ^ v4))) - *((byte *)&v10 + 3); v8 = v4 ^ *(byte *)(v6 + v5++ + a4); v7[i] = v8; i++; } } while ( v5 < a3 ); memcpy(szOut, v7, a3); } return 0; } void DecodeFirst(unsigned char* szText) { int iLength = strlen((char*)szText); int iSubLength = iLength/2; unsigned char* szXXX = new unsigned char[iSubLength+1]; memset(szXXX, 0, iSubLength+1); for (int i=0; i<iSubLength; i++) { unsigned char One = szText[2*i] - 'a'; unsigned char Two = szText[2*i+1] -'j'; unsigned char Total = One+Two*16; szXXX[i] = Total; } unsigned char* szOutData = new unsigned char[iSubLength+1]; memset(szOutData, 0, iSubLength+1); DecodeSecond(0, szXXX, iSubLength, 0, szOutData); printf(" --------------------Decode Data--------------------------------rn"); hexdump(szOutData, iSubLength);  delete [] szOutData; return; } void hexdump(void *pAddressIn, long  lSize) { char szBuf; long lIndent = 1; long lOutLen, lIndex, lIndex2, lOutLen2; long lRelPos; struct { char *pData; unsigned long lSize; } buf; unsigned char *pTmp,ucTmp; unsigned char *pAddress = (unsigned char *)pAddressIn; buf.pData   = (char *)pAddress; buf.lSize   = lSize; while (buf.lSize > 0) { pTmp     = (unsigned char *)buf.pData; lOutLen  = (int)buf.lSize; if (lOutLen > 16) lOutLen = 16; sprintf(szBuf, " |                            " "                      " "    %08lX", pTmp-pAddress); lOutLen2 = lOutLen; for(lIndex = 1+lIndent, lIndex2 = 53-15+lIndent, lRelPos = 0; lOutLen2; lOutLen2--, lIndex += 2, lIndex2++ ) { ucTmp = *pTmp++; sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp); if(!isprint(ucTmp))  ucTmp = '.'; // nonprintable char szBuf[lIndex2] = ucTmp; if (!(++lRelPos & 3))     // extra blank after 4 bytes {  lIndex++; szBuf[lIndex+2] = ' '; } } if (!(lRelPos & 3)) lIndex--; szBuf[lIndex  ]   = '|'; szBuf[lIndex+1]   = ' '; printf("%sn", szBuf); buf.pData   += lOutLen; buf.lSize   -= lOutLen; } }```

Decryption tool