参考:
https://www.hacking8.com/sqlmap-parse/
从最早的开始:
https://codeload.github.com/sqlmapproject/sqlmap/zip/0.6.2
下载使用PyCharm自带的debug。
- cmdLineOptions = cmdLineParser(): 解析命令行参数;
- start() 开始;
– 检测连接:checkConnection,就是使用urllib2.urlopen打开url;
最后返回该页面的md5值:
没有进入Exception就会默认执行return True:
– 检测稳定性:checkStability
然后访问三次该url,成功则返回True:
(第一次为checkConnection,后三次为checkStability)
– 检测动态性:checkDynParam。若为动态,则值不同时,会返回不同的页面。
通过将参数的值替换为随机生成的数字,然后重新访问页面。
randInt = randomInt() # 生成随机数
payload = agent.payload(place, parameter, value, str(randInt)) # 替换动态参数的值为随机数
dynResult1 = Request.queryPage(payload, place) # 访问页面,得到这个页面的md5值
if kb.defaultResult == dynResult1: # 若两个页面的值一样,说明这个参数并不是动态的
return False
logMsg = "confirming that %s parameter '%s' is dynamic" % (place, parameter)
logger.info(logMsg) # 打印日志,确认这个参数是动态的
然后又生成两次随机字符串,将参数的值替换为随机字符串,然后再访问页面,对响应取md5值。
只要这两个请求返回的响应的任何一个md5值与默认提供的请求的响应的md5值不同,即可认为页面是动态的。然后log一下。
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
logger.info(logMsg)
– 进入checkSqlInjection(place, parameter, value, parenthesis),其中parenthesis表示sql注入的payload为几层括号层数。这个函数用来判断GET, POST, Cookie, User-Agent这些地方是否存在SQL注入:1、数字型;2、单引号型;3、双引号型。
1、数字型,用一个随机数字 AND 7998=7998
访问之后得到的页面的md5值与+1之后的payload,也就是 AND 7998=7999
得到的页面的md5值对比,
若不同,则继续用一个随机字符串替换之后AND qtBoW
,若返回的页面md5值也跟基准值不一样,确认存在数字型注入。
创建目标的目录;
action(): 利用SQL注入点来执行payload,操作数据库。
# Enumeration options
if conf.getBanner: # 获取banner信息
dumper.string("banner", conf.dbmsHandler.getBanner())
if conf.getCurrentUser: # 获取当前用户
dumper.string("current user", conf.dbmsHandler.getCurrentUser())
if conf.getCurrentDb: # 获取当前db
dumper.string("current database", conf.dbmsHandler.getCurrentDb())
if conf.getUsers: # 获取所有用户
dumper.lister("database management system users", conf.dbmsHandler.getUsers())
if conf.getPasswordHashes: # 获取密码hash
dumper.userSettings("database management system users password hashes",
conf.dbmsHandler.getPasswordHashes(), "password hash")
if conf.getPrivileges:
dumper.userSettings("database management system users privileges",
conf.dbmsHandler.getPrivileges(), "privilege")
if conf.getDbs:
dumper.lister("available databases", conf.dbmsHandler.getDbs())
if conf.getTables:
dumper.dbTables(conf.dbmsHandler.getTables())
if conf.getColumns:
dumper.dbTableColumns(conf.dbmsHandler.getColumns())
if conf.dumpTable:
dumper.dbTableValues(conf.dbmsHandler.dumpTable())
if conf.dumpAll:
conf.dbmsHandler.dumpAll()
if conf.query:
dumper.string(conf.query, conf.dbmsHandler.sqlQuery(conf.query))
if conf.sqlShell:
conf.dbmsHandler.sqlShell()
# File system options
if conf.rFile: # 读文件
dumper.string(conf.rFile, conf.dbmsHandler.readFile(conf.rFile))
if conf.wFile: # 写文件
dumper.string(conf.wFile, conf.dbmsHandler.writeFile(conf.wFile))
# Takeover options
if conf.osShell: # 拿到操作系统权限
conf.dbmsHandler.osShell()