import argparse, os, re, sys, socket
from subprocess import PIPE, Popen
from urlparse import urlparse

__author__ = 'Caleb Kinney'


def get_args():
    parser = argparse.ArgumentParser(
        description='Recon Scanner')
    parser.add_argument(
        '-i', '--ip', type=str, help='IP Address', required=True)
    parser.add_argument(
        '-d', '--deep', type=str, help='Deep Scan', required=False)

    args = parser.parse_args()
    ip = args.ip
    deep = args.deep

    return ip, deep

ip, deep = get_args()

print("\n")
print("\033[92m")
print("______                     ")
print("| ___ \                    ")
print("| |_/ /___  ___ ___  _ __  ")
print("|    // _ \/ __/ _ \| '_ \ ")
print("| |\ \  __/ (_| (_) | | | |")
print("\_| \_\___|\___\___/|_| |_|")
print(" Version 0.5 - 10-31-2016")

o = urlparse(ip)
ipNoSpace = ip.replace(".", "")
ipNoSpace2 = ipNoSpace.replace(",", "")
ipNoSpace3 = ipNoSpace2.replace("-", "")
ipNoSpace4 = ipNoSpace3.replace("/", "")
if ipNoSpace4.isdigit() == True:
    ip = ip.replace(',',' ')
elif (o.hostname != None):
    o = urlparse(ip)
    ip = (socket.gethostbyname(o.hostname))
    print("\033[1;37m\nHostname: [ %s ]") % (o.hostname)
else:
    sys.exit("\nERROR: Please run recon script with full URL or IP Address. "
        "\nUsage:-i [http://www.example.com] or -i [192.168.0.1] ")

newpath = r'Output/Recon'
ip2 = ip.replace(" ", "")
newpath2 = r'Output/Recon/%s' % ip2
if not os.path.exists(newpath):
    os.makedirs(newpath)
if not os.path.exists(newpath2):
    os.makedirs(newpath2)

print "\033[1;37m\nScanning IP Address(es): [ %s ]" % ip


def cmdline(command):
    process = Popen(
        args=command,
        stdout=PIPE,
        shell=True
    )
    return process.communicate()[0]


def nmapHostDiscover():
    nmapHostScan = ("nmap -sP %s | grep 'Nmap scan report for' | cut -f 5 -d ' ' | awk -vORS=, '{ print $1 }'") % ip
    global openHosts
    openHosts = cmdline(nmapHostScan)
    openHosts = openHosts[:-1]
    global openHostsLst
    openHostsLst = []
    for host in openHosts.split(','):
        openHostsLst.append(host)
    print(("\n\033[1;31mThe \033[92m" + str(len(openHostsLst)) + "\33[1;31m Discovered Host(s) for %s: \033[1;37m" + openHosts) % ip)
    hostsScan(openHostsLst)
    #global ip, ip2
    #ip = ip2

def hostsScan(openHostLst):
    for host in openHostLst:
        print("\n\033[1;31mScanning: \033[1;37m" + host)
        nmapOpenPorts(host)
    for host in openHostLst:
        print("\n\033[1;31mScanning (ALL Ports): \033[1;37m" + host)
        nmapOpenPorts2(host)

def nmapOpenPorts(hosts):
    nmapsSPortScan = ("nmap -sTU --top-ports 1000 %s | grep open | awk -vORS=, '{ print $1 }' | sed 's/,$//' | grep -o '[0-9]*' | awk -vORS=, '{ print $1 }'") % (hosts)
    global openPorts
    print(("\n\033[1;31mRunning command:\033[1;37m nmap -sTU --top-ports 1000 %s") % hosts)
    openPorts = cmdline(nmapsSPortScan)
    openPortsLst = []
    if len(str(openPorts)) >= 1:
        openPorts = openPorts[:-1]
        for port in openPorts.split(','):
            if port not in openPortsLst:
                openPortsLst.append(port)
        print(("\n\033[1;31mThe \033[92m"  + str(len(openPortsLst)) + "\033[1;31m Top1000 open ports for %s are: \033[1;37m" + openPorts) % hosts)
        nmapDeepScan(openPorts, hosts, openPortsLst)
        if deep == 'y':
            nmapPortEnum(openPorts, hosts)
        print(
            "\n\033[92mRecon Script Complete for Top1000 ports " + hosts + "- output saved as /Output/Recon/" + hosts + ".nmap \n\033[1;37m")

