__author__ = 'root'
import network
from libnmap.process import NmapProcess
from libnmap.parser import NmapParser, NmapParserException
from ftplib import FTP
import pxssh
import telnetlib
from smtplib import SMTP_SSL as SMTP
from email import MIMEText
from imaplib import IMAP4, IMAP4_SSL


class network_pentest(object):
    def __init__(self, iface, timeout=300, ftp_login=False, ssh_login=False, telnet_login=False, smtp_login=False,
                 pop_login=False, imap_login=False, ldap_login=False, smb_login=False, rlogin_login=False,
                 mssql_login=False, mysql_login=False, pgsql_login=False, vnc_login=False, snmp_login=False):
        self.iface = iface
        self.timeout = timeout
        self.ftp_login = ftp_login
        self.ssh_login = ssh_login
        self.telnet_login = telnet_login
        self.smtp_login = smtp_login
        self.pop_login = pop_login
        self.imap_login = imap_login
        self.ldap_login = ldap_login
        self.smb_login = smb_login
        self.rlogin_login = rlogin_login
        self.mssql_login = mssql_login
        self.mysql_login = mysql_login
        self.pgsql_login = pgsql_login
        self.vnc_login = vnc_login
        self.snmp_login = snmp_login
        self.network_host_list = network.network_host_ip('eth0')
        self.my_ip = network.get_ip_address('eht0')
        self.user = []
        self.password = []
        self.idx = len(self.user)
        self.return_result = "["

    def run(self):
        for ip in self.network_host_list:
            port_l, proto_l, state_l, service_l = self.port_scan(ip)
            for idx, port in enumerate(port_l):
                if self.ftp_login and port == '21':
                    id, pw = self.ftp_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.ssh_login and port == '22':
                    id, pw = self.ssh_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.telnet_login and port == '23':
                    id, pw = self.telnet_login(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.smtp_login and port == '25':
                    id, pw = self.smtp_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.pop_login and port == '110':
                    id, pw = self.pop_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.imap_login and (port == '143' or port == '993'):
                    id, pw = self.imap_connect(ip, port)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.ldap_login and port == '389':
                    id, pw = self.ldap_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.smb_login and port == '445':
                    id, pw = self.smb_connect(ip, port)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.rlogin_login and port == '513':
                    id, pw = self.rlogin_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.mssql_login and port == '1433':
                    id, pw = self.mssql_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.mysql_login and port == '3306':
                    id, pw = self.mysql_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                elif self.pgsql_login and port == '5432':
                    id, pw = self.pgsql_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                if self.vnc_login and port == '5900':
                    id, pw = self.vnc_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
                if self.snmp_login and port == '161':
                    id, pw = self.snmp_connect(ip)
                    self.return_result += "{ip_addr: " + ip + ", service: " + service_l[idx] + ", id: " + id + \
                                          ", password: " + pw + "}, "
            self.return_result += self.return_result[:-2] + "]"
    def port_scan(self, ip):
        process = NmapProcess(targets=ip, options="-sT", event_callback=None, safe_mode=None, fqp=None)
        rc = process.run()
        index = 0
        port = []
        proto = []
        state = []
        service = []
        if rc != 0:
            return False
        try:
            parser = NmapParser.parse(process.stdout)
        except NmapParserException:
            print("Exception Network Error")
        for host in parser.hosts:
            for serv in host.services:
                port.append(serv.port)
                proto.append(serv.protocol)
                state.append(serv.state)
                service.append(serv.service)
                index += 1
        return port, proto, state, service

    def ftp_connect(self, host):
        try:
            fp = FTP(host)
            idx = 0
            while int(self.idx) > idx:
                try:
                    fp.login(self.user[idx], self.password[idx])
                    fp.retrlines('LIST')
                    fp.quit()
                    return self.user[idx], self.password[idx]
                except:
                    pass
                idx += 1
        except:
            return False

    def ssh_connect(self, host):
        ssh = pxssh.pxssh()
        idx = 0
        while int(self.idx) > idx:
            try:
                ssh.login(host, self.user[idx], self.password[idx])
                ssh.sendline('uptime')
                return self.user[idx], self.password[idx]
            except pxssh.ExceptionPxssh:
                pass
            idx += 1
        return False

    def telnet_connect(self, host):
        tn = telnetlib.Telnet(host)
        idx = 0
        try:
            tn.read_until(b"login: ")
        except EOFError:
            return False
        idx = 0
        while int(self.idx) > idx:
            try:
                tn.write(self.user[idx])
                tn.write(self.password[idx])
                (i, obj, byt) = tn.expect([b'incorrect', b'@'], 2)
                if i == 1:
                    return self.user[idx], self.password[idx]
            except:
                pass
            idx += 1
        return False

    def smtp_connect(self, host):
        msg = MIMEText('test', 'test')
        msg['Subject'] = 'Atear_SMTP_Login'
        msg['From'] = 'Atear@open.com'
        idx = 0
        while int(self.idx) > idx:
            try:
                conn = SMTP(host)
                conn.debuglevel(False)
                conn.login(self.user[idx], self.password[idx])
                conn.sendmail()
                return self.user[idx], self.psasword[idx]
            except:
                pass
            idx += 1
        return False

    def imap_connect(self, host, port):
        if port == '993':
            klass = IMAP4_SSL
        else:
            klass = IMAP4
        fp = klass(host, port)
        resp = fp.welcome
        idx = 0
        while self.idx < idx:
            try:
                fp.login(self.user[idx], self.password[idx])
                return self.user[idx], self.password[idx]
            except:
                pass
            idx += 1
        return False

    def ldap_connect(self, host):
        return False

    def smb_connect(self, host, port):
        from impacket.smbconnection import SMBConnection
        idx = 0
        while self.idx < idx:
            try:
                fp = SMBConnection(self.user[idx], self.password[idx],
                                    self.my_ip, host,
                                    use_ntlm_v2=True)
            except:
                return False
        return False

    def rlogin_connect(self, host):
        return False

    def mssql_connect(self, host):
        return False

    def mysql_connect(self, host):
        return False

    def pgsql_connect(self, host):
        return False

    def vnc_connect(self, host):
        return False

    def snmp_connect(self, host):
        return False

    def get_values(self):
        return self.return_result