In memory of Terry Davis (August 11, 2018)
Table of Contents
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/list | will 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. |
Form3 | listeners creation and management |
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.
offensive security expert and founder of 0xsp security research and development (SRD), passionate about hacking and breaking stuff, coder and maintainer of 0xsp-mongoose RED, and many other open-source projects