更新病毒碼(AVG)
作者:csc@ocean-pioneer.com
最後更新日期:2004/03/31

AVG(www.grisoft.com)AVG6.0
本人自己寫了一個小程式,可以在linux下自動比對病毒碼共下載最新及在client端windows執行更新的程式


更新AVG(參考AVG的help 檔)
AVG防毒程式,提供單一的方法來更新,不只是病毒碼還包含了程式的更 新,它全部壓縮在一個更新檔中
如何手動更新,到網站下載檔案*.bin並將檔案放在avg安裝目錄下 (預設C:\Program Files\Grisoft\AVG6)的update目錄,啟動程式avgw.exe,該程式就會自動檢查是否需要更新,如果需要更新則會啟動更新的步 驟

以下是一些程式的基本問題
  1. 病毒碼的資訊在那:ftp://ftp.grisoft.com/pub/softw/60/xx/avg6info.ctf
  2. AVG CTF File
    "d600ppxe.bin" s=2484161 v=6 t=120 r=0 l=2 ;
    "d6032pgl.bin" s=1547353 v=6 t=516 r=515 l=7 ;
    "d6032lhj.bin" s=3775889 v=6 t=516 r=0 l=7 ;
    "../xx/u6122pdc.bin" s=3011303 v=6 t=639 r=516 l=0 ;
    "../xx/u6122wbc.bin" s=959041 v=6 t=639 r=606 l=0 ;
    "../xx/u6122xxo.bin" s=801149 v=6 t=639 r=627 l=0 ;
  3. 我想如果正常更新則版本的差異在最小的範圍內,則最後一行就是最後需要更新檔案,u6122xxo.bin 檔案大小s=801149,防毒軟體的版本v=6,更新程式的版本t=639,要更新到的版本才可以使用這個版本
  4. 下載檔案ftp://ftp.grisoft.com/pub/softw/60/xx/avginfo.ctf,檢查這個檔案和你的檔案, 我猜想整個檔案不相同就是需要更新,因此下載並比對AVGINFO.CTF,不同則下載更新
  5. 使用python語言來寫
  6. 其它的軟體工具linux(wget,grep),windows(autoit)
  7. 在AVG的安裝目錄下有一個更新記錄檔update.log
    根據說明在更新檔bin內可能含有病毒碼,或其它更新元件(是一個壓縮檔),因此分析上述檔案驗證u6122xxo.bin包含了 version.avg, avgcore.vxd,avg.ovl,microavi.avg,而執行avgw.exe時會檢查bin檔,並更新必要更新的元件
實作
  1. 使用wget -O /tmp/avg6info.ctf ftp://ftp.grisoft.com/pub/softw/60/xx/avg6info.ctf
  2. 使用python模組re
    f=open("/tmp/avg6info.ctf").readlines()
    parse_string=f[len(f)-1]  會取得最後一行
    "../xx/u6122xxo.bin" s=801149 v=6 t=639 r=627 l=0 ;
    last_file=re.search('[a-zA-Z0-9]*.bin',parse_string)     最後檔案名稱
    last_version=re.search('t=[0-9][0-9][0-9]',parse_string) 最後的版本
    last_filesize=re.search('s=[0-9]*',parse_string)         最後檔案的大小
  3. 因為病毒碼的名稱為*.bin,我們只要將檔案放在目錄下,刪除舊*.bin
  4. 伺服器端:下載及更新病毒碼
    將本程式放在cron.daily,並自己修改work_dir參 數,這是你放置病毒碼所在
    則每天會去AVG的網站檢查是否更新如果更新則下載到work_dir並 更改檔名為,因為我的分享目錄放在hpnse45的NT4.0的伺服器上因此多執行了mount的指令,你可以根據你需求來修改
  5. 因應別人要求email 通知,使用類別smtplib
    server=smtplib.SMTP('localhsot')
    server.sendmail("寄件者","收件者","內容") -如果需要主旨請加在內容"Subject: 文字 \n其它內容"
    server.quit()
  6. 試著使用外部郵件,也就是寫好一個郵件,讀進來然後使用5的命令來送mail
  7. rm 可以合併rm -f *.txt & rm -f *.bin 為 rm -f *.txt *.bin之類
avg.py(可以使用但尚未更新到最新)
#!/usr/bin/python
import re,string,commands,sys,string,os.path
import smtplib
from time import localtime,time,strftime

status_n,status_s=commands.getstatusoutput('mount -t smbfs -o username=abc,password=abc //hpnse45/vol1 /mnt/update_v')
if status_n:
   print " Mount my other smb file error!"
   sys.exit(1)


work_dir='/mnt/update_v/temp/update_v/avg'
version_file='avg6info.ctf'

#avg ftp site
avg_ftp="ftp://ftp.grisoft.com"

#virus info data
virus_data_url='/pub/softw/60/xx/avg6info.ctf'
virus_data_dir='/pub/softw/60/xx'


#Email notify when update
#Email_notify=1 enable email notify otherwise Email_notiyf=0 to turn it off
email_notify=1
notify_from ="set you sender email address"
notify_email="your email address"
notify_time=strftime('%m-%d-%H:%M',localtime(time()))
notify_message="AVG update virus at "+notify_time
notify_subject='Update AVG notify'


print "Download virus info file....."
virus_info_url=avg_ftp+virus_data_url
print virus_info_url
status_n,status_s=commands.getstatusoutput('wget -O /tmp/avg6info.ctf '+virus_info_url)
if status_n:
    print "Download virus information file  error!"
    sys.exit(1)
