#!/usr/bin/python

"""
Module smbgold for Inguma
Copyright (c) 2007 Joxean Koret <joxeankoret@yahoo.es>

License is GPL
"""
import sys
import time
import string
from impacket import smb
from lib.libexploit import CIngumaModule

name = "smbgold"
brief_description = "Search for 'gold' in shared SMB directories"
type = "gather"

INTERESTING = ["pass", "priv", "conf", "secr", ".mdb", "id_dsa", "id_rsa"]

class CSmbGold(CIngumaModule):

    target = ""
    waitTime = 0
    timeout = 1
    exploitType = 1
    services = {}
    results = {}
    interactive = True

    def help(self):
        print "target = <target host or network>"
        print
        print "Optional:"
        print "user = <username>"
        print "password = <password>"

    def info(self):
        if not self.smb:
            print "Open a connection first."

        domain = self.smb.get_server_domain()
        lanman = self.smb.get_server_lanman()
        serverName = self.smb.get_server_name()
        serverOs = self.smb.get_server_os()
        serverTime = self.smb.get_server_time()
        sessionKey = self.smb.get_session_key()
        loginRequired = self.smb.is_login_required()

        print "Current connection information"
        print "------------------------------"
        print
        print "Domain name      :", domain
        print "Lanman           :", lanman
        print "Server name      :", serverName
        print "Operative System :", serverOs
        print "Server Time      :", serverTime
        print "Session Key      :", sessionKey
        print
        print "Is login required?", loginRequired

        data = {}
        data["domain"] = domain
        data["lanman"] = lanman
        data["server_name"] = serverName
        data["os"] = serverOs
        data["time"] = (time.time(), serverTime)
        data["key"] = sessionKey
        data["login_required"] = loginRequired

        self.addToDict(self.target + "_os", serverOs)
        self.addToDict(self.target + "_smb", data)

    def run(self):
        # Open the connection
        self.smb = smb.SMB("*SMBSERVER", self.target, self.port)

        if self.user != "" and self.user is not None:
            self.smb.login(self.user, self.password)
        else:
            if self.smb.is_login_required():
                print "Valid credentials *ARE* required for target %s" % self.target
                print 'Use the following syntax prior to rerun the module:\r\n\r\nuser="username"\r\npassword="password"\r\n'
                print
                return False
            else:
                self.smb.login("", "")

        try:
            self.info()
            print
        except:
            print "[!]", sys.exc_info()[1]
            print "You will need a valid account :("

        self.searchGold()

        return True

    def scanDir(self, shareName, dir):
        pwd = "/" + dir + "/*"

        for f in self.smb.list_path(shareName, pwd):
            name = f.get_longname()
            if name == "." or name == "..":
                continue
            else:
                for x in INTERESTING:
                    if name.lower().find(x) > -1:
                        print "  --> Found", name
                        self.addToDict("share_gold_" + shareName, dir + "/" + name)
                
                if f.is_directory():
                    self.scanDir(shareName, dir + "/" + f.get_longname())
                else:
                    continue

    def scanShare(self, shareName):
        print "Scanning share %s..." % shareName
        print
        self.tid = self.smb.tree_connect(shareName)
        pwd = "/"
        for f in self.smb.list_path(shareName, pwd):
            name = f.get_longname()

            if name == "." or name == "..":
                continue
            else:
                for x in INTERESTING:
                    if name.lower().find(x) > -1:
                        print "  --> Found", name
                        self.addToDict("share_gold_" + shareName, name)
                
                if f.is_directory():
                    self.scanDir(shareName, f.get_longname())
                else:
                    continue

        print

    def searchGold(self):
        print "List of remote shares"
        print "---------------------"
        print
        try:
            list = self.smb.list_shared()
        except:
            print "Error:", sys.exc_info()[1]
            print "Invalid credentials?"
            return False

        for share in list:
            if share.get_type() == 0 and not share.get_name().endswith("$"):
                print "Name:", share.get_name()
                print "Comment:", share.get_comment()
                print "Type:", share.get_type()
                print
                self.scanShare(share.get_name())

    def printSummary(self):
        pass
