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.


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: