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. python单ip端口扫描器

    from socket import * import threading #导入线程相关模块 # qianxiao996精心制作 #博客地址:https://blog.csdn.net/qq_363 ...

  2. linux鸟哥学习笔记

    Linux学习笔记 Linux档案权限和目录配置 目录如果没有x权限,则无法进入该目录 改变文件和属性 chgrp: 改变档案所属的群组 chown:改变档案的拥有者 chmod:改变档案的权限,SU ...

  3. IDEA的git的拉去提交Java day9

    赶鸭子上架,没法子. 新的知识点24号继续学习,今天认真熟悉了以下IDEA,的git代码的提交和拉去,不过拉去下来的项目有些打开的问题有点多,还在继续解决中-- git知识明天一并上传博客.

  4. 《HelloGitHub》第 72 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...

  5. mq 的缺点 ?

    系统可用性降低 系统引入的外部依赖越多,越容易挂掉,本来你就是 A 系统调用 BCD 三个系统的 接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整?MQ ...

  6. JdbcTemplate?

    JdbcTemplate 类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理.

  7. javax.net.ssl.sslhandshakeException:sun.security.validator.validatorException:PKIX path buildind failed

    前段时间开发的一个需求,需要通过图片URL获取图片的base64编码,测试的时候使用的是百度图片的url,测试没有问题,但是发布后测试时报如下错: javax.net.ssl.sslhandshake ...

  8. 有哪些不同类型的IOC(依赖注入)方式?

    构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖. Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参stati ...

  9. Error 和 Exception 有什么区别?

    Error 表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情 况下的一种严重问题:比如内存溢出,不可能指望程序能处理这样的情况: Exception 表示需要捕捉或者需要程序进行处理 ...

  10. JVM-learning

    JVM是什么?? Java Virtual Mechine JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台.所有的Java 程序都要在JRE下才能运行. ...