心血来潮让ChatGPT写了一个目录扫描工具,然后进行了一定的修改和完善,可以实现对网站目录的一个简单扫描并输出扫描结果,主要包括存在页面、重定向页面和禁止访问页面。
虽然代码很简单,但是做这个东西的过程还是挺有意思的,也从中学到了一些知识。
代码主要包括三个部分
(1)自定义函数:print_colored_mask_startup_screen()
该函数可以用来输出程序的一些用法和介绍,加了一些看起来酷酷的背景和字体。
(2)自定义函数:directory_scan(url, wordlist)
该函数用于实现扫描功能,接受参数url和wordlist。
(3)main()函数
除了用来调用前面定义的两个函数,main函数中的其它代码可以保证程序正常继续运行和关闭,以及对用户输入错误的提示和处理。
原本我最初的想法是使用 -u 和 -d 追加参数来指定目标url和爆破字典,但是后续转成exe程序后发现,由于没有指定参数会导致程序无法双击打开,只能在cmd中切换到程序所在位置,指定好参数后才能运行,于是修改成了双击打开直接输目标url和字典。
来看效果,首先跑一下py文件是否正常:
接下来我们把py文件转为exe可执行程序
需要先装一个库:pyinstaller
如果安装好之后执行报错可以参考我上一篇博客:http://t.csdnimg.cn/JeMEg
在pycharm终端执行命令:
pyinstaller --onefile --hidden-import=requests MySc.py
hidden参数是确告诉PyInstaller包含requests库,否则生成的东西除了exe程序还会有一个_internal文件夹,该文件夹是requests库的内部文件夹,用于存储库的内部数据和模块,在许多情况下,这个文件夹会随着库的使用而生成,我们可以使用上面的参数确保requests库的相关代码被包括在生成的exe文件中,并且不会产生_internal文件夹。
成功生成exe程序
我们需要先在程序所在目录创建一个用于爆破的字典
双击打开运行程序,输入参数后成功实现了对网站目录扫描
接下来对可能出现的错误进行测试:包括输入错误的url或者不存在的字典路径或者没有输入的情况
可以看到程序会针对错误给出提示,并要求重新输入;
并且每次扫描结束我们也可以使用E命令或者C命令来控制是否继续下一次扫描。
原本想使用pyinstaller --onefile --icon来修改生成exe程序的图标,但是失败了,因为pyinstaller的--onefile选项允许生成一个单文件的可执行程序,但它通常不直接支持将图标嵌入到生成的可执行文件中,其实可以使用pywin32库中的pywin32ctypes模块来更改exe文件的图标,但是呢也没搞出来,后面我再看看。
下面附上py文件源码:
import requests
def print_colored_mask_startup_screen():
colored_mask_art = """
██╗ ██╗ █████╗ ██████╗ ████████╗ M M Y Y OOO N N ██████╗ ██╗ ██╗███╗ ██╗██╗ ██╗███████╗██╗ ██╗
██║ ██║██╔══██╗██╔══██╗╚══██╔══╝ MM MM Y Y O O NN N ██╔══██╗██║ ██║████╗ ██║██║ ██║██╔════╝██║ ██║
██║ █╗ ██║███████║██████╔╝ ██║ M M M Y O O N N N ██████╔╝██║ ██║██╔██╗ ██║██║ ██║███████╗██║ ██║
██║███╗██║██╔══██║██╔══██╗ ██║ M M Y O O N NN ██╔══██╗██║ ██║██║╚██╗██║██║ ██║╚════██║██║ ██║
╚███╔███╔╝██║ ██║██║ ██║ ██║ M M Y OOO N N ██████╔╝╚██████╔╝██║ ╚████║╚██████╔╝███████║███████╗███████╗
╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝
=================================
Directory Scanner
Version: 1.0
Author: Myon
=================================
"""
# 使用ANSI转义码将文本颜色更改为红色
colored_mask_art = "\033[31m" + colored_mask_art + "\033[0m"
print(colored_mask_art)
def directory_scan(url, wordlist):
found = []
redirect = []
forbidden = []
not_found = []
with open(wordlist, 'r') as file:
for line in file:
directory = line.strip()
full_url = f"{url}/{directory}"
response = requests.head(full_url)
if response.status_code == 200:
found.append(full_url)
elif response.status_code == 301 or response.status_code == 302:
redirect.append(full_url)
elif response.status_code == 403 or response.status_code == 401:
forbidden.append(full_url)
elif response.status_code == 404:
not_found.append(full_url)
print("Found:")
for url in found:
print(f"{url}")
print("\nRedirected:")
for url in redirect:
print(f"{url}")
print("\nForbidden:")
for url in forbidden:
print(f"{url}")
print("\nNot Found:")
for url in not_found:
print(f"{url}")
def main():
while True:
print_colored_mask_startup_screen()
while True:
url = input("Enter the target URL: ")
dictionary = input("Enter the path to the wordlist file: ")
if not url or not dictionary:
print("Please enter the target URL and wordlist.")
continue
try:
if not url.startswith(("http://", "https://")):
raise requests.exceptions.MissingSchema("Invalid URL format")
except requests.exceptions.MissingSchema:
print("URL format is invalid. Please enter a valid URL.")
continue
try:
with open(dictionary, 'r'):
pass
except FileNotFoundError:
print("Dictionary file not found.")
continue
directory_scan(url, dictionary)
while True:
command = input("Enter 'E' to exit or 'C' to continue scanning: ")
if command == "E":
return
elif command == "C":
break
else:
print("Invalid command. Please enter 'E' or 'C.")
if __name__ == "__main__":
main()