Packet Data Sniffing from ASP.NET - c#

I would like to sniff packet data using C#
I need it to sniff all types of data not only HTTP
When I try to do it I get this error:
System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Bind(EndPoint localEP)
public void StartCapture(string InterfaceIp)
{
try
{
//Start capturing the packets...
//For sniffing the socket to capture the packets has to be a raw socket, with the
//address family being of type internetwork, and protocol being IP
mainSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Raw, System.Net.Sockets.ProtocolType.IP);
//Bind the socket to the selected IP address
mainSocket.Bind(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(InterfaceIp), 0));
//Set the socket options
mainSocket.SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP, //Applies only to IP packets
System.Net.Sockets.SocketOptionName.HeaderIncluded, //Set the include the header
true); //option to true
byte[] byTrue = new byte[4] { 1, 0, 0, 0 };
byte[] byOut = new byte[4] { 1, 0, 0, 0 }; //Capture outgoing packets
//Socket.IOControl is analogous to the WSAIoctl method of Winsock 2
mainSocket.IOControl(System.Net.Sockets.IOControlCode.ReceiveAll, //Equivalent to SIO_RCVALL constant
//of Winsock 2
byTrue,
byOut);
//Start receiving the packets asynchronously
mainSocket.BeginReceive(byteData, 0, byteData.Length, System.Net.Sockets.SocketFlags.None,
new AsyncCallback(OnReceive), null);
}
catch (Exception ex)
{
//Report Exception
}
}
Note:I am using ASP.Net & it is really important to sniff the data and not only the headers of the packet
I think the problem is related to not having the right privileges to access to socket, although using impersonation didn't solve the problem
I found the solution to my problem, it's related to a recent implementation that limits binding to a socket that is protected and limited to a single ip address
Here are some interesting links
http://msdn.microsoft.com/en-us/library/cc150667(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms740668%28v=VS.85%29.aspx

If you are OK with using a library, SharpPcap is a nice one and it's very simple to use.

I'm experimenting with raw sockets.
I fixed this error,
System.Net.Sockets.SocketException: 'An attempt was made to access a
socket in a way forbidden by its access permissions'
simply by running visual studio in administrator mode.

Related

C# .Net 10054 UDP Exception? Cause, fix? [duplicate]

