So I wrote a little remote control client/server based app to turn off my roomates torrent client at night (to avoid having to go into his room). I could have done this with remote software such as teamviewer or VNC but I don't need all the functionality that they provide plus I figuired it was a good learning exercise. It's not a trojan per se, since he knows it is running so don't flame me! haha.

It works great on windows XP and vista but doesn't work at all on Windows 7 for some reason. It works like this:

-the server is always listening for incoming TCP connections
-if you click a 'heartbeat' button on the server it sends out a UDP broadcast to the LAN
-if the trojan is running on a computer in the lan and receives the right UDP broadcast data it will try to connect to the originating IP of that broadcast via TCP
-Once this connection is established serialized classes can be sent back and forth, giving me the ability to do things such as shutdown his computer, reboot it, get a list of running procs, kill a proc, or run a proc.

On windows 7 it doesn't seem like it is getting the UDP broadcast at all, as there is no attempt to connect via tcp after the heartbeat is sent out. I am hesitant to post the code for it since I know script kiddies from around the world will probably abuse it far beyond its original intent, so I will post only where I think the problem is occuring (if you want the whole source and have a good reputation on here feel free to ask):

Server code:

//Broadcast the heartbeat pulse
private void btnPulse_Click(object sender, EventArgs e)
        {
            IPEndPoint groupEP = new IPEndPoint(IPAddress.Broadcast, 8002);
            UdpClient uClient = new UdpClient();
            uClient.EnableBroadcast = true;
            uClient.Send(Encoding.ASCII.GetBytes("KyleTrojStart"), Encoding.ASCII.GetBytes("KyleTrojStart").Length, groupEP);
            Log("Broadcasting heartbeat to LAN");
        }
//Listen for TCP connections
        private void StartNetwork()
        {
            sListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                sListen.Bind(new IPEndPoint(IPAddress.Any, 8003));
                sListen.Listen(5);
                sListen.BeginAccept(cbAccept, sListen);
            }
            catch (SocketException sE)
            {
                Log("Socket exception: " + sE.Message);
            }
        }
//Callback for accepting connections - this code is never reached
        private void cbAccept(IAsyncResult aR)
        {
            Socket lSock = (Socket)(aR.AsyncState);
            try
            {
                Socket conSock = lSock.EndAccept(aR);
                Invoke(new delVoidSocket(cbHandleAccept), conSock);
                sListen.BeginAccept(cbAccept, sListen);
            }
            catch (SocketException sE)
            {
                Invoke(new delVoidString(cbHandleError), sE.Message);
            }
        }
//Callback for handling accepted connections - this code is never reached
        private void cbHandleAccept(Socket sok)
        {
                mCon = new CustomConnectionClass(sok, DATA_BUFF_SIZE);
                Log("New connection established.");
                foreach (Control c in this.Controls)
                    c.Enabled = true;
                mCon.Sock.BeginReceive(mCon.DataBuffer, 0, (int)DATA_BUFF_SIZE, SocketFlags.None, cbReceive, mCon.Sock);
        }

This is on the client (the actual trojan)

volatile bool bKillThread = false;
        //Wait for the server on a seperate thread
        private void WaitForServer(object _Callback)
        {
            delVoidIP cbFunc = (delVoidIP)_Callback;
            UdpClient listener = new UdpClient(8002);
            IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 8002);
            byte[] bData;
            do
            {
                //probably doesn't run past here, but I could be wrong
                bData = listener.Receive(ref groupEP);
                if (Encoding.ASCII.GetString(bData, 0, bData.Length) == "KyleTrojStart") 
                    Invoke(cbFunc, groupEP.Address);
                System.Threading.Thread.Sleep(1000);
            } while (bKillThread == false);
        }

I haven't had the chance to debug the client in a windows 7 environment (as I don't have visual studio installed on a windows 7 machine). I am hoping it is a simple security issue which I can just disable on his computer. His firewall is disabled and in the advanced config I allowed UDP and TCP ports 8002,8003 incoming and outgoing. ANY help would be appreciated!

Recommended Answers

