【工具学习】DirSearch解构1——读取参数与配置

admin 2022年9月16日08:09:42评论53 views字数 6543阅读21分48秒阅读模式

0x01 前言

好久不见,搞了个知识星球,大学生补贴一下生活费,因为技术菜,所以也就50意思下,大佬勿喷,也算是记录一下自己成长的过程,最近打算学习下优秀的安全工具,就从WEB目录扫描工具DirSearch入手了,这个系列是周更,点点关注,和我一起开启自律之旅吧。

0x02 Demo

因为优秀的工具一般比较完善了,代码比较多,对新手不太友好,所以我们化繁为简,只把实现功能的最核心的代码留下,复现一个demo出来

实现命令行读取参数,并设置默认参数from optparse import Option, OptionGroup, OptionParser
usage = "usage: %prog [options] -u baidu -f file.txt"optparse = OptionParser(usage=usage)
general = OptionGroup(optparse,'general','default mode')general.add_option('-u','--url',action='store',type='string',dest='URL',help='add a target,such as %default',default='baidu.com')general.add_option('-r','--random-useragent',action='store_true',dest='UA',help='random useragent')
advanced = OptionGroup(optparse,'advanced','open advanced scan')advanced.add_option('-t','--thread',action='store',type='int',help='set thread',dest='thread')
optparse.add_option_group(general)optparse.add_option_group(advanced)options,args = OptionParser.parse_args(optparse)
print(options)


输出如下:

【工具学习】DirSearch解构1——读取参数与配置


生成配置与读取配置import configparserimport os.path

#生成配置文件config = configparser.ConfigParser()

config['default'] = {'user':'韬光养晦安全','id':'1'}config['advanced'] = {'thread':'25'}

dir = os.path.dirname(__file__)path = dir+'\'+'config.ini'with open(path,'w') as file: config.write(file) #读取配置文件config.read(path)print(config.sections())print(config['default']['user'])print(config.get('default','user'))


生成的配置文件如下:

【工具学习】DirSearch解构1——读取参数与配置


0x03 正文

由于DirSearch功能太多了,所以作者把功能点细化成了很多个模块,代码阅读起来交错复杂,于是我把【读取参数与配置】这个功能点的代码进行了整合,分成了三个文件,如下:

file.py#关于@property和@xx.setter参考文章https://blog.csdn.net/qq_41359051/article/details/82939655#关于*args的参考文章https://blog.csdn.net/weixin_40796925/article/details/107574267#关于os.access的参考文章https://www.runoob.com/python/os-access.html#关于raise NotImplementedError的参考文章https://blog.csdn.net/qq_40666620/article/details/105026716#关于@staticmethod的参考文章https://blog.csdn.net/polyhedronx/article/details/81911548#关于__init__的参考文章https://www.jb51.net/article/188360.htm

import osimport os.path

class FileUtils: @staticmethod def exists(file_name): return os.access(file_name,os.F_OK) @staticmethod def build_path(*path_components): if path_components: path = os.path.join(*path_components) else: path = "" return path class File: def __init__(self,*path_components): self._path = FileUtils.build_path(*path_components) @property def path(self): return self._path @path.setter def path(self,value): raise NotImplemented def exists(self): return FileUtils.exists(self.path) def __enter__(self):#删除后无法读取文件流 return self def __exit__(self,type,value,tb):#删除后无法读取文件流 pass

def _access_file(path): with File(path) as fd: if not fd.exists(): print(f"{path} no exists") else:            print(f"{path} exists")
config.py#关于configparser的参考文章https://www.cnblogs.com/plf-Jack/p/11170284.html#关于optionparser的参考文章https://blog.csdn.net/qq_38684504/article/details/100975952


import configparserimport os

class ConfigParser(configparser.ConfigParser): def __init__(self): configparser.ConfigParser.__init__(self)

def safe_get(self, section, option, default="", allowed=None): try: result = configparser.ConfigParser.get(self, section, option)

if allowed is not None: return result if result in allowed else default

return result except (configparser.NoSectionError, configparser.NoOptionError): return default

