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

VSole2022-03-04 12:35:33

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

背景介绍:

今天的分享来自国外一位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)")    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("Received Keyboard Interrupt  , Terminating threads")            sys.exit()    for thread in threads:        try:            thread.join()        except KeyboardInterrupt:            print("Received Keyboard Interrupt  , Terminating threads")            sys.exit()    finish=time.perf_counter()    print(f"\t\t Checked {total_len} Directories in {round(finish-start,2)} Seconds")
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("Received Keyboard Interrupt  , Terminating threads")        sys.exit()    except Exception as e:        print(f"An error Occurred : {e}")        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("Too High Value for Threads with Respect to Input Word-list")            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])}        ======================================                    ''')        print("------- Started Brute forcing Directories -------")        myList_new=prepare(myList,numOfChunks)        brute(myList_new,url)    except Exception as e:        print(f"An error Occurred : {e}")        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("Received Keyboard Interrupt  , Terminating threads")            sys.exit()    for thread in threads:        try:            thread.join()        except KeyboardInterrupt:            print("Received Keyboard Interrupt  , Terminating threads")            sys.exit()    finish=time.perf_counter()    print(f"\t\t Checked {total_len} Directories in {round(finish-start,2)} Seconds")
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("Received Keyboard Interrupt  , Terminating threads")        sys.exit()    except Exception as e:        print(f"An error Occurred : {e}")        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上

线程多线程
本作品采用《CC 协议》,转载必须注明作者和本文链接
Java 8 的内存结构
2022-03-10 14:37:13
java8内存结构图虚拟机内存与本地内存的区别Java虚拟机在执行的时候会把管理的内存分配成不同的区域,这些
Java线程安全:狭义地认为是多线程之间共享数据的访问。 Java语言中各种操作共享的数据有5种类型:不可变、绝对线程安全、相对线程安全、线程兼容、线程独立
任务的状态保存及再加载, 这段过程就叫做上下文切换。上下文切换会导致额外的开销,常常表现为高并发执行时速度会慢串行,因此减少上下文切换次数便可以提高多线程程序的运行效率。在这种机制下,一个线程的堵塞不会导致整个进程堵塞。当CPU接收到中断请求时,会在正在运行的程序和发起中断请求的程序之间进行一次上下文切换。高并发,低耗时的情况,建议少线程
前两天做了一个导入的功能,导入开始的时候非常慢,导入2w条数据要1分多钟,后来一点一点的优化,从直接把list怼进Mysql中,到分配把list导入Mysql中,到多线程把list导入Mysql中。 时间是一点一点的变少了。非常的爽,最后变成了10s以内。 下面就展示一下过程。
通过Scala对文件进行读写操作在实际业务中应用也比较多,这里介绍几种常用的方式,直接上代码:1.从文件中读取内容object Main {. 但是ArrayBuffer 进行添加元素时,使用方法:+=。= new ArrayBuffer[Int],索引容量情况:下当array长度为1,但大小0已经大于16,并且array没有及时扩展时,会报越界。
声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部
多线程是Java的一个难点,但是它也很有趣,听说玩得溜得起飞的人,人生都开启多线程模式了…
ArrayList是线程不安全的,于是JDK新增加了一个线程并发安全的List——CopyOnWriteList,中心思想就是copy-on-write,简单来说是读写分离:读时共享、写时复制(原本的array)更新(且为独占式的加锁),而我们下面分析的源码具体实现也是这个思想的体现。 继承体系:
Carbon Black的安全研究人员在周三的一份报告中说,一种名为Conti的勒索病毒正在使用多达32个并行CPU线程来对受感染计算机上的文件进行加密,以达到极快的加密速度。Conti只是今年发现的一系列勒索软件中最新的一种。安全研究人员于今年 2 月初首次发现了Conti开发人员,但是Carbon Black现在报道其TAU 发现了Conti感染。Carbon Black的TAU在周三发布的技术报告中说,在分析Conti代码时突出的项目是对多线程操作的支持。
介绍一个好用的web信息收集工具 其功能包括: 子域名收集 多线程子域名爆破 指纹信息收集 备案信息收集 批量子域名收集和批量子域名爆破 是一款挖掘SRC的实用小工具
VSole
网络安全专家