diff options
87 files changed, 1639 insertions, 211 deletions
| diff --git a/.gitmodules b/.gitmodules index 2823cad5..b51a2b2e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,12 @@  [submodule "submodules/github/jbalogh/python-irclib"]  	path = submodules/github/jbalogh/python-irclib  	url = https://github.com/jbalogh/python-irclib.git +[submodule "Reaktor/repos/gxfr"] +	path = Reaktor/repos/gxfr +	url = https://github.com/makefu/gxfr.git +[submodule "Reaktor/repos/dnsrecon"] +	path = Reaktor/repos/dnsrecon +	url = https://github.com/makefu/dnsrecon.git +[submodule "Reaktor/repos/whatweb"] +	path = Reaktor/repos/whatweb +	url = https://github.com/urbanadventurer/WhatWeb.git diff --git a/Monitoring/plugins/notify_irc b/Monitoring/plugins/notify_irc new file mode 100755 index 00000000..e1de0866 --- /dev/null +++ b/Monitoring/plugins/notify_irc @@ -0,0 +1,87 @@ +#! /usr/bin/env python +# +# Example program using irclib.py. +# +# This program is free without restrictions; do anything you like with +# it. +# +# Joel Rosdahl <joel@rosdahl.net> + +import irclib +import sys +#irclib.DEBUG= True +class IRCCat(irclib.SimpleIRCClient): +    def __init__(self, target,msg=""): +        irclib.SimpleIRCClient.__init__(self) +        self.target = target +        self.msg = msg + +    def on_welcome(self, connection, event): +        if irclib.is_channel(self.target): +            connection.join(self.target) +        else: +            self.send_it() + +    def on_join(self, connection, event): +        self.send_it() + +    def on_disconnect(self, connection, event): +        sys.exit(0) + +    def send_it(self): +        if self.msg: +            print "writing given argv privmsg",self.msg +            self.connection.privmsg(self.target, self.msg) +        else: +            print "writing stdin privmsg:" +            while 1: +                line = sys.stdin.readline() +                if not line: +                    break +                print line +                self.connection.privmsg(self.target, line) +        self.connection.quit("Using irclib.py") +def findGreatNick(prefix='shinken'): +    import random +    import re +    dic="/usr/share/dict/danish" +    found=False +    while not found: +      w = random.choice(list(open(dic))) +      found = re.match(r"^[a-zA-Z_-]+$",w) +    return  prefix +"|"+w.strip() + +def main(): +    if len(sys.argv) < 3: +        print "Usage: notify_irc <server[:port]> <target> [message]" +        print "\ntarget is a nickname or a channel." +        sys.exit(1) + +    s = sys.argv[1].split(":", 1) +    server = s[0] +    if len(s) == 2: +        try: +            port = int(s[1]) +        except ValueError: +            print "Error: Erroneous port." +            sys.exit(1) +    else: +        port = 6667 +    import random +    nickname = findGreatNick() +    print nickname +    target = sys.argv[2] +    msg = "" +    if len(sys.argv) == 4: +      msg = sys.argv[3] +    c = IRCCat(target,msg) +    try: +        print "trying to connect to ",server,port,nickname +        c.connect(server, port, nickname ) +    except irclib.ServerConnectionError, x: +        print x +        sys.exit(1) +    c.start() + +if __name__ == "__main__": +    main() diff --git a/Reaktor/IRC/asybot.py b/Reaktor/IRC/asybot.py index 657cee40..df758ed6 100755 --- a/Reaktor/IRC/asybot.py +++ b/Reaktor/IRC/asybot.py @@ -9,12 +9,14 @@ def is_executable(x):  from asynchat import async_chat as asychat  from asyncore import loop -from socket import AF_INET, SOCK_STREAM +from socket import AF_INET, SOCK_STREAM,gethostname  from signal import SIGALRM, signal, alarm  from datetime import datetime as date, timedelta +import shlex +from time import sleep  from sys import exit  from re import split, search - +from textwrap import TextWrapper  import logging,logging.handlers  log = logging.getLogger('asybot')  hdlr = logging.handlers.SysLogHandler(facility=logging.handlers.SysLogHandler.LOG_DAEMON) @@ -37,6 +39,7 @@ class asybot(asychat):      self.set_terminator('\r\n')      self.create_socket(AF_INET, SOCK_STREAM)      self.connect((self.server, self.port)) +    self.wrapper = TextWrapper(subsequent_indent=" ",width=400)      # When we don't receive data for alarm_timeout seconds then issue a      # PING every hammer_interval seconds until kill_timeout seconds have @@ -105,8 +108,10 @@ class asybot(asychat):    def on_privmsg(self, prefix, command, params, rest):      def PRIVMSG(text): -      msg = 'PRIVMSG %s :%s' % (','.join(params), text) -      self.push(msg) +      for line in self.wrapper.wrap(text): +        msg = 'PRIVMSG %s :%s' % (','.join(params), line) +        self.push(msg) +        sleep(1)      def ME(text):        PRIVMSG('ACTION ' + text + '') @@ -125,7 +130,7 @@ class asybot(asychat):        from os.path import realpath, dirname, join        from subprocess import Popen as popen, PIPE - +      from time import time        Reaktor_dir = dirname(realpath(dirname(__file__)))        public_commands = join(Reaktor_dir, 'public_commands')        command = join(public_commands, _command) @@ -133,29 +138,28 @@ class asybot(asychat):        if is_executable(command):          env = {} +        args = [] +        start = time()          if _argument != None:            env['argument'] = _argument - +          args = shlex.split(_argument)          try: -          p = popen([command], stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env) +          p = popen([command] + args,bufsize=1, stdout=PIPE, stderr=PIPE, env=env)          except OSError, error:            ME('brain damaged')            log.error('OSError@%s: %s' % (command, error))            return - -        stdout, stderr = [ x[:len(x)-1] for x in -            [ x.split('\n') for x in p.communicate()]] -        code = p.returncode          pid = p.pid +        for line in iter(p.stdout.readline,""): +          PRIVMSG(line) +          log.debug('%s stdout: %s' % (pid, line))  +        p.wait() +        elapsed = time() - start +        code = p.returncode +        log.info('command: %s -> %s in %d seconds' % (command, code,elapsed)) +        [log.debug('%s stderr: %s' % (pid, x)) for x in p.stderr.readlines()] -        log.info('command: %s -> %s' % (command, code)) -        [log.debug('%s stdout: %s' % (pid, x)) for x in stdout] -        [log.debug('%s stderr: %s' % (pid, x)) for x in stderr] - -        if code == 0: -          [PRIVMSG(x) for x in stdout] -          [PRIVMSG(x) for x in stderr] -        else: +        if code != 0:            ME('mimimi')        else: @@ -181,8 +185,12 @@ if __name__ == "__main__":    lol = logging.DEBUG if env.get('debug',False) else logging.INFO    logging.basicConfig(level=lol) -  name = getconf1('Name', '/etc/tinc/retiolum/tinc.conf') -  hostname = '%s.retiolum' % name +  try:  +    name = getconf1('Name', '/etc/tinc/retiolum/tinc.conf') +    hostname = '%s.retiolum' % name +  except: +    name = gethostname() +    hostname = name    nick = str(env.get('nick', name))    host = str(env.get('host', 'supernode'))    port = int(env.get('port', 6667)) diff --git a/Reaktor/IRC/index b/Reaktor/IRC/index index 24982c76..50022ec9 100755 --- a/Reaktor/IRC/index +++ b/Reaktor/IRC/index @@ -3,5 +3,4 @@ set -xeuf  # cd //Reaktor  cd $(dirname $(readlink -f $0))/.. - -exec python IRC/asybot.py "$@" +host=irc.freenode.net target='#krebsco' python IRC/asybot.py "$@" diff --git a/Reaktor/Makefile b/Reaktor/Makefile new file mode 100644 index 00000000..2241dba6 --- /dev/null +++ b/Reaktor/Makefile @@ -0,0 +1,23 @@ +submodules = gxfr dnsrecon bxfr whatweb +security_modules = subdomains revip whatweb + +all: init all-mods + +init: init-submodules $(submodules) +init-submodules:  +	cd ..;git submodule init; git submodule update +$(submodules): +	cd repos/$@ ; git checkout master;git pull + +all-mods: $(addprefix public_commands/,$(security_modules)) +public_commands/%:commands/% +	ln -s ../$< $@ + +debian-autostart: +	useradd reaktor ||: +	cp startup/init.d/reaktor-debian /etc/init.d/reaktor +	cp startup/conf.d/reaktor /etc/default/ +	update-rc.d reaktor defaults +supervisor-autostart: +	useradd reaktor ||: +	cp startup/supervisor/Reaktor.conf /etc/supervisor/conf.d/ diff --git a/Reaktor/commands/revip b/Reaktor/commands/revip new file mode 120000 index 00000000..e2c3b7ab --- /dev/null +++ b/Reaktor/commands/revip @@ -0,0 +1 @@ +../repos/revip/revip
\ No newline at end of file diff --git a/Reaktor/commands/subdomains b/Reaktor/commands/subdomains new file mode 120000 index 00000000..0489555f --- /dev/null +++ b/Reaktor/commands/subdomains @@ -0,0 +1 @@ +../repos/consolidate_dns/index
\ No newline at end of file diff --git a/Reaktor/commands/whatweb b/Reaktor/commands/whatweb new file mode 100755 index 00000000..84130d5c --- /dev/null +++ b/Reaktor/commands/whatweb @@ -0,0 +1,7 @@ +#!/bin/sh +#wrapper for WhatWeb +here=$(dirname `readlink -f $0`) +whatweb_bin="$here/../repos/whatweb/whatweb" +[ -e "$whatweb_bin" ] || ( echo "!! Whatweb app does not exist" && exit 1 ) +[ "balls$1" = "balls" ] && ( echo "!! no host given" && exit 1) +exec $whatweb_bin -a 3 "$1" diff --git a/Reaktor/repos/bxfr/bxfr.py b/Reaktor/repos/bxfr/bxfr.py new file mode 100644 index 00000000..8e6bd101 --- /dev/null +++ b/Reaktor/repos/bxfr/bxfr.py @@ -0,0 +1,238 @@ +#!/usr/bin/python -tt + +# gxfr replicates dns zone transfers by enumerating subdomains using advanced search engine queries and conducting dns lookups. +# By Tim Tomes (LaNMaSteR53) +# Available for download at http://LaNMaSteR53.com or http://code.google.com/p/gxfr/ + +import sys, os.path, urllib, urllib2, re, time, socket, random, socket + + +def help(): +  print """  Syntax: ./gxfr.py domain [options] +   +  -h, --help               this screen +  -v                       enable verbose mode +  -t [num of seconds]      set number of seconds to wait between queries (default=15) +  -q [max num of queries]  restrict to maximum number of queries (default=0, indefinite) +  --dns-lookup             enable dns lookups of all subdomains +  --proxy [file|ip:port|-] use a proxy or list of open proxies to send queries (@random w/list) +                             - [file] must consist of 1 or more ip:port pairs +                             - replace filename with '-' (dash) to accept stdin +  --user-agent ['string']  set custom user-agent string +  --timeout [seconds]      set socket timeout (default=system default) +  --csv [file] +   +  Examples:  +  $ ./gxfr.py foxnews.com --dns-lookup -v +  $ ./gxfr.py foxnews.com --dns-lookup --proxy open_proxies.txt --timeout 10 +  $ ./gxfr.py foxnews.com --dns-lookup -t 5 -q 5 -v --proxy 127.0.0.1:8080 +  $ curl http://rmccurdy.com/scripts/proxy/good.txt | ./gxfr.py website.com -v -t 3 --proxy - +  """ +  sys.exit(2) + +if len(sys.argv) < 2: +  help() + +if '-h' in sys.argv or '--help' in sys.argv: +  help() + +# declare vars and process arguments +#http://www.bing.com/search?q=site%3agoogle.de&qs=n&filt=all&pq=site%3agoogle.d&sc=8-5&sp=-1&sk=&first=1&FORM=PORE +query_cnt = 0 +csvname = False +domain = sys.argv[1] +sys.argv = sys.argv[2:] +lookup = False +encrypt = True +base_url = 'http://www.bing.com' +base_uri = '/search?qs=n&form=QBRE&sc=0-0&sp=-1&sk=' +base_query = 'site:' + domain +pattern = '//([\.\w-]*)\.%s.+?' % (domain) +proxy = False +user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; FDM; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 1.1.4322)' +verbose = False +secs = 15 +max_queries = 10 # default = 10 queries +# process command line arguments +if len(sys.argv) > 0: +  if '--dns-lookup' in sys.argv: +    lookup = True +  if '--csv' in sys.argv: +    csvname = sys.argv[sys.argv.index('--csv') + 1] +  if '--proxy' in sys.argv: +    proxy = True +    filename = sys.argv[sys.argv.index('--proxy') + 1] +    if filename == '-': +      proxies = sys.stdin.read().split()      +    elif os.path.exists(filename): +      content = open(filename).read() +      proxies = re.findall('\d+\.\d+\.\d+\.\d+:\d+', content) +    elif re.match(r'^\d+\.\d+\.\d+\.\d+:\d+$', filename): +      proxies = [filename] +    else: +      help() +  if '--timeout' in sys.argv: +    timeout = int(sys.argv[sys.argv.index('--timeout') + 1]) +    socket.setdefaulttimeout(timeout) +  if '--user-agent' in sys.argv: +    user_agent = sys.argv[sys.argv.index('--user-agent') + 1]   +  if '-v' in sys.argv: +    verbose = True +  if '-t' in sys.argv: +    secs = int(sys.argv[sys.argv.index('-t') + 1]) +  if '-q' in sys.argv: +    max_queries = int(sys.argv[sys.argv.index('-q') + 1]) +subs = [] +new = True +page = 0 + +# --begin-- +print '[-] domain:', domain +print '[-] user-agent:', user_agent +# execute search engine queries and scrape results storing subdomains in a list +print '[-] querying search engine, please wait...' +# loop until no new subdomains are found +while new == True: +  try: +    query = '' +    # build query based on results of previous results +    for sub in subs: +      query += ' -site:%s.%s' % (sub, domain) +    full_query = base_query + query +    start_param = '&first=%s' % (str(page*10)) +    query_param = '&q=%s&pq=%s' % (urllib.quote_plus(full_query),urllib.quote_plus(full_query)) +    if len(base_uri) + len(query_param) + len(start_param) < 2048: +      last_query_param = query_param +      params = query_param + start_param +    else: +      params = last_query_param[:2047-len(start_param)-len(base_uri)] + start_param +    full_url = base_url + base_uri + params +    # note: query character limit is passive in mobile, but seems to be ~794 +    # note: query character limit seems to be 852 for desktop queries +    # note: typical URI max length is 2048 (starts after top level domain) +    if verbose: print '[+] using query: %s...' % (full_url) +    # build web request and su | 
