【白帽故事】打造一款多线程目录爆破扫描器

admin 2022年3月4日18:18:17评论73 views字数 4278阅读14分15秒阅读模式

声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。


背景介绍:


今天的分享来自国外一位ID为Mayank Pandey的白帽子,他分享了使用Python多线程功能打造的一款多线程网站目录爆破扫描器。废话不多说,上代码(代码很少,100行不到):


from threading import Threadimport time,requests,sys,os.path
def usage(): print("----------USAGE INSTRUCTION ---------") print(f"{sys.argv[0]} URL WORDLIST NUMBER_OF_THREADS(Default is 10)n") sys.exit()
def prepare(myList,numOfChunks): for i in range(0, len(myList), numOfChunks): yield myList[i:i + numOfChunks]
def brute(myList,url): start=time.perf_counter() for lists in myList: threads.append(Thread(target=worker,args=(lists,url),daemon=True)) for thread in threads: try: thread.start() except KeyboardInterrupt: print("nReceived Keyboard Interrupt , Terminating threadsn") sys.exit() for thread in threads: try: thread.join() except KeyboardInterrupt: print("nReceived Keyboard Interrupt , Terminating threadsn") sys.exit() finish=time.perf_counter() print(f"nntt Checked {total_len} Directories in {round(finish-start,2)} Secondsn")
def worker(lists,url): try: for word in lists: if word.startswith("/"): word=word[1:] url2=url+"/"+word.strip() r=requests.get(url2) if str(r.status_code) in match: print(f"/{word.strip():<40} [ Status: {r.status_code} Length:{len(r.content)} ]") except KeyboardInterrupt: print("nReceived Keyboard Interrupt , Terminating threadsn") sys.exit() except Exception as e: print(f"nAn error Occurred : {e}n") sys.exit()
if __name__ == "__main__": try: match=['200','301','302','401','403','429'] #change this to filter responses try: if sys.argv[1]: url=sys.argv[1] if sys.argv[2]: wordlist=sys.argv[2] try: if sys.argv[3]: numOfThreads=int(sys.argv[3]) except: numOfThreads=10 except: usage() if os.path.isfile(wordlist)==False: print(f"The file {wordlist} doesn't exist") sys.exit() with open(wordlist,'r') as w: myList=w.readlines() total_len=len(myList) final=[] threads=[] if numOfThreads>total_len or numOfThreads<0: print("nToo High Value for Threads with Respect to Input Word-listn") sys.exit(1) numOfChunks=len(myList)//numOfThreads if url.endswith("/"): url=url[0:-1] print(f''' ====================================== URL --> {url} Word-list --> {wordlist} Threads --> {numOfThreads} Status Codes --> {','.join([w for w in match])} ====================================== nn ''') print("------- Started Brute forcing Directories -------n") myList_new=prepare(myList,numOfChunks) brute(myList_new,url) except Exception as e: print(f"nAn error Occurred : {e}n") sys.exit()


代码详解:

导入和使用详细信息:

from threading import Threadimport time,requests,sys,os.path def usage():        print("----------USAGE INSTRUCTION ---------")        print(f"{sys.argv[0]} URL WORDLIST NUMBER_OF_THREADS")        sys.exit()


这一段代码主要是导入线程和相关模块,Usage()函数向用户展示了如何使用程序,它在命令行参数不足时会被触发。


分块处理:


def prepare(myList,numOfChunks):        for i in range(0, len(myList), numOfChunks):            yield myList[i:i + numOfChunks]


该函数是线程数发挥作用的主要地方,利用它对主列表进行分块处理。


多线程逻辑:

def brute(myList,url):    start=time.perf_counter()    for lists in myList:        threads.append(Thread(target=worker,args=(lists,url),daemon=True))    for thread in threads:        try:            thread.start()        except KeyboardInterrupt:            print("nReceived Keyboard Interrupt  , Terminating threadsn")            sys.exit()    for thread in threads:        try:            thread.join()        except KeyboardInterrupt:            print("nReceived Keyboard Interrupt  , Terminating threadsn")            sys.exit()    finish=time.perf_counter()    print(f"nntt Checked {total_len} Directories in {round(finish-start,2)} Secondsn")


def worker(lists,url):    try:        for word in lists:            if word.startswith("/"):                word=word[1:]            url2=url+"/"+word.strip()            r=requests.get(url2)            if str(r.status_code) in match:                print(f"/{word.strip():<40}  [ Status: {r.status_code}  Length:{len(r.content)} ]")    except KeyboardInterrupt:        print("nReceived Keyboard Interrupt  , Terminating threadsn")        sys.exit()    except Exception as e:        print(f"nAn error Occurred : {e}n")        sys.exit()


上面定义了两个函数brute()和worker(),线程会从brute()函数开始,worker()函数将负责处理请求。


threads.append(Thread(target=worker,args=(lists,url),daemon=True))


从分块列表中提取列表,并使用它启动Thread。


线程将以Worker函数作为目标,这些函数将被附加到包含所有线程的列表中,在此之后,将启动并关联所有线程。


for thread in threads:      thread.start()        for thread in threads:            thread.join()

thread.start():


创建线程实例时,它并不会立即执行,所以需要调用它的start()方法。一旦启动,线程将独立运行,直到目标函数返回。


thread.join():


在调用join()方法时,调用线程会被阻塞,直到终止线程对象(在其上调用线程),线程对象会在以下任何一种情况下终止:


  • 正常情况

  • 处理一个不当的异常时

  • 发生超时


这有助于所有线程完成其工作并正常退出。


在Worker方法关闭(所有线程都关闭)之后,控制将返回到brute()函数,然后继续接下来正常的程序流程。


大概就是这样,使用Python的多线程创建一个简单的扫描工具,但是请记住不要使用太多的线程来运行你的程序,因为一旦处理不当,可能会导致其它程序的崩溃。


当然这个扫描器的代码目前已经放在Github上,地址如下:


https://github.com/kurogai/100-redteam-projects/tree/master/Projects/Directory_BruteForcer


====正文结束====


原文始发于微信公众号(骨哥说事):【白帽故事】打造一款多线程目录爆破扫描器

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年3月4日18:18:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【白帽故事】打造一款多线程目录爆破扫描器http://cn-sec.com/archives/815791.html

发表评论

匿名网友 填写信息