Building mini c2c in Pascal – Part 2

In memory of Terry Davis (August 11, 2018)

an idiot admire complexity, a genius admires simplicity

Terry Davis


In this part, I will continue developing the team server for the operator side and designing the operator GUI interface. since the topic will contain several cod blocks, I have done the workshop videos via twitch and shared them with the Github repo [DEV-02]. you may also refer to the youtube channel to watch the recorded live sessions
While this article will explain the whole project flow.

However, I will finish the pending server/operator side functions and start designing and coding the operator interface.

/decoys/listwill show all connected agents to the team server so that the operator can assign the task
/listeners/create will create customized threaded listeners for agent communications

Team server Development – Continued

The decoys/list end-point will be responsible for handling all connected decoys that operators could access and manage. At the same time, the listeners/create function will allow operators to generate multiple decoys listeners and profiles.

My methodology to code these two functions is similar to the previous codded API end-points in part 1. so the operator will send a GET/POST request with required parameters to the team server, and the team server will handle the submitted request and execute it internally and then forward the results back as JSON response.

procedure TPasserver.decoys_list(req: Trequest; res: TResponse);
var
JSON : TJSONOBJECT;
JArray : TjsonArray;
UUID_list : Tstrings;
httpcode:integer;
i : integer;
begin

{there be must be auth protection }
JSON := TJSONObject.Create;   // going to create json object

try
try
validateRequest(req); // protect the end-point with valid authentication beaer token 


except on E: Exception do
begin
    Json.Add('success', False);
  Json.Add('reason', E.message);
    httpCode := 401;
   jsonresponse(res,Json,httpcode); 

end;
end;

  // reflect the status if in case auth is failed,
JArray := TjsonArray.Create;  // create json array to handle the list of decoys
Json.Add('decoys',jarray);
httpcode := 200;   // that will solve parsing the content bugs 


with DB do  begin
UUID_LIST := all_decoys;   // will take the list as string 
end;

for i := 0 to UUID_list.Count -1 do begin    // read all inside the list
JArray.Add(UUID_LIST[i]);   // add it into json array.
end;

jsonresponse(res,JSON,httpcode);

finally
 json.Free;
end;   
end;Code language: Delphi (delphi)

After that, we need to add a listeners feature in our team server, which will be assigned to each generated decoy with a specific profile.
To achieve that, the team server API will get the information submitted from the operator and create an internal thread that will create a unique listener for a decoy.

The below code snippet will handle the operator authenticated request, including listener option parameters(lhost,lport), and forward that request into the team server-internal function to create a threaded API server for the agent communications only.

procedure TPasserver.listeners_create(req:TRequest; res: Tresponse);
var
JSON : TJSONOBJECT;
l_port: string;
httpcode : integer;

begin
JSON := TJSONObject.Create;

try
try
validateRequest(req); 

except on E: Exception do
begin
    Json.Add('success', False);
    Json.Add('reason', E.message);
    httpCode := 401;
    jsonresponse(res,Json,httpcode);
end;
end;

 l_port := req.QueryFields.Values['l_port'];
 l_host := req.QueryFields.Values['l_host'];



with s_child do begin

 s_child := Tchild.create(true); // here will spawn another thread to handle child decoy API server
 s_child.execute(l_port);

end;
JSON.Add('port',l_port);
JSON.Add('host',l_host);
jsonresponse(res,Json,httpcode);

finally
json.Free;
end;

end;Code language: JavaScript (javascript)

As we discussed, the decoy API server differs from the team server. So we need to structure the required JSON API end-points and the threaded HTTP server.

function TChild.Listeners: TMyListeners;   // our listner function
var
  LAZ : TPasserver;

begin

{still in progress}

  with LAZ do begin

  HTTPRouter.RegisterRoute('/agent/heart_beat',@agent_heart_beat);




  end;

 _Listeners.Threaded := true;
 _Listeners.Initialize;


Result := _Listeners;
end; Code language: PHP (php)

For a quick demonstration, I have made an agent heartbeat end-point and will later see if we can access it when creating a listener and forwarding an agent API server.

procedure TPasserver.agent_heart_beat(req : Trequest; res: TResponse);
var
JSON: TJSONOBJECT;
httpcode:integer;
begin

JSON := Tjsonobject.Create;
Json.Add('status', 'i am a live '+l_host);
httpCode := 200;