else :
    print "Download successful !"
 
last_file=open("/tmp/avg6info.ctf").readlines()

parse_string=last_file[len(last_file)-1]
last_file=re.search('[a-zA-Z0-9]*.bin',parse_string)
if last_file==None:
   print "Parse last file  error !"
   sys.exit(1)
last_file=last_file.group()
last_version=re.search('t=[0-9][0-9][0-9]',parse_string)
if last_version==None:
   print "Parse last file version error !"
   sys.exit(1)
last_version=last_version.group()
last_filesize=re.search('s=[0-9]*',parse_string)
if last_filesize==None:
   print "Parse last file size error !"
   sys.exit(1)
last_filesize=last_filesize.group()
print "=======last virus file ========"
print "file ="+last_file
print "version="+last_version[2:]
print "size="+last_filesize[2:]
print "*******************************"
need_update=0
#compare version file and last_file
if os.path.exists(work_dir+"/"+version_file):
   current_file=open(work_dir+"/"+version_file).readlines()
   parse_string=current_file[len(current_file)-1]
  
   current_file=re.search('[a-zA-Z0-9]*.bin',parse_string)        
   if current_file==None:
      print "Parse current file error !"
      sys.exit(1)
   current_file=current_file.group()
   current_version=re.search('t=[0-9][0-9][0-9]',parse_string)
   if current_version==None:
      print "Parse current version error!"
      sys.exit(1)
   current_version=current_version.group()
   current_filesize=re.search('s=[0-9]*',parse_string) 
   if current_filesize==None:
      print "parse current file size error!"
      sys.exit(1)
   current_filesize=current_filesize.group()
   print "=======current file ==========="
   print "file="+current_file
   print "version="+current_version[2:]
   print "size="+current_filesize[2:]

   last_file=open("/tmp/avg6info.ctf").readline()
   current_file=open(work_dir+"/"+version_file).readline()
   if last_file==current_file:
      need_update=0
      commands.getstatusoutput('rm -f '+version_file)
   else:
      need_update=1
else:
   print "avg6info.ctf no exists ,need update!"
   need_update=1

if need_update==1: 
   #get last_file
   print "Download update file............."
   update_url=avg_ftp+virus_data_dir+"/"+last_file
   print update_url
   status_n,status_f=commands.getstatusoutput('wget -O /tmp/'+last_file+' '+update_url)
   if status_n:
      print "can't get last update file!"
      sys.exit(1)
   status_n,status_s=commands.getstatusoutput('rm -f '+work_dir+'/'+current_file)
   status_n,status_s=commands.getstatusoutput('rm -f '+work_dir+'/*.txt')
   status_n,status_s=commands.getstatusoutput('mv -f /tmp/'+last_file+' '+work_dir)

   if status_n:
      print "update bin file fails!"
   else:
      status_n,status_s=commands.getoutput('mv -f /tmp/'+version_file+' '+work_dir)
      if status_n:
          print "update version file fails!"
      else:
          if email_notify :
              notify_message="Subject: "+notify_subject+"\n"+notify_message+"\n version="+last_version[2:]
              server=smtplib.SMTP('localhsot')
              server.sendmail(notify_from,notify_email,notify_message)
              server.quit()
         print "complete update file!"
else:
   print "virus_file is up to date!"

status_s=commands.getoutput('umount /mnt/update_v')


server端下載更新設定
1.每天一次,將程式直接複製到/etc/cron.daily,改變為可以執行chmod +x avg.py
2.注意samba分享的權限,因為使用samba來分享,權限必須可以讀,而client 要寫入電腦名稱.txt
因此要可以寫入
3.每天二次0點10分,6點10分,在/etc/cron.d(因為更新的速度沒有這麼快所以一天一次就好了)
  寫一個檔案symantec
  10 0,6 * * *  root /root/symantec.py
  意義如下:
  分 時 日 月 週  執行者的身份 執行的程式



client 端的處理原則
如何得知client已經更新了,最簡單的方法在server目錄中放置一個檔案依你的機器命名(如:server1.txt),當sever端更新時會 將該類型檔案刪除(*.txt),一旦你執行更新後, 在server都會有一個你的檔案,就可以根據這個檔案來決定是否要更新

寫一個autoit的程式來執行這個動作
avg.au3
if Not FileExists(@ScriptDir&"\"&@computername&".txt") Then
   filedelete("C:\Program Files\Grisoft\AVG6\UPDATE\*.bin")
   filecopy (@ScriptDir&"\*.bin","C:\Program Files\Grisoft\AVG6\UPDATE")
   run("C:\Program Files\Grisoft\AVG6\avgw.exe")
   FileOpen(@ScriptDir&"\"&@computername&".txt",2)
endif
exit
將這個程式編譯成為exe檔
放在病毒碼更新目錄中就可以,因為我是設在/home/samba/vol1/update_v/avg因此就可以放在這,則將這個目錄分享 出去就可以,使用登入的方式或是排程來更新你的病毒碼

登入批次檔設定
加入上述目錄的分享路徑(例如:/home/samba/vol1分享為f:)
例:
f:\update_v\avg\avg.exe

每次登入會檢查在執行avg.exe目錄下是否有你電腦名稱.txt,如果沒有執行更新的動作並在該目放置電腦的名稱.txt,則否就直接離開

如果不是使用登入網域的方式,使用排程程式,選擇"在使用者登入執行"