自動更新病毒碼(symantec)
作者:csc@ocean-pioneer.com
上次更新日期:2004/03/31
最後更新日期:2004/09/1(變動兩行)

參考http://nau.sourceforge.net/
根據上述網站,因為覺得太複雜了,因此本人自己寫了一個小程式,可以在linux下自動比對病毒碼共下載最新,檢查md5如果成功寫入分享目錄中,及 client端windows的程式symantec.zip幫你自動更新 client端的病毒碼

以下是一些程式的基本問題
  1. 病毒碼的資訊在那:http://securityresponse.symantec.com/avcenter/download/pages/US-N95.html
  2. 你的病毒碼的資訊在那,可以先前將每一次下載保留其檔案的版本資訊在下來用來比對
    20040310-005-i32.exe (20040310的更新檔)
    年月日-vvv-i32.exe (vvv為版本可以多個,001,002....)
  3. 下載US-N95.html
    並尋找文字i32.exe ,你將會得到要下載的檔案的那一列,則內含有一個href="   ",這是我們要下載的更新程式,至於md5的碼在網頁中包含了許多個,但是第一個就是我們要的
  4. 使用python語言來寫
  5. 其它的軟體工具linux(wget,md5sum,grep),windows(autoit)
實作
  1. 使用wget -O /tmp/US-N95.html http://securityresponse.symantec.com/avcenter/download/pages/US-N95.html
  2. 使用python模組re
      s=open("/tmp/US-N95.html").read()
      re.search('[0-9]*-[0-9]*-i32.exe',s) -找20040315-005-i32.exe
      re.search('<a href="http://[a-z0-9/-]*">',s -找檔案的路徑<a href="http://././20040315-005-i32.exe">
      re.search('MD5[< ][/ :0-9A-Za-z>]*',s)
       -找 md5檢查碼
  3. 下載回來的更新程式使用固定名稱nav_db.exe
  4. 伺服器端:下載及更新病毒碼
    可以下載比對病毒碼,並檢查md5是否正確
    將本程式放在cron.daily,並自己修改work_dir參 數,這是你放置病毒碼所在
    則每天會去symantec的網站檢查是否更新如果更新則下載到work_dir並 更改檔名為nav_db.exe
  5. 因應別人要求email 通知,使用類別smtplib
    server=smtplib.SMTP('localhsot')
    server.sendmail("寄件者","收件者","內容") -如果需要主旨請加在內容"Subject: 文字 \n其它內容"
    server.quit()
  6. 使用外部郵件,加入下面程式碼:
    import smtplib
    email_notif=1
    email_msg="/homesamba/vol1/abc.eml"
    email_from="aa@xxx.com.tw"
    email_to="bb@xxx.com.tw"

    下載成功處
    if email_notify:
       msg=open(email_msg).read()
       server.smtplib.SMTP('localhost')
       server.sendmail(email_from.email_to,msg)
       server.quit()
symantec.py
#!/usr/bin/python
import re,string,commands,sys,string,os.path
import smtplib
from time import localtime,time,strftime

work_dir='/home/samba/vol1/update_v/symantec'
version_file='sym_version.log'

#symantec web site
symantec_url="http://securityresponse.symantec.com"

#virus code data
virus_data_url='/avcenter/download/pages/US-N95.html'



#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="Symantec update virus at "+notify_time
notify_subject='Update Symantec notify'



print "Download virus data file....."
print symantec_url+virus_data_url
status_n,status_s=commands.getstatusoutput('wget --tries=3 --timeout=30 --wait=15 -O /tmp/US-N95.html '+symantec_url+virus_data_url)
if status_n:
    print "Download virus data url error!"
    sys.exit(1)
 
source_file=open("/tmp/US-N95.html").read()
#get last_file
last_file=re.search('[0-9]*-[0-9]*-i32.exe',source_file)
if last_file==None:
   print "Parse error ! Couldn't found last_file in US-N95.html"
   sys.exit(1)
last_file=last_file.group()
######################
#get last_file url
######################
#last_file_url=re.search('<a href="/[a-z0-9:/.-]*">',source_file)
last_file_url=re.search('<a href="http://[a-z0-9/.-]*i32.exe">',source_file)
if last_file_url==None:
   print "Parse error ! Couldn't found last_file_url in US-N95.html"
   sys.exit(1)

last_file_url=last_file_url.group()
last_file_url=string.split(last_file_url,'"')[1]

###################
#get last_file md5
###################
last_file_md5=re.search('MD5[< ][/ :0-9A-Za-z>]*',source_file)
if last_file_md5==None:
   print "Parse error ! Couldn't found last_file_md5 in US-N95.html"
   sys.exit(1)

last_file_md5=last_file_md5.group()
last_file_md5=string.strip(string.split(last_file_md5,':')[1])


need_update=0
#compare version file and last_file
if os.path.exists(work_dir+"/"+version_file):
   version_f=open(work_dir+"/"+version_file,"r+")
   t_line=version_f.readline()
   if last_file>t_line:
      need_update=1
      version_f.seek(0)
else:
   version_f=open(work_dir+"/"+version_file,"w")
   need_update=1
   

if need_update:
   print "Download update file!"
   #update_url=symantec_url+last_file_url
   update_url=last_file_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()
     
   #check md5
   status_s=commands.getoutput('md5sum '+'/tmp/'+last_file)
   md5_string=string.split(status_s," ")[0]
   md5_string=string.upper(string.strip(md5_string))
   if md5_string==last_file_md5:
      print "The md5 checksum is match !"
   else:
      print "The md5 Checksum is dismatch!"
      print "Download file:"+md5_string
      print "Web site     :"+last_file_md5
      sys.exit(1)   
   print "Install the update file....."
   status_n,status_s=commands.getstatusoutput('mv -f /tmp/'+last_file+' '+work_dir+'/nav_db.exe')
   if status_n:
      print "update file fails!"
   else:
      status_s=commands.getoutput('rm -rf '+work_dir+"/*.txt")
      if email_notify :
         notify_message="Subject: "+notify_subject+"\n"+notify_message+"\n version="+last_file
         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!"
if need_update==1:  
   version_f.write(last_file)
   version_f.close()



server端下載更新設定
1.每天一次,將程式直接複製到/etc/cron.daily,改變為可以執行chmod +x symantec.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的程式來執行這個動作
symantec.au3
if Not FileExists(@ScriptDir&"\"&@computername&".txt") Then
   run(@ScriptDir&"\nav_db.exe")
   winwait("SARC Intelligent Updater","",20)
   send("y")
   winwaitactive("SARC","確定")
   Send("{Enter}")
   FileOpen(@ScriptDir&"\"&@computername&".txt",2)
endif
exit 
將這個程式編譯成為exe檔
放在病毒碼更新目錄中就可以,因為我是設在/home/samba/vol1/update_v/symantec因此就可以放在這,則將這個目錄分享 出去就可以,使用登入的方式或是排程來更新你的病毒碼

登入批次檔
加入上述目錄的路徑,就會自動更新了
例:
f:\update_v\symantec\symantec.exe

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

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



後記:
我碰到幾個問題
  1. symantec網站好像不是很穩定,可連線的時間好像有固定的時間,其中下午12-5點左右好像不是很容易連線成功,因此建議一天至少檢查 更新兩次
  2. 我在winodws寫python程式,在第一行加入#!/usr/python然後在linux執行上會有問題,:bad interpreter: No such file or directory,千尋不到我要的答案,一想會不會是檔案格式的問題,使用dos2unix -o 檔案,再執行chmod +x 檔案,這個錯誤訊息就不見了
  3. 在windows端如果使用登入的方式在登入批次檔,不要加入cd相關指令否則登入會hold在登入視窗