def safe_getfloat(self, section, option, default=0, allowed=None): try: result = configparser.ConfigParser.getfloat(self, section, option)

if allowed is not None: return result if result in allowed else default

return result except (configparser.NoSectionError, configparser.NoOptionError): return default

def safe_getboolean(self, section, option, default=False, allowed=None): try: result = configparser.ConfigParser.getboolean(self, section, option)

if allowed is not None: return result if result in allowed else default

return result except (configparser.NoSectionError, configparser.NoOptionError): return default

def safe_getint(self, section, option, default=0, allowed=None): try: result = configparser.ConfigParser.getint(self, section, option)

if allowed is not None: return result if result in allowed else default

return result except (configparser.NoSectionError, configparser.NoOptionError): return default def parse_config(opt): config = ConfigParser() config.read(opt.config) opt.thread_count = opt.thread_count or config.safe_getint( "general", "threads", 25 ) return opt from file import FileUtilsimport sysSCRIPT_PATH = os.path.dirname(__file__)VERSION = 1.0from optparse import OptionGroup,OptionParserdef parse_arguments(): usage = "Usage: %prog [-u|--url] target [-e|--extensions] extensions [options]" parser = OptionParser(usage, version=f"dirsearch v{VERSION}") mandatory = OptionGroup(parser, "Mandatory") mandatory.add_option( "-u", "--url", action="append", dest="urls", metavar="URL", help="Target URL(s), support multiple flags", ) mandatory.add_option( "--config", action="store", dest="config", metavar="PATH", help="Full path to config file, see 'config.ini' for example (Default: config.ini)", default=FileUtils.build_path(SCRIPT_PATH, "config.ini"), ) mandatory.add_option( "-t", "--threads", action="store", type="int", dest="thread_count", metavar="THREADS", help="Number of threads", ) parser.add_option_group(mandatory) options, _ = parser.parse_args() return options

def parse_options(): opt = parse_config(parse_arguments()) print(opt) if not opt.urls: print("URL target is missing, try using -u <url>") exit(1) parse_options()
config.ini# If you want to edit dirsearch default configurations, you can# edit values in this file. Everything after `#` is a comment# and won't be applied

[general]threads = 25recursive = Falsedeep-recursive = Falseforce-recursive = Falserecursion-status = 200-399,401,403max-recursion-depth = 0exclude-subdirs = %%ff/,.;/,..;/,;/,./,../,%%2e/,%%2e%%2e/random-user-agents = Falsemax-time = 0# subdirs = /,api/# include-status = 200-299,401# exclude-status = 400,500-999# exclude-sizes = 0b,123gb# exclude-texts = "Not found"# exclude-regex = "^403$"# exclude-redirect = "*/error.html"# exclude-response = 404.html# skip-on-status = 429,999

[dictionary]default-extensions = php,aspx,jsp,html,jsforce-extensions = Falseoverwrite-extensions = Falselowercase = Falseuppercase = Falsecapitalization = False# exclude-extensions = old,log# prefixes = .,admin# suffixes = ~,.bak# wordlists = /path/to/wordlist1.txt,/path/to/wordlist2.txt

[request]http-method = getfollow-redirects = False# headers-file = /path/to/headers.txt# user-agent = MyUserAgent# cookie = SESSIONID=123

[connection]timeout = 7.5delay = 0max-rate = 0max-retries = 1exit-on-error = False## By disabling `scheme` variable, dirsearch will automatically identify the URI scheme# scheme = http# proxy = localhost:8080# proxy-file = /path/to/proxies.txt# replay-proxy = localhost:8000

[advanced]crawl = False

[view]full-url = Falsequiet-mode = Falsecolor = Trueshow-redirects-history = False

[output]## Support: plain, simple, json, xml, md, csv, html, sqlitereport-format = plainautosave-report = Trueautosave-report-folder = reports/# log-file = /path/to/dirsearch.log# log-file-size = 50000000


原文始发于微信公众号(韬光养晦安全):【工具学习】DirSearch解构1——读取参数与配置

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年9月16日08:09:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【工具学习】DirSearch解构1——读取参数与配置http://cn-sec.com/archives/1286783.html

发表评论

匿名网友 填写信息