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源码分析(一)的更多相关文章

  1. SQLMAP源码分析(一)

    说起来,学习Python很大一部分原因是由于对WEB安全的兴趣以及对SQLMAP这款工具的好奇,曾经设想学完Python基础就读一读SQLMAP源码,然而懒病一犯,随之就大江东去.近来,又重新燃起了读 ...

  2. SQLmap源码分析之框架初始化(一)

    SQLmap是现在搞web人手一个的注入神器,不仅包含了主流数据库的SQL注入检测,而且包含提权以及后渗透模块.基于python2.x开发而成,使用方便.所以研究web安全少不了分析源码,学习代码的同 ...

  3. SQLMAP源码分析-目录结构

    -----------------------------------------------------------------------------│  README.md│  sqlmap.c ...

  4. Python:Sqlmap源码精读之解析xml

    XML <?xml version="1.0" encoding="UTF-8"?> <root> <!-- MySQL --&g ...

  5. MyBatis源码分析(1)-MapConfig文件的解析

    1.简述 MyBatis是一个优秀的轻ORM框架,由最初的iBatis演化而来,可以方便的完成sql语句的输入输出到java对象之间的相互映射,典型的MyBatis使用的方式如下: String re ...

  6. Mybatis源码分析之SqlSessionFactory(一)

    简介 MyBatis的前身叫iBatis,本是apache的一个开源项目, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBa ...

  7. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  8. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  9. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

随机推荐

  1. 内网渗透----域环境搭建(server 2012)

    先确定两台服务器相通 1.配置静态IP与DNS 2.配置域服务 点击服务器管理器-添加角色和功能-下一步-添加AD域服务: 3.提升为域控制器 安装完成后,可在旗帜处选择提升为域控制器 添加新林 添加 ...

  2. 《前端运维》二、Nginx--4代理、负载均衡与其他

    一.代理服务 比较容易理解吧,简单来说.客户端访问服务器并不是直接访问的,而是通过中间代理服务器,代理服务器再去访问服务器.就像一个中转站一样,无论什么,只要从客户端到服务器,你就要通过我. 一)正向 ...

  3. Kubernetes:存储管理

    Blog:博客园 个人 参考:Volumes | Kubernetes.Persistent Volumes | Kubernetes.Kubernetes 基础入门实战 简单来说,存储卷是定义在Po ...

  4. 【算法】两个list合并

    转载博客地址 http://blog.sina.com.cn/s/blog_5da93c8f0101fdrp.html 有两个ArrayList,分别为list1和list2,分析这两个list后生成 ...

  5. 七牛云简单实用-uploadManager.put(..)抛出异常

    描述: 本人小白,最近在写一个仿头条的项目,其中有用到七牛云做为图片的存储以代替本地服务其存储,按照视频教程配置服务器端的简单上传功能,总是报错: 参照官方文档:https://developer.q ...

  6. Maria DB数据库基础知识

    Maria DB连接 与MariaDB建立连接的一种方法是在命令提示符下使用mysql二进制文件. Maria DB命令行登录数据库服务: mysql -u root -p -- 换行输入密码 上面给 ...

  7. OGNL(Object-Graph Navigation Language)使用

    OGNL表达式:https://www.jianshu.com/p/6bc6752d11f4 Apache OGNL:http://commons.apache.org/proper/commons- ...

  8. 关于TP框架

    TP的特性有哪些? 1.多表查询非常方便,在model中几句代码就可以完成对多表的关联操作. 2.融合了smarty模板,使前后台分离 3.支持多种缓存技术,尤其对memcache技术支持非常好 4. ...

  9. vue2与vue3的区别

    template <template> <div class="wrap"> <div>{{ num }}</div> <Bu ...

  10. Python - set类型