Eventually I get into producing something I think is useful for others. You'll find random technical knowledge in this Blog so please be patient and use the search function. Some of these software are rather lame and old, the list is ordered by the approximate age (newest first). Unfortunately my older stuff are lost or scattered around my old CDs, not readable anymore 8(.
MuddleFTPD scripting patch - This is a diff patch for muddleftpd to allow running of external scripts upon ftp events such as finished uploads. The patch has a race condition which has not been fixed. The patch was dropped by the muddleftpd team because it executes external commands (why… that's its purpose anyway). Now I recommend you to use proftpd or pure-ftpd instead…
freemail.zip - My old contribution to the web IMAP email gateway scene. Written in an early version of PHP in 2001 and it's still in use somewhere (I won't tell you: use google…).
During migration it's sometimes useful to test a server with many virtual hosts before directing them to their new IP. For this purpose it's necessary to have a proper hosts file on the testing station. The following bash/awk script reads and parses bind9 configuration from an OpenVZ virtualized ROOT directory (can be substituted as /
for non-virtualized environments), then converts zone A records to a suitable hosts file format (IPADDR FQDN). The output can be then copied into /etc/hosts
or C:\WINDOWS\SYSTEM32\DRIVERS\ETC\HOSTS
files respectively.
#!/bin/bash ROOT=/var/lib/vz/root/1000/ bindconf=$ROOT/etc/bind/named.conf OLDIP=1.2.3.4 NEWIP=5.6.7.8 dumpbindconf() { awk -v ROOT=$ROOT ' {rinclude($0)} function rinclude(line,x,a) { sub(/^#/,"",line); # strip leading comments split(line,a,/ /); if ( a[1] ~ /^[ ]*include/ ) { #looking for =include at start of line file=ROOT a[2] gsub(/[\";]/,"",file) print ";------ INCLUDE " file while ( ( getline x < file ) > 0) rinclude(x);. close(a[2])} else {print line} } ' } dumpzones() { awk -v ROOT=$ROOT ' /^[ ]*zone/ {. zone=$2 gsub(/[\";]/,"",zone) } /^[ \t]*file/ { file=$2 gsub(/[\";]/,"",file) file=ROOT file print "; zone file for " zone gethosts(file) } function gethosts(file) { while ( ( getline x < file ) > 0 ) print x; close(file) } ' } dumptohosts() { awk ' /^; zone file for/ {. zone=$5 gsub(/[\";]/,"",zone) #print zone } /^.*@.*IN.*A.*[0-9]+/ { print $4 " " zone } /^[^@]*IN.*A.*[0-9]+/ { print $4 " " $1 "." zone } ' } cat "$bindconf" | dumpbindconf | dumpzones | dumptohosts | grep "$OLDIP" | sed "s/$OLDIP/$NEWIP/g"
This PHP code snippet is userful in removing accents from international (latin), especially hungarian texts.
<?PHP function unaccent($txt) { return strtr(recode("utf8..l1",strtr($txt,"őŐűŰ","oOuU")), "\xe1\xc1\xe0\xc0\xe2\xc2\xe4\xc4\xe3\xc3\xe5\xc5". "\xaa\xe7\xc7\xe9\xc9\xe8\xc8\xea\xca\xeb\xcb\xed". "\xcd\xec\xcc\xee\xce\xef\xcf\xf1\xd1\xf3\xd3\xf2". "\xd2\xf4\xd4\xf6\xd6\xf5\xd5\x8\xd8\xba\xf0\xfa\xda". "\xf9\xd9\xfb\xdb\xfc\xdc\xfd\xdd\xff\xe6\xc6\xdf\xf8"."őŐűŰ", "aAaAaAaAaAaAacCeEeEeEeEiIiIiIiInNo". "OoOoOoOoOoOoouUuUuUuUyYyaAso"."oOuU"); } function doit($dir) { foreach(glob($dir."/*") as $entry) { echo $entry." => ".unaccent($entry)."\n"; rename($entry,unaccent($entry)); if(is_dir($entry)) doit($entry); } } doit("."); ?>
This python script uses snort's database event logs and the whois database to send scheduled e-mails to abuse ISP-s about incidents.
#!/usr/bin/python import sys import os import re import pprint from pyPgSQL import PgSQL from sets import Set import smtplib from email.MIMEText import MIMEText from email.MIMEMultipart import MIMEMultipart _DB=None _DBname="snortdb" _DBuser="snortdb" _DBpass="password" _DBhost="localhost" primaryrecipient="email@add.ress.hu" treshold=5 # minimum no. of events to mail mailhead=""" Hello! This is an automatically generated message from the netpolice robot at MTA SZTAKI Network Security Department. You can reach us at netpolice@sztaki.hu so please DO NOT REPLY to this mail's sending address as your reply will be silently discarded. We are to inform you about several security violations originating from your address space. Please note that our detection system uses an IP packet pattern database so false positives can never be completely eliminated. If you are sure that our warning was pointless please discard this letter, we are sorry for your inconvenience. Your e-mail address has been carefully harvested from the attached whois record. If this message is not for you to concern please tell the responsible person or group to set up an e-mail address beginning with the word 'abuse' and ask your whois administrator to update the record. Our system cannot distinguish between different abuse adresses established for different types of incidents. ---------------------------------------------------------------------- The following activities were detected (you can find more information as the destination port address and other details on the URLs below): %s The activities above were detected from the following source addresses: %s The detailed transcript of the events follows. Note that our system logs the same action from the same source or destination address once per 60 seconds so the actual event rate could be higher. My time zone is CE(S)T (CET with or without daylight saving). See: http://www.timeanddate.com/worldclock/city.html?n=50 ---------------------------------------------------------------------- """ print "snortwarn.py starting ...\n" pp = pprint.PrettyPrinter(indent=4) def int2dquad(int32): a=str((int32 & 0x0ff000000) >> 24) b=str((int32 & 0x000ff0000) >> 16) c=str((int32 & 0x00000ff00) >> 8) d=str((int32 & 0x0000000ff)) return a+"."+b+"."+c+"."+d def db_connect(): global _DB try: _DB = PgSQL.connect(database=_DBname,user=_DBuser,password=_DBpass,host=_DBhost) except PgSQL.Error, msg: print "Connection to database '%s' failed" % dbname print msg, sys.exit() return _DB def db_query(query): global _DB if _DB is None: _DB=db_connect() cur = _DB.cursor() try: cur.execute(query) except PgSQL.Error, msg: print "db_query failed\n%s" % msg, sys.exit() desc={}; i=0 for r in cur.description: desc[i]=r[0] i=i+1 try: cur.arraysize=1000; res = cur.fetchall() except StandardError, msg: print "db_query: fetch of all instanaces failed\n%s" % msg, sys.exit() result={} i=0 for r in res: u=0 result[i]={} for d in desc.values(): result[i][d] = r[u] u=u+1 i=i+1 cur.close() _DB.commit() return result print "fetching alerts from database ..." res=db_query(""" select event.\"timestamp\",signature.sig_name,signature.sig_sid,iphdr.ip_src,iphdr.ip_dst from event,signature,iphdr where iphdr.ip_ttl>0 and iphdr.cid=event.cid and signature.sig_id=event.signature and event.\"timestamp\"> timestamp 'now' - interval '24 hours' and signature in ( select s.sig_id from signature s,sig_class c where s.sig_class_id=c.sig_class_id and c.sig_class_name in ( 'web-application-attack','attempted-admin','misc-attack','denial-of-service','attempted-dos' ) ) """) # order by timestamp print "got " + str(len(res)) + " events ..." # group by ip ips={} for r in res.values(): src=int2dquad(r['ip_src']) if not ips.has_key(src): ips[src]={'count':0, 'alerts': Set(), 'events':{}} ips[src]['count']+=1 ips[src]['events'][r['timestamp']]=r ips[src]['alerts']|=Set([str(r['sig_sid'])+"|"+r['sig_name']]) #pp.pprint(ips) # fetch whois for each ip for r in ips: if ips[r]['count']<3: # drop low noise ips print "dropping "+r+" (bellow alarm treshold)..." ips[r]=None continue print "collecting whois data for "+r+" ..." whois='' whoisp=os.popen("jwhois "+r) whois+=whoisp.read(1024000); whoisp.close(); # whoisp=os.popen("jwhois +"+r) # whois+=whoisp.read(1024000); # whoisp.close(); e=None mailregex="[0-9a-z_.-]*@[0-9a-z_.-]+[.][a-z]+" s=Set() s|=Set(re.compile('(?ims)([0-9a-z_.-]*abuse'+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)abuse.*?('+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)incident.*?('+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)spam.*?('+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)role.*?('+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)person.*?('+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)route.*?('+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)notify.*?('+mailregex+')').findall(whois)) if len(s) == 0: s|=Set(re.compile('(?ims)('+mailregex+')').findall(whois)) if len(s) > 0: e=list(s) # loopback or private ips: no notify if len(re.compile('(?ims)(127[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}|172[.]16[.][0-9]{1,3}[.][0-9]{1,3}|192[.]168[.][0-9]{1,3}[.][0-9]{1,3})').findall(r))>0: print " loopback or private ip " + str(r); # e=[primaryrecipient] e=["mcree@sztaki.hu"] # do not notify ripe or arin technical addresses and our own address if len(re.compile('(?ims)(@ripe.net|@arin.net|@arpnic.net|@nic[.])').findall(str(e)))>0: print " dropping whois technical mail address " + str(e); # e=[primaryrecipient] e=["mcree@sztaki.hu"] # local address if len(re.compile('(?ims)(@sztaki.hu)').findall(str(e)))>0: print " dropping whois technical mail address " + str(e); # e=[primaryrecipient] e=["mcree@sztaki.hu", "btoth@sztaki.hu"] ips[r]['whois']=whois if e is not None: ips[r]['email']=e else: ips[r]['email']=None print " WARNING: no mail address found!" #pp.pprint(ips) # group by emails emails={} for r in ips: if ips[r] is not None: e=ips[r]['email'] if e is not None: if not emails.has_key(str(e)): emails[str(e)]={'count':0, 'alerts':Set(), 'whois':ips[r]['whois'], 'ips':[], 'email':e} emails[str(e)]['ips']+=[r] emails[str(e)]['count']+=ips[r]['count'] emails[str(e)]['alerts']|=ips[r]['alerts'] #pp.pprint(emails) #pp.pprint(ips) for e in emails: if emails[e]['count']>=treshold: print "sending mail to "+e attsum="" for a in emails[e]['alerts']: (sid,desc)=a.split('|') attsum+=desc+"\n" attsum+=" -> http://www.snort.org/snort-db/sid.html?sid="+sid+"\n" ipseach="" ipsuml=[] for i in emails[e]['ips']: ipseach+=i+" ("+str(ips[i]['count'])+" event(s))\n" for a in ips[i]['alerts']: (sid,desc)=a.split('|') ipseach+=" "+desc+"\n" for v in ips[i]['events'].values(): ipsuml+=[str(v['timestamp'])+' '+int2dquad(v['ip_src'])+" -> "+int2dquad(v['ip_dst'])+' '+v['sig_name']+"\n"] ipseach+="" ipsuml.sort() if(len(ipsuml)>100): ipsuml=ipsuml[0:99] ipsum="" ipsum=ipsum.join(ipsuml) ipsum="Transcript follows (limited to 100 records):\n\n"+ipsum+"\n----------------------------------------------------------------------\n\n" #print mailhead % (attsum, ipseach) #print ipsum commaspace=', ' msg=MIMEMultipart() msg['Subject']="Security Notification" msg['From']="devnull@sztaki.hu" msg['To']=commaspace.join([primaryrecipient] + emails[e]['email']) msg.attach(MIMEText((mailhead % (attsum, ipseach)) + ipsum)) # msg.attach(MIMEText(ipsum)) msg.attach(MIMEText("Whois query result follows:\n\n"+emails[e]['whois'])) msg.preamble = 'You should view this message MIME-aware mail reader.\n' msg.epilogue = '' s = smtplib.SMTP() s.connect() for recip in ([primaryrecipient] + emails[e]['email']): # print "sending mail to " + str(recip) s.sendmail("devnull@sztaki.hu", recip, msg.as_string()) s.close() #print msg.as_string()
<< Newer entries | Older entries >>