当防火墙阻止ping时,如何从扫描本地网络中获取mac地址



对于我目前正在Delphi中编写的安全产品。我使用下面的解决方案来使用ARP表从设备中获取MAC地址,以检测网络上的内容。

如何从arp中查找MAC地址-扫描

我只是执行一系列Ping命令来填充ARP表并从ARP表中读取结果。

但是,当计算机上的防火墙正在阻止Ping时。有时MAC仍然暴露在ARP中,但并非总是如此。检测网络上的所有设备并从中获取MAC地址的更好解决方案是什么?

//-----------------------------------------------------------------------------
{ ARP-table lists relations between remote IP and remote MAC-address.
NOTE: these are cached entries;when there is no more network traffic to a
node, entry is deleted after a few minutes.
}
//-----------------------------------------------------------------------------
procedure Get_ARPTable( aList: TStrings; aDeviceList : TObjectList<TNetworkDevice>);
var
lIPNetRow    : TMibIPNetRow;
lTableSize   : DWORD;
lNumEntries  : DWORD;
lErrorCode   : DWORD;
lIdx         : Integer;
lPBuf        : PAnsiChar;
lPhysAddr    : TMACAddress;
lMacAddr2Str : string;
ldwAddr      : string;
ldwType      : string;
lNewDevice   : TNetworkDevice;
begin
if not LoadIpHlp then Exit;
if not Assigned( aList ) then Exit;
if not Assigned( aDeviceList) then Exit;
Get_LocalNetworkDevices(aDeviceList);
aList.Clear;
lTableSize := 0;
lErrorCode := GetIPNetTable( Nil, @lTableSize, False );
//
if lErrorCode = ERROR_NO_DATA then
begin
aList.Add( ' ARP-cache empty.' );
EXIT;
end;
// get table
GetMem( lPBuf, lTableSize );
lNumEntries := 0;
try
lErrorCode := GetIpNetTable( PTMIBIPNetTable( lPBuf ), @lTableSize, False );
if lErrorCode = NO_ERROR then
begin
lNumEntries := PTMIBIPNetTable( lPBuf )^.dwNumEntries;
if lNumEntries > 0 then
begin
Inc( lPBuf, SizeOf( DWORD ) );
for lIdx := 1 to lNumEntries do
begin
lIPNetRow := PTMIBIPNetRow( lPBuf )^;
lMacAddr2Str := MacAddr2Str( lIPNetRow.bPhysAddr, lIPNetRow.dwPhysAddrLen );
lPhysAddr := lIPNetRow.bPhysAddr;
ldwAddr := IPAddr2StrTrunc(lIPNetRow.dwAddr);
ldwType := ARPEntryType[lIPNetRow.dwType];
lNewDevice := SeekDevice(aDeviceList, lMacAddr2Str);
if Assigned(lNewDevice) then
begin
lNewDevice.IP := ldwAddr;
lNewDevice.IsNew := False;
lNewDevice.EntryType :=  ARPEntryType[lIPNetRow.dwType];
if (lNewDevice.EntryType = 'Dynamic') or
(lNewDevice.EntryType = 'Static') then
lNewDevice.SetStamp;
end
else
begin
lNewDevice := TNetworkDevice.Create;
lNewDevice.IP := ldwAddr;
lNewDevice.EntryType  := ARPEntryType[lIPNetRow.dwType];
lNewDevice.AddOrUpdate(lMacAddr2Str);
lNewDevice.SetFirstSeen;
lNewDevice.SetStamp;
lNewDevice.State := dtRogue;
lNewDevice.IsNew := True;
aDeviceList.Add(lNewDevice);
end;
with lIPNetRow do
begin
aList.Add( Format( '%8x | %12s | %16s| %10s',
[dwIndex, MacAddr2Str( bPhysAddr, dwPhysAddrLen ),
IPAddr2Str( dwAddr ), ARPEntryType[dwType]
]));
end;
Inc( lPBuf, SizeOf( lIPNetRow ) );
end;
end
else
aList.Add( ' ARP-cache empty.' );
end
else
aList.Add( SysErrorMessage( lErrorCode ) );
// we _must_ restore Pointer!
finally
Dec( lPBuf, SizeOf( DWORD ) + lNumEntries * SizeOf( lIPNetRow ) );
FreeMem( lPBuf );
end;
end;

为了补充ping,您可以尝试在任何端口上建立TCP连接,例如端口80(HTTP(。当然,大部分连接都会被拒绝,但你仍然可以在ARP表中找到一个条目。

根据防火墙的不同,您也可能只是简单地得到响应。然后你必须尝试另一个端口。我建议135(RPC(或445或139(两者都是SMB(,如果启用了网络共享,应该打开。3389中的另一个由RDP使用(如果启用(。

只有当子网较小(C类,256个地址(或中等(B类,16K地址(时,这才是可行的。不管怎样,这需要很多时间。

最新更新