[原]VC++信息安全编程(19)PnP溢出代码漏洞扫描检测
具体漏洞检测代码#include "winsock2.h"
#include "windows.h"
#include <winnetwk.h>
#include <Rpc.h>
#include "stdio.h"
#include "string.h"
#pragma comment(lib, "ws2_32")
#pragma comment(lib, "mpr")
#pragma comment(lib, "Rpcrt4")
//72字节netbios会话请求,若445端口连接不成功,访问139 的时候就先发送这个
unsigned char reqNBSS[] =
"\x81\x00\x00\x44\x20\x43\x4B\x46\x44\x45\x4E\x45\x43\x46\x44\x45"
"\x46\x46\x43\x46\x47\x45\x46\x46\x43\x43\x41\x43\x41\x43\x41\x43"
"\x41\x43\x41\x43\x41\x00\x20\x46\x44\x45\x44\x46\x46\x43\x4E\x45"
"\x46\x44\x47\x44\x48\x44\x44\x46\x49\x45\x44\x46\x47\x46\x43\x45"
"\x4C\x45\x49\x44\x44\x41\x41\x00";
//Negotiate 协议
unsigned char SMB_Negotiate[] =
"\x00\x00\x00\x2f\xFF\x53\x4D\x42\x72\x00\x00\x00\x00\x18\x01\xC5"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFE"
"\x00\x00\x00\x00\x00\x0C\x00\x02\x4E\x54\x20\x4C\x4D\x20\x30\x2E"
"\x31\x32\x00";
//建立会话
unsigned char SMB_SessionSetupAndX[] =
"\x00\x00\x00\xa6\xFF\x53\x4D\x42\x73\x00\x00\x00\x00\x18\x01\xC5"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFE"
"\x00\x00\x01\x00\x0D\xFF\x00\x00\x00\x00\x20\x32\x00\x00\x00\x00"
"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xD4\x00\x00\x00\x69"
"\x00\x00\x00\x00\x00\x00\x57\x00\x69\x00\x6E\x00\x64\x00\x6F\x00"
"\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00"
"\x53\x00\x65\x00\x72\x00\x57\x00\x69\x00\x6E\x00\x64\x00\x6F\x00"
"\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00"
"\x53\x00\x65\x00\x72\x00\x00\x00\x41\x00\x41\x00\x41\x00\x41\x00"
"\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00"
"\x41\x00\x41\x00\x41\x00\x41\x00\x00\x00";
//列出要访问的共享资源---命名管道
unsigned char SMB_TreeConnectAndX[] =
"\x00\x00\x00\x3a\xFF\x53\x4D\x42\x75\x00\x00\x00\x00\x18\x01\xC5"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFE"
"\x00\x08\x03\x00\x04\xFF\x00\x00\x00\x08\x00\x01\x00\x0E\x00\x00"
"\x49\x00\x50\x00\x43\x00\x24\x00\x00\x00\x49\x50\x43\x00";
//扫描数据
char szScan[] =
"\x05\x00\x00\x03\x10\x00\x00\x00\xF8\x00\x00\x00\x01\x00\x00\x00"
"\x00\xE0\x00\x00\x00\x00\x36\x00\x3D\x00\x00\x00\x00\x00\x00\x00"
"\x3D\x00\x00\x00\x50\x00\x43\x00\x49\x00\x5C\x00\x56\x00\x45\x00"
"\x4E\x00\x5F\x00\x31\x00\x30\x00\x31\x00\x31\x00\x26\x00\x44\x00"
"\x45\x00\x56\x00\x5F\x00\x30\x00\x30\x00\x30\x00\x39\x00\x26\x00"
"\x53\x00\x55\x00\x42\x00\x53\x00\x59\x00\x53\x00\x5F\x00\x32\x00"
"\x31\x00\x31\x00\x34\x00\x30\x00\x41\x00\x30\x00\x30\x00\x26\x00"
"\x52\x00\x45\x00\x56\x00\x5F\x00\x32\x00\x30\x00\x5C\x00\x33\x00"
"\x26\x00\x32\x00\x36\x00\x37\x00\x41\x00\x36\x00\x31\x00\x36\x00"
"\x41\x00\x26\x00\x30\x00\x26\x00\x35\x00\x30\x00\x00\x00\xAF\x72"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xEC\x00\x00\x00\x00\x00\x00"
"\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00";
BYTE PRPC =
{
0x05,0x00,0x0B,0x03,0x10,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
0xB8,0x10,0xB8,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
0x6A,0x28,0x19,0x39,0x0C,0xB1,0xD0,0x11,0x9B,0xA8,0x00,0xC0,0x4F,0xD9,0x2E,0xF5,
0x00,0x00,0x00,0x00,0x04,0x5D,0x88,0x8A,0xEB,0x1C,0xC9,0x11,0x9F,0xE8,0x08,0x00,
0x2B,0x10,0x48,0x60,0x02,0x00,0x00,0x00
};
//RPC接口属性
struct RPCBIND
{
BYTE VerMaj;
BYTE VerMin;
BYTE PacketType;
BYTE PacketFlags;
DWORD DataRep;
WORD FragLength;
WORD AuthLength;
DWORD CallID;
WORD MaxXmitFrag;
WORD MaxRecvFrag;
DWORD AssocGroup;
BYTE NumCtxItems;
WORD ContextID;
WORD NumTransItems;
GUID InterfaceUUID; //16字节的GUID对象
WORD InterfaceVerMaj;
WORD InterfaceVerMin;
GUID TransferSyntax;
DWORD SyntaxVer;
};
//转换为UNICODE
void convert_name(char *out, char *name)
{
unsigned long len;
len = strlen(name);
out += len * 2 - 1;
while (len--)
{
*out-- = '\x00';
*out-- = name;
}
}
//设置RPC接口属性,并通过管道browser进行访问
BOOL BindRpcInterface(HANDLE PH, char *Interface, char *InterfaceVer)
{
BYTE rbuf;
DWORD dw;
struct RPCBIND RPCBind;
BOOL bRet;
memcpy(&RPCBind, &PRPC, sizeof(RPCBind));
UuidFromString((unsigned char *)Interface, &RPCBind.InterfaceUUID);
UuidToString(&RPCBind.InterfaceUUID, (unsigned char **)&Interface);
RPCBind.InterfaceVerMaj = atoi(&InterfaceVer);
RPCBind.InterfaceVerMin = atoi(&InterfaceVer);
bRet = TransactNamedPipe(PH, &RPCBind, sizeof(RPCBind), rbuf, sizeof(rbuf), &dw, NULL);
//printf("%d\n", WSAGetLastError());
return bRet;
}
//扫描函数
BOOL ScanPNP(HANDLE PipeHandle)
{
BYTE rbuf = {0};
DWORD dw;
if(!TransactNamedPipe(PipeHandle, szScan, sizeof(szScan), rbuf, sizeof(rbuf), &dw, NULL))
{
printf("Cann't get scan data!\n");
return FALSE;
}
if(dw != 0x48)
{
return FALSE;
}
if(rbuf != 0x0b)
{
return FALSE;
}
return TRUE;
}
//主函数
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("Usage: %s <host>\n", argv);
return 1;
}
WSADATA wsa;
if(WSAStartup(MAKEWORD(1, 0), &wsa) != 0)
{
printf("1\n");
return -1;
}
//创建套接字
SOCKET ClientSock;
sockaddr_in ClientAddr;
int len;
unsigned char szRecv = {0};
ClientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ClientAddr.sin_family= AF_INET;
ClientAddr.sin_port = htons(445);
ClientAddr.sin_addr.S_un.S_addr = inet_addr(argv);
printf("[*] Connecting to 445 ... ");
//先连接445端口,如果不成功,则连接139
if(connect(ClientSock, (const sockaddr *)&ClientAddr, sizeof(ClientAddr)) < 0)
{
printf("Cann't connecting to 445 ... ");
printf("[*] Connecting to 445 ... ");
ClientAddr.sin_port = htons(139);
if(connect(ClientSock, (const sockaddr *)&ClientAddr, sizeof(ClientAddr)) < 0)
{
printf("Cann't create NULL session!\n");
return -1;
}
//发送72字节的reqNBSS
if(send(ClientSock, (const char *)reqNBSS, sizeof(reqNBSS) - 1, 0) < 0)
{
printf("[-] Send reqNBSS failed\n");
closesocket(ClientSock);
return -1;
}
len = recv(ClientSock, (char *)szRecv, sizeof(szRecv) - 1, 0);
if(len < 0)
{
printf("2\n");
closesocket(ClientSock);
return -1;
}
}
printf("ok!\n");
//发送SMB_Negotiate
if (send(ClientSock, (const char *)SMB_Negotiate, sizeof(SMB_Negotiate) - 1, 0) < 0)
{
printf("\n[-] send SMB_Negotiate failed\n");
return -1;
}
len = recv(ClientSock, (char *)szRecv, sizeof(szRecv) - 1, 0);
if ((len <= 10) || (szRecv != 0))
{
printf("3\n");
return -1;
}
//发送SMB_SessionSetupAndX
if (send(ClientSock, (const char *)SMB_SessionSetupAndX, sizeof(SMB_SessionSetupAndX)-1, 0) < 0)
{
printf("\n[-] send SMB_SessionSetupAndX failed\n");
return -1;
}
len = recv(ClientSock, (char *)szRecv, 4096, 0);
if (len <= 10 || (szRecv != 0))
{
printf("4\n");
exit(0);
}
//发送SMB_TreeConnectAndX
if (send(ClientSock, (const char *)SMB_TreeConnectAndX, sizeof(SMB_TreeConnectAndX), 0) < 0)
{
printf("\n[-] send failed\n");
return -1;
}
len = recv(ClientSock, (char *)szRecv, 4096, 0);
if ((len <= 10) || (szRecv != 0))
{
printf("6\n");
return -1;
}
//下面就是获取管道客户端句柄
char szPipe;
HANDLE hFile;
//打开命名管道“\\server\pipe\browser”客户端句柄
_snprintf(szPipe, sizeof(szPipe), "\\\\%s\\pipe\\browser", argv);
hFile = CreateFile(szPipe, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if(hFile == (HANDLE)(-1))
{
printf("cann't find named pipe\n");
return -1;
}
//BIND rpc接口
if(!BindRpcInterface(hFile, "8d9f4e40-a03d-11ce-8f69-08003e30051b", "1.0"))
{
printf("can't get namedpipe! %d\n", GetLastError());
return -1;
}
//发送请求RPC request包
BOOL ret = ScanPNP(hFile);
closesocket(ClientSock);
if(ret)
{
printf("Vulnerable\n");
return 0;
}
else
printf("Not Vulnerable\n");
return 0;
}
作者:yincheng01 发表于2011-12-15 8:12:35 原文链接
页:
[1]