I need to obtain UDP datagram from Asynchronous Socket Server but an exception occurred in my application :
Problem appear there :
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
The full source code:
class Program
{
static void Main(string[] args)
{
const int PORT = 30485;
IPAddress IP;
IPAddress.TryParse("92.56.23.87", out IP);
// This constructor arbitrarily assigns the local port number.
UdpClient udpClient = new UdpClient(PORT);
Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
try
{
udpClient.Connect("92.56.23.87", PORT);
if (udpClient.Client.Connected)
Console.WriteLine("Connected.");
// Sends a message to the host to which you have connected.
Byte[] sendBytes = Encoding.ASCII.GetBytes("CONNECT");
udpClient.Send(sendBytes, sendBytes.Length);
//IPEndPoint object will allow us to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IP, PORT);
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
// Uses the IPEndPoint object to determine which of these two hosts responded.
Console.WriteLine("This is the message you received " + returnData.ToString());
Console.WriteLine("This message was sent from " + RemoteIpEndPoint.Address.ToString() + " on their port number " + RemoteIpEndPoint.Port.ToString());
udpClient.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
Exception:
Connected.
System.Net.Sockets.SocketException (0x80004005): An existing connection
was forcibly closed by the remote host at System.Net.Sockets.Socket.ReceiveFrom(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint& remoteEP) at ystem.Net.Sockets.UdpClient.Receive(IPEndPoint& remoteEP) at ConsoleApplication7.Program.Main(String[] args) in c:\users\user\documents\visual studio 2010\Projects\ConsoleApplication7\ConsoleApplication7\Program.cs
What can be the problem?
To provide more information, i bought the private socks connection on this page: http://rapidsocks.com/
this services give me a list of IP and port who in really is not a proxy .. just a connection that give me a proxyIP:proxyPort from a pool on server in response...
How to get that answer with proxyIP:proxyPort from the server?
In UDP land, one way this can occur is when you send a UDP packet to a host, and the remote host doesn't have a listener on that port, and bounces an ICMP host unreachable message in response.
In plain English, what this exception tells you that no process is listening on the far-end on that port.
Update: You should be able to avoid that behavior with the following code:
var udpClient = new UdpClient();
uint IOC_IN = 0x80000000;
uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
Microsoft Article 263823 said this on the subject: [hard to find as of 2019]
SYMPTOMS
In Windows 2000, a User Datagram Protocol (UDP) program may
not work and may generate a WSAECONNRESET response.
CAUSE
If sending a datagram using the sendto function results in an
"ICMP port unreachable" response and the select function is set for
readfds, the program returns 1 and the subsequent call to the recvfrom
function does not work with a WSAECONNRESET (10054) error response. In
Microsoft Windows NT 4.0, this situation causes the select function to
block or time out.
RESOLUTION
A new sockets IOCTL called "SIO_UDP_CONNRESET" has been
introduced in Windows 2000. When this IOCTL is used, the program must
be rewritten specifically for Windows 2000 to obtain the original
Windows NT 4.0 behavior. Windows NT 4.0, Microsoft Windows 95, and
Microsoft Windows 98 have no support for this new IOCTL. In addition
to rewriting your application, you will need the hotfix referenced
further down in this article.
This really is a generic error message that could mean anything. Time to get the low level network traffic sniffers to filter what is actually going wrong. Adding extra error handling try catch blocks on the server with decent logging is always a great place to start.

C# .Net Socket Server Client

I've got a little problem with the .Net Sockets in C#.
I programmed a client and a server working with TCP.
As the client is opened it sends a handshake to the server. The server answers with it's state (clientexists, clientaccepted,...). After that the application sends a getdata-request, abandons the connection and listens for the server's 'response'. Now, the server builds a connection to the client and sends all the data the client needs.
The code and everything else works, but the problem:
On our company testserver it works fine, on the live server only the handshake works. After it the client doesn't receive any more data. Serverapplication is the same on both servers.
I thought the problem was caused by some firewall (server wants to build a tcp connection to the client -> not good), but the system administrator said there is no firewall that could block that.
Now I'm searching for a ('cheap') solution that doesn't take too much time and changes in code. If anyone knows how to theoretically solve that, that would be great.
BTW: I am not allowed to do anything on the live server other than run the serverapplication. I don't have the possibility to debug on this server.
I can't publish all of my code, but if you need to see specific parts of it, ask for it please.
---EDIT---
Client-Server communication
1) Client startup
Client send handshake (new tcp connection)
2) Server validates handshake and saves IP
Server responds with it's client state (same tcp connection)
3) Client acknowledges this response and abandons this connection
Client sends getdata-request (new tcp connection)
Client abandons this tcp connection, too
4) Server receives getdata-request and collects the needed data in the main database
Server sends all the collected data to the client (multiple tcp connections)
5) Client receives all data and displays it in it's GUI (multiple tcp connections and the order of the data is kept by working with AutoResetEvents and Counts of sockets to send)
This is the main part my code does. It's by far not the best but it was for me as I wrote it I guess. Step one, two and three work as intended. The processing of the data works fine, too.
Another thing i forgot to mention is that the solution uses two Ports '16777' and '16778'. One to receive/listen and one to send.
My code is based on the MSDN example of the asynchronous server and client.
Sending a handshake (and getdata-request)
public void BeginSend(String data)
{
try
{
StateObject state = new StateObject();
state.workSocket = sender;
byte[] byteData = Encoding.UTF8.GetBytes(data);
sender.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback((IAsyncResult e) =>
{
Socket socket = (Socket)e.AsyncState;
SocketBase.StateObject stateObject = new SocketBase.StateObject();
stateObject.workSocket = socket;
socket.BeginReceive(stateObject.buffer, 0, 256, SocketFlags.None, new AsyncCallback(this.ReadCallback), (object)stateObject);
}), sender);
sender = RetrieveSocket(); //Socketreset
Thread.Sleep(100);
}
catch /*(Exception e)*/
{
//--
}
}
Server listener
public void StartListening()
{
listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(System.Int32.MaxValue);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
//--
}
}
public void AcceptCallback(...);
public void ReadCallback(...);
Socket send
private void Send(Socket handler, String data)
{
Socket t = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint).Address);
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.UTF8.GetBytes(data);
// Begin sending the data to the remote device.
t.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), t);
}
Socket send all data part (answer to getdata-request | socToHandle should be the socket of the previous connection of the getdata-request)
private void SendAllData(Socket socToHandle, string PakContent)
{
#region IsThereADatetime? //Resolve a given datetime
#region GiveClientNumberOfPackets //Send the client info about how much he has to receive (See line below)
Send(socToHandle, "ALERT#TASKCOUNT;OPT-" + GetBestDate(dateStart) + EndSocket);
#region #SendResouces
#region #SendGroups
#region #SendTasks
}
Looking through my old code I have one idea =>
Could I send everything over the same connection by changing:
Socket t = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint).Address);
(which creates a new connection) to something that uses the same connection?
If that would work, how can I do that?
And would the listener part of the client still receive single packets?
Servers and their environment are configured to handle incoming requests properly. Clients are usually behind a router, which by default make them unable to receive incoming connections from outside their network (a good thing).
To enable incoming connections, you could configure your router to forward all requests for a certain port number to your machine. No one else on your network would be able to run the client then, though.
This is why in a typical multiple clients-single server environment, the client makes all the connections, and only the server requires any changes to the network landscape.
I don't know why you chose to connect to the clients from the server side, but I would strongly advise against this - any cheap solution that uses this mechanism may turn out to be very expensive in the end.

