diff --git a/doc/sqlmap-泛读报告.docx b/doc/sqlmap-泛读报告.docx new file mode 100644 index 0000000..c87ed17 Binary files /dev/null and b/doc/sqlmap-泛读报告.docx differ diff --git a/src/sqlmap-master/extra/beep/beep.py b/src/sqlmap-master/extra/beep/beep.py index 788bafd..4ed4a29 100644 --- a/src/sqlmap-master/extra/beep/beep.py +++ b/src/sqlmap-master/extra/beep/beep.py @@ -9,96 +9,114 @@ See the file 'LICENSE' for copying permission import os import sys -import wave +import wave # 用于处理 WAV 文件格式 +# 指定蜂鸣音频文件的路径 BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav") def beep(): + """根据操作系统播放蜂鸣声。""" try: + # 检测操作系统并调用相应的播放方法 if sys.platform.startswith("win"): - _win_wav_play(BEEP_WAV_FILENAME) + _win_wav_play(BEEP_WAV_FILENAME) # Windows 系统使用 WAV 播放 elif sys.platform.startswith("darwin"): - _mac_beep() + _mac_beep() # macOS 系统使用系统蜂鸣 elif sys.platform.startswith("cygwin"): - _cygwin_beep(BEEP_WAV_FILENAME) + _cygwin_beep(BEEP_WAV_FILENAME) # Cygwin 使用音频文件播放 elif any(sys.platform.startswith(_) for _ in ("linux", "freebsd")): - _linux_wav_play(BEEP_WAV_FILENAME) + _linux_wav_play(BEEP_WAV_FILENAME) # Linux 和 FreeBSD 系统使用 WAV 播放 else: - _speaker_beep() + _speaker_beep() # 其他系统使用控制台蜂鸣 except: + # 捕获异常并使用控制台蜂鸣 _speaker_beep() def _speaker_beep(): - sys.stdout.write('\a') # doesn't work on modern Linux systems + """在控制台播放蜂鸣声(警报声)。""" + sys.stdout.write('\a') # 在现代 Linux 系统上可能无效 try: - sys.stdout.flush() + sys.stdout.flush() # 尝试刷新标准输出 except IOError: - pass + pass # 忽略任何 I/O 错误 -# Reference: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00815.html +# Cygwin 使用系统命令播放音频文件 def _cygwin_beep(filename): os.system("play-sound-file '%s' 2>/dev/null" % filename) +# macOS 系统使用 Carbon 库的 SysBeep 函数 def _mac_beep(): - import Carbon.Snd - Carbon.Snd.SysBeep(1) + import Carbon.Snd # 导入 Carbon 库 + Carbon.Snd.SysBeep(1) # 播放系统蜂鸣声 +# Windows 系统播放 WAV 文件 def _win_wav_play(filename): - import winsound + import winsound # 导入 winsound 库 - winsound.PlaySound(filename, winsound.SND_FILENAME) + winsound.PlaySound(filename, winsound.SND_FILENAME) # 播放指定的 WAV 文件 +# Linux 系统播放 WAV 文件的实现 def _linux_wav_play(filename): + # 尝试使用不同的命令播放音频文件 for _ in ("aplay", "paplay", "play"): if not os.system("%s '%s' 2>/dev/null" % (_, filename)): - return + return # 成功播放音乐后返回 - import ctypes + import ctypes # 导入 ctypes 库以调用 C 函数 + # PulseAudio 的相关常量定义 PA_STREAM_PLAYBACK = 1 PA_SAMPLE_S16LE = 3 - BUFFSIZE = 1024 + BUFFSIZE = 1024 # 缓冲区大小 + # 定义 PulseAudio 样本规格的结构 class struct_pa_sample_spec(ctypes.Structure): _fields_ = [("format", ctypes.c_int), ("rate", ctypes.c_uint32), ("channels", ctypes.c_uint8)] try: - pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0") + pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0") # 加载 PulseAudio 库 except OSError: - return + return # 如果加载失败,则返回 + # 打开 WAV 文件 wave_file = wave.open(filename, "rb") + # 设置 PulseAudio 样本规格 pa_sample_spec = struct_pa_sample_spec() - pa_sample_spec.rate = wave_file.getframerate() - pa_sample_spec.channels = wave_file.getnchannels() - pa_sample_spec.format = PA_SAMPLE_S16LE + pa_sample_spec.rate = wave_file.getframerate() # 获取采样频率 + pa_sample_spec.channels = wave_file.getnchannels() # 获取声道数 + pa_sample_spec.format = PA_SAMPLE_S16LE # 设置样本格式 error = ctypes.c_int(0) - pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None, "playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error)) + # 创建 PulseAudio 流 + pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None, + "playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error)) if not pa_stream: raise Exception("Could not create pulse audio stream: %s" % pa.strerror(ctypes.byref(error))) while True: + # 获取延迟 latency = pa.pa_simple_get_latency(pa_stream, ctypes.byref(error)) if latency == -1: raise Exception("Getting latency failed") - buf = wave_file.readframes(BUFFSIZE) + buf = wave_file.readframes(BUFFSIZE) # 从 WAV 文件读取帧 if not buf: - break + break # 如果没有更多帧可读,退出循环 + # 播放读取的帧 if pa.pa_simple_write(pa_stream, buf, len(buf), ctypes.byref(error)): raise Exception("Could not play file") - wave_file.close() + wave_file.close() # 关闭 WAV 文件 + # 确保所有数据都已播放完成 if pa.pa_simple_drain(pa_stream, ctypes.byref(error)): raise Exception("Could not simple drain") - pa.pa_simple_free(pa_stream) + pa.pa_simple_free(pa_stream) # 释放 PulseAudio 流资源 if __name__ == "__main__": - beep() + beep() # 调用蜂鸣函数 \ No newline at end of file diff --git a/src/sqlmap-master/extra/cloak/cloak.py b/src/sqlmap-master/extra/cloak/cloak.py index 8f361a0..ee8a396 100644 --- a/src/sqlmap-master/extra/cloak/cloak.py +++ b/src/sqlmap-master/extra/cloak/cloak.py @@ -7,82 +7,99 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) See the file 'LICENSE' for copying permission """ -from __future__ import print_function +from __future__ import print_function # 兼容 Python 2 和 3 的 print 函数 import os import struct import sys -import zlib +import zlib # 用于数据压缩和解压缩 from optparse import OptionError from optparse import OptionParser +# 在 Python 3 中定义 xrange 和 ord 的兼容 if sys.version_info >= (3, 0): - xrange = range - ord = lambda _: _ + xrange = range # 使用 Python 3 的 range + ord = lambda _: _ # 在 Python 3 中直接使用字符 -KEY = b"E6wRbVhD0IBeCiGJ" +KEY = b"E6wRbVhD0IBeCiGJ" # 定义加密/解密的密钥 def xor(message, key): + """执行 XOR 操作,返回加密或解密后的字节序列。""" + # 对 message 的每个字节进行 XOR 运算,并返回字节串 return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message))) def cloak(inputFile=None, data=None): + """对输入文件或数据进行加密和压缩。""" if data is None: + # 如果没有提供数据,则读取文件内容 with open(inputFile, "rb") as f: - data = f.read() + data = f.read() # 以二进制模式读取文件数据 + # 对数据进行压缩后再使用 XOR 加密 return xor(zlib.compress(data), KEY) def decloak(inputFile=None, data=None): + """对输入文件或数据进行解密和解压缩。""" if data is None: + # 如果没有提供数据,则读取文件内容 with open(inputFile, "rb") as f: data = f.read() + try: + # 首先对数据进行 XOR 解密,然后解压缩 data = zlib.decompress(xor(data, KEY)) except Exception as ex: + # 如果解压缩过程中发生异常,打印错误信息并退出 print(ex) print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile) sys.exit(1) finally: - f.close() + f.close() # 确保文件流被关闭 - return data + return data # 返回解密后的数据 def main(): - usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0] - parser = OptionParser(usage=usage, version='0.2') + """主函数,负责解析命令行参数并执行加密或解密操作。""" + usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0] # 使用说明 + parser = OptionParser(usage=usage, version='0.2') # 创建 OptionParser 对象 try: - parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt') - parser.add_option('-i', dest='inputFile', help='Input file') - parser.add_option('-o', dest='outputFile', help='Output file') + # 添加命令行选项 + parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt') # 解密选项 + parser.add_option('-i', dest='inputFile', help='Input file') # 输入文件选项 + parser.add_option('-o', dest='outputFile', help='Output file') # 输出文件选项 - (args, _) = parser.parse_args() + (args, _) = parser.parse_args() # 解析命令行参数 if not args.inputFile: - parser.error('Missing the input file, -h for help') + parser.error('Missing the input file, -h for help') # 如果未提供输入文件,则报错 except (OptionError, TypeError) as ex: - parser.error(ex) + parser.error(ex) # 捕获解析错误 + # 检查输入文件是否存在 if not os.path.isfile(args.inputFile): print('ERROR: the provided input file \'%s\' is non existent' % args.inputFile) sys.exit(1) + # 根据是否需要解密选择处理函数 if not args.decrypt: - data = cloak(args.inputFile) + data = cloak(args.inputFile) # 加密文件内容 else: - data = decloak(args.inputFile) + data = decloak(args.inputFile) # 解密文件内容 + # 如果未指定输出文件名,则根据是否解密自动生成 if not args.outputFile: if not args.decrypt: - args.outputFile = args.inputFile + '_' + args.outputFile = args.inputFile + '_' # 添加后缀表示加密 else: - args.outputFile = args.inputFile[:-1] + args.outputFile = args.inputFile[:-1] # 移除后缀表示解密 + # 写入结果到输出文件 f = open(args.outputFile, 'wb') - f.write(data) - f.close() + f.write(data) # 写入数据 + f.close() # 关闭文件 if __name__ == '__main__': - main() + main() # 程序入口 \ No newline at end of file diff --git a/src/sqlmap-master/extra/dbgtool/dbgtool.py b/src/sqlmap-master/extra/dbgtool/dbgtool.py index 5443af7..bc1b1be 100644 --- a/src/sqlmap-master/extra/dbgtool/dbgtool.py +++ b/src/sqlmap-master/extra/dbgtool/dbgtool.py @@ -7,7 +7,7 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) See the file 'LICENSE' for copying permission """ -from __future__ import print_function +from __future__ import print_function # 兼容 Python 2 和 3 的 print 函数 import os import sys @@ -16,81 +16,97 @@ from optparse import OptionError from optparse import OptionParser def convert(inputFile): - fileStat = os.stat(inputFile) - fileSize = fileStat.st_size + """将给定的二进制输入文件转换为 ASCII 调试脚本。""" + fileStat = os.stat(inputFile) # 获取文件状态 + fileSize = fileStat.st_size # 获取文件大小 + # 检查文件大小是否超过 65280 字节(可调试的最大限制) if fileSize > 65280: print("ERROR: the provided input file '%s' is too big for debug.exe" % inputFile) - sys.exit(1) + sys.exit(1) # 如果文件太大,退出程序 - script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_")) - script += "%x\nf 0100 ffff 00\n" % fileSize - scrString = "" - counter = 256 - counter2 = 0 + # 开始构建调试脚本 + script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_")) # 设置脚本名称 + script += "%x\nf 0100 ffff 00\n" % fileSize # 写入文件大小信息 + scrString = "" # 用于构建写入命令 + counter = 256 # 地址计数器从 256 开始 + counter2 = 0 # 0 计数器,用于控制输出的字符数 + # 读取输入文件的二进制内容 fp = open(inputFile, "rb") - fileContent = fp.read() + fileContent = fp.read() # 读取所有内容 + # 遍历文件的每个字节 for fileChar in fileContent: + # 在 Python 3 中字符是字节,直接使用;在 Python 2 中需要使用 ord() 函数 unsignedFileChar = fileChar if sys.version_info >= (3, 0) else ord(fileChar) + # 如果字符不是空字节(0),则进行处理 if unsignedFileChar != 0: - counter2 += 1 + counter2 += 1 # 增加有效字符计数 if not scrString: + # 如果 scrString 为空,开始创建新的写入命令 scrString = "e %0x %02x" % (counter, unsignedFileChar) else: + # 否则,将字符附加到 scrString 中 scrString += " %02x" % unsignedFileChar elif scrString: + # 如果遇到空字节,且 scrString 中有内容,需要把当前 scrString 添加到脚本 script += "%s\n" % scrString - scrString = "" - counter2 = 0 + scrString = "" # 清空 scrString + counter2 = 0 # 重置有效字符计数 - counter += 1 + counter += 1 # 增加地址计数器 + # 每 20 个有效字符输出一次 if counter2 == 20: - script += "%s\n" % scrString - scrString = "" - counter2 = 0 + script += "%s\n" % scrString # 将当前 scrString 加入脚本 + scrString = "" # 清空 scrString + counter2 = 0 # 重置计数 + # 完成脚本,添加结束指令 script += "w\nq\n" - return script + return script # 返回生成的调试脚本 def main(inputFile, outputFile): + """主功能,处理文件输入输出。""" + # 检查输入文件是否是常规文件 if not os.path.isfile(inputFile): print("ERROR: the provided input file '%s' is not a regular file" % inputFile) - sys.exit(1) + sys.exit(1) # 如果不是,退出程序 + # 调用转换函数 script = convert(inputFile) + # 如果提供了输出文件,写入脚本 if outputFile: - fpOut = open(outputFile, "w") - sys.stdout = fpOut - sys.stdout.write(script) - sys.stdout.close() + with open(outputFile, "w") as fpOut: + sys.stdout = fpOut # 将标准输出重定向到输出文件 + sys.stdout.write(script) # 写入脚本内容 + sys.stdout.close() # 关闭文件 else: - print(script) + print(script) # 如果没有输出文件,直接打印脚本 if __name__ == "__main__": - usage = "%s -i <input file> [-o <output file>]" % sys.argv[0] - parser = OptionParser(usage=usage, version="0.1") + usage = "%s -i <input file> [-o <output file>]" % sys.argv[0] # 程序用法说明 + parser = OptionParser(usage=usage, version="0.1") # 创建解析器 try: - parser.add_option("-i", dest="inputFile", help="Input binary file") - - parser.add_option("-o", dest="outputFile", help="Output debug.exe text file") + # 添加命令行选项 + parser.add_option("-i", dest="inputFile", help="Input binary file") # 输入文件 + parser.add_option("-o", dest="outputFile", help="Output debug.exe text file") # 输出文件 - (args, _) = parser.parse_args() + (args, _) = parser.parse_args() # 解析参数 if not args.inputFile: - parser.error("Missing the input file, -h for help") + parser.error("Missing the input file, -h for help") # 必须提供输入文件 except (OptionError, TypeError) as ex: - parser.error(ex) + parser.error(ex) # 捕获错误并报告 - inputFile = args.inputFile - outputFile = args.outputFile + inputFile = args.inputFile # 输入文件名 + outputFile = args.outputFile # 输出文件名 - main(inputFile, outputFile) + main(inputFile, outputFile) # 调用主函数 \ No newline at end of file diff --git a/src/sqlmap-master/extra/icmpsh/icmpsh_m.py b/src/sqlmap-master/extra/icmpsh/icmpsh_m.py index 17370fd..70de16c 100644 --- a/src/sqlmap-master/extra/icmpsh/icmpsh_m.py +++ b/src/sqlmap-master/extra/icmpsh/icmpsh_m.py @@ -5,7 +5,6 @@ # # Copyright (c) 2010, Bernardo Damele A. G. <bernardo.damele@gmail.com> # -# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -28,117 +27,117 @@ def setNonBlocking(fd): """ Make a file descriptor non-blocking """ + import fcntl # 导入用于文件控制选项的库 - import fcntl - - flags = fcntl.fcntl(fd, fcntl.F_GETFL) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) + flags = fcntl.fcntl(fd, fcntl.F_GETFL) # 获取当前文件描述符的状态标志 + flags = flags | os.O_NONBLOCK # 将非阻塞标志添加到当前标志 + fcntl.fcntl(fd, fcntl.F_SETFL, flags) # 设置文件描述符为非阻塞模式 def main(src, dst): + """主程序函数,用于设置 ICMP socket 和处理命令。""" if sys.platform == "nt": - sys.stderr.write('icmpsh master can only run on Posix systems\n') + sys.stderr.write('icmpsh master can only run on Posix systems\n') # 检查是否在 Windows 上运行 sys.exit(255) try: - from impacket import ImpactDecoder - from impacket import ImpactPacket + from impacket import ImpactDecoder # 导入 Impacket 库用于解析数据包 + from impacket import ImpactPacket # 导入 Impacket 用于构建数据包 except ImportError: - sys.stderr.write('You need to install Python Impacket library first\n') + sys.stderr.write('You need to install Python Impacket library first\n') # 检查是否安装 Impacket sys.exit(255) - # Make standard input a non-blocking file - stdin_fd = sys.stdin.fileno() + # 将标准输入设置为非阻塞 + stdin_fd = sys.stdin.fileno() # 获取标准输入的文件描述符 setNonBlocking(stdin_fd) - # Open one socket for ICMP protocol - # A special option is set on the socket so that IP headers are included - # with the returned data + # 为 ICMP 协议打开一个 socket try: - sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) + sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) # 创建原始 ICMP socket except socket.error: - sys.stderr.write('You need to run icmpsh master with administrator privileges\n') + sys.stderr.write('You need to run icmpsh master with administrator privileges\n') # 检查运行权限 sys.exit(1) - sock.setblocking(0) - sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) + sock.setblocking(0) # 设置 socket 为非阻塞模式 + sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # 启用 IP 头包含在发送包中 - # Create a new IP packet and set its source and destination addresses + # 创建一个新的 IP 包,设置源和目的地址 ip = ImpactPacket.IP() - ip.set_ip_src(src) - ip.set_ip_dst(dst) + ip.set_ip_src(src) # 设置源 IP + ip.set_ip_dst(dst) # 设置目标 IP - # Create a new ICMP packet of type ECHO REPLY + # 创建一个新的 ICMP 包,类型为回显应答(ECHO REPLY) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHOREPLY) - # Instantiate an IP packets decoder + # 实例化 IP 数据包解码器 decoder = ImpactDecoder.IPDecoder() + # 在无限循环中发送和接收命令 while True: try: cmd = '' - # Wait for incoming replies - if sock in select.select([sock], [], [])[0]: - buff = sock.recv(4096) + # 等待输入的回复 + if sock in select.select([sock], [], [])[0]: # 监控 socket 是否可读 + buff = sock.recv(4096) # 接收最大 4096 字节的数据 if 0 == len(buff): - # Socket remotely closed + # 如果接收到的数据长度为 0,说明对方关闭了 socket sock.close() sys.exit(0) - # Packet received; decode and display it - ippacket = decoder.decode(buff) - icmppacket = ippacket.child() + # 解析接收到的数据包 + ippacket = decoder.decode(buff) # 解码 IP 包 + icmppacket = ippacket.child() # 获取 ICMP 包 - # If the packet matches, report it to the user + # 检查 ICMP 数据包的源和目的地址以及类型 if ippacket.get_ip_dst() == src and ippacket.get_ip_src() == dst and 8 == icmppacket.get_icmp_type(): - # Get identifier and sequence number + # 获取标识符和序列号 ident = icmppacket.get_icmp_id() seq_id = icmppacket.get_icmp_seq() - data = icmppacket.get_data_as_string() + data = icmppacket.get_data_as_string() # 获取数据 if len(data) > 0: - sys.stdout.write(data) + sys.stdout.write(data) # 输出接收到的数据 - # Parse command from standard input + # 从标准输入读取命令 try: - cmd = sys.stdin.readline() + cmd = sys.stdin.readline() # 读取用户输入的命令 except: pass - if cmd == 'exit\n': + if cmd == 'exit\n': # 如果输入为 'exit',退出循环 return - # Set sequence number and identifier + # 设置序列号和标识符,以便回复 icmp.set_icmp_id(ident) icmp.set_icmp_seq(seq_id) - # Include the command as data inside the ICMP packet + # 将命令作为数据包含在 ICMP 包中 icmp.contains(ImpactPacket.Data(cmd)) - # Calculate its checksum + # 计算 ICMP 包的校验和 icmp.set_icmp_cksum(0) - icmp.auto_checksum = 1 + icmp.auto_checksum = 1 # 自动计算校验和 - # Have the IP packet contain the ICMP packet (along with its payload) + # 将 ICMP 包插入到 IP 包中 ip.contains(icmp) try: - # Send it to the target host + # 发送数据包到目标主机 sock.sendto(ip.get_packet(), (dst, 0)) except socket.error as ex: - sys.stderr.write("'%s'\n" % ex) + sys.stderr.write("'%s'\n" % ex) # 输出错误信息 sys.stderr.flush() except: break if __name__ == '__main__': + # 检查参数,确保提供了源 IP 和目标 IP if len(sys.argv) < 3: msg = 'missing mandatory options. Execute as root:\n' msg += './icmpsh-m.py <source IP address> <destination IP address>\n' sys.stderr.write(msg) sys.exit(1) - main(sys.argv[1], sys.argv[2]) + main(sys.argv[1], sys.argv[2]) # 调用主函数,传入源和目标 IP \ No newline at end of file diff --git a/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp b/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp index 743f2a2..31ae1f9 100644 --- a/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp +++ b/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp @@ -2,7 +2,7 @@ runcmd - a program for running command prompt commands Copyright (C) 2010 Miroslav Stampar email: miroslav.stampar@gmail.com - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -25,22 +25,27 @@ #include <string> using namespace std; + int main(int argc, char* argv[]) { - FILE *fp; - string cmd; + FILE *fp; + string cmd; - for( int count = 1; count < argc; count++ ) - cmd += " " + string(argv[count]); + // 从命令行参数获取命令并构建完整的命令字符串 + for (int count = 1; count < argc; count++) + cmd += " " + string(argv[count]); // 将每个参数添加到 cmd 字符串中,并用空格分隔 + // 使用 _popen() 函数以只读的方式打开一个命令进程 fp = _popen(cmd.c_str(), "r"); + // 检查文件指针是否有效 if (fp != NULL) { - char buffer[BUFSIZ]; + char buffer[BUFSIZ]; // 声明一个缓冲区用于接收输出 + // 读取命令的输出并将其写到标准输出 while (fgets(buffer, sizeof buffer, fp) != NULL) - fputs(buffer, stdout); + fputs(buffer, stdout); // 将缓冲区的内容输出到控制台 } return 0; -} +} \ No newline at end of file diff --git a/src/sqlmap-master/extra/shutils/duplicates.py b/src/sqlmap-master/extra/shutils/duplicates.py index 8f09a59..df39403 100644 --- a/src/sqlmap-master/extra/shutils/duplicates.py +++ b/src/sqlmap-master/extra/shutils/duplicates.py @@ -3,28 +3,32 @@ # Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) # See the file 'LICENSE' for copying permission -# Removes duplicate entries in wordlist like files +# Removes duplicate entries in wordlist-like files -from __future__ import print_function +from __future__ import print_function # 确保使用 Python 3 的 print() 函数 -import sys +import sys # 导入系统模块,用于处理命令行参数和文件操作 if __name__ == "__main__": + # 检查程序是否接收到至少一个命令行参数 if len(sys.argv) > 1: - items = list() + items = list() # 初始化一个列表用于存储唯一条目 + # 打开指定的文件进行读取 with open(sys.argv[1], 'r') as f: - for item in f: - item = item.strip() + for item in f: # 遍历文件中的每一行 + item = item.strip() # 去掉行首尾的空白字符 + try: - str.encode(item) - if item in items: - if item: - print(item) + str.encode(item) # 尝试对字符串编码,确保内容是有效的字符串 + if item in items: # 检查条目是否已经在列表中 + if item: # 确保条目不为空 + print(item) # 打印重复的条目 else: - items.append(item) + items.append(item) # 如果条目不在列表中,则添加到列表 except: - pass + pass # 捕获异常,继续处理下一个条目 + # 以写入模式打开同一个文件,准备写入去重后的唯一条目 with open(sys.argv[1], 'w+') as f: - f.writelines("\n".join(items)) + f.writelines("\n".join(items)) # 将唯一条目写回文件,以换行符分隔 \ No newline at end of file diff --git a/src/sqlmap-master/extra/shutils/newlines.py b/src/sqlmap-master/extra/shutils/newlines.py index fe28a35..a2899b6 100644 --- a/src/sqlmap-master/extra/shutils/newlines.py +++ b/src/sqlmap-master/extra/shutils/newlines.py @@ -6,25 +6,30 @@ import os import sys def check(filepath): - if filepath.endswith(".py"): - content = open(filepath, "rb").read() - pattern = "\n\n\n".encode("ascii") + # 检查给定路径的文件 + if filepath.endswith(".py"): # 检查文件扩展名是否为 .py + content = open(filepath, "rb").read() # 以二进制模式打开文件并读取全部内容 + pattern = "\n\n\n".encode("ascii") # 定义一个二进制模式的换行符序列,表示三个换行符 + # 检查内容中是否包含三个连续的换行符 if pattern in content: - index = content.find(pattern) + index = content.find(pattern) # 找到模式在内容中的第一个出现位置 + # 打印文件路径和模式前后各 30 个字节的内容 print(filepath, repr(content[index - 30:index + 30])) if __name__ == "__main__": try: - BASE_DIRECTORY = sys.argv[1] - except IndexError: + BASE_DIRECTORY = sys.argv[1] # 尝试获取命令行中指定的目录路径 + except IndexError: # 如果没有指定目录参数 print("no directory specified, defaulting to current working directory") - BASE_DIRECTORY = os.getcwd() + BASE_DIRECTORY = os.getcwd() # 使用当前工作目录作为默认目录 print("looking for *.py scripts in subdirectories of '%s'" % BASE_DIRECTORY) + # 遍历指定目录及其子目录中的所有文件 for root, dirs, files in os.walk(BASE_DIRECTORY): + # 如果路径中包含 "extra" 或 "thirdparty",则跳过该目录 if any(_ in root for _ in ("extra", "thirdparty")): continue - for name in files: - filepath = os.path.join(root, name) - check(filepath) + for name in files: # 遍历文件列表 + filepath = os.path.join(root, name) # 构建文件的完整路径 + check(filepath) # 调用 check 函数检查该文件 \ No newline at end of file diff --git a/src/sqlmap-master/extra/vulnserver/vulnserver.py b/src/sqlmap-master/extra/vulnserver/vulnserver.py index cfa1d1b..bb00798 100644 --- a/src/sqlmap-master/extra/vulnserver/vulnserver.py +++ b/src/sqlmap-master/extra/vulnserver/vulnserver.py @@ -6,6 +6,9 @@ vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes) Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) See the file 'LICENSE' for copying permission """ +# 该脚本实现了一个简单的 HTTP 服务器,故意留下 SQL 注入漏洞,供测试和学习之用。 +# 它展示了基本的 Web 服务器如何处理请求、解析参数以及如何与 SQLite 数据库交互。 +# 此类工具应仅在安全的实验环境中使用,以避免滥用和安全风险。在实际应用中,开发者应注意保护数据库查询以防止 SQL 注入攻击。 from __future__ import print_function @@ -17,29 +20,26 @@ import sys import threading import traceback +# 检查 Python 版本 PY3 = sys.version_info >= (3, 0) -UNICODE_ENCODING = "utf-8" -DEBUG = False +UNICODE_ENCODING = "utf-8" # 定义 Unicode 编码 +DEBUG = False # 调试模式标志 if PY3: - from http.client import INTERNAL_SERVER_ERROR - from http.client import NOT_FOUND - from http.client import OK - from http.server import BaseHTTPRequestHandler - from http.server import HTTPServer + # 导入 Python 3 中的 HTTP 相关模块 + from http.client import INTERNAL_SERVER_ERROR, NOT_FOUND, OK + from http.server import BaseHTTPRequestHandler, HTTPServer from socketserver import ThreadingMixIn - from urllib.parse import parse_qs - from urllib.parse import unquote_plus + from urllib.parse import parse_qs, unquote_plus else: - from BaseHTTPServer import BaseHTTPRequestHandler - from BaseHTTPServer import HTTPServer - from httplib import INTERNAL_SERVER_ERROR - from httplib import NOT_FOUND - from httplib import OK + # 对于 Python 2,导入相应的 HTTP 相关模块 + from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer + from httplib import INTERNAL_SERVER_ERROR, NOT_FOUND, OK from SocketServer import ThreadingMixIn from urlparse import parse_qs from urllib import unquote_plus +# SQLite 模式定义,创建用户表并插入示例数据 SCHEMA = """ CREATE TABLE users ( id INTEGER, @@ -54,9 +54,11 @@ SCHEMA = """ INSERT INTO users (id, name, surname) VALUES (5, NULL, 'nameisnull'); """ +# 定义监听地址和端口 LISTEN_ADDRESS = "localhost" LISTEN_PORT = 8440 +# 全局变量 _conn = None _cursor = None _lock = None @@ -68,13 +70,15 @@ def init(quiet=False): global _cursor global _lock + # 在内存中创建 SQLite 数据库连接 _conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False) - _cursor = _conn.cursor() - _lock = threading.Lock() + _cursor = _conn.cursor() # 创建游标,用于执行 SQL 命令 + _lock = threading.Lock() # 创建线程锁,以处理多线程环境下的数据库访问 - _cursor.executescript(SCHEMA) + _cursor.executescript(SCHEMA) # 执行脚本以创建表并插入数据 if quiet: + # 如果 quiet 为 True,则禁止输出 global print def _(*args, **kwargs): @@ -83,6 +87,7 @@ def init(quiet=False): print = _ class ThreadingServer(ThreadingMixIn, HTTPServer): + # 允许多线程处理 HTTP 请求 def finish_request(self, *args, **kwargs): try: HTTPServer.finish_request(self, *args, **kwargs) @@ -91,13 +96,16 @@ class ThreadingServer(ThreadingMixIn, HTTPServer): traceback.print_exc() class ReqHandler(BaseHTTPRequestHandler): + # 请求处理类 def do_REQUEST(self): + # 处理请求,分割路径和查询字符串 path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "") params = {} if query: - params.update(parse_qs(query)) + params.update(parse_qs(query)) # 解析查询字符串为字典 + # 检查是否出现恶意脚本 if "<script>" in unquote_plus(query): self.send_response(INTERNAL_SERVER_ERROR) self.send_header("X-Powered-By", "Express") @@ -106,18 +114,25 @@ class ReqHandler(BaseHTTPRequestHandler): self.wfile.write("CLOUDFLARE_ERROR_500S_BOX".encode(UNICODE_ENCODING)) return + # 处理请求数据(如果有) if hasattr(self, "data"): if self.data.startswith('{') and self.data.endswith('}'): - params.update(json.loads(self.data)) + params.update(json.loads(self.data)) # JSON 数据 elif self.data.startswith('<') and self.data.endswith('>'): - params.update(dict((_[0], _[1].replace("'", "'").replace(""", '"').replace("<", '<').replace(">", '>').replace("&", '&')) for _ in re.findall(r'name="([^"]+)" value="([^"]*)"', self.data))) + # 解析 HTML 表单数据 + params.update(dict((_[0], _[1].replace("'", "'").replace(""", '"') + .replace("<", '<').replace(">", '>').replace("&", '&')) + for _ in re.findall(r'name="([^"]+)" value="([^"]*)"', self.data))) else: - self.data = self.data.replace(';', '&') # Note: seems that Python3 started ignoring parameter splitting with ';' + # 处理 URL 编码数据 + self.data = self.data.replace(';', '&') # 兼容性处理 params.update(parse_qs(self.data)) + # 处理请求头参数 for name in self.headers: params[name.lower()] = self.headers[name] + # 处理 Cookie 参数 if "cookie" in params: for part in params["cookie"].split(';'): part = part.strip() @@ -125,14 +140,17 @@ class ReqHandler(BaseHTTPRequestHandler): name, value = part.split('=', 1) params[name.strip()] = unquote_plus(value.strip()) + # 将多值参数转换为单值 for key in params: if params[key] and isinstance(params[key], (tuple, list)): params[key] = params[key][-1] - self.url, self.params = path, params + self.url, self.params = path, params # 存储 URL 和参数 if self.url == '/': + # 主页处理 if not any(_ in self.params for _ in ("id", "query")): + # 如果没有 ID 或查询参数,则显示主页面 self.send_response(OK) self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING) self.send_header("Connection", "close") @@ -142,27 +160,33 @@ class ReqHandler(BaseHTTPRequestHandler): code, output = OK, "" try: + # 处理回显参数 if self.params.get("echo", ""): output += "%s<br>" % self.params["echo"] if self.params.get("reflect", ""): output += "%s<br>" % self.params.get("id") - with _lock: + with _lock: # 使用锁来确保线程安全 if "query" in self.params: + # 执行任意 SQL 查询 _cursor.execute(self.params["query"]) elif "id" in self.params: + # 通过 ID 查询用户 if "base64" in self.params: - _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % base64.b64decode("%s===" % self.params["id"], altchars=self.params.get("altchars")).decode()) + _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % + base64.b64decode("%s===" % self.params["id"], + altchars=self.params.get("altchars")).decode()) else: _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"]) - results = _cursor.fetchall() + results = _cursor.fetchall() # 获取查询结果 output += "<b>SQL results:</b><br>\n" + # 根据查询结果决定响应的状态码和内容 if self.params.get("code", ""): if not results: - code = INTERNAL_SERVER_ERROR + code = INTERNAL_SERVER_ERROR # 出错 else: if results: output += "<table border=\"1\">\n" @@ -175,15 +199,16 @@ class ReqHandler(BaseHTTPRequestHandler): output += "</table>\n" else: - output += "no results found" + output += "no results found" # 查询无结果 output += "</body></html>" except Exception as ex: code = INTERNAL_SERVER_ERROR + # 捕获异常并返回错误信息 output = "%s: %s" % (re.search(r"'([^']+)'", str(type(ex))).group(1), ex) + # 发送响应 self.send_response(code) - self.send_header("Content-type", "text/html") self.send_header("Connection", "close") @@ -194,26 +219,30 @@ class ReqHandler(BaseHTTPRequestHandler): self.end_headers() self.wfile.write(output if isinstance(output, bytes) else output.encode(UNICODE_ENCODING)) else: + # 对于未定义的路径返回 404 self.send_response(NOT_FOUND) self.send_header("Connection", "close") self.end_headers() def do_GET(self): - self.do_REQUEST() + self.do_REQUEST() # 处理 GET 请求 def do_PUT(self): - self.do_POST() + self.do_POST() # 处理 PUT 请求 def do_HEAD(self): - self.do_REQUEST() + self.do_REQUEST() # 处理 HEAD 请求 def do_POST(self): + # 处理 POST 请求 length = int(self.headers.get("Content-length", 0)) if length: + # 读取请求体数据 data = self.rfile.read(length) data = unquote_plus(data.decode(UNICODE_ENCODING, "ignore")) self.data = data elif self.headers.get("Transfer-encoding") == "chunked": + # 处理 chunked 请求 data, line = b"", b"" count = 0 @@ -232,10 +261,10 @@ class ReqHandler(BaseHTTPRequestHandler): self.data = data.decode(UNICODE_ENCODING, "ignore") - self.do_REQUEST() + self.do_REQUEST() # 处理 POST 逻辑 def log_message(self, format, *args): - return + return # 不记录日志 def run(address=LISTEN_ADDRESS, port=LISTEN_PORT): global _alive @@ -244,16 +273,17 @@ def run(address=LISTEN_ADDRESS, port=LISTEN_PORT): _alive = True _server = ThreadingServer((address, port), ReqHandler) print("[i] running HTTP server at 'http://%s:%d'" % (address, port)) - _server.serve_forever() + _server.serve_forever() # 开始监听并处理请求 except KeyboardInterrupt: - _server.socket.close() + _server.socket.close() # 关闭服务器 raise finally: _alive = False if __name__ == "__main__": try: - init() - run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS, int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT)) + init() # 初始化数据库和服务器 + run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS, + int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT)) except KeyboardInterrupt: - print("\r[x] Ctrl-C received") + print("\r[x] Ctrl-C received") # 捕获 Ctrl-C 终止信号 \ No newline at end of file diff --git a/src/sqlmap-master/lib/class_diagram/blind_classes_blind.png b/src/sqlmap-master/lib/class_diagram/blind_classes_blind.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/blind_classes_blind.png differ diff --git a/src/sqlmap-master/lib/class_diagram/blind_packages_blind.png b/src/sqlmap-master/lib/class_diagram/blind_packages_blind.png new file mode 100644 index 0000000..11484b3 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/blind_packages_blind.png differ diff --git a/src/sqlmap-master/lib/class_diagram/controller_classes_controller.png b/src/sqlmap-master/lib/class_diagram/controller_classes_controller.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/controller_classes_controller.png differ diff --git a/src/sqlmap-master/lib/class_diagram/controller_packages_controller.png b/src/sqlmap-master/lib/class_diagram/controller_packages_controller.png new file mode 100644 index 0000000..e4ca890 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/controller_packages_controller.png differ diff --git a/src/sqlmap-master/lib/class_diagram/core_classes_core.png b/src/sqlmap-master/lib/class_diagram/core_classes_core.png new file mode 100644 index 0000000..4e0f3a8 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/core_classes_core.png differ diff --git a/src/sqlmap-master/lib/class_diagram/core_packages_core.png b/src/sqlmap-master/lib/class_diagram/core_packages_core.png new file mode 100644 index 0000000..03f35fa Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/core_packages_core.png differ diff --git a/src/sqlmap-master/lib/class_diagram/dns_classes_dns.png b/src/sqlmap-master/lib/class_diagram/dns_classes_dns.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/dns_classes_dns.png differ diff --git a/src/sqlmap-master/lib/class_diagram/dns_packages_dns.png b/src/sqlmap-master/lib/class_diagram/dns_packages_dns.png new file mode 100644 index 0000000..3c73804 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/dns_packages_dns.png differ diff --git a/src/sqlmap-master/lib/class_diagram/error_classes_error.png b/src/sqlmap-master/lib/class_diagram/error_classes_error.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/error_classes_error.png differ diff --git a/src/sqlmap-master/lib/class_diagram/error_packages_error.png b/src/sqlmap-master/lib/class_diagram/error_packages_error.png new file mode 100644 index 0000000..0c1eedf Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/error_packages_error.png differ diff --git a/src/sqlmap-master/lib/class_diagram/parse_classes_parse.png b/src/sqlmap-master/lib/class_diagram/parse_classes_parse.png new file mode 100644 index 0000000..f0acca2 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/parse_classes_parse.png differ diff --git a/src/sqlmap-master/lib/class_diagram/parse_packages_parse.png b/src/sqlmap-master/lib/class_diagram/parse_packages_parse.png new file mode 100644 index 0000000..18a478b Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/parse_packages_parse.png differ diff --git a/src/sqlmap-master/lib/class_diagram/request_classes_request.png b/src/sqlmap-master/lib/class_diagram/request_classes_request.png new file mode 100644 index 0000000..aa6d21f Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/request_classes_request.png differ diff --git a/src/sqlmap-master/lib/class_diagram/request_packages_request.png b/src/sqlmap-master/lib/class_diagram/request_packages_request.png new file mode 100644 index 0000000..319c7bc Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/request_packages_request.png differ diff --git a/src/sqlmap-master/lib/class_diagram/takeover_classes_takeover.png b/src/sqlmap-master/lib/class_diagram/takeover_classes_takeover.png new file mode 100644 index 0000000..390cad8 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/takeover_classes_takeover.png differ diff --git a/src/sqlmap-master/lib/class_diagram/takeover_packages_takeover.png b/src/sqlmap-master/lib/class_diagram/takeover_packages_takeover.png new file mode 100644 index 0000000..260706c Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/takeover_packages_takeover.png differ diff --git a/src/sqlmap-master/lib/class_diagram/techniques_classes_techniques.png b/src/sqlmap-master/lib/class_diagram/techniques_classes_techniques.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/techniques_classes_techniques.png differ diff --git a/src/sqlmap-master/lib/class_diagram/techniques_packages_techniques.png b/src/sqlmap-master/lib/class_diagram/techniques_packages_techniques.png new file mode 100644 index 0000000..3fb3d13 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/techniques_packages_techniques.png differ diff --git a/src/sqlmap-master/lib/class_diagram/union_classes_union.png b/src/sqlmap-master/lib/class_diagram/union_classes_union.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/union_classes_union.png differ diff --git a/src/sqlmap-master/lib/class_diagram/union_packages_union.png b/src/sqlmap-master/lib/class_diagram/union_packages_union.png new file mode 100644 index 0000000..6a34f3a Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/union_packages_union.png differ diff --git a/src/sqlmap-master/lib/class_diagram/utils_classes_utils.png b/src/sqlmap-master/lib/class_diagram/utils_classes_utils.png new file mode 100644 index 0000000..66aec56 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/utils_classes_utils.png differ diff --git a/src/sqlmap-master/lib/class_diagram/utils_packages_utils.png b/src/sqlmap-master/lib/class_diagram/utils_packages_utils.png new file mode 100644 index 0000000..192aa84 Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/utils_packages_utils.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/access_classes_access.png b/src/sqlmap-master/plugins/dbms/class_diagram/access_classes_access.png new file mode 100644 index 0000000..c8716f0 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/access_classes_access.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/access_packages_access.png b/src/sqlmap-master/plugins/dbms/class_diagram/access_packages_access.png new file mode 100644 index 0000000..421495a Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/access_packages_access.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/altibase_classes_altibase.png b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_classes_altibase.png new file mode 100644 index 0000000..ceffc56 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_classes_altibase.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/altibase_packages_altibase.png b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_packages_altibase.png new file mode 100644 index 0000000..b11b497 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_packages_altibase.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cache_classes_cache.png b/src/sqlmap-master/plugins/dbms/class_diagram/cache_classes_cache.png new file mode 100644 index 0000000..b81383c Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cache_classes_cache.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cache_packages_cache.png b/src/sqlmap-master/plugins/dbms/class_diagram/cache_packages_cache.png new file mode 100644 index 0000000..285d370 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cache_packages_cache.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_classes_clickhouse.png b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_classes_clickhouse.png new file mode 100644 index 0000000..68d9343 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_classes_clickhouse.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_packages_clickhouse.png b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_packages_clickhouse.png new file mode 100644 index 0000000..b46b913 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_packages_clickhouse.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_classes_cratedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_classes_cratedb.png new file mode 100644 index 0000000..f54cc4d Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_classes_cratedb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_packages_cratedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_packages_cratedb.png new file mode 100644 index 0000000..1cd17d8 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_packages_cratedb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_classes_cubrid.png b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_classes_cubrid.png new file mode 100644 index 0000000..034e8eb Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_classes_cubrid.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_packages_cubrid.png b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_packages_cubrid.png new file mode 100644 index 0000000..e0e064c Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_packages_cubrid.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/db2_classes_db2.png b/src/sqlmap-master/plugins/dbms/class_diagram/db2_classes_db2.png new file mode 100644 index 0000000..d11ff5a Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/db2_classes_db2.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/db2_packages_db2.png b/src/sqlmap-master/plugins/dbms/class_diagram/db2_packages_db2.png new file mode 100644 index 0000000..336f656 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/db2_packages_db2.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/derby_classes_derby.png b/src/sqlmap-master/plugins/dbms/class_diagram/derby_classes_derby.png new file mode 100644 index 0000000..a3b7350 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/derby_classes_derby.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/derby_packages_derby.png b/src/sqlmap-master/plugins/dbms/class_diagram/derby_packages_derby.png new file mode 100644 index 0000000..e5e57a2 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/derby_packages_derby.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_classes_extremedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_classes_extremedb.png new file mode 100644 index 0000000..feda6ac Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_classes_extremedb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_packages_extremedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_packages_extremedb.png new file mode 100644 index 0000000..29a17f1 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_packages_extremedb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/firebird_classes_firebird.png b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_classes_firebird.png new file mode 100644 index 0000000..dfa47db Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_classes_firebird.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/firebird_packages_firebird.png b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_packages_firebird.png new file mode 100644 index 0000000..af96735 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_packages_firebird.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_classes_frontbase.png b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_classes_frontbase.png new file mode 100644 index 0000000..079b591 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_classes_frontbase.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_packages_frontbase.png b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_packages_frontbase.png new file mode 100644 index 0000000..9c81518 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_packages_frontbase.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/h2_classes_h2.png b/src/sqlmap-master/plugins/dbms/class_diagram/h2_classes_h2.png new file mode 100644 index 0000000..496383d Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/h2_classes_h2.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/h2_packages_h2.png b/src/sqlmap-master/plugins/dbms/class_diagram/h2_packages_h2.png new file mode 100644 index 0000000..7b977e8 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/h2_packages_h2.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_classes_hsqldb.png b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_classes_hsqldb.png new file mode 100644 index 0000000..2a3ffa0 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_classes_hsqldb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_packages_hsqldb.png b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_packages_hsqldb.png new file mode 100644 index 0000000..89c66ce Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_packages_hsqldb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/informix_classes_informix.png b/src/sqlmap-master/plugins/dbms/class_diagram/informix_classes_informix.png new file mode 100644 index 0000000..cbc5977 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/informix_classes_informix.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/informix_packages_informix.png b/src/sqlmap-master/plugins/dbms/class_diagram/informix_packages_informix.png new file mode 100644 index 0000000..0f46bc6 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/informix_packages_informix.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_classes_maxdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_classes_maxdb.png new file mode 100644 index 0000000..6d80090 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_classes_maxdb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_packages_maxdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_packages_maxdb.png new file mode 100644 index 0000000..89cc076 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_packages_maxdb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_classes_mckoi.png b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_classes_mckoi.png new file mode 100644 index 0000000..e7c65ed Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_classes_mckoi.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_packages_mckoi.png b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_packages_mckoi.png new file mode 100644 index 0000000..b8c92f8 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_packages_mckoi.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_classes_mimersql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_classes_mimersql.png new file mode 100644 index 0000000..4d25a81 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_classes_mimersql.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_packages_mimersql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_packages_mimersql.png new file mode 100644 index 0000000..2f563ef Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_packages_mimersql.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_classes_monetdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_classes_monetdb.png new file mode 100644 index 0000000..a5a7d8a Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_classes_monetdb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_packages_monetdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_packages_monetdb.png new file mode 100644 index 0000000..2ed9a4b Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_packages_monetdb.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_classes_mssqlserver.png b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_classes_mssqlserver.png new file mode 100644 index 0000000..ddc61ac Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_classes_mssqlserver.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_packages_mssqlserver.png b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_packages_mssqlserver.png new file mode 100644 index 0000000..ef94b07 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_packages_mssqlserver.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mysql_classes_mysql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_classes_mysql.png new file mode 100644 index 0000000..9eaea2f Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_classes_mysql.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mysql_packages_mysql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_packages_mysql.png new file mode 100644 index 0000000..018e829 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_packages_mysql.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/oracle_classes_oracle.png b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_classes_oracle.png new file mode 100644 index 0000000..92bccd2 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_classes_oracle.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/oracle_packages_oracle.png b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_packages_oracle.png new file mode 100644 index 0000000..28489bd Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_packages_oracle.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_classes_postgresql.png b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_classes_postgresql.png new file mode 100644 index 0000000..a5ad53d Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_classes_postgresql.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_packages_postgresql.png b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_packages_postgresql.png new file mode 100644 index 0000000..a92b34a Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_packages_postgresql.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/presto_classes_presto.png b/src/sqlmap-master/plugins/dbms/class_diagram/presto_classes_presto.png new file mode 100644 index 0000000..305d35e Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/presto_classes_presto.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/presto_packages_presto.png b/src/sqlmap-master/plugins/dbms/class_diagram/presto_packages_presto.png new file mode 100644 index 0000000..f41e9b6 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/presto_packages_presto.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/raima_classes_raima.png b/src/sqlmap-master/plugins/dbms/class_diagram/raima_classes_raima.png new file mode 100644 index 0000000..c69870a Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/raima_classes_raima.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/raima_packages_raima.png b/src/sqlmap-master/plugins/dbms/class_diagram/raima_packages_raima.png new file mode 100644 index 0000000..0034ecd Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/raima_packages_raima.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_classes_sqlite.png b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_classes_sqlite.png new file mode 100644 index 0000000..1823aa4 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_classes_sqlite.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_packages_sqlite.png b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_packages_sqlite.png new file mode 100644 index 0000000..54bb312 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_packages_sqlite.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sybase_classes_sybase.png b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_classes_sybase.png new file mode 100644 index 0000000..97471ba Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_classes_sybase.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sybase_packages_sybase.png b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_packages_sybase.png new file mode 100644 index 0000000..043c8f8 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_packages_sybase.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/vertica_classes_vertica.png b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_classes_vertica.png new file mode 100644 index 0000000..40e2f28 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_classes_vertica.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/vertica_packages_vertica.png b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_packages_vertica.png new file mode 100644 index 0000000..fea71c3 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_packages_vertica.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_classes_virtuoso.png b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_classes_virtuoso.png new file mode 100644 index 0000000..0118466 Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_classes_virtuoso.png differ diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_packages_virtuoso.png b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_packages_virtuoso.png new file mode 100644 index 0000000..39686ca Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_packages_virtuoso.png differ diff --git a/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py b/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py index b676f69..8fa5a43 100644 --- a/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py +++ b/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py @@ -32,40 +32,47 @@ from thirdparty.six.moves import zip as _zip class Enumeration(GenericEnumeration): def __init__(self): GenericEnumeration.__init__(self) - + # 将缓存的数据处理字符中的下划线替换为空格 kb.data.processChar = lambda x: x.replace('_', ' ') if x else x def getPasswordHashes(self): + # 输出警告信息,因SAP MaxDB不支持用户密码哈希的枚举 warnMsg = "on SAP MaxDB it is not possible to enumerate the user password hashes" logger.warning(warnMsg) return {} def getDbs(self): + # 若缓存的数据库信息不为空则返回缓存内容 if len(kb.data.cachedDbs) > 0: return kb.data.cachedDbs infoMsg = "fetching database names" logger.info(infoMsg) + # 查询数据库名称的SQL语句 rootQuery = queries[DBMS.MAXDB].dbs query = rootQuery.inband.query retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.schemaname' % kb.aliasName], blind=True) + # 如果查询结果有效,缓存数据库名称 if retVal: kb.data.cachedDbs = next(six.itervalues(retVal[0])) + # 对数据库名称进行排序 if kb.data.cachedDbs: kb.data.cachedDbs.sort() return kb.data.cachedDbs def getTables(self, bruteForce=None): + # 如果缓存的表信息不为空,则返回缓存内容 if len(kb.data.cachedTables) > 0: return kb.data.cachedTables self.forceDbmsEnum() + # 根据当前选中的数据库获取数据库名称 if conf.db == CURRENT_DB: conf.db = self.getCurrentDb() @@ -74,6 +81,7 @@ class Enumeration(GenericEnumeration): else: dbs = self.getDbs() + # 对数据库名称进行安全处理 for db in (_ for _ in dbs if _): dbs[dbs.index(db)] = safeSQLIdentificatorNaming(db) @@ -83,6 +91,7 @@ class Enumeration(GenericEnumeration): rootQuery = queries[DBMS.MAXDB].tables + # 遍历每个数据库,查询表名称 for db in dbs: query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER') blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) @@ -95,6 +104,7 @@ class Enumeration(GenericEnumeration): else: kb.data.cachedTables[db].append(table) + # 对每个数据库的表进行排序 for db, tables in kb.data.cachedTables.items(): kb.data.cachedTables[db] = sorted(tables) if tables else tables @@ -103,6 +113,7 @@ class Enumeration(GenericEnumeration): def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None, dumpMode=False): self.forceDbmsEnum() + # 获取当前选中的数据库 if conf.db is None or conf.db == CURRENT_DB: if conf.db is None: warnMsg = "missing database parameter. sqlmap is going " @@ -118,19 +129,24 @@ class Enumeration(GenericEnumeration): errMsg += "the tables' columns" raise SqlmapMissingMandatoryOptionException(errMsg) + # 对数据库名称进行安全处理 conf.db = safeSQLIdentificatorNaming(conf.db) + # 获取需要查询的列名 if conf.col: colList = conf.col.split(',') else: colList = [] + # 处理排除的列名 if conf.exclude: colList = [_ for _ in colList if re.search(conf.exclude, _, re.I) is None] + # 对列名进行安全处理 for col in colList: colList[colList.index(col)] = safeSQLIdentificatorNaming(col) + # 获取需要查询的表名 if conf.tbl: tblList = conf.tbl.split(',') else: @@ -146,12 +162,14 @@ class Enumeration(GenericEnumeration): errMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db) raise SqlmapNoneDataException(errMsg) + # 对表名进行安全处理 for tbl in tblList: tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl, True) if bruteForce: resumeAvailable = False + # 检查列名是否已存在于缓存中 for tbl in tblList: for db, table, colName, colType in kb.brute.columns: if db == conf.db and table == tbl: @@ -188,6 +206,7 @@ class Enumeration(GenericEnumeration): rootQuery = queries[DBMS.MAXDB].columns + # 遍历每个表,查询列名称及数据类型 for tbl in tblList: if conf.db is not None and len(kb.data.cachedColumns) > 0 and conf.db in kb.data.cachedColumns and tbl in kb.data.cachedColumns[conf.db]: infoMsg = "fetched tables' columns on " @@ -196,6 +215,7 @@ class Enumeration(GenericEnumeration): return {conf.db: kb.data.cachedColumns[conf.db]} + # 在剩余模式且限制列名时,继续缓存 if dumpMode and colList: table = {} table[safeSQLIdentificatorNaming(tbl, True)] = dict((_, None) for _ in colList) @@ -209,6 +229,7 @@ class Enumeration(GenericEnumeration): blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) + # 查询表的列名称和数据类型的SQL语句 query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER') retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=blind) @@ -216,6 +237,7 @@ class Enumeration(GenericEnumeration): table = {} columns = {} + # 将查询结果中的列名和数据类型进行处理 for columnname, datatype, length in _zip(retVal[0]["%s.columnname" % kb.aliasName], retVal[0]["%s.datatype" % kb.aliasName], retVal[0]["%s.len" % kb.aliasName]): columns[safeSQLIdentificatorNaming(columnname)] = "%s(%s)" % (datatype, length) @@ -225,21 +247,25 @@ class Enumeration(GenericEnumeration): return kb.data.cachedColumns def getPrivileges(self, *args, **kwargs): + # 输出警告信息,因SAP MaxDB不支持用户权限的枚举 warnMsg = "on SAP MaxDB it is not possible to enumerate the user privileges" logger.warning(warnMsg) return {} def search(self): + # 输出警告,表示SAP MaxDB不支持搜索功能 warnMsg = "on SAP MaxDB search option is not available" logger.warning(warnMsg) def getHostname(self): + # 输出警告信息,因SAP MaxDB不支持主机名的枚举 warnMsg = "on SAP MaxDB it is not possible to enumerate the hostname" logger.warning(warnMsg) def getStatements(self): + # 输出警告信息,因SAP MaxDB不支持SQL语句的枚举 warnMsg = "on SAP MaxDB it is not possible to enumerate the SQL statements" logger.warning(warnMsg) - return [] + return [] \ No newline at end of file diff --git a/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py b/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py index a60bc65..1c686ab 100644 --- a/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py +++ b/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py @@ -21,12 +21,19 @@ from plugins.generic.fingerprint import Fingerprint as GenericFingerprint class Fingerprint(GenericFingerprint): def __init__(self): + """ + 初始化Fingerprint类,指定为SAP MaxDB。 + """ GenericFingerprint.__init__(self, DBMS.MAXDB) def _versionCheck(self): + """ + 执行SAP MaxDB的SYSINFO版本检查。 + """ infoMsg = "executing %s SYSINFO version check" % DBMS.MAXDB logger.info(infoMsg) + # 构建查询语句 query = agent.prefixQuery("/* NoValue */") query = agent.suffixQuery(query) payload = agent.payload(newValue=query) @@ -40,12 +47,14 @@ class Fingerprint(GenericFingerprint): minor, major = None, None + # 检查主要版本号 for version in (6, 7): result = inject.checkBooleanExpression("%d=(SELECT MAJORVERSION FROM SYSINFO.VERSION)" % version) if result: major = version + # 检查次要版本号 for version in xrange(0, 10): result = inject.checkBooleanExpression("%d=(SELECT MINORVERSION FROM SYSINFO.VERSION)" % version) @@ -58,12 +67,17 @@ class Fingerprint(GenericFingerprint): return None def getFingerprint(self): + """ + 获取指纹信息。 + """ value = "" + # 获取Web服务器的操作系统指纹 wsOsFp = Format.getOs("web server", kb.headersFp) if wsOsFp: value += "%s\n" % wsOsFp + # 获取后端数据库的操作系统指纹 if kb.data.banner: dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp) @@ -77,6 +91,7 @@ class Fingerprint(GenericFingerprint): value += DBMS.MAXDB return value + # 获取活性指纹 actVer = Format.getDbms() + " (%s)" % self._versionCheck() blank = " " * 15 value += "active fingerprint: %s" % actVer @@ -84,6 +99,7 @@ class Fingerprint(GenericFingerprint): if kb.bannerFp: value += "\n%sbanner parsing fingerprint: -" % blank + # 获取HTML错误消息指纹 htmlErrorFp = Format.getErrorParsedDBMSes() if htmlErrorFp: @@ -92,9 +108,13 @@ class Fingerprint(GenericFingerprint): return value def checkDbms(self): + """ + 检测后端数据库是否为SAP MaxDB。 + """ if not conf.extensiveFp and Backend.isDbmsWithin(MAXDB_ALIASES): setDbms(DBMS.MAXDB) + # 获取Banner信息 self.getBanner() return True @@ -102,12 +122,14 @@ class Fingerprint(GenericFingerprint): infoMsg = "testing %s" % DBMS.MAXDB logger.info(infoMsg) + # 检查ALPHA(NULL)是否为NULL result = inject.checkBooleanExpression("ALPHA(NULL) IS NULL") if result: infoMsg = "confirming %s" % DBMS.MAXDB logger.info(infoMsg) + # 检查MAPCHAR(NULL,1,DEFAULTMAP)是否为NULL result = inject.checkBooleanExpression("MAPCHAR(NULL,1,DEFAULTMAP) IS NULL") if not result: @@ -128,10 +150,13 @@ class Fingerprint(GenericFingerprint): return False def forceDbmsEnum(self): + """ + 强制进行数据库枚举。 + """ if conf.db: conf.db = conf.db.upper() else: conf.db = "USER" if conf.tbl: - conf.tbl = conf.tbl.upper() + conf.tbl = conf.tbl.upper() \ No newline at end of file diff --git a/src/sqlmap-master/plugins/dbms/mysql/connector.py b/src/sqlmap-master/plugins/dbms/mysql/connector.py index e965bfe..266cb93 100644 --- a/src/sqlmap-master/plugins/dbms/mysql/connector.py +++ b/src/sqlmap-master/plugins/dbms/mysql/connector.py @@ -13,11 +13,12 @@ except: import logging import struct -from lib.core.common import getSafeExString -from lib.core.data import conf -from lib.core.data import logger -from lib.core.exception import SqlmapConnectionException -from plugins.generic.connector import Connector as GenericConnector +from lib.core.common import getSafeExString # 用于安全获取异常字符串的函数 +from lib.core.data import conf # sqlmap的配置管理 +from lib.core.data import logger # sqlmap的日志记录模块 +from lib.core.exception import SqlmapConnectionException # 自定义的连接异常 +from plugins.generic.connector import Connector as GenericConnector # 基础连接类 + class Connector(GenericConnector): """ @@ -30,17 +31,28 @@ class Connector(GenericConnector): """ def connect(self): + """ + 初始化到MySQL数据库的连接。 + 使用提供的凭据和配置设置建立连接。 + """ self.initConnection() try: - self.connector = pymysql.connect(host=self.hostname, user=self.user, passwd=self.password, db=self.db, port=self.port, connect_timeout=conf.timeout, use_unicode=True) + self.connector = pymysql.connect(host=self.hostname, user=self.user, passwd=self.password, db=self.db, port=self.port, connect_timeout=conf.timeout, use_unicode=True) # 确保使用Unicode进行字符编码 except (pymysql.OperationalError, pymysql.InternalError, pymysql.ProgrammingError, struct.error) as ex: + # 如果在连接期间发生错误,抛出连接异常 raise SqlmapConnectionException(getSafeExString(ex)) - self.initCursor() - self.printConnected() + self.initCursor() # 初始化用于执行查询的游标 + self.printConnected() # 记录连接成功的信息 def fetchall(self): + """ + 从游标结果集中获取所有行。 + + 返回: + 从数据库获取的行列表,或者在发生错误时返回None。 + """ try: return self.cursor.fetchall() except pymysql.ProgrammingError as ex: @@ -48,6 +60,17 @@ class Connector(GenericConnector): return None def execute(self, query): + + """ + 在数据库上执行SQL查询。 + + 参数: + query (str): 要执行的SQL查询。 + + 返回: + bool: 如果查询成功执行,返回True;否则返回False。 + """ + retVal = False try: @@ -63,6 +86,15 @@ class Connector(GenericConnector): return retVal def select(self, query): + """ + 执行SELECT SQL查询并返回结果。 + + 参数: + query (str): 要执行的SELECT SQL查询。 + + 返回: + 从数据库获取的行列表,或者如果执行失败则返回None。 + """ retVal = None if self.execute(query): diff --git a/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py b/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py index 5f32b4f..4f4b4ec 100644 --- a/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py +++ b/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py @@ -17,17 +17,23 @@ from lib.core.settings import SQLITE_ALIASES from lib.request import inject from plugins.generic.fingerprint import Fingerprint as GenericFingerprint +# 该插件用于检测sqlite数据库,通过执行一些常用函数来判断数据库类型,并获取数据库版本信息,最后返回检测结果。 +# 通过执行SQLITE_VERSION()函数来判断数据库类型,获取数据库版本信息,检测数据库是否存在。 + class Fingerprint(GenericFingerprint): def __init__(self): + # 初始化父类Fingerprint,对象的数据库管理系统类型设置为SQLite GenericFingerprint.__init__(self, DBMS.SQLITE) def getFingerprint(self): value = "" + # 获取Web服务器的操作系统指纹 wsOsFp = Format.getOs("web server", kb.headersFp) if wsOsFp: value += "%s\n" % wsOsFp + # 获取数据库服务器的操作系统指纹 if kb.data.banner: dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp) @@ -36,14 +42,17 @@ class Fingerprint(GenericFingerprint): value += "back-end DBMS: " + # 如果不是详尽指纹模式,直接返回DBMS类型 if not conf.extensiveFp: value += DBMS.SQLITE return value + # 获取当前活动的数据库管理系统信息 actVer = Format.getDbms() blank = " " * 15 value += "active fingerprint: %s" % actVer + # 如果有数据库版本信息的指纹,则进行处理 if kb.bannerFp: banVer = kb.bannerFp.get("dbmsVersion") @@ -51,6 +60,7 @@ class Fingerprint(GenericFingerprint): banVer = Format.getDbms([banVer]) value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) + # 获取HTML错误消息中的指纹 htmlErrorFp = Format.getErrorParsedDBMSes() if htmlErrorFp: @@ -66,6 +76,7 @@ class Fingerprint(GenericFingerprint): * http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions """ + # 如果不是详尽指纹模式并且数据库管理系统在已知的SQLite别名之中 if not conf.extensiveFp and Backend.isDbmsWithin(SQLITE_ALIASES): setDbms(DBMS.SQLITE) @@ -76,12 +87,14 @@ class Fingerprint(GenericFingerprint): infoMsg = "testing %s" % DBMS.SQLITE logger.info(infoMsg) + # 检查布尔表达式,验证是否为SQLite result = inject.checkBooleanExpression("LAST_INSERT_ROWID()=LAST_INSERT_ROWID()") if result: infoMsg = "confirming %s" % DBMS.SQLITE logger.info(infoMsg) + # 进一步确认数据库版本 result = inject.checkBooleanExpression("SQLITE_VERSION()=SQLITE_VERSION()") if not result: @@ -93,6 +106,7 @@ class Fingerprint(GenericFingerprint): infoMsg = "actively fingerprinting %s" % DBMS.SQLITE logger.info(infoMsg) + # 依据RANDOMBLOB函数确定SQLite版本 result = inject.checkBooleanExpression("RANDOMBLOB(-1)>0") version = '3' if result else '2' Backend.setVersion(version) @@ -109,4 +123,5 @@ class Fingerprint(GenericFingerprint): return False def forceDbmsEnum(self): + # 强制数据库管理系统枚举,设置数据库名称 conf.db = "%s%s" % (DBMS.SQLITE, METADB_SUFFIX) diff --git a/src/sqlmap-master/plugins/generic/class_diagram/class_diagram_classes_class_diagram.png b/src/sqlmap-master/plugins/generic/class_diagram/class_diagram_classes_class_diagram.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/plugins/generic/class_diagram/class_diagram_classes_class_diagram.png differ diff --git a/src/sqlmap-master/plugins/generic/class_diagram/generic_classes_generic.png b/src/sqlmap-master/plugins/generic/class_diagram/generic_classes_generic.png new file mode 100644 index 0000000..7994a60 Binary files /dev/null and b/src/sqlmap-master/plugins/generic/class_diagram/generic_classes_generic.png differ diff --git a/src/sqlmap-master/plugins/generic/class_diagram/generic_packages_generic.png b/src/sqlmap-master/plugins/generic/class_diagram/generic_packages_generic.png new file mode 100644 index 0000000..a37df7d Binary files /dev/null and b/src/sqlmap-master/plugins/generic/class_diagram/generic_packages_generic.png differ diff --git a/src/sqlmap-master/sqlmap.py b/src/sqlmap-master/sqlmap.py index 70fb972..cd8385d 100644 --- a/src/sqlmap-master/sqlmap.py +++ b/src/sqlmap-master/sqlmap.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) +Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) See the file 'LICENSE' for copying permission """ @@ -10,13 +10,16 @@ from __future__ import print_function try: import sys + # 防止Python自动生成.pyc文件 sys.dont_write_bytecode = True try: + # 检查sqlmap的安装是否正确 __import__("lib.utils.versioncheck") # this has to be the first non-standard import except ImportError: sys.exit("[!] wrong installation detected (missing modules). Visit 'https://github.com/sqlmapproject/sqlmap/#installation' for further details") + # 导入标准库模块 import bdb import glob import inspect @@ -32,6 +35,7 @@ try: import traceback import warnings + # 忽略DeprecationWarning,除非命令行参数中包含"--deprecations" if "--deprecations" not in sys.argv: warnings.filterwarnings(action="ignore", category=DeprecationWarning) else: @@ -41,14 +45,17 @@ try: if sys.version_info >= (3, 0): warnings.simplefilter("ignore", category=ResourceWarning) + # 忽略特定警告 warnings.filterwarnings(action="ignore", message="Python 2 is no longer supported") warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning) warnings.filterwarnings(action="ignore", message=".*using a very old release", category=UserWarning) warnings.filterwarnings(action="ignore", message=".*default buffer size will be used", category=RuntimeWarning) warnings.filterwarnings(action="ignore", category=UserWarning, module="psycopg2") + # 导入sqlmap的核心日志模块 from lib.core.data import logger + # 导入sqlmap的核心功能模块 from lib.core.common import banner from lib.core.common import checkPipedInput from lib.core.common import checkSums @@ -90,6 +97,8 @@ try: from lib.core.settings import VERSION from lib.parse.cmdline import cmdLineParser from lib.utils.crawler import crawl +except Exception as ex: + print("An error occurred: " + str(ex)) except KeyboardInterrupt: errMsg = "user aborted" @@ -102,26 +111,38 @@ except KeyboardInterrupt: def modulePath(): """ - This will get us the program's directory, even if we are frozen - using py2exe - """ + 获取程序的目录路径,即使使用了 py2exe 进行冻结打包也能正确获取。 + 返回值: + 返回程序所在目录的Unicode编码路径字符串。 + """ try: + # 如果程序被py2exe冻结,则使用sys.executable获取路径;否则使用__file__获取 _ = sys.executable if weAreFrozen() else __file__ except NameError: + # 如果__file__未定义(在某些环境下可能发生),则使用inspect模块获取当前函数的文件路径 _ = inspect.getsourcefile(modulePath) + # 获取_的目录路径,并转换为Unicode编码 return getUnicode(os.path.dirname(os.path.realpath(_)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING) def checkEnvironment(): + """ + 检查运行环境是否适合运行 sqlmap。 + + 如果在检查过程中发现问题,则会记录错误信息并退出程序。 + """ try: + # 检查程序目录是否存在 os.path.isdir(modulePath()) except UnicodeEncodeError: + # 如果系统无法正确处理非ASCII路径,则记录错误信息并退出 errMsg = "your system does not properly handle non-ASCII paths. " errMsg += "Please move the sqlmap's directory to the other location" logger.critical(errMsg) raise SystemExit + # 检查sqlmap的版本是否低于1.0,如果是,则说明运行环境有问题 if LooseVersion(VERSION) < LooseVersion("1.0"): errMsg = "your runtime environment (e.g. PYTHONPATH) is " errMsg += "broken. Please make sure that you are not running " @@ -130,68 +151,81 @@ def checkEnvironment(): logger.critical(errMsg) raise SystemExit - # Patch for pip (import) environment + # 如果是通过pip安装的sqlmap,则需要对sys.modules进行一些修补操作 if "sqlmap.sqlmap" in sys.modules: for _ in ("cmdLineOptions", "conf", "kb"): + # 将lib.core.data模块中的cmdLineOptions、conf、kb变量添加到全局变量中 globals()[_] = getattr(sys.modules["lib.core.data"], _) for _ in ("SqlmapBaseException", "SqlmapShellQuitException", "SqlmapSilentQuitException", "SqlmapUserQuitException"): + # 将lib.core.exception模块中的异常类添加到全局变量中 globals()[_] = getattr(sys.modules["lib.core.exception"], _) - def main(): """ - Main function of sqlmap when running from command line. + 当从命令行运行时,这是 sqlmap 的主函数。 """ try: + # 应用脏补丁和解析交叉引用 dirtyPatches() resolveCrossReferences() + + # 检查运行环境并设置程序路径 checkEnvironment() setPaths(modulePath()) banner() - # Store original command line options for possible later restoration + # 解析命令行参数并更新全局配置 args = cmdLineParser() cmdLineOptions.update(args.__dict__ if hasattr(args, "__dict__") else args) initOptions(cmdLineOptions) + # 如果有管道输入,则设置批量模式 if checkPipedInput(): conf.batch = True + # 如果配置了API,设置API日志和重定向标准输出和错误 if conf.get("api"): - # heavy imports + # 延迟导入(重量级导入) from lib.utils.api import StdDbOut from lib.utils.api import setRestAPILog - # Overwrite system standard output and standard error to write - # to an IPC database + # 重定向标准输出和错误到IPC数据库 sys.stdout = StdDbOut(conf.taskid, messagetype="stdout") sys.stderr = StdDbOut(conf.taskid, messagetype="stderr") setRestAPILog() + # 设置显示时间并显示法律声明和启动信息 conf.showTime = True dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True) dataToStdout("[*] starting @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True) + # 初始化程序 init() + # 如果没有设置更新所有选项,则执行后续操作 if not conf.updateAll: - # Postponed imports (faster start) + # 延迟导入(更快的启动) if conf.smokeTest: + # 运行烟雾测试 from lib.core.testing import smokeTest os._exitcode = 1 - (smokeTest() or 0) elif conf.vulnTest: + # 运行漏洞测试 from lib.core.testing import vulnTest os._exitcode = 1 - (vulnTest() or 0) else: + # 启动sqlmap控制器 from lib.controller.controller import start if conf.profile: + # 如果设置了性能分析,则进行性能分析 from lib.core.profiling import profile globals()["start"] = start profile() else: try: + # 如果设置了爬取深度和批量文件,则开始爬取 if conf.crawlDepth and conf.bulkFile: targets = getFileItems(conf.bulkFile) @@ -223,6 +257,7 @@ def main(): except Exception as ex: os._exitcode = 1 + # 如果无法启动新线程,则记录错误信息并退出 if "can't start new thread" in getSafeExString(ex): errMsg = "unable to start new threads. Please check OS (u)limits" logger.critical(errMsg) @@ -230,6 +265,7 @@ def main(): else: raise + # 捕获并处理各种异常,记录错误信息并退出 except SqlmapUserQuitException: if not conf.batch: errMsg = "user quit" @@ -272,61 +308,73 @@ def main(): os._exitcode = 255 + # 如果异常信息中包含内存耗尽相关的消息,则记录内存耗尽错误并退出 if any(_ in excMsg for _ in ("MemoryError", "Cannot allocate memory")): errMsg = "memory exhaustion detected" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含磁盘空间不足相关的消息,则记录磁盘空间错误并退出 elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded", "Disk full while accessing")): errMsg = "no space left on output device" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含分页文件空间不足的消息,则记录分页文件空间错误并退出 elif any(_ in excMsg for _ in ("The paging file is too small",)): errMsg = "no space left for paging file" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含权限拒绝和Metasploit相关的消息,则记录Metasploit权限错误并退出 elif all(_ in excMsg for _ in ("Access is denied", "subprocess", "metasploit")): errMsg = "permission error occurred while running Metasploit" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含权限拒绝和metasploit相关的消息,则记录Metasploit权限错误并退出 elif all(_ in excMsg for _ in ("Permission denied", "metasploit")): errMsg = "permission error occurred while using Metasploit" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含只读文件系统的消息,则记录只读文件系统错误并退出 elif "Read-only file system" in excMsg: errMsg = "output device is mounted as read-only" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含系统资源不足的消息,则记录资源耗尽错误并退出 elif "Insufficient system resources" in excMsg: errMsg = "resource exhaustion detected" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含磁盘I/O错误的消息,则记录I/O错误并退出 elif "OperationalError: disk I/O error" in excMsg: errMsg = "I/O error on output device" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含URL违反BIDI规则的消息,则记录无效URL错误并退出 elif "Violation of BIDI" in excMsg: errMsg = "invalid URL (violation of Bidi IDNA rule - RFC 5893)" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含无效IPv6 URL的消息,则记录无效URL错误并退出 elif "Invalid IPv6 URL" in excMsg: errMsg = "invalid URL ('%s')" % excMsg.strip().split('\n')[-1] logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含临时文件访问问题的消息,则记录临时文件访问错误并退出 elif "_mkstemp_inner" in excMsg: errMsg = "there has been a problem while accessing temporary files" logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含无法写入临时目录的消息,则记录临时目录写入错误并退出 elif any(_ in excMsg for _ in ("tempfile.mkdtemp", "tempfile.mkstemp", "tempfile.py")): errMsg = "unable to write to the temporary directory '%s'. " % tempfile.gettempdir() errMsg += "Please make sure that your disk is not full and " @@ -335,131 +383,139 @@ def main(): logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含权限拒绝的消息,则记录文件访问权限错误并退出 elif "Permission denied: '" in excMsg: match = re.search(r"Permission denied: '([^']*)", excMsg) errMsg = "permission error occurred while accessing file '%s'" % match.group(1) logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含sqlalchemy包版本问题的消息,则记录sqlalchemy版本错误并退出 elif all(_ in excMsg for _ in ("twophase", "sqlalchemy")): errMsg = "please update the 'sqlalchemy' package (>= 1.1.11) " - errMsg += "(Reference: 'https://qiita.com/tkprof/items/7d7b2d00df9c5f16fffe')" + # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含Python版本问题的消息,则记录Python版本错误并退出 elif "invalid maximum character passed to PyUnicode_New" in excMsg and re.search(r"\A3\.[34]", sys.version) is not None: errMsg = "please upgrade the Python version (>= 3.5) " - errMsg += "(Reference: 'https://bugs.python.org/issue18183')" + # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) raise SystemExit + # 如果异常信息中包含PyMySQL包版本问题的消息,则记录PyMySQL版本错误并退出 elif all(_ in excMsg for _ in ("scramble_caching_sha2", "TypeError")): errMsg = "please downgrade the 'PyMySQL' package (=< 0.8.1) " - errMsg += "(Reference: 'https://github.com/PyMySQL/PyMySQL/issues/700')" - logger.critical(errMsg) - raise SystemExit - - elif "must be pinned buffer, not bytearray" in excMsg: - errMsg = "error occurred at Python interpreter which " - errMsg += "is fixed in 2.7. Please update accordingly " - errMsg += "(Reference: 'https://bugs.python.org/issue8104')" + # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。 logger.critical(errMsg) raise SystemExit - elif all(_ in excMsg for _ in ("OSError: [Errno 22] Invalid argument: '", "importlib")): - errMsg = "unable to read file '%s'" % extractRegexResult(r"OSError: \[Errno 22\] Invalid argument: '(?P<result>[^']+)", excMsg) - logger.critical(errMsg) - raise SystemExit + # 如果异常信息中包含Python解 - elif "hash_randomization" in excMsg: - errMsg = "error occurred at Python interpreter which " - errMsg += "is fixed in 2.7.3. Please update accordingly " - errMsg += "(Reference: 'https://docs.python.org/2/library/sys.html')" - logger.critical(errMsg) - raise SystemExit - - elif "AttributeError: unable to access item" in excMsg and re.search(r"3\.11\.\d+a", sys.version): - errMsg = "there is a known issue when sqlmap is run with ALPHA versions of Python 3.11. " - errMsg += "Please downgrade to some stable Python version" - logger.critical(errMsg) - raise SystemExit - - elif all(_ in excMsg for _ in ("Resource temporarily unavailable", "os.fork()", "dictionaryAttack")): - errMsg = "there has been a problem while running the multiprocessing hash cracking. " - errMsg += "Please rerun with option '--threads=1'" - logger.critical(errMsg) - raise SystemExit - - elif "can't start new thread" in excMsg: - errMsg = "there has been a problem while creating new thread instance. " - errMsg += "Please make sure that you are not running too many processes" - if not IS_WIN: - errMsg += " (or increase the 'ulimit -u' value)" - logger.critical(errMsg) - raise SystemExit - - elif "can't allocate read lock" in excMsg: - errMsg = "there has been a problem in regular socket operation " - errMsg += "('%s')" % excMsg.strip().split('\n')[-1] - logger.critical(errMsg) - raise SystemExit + # 假设excMsg是一个包含异常信息的字符串变量 + # 检查excMsg是否包含"pymysql"和"configparser"这两个字符串 elif all(_ in excMsg for _ in ("pymysql", "configparser")): + # 如果都包含,则设置错误信息为检测到'pymsql'的错误初始化(使用了Python3的依赖) errMsg = "wrong initialization of 'pymsql' detected (using Python3 dependencies)" + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查excMsg是否包含"ntlm"、"socket.error, err"和"SyntaxError"这三个字符串 elif all(_ in excMsg for _ in ("ntlm", "socket.error, err", "SyntaxError")): + # 如果都包含,则设置错误信息为检测到'python-ntlm'的错误初始化(使用了Python2的语法) errMsg = "wrong initialization of 'python-ntlm' detected (using Python2 syntax)" + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查excMsg是否包含"drda"和"to_bytes"这两个字符串 elif all(_ in excMsg for _ in ("drda", "to_bytes")): + # 如果都包含,则设置错误信息为检测到'drda'的错误初始化(使用了Python3的语法) errMsg = "wrong initialization of 'drda' detected (using Python3 syntax)" + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit - + + # 检查excMsg是否包含特定的错误信息,即'WebSocket'对象没有'status'属性 elif "'WebSocket' object has no attribute 'status'" in excMsg: + # 如果包含,则设置错误信息为检测到错误的websocket库 errMsg = "wrong websocket library detected" - errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')" + # 添加参考链接到错误信息中 + errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')" + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查excMsg是否包含特定的错误信息,即初始化GUI界面时出现问题 elif all(_ in excMsg for _ in ("window = tkinter.Tk()",)): + # 如果包含,则设置错误信息为GUI界面初始化问题 errMsg = "there has been a problem in initialization of GUI interface " + # 添加具体的错误信息到错误消息中 errMsg += "('%s')" % excMsg.strip().split('\n')[-1] + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查excMsg是否包含特定的错误信息,即使用了不同版本的sqlmap文件 elif any(_ in excMsg for _ in ("unable to access item 'liveTest'",)): + # 如果包含,则设置错误信息为检测到使用了不同版本的sqlmap文件 errMsg = "detected usage of files from different versions of sqlmap" + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查errMsg是否包含特定的错误信息,即版本号相关的错误 elif any(_ in errMsg for _ in (": 9.9.9#",)): + # 如果包含,则设置错误信息为一个简单的文本 errMsg = "LOL xD" + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查是否设置了键盘中断的标记 elif kb.get("dumpKeyboardInterrupt"): + # 如果设置了,则抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查excMsg是否包含特定的错误信息,即"Broken pipe" elif any(_ in excMsg for _ in ("Broken pipe",)): + # 如果包含,则直接抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查valid变量是否为False elif valid is False: + # 如果为False,则设置错误信息为代码校验失败 errMsg = "code checksum failed (turning off automatic issue creation). " errMsg += "You should retrieve the latest development version from official GitHub " errMsg += "repository at '%s'" % GIT_PAGE + # 使用logger记录这个严重错误 logger.critical(errMsg) + # 打印空行 print() + # 将错误信息输出到标准输出 dataToStdout(excMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit + # 检查errMsg和excMsg组合后是否包含特定的错误信息,即文件路径或特定参数 elif any(_ in "%s\n%s" % (errMsg, excMsg) for _ in ("tamper/", "waf/", "--engagement-dojo")): + # 如果包含,则使用logger记录这个严重错误 logger.critical(errMsg) + # 打印空行 print() + # 将错误信息输出到标准输出 dataToStdout(excMsg) + # 抛出SystemExit异常,导致程序退出 raise SystemExit elif any(_ in excMsg for _ in ("ImportError", "ModuleNotFoundError", "<frozen", "Can't find file for module", "SAXReaderNotAvailable", "<built-in function compile> returned NULL without setting an exception", "source code string cannot contain null bytes", "No module named", "tp_name field", "module 'sqlite3' has no attribute 'OperationalError'")): @@ -606,21 +662,31 @@ def main(): conf.disableBanner = True main() +# 检查是否是作为主模块运行,如果是,则执行以下代码 if __name__ == "__main__": try: + # 尝试调用main函数 main() except KeyboardInterrupt: + # 如果用户按下Ctrl+C(键盘中断),则捕获KeyboardInterrupt异常,但不执行任何操作(pass表示空操作) pass except SystemExit: + # 如果程序调用了sys.exit(),则重新抛出SystemExit异常,允许正常退出流程 raise except: + # 捕获其他所有异常,并打印异常信息 traceback.print_exc() finally: - # Reference: http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program + # 无论try块中的代码是否成功执行,都会执行finally块中的代码 + # 参考:http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program + # 检查当前线程数量是否大于1(主线程和至少一个其他线程) if threading.active_count() > 1: + # 如果大于1,则调用os._exit强制退出程序,不进行清理操作 + # getattr(os, "_exitcode", 0)用于获取os模块的_exitcode属性,如果不存在则默认为0 os._exit(getattr(os, "_exitcode", 0)) else: + # 如果只有主线程,则正常退出程序 sys.exit(getattr(os, "_exitcode", 0)) else: - # cancelling postponed imports (because of CI/CD checks) - __import__("lib.controller.controller") + # 如果不是作为主模块运行,则取消延迟导入(因为CI/CD检查) + __import__("lib.controller.controller") \ No newline at end of file diff --git a/src/sqlmap-master/tamper/class_diagram/class_diagram_classes_class_diagram.png b/src/sqlmap-master/tamper/class_diagram/class_diagram_classes_class_diagram.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/tamper/class_diagram/class_diagram_classes_class_diagram.png differ diff --git a/src/sqlmap-master/tamper/class_diagram/tamper_classes_tamper.png b/src/sqlmap-master/tamper/class_diagram/tamper_classes_tamper.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/tamper/class_diagram/tamper_classes_tamper.png differ diff --git a/src/sqlmap-master/tamper/class_diagram/tamper_packages_tamper.png b/src/sqlmap-master/tamper/class_diagram/tamper_packages_tamper.png new file mode 100644 index 0000000..7278781 Binary files /dev/null and b/src/sqlmap-master/tamper/class_diagram/tamper_packages_tamper.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/ansistrm_classes_ansistrm.png b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_classes_ansistrm.png new file mode 100644 index 0000000..a1efc3f Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_classes_ansistrm.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/ansistrm_packages_ansistrm.png b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_packages_ansistrm.png new file mode 100644 index 0000000..6017f12 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_packages_ansistrm.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_classes_beautifulsoup.png b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_classes_beautifulsoup.png new file mode 100644 index 0000000..ae333d2 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_classes_beautifulsoup.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_packages_beautifulsoup.png b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_packages_beautifulsoup.png new file mode 100644 index 0000000..8061c87 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_packages_beautifulsoup.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/bottle_classes_bottle.png b/src/sqlmap-master/thirdparty/class_diagram/bottle_classes_bottle.png new file mode 100644 index 0000000..e9a56cb Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/bottle_classes_bottle.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/bottle_packages_bottle.png b/src/sqlmap-master/thirdparty/class_diagram/bottle_packages_bottle.png new file mode 100644 index 0000000..8242e92 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/bottle_packages_bottle.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/chardet_classes_chardet.png b/src/sqlmap-master/thirdparty/class_diagram/chardet_classes_chardet.png new file mode 100644 index 0000000..08b6c01 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/chardet_classes_chardet.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/chardet_packages_chardet.png b/src/sqlmap-master/thirdparty/class_diagram/chardet_packages_chardet.png new file mode 100644 index 0000000..570855c Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/chardet_packages_chardet.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/clientform_classes_clientform.png b/src/sqlmap-master/thirdparty/class_diagram/clientform_classes_clientform.png new file mode 100644 index 0000000..dbb2fd1 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/clientform_classes_clientform.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/clientform_packages_clientform.png b/src/sqlmap-master/thirdparty/class_diagram/clientform_packages_clientform.png new file mode 100644 index 0000000..8c9add4 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/clientform_packages_clientform.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/colorama_classes_colorama.png b/src/sqlmap-master/thirdparty/class_diagram/colorama_classes_colorama.png new file mode 100644 index 0000000..e212382 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/colorama_classes_colorama.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/colorama_packages_colorama.png b/src/sqlmap-master/thirdparty/class_diagram/colorama_packages_colorama.png new file mode 100644 index 0000000..93a133f Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/colorama_packages_colorama.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/fcrypt_classes_fcrypt.png b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_classes_fcrypt.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_classes_fcrypt.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/fcrypt_packages_fcrypt.png b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_packages_fcrypt.png new file mode 100644 index 0000000..a00060a Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_packages_fcrypt.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/identywaf_classes_identywaf.png b/src/sqlmap-master/thirdparty/class_diagram/identywaf_classes_identywaf.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/identywaf_classes_identywaf.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/identywaf_packages_identywaf.png b/src/sqlmap-master/thirdparty/class_diagram/identywaf_packages_identywaf.png new file mode 100644 index 0000000..f39d923 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/identywaf_packages_identywaf.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/keepalive_classes_keepalive.png b/src/sqlmap-master/thirdparty/class_diagram/keepalive_classes_keepalive.png new file mode 100644 index 0000000..d770bba Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/keepalive_classes_keepalive.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/keepalive_packages_keepalive.png b/src/sqlmap-master/thirdparty/class_diagram/keepalive_packages_keepalive.png new file mode 100644 index 0000000..9d58587 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/keepalive_packages_keepalive.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/magic_classes_magic.png b/src/sqlmap-master/thirdparty/class_diagram/magic_classes_magic.png new file mode 100644 index 0000000..f86b124 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/magic_classes_magic.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/magic_packages_magic.png b/src/sqlmap-master/thirdparty/class_diagram/magic_packages_magic.png new file mode 100644 index 0000000..f9298b3 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/magic_packages_magic.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/multipart_classes_multipart.png b/src/sqlmap-master/thirdparty/class_diagram/multipart_classes_multipart.png new file mode 100644 index 0000000..5c10f0f Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/multipart_classes_multipart.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/multipart_packages_multipart.png b/src/sqlmap-master/thirdparty/class_diagram/multipart_packages_multipart.png new file mode 100644 index 0000000..072e924 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/multipart_packages_multipart.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/odict_classes_odict.png b/src/sqlmap-master/thirdparty/class_diagram/odict_classes_odict.png new file mode 100644 index 0000000..1cd5229 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/odict_classes_odict.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/odict_packages_odict.png b/src/sqlmap-master/thirdparty/class_diagram/odict_packages_odict.png new file mode 100644 index 0000000..34b7e4f Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/odict_packages_odict.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/prettyprint_classes_prettyprint.png b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_classes_prettyprint.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_classes_prettyprint.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/prettyprint_packages_prettyprint.png b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_packages_prettyprint.png new file mode 100644 index 0000000..a9fca5a Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_packages_prettyprint.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/pydes_classes_pydes.png b/src/sqlmap-master/thirdparty/class_diagram/pydes_classes_pydes.png new file mode 100644 index 0000000..e7753cc Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/pydes_classes_pydes.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/pydes_packages_pydes.png b/src/sqlmap-master/thirdparty/class_diagram/pydes_packages_pydes.png new file mode 100644 index 0000000..246230a Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/pydes_packages_pydes.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/six_classes_six.png b/src/sqlmap-master/thirdparty/class_diagram/six_classes_six.png new file mode 100644 index 0000000..c954792 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/six_classes_six.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/socks_classes_socks.png b/src/sqlmap-master/thirdparty/class_diagram/socks_classes_socks.png new file mode 100644 index 0000000..b8d3c7d Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/socks_classes_socks.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/socks_packages_socks.png b/src/sqlmap-master/thirdparty/class_diagram/socks_packages_socks.png new file mode 100644 index 0000000..1c5f9c4 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/socks_packages_socks.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/termcolor_classes_termcolor.png b/src/sqlmap-master/thirdparty/class_diagram/termcolor_classes_termcolor.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/termcolor_classes_termcolor.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/termcolor_packages_termcolor.png b/src/sqlmap-master/thirdparty/class_diagram/termcolor_packages_termcolor.png new file mode 100644 index 0000000..91df5e1 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/termcolor_packages_termcolor.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/wininetpton_classes_wininetpton.png b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_classes_wininetpton.png new file mode 100644 index 0000000..f69e17b Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_classes_wininetpton.png differ diff --git a/src/sqlmap-master/thirdparty/class_diagram/wininetpton_packages_wininetpton.png b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_packages_wininetpton.png new file mode 100644 index 0000000..165aa31 Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_packages_wininetpton.png differ diff --git a/src/sqlmap-master/thirdparty/socks/socks.py b/src/sqlmap-master/thirdparty/socks/socks.py index 4005cab..af914a4 100644 --- a/src/sqlmap-master/thirdparty/socks/socks.py +++ b/src/sqlmap-master/thirdparty/socks/socks.py @@ -121,6 +121,7 @@ def unwrapmodule(module): module.socket.socket = _orgsocket module.socket.create_connection = _orgcreateconnection + class socksocket(socket.socket): """socksocket([family[, type[, proto]]]) -> socket object Open a SOCKS enabled socket. The parameters are the same as @@ -129,11 +130,17 @@ class socksocket(socket.socket): """ def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None): + # 初始化父类 socket _orgsocket.__init__(self, family, type, proto, _sock) + + # 根据默认代理设置代理 if _defaultproxy != None: self.__proxy = _defaultproxy else: + # 初始化代理信息,如果没有默认代理则设为空元组 self.__proxy = (None, None, None, None, None, None) + + # 用于保存代理关联的本地socket信息 self.__proxysockname = None self.__proxypeername = None @@ -142,121 +149,111 @@ class socksocket(socket.socket): Receive EXACTLY the number of bytes requested from the socket. Blocks until the required number of bytes have been received. """ + # 从socket接收指定字节数数据 data = self.recv(count) + # 当接收的数据少于请求的字节数时继续接收 while len(data) < count: - d = self.recv(count-len(data)) - if not d: raise GeneralProxyError((0, "connection closed unexpectedly")) - data = data + d + d = self.recv(count - len(data)) + if not d: + raise GeneralProxyError((0, "connection closed unexpectedly")) # 如果连接关闭则抛出异常 + data = data + d # 累加接收到的数据 return data def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None): """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) Sets the proxy to be used. - proxytype - The type of the proxy to be used. Three types - are supported: PROXY_TYPE_SOCKS4 (including socks4a), - PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP - addr - The address of the server (IP or DNS). - port - The port of the server. Defaults to 1080 for SOCKS - servers and 8080 for HTTP proxy servers. - rdns - Should DNS queries be preformed on the remote side - (rather than the local side). The default is True. - Note: This has no effect with SOCKS4 servers. - username - Username to authenticate with to the server. - The default is no authentication. - password - Password to authenticate with to the server. - Only relevant when username is also provided. """ + # 设置代理类型、地址、端口等参数 self.__proxy = (proxytype, addr, port, rdns, username, password) def __negotiatesocks5(self, destaddr, destport): """__negotiatesocks5(self,destaddr,destport) Negotiates a connection through a SOCKS5 server. """ - # First we'll send the authentication packages we support. - if (self.__proxy[4]!=None) and (self.__proxy[5]!=None): - # The username/password details were supplied to the - # setproxy method so we support the USERNAME/PASSWORD - # authentication (in addition to the standard none). - self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02)) + # 发送支持的认证方法 + if (self.__proxy[4] != None) and (self.__proxy[5] != None): + # 如果提供了用户名和密码,则支持用户名/密码认证 + self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02)) # 0x02 代表用户名/密码认证 else: - # No username/password were entered, therefore we - # only support connections with no authentication. - self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00)) - # We'll receive the server's response to determine which - # method was selected + # 仅支持无认证连接 + self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00)) # 0x01 代表无认证 + + # 接收服务器的响应以确定选定的身份验证方法 chosenauth = self.__recvall(2) if chosenauth[0:1] != b'\x05': self.close() - raise GeneralProxyError((1, _generalerrors[1])) - # Check the chosen authentication method + raise GeneralProxyError((1, _generalerrors[1])) # 无效的协议版本 + + # 检查所选的身份验证方法 if chosenauth[1:2] == b'\x00': - # No authentication is required + # 无需身份验证 pass elif chosenauth[1:2] == b'\x02': - # Okay, we need to perform a basic username/password - # authentication. - self.sendall(b'\x01' + chr(len(self.__proxy[4])).encode() + self.__proxy[4].encode() + chr(len(self.__proxy[5])).encode() + self.__proxy[5].encode()) - authstat = self.__recvall(2) + # 需要进行用户名/密码身份验证 + self.sendall(b'\x01' + chr(len(self.__proxy[4])).encode() + self.__proxy[4].encode() + chr( + len(self.__proxy[5])).encode() + self.__proxy[5].encode()) + authstat = self.__recvall(2) # 接收身份验证状态 if authstat[0:1] != b'\x01': - # Bad response self.close() - raise GeneralProxyError((1, _generalerrors[1])) + raise GeneralProxyError((1, _generalerrors[1])) # 无效的认证响应 if authstat[1:2] != b'\x00': - # Authentication failed self.close() - raise Socks5AuthError((3, _socks5autherrors[3])) - # Authentication succeeded + raise Socks5AuthError((3, _socks5autherrors[3])) # 身份验证失败 else: - # Reaching here is always bad + # 非法的身份验证方法 self.close() if chosenauth[1:2] == b'\xff': - raise Socks5AuthError((2, _socks5autherrors[2])) + raise Socks5AuthError((2, _socks5autherrors[2])) # 不支持的身份验证 else: raise GeneralProxyError((1, _generalerrors[1])) - # Now we can request the actual connection - req = struct.pack('BBB', 0x05, 0x01, 0x00) - # If the given destination address is an IP address, we'll - # use the IPv4 address request even if remote resolving was specified. + + # 请求实际连接 + req = struct.pack('BBB', 0x05, 0x01, 0x00) # 0x01 表示连接请求 try: + # 尝试将目标地址作为IP地址处理 ipaddr = socket.inet_aton(destaddr) - req = req + b'\x01' + ipaddr + req = req + b'\x01' + ipaddr # IPv4地址请求 except socket.error: - # Well it's not an IP number, so it's probably a DNS name. - if self.__proxy[3]: - # Resolve remotely + # 目标地址不是IP地址,可能是DNS名称 + if self.__proxy[3]: # 检查是否需要远程解析 ipaddr = None - req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + (destaddr if isinstance(destaddr, bytes) else destaddr.encode()) + req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + ( + destaddr if isinstance(destaddr, bytes) else destaddr.encode()) else: - # Resolve locally + # 本地解析 ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) req = req + chr(0x01).encode() + ipaddr - req = req + struct.pack(">H", destport) - self.sendall(req) - # Get the response + req = req + struct.pack(">H", destport) # 添加目标端口 + self.sendall(req) # 发送请求 + + # 获取响应 resp = self.__recvall(4) if resp[0:1] != chr(0x05).encode(): self.close() - raise GeneralProxyError((1, _generalerrors[1])) + raise GeneralProxyError((1, _generalerrors[1])) # 协议错误 elif resp[1:2] != chr(0x00).encode(): - # Connection failed + # 连接失败 self.close() - if ord(resp[1:2])<=8: + if ord(resp[1:2]) <= 8: raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])])) else: raise Socks5Error((9, _socks5errors[9])) - # Get the bound address/port + + # 解析绑定地址/端口 elif resp[3:4] == chr(0x01).encode(): - boundaddr = self.__recvall(4) + boundaddr = self.__recvall(4) # IPv4绑定地址 elif resp[3:4] == chr(0x03).encode(): - resp = resp + self.recv(1) - boundaddr = self.__recvall(ord(resp[4:5])) + resp = resp + self.recv(1) # 读取后续字节 + boundaddr = self.__recvall(ord(resp[4:5])) # DNS名 else: self.close() - raise GeneralProxyError((1,_generalerrors[1])) + raise GeneralProxyError((1, _generalerrors[1])) + + # 获取绑定端口 boundport = struct.unpack(">H", self.__recvall(2))[0] - self.__proxysockname = (boundaddr, boundport) + self.__proxysockname = (boundaddr, boundport) # 保存绑定的socket信息 if ipaddr != None: - self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) + self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) # 保存peer名称 else: self.__proxypeername = (destaddr, destport) @@ -264,135 +261,153 @@ class socksocket(socket.socket): """getsockname() -> address info Returns the bound IP address and port number at the proxy. """ - return self.__proxysockname + return self.__proxysockname # 返回代理的socket信息 def getproxypeername(self): """getproxypeername() -> address info Returns the IP and port number of the proxy. """ - return _orgsocket.getpeername(self) + return _orgsocket.getpeername(self) # 返回代理的peer信息 def getpeername(self): """getpeername() -> address info Returns the IP address and port number of the destination machine (note: getproxypeername returns the proxy) """ - return self.__proxypeername + return self.__proxypeername # 返回目标机器的peer名称 - def __negotiatesocks4(self,destaddr,destport): + def __negotiatesocks4(self, destaddr, destport): """__negotiatesocks4(self,destaddr,destport) Negotiates a connection through a SOCKS4 server. """ - # Check if the destination address provided is an IP address + # 检查目标地址是否为IP地址 rmtrslv = False try: ipaddr = socket.inet_aton(destaddr) except socket.error: - # It's a DNS name. Check where it should be resolved. + # 目标是DNS名称, 检查是否应进行远程解析 if self.__proxy[3]: - ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01) + ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01) # 默认IP地址 rmtrslv = True else: - ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) - # Construct the request packet - req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr - # The username parameter is considered userid for SOCKS4 + ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) # 本地解析 + + # 构造请求报文 + req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr # SOCKS4 请求 + # 用户名参数视为userid if self.__proxy[4] != None: req = req + self.__proxy[4] - req = req + chr(0x00).encode() - # DNS name if remote resolving is required - # NOTE: This is actually an extension to the SOCKS4 protocol - # called SOCKS4A and may not be supported in all cases. + req = req + chr(0x00).encode() # 请求结束 + + # 需要远程解析的情况下使用DNS名称 if rmtrslv: - req = req + destaddr + chr(0x00).encode() - self.sendall(req) - # Get the response from the server + req = req + destaddr + chr(0x00).encode() # SOCKS4A扩展 + self.sendall(req) # 发送请求 + + # 获取服务器响应 resp = self.__recvall(8) if resp[0:1] != chr(0x00).encode(): - # Bad data + # 出现错误 self.close() - raise GeneralProxyError((1,_generalerrors[1])) + raise GeneralProxyError((1, _generalerrors[1])) # 无效数据 if resp[1:2] != chr(0x5A).encode(): - # Server returned an error + # 服务器返回错误 self.close() if ord(resp[1:2]) in (91, 92, 93): self.close() - raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90])) + raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90])) # 处理错误代码 else: - raise Socks4Error((94, _socks4errors[4])) - # Get the bound address/port - self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0]) + raise Socks4Error((94, _socks4errors[4])) # 一般性错误 + + # 获取绑定的地址和端口 + self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0]) # 保存绑定信息 if rmtrslv != None: - self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) + self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) # 目标地址 else: - self.__proxypeername = (destaddr, destport) + self.__proxypeername = (destaddr, destport) # 目标地址 def __negotiatehttp(self, destaddr, destport): """__negotiatehttp(self,destaddr,destport) Negotiates a connection through an HTTP server. """ - # If we need to resolve locally, we do this now + # 本地解析 if not self.__proxy[3]: addr = socket.gethostbyname(destaddr) else: addr = destaddr - self.sendall(("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode()) - # We read the response until we get the string "\r\n\r\n" + + # 发送HTTP的CONNECT请求 + self.sendall( + ("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode()) + + # 读取响应直到遇到"\r\n\r\n" resp = self.recv(1) while resp.find("\r\n\r\n".encode()) == -1: resp = resp + self.recv(1) - # We just need the first line to check if the connection - # was successful + + # 仅需第一行检查连接是否成功 statusline = resp.splitlines()[0].split(" ".encode(), 2) if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()): self.close() - raise GeneralProxyError((1, _generalerrors[1])) + raise GeneralProxyError((1, _generalerrors[1])) # 无效的HTTP协议 try: - statuscode = int(statusline[1]) + statuscode = int(statusline[1]) # 获取状态码 except ValueError: self.close() - raise GeneralProxyError((1, _generalerrors[1])) + raise GeneralProxyError((1, _generalerrors[1])) # 状态码无效 if statuscode != 200: self.close() - raise HTTPError((statuscode, statusline[2])) - self.__proxysockname = ("0.0.0.0", 0) - self.__proxypeername = (addr, destport) + raise HTTPError((statuscode, statusline[2])) # 显示状态码错误 + + # 连接成功后的代理信息 + self.__proxysockname = ("0.0.0.0", 0) # 绑定在0.0.0.0 + self.__proxypeername = (addr, destport) # 保存peer信息 def connect(self, destpair): - """connect(self, despair) + """connect(self, destpair) Connects to the specified destination through a proxy. - destpar - A tuple of the IP/DNS address and the port number. + destpair - A tuple of the IP/DNS address and the port number. (identical to socket's connect). To select the proxy server use setproxy(). """ - # Do a minimal input check first - if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (type(destpair[1]) != int): + # 校验输入参数 + if (not type(destpair) in (list, tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or ( + type(destpair[1]) != int): raise GeneralProxyError((5, _generalerrors[5])) + + # 根据代理类型选择相应的握手协议 if self.__proxy[0] == PROXY_TYPE_SOCKS5: if self.__proxy[2] != None: portnum = self.__proxy[2] else: - portnum = 1080 - _orgsocket.connect(self, (self.__proxy[1], portnum)) - self.__negotiatesocks5(destpair[0], destpair[1]) + portnum = 1080 # 默认端口 + + _orgsocket.connect(self, (self.__proxy[1], portnum)) # 连接到代理 + self.__negotiatesocks5(destpair[0], destpair[1]) # 握手 + elif self.__proxy[0] == PROXY_TYPE_SOCKS4: if self.__proxy[2] != None: portnum = self.__proxy[2] else: - portnum = 1080 - _orgsocket.connect(self,(self.__proxy[1], portnum)) - self.__negotiatesocks4(destpair[0], destpair[1]) + portnum = 1080 # 默认端口 + + _orgsocket.connect(self, (self.__proxy[1], portnum)) # 连接到代理 + self.__negotiatesocks4(destpair[0], destpair[1]) # 握手 + elif self.__proxy[0] == PROXY_TYPE_HTTP: if self.__proxy[2] != None: portnum = self.__proxy[2] else: - portnum = 8080 - _orgsocket.connect(self,(self.__proxy[1], portnum)) - self.__negotiatehttp(destpair[0], destpair[1]) + portnum = 8080 # 默认端口 + + _orgsocket.connect(self, (self.__proxy[1], portnum)) # 连接到代理 + self.__negotiatehttp(destpair[0], destpair[1]) # 握手 + elif self.__proxy[0] == None: + # 没有代理时直接连接目标 _orgsocket.connect(self, (destpair[0], destpair[1])) else: - raise GeneralProxyError((4, _generalerrors[4])) + raise GeneralProxyError((4, _generalerrors[4])) # 不支持的代理类型 def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None): diff --git a/src/sqlmap-master/thirdparty/termcolor/termcolor.py b/src/sqlmap-master/thirdparty/termcolor/termcolor.py index ddea6dd..2ba380b 100644 --- a/src/sqlmap-master/thirdparty/termcolor/termcolor.py +++ b/src/sqlmap-master/thirdparty/termcolor/termcolor.py @@ -79,12 +79,14 @@ COLORS = dict( )) ) +# 添加亮色到 COLORS 字典 COLORS.update(dict(("light%s" % color, COLORS[color] + 60) for color in COLORS)) -# Reference: https://misc.flogisoft.com/bash/tip_colors_and_formatting -COLORS["lightgrey"] = 37 -COLORS["darkgrey"] = 90 +# 带有参考的颜色定义 +COLORS["lightgrey"] = 37 # 亮灰色 +COLORS["darkgrey"] = 90 # 深灰色 +# 定义重置颜色的转义序列 RESET = '\033[0m' @@ -104,34 +106,37 @@ def colored(text, color=None, on_color=None, attrs=None): colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink']) colored('Hello, World!', 'green') """ + # 检查环境变量,以决定是否支持 ANSI 颜色 if os.getenv('ANSI_COLORS_DISABLED') is None: - fmt_str = '\033[%dm%s' + fmt_str = '\033[%dm%s' # ANSI 格式化字符串 if color is not None: - text = fmt_str % (COLORS[color], text) + text = fmt_str % (COLORS[color], text) # 将文本颜色应用于文本 if on_color is not None: - text = fmt_str % (HIGHLIGHTS[on_color], text) + text = fmt_str % (HIGHLIGHTS[on_color], text) # 将背景颜色应用于文本 if attrs is not None: for attr in attrs: - text = fmt_str % (ATTRIBUTES[attr], text) + text = fmt_str % (ATTRIBUTES[attr], text) # 应用文本属性 - text += RESET + text += RESET # 重置颜色到默认值 return text def cprint(text, color=None, on_color=None, attrs=None, **kwargs): - """Print colorize text. + """打印带颜色的文本。 - It accepts arguments of print function. + 支持 print 函数的所有参数。 """ - - print((colored(text, color, on_color, attrs)), **kwargs) + print((colored(text, color, on_color, attrs)), **kwargs) # 调用 colored 函数并进行打印 if __name__ == '__main__': - print('Current terminal type: %s' % os.getenv('TERM')) + # 用于测试的主模块 + print('Current terminal type: %s' % os.getenv('TERM')) # 打印当前终端类型 print('Test basic colors:') + + # 测试基本颜色 cprint('Grey color', 'grey') cprint('Red color', 'red') cprint('Green color', 'green') @@ -143,6 +148,7 @@ if __name__ == '__main__': print(('-' * 78)) print('Test highlights:') + # 测试背景高亮 cprint('On grey color', on_color='on_grey') cprint('On red color', on_color='on_red') cprint('On green color', on_color='on_green') @@ -154,6 +160,7 @@ if __name__ == '__main__': print('-' * 78) print('Test attributes:') + # 测试文本属性 cprint('Bold grey color', 'grey', attrs=['bold']) cprint('Dark red color', 'red', attrs=['dark']) cprint('Underline green color', 'green', attrs=['underline']) @@ -161,13 +168,12 @@ if __name__ == '__main__': cprint('Reversed blue color', 'blue', attrs=['reverse']) cprint('Concealed Magenta color', 'magenta', attrs=['concealed']) cprint('Bold underline reverse cyan color', 'cyan', - attrs=['bold', 'underline', 'reverse']) + attrs=['bold', 'underline', 'reverse']) cprint('Dark blink concealed white color', 'white', - attrs=['dark', 'blink', 'concealed']) + attrs=['dark', 'blink', 'concealed']) print(('-' * 78)) print('Test mixing:') - cprint('Underline red on grey color', 'red', 'on_grey', - ['underline']) - cprint('Reversed green on red color', 'green', 'on_red', ['reverse']) - + # 测试混合使用颜色和属性 + cprint('Underline red on grey color', 'red', 'on_grey', ['underline']) + cprint('Reversed green on red color', 'green', 'on_red', ['reverse']) \ No newline at end of file diff --git a/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py b/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py index 50ae621..cfe5b3b 100644 --- a/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py +++ b/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py @@ -9,30 +9,51 @@ import ctypes import os +# 定义 sockaddr 结构体,以便与底层 socket API 交互 class sockaddr(ctypes.Structure): - _fields_ = [("sa_family", ctypes.c_short), - ("__pad1", ctypes.c_ushort), - ("ipv4_addr", ctypes.c_byte * 4), - ("ipv6_addr", ctypes.c_byte * 16), - ("__pad2", ctypes.c_ulong)] + _fields_ = [ + ("sa_family", ctypes.c_short), # 地址族,例如 AF_INET 或 AF_INET6 + ("__pad1", ctypes.c_ushort), # 填充字段用于对齐 + ("ipv4_addr", ctypes.c_byte * 4), # IPv4 地址(4 字节) + ("ipv6_addr", ctypes.c_byte * 16), # IPv6 地址(16 字节) + ("__pad2", ctypes.c_ulong) # 额外填充字段 + ] + +# 检测是否在 Windows 平台上,并加载相应的 Windows socket 函数 if hasattr(ctypes, 'windll'): - WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA - WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA + WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA # 字符串转换为地址 + WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA # 地址转换为字符串 else: def not_windows(): raise SystemError( "Invalid platform. ctypes.windll must be available." ) - WSAStringToAddressA = not_windows - WSAAddressToStringA = not_windows + + + WSAStringToAddressA = not_windows # 非 Windows 平台时的占位符 + WSAAddressToStringA = not_windows # 非 Windows 平台时的占位符 def inet_pton(address_family, ip_string): - addr = sockaddr() - addr.sa_family = address_family - addr_size = ctypes.c_int(ctypes.sizeof(addr)) + """ + Convert an IP address from text to binary format. + + Args: + address_family: The address family (AF_INET for IPv4 or AF_INET6 for IPv6). + ip_string: The IP address in string form (e.g., "192.168.1.1"). + + Returns: + A packed binary representation of the IP address. + Raises: + socket.error: If the conversion fails. + """ + addr = sockaddr() # 创建 sockaddr 实例 + addr.sa_family = address_family # 设置地址族 + addr_size = ctypes.c_int(ctypes.sizeof(addr)) # 地址结构的大小 + + # 调用 WSAStringToAddressA 将字符串 IP 转换为二进制地址 if WSAStringToAddressA( ip_string, address_family, @@ -40,34 +61,50 @@ def inet_pton(address_family, ip_string): ctypes.byref(addr), ctypes.byref(addr_size) ) != 0: - raise socket.error(ctypes.FormatError()) + raise socket.error(ctypes.FormatError()) # 转换失败时抛出异常 + # 根据地址族返回相应的打包 IP 地址 if address_family == socket.AF_INET: - return ctypes.string_at(addr.ipv4_addr, 4) + return ctypes.string_at(addr.ipv4_addr, 4) # IPv4 地址 if address_family == socket.AF_INET6: - return ctypes.string_at(addr.ipv6_addr, 16) + return ctypes.string_at(addr.ipv6_addr, 16) # IPv6 地址 - raise socket.error('unknown address family') + raise socket.error('unknown address family') # 抛出未知地址族的异常 def inet_ntop(address_family, packed_ip): - addr = sockaddr() - addr.sa_family = address_family - addr_size = ctypes.c_int(ctypes.sizeof(addr)) - ip_string = ctypes.create_string_buffer(128) - ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string)) + """ + Convert a binary IP address to its text representation. + + Args: + address_family: The address family (AF_INET for IPv4 or AF_INET6 for IPv6). + packed_ip: The packed binary IP address. + + Returns: + The IP address in string form. + Raises: + socket.error: If the conversion fails. + """ + addr = sockaddr() # 创建 sockaddr 实例 + addr.sa_family = address_family # 设置地址族 + addr_size = ctypes.c_int(ctypes.sizeof(addr)) # 地址结构的大小 + ip_string = ctypes.create_string_buffer(128) # 用于存储 IP 字符串 + ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string)) # 字符串大小 + + # 根据地址族填充 sockaddr 结构 if address_family == socket.AF_INET: if len(packed_ip) != ctypes.sizeof(addr.ipv4_addr): - raise socket.error('packed IP wrong length for inet_ntoa') - ctypes.memmove(addr.ipv4_addr, packed_ip, 4) + raise socket.error('packed IP wrong length for inet_ntoa') # IPv4 地址长度错误 + ctypes.memmove(addr.ipv4_addr, packed_ip, 4) # 复制 IPv4 地址 elif address_family == socket.AF_INET6: if len(packed_ip) != ctypes.sizeof(addr.ipv6_addr): - raise socket.error('packed IP wrong length for inet_ntoa') - ctypes.memmove(addr.ipv6_addr, packed_ip, 16) + raise socket.error('packed IP wrong length for inet_ntoa') # IPv6 地址长度错误 + ctypes.memmove(addr.ipv6_addr, packed_ip, 16) # 复制 IPv6 地址 else: - raise socket.error('unknown address family') + raise socket.error('unknown address family') # 抛出未知地址族的异常 + # 调用 WSAAddressToStringA 将二进制地址转换为字符串 if WSAAddressToStringA( ctypes.byref(addr), addr_size, @@ -75,11 +112,12 @@ def inet_ntop(address_family, packed_ip): ip_string, ctypes.byref(ip_string_size) ) != 0: - raise socket.error(ctypes.FormatError()) + raise socket.error(ctypes.FormatError()) # 转换失败时抛出异常 + + return ip_string[:ip_string_size.value - 1] # 返回字符串表示形式,移除尾部的空字符 - return ip_string[:ip_string_size.value - 1] -# Adding our two functions to the socket library +# 如果在 Windows 平台,将自定义的函数添加到 socket 库中 if os.name == 'nt': - socket.inet_pton = inet_pton - socket.inet_ntop = inet_ntop + socket.inet_pton = inet_pton # 添加 inet_pton 函数 + socket.inet_ntop = inet_ntop # 添加 inet_ntop 函数 \ No newline at end of file