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. Windows 8下完美使用Virtual PC 2007(virtual pc 2007 64 win8 兼容性)

    Windows 8下完美使用Virtual PC 2007(virtual pc 2007 64 win8 兼容性) 一.从微软的官方网站下载Virtual PC 2007 SP1英文版,文件名为se ...

  2. Windows10运行Cura源代码,搭建环境教程

    参考官方文档 https://github.com/Ultimaker/Cura/wiki/Running-Cura-from-Source-on-Windows#python-3810 注意 这些说 ...

  3. Java反射详解篇--一篇入魂

    1.反射概述 Java程序在运行时操作类中的属性和方法的机制,称为反射机制. 一个关键点:运行时 一般我们在开发程序时,都知道自己具体用了什么类,直接创建使用即可.但当你写一些通用的功能时没办法在编写 ...

  4. 怎么让一个div消失在视野里

    怎么让一个div消失在视野里 视野内隐藏 1.设置高度宽度为0 div { height: 0; width: 0; } 2.设置透明度为0 div { opacity: 0; } 3.设置displ ...

  5. Spring cache源码分析

    Spring cache是一个缓存API层,封装了对多种缓存的通用操作,可以借助注解方便地为程序添加缓存功能. 常见的注解有@Cacheable.@CachePut.@CacheEvict,有没有想过 ...

  6. java 集合及其线程安全 及其 set linkedList map table 区别

    早在jdk的1.1版本中,所有的集合都是线程安全的.但是在1.2以及之后的版本中就出现了一些线程不安全的集合,为什么版本升级会出现一些线程不安全的集合呢?因为线程不安全的集合普遍比线程安全的集合效率高 ...

  7. 正则-Java注释代码

    今天写了个匹配java中常见的注释,记录一下,以备后用,使用条件将行两边的空格trim掉. (^\/\*.*)|(^\/\/.*)|(^\*.*)

  8. BeanFactory – BeanFactory 实现举例?

    Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离. 最常用的BeanFactory 实现是XmlBeanFactory 类.

  9. uWSGI+django+nginx的工作原理流程与部署

    二.必要的前提 2.1 准备知识 django 一个基于python的开源web框架,请确保自己熟悉它的框架目录结构. uWSGI 一个基于自有的uwsgi协议.wsgi协议和http服务协议的web ...

  10. kafka消费组创建和删除原理

    0.10.0.0版本的kafka的消费者和消费组已经不在zk上注册节点了,那么消费组是以什么形式存在的呢? 1 入口 看下kafka自带的脚本kafka-consumer-groups.sh,可见脚本 ...