All 7 Replies

Whose machine is now running Win7, yours (the sender), his (the receiver), or both? Try to track down if the problem is sending the packet or receiving the packet.

You can also use something like Wireshark to watch network traffic to ensure that you do in fact see your UDP broadcast. If you see it then the sender is working fine. If there's nothing after that then there's a problem receiving it. If you see the receiving end attempt to initiate a TCP connection with your machine, then you know it received the UDP packet just fine and the problem is connecting via TCP.

Since the only "difference" seems to be the operating system it doesn't sound to me like it would be a problem with your code. I've run networking programs I've written on XP and Win7 back and forth with no problems, but I'm by no means an expert. They very well could have changed something I just haven't come across myself.

The receiver is running windows 7. Maybe I will try wireshark tonight, or maybe I will just change the client to create a log file with all the debug info that I need (to avoid having to install visual studio on a win7 system).

After some googling I think it may have to do with new security features that prevent Windows 7 from receiving UDP broadcasts, which would be no good at all.

I suppose if I need to I could strip out the UDP stuff altogether, but I kind of want to keep it to avoid having to hardcode/load a list of predetermined host or client IPs. Have you had any success with UDP broadcasts in Windows 7?

I haven't worked with UDP broadcasts, but after searching some I found this on msdn:

Win 7/XP UDP Broadcast differences
Just a note on UDP broadcast on Windows 7. Maybe this is documented somewhere but it cost me a couple of days: 0UdpClient client = new UdpClient(_localPort, AddressFamily.InterNetwork);
IPEndPoint groupEp = new IPEndPoint(IPAddress.Broadcast, _remotePort);

client.Connect(groupEp);

client.Send(_findBytes, _findBytes.Length);
client.Close();

This code will work on XP and send broadcast UDP messages. On Windows 7, no packets are sent (confirmed with Wireshark). Fix for Windows 7 is to restrict the broadcast range:
IPAddress destIp = IPAddress.Parse("192.168.1.255");

IPEndPoint groupEp = new IPEndPoint(destIp, _remotePort);

The packets are now sent.

I saw something similar to this earlier in my searching too. Even though this person is talking about sending from Win7, it may still apply to receiving. Try changing your

IPEndPoint groupEP = new IPEndPoint(IPAddress.Broadcast, 8002);

to

IPEndPoint groupEP = new IPEndPoint(IPAddress.Parse("192.168.1.255"), 8002);

Obviously substitute "192.168.1" with whatever your own local network is, if different.

After reading more you definitely need to check with Wireshark, and it will save time if you check it from the receiver. I saw a thread where Win7 wouldn't pass broadcast packets up to the application layer if the source had an unconfigured IP. They were seeing the broadcast packets on the receiver with Wireshark, but the packets never made it to their application. Since your source field would be set (ie, not 0.0.0.1) I don't think that specific issue is occurring. I'll keep looking for more. Now you've got me intrigued lol.

Another thought, you might be able to get the IP address through DNS... If you look at if you have anything shared for example, anyone on your network can access your computer with \\MyComputerName... there has to be some sort of name resolution happening there.

Maybe you can do something like

IPHostEntry _iphe = Dns.GetHostByName("KylesComputer");
IPEndPoint _ep = new IPEndPoint(_iphe.AddressList[0], 8002);
UdpClient _uClient = new UdpClient();
byte[] _content = Encoding.ASCII.GetBytes("KyleTrojStart");
uClient.Send(_content, _content.Length, _ep);

Assuming this works, you now only have to worry about Kyle changing his computer name (unlikely) instead of your router handing out a new IP (inevitable if you don't static your hosts). I haven't had time to try this, but I'll give it a shot when I do.

Hey. Interesting posts. As much as I would like to nerd it up on a Friday night, I have spent all day coding at work and need some beer. I will try implementing that narrowing of the broadcast range some other day, and will post my results here. Thanks for the helpful insight.

Update - seems to be connecting just fine with the narrowed broadcast IP. Not to sure why microsoft would make sockets less functional.....

You need deal with firewall.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.