Listar IPs usando la clase Ping: [Enlace externo eliminado para invitados]
Obtener información del host usando SMB (sólo si el host es Windows): [Enlace externo eliminado para invitados]
/*
* Autor: Blau
* Fuentes:
* Tim Coker- https://stackoverflow.com/a/4042887
* TeskeVirtualSystem - https://github.com/TeskeVirtualSystem/MS17010Test
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace lanman
{
class RemoteHost
{
public string IP { get; set; }
public string Hostname { get; set; }
public string OsVersion { get; set; }
public string OsBuild { get; set; }
public string Workgroup { get; set; }
public RemoteHost() { }
}
class Program
{
static CountdownEvent countdown;
static int upCount = 0;
static object lockObj = new object();
const bool resolveNames = true;
static List<RemoteHost> remoteHosts = new List<RemoteHost>();
static void Main(string[] args)
{
countdown = new CountdownEvent(1);
Stopwatch sw = new Stopwatch();
sw.Start();
string ipBase = "192.168.16.";
for (int i = 1; i < 255; i++)
{
string ip = ipBase + i.ToString();
Ping p = new Ping();
p.PingCompleted += new PingCompletedEventHandler(p_PingCompleted);
countdown.AddCount();
p.SendAsync(ip, 1000, ip);
}
countdown.Signal();
countdown.Wait();
sw.Stop();
TimeSpan span = new TimeSpan(sw.ElapsedTicks);
Console.WriteLine("Took {0} milliseconds. {1} hosts active.", sw.ElapsedMilliseconds, upCount);
foreach(RemoteHost r in remoteHosts)
{
Console.WriteLine($"[{r.IP}]\n\t- Hostname: {r.Hostname}\n\t- OS: {r.OsVersion}\n\t- OSBuild: {r.OsBuild}\n\t- Workgroup: {r.Workgroup}");
}
}
static void p_PingCompleted(object sender, PingCompletedEventArgs e)
{
string ip = (string)e.UserState;
string name = string.Empty;
if (e.Reply != null && e.Reply.Status == IPStatus.Success)
{
if (resolveNames)
{
try
{
IPHostEntry hostEntry = Dns.GetHostEntry(ip);
name = hostEntry.HostName;
}
catch (SocketException ex) { }
}
lock (lockObj)
{
upCount++;
}
RemoteHost r = new RemoteHost();
r.IP = ip;
r.Hostname = name;
GetRemoteInfo(r.IP, r);
lock (remoteHosts)
{
remoteHosts.Add(r);
}
}
countdown.Signal();
}
static void GetRemoteInfo(string ip, RemoteHost r)
{
const int bufferSize = 1024;
const int timeout = 5000;
byte[] negotiateProtoRequest = { 0x00, 0x00, 0x00, 0x54, 0xFF, 0x53, 0x4D, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x4B, 0x00, 0x00, 0xC5, 0x5E, 0x00, 0x31, 0x00, 0x02, 0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x31, 0x2E, 0x30, 0x00, 0x02, 0x4C, 0x4D, 0x31, 0x2E, 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x4E, 0x54, 0x20, 0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x20, 0x31, 0x2E, 0x30, 0x00, 0x02, 0x4E, 0x54, 0x20, 0x4C, 0x4D, 0x20, 0x30, 0x2E, 0x31, 0x32, 0x00};
byte[] sessionSetupAndxRequest = { 0x00,0x00,0x00,0x63,0xFF,0x53,0x4D,0x42,0x73,0x00,0x00,0x00,0x00,0x18,0x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2F,0x4B,0x00,0x00,0xC5,0x5E,0x0D,0xFF,0x00,0x00,0x00,0xDF,0xFF,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x26,0x00,0x00,0x2e,0x00,0x57,0x69,0x6e,0x64,0x6f,0x77,0x73,0x20,0x32,0x30,0x30,0x30,0x20,0x32,0x31,0x39,0x35,0x00,0x57,0x69,0x6e,0x64,0x6f,0x77,0x73,0x20,0x32,0x30,0x30,0x30,0x20,0x35,0x2e,0x30,0x00};
try
{
byte[] buffer = new byte[bufferSize];
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.ReceiveTimeout = timeout;
client.SendTimeout = timeout;
IPAddress ipAddress = IPAddress.Parse(ip);
client.Connect(new IPEndPoint(ipAddress, 445));
client.Send(negotiateProtoRequest);
var receivedBytes = client.Receive(buffer, SocketFlags.Partial);
var oBuff = buffer.Take(receivedBytes).ToArray();
client.Send(sessionSetupAndxRequest);
receivedBytes = client.Receive(buffer, SocketFlags.Partial);
oBuff = buffer.Take(receivedBytes).ToArray();
var netbiosB = oBuff.Take(4).ToArray();
var smbHeaderB = oBuff.Skip(4).Take(32).ToArray();
var smb = ByteArrayToSmbHeader(smbHeaderB);
var sessionSetupAndxResponse = oBuff.Skip(36).ToArray();
var nativeOsB = sessionSetupAndxResponse.Skip(9).ToArray();
var osData = Encoding.ASCII.GetString(nativeOsB).Split('\x00');
string OSName = osData[0];
string OSBuild = string.Empty, Workgroup = string.Empty;
if (osData.Count() >= 3)
{
OSBuild = osData[1];
Workgroup = osData[2];
}
r.OsVersion = osData[0];
r.OsBuild = OSBuild;
r.Workgroup = Workgroup;
}
catch (Exception Ex) { }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SmbHeader
{
public UInt32 server_component;
public byte smb_command;
public byte error_class;
public byte reserved1;
public UInt16 error_code;
public byte flags;
public UInt16 flags2;
public UInt16 process_id_high;
public UInt64 signature;
public UInt16 reserved2;
public UInt16 tree_id;
public UInt16 process_id;
public UInt16 user_id;
public UInt16 multiplex_id;
}
public static SmbHeader ByteArrayToSmbHeader(byte[] bytes)
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
SmbHeader stuff = (SmbHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SmbHeader));
handle.Free();
return stuff;
}
}
}