sqlmap源码分析(一)
Sqlmap源码分析(一)
此次分析的sqlmap目标版本为1.6.1.2#dev
只对sqlmap的核心检测代码进行详细分析其他的一带而过
sqlmap.py文件结构
为了不让篇幅过长下面只写出了sqlmap.py(入口点)引用的前三个函数,
from __future__ import print_function # 即使在python2.X,使用print就得像python3.X那样加括号
try:
'''
代码作用:
python版本检测 导入必要的包 禁止生成__pycache__
导入官方模块
消除一些可忽略的警告
导入自定义模块
'''
except KeyboardInterrupt:
'''
代码作用:
处理ctrl c v手动中断
'''
def modulePath():
pass
def checkEnvironment():
pass # 下方有详细代码 这里为了方便展示整体结构不再列出
def main():
try:
dirtyPatches() # 补丁 针对python3进行额外配置,对其他第三方的一些参数调整(下方有详细代码)
resolveCrossReferences() # 解决交叉引用(下方有详细代码)
checkEnvironment() # 检测环境 sqlmap版本和路径是否正常(下方有详细代码)
setPaths(modulePath()) # 路径配置
banner() # 见名知意打印banner信息
'''
代码作用:
对命令行进行处理
根据信息进行初始化
下面的if和elif中代码 测试sqlmap能否能正常运行如果没问题就进入start()执行sql注入
'''
if:
pass
elif:
pass
else:
pass
start()
pass
except:# 长达300行的自定义错误处理
pass
finally:# 收尾工作
pass
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
pass
except SystemExit:
raise
except:
traceback.print_exc()
finally: # 根据线程数设定不同的退出方式
if threading.active_count() > 1:
os._exit(getattr(os, "_exitcode", 0))
else:
sys.exit(getattr(os, "_exitcode", 0))
else:
__import__("lib.controller.controller")
dirtyPatches函数
函数作用
- 对http.client进行参数的修改,以及针对python3相应方法的重新设置
- 对universaldetector检测编码方式的调整
- 针对Windows操作系统上添加对inet_pton()
- PLACE.CUSTOM_POST调整
def dirtyPatches():
"""
在thirdparty\six\init.py中有这样一行 MovedModule("http_client", "httplib", "http.client"),
six是Python2和3的兼容性库。这个项目旨在支持可同时运行在Python2和3上的代码库
如果是python3 _http_client实际就是http.client
"""
# 可以接收很长的响应头结果行 在Python\Lib\http\client.py中_MAXLINE=65536
_http_client._MAXLINE = 1 * 1024 * 1024
if six.PY3: # 如果是python3就执行这部分代码
'''
hasattr 返回对象是否具有具有给定名称的属性
如果_http_client.HTTPConnection没有__send_output(python3中没有)
就新建一个并且函数引用,现在执行__send_output函数等同于_send_output
'''
if not hasattr(_http_client.HTTPConnection, "__send_output"):
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
def _send_output(self, *args, **kwargs):
'''
conf是AttribDict类(在lib/core/datatype.py中)的对象
此类定义了字典,并添加了将成员作为属性访问的功能。因为AttribDict继承了python的dict类重写了一部分功能
产生的对象就可以理解为字典
'''
if conf.get("chunked") and "encode_chunked" in kwargs:
kwargs["encode_chunked"] = False
self.__send_output(*args, **kwargs)
# 理解为将_send_output函数内容更新
_http_client.HTTPConnection._send_output = _send_output
# 现在xx.__send_output的内容为原xx._send_output
# 现在xx._send_output=自定义函数的内容
if IS_WIN:
# 针对Windows操作系统上添加对inet_pton()的支持处理ipv4,将ip地址192.168.1.1转换成二进制的ip地址
from thirdparty.wininetpton import win_inet_pton
# 关于编码的配置
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
# 与上面_send_output操作流程类似
if hasattr(_http_client, "LineAndFileWrapper"):
def _(self, *args):
return self._readline()
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
_http_client.LineAndFileWrapper.readline = _
# 原值为0.2 universaldetector是Mozilla公司提供的检测编码方式的工具
thirdparty.chardet.universaldetector.MINIMUM_THRESHOLD = 0.90
# 从命令行中匹配对应值 如果匹配到并且值不等于"POST"进行替换操作
match = re.search(r" --method[= ](\w+)", " ".join(sys.argv))
if match and match.group(1).upper() != PLACE.POST:
PLACE.CUSTOM_POST = PLACE.CUSTOM_POST.replace("POST", "%s (body)" % match.group(1))
try:
os.urandom(1) # 返回包含适合加密使用的随机字节的字节对象(b'\x03')
except NotImplementedError:
if six.PY3:
os.urandom = lambda size: bytes(random.randint(0, 255) for _ in range(size))
else:
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
resolveCrossReferences函数
下面全部都是函数的替换,等号右侧isDigit、readInput等都是函数。
def resolveCrossReferences():
lib.core.threads.isDigit = isDigit
lib.core.threads.readInput = readInput
lib.core.common.getPageTemplate = getPageTemplate
lib.core.convert.filterNone = filterNone
lib.core.convert.isListLike = isListLike
lib.core.convert.shellExec = shellExec
lib.core.convert.singleTimeWarnMessage = singleTimeWarnMessage
lib.core.option._pympTempLeakPatch = pympTempLeakPatch
lib.request.connect.setHTTPHandlers = _setHTTPHandlers
lib.utils.search.setHTTPHandlers = _setHTTPHandlers
lib.controller.checks.setVerbosity = setVerbosity
lib.utils.sqlalchemy.getSafeExString = getSafeExString
thirdparty.ansistrm.ansistrm.stdoutEncode = stdoutEncode
checkEnvironment函数
函数作用:
- 检测目录是否正常
- 检测sqlmap版本是否在1.0以上
- 将对应的特殊的字典类型变量放到全局中
def checkEnvironment():
try: # 检测是否是一个正常的目录 如果有编码问题报错处理
os.path.isdir(modulePath())
except UnicodeEncodeError:
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版本 如果过低提示更新版本 并退出
if LooseVersion(VERSION) < LooseVersion("1.0"):
errMsg = "your runtime environment (e.g. PYTHONPATH) is "
errMsg += "broken. Please make sure that you are not running "
errMsg += "newer versions of sqlmap with runtime scripts for older "
errMsg += "versions"
logger.critical(errMsg)
raise SystemExit
if "sqlmap.sqlmap" in sys.modules:
for _ in ("cmdLineOptions", "conf", "kb"):
# 将系统路径lib.core.data中的"cmdLineOptions", "conf", "kb"变为同名的全局变量,这三个是AttribDict(dict)的对象。
globals()[_] = getattr(sys.modules["lib.core.data"], _)
for _ in (
"SqlmapBaseException", "SqlmapShellQuitException", "SqlmapSilentQuitException",
"SqlmapUserQuitException"):
globals()[_] = getattr(sys.modules["lib.core.exception"], _)
通过读代码发现sqlmap花费了大量的代码在python2的基础上进行修补
start函数
@stackedmethod
def start():
'''
这些if并不涉及核心的检测代码所以忽略掉
'''
if xxx:
pass
if xxx:
pass
if xxx:
pass
for targetUrl, targetMethod, targetData, targetCookie, targetHeaders in kb.targets:
# 核心代码 核心代码 核心代码
if xxx:
pass
if xxx:
pass
return True
核心代码很复杂需要花一些时间 在后续的随笔中再进行分析
sqlmap源码分析(一)的更多相关文章
- SQLMAP源码分析(一)
说起来,学习Python很大一部分原因是由于对WEB安全的兴趣以及对SQLMAP这款工具的好奇,曾经设想学完Python基础就读一读SQLMAP源码,然而懒病一犯,随之就大江东去.近来,又重新燃起了读 ...
- SQLmap源码分析之框架初始化(一)
SQLmap是现在搞web人手一个的注入神器,不仅包含了主流数据库的SQL注入检测,而且包含提权以及后渗透模块.基于python2.x开发而成,使用方便.所以研究web安全少不了分析源码,学习代码的同 ...
- SQLMAP源码分析-目录结构
-----------------------------------------------------------------------------│ README.md│ sqlmap.c ...
- Python:Sqlmap源码精读之解析xml
XML <?xml version="1.0" encoding="UTF-8"?> <root> <!-- MySQL --&g ...
- MyBatis源码分析(1)-MapConfig文件的解析
1.简述 MyBatis是一个优秀的轻ORM框架,由最初的iBatis演化而来,可以方便的完成sql语句的输入输出到java对象之间的相互映射,典型的MyBatis使用的方式如下: String re ...
- Mybatis源码分析之SqlSessionFactory(一)
简介 MyBatis的前身叫iBatis,本是apache的一个开源项目, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBa ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
随机推荐
- RDMA相关的技术网站
https://www.cnblogs.com/vlhn/p/7909893.html https://www.cnblogs.com/vlhn/ 这个家伙的博客写的还不错,可以参考.
- 74CMS 3.4 反射型XSS漏洞
一. 启动环境 1.双击运行桌面phpstudy.exe软件 2.点击启动按钮,启动服务器环境 二.代码审计 1.双击启动桌面Seay源代码审计系统软件 2.因为74CMS3.4源代码编辑使用GBK编 ...
- 在Spring框架中如何更有效地使用JDBC?
使用SpringJDBC 框架,资源管理和错误处理的代价都会被减轻.所以开发者只需写statements 和 queries从数据存取数据,JDBC也可以在Spring框架提供的模板类的帮助下更有效地 ...
- REST 和RPC对比?
1.RPC主要的缺陷是服务提供方和调用方式之间的依赖太强,需要对每一个微服务进行接口的定义,并通过持续继承发布,严格版本控制才不会出现冲突. 2.REST是轻量级的接口,服务的提供和调用不存在代码之间 ...
- jedis 和 redisson 有哪些区别?
Jedis 和 Redisson 都是Java中对Redis操作的封装.Jedis 只是简单的封装了 Redis 的API库,可以看作是Redis客户端,它的方法和Redis 的命令很类似.Redis ...
- jvm-learning-双亲委派机制
是什么 工作原理 例子 优势 什么是沙箱安全机制 其他知识 对类加载器的引用 类的主动使用和被动使用
- spring集成mongodb简单使用和测试方式
@EnableMongoRepositories @ComponentScan(basePackages = "cn.example") @Configuration public ...
- 使用 Spring 通过什么方式访问 Hibernate?
在 Spring 中有两种方式访问 Hibernate:控制反转 Hibernate Template 和 Callback.继承 HibernateDAOSupport 提供一个 AOP 拦截器.
- Python - 本地文件读写(初级)
- 深入Linux 内核架构之 CFS
linux内核分析--CFS(完全公平调度算法) 1.1 CFS原理 cfs定义了一种新的模型,它给cfs_rq(cfs的run queue)中的每一个进程安排一个虚拟时钟,vruntime.如果 ...