def nmapOpenPorts2(hosts):
    nmapsSPortScan = (
                     "nmap -n -PN -sT -sU -p- %s | grep open | awk -vORS=, '{ print $1 }' | sed 's/,$//' | grep -o '[0-9]*' | awk -vORS=, '{ print $1 }'") % (
                     hosts)
    print(("\n\033[1;31mRunning command:\033[1;37m nmap -n -PN -sT -sU -p- %s") % hosts)
    openPorts = cmdline(nmapsSPortScan)
    openPortsLst = []
    if len(str(openPorts)) >= 1:
        openPorts = openPorts[:-1]
        for port in openPorts.split(','):
            if port not in openPortsLst:
                openPortsLst.append(port)
        print(("\n\033[1;31mThe \033[92m" + str(
            len(openPortsLst)) + "\033[1;31m ALL open ports for %s are: \033[1;37m" + openPorts) % hosts)
        nmapDeepScan2(openPorts, hosts, openPortsLst)
    print("\n\033[92mRecon Script Complete for ALL ports " + hosts + "- output saved as /Output/Recon/" + hosts + ".nmap \n\033[1;37m")

def nmapPortEnum(openports, hosts):
    if "445" in openports:
        portCmd = ("nmap --script=smb-enum-shares.nse,smb-os-discovery,smb-enum-users,smb-brute -p 445 " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "_smb_enum.txt")
        print("\n\033[1;31mRunning command: \033[1;37m" + portCmd)
        os.system(portCmd)
        portCmd2 = ("nmap --script=ms-sql-info -p 445 " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "_445_ms-sql_info.txt")
        print("\n\033[1;31mRunning command: \033[1;37m" + portCmd2)
        os.system(portCmd2)
    if "1433" in openports:
        portCmd = ("nmap  --script=ms-sql-info,ms-sql-config,ms-sql-dump-hashes --script-args=mssql.instance-port=1433,smsql.username-sa,mssql.password-sa -p 1433" + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "_ms-sql_info.txt")
        print("\n\033[1;31mRunning command: \033[1;37m" + portCmd)
        os.system(portCmd)
    if "25" in openports:
        portCmd = ("nmap --script=smtp-enum-users.nse -p 25 " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "_smtp-enumusers.txt")
        print("\n\033[1;31mRunning command: \033[1;37m" + portCmd)
        os.system(portCmd)
    snmpPortList = ["161", "162"]
    for port in snmpPortList:
        if port in openports:
            portCmd = ("nmap --script=snmp-netstat,snmp-processes -p " + port + " " + hosts +  " -oN Output/Recon/" + ip + "/" + hosts + "_" + port + "_snmp-enum.txt")
            print("\n\033[1;31mRunning command: \033[1;37m" + portCmd)
            os.system(portCmd)
    ftpPortList = ["21", "22"]
    for port in ftpPortList:
        if port in openports:
            portCmd = ("nmap --script=ftp-anon,ftp-bounce,ftp-libopie,ftp-proftpd-backdoor,ftp-vsftpd-backdoor,ftp-vuln-cve2010-4221 -p " + port + " " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "_" + port + "_ftp-enum.txt")
            print("\n\033[1;31mRunning command: \033[1;37m" + portCmd)
            os.system(portCmd)
    if "25" in openports:
        portCmd = ("nmap --script=smtp-enum-users.nse -p 25 " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "_smtp-enumusers.txt")
        print("\n\033[1;31mRunning command: \033[1;37m" + portCmd)
        os.system(portCmd)
    httpPortLst = ["80", "443", "8080"]
    for port in httpPortLst:
        if port in openports:
            portCmd = ("nikto -C all -h http://" + hosts + ":" + port + "/ > Output/Recon/" + ip + "/" + hosts + "_" + port + "_Nikto.txt")
            print("\n\033[1;31mRunning command: \033[1;37m" + portCmd)
            os.system(portCmd)
            portCmd2 = ("nmap --script=http-vhosts,http-userdir-enum,http-apache-negotiation,http-backup-finder,http-config-backup,http-default-accounts,http-methods,http-method-tamper,http-passwd,http-robots.txt -p " + port + " " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "_" + port + "_httpenum.txt")
            print("\n\033[1;31mRunning command: \033[1;37m" + portCmd2)
            os.system(portCmd2)


def nmapDeepScan(openPorts, hosts, openPortsLst):
    nmapDeepScanCmd = ("nmap -A -T4 " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "Top1000-p" + str(len(openPortsLst)) + " -p " + openPorts)
    print("\n\033[1;31mRunning command: \033[1;37m" + nmapDeepScanCmd)
    os.system(nmapDeepScanCmd)

def nmapDeepScan2(openPorts, hosts, openPortsLst):
    nmapDeepScanCmd = ("nmap -A -T4 " + hosts + " -oN Output/Recon/" + ip + "/" + hosts + "ALL-p" + str(len(openPortsLst)) + " -p " + openPorts)
    print("\n\033[1;31mRunning command: \033[1;37m" + nmapDeepScanCmd)
    os.system(nmapDeepScanCmd)

nmapHostDiscover()