jsonresponse(res,Json,httpcode);

end;   Code language: Delphi (delphi)

Operator interface

the expected result is to have a neat Graphical user interface(GUI) built using GTK3 with needed functionality such as login/create listers/manage decoys ..etc.

Since the graphical interface development could take much time to explain each step, I will only cover the important parts of development and code functions.

Form1 contains (username,password,team server IP address,port)
Form2 main dashboard to view connected decoys and assign tasks, including viewing results.
Form3listeners creation and management
Login form

the login form will be the first form to appear with options (server address, port, SSL) and username, and password; I have used the fphttpclient library for sending requests, which supports SSL.

function POST_Requester(URL_DATA,payload:string):string;
var
FPHTTPClient: TFPHTTPClient;
Resultget : string;
begin
	FPHTTPClient := TFPHTTPClient.Create(nil);
	FPHTTPClient.AllowRedirect := True;
	   try
	   Resultget := FPHTTPClient.FormPost(URL_DATA,payload);
	   POST_Requester := Resultget;

	   except
	      on E: exception do
	         writeln(E.Message);
	   end;
	FPHTTPClient.Free;

	end;   Code language: Delphi (delphi)

While the operator dashboard would look like the following figure below, with some options such as creating listeners/decoys and managing the connected sessions.

As for now, I have added a function to retrieve the connected decoys and list them on the VirtualTreeView list.

procedure Tform2.get_connections_list;    
var
rs,proc: string;
i :integer;


jData : TJSONData;
E : TJsonEnum;
Data: PTreeDecoy;
XNode: PVirtualNode;
p_size,d_size : integer;

begin

  proc := 'https://';
  try

 rs := sync_remote_GET(proc+form1.edit1.Text+':'+form1.edit2.Text+'/decoys/list',Label1.Caption);

 ////  JSON Parser to extract connected decoys with info /////////////////
 jData := GetJSON(rs);

 for E in JData do begin
   case E.Key of
     'decoys':     //grab decoy list
    decoy_list:=CreateTdecoy_list(e.Value);


   end;
 end;


p_size := length(decoy_list);


for i :=0 to p_size -1 do begin

XNode := VST.AddChild(nil);
if  Assigned(Xnode) then begin

 Data := VST.GetNodeData(XNode);

 Data^.UUID:= decoy_list[i];



end;
end;

 except
       on E: Exception do
       showmessage(E.message);
  end;




end;   Code language: Delphi (delphi)

Let’s now continue to do the third part, which is the creation of listeners from the operator dashboard. To achieve that, I need to put the web requester inside a created thread to avoid freezing the main application and simultaneously get the job done.

First, we need to declare a thread with execute override procedure and add cthreads unit into client.lpr project file

type
   TWorker = class(Tthread)

   protected
   procedure execute;override;
   public

   constructor create(CreateSuspended : boolean);

   end;   Code language: JavaScript (javascript)

, and inside the execute procedure, I have added the web requester code with the authentication bearer

function sync_remote_GET(URL,token:string):string; // this is for GET request only.
var
FPHTTPClient: TFPHTTPClient;
Resultget : string;
begin
	FPHTTPClient := TFPHTTPClient.Create(nil);
	FPHTTPClient.AllowRedirect := True;
        FPHTTPClient.AddHeader('Authorization','Basic '+token);

	   try
	   Resultget := FPHTTPClient.Get(URL);
	   sync_remote_GET := Resultget;

	   except
	      on E: exception do
	         showmessage(E.Message);
	   end;
	FPHTTPClient.Free;

	end;   


procedure Tworker.execute;
begin

sync_remote_GET(c_url+g_payload,g_token);
end; Code language: Delphi (delphi)

that will resolve the issue of freezing components while sending HTTP/HTTPS requests into the team server. As a result, we can create a listener profile successfully, and the agent server works well.

What’s next

In summary, I have managed to create a blazing team server with low latency and support authentications for multiple operators simultaneously. In addition, I have finished structuring the stable version of the team server and the expected operation; of course, many things will need to be added/modified when I start covering the coding of the agent(decoy), so I think that’s what is coming next.

Github

I have uploaded the project code at this stage of development to the main repo of this project, DEV-02; feel free to contribute or support by sharing knowledge.




Please follow and like us: