{"id":41,"date":"2009-03-03T06:15:00","date_gmt":"2009-03-03T06:15:00","guid":{"rendered":"https:\/\/freezion.com\/2009\/03\/03\/asncheck-script\/"},"modified":"2009-03-03T06:15:00","modified_gmt":"2009-03-03T06:15:00","slug":"asncheck-script","status":"publish","type":"post","link":"https:\/\/freezion.com\/?p=41","title":{"rendered":"ASNCheck Script"},"content":{"rendered":"<p>While working on a project today I decided that it would be handy to have a script that could take an AS number (from stdin or from a list of them) and check the health status of it (via things like DNSBL for example), specifically gathering information that could lead one to determine the relative infection\/compromise level.<\/p>\n<p>Ideally, such a script would be able to alternatively take an IP address, determine the AS for it and then report on both the IP provided as well as the overall &#8220;health&#8221; of the AS associated with it.<\/p>\n<p>Well, some of that I managed to whip out tonight, though not all.<\/p>\n<p>I&#8217;ll keep working on this, but I think it&#8217;s useful enough now to warrant posting (I normally do *not* make code public in this raw a state, so take note that there are very likely bugs in this).<\/p>\n<p>That said, here&#8217;s &#8216;asncheck.py&#8217;.<br \/>\nIn its current state, it just returns a list of IP addresses from a given AS which are in the <a href=\"http:\/\/dshield.org\/\">dShield<\/a> current watchlist.<\/p>\n<pre>#! \/usr\/bin\/env python\n# ------------------------------------------------\n# asncheck:\n# retrieves the current dshield watchlist for\n# a given AS, returning just the IP addresses.\n# sample url:\n# https:\/\/secure.dshield.org\/asdetailsascii.html?as=123\n# ------------------------------------------------\n# written by:\n# jason ross (algorythm@gmail.com)\n# ------------------------------------------------\nimport sys\n\ndef main():\n   # here beginneth the script\n   opts = parmsdealer()\n\n   if (opts.verbose == 1):\n      print \"nRetrieving information for AS Number \" + opts.asn + \":n\"\n\n   if (opts.infile):\n      try:\n         filedata = open(opts.infile, 'rU')\n      except IOError:\n         print \"unable to open input file '\" + opts.infile + \"'n\"\n         sys.exit(1)\n      except:\n          print \"Unexpected error:\", sys.exc_info()[0]\n          sys.exit(1)\n      else:\n         for line in filedata:\n            print line\n            asn = line.split(opts.delim, 3)[int(opts.col)]\n\n   if (opts.asn):\n      asn = opts.asn\n\n   dshield(asn, opts.verbose)\n\n   #print '{0}.{1}.{2}.{3}'.format(oct1.zfill(3),oct2.zfill(3),oct3.zfill(3),oct4.zfill(3))\n\n\ndef parmsdealer():\n   import sys\n   from optparse import OptionParser\n   version=\"nasncheck: version 0.1nauthor: jason ross &lt;algorythm@gmail.com&gt;n\"\n   usage=\"nn%prog [OPTIONS]n\"\n   parser = OptionParser(usage=usage, version=version)\n\n   # set up command line arguments\n   parser.set_defaults(col=0)\n   parser.set_defaults(delim=\"|\")\n   parser.set_defaults(verbose=0)\n\n   parser.add_option(\"-v\", \"--verbose\", dest=\"verbose\",\n                     action=\"store_true\", help=\"turn on\/off verbosity (default: off)\")\n   parser.add_option(\"-a\", \"--asn\", dest=\"asn\",\n                     action=\"store\", help=\"specify the AS to retrieve data for (just the number, or with 'AS' prepended)\")\n   parser.add_option(\"-f\", \"--infile\", dest=\"infile\",\n                     action=\"store\", help=\"get the AS from the specified file (can be a list)\")\n   parser.add_option(\"-c\", \"--col\", dest=\"col\",\n                     action=\"store\", help=\"[required with -f] specifies which column in an input file contains the AS (default is to use the first column: '0')\")\n   parser.add_option(\"-d\", \"--delim\", dest=\"delim\",\n                     action=\"store\", help=\"[required with -f] specifies the delimiter to use when parsing the input file (default is to use the ASCII pipe character (0x7c):  '|')\")\n\n   # process command line arguments\n   (options, args) = parser.parse_args()\n\n   # exit if we're missing options\n   if (not options.asn and not options.infile):\n      print \"n\" + sys.argv[0] + \": missing parameter(s)n\"\n      parser.print_help()\n      print \"n\"\n      sys.exit(1)\n\n   # exit if we've got conflicting options\n   if (options.asn and options.infile):\n      print \"n\" + sys.argv[0] + \": can't set both an asn and an input file (there can be only one!)n\"\n      parser.print_help()\n      print \"n\"\n      sys.exit(1)\n\n   return options\n\n\ndef dshield(asn, verbose):\n   import socket\n   import urllib\n   import urllib2\n   import re\n\n   # urllib2 calls socket, so we can set the timeout here\n   timeout = 5\n   socket.setdefaulttimeout(timeout)\n\n   baseuri = 'https:\/\/secure.dshield.org\/asdetailsascii.html'\n\n   params = {}\n   params['as'] = asn\n   encparams = urllib.urlencode(params)\n\n   requri = baseuri + '?' + encparams\n   req = urllib2.Request(requri)\n\n   if (verbose == 1):\n      print \"opening \" + requri + \"n\"\n\n   try:\n      res = urllib2.urlopen(req)\n   except urllib2.URLError, e:\n      if hasattr(e, \"code\"):\n         print \"site borked! HTTP error: \"\n         print e.code\n      elif hasattr(e, \"reason\"):\n         print \"server borked! reason: \"\n         print e.reason\n   else:\n      data = res.readlines()\n#      print data\n      for line in data:\n         if ( re.match(r\"[0-9]\", line) ):\n            ip = line.split()\n            print ip[0]\n\n\nif __name__ == \"__main__\":\n   main()<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>While working on a project today I decided that it would be handy to have a script that could&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[25,42,56],"class_list":["post-41","post","type-post","status-publish","format-standard","hentry","category-tech","tag-ir","tag-net","tag-tools"],"_links":{"self":[{"href":"https:\/\/freezion.com\/index.php?rest_route=\/wp\/v2\/posts\/41","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/freezion.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/freezion.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/freezion.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/freezion.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=41"}],"version-history":[{"count":0,"href":"https:\/\/freezion.com\/index.php?rest_route=\/wp\/v2\/posts\/41\/revisions"}],"wp:attachment":[{"href":"https:\/\/freezion.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=41"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/freezion.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=41"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/freezion.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=41"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}