Empty message while receiving data from socket

I'm trying to connect to an UAP Server (used for sending and receiving USSD messages in Huawei) using Socket class but there's a problem while receiving data from server. I can connect to server correctly and also I can send data to server but I have problem with receiving data.
This is my code for connecting and sending message:
IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); //server
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 2020);
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(remoteEP);
//bind to socket, here I send bind message
Bind();
and inside the Bind function, I call receive method to get data from server:
private static void receive()
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = clientSocket;
// Begin receiving the data from the remote device.
clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(receiveCallback), state);
}
catch (Exception ex)
{
Console.WriteLine("receive | " + ex.ToString());
}
}//receive
Here you can see my Wireshark log while connecting, sending data and receiving data from server:
But as you can see, last two messages from server are highlighted with red color which means there's a problem with receiving data from server. Also I don't see data field in details:
I really don't know what's the problem, is this a problem with server or not? Should I use another Socket client to connect and receive data from server or not?
TCP reset packets aren't a part of your application level protocol and your application shouldn't be expected to see them.
Exactly what is the incorrect behavior with your application, because with what you've posted, I'm not seeing any problems.

An existing connection was forcibly closed by the remote host

I need to obtain UDP datagram from Asynchronous Socket Server but an exception occurred in my application :
Problem appear there :
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
The full source code:
class Program
{
static void Main(string[] args)
{
const int PORT = 30485;
IPAddress IP;
IPAddress.TryParse("92.56.23.87", out IP);
// This constructor arbitrarily assigns the local port number.
UdpClient udpClient = new UdpClient(PORT);
Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
try
{
udpClient.Connect("92.56.23.87", PORT);
if (udpClient.Client.Connected)
Console.WriteLine("Connected.");
// Sends a message to the host to which you have connected.
Byte[] sendBytes = Encoding.ASCII.GetBytes("CONNECT");
udpClient.Send(sendBytes, sendBytes.Length);
//IPEndPoint object will allow us to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IP, PORT);
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
// Uses the IPEndPoint object to determine which of these two hosts responded.
Console.WriteLine("This is the message you received " + returnData.ToString());
Console.WriteLine("This message was sent from " + RemoteIpEndPoint.Address.ToString() + " on their port number " + RemoteIpEndPoint.Port.ToString());
udpClient.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
Exception:
Connected.
System.Net.Sockets.SocketException (0x80004005): An existing connection
was forcibly closed by the remote host at System.Net.Sockets.Socket.ReceiveFrom(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint& remoteEP) at ystem.Net.Sockets.UdpClient.Receive(IPEndPoint& remoteEP) at ConsoleApplication7.Program.Main(String[] args) in c:\users\user\documents\visual studio 2010\Projects\ConsoleApplication7\ConsoleApplication7\Program.cs
What can be the problem?
To provide more information, i bought the private socks connection on this page: http://rapidsocks.com/
this services give me a list of IP and port who in really is not a proxy .. just a connection that give me a proxyIP:proxyPort from a pool on server in response...
How to get that answer with proxyIP:proxyPort from the server?
In UDP land, one way this can occur is when you send a UDP packet to a host, and the remote host doesn't have a listener on that port, and bounces an ICMP host unreachable message in response.
In plain English, what this exception tells you that no process is listening on the far-end on that port.
Update: You should be able to avoid that behavior with the following code:
var udpClient = new UdpClient();
uint IOC_IN = 0x80000000;
uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
Microsoft Article 263823 said this on the subject: [hard to find as of 2019]
SYMPTOMS
In Windows 2000, a User Datagram Protocol (UDP) program may
not work and may generate a WSAECONNRESET response.
CAUSE
If sending a datagram using the sendto function results in an
"ICMP port unreachable" response and the select function is set for
readfds, the program returns 1 and the subsequent call to the recvfrom
function does not work with a WSAECONNRESET (10054) error response. In
Microsoft Windows NT 4.0, this situation causes the select function to
block or time out.
RESOLUTION
A new sockets IOCTL called "SIO_UDP_CONNRESET" has been
introduced in Windows 2000. When this IOCTL is used, the program must
be rewritten specifically for Windows 2000 to obtain the original
Windows NT 4.0 behavior. Windows NT 4.0, Microsoft Windows 95, and
Microsoft Windows 98 have no support for this new IOCTL. In addition
to rewriting your application, you will need the hotfix referenced
further down in this article.
This really is a generic error message that could mean anything. Time to get the low level network traffic sniffers to filter what is actually going wrong. Adding extra error handling try catch blocks on the server with decent logging is always a great place to start.

Don't know why I'm getting Error Code 10022 (Invalid Argument) when setting socket options in my C# sniffer

I'm writing a packet sniffer as an exercise in learning .Net 4 socket development on in C#. My goal is to sniff IP packets coming in and out out my computer.
My problem is that I'm getting error code 10022, invalid argument, on my call to SetSocketOption. I don't see where I have an invalid argument. I have some admin privs on my computer, but perhaps I don't have enough. It's my work computer and the IT department is pretty strict. With that said, if it was a permissions problem I would expect a different exception.
I'm not sure what my next step should be to debug this problem. Anyone have an idea?
Here's the code follows:
public Sniffer()
{
try
{
socket = new Socket(
AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
IPAddress[] ipAddresses = Dns.GetHostEntry(
Dns.GetHostName()).AddressList;
socket.Bind(new IPEndPoint(ipAddresses[0], 0));
socket.SetSocketOption(
SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
byte[] inputData = new byte[4] { 1, 0, 0, 0 };
byte[] outValue = new byte[4];
socket.IOControl(IOControlCode.ReceiveAll, inputData, outValue);
}
catch (SocketException ex)
{
string ErrorMessage = ex.Message;
}
}
Microsoft has restricted the use of raw sockets on non-server editions of the the windows OS on all OS's newer than XP SP2, due to abuse by viruses in the early 2000's.
You can read more on what restrictions are in place from the page on TCP/IP Raw Sockets on the MSDN.
WSAEINVAL 10022
Invalid argument.
Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function). In some instances, it also refers to the current state of the socket—for instance, calling accept on a socket that is not listening.
Take a look about this error here:
http://msdn.microsoft.com/en-us/library/ms740668(v=vs.85).aspx

Categories

Resources