Is it possible to install an application on remote computer without approaching it?
Yes, it is. But two conditions must be met:
- Windows NT must be installed on remote computer
- Our application must be a service
The thing is rather simple. Here is the algorithm:
- Finding disks on remote computer
- Finding the disk with Windows installed on it
- Copying files
- Installing and running the service
Finding disks on remote computer
By default Windows NT shares all local disks - to read and write.
Share names consist of disk letter and "$" at the end.
Thus for disk C, the share is C$, for D - D$ etc.
Only
administrator can access those shares, thus I assume,
the user performing the installation has administrator rights
on the remote computer.
If not,
ImpersonateLoggedOnUser function could be used. Maybe I'll describe it one day...
Now we can access disks. All disks on remote computer ought to be found.
Unfortunatelly
WNetEnumResource function does not list these shares.
The only solution I managed to conceive is to use
WNetGetResourceInformation function.
The only problem with that one is that there is no such function neither in Delphi nor
in VS6 :-|. But that is not a problem for us:
interface
uses Windows;
function WNetGetResourceInformation(lpNetResource: PNetResource;
lpBuffer: Pointer; var cbBuffer: DWORD;
var lplpSystem: PAnsiChar): DWORD; stdcall;
implementation
function WNetGetResourceInformation;
external mpr name 'WNetGetResourceInformationA';
|
We have the function, now we must check for every letter from A to Z if such a share exists:
procedure FindDisks;
var
NetResource : TNetResource;
Size : DWORD;
Result : DWORD;
Res : PNetResource;
Str : PChar;
c : Char;
begin
with NetResource do
begin
dwScope := RESOURCE_GLOBALNET;
dwType := RESOURCETYPE_DISK;
dwDisplayType := RESOURCEDISPLAYTYPE_SHARE;
dwUsage := 0;
lpLocalName := nil;
lpComment := nil;
lpProvider := nil;
end;
Size := SizeOf(TNetResource);
GetMem(Res, Size);
try
for c := 'A' to 'Z' do
begin
NetResource.lpRemoteName := PChar('\\host\'+c+'$');
Result := WNetGetResourceInformation(@NetResource, Res, Size, Str);
if Result=ERROR_MORE_DATA then
begin
ReallocMem(Res, Size);
Result := WNetGetResourceInformation(@NetResource, Res, Size, Str);
end;
if Result=NO_ERROR then ShowMessage(Res^.lpRemoteName);
end;
finally
FreeMem(Res);
end;
end;
|
And there we have it, remote computer disk list.
Finding the disk with Windows insalled on it
This one is simpler.
It is sufficient to use
RegConnectRegistry function.
procedure GetSystemRoot;
var
Key : HKEY;
SubKey : HKEY;
Path : array[0..1024] of Char;
DataType : DWORD;
Size : DWORD;
begin
RegConnectRegistry('\\host', HKEY_LOCAL_MACHINE, Key);
try
RegOpenKeyEx(Key, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion',
0, KEY_READ, SubKey);
try
Size := SizeOf(Path);
RegQueryValueEx(SubKey, 'SystemRoot', nil, @DataType, @Path, @Size);
ShowMessage(Path);
finally
RegCloseKey(SubKey);
end;
finally
RegCloseKey(Key);
end;
end;
|
Of course it would be nice to check errors, but I leave it to you.
This way other information from remote register can be read as well.
Copying files
Anyone can do this. The destinations path is different.
Instead of disk letters we have
\\host\C$ for
C:, etc.
Installing and running the service
Similarly as with register we connect to the remote computer using API function.
procedure InstallService;
var
SCMan : SC_HANDLE;
Svc : SC_HANDLE;
begin
SCMan := OpenSCManager('\\host', nil, SC_MANAGER_ALL_ACCESS);
try
Svc := CreateService(SCMan, 'ServiceName', 'DisplayName',
SERVICE_ALL_ACCESS, ...);
CloseServiceHandle(Svc);
finally
CloseServiceHandle(SCMan);
end;
end;
|
Here you should also check whether the function performs correctly :-).
And now we have an application installed on the remote computer
and the remote computer user is not even aware of the fact he has a backdoor on his PC ;-).
Michał B±kowski