1

How do I close tcp v4 and tcp v6 connections on Windows? I don't want to kill the entire process that has the open connection as this obviously will kick everyone else off that process. I need to do this from a separate process, and so will not have access to socket handles, etc. I am using Windows API to get tcp table, etc. so I know which connections are active.

jjxtra
  • 20,415
  • 16
  • 100
  • 140
  • According to [this](https://social.msdn.microsoft.com/Forums/sqlserver/en-US/4e4f2fbb-47ec-41c8-9c00-25c35a08254f/using-gettcp6table2-and-deleting-mibtcp6row2-entries?forum=wsk) SetTcpEntry6 is not there (yet?)... – Michael Chourdakis Apr 10 '19 at 20:18
  • Heh, yea that's literally the only information I have found. Sounds like Microsoft is just being lazy. I hope this doesn't involve injecting an RST packet that would be a royal pain, there has GOT to be an easier way... – jjxtra Apr 10 '19 at 20:21

2 Answers2

1

One way might be to enumerate all open handles on the system, or at least the open handles of a given target process, until you find the SOCKET handle you are interested in (see HOWTO: Enumerate handles, Socket Handles, and C++ Get Handle of Open Sockets of a Program - though I'm not sure how you would be able to retrieve the IP/Port pairs of a SOCKET to compare to the active connection you are interested in, without injecting remote getsockname()/getpeername() calls into the owning process of the SOCKET).

Once you have found the SOCKET handle you want, you can then close it by using DuplicateHandle() with the DUPLICATE_CLOSE_SOURCE flag 1.

1: This is how the "Close Handle" feature in Process Explorer works.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Do getsockname and getpeername work on duplicated handles? – jjxtra Apr 12 '19 at 00:13
  • Probably, but that won't help in this situation since you would have to duplicate without `DUPLICATE_CLOSE_SOURCE`, which defeats the purpose of duplicating. Unless you duplicate once, test, and then duplicate again when closing a match. But you really don't want the overhead of duplicating every open socket just to test them, you want to duplicate only the socket you intend to close. – Remy Lebeau Apr 12 '19 at 00:18
  • 1
    It is a pity that SetTcpEntry6 does not exist – jjxtra Apr 12 '19 at 00:50
  • I was unable to get this working unfortunately, a lot of weird errors and garbage data. It is quite possible I made an error somewhere, but as this is a private and mostly undocumented API, I don't feel good about using it in production. – jjxtra May 01 '19 at 18:49
0

Since I'm using C#, I cannot PInvoke SetTcpEntry, even as administrator with an app.manifest file, it always sends a 317 error. So I created a C++ .exe to close a comma separated list of ipv4 addresses on the command line using SetTcpEntry, works fine even without an app.manifest file. That solves kicking ipv4 connections.

I tried using the get handles approach with NtQuerySystemInformation but never could get it working quite right, and it is a private mostly undocumented API and seems unsafe to use.

So, for ipv6, I am using windivert and injecting RST flag to ipv6 packets with certain ip addresses. It is as simple as setting the RST flag of an incoming packet before sending it on through with windivert. The downside is, if the client never sends another packet, the ipv6 socket still stays open indefinitely.

Perhaps someday Microsoft will add a SetTcpEntry6 function, but until then this appears to be the only realistic way.

UPDATE 2022-05-01, found this gem at https://www.x86matthew.com/view_post?id=settcpentry6

jjxtra
  • 20,415
  • 16
  • 100
  • 140