webgoat-(A1)injection

这篇具有很好参考价值的文章主要介绍了webgoat-(A1)injection。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SQL Injection (intro)

01

概念
This lesson describes what Structured Query Language (SQL) is and how it can be manipulated to perform tasks that were not the original intent of the developer.
课程目标是描述什么是SQL以及SQL如何执行那些非开发者本意的任务。

目标
The user will have a basic understanding of how SQL works and what it is used for 用户将会理解SQL如何工作,理解什么是SQL注入,以及SQL注入如何工作,并掌握DML,DDL,DCL,字符型SQL注入,数字型SQL注入,SQL注入如何影响CIA原则

02 What is SQL?

There are three main categories of SQL commands:

Data Manipulation Language (DML)

Data Definition Language (DDL)

Data Control Language (DCL)

Each of these command types can be used by attackers to compromise the confidentiality, integrity, and/or availability of a system. Proceed with the lesson to learn more about the SQL command types and how they relate to protections goals.

If you are still struggling with SQL and need more information or practice, you can visit http://www.sqlcourse.com/ for free and interactive online training.
webgoat-(A1)injection,安全测试,安全
webgoat-(A1)injection,安全测试,安全

作业要求获取Bob用户的部门,并提示你拥有全部管理员权限,可以在没有认证下访问所有数据
直接输入SQL语句 select department from Employees where first_name=‘Bob’
webgoat-(A1)injection,安全测试,安全

03 DML

Data Manipulation Language (DML)
As implied by the name, data manipulation language deals with the manipulation of data. Many of the most common SQL statements, including SELECT, INSERT, UPDATE, and DELETE, may be categorized as DML statements. DML statements may be used for requesting records (SELECT), adding records (INSERT), deleting records (DELETE), and modifying existing records (UPDATE).
数据操作语言 (DML)DML 语句可用于请求记录 (SELECT)、添加记录 (INSERT)、删除记录 (DELETE) 和修改现有记录 (UPDATE)。
If an attacker succeeds in “injecting” DML statements into a SQL database, he can violate the confidentiality (using SELECT statements), integrity (using UPDATE statements), and availability (using DELETE or UPDATE statements) of a system.
如果攻击者成功地将 DML 语句“注入”到 SQL 数据库中,则可能会破坏系统的机密性(使用 SELECT 语句)、完整性(使用 UPDATE 语句)和可用性(使用 DELETE 或 UPDATE 语句)
DML commands are used for storing, retrieving, modifying, and deleting data.
DML用来存储,修改或者删除数据。
SELECT - retrieve data from a database

INSERT - insert data into a database

UPDATE - updates existing data within a database

DELETE - delete records from a database

Example:

Retrieve data:

SELECT phone
FROM employees
WHERE userid = 96134;

This statement retrieves the phone number of the employee who has the userid 96134.
webgoat-(A1)injection,安全测试,安全
题目要求修改Tobi的部门为sales
输入查询语句:UPDATE employees SET department =‘Sales’ WHERE first_name=‘Tobi’

webgoat-(A1)injection,安全测试,安全

04 Data Definition Language (DDL) 数据定义语言

Data definition language includes commands for defining data structures. DDL commands are commonly used to define a database’s schema. The schema refers to the overall structure or organization of the database and. in SQL databases, includes objects such as tables, indexes, views, relationships, triggers, and more.
数据定义语言 (DDL)DDL 命令通常用于定义数据库的架构。架构是指数据库的整体结构或组织,在 SQL 数据库中,包括表、索引、视图、关系、触发器等对象。
如果攻击者成功地将 DDL 类型的 SQL 命令“注入”到数据库中,他可能会破坏系统的完整性(使用 ALTER 和 DROP 语句)和可用性(使用 DROP 语句)。
If an attacker successfully “injects” DDL type SQL commands into a database, he can violate the integrity (using ALTER and DROP statements) and availability (using DROP statements) of a system.

DDL commands are used for creating, modifying, and dropping the structure of database objects.
DML语言用来创建,修改,删除数据库对象的结构

CREATE - create database objects such as tables and views

ALTER - alters the structure of the existing database

DROP - delete objects from the database

Example:

CREATE TABLE employees(
    userid varchar(6) not null primary key,
    first_name varchar(20),
    last_name varchar(20),
    department varchar(20),
    salary varchar(10),
    auth_tan varchar(6)
);

This statement creates the employees example table given on page 2.
题目要求修改表结构添加一列phone
webgoat-(A1)injection,安全测试,安全
数据语句:ALTER TABLE Employees
ADD phone varchar(20)
webgoat-(A1)injection,安全测试,安全

05

Data Control Language (DCL)
Data control language is used to implement access control logic in a database. DCL can be used to revoke and grant user privileges on database objects such as tables, views, and functions.

If an attacker successfully “injects” DCL type SQL commands into a database, he can violate the confidentiality (using GRANT commands) and availability (using REVOKE commands) of a system. For example, the attacker could grant himself admin privileges on the database or revoke the privileges of the true administrator.
数据控制语言 (DCL)DCL 可用于撤消和授予用户对数据库对象(如表、视图和函数)的权限。如果攻击者成功地将 DCL 类型的 SQL 命令“注入”到数据库中,他可能会破坏系统的机密性(使用 GRANT 命令)和可用性(使用 REVOKE 命令)。例如,攻击者可以授予自己对数据库的管理员权限或撤消真正管理员的权限。
DCL命令用于实现对数据库对象的访问控制。
DCL commands are used to implement access control on database objects.

GRANT - give a user access privileges on database objects

REVOKE - withdraw user privileges that were previously given using GRANT

GRANT - 授予用户对数据库对象的访问权限
REVOKE - 撤销以前使用 GRANT 授予的用户权限
GRANT语句用于授权用户或角色执行特定的数据库操作或访问特定的表。

下面是一个示例,演示如何使用GRANT语句将表的SELECT权限授予用户"username":
GRANT SELECT ON table_name TO username;
在上面的语句中,将"table_name"替换为您要授予权限的表的实际名称,并将"username"替换为您要授予权限的用户的实际名称。
题目要求给表添加权限
webgoat-(A1)injection,安全测试,安全

06 SQL注入

SQL注入(也称为SQLi)是最常见的网络黑客技术之一。SQL 注入攻击包括通过从客户端到应用程序的 SQL 查询输入插入或“注入”恶意代码。如果处理不当,SQL注入会严重影响数据的完整性和安全性。

示例

For example, consider a web application that allows users to retrieve user information simply by inputting a username into a form field. The input from the user is sent to the server and gets inserted into a SQL query which then is processed by a SQL interpreter.

The SQL query to retrieve the user information from the database follows:

"SELECT * FROM users WHERE name = '" + userName + "'";

The variable userName holds the input from the client and “injects” it into the query.
If the input were Smith the query would then become

"SELECT * FROM users WHERE name = 'Smith'";

and would retrieve all data for the user with the name Smith.

If an attacker inputs data containing characters or strings that have a “special” meaning to the SQL interpreter (such as ;, --, or '), and the data is not correctly sanitized or validated, the attacker can modify the intended behavior of the SQL query in order to perform other (malicious) actions on the database.
如果攻击者输入的字符包含的特殊字符,会被SQL解析,如; – or ’ 数据没有经过净化或者验证,攻击者就可能执行该SQL语句本不该执行的任务。

Here is an input field. Try typing some SQL in here to better understand how the query changes.
webgoat-(A1)injection,安全测试,安全

示例

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 表中的所有条目

07 SQL注入影响

Consequences of SQL injection

A successful SQL injection exploit can:

Read and modify sensitive data from the database、Execute administrative operations on the database、Shutdown auditing or the DBMS、Truncate tables and logs、Add users

Recover the content of a given file present on the DBMS file system、Issue commands to the operating system

SQL injection attacks allow attackers to

Spoof identity、Tamper with existing data、Cause repudiation issues such as voiding transactions or changing balances、Allow the complete disclosure of all data on the system、Destroy the data or make it otherwise unavailable、Become administrator of the database server
成功的 SQL 注入漏洞可以:
从数据库中读取和修改敏感数据、对数据库执行管理操作、关闭审核或 DBMS、截断表和日志、添加用户、恢复 DBMS 文件系统上存在的给定文件的内容、向操作系统发出命令
SQL 注入攻击允许攻击者
欺骗身份、篡改现有数据、导致否认问题,例如取消交易或更改余额、允许完全披露系统上的所有数据、销毁数据或使其不可用、成为数据库服务器的管理员

08 Severity of SQL injection

The severity of SQL injection attacks is limited by

Attacker’s skill and imagination、Defense in depth countermeasures、Input validation、Least privilege、Database technology
SQL注入攻击的严重程度取决于攻击者的技术、输入验证、最小权限、数据库技术、对抗措施的深度。

Not all databases support command chaining 并非所有数据库都支持命令链

Microsoft Access、MySQL Connector/J and C、Oracle

SQL injection is more common in PHP, Classic ASP, Cold Fusion and older languages

不提供参数化查询支持的语言

参数化查询已添加到新版本中

Web 技术的早期采用者(即旧代码)

并非所有数据库都是平等的 (SQL Server)

Command shell: master.dbo.xp_cmdshell ‘cmd.exe dir c:’

Registry commands: xp_regread, xp_regdeletekey, …

09 字符串 SQL 注入

Try It! String SQL injection
The query in the code builds a dynamic query as seen in the previous example. The query is built by concatenating strings making it susceptible to String SQL injection:

“SELECT * FROM user_data WHERE first_name = ‘John’ AND last_name = '” + lastName + “'”;
Try using the form below to retrieve all the users from the users table. You should not need to know any specific user name to get the complete list.
webgoat-(A1)injection,安全测试,安全
题目要求选择输入,获取到所有用户信息。 应该选择 Smith ’ ‘1’='1 需要闭合单引号,且跟上一个字符串注入
webgoat-(A1)injection,安全测试,安全

10 Numeric SQL injection 数字型注入

The query in the code builds a dynamic query as seen in the previous example. The query in the code builds a dynamic query by concatenating a number making it susceptible to Numeric SQL injection:

"SELECT * FROM user_data WHERE login_count = " + Login_Count + " AND userid = "  + User_ID;

题目要求找到哪个域有SQL注入漏洞,且成功获取所有用户数据。
webgoat-(A1)injection,安全测试,安全
因为这里的字段是数值,所以是一个数字型注入,在logincount输入 1 or 1=1 --; 提示无法解析为number,所以这个输入框没有注入。
在logincount输入 1 userid输入 1 or 1=1 --; 得到结果。
webgoat-(A1)injection,安全测试,安全
webgoat-(A1)injection,安全测试,安全

11 通过字符串 SQL 注入损害机密性

如果系统容易受到 SQL 注入攻击,则该系统的 CIA 各个方面都可能很容易受到损害在下面的三节中,您将学习如何使用SQL 字符串注入或查询链等技术来破坏 CIA 三合会的各个方面。

在本课中,我们将讨论保密性。攻击者使用 SQL 注入很容易破坏机密性;例如,成功的 SQL 注入可以让攻击者从数据库中读取信用卡号码等敏感数据。

什么是字符串 SQL 注入?
如果应用程序只是通过将用户提供的字符串连接到查询来构建 SQL 查询,则该应用程序可能非常容易受到字符串 SQL 注入的影响。
更具体地说,如果用户提供的字符串只是在没有任何清理或准备的情况下连接到 SQL 查询,那么您可以通过简单地将引号插入输入字段来修改查询的行为。例如,您可以用引号结束字符串参数,然后输入您自己的 SQL。

轮到你了!
您是一位名叫约翰·史密斯的员工,在一家大公司工作。公司有一个内部系统,可以让所有员工看到自己所在的部门、工资等内部数据。

该系统要求员工使用唯一的身份验证 TAN来查看他们的数据。
您当前的 TAN 是3SL99A。

由于您总是渴望成为薪酬最高的员工,因此您希望利用该系统,以便查看所有同事的数据以查看他们当前的工资,而不是查看自己的内部数据。

使用下面的表格并尝试从员工表中检索所有员工数据。您无需知道任何具体名称或 TAN 即可获取所需信息。
您已经发现执行您的请求的查询如下所示:

"SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";

webgoat-(A1)injection,安全测试,安全
题目要求注入查到所有用户信息
在Employee Name框内输入 ’ or ‘1’ = ‘1’ – 提交
webgoat-(A1)injection,安全测试,安全

12 通过查询链接损害完整性

在上一课中破坏了数据的机密性之后,这次我们将 通过使用 SQL查询链接来破坏数据的完整性。

如果存在足够严重的漏洞,则可能会使用 SQL 注入来破坏数据库中任何数据的完整性。成功的 SQL 注入可能允许攻击者更改他甚至不应该访问的信息。

什么是 SQL 查询链?
查询链正是它听起来的样子。通过查询链接,您尝试将一个或多个查询附加到实际查询的末尾。您可以使用;来完成此操作 元字符。A ; 标记 SQL 语句的结束;它允许人们在初始查询之后立即启动另一个查询,甚至不需要开始一个新行。
使用;来表示一个SQL语句结束,直接写另一个SQL语句。
轮到你了!
您刚刚发现托比和鲍勃似乎都比您赚更多的钱!当然,你不能就此罢休。
最好去改变你自己的工资,这样你就能赚到最多的钱!

请记住:您的名字是 John Smith,您当前的 TAN 是3SL99A。 题目要求修改你的工资。
webgoat-(A1)injection,安全测试,安全
在Employee name处输入 Smith’; update employees set salary = 1111111 where last_name = 'Smith ';–
点击查询,这里用到的是闭合单引号,拼接更新数据语句,并使用–来使后面的语句无效。
webgoat-(A1)injection,安全测试,安全

13 损害可用性

在前面的课程中成功妥协了机密性和完整性之后,我们现在要破坏CIA 三合会的第三个要素:可用性。

有许多不同的方法可以违反可用性。如果帐户被删除或密码被更改,实际所有者将无法再访问该帐户。攻击者还可能尝试删除部分数据库,甚至删除整个数据库,以使数据无法访问。撤销管理员或其他用户的访问权限是损害可用性的另一种方式;这将阻止这些用户访问数据库的特定部分甚至整个数据库。

轮到你了!
现在你是公司里收入最高的人了。但你看到了吗?似乎有一个access_log表,您的所有操作都已记录到其中!
最好在任何人注意到之前将其彻底删除。
题目要求删除表access_log
webgoat-(A1)injection,安全测试,安全
输入 '; drop table access_log;–
webgoat-(A1)injection,安全测试,安全

SQL Injection (advanced)

01

概念
本课程介绍 SQL 注入的更高级主题。

目标
结合SQL注入技术
SQL盲注入

02

特殊字符

/* */ are inline comments
– , # are line comments

Example: SELECT * FROM users WHERE name = 'admin' -- AND pass = 'pass'

; allows query chaining

Example: SELECT * FROM users; DROP TABLE users;

',+,|| allows string concatenation
Char() strings without quotes

Example: SELECT * FROM users WHERE name = '+char(27) OR 1=1

+char(27) 是一个尝试利用SQL注入漏洞的例子。char(27) 是ASCII中的转义字符,代表单引号 '。所以 +char(27) 会添加一个额外的单引号到字符串中

Special Statements

SQL UNION 操作符

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

SQL UNION 语法

SELECT first_name FROM user_system_data UNION SELECT login_count FROM user_data;

注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

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

joins

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

03 Try It! Pulling data from other tables

The input field below is used to get data from a user by their last name.
The table is called ‘user_data’:

CREATE TABLE user_data (userid int not null,
                        first_name varchar(20),
                        last_name varchar(20),
                        cc_number varchar(30),
                        cc_type varchar(10),
                        cookie varchar(20),
                        login_count int);

Through experimentation you found that this field is susceptible to SQL injection. Now you want to use that knowledge to get the contents of another table.
The table you want to pull data from is:

CREATE TABLE user_system_data (userid int not null primary key,
			                   user_name varchar(12),
			                   password varchar(10),
			                   cookie varchar(30));

6.a) Retrieve all data from the table
6.b) When you have figured it out…​. What is Dave’s password?

Note: There are multiple ways to solve this Assignment. One is by using a UNION, the other by appending a new SQL statement. Maybe you can find both of them.
题目要求获取到另外一个表的数据,并找到David的密码,提示可以用union或者语句拼接。
webgoat-(A1)injection,安全测试,安全方法一语句拼接:

';select * from user_system_data where '1' = '1' --

webgoat-(A1)injection,安全测试,安全
方法二: union
webgoat-(A1)injection,安全测试,安全
随便输入一个发现user_data查询的是所有字段,所以uinon后面select字段要对应,
输入 Dave’ union select userid ,user_name,‘3’,password,‘4’,cookie,userid from user_system_data;–
webgoat-(A1)injection,安全测试,安全

或者
ji’ union select userid,user_name,user_name,user_name,user_name,password,userid from user_system_data–
用union拼接即可,需要注意第二个语句字段数和字段类型需要和user_data表的保持一致即可。
webgoat-(A1)injection,安全测试,安全
’ or true union select 1,‘2’,‘3’,‘4’,‘5’,password, 7 from user_system_data–
这种查询也可以,因为第二个语句只要password结果,所以让其他为int的用数字,char的用字符。
webgoat-(A1)injection,安全测试,安全

04 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

Blind SQL injection
Blind SQL injection is a type of SQL injection attack that asks the database true or false questions and determines the answer based on the application’s response. This attack is often used when the web application is configured to show generic error messages, but has not mitigated the code that is vulnerable to SQL injection.
SQL盲注,通过询问数据库问题,根据返回是false或者true来进行猜测攻击。

Difference
Let us first start with the difference between a normal SQL injection and a blind SQL injection. In a normal SQL injection the error messages from the database are displayed and gives enough information to find out how the query is working. Or in the case of a UNION based SQL injection the application does not reflect the information directly on the web page. So in the case where nothing is displayed you will need to start asking the database questions based on a true or false statement. That is why a blind SQL injection is much more difficult to exploit.
普通的SQL注入会将数据库错误信息显示出来,我们有信息知道语句是什么。所以如果信息回显,我们就只能问数据库问题,所以盲注SQL难以利用。

There are several different types of blind SQL injections: content-based and time-based SQL injections.

Example

In this case we are trying to ask the database a boolean question based on a unique id, for example suppose we have the following url: https://my-shop.com?article=4 On the server side this query will be translated as follows:

SELECT * FROM articles WHERE article_id = 4

When we want to exploit this we change the url into:

https://shop.example.com?article=4 AND 1=1

This will be translated to:

SELECT * FROM articles WHERE article_id = 4 and 1 = 1

If the browser will return the same page as it used to when using https://shop.example.com?article=4 you know the website is vulnerable for a blind SQL injection. If the browser responds with a page not found or something else you know a blind SQL injection might not work. You can now change the SQL query and test for example: https://shop.example.com?article=4 AND 1=2 which will not return anything because the query returns false.
如果第二个链接返回页面与第一个一样,说明有SQL盲注漏洞。如果返回404,说明没有SQL盲注。

How do we actually take advantage of this? Above we only asked the database a trivial question but you can for example also use the following url:

https://shop.example.com?article=4 AND substring(database_version(),1,1) = 2

Most of the time you start by finding which type of database is used, based on the type of database you can find the system tables of the database you can enumerate all the tables present in the database. With this information you can start getting information from all the tables and you are able to dump the database.
Be aware that this approach might not work if the privileges of the database are setup correctly (meaning the system tables cannot be queried with the user used to connect from the web application to the database).如果数据库表权限正确配置,则这种方法无效。

Another way is called a time-based SQL injection, in this case you will ask the database to wait before returning the result. You might need to use this if you are totally blind. This means there is no difference between the response data. To achieve this kind of SQL injection you could use:
基于时间的盲注,让数据库在返回结果前等待。返回数据是没有区别的,如果返回结果延迟了,说明有时间盲注。

article = 4; sleep(10) --

05

题目要求以tom身份登录。
webgoat-(A1)injection,安全测试,安全
这个题,login页面无注入,注册页面的username有注入。使用or注入,发现无法返回结果。
webgoat-(A1)injection,安全测试,安全
看了源码,直接将username拼接到了SQL语句,所以有注入问题,但是如果查询到结果,也会返回失败。
所以or注入是无用的。百度了其他人的解法,这题还用了爆破。。。是不是SQL注入问题我就问。抄答案tom密码为 thisisasecretfortomonly
webgoat-(A1)injection,安全测试,安全

06

几个关于预处理语句的问题。
A statement has got values instead of a prepared statement
Which one of the following characters is a placeholder for variables 问号?
How can prepared statements be faster than statements? Prepared statements are compiled once by the database management system waiting for input and are pre-compiled this way.
How can a prepared statement prevent SQL-Injection? Placeholders can prevent that the users input gets attached to the SQL query resulting in a seperation of code and data.
What happens if a person with malicious intent writes into a register form :Robert); DROP TABLE Students;-- that has a prepared statement? The database registers ‘Robert’ ); DROP TABLE Students;–'.

预处理语句 prepared statement

在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';

预处理语句,可以看到用三个占位符表示变量,保留对应变量字符串只作用于占位符处。

 PreparedStatement preparedStatement =
              connection.prepareStatement("INSERT INTO sql_challenge_users VALUES (?, ?, ?)");
          preparedStatement.setString(1, username_reg);
          preparedStatement.setString(2, email_reg);
          preparedStatement.setString(3, password_reg);
          preparedStatement.execute();

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

sql

SELECT * FROM customers;

示例(动态语句):

sql

SELECT * FROM customers WHERE name = 'John';
 String checkUserQuery =
            "select userid from sql_challenge_users where userid = '" + username_reg + "'";
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(checkUserQuery);

sql语句,直接将用户输入拼接到SQL语句中,导致SQL注入漏洞。

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

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

01 Immutable Queries

These are the best defense against SQL injection. They either do not have data that could get interpreted, or they treat the data as a single entity that is bound to a column without interpretation.如下方法是针对 SQL 注入的最佳防御措施。它们要么没有可以解释的数据,要么将数据视为绑定到列而不进行解释的单个实体。

Static Queries 不需要用户输入

String query = "SELECT * FROM products";
String query = "SELECT * FROM users WHERE user = '" + session.getAttribute("UserID") + "'";

Parameterized Queries 参数化查询,使用预编译的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语句只需要编译一次,然后可以多次执行,这样可以提高数据库的性能。

Stored Procedures

Only if stored procedure does not generate dynamic SQL

02 Stored Procedures 存储过程

Safe Stored Procedure (Microsoft SQL Server) 安全的存储过程

CREATE PROCEDURE ListCustomers(@Country nvarchar(30))
AS
SELECT city, COUNT(*)
FROM customers
WHERE country LIKE @Country GROUP BY city


EXEC ListCustomers ‘USA’

Injectable Stored Procedure (Microsoft SQL Server) 可注入的存储过程

CREATE PROCEDURE getUser(@lastName nvarchar(25))
AS
declare @sql nvarchar(255)
set @sql = 'SELECT * FROM users WHERE
            lastname = + @LastName + '
exec sp_executesql @sql

03 Parameterized Queries - Java Snippet

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_table WHERE 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 ... }

Important
Use the prepared statement correctly; parameters should be set with ps.set…() and DO NOT use the following statement:

String insertStatement = "INSERT INTO USERS (id, name, email) VALUES (%s, %s, %s)".format("1", "webgoat", "webgoat@owasp.org");
PreparedStatement statement = conn.prepareStatement(insertStatement);
statement.executeUpdate();

(For the sake of the example, we assume that the passed values are based on user input). The example above is not the correct way to use a prepared statement, use:

PreparedStatement statement = conn.prepareStatement("INSERT INTO USERS (id, name, email) VALUES (?, ?, ?)");
statement.setString(1, "1");
statement.setString(2, "webgoat");
statement.setString(3, "webgoat@owasp.org");
statement.executeUpdate();

04 参数化查询 - Java 示例

public static String loadAccount() {
  // Parser returns only valid string data
  String accountID = getParser().getStringParameter(ACCT_ID, "");
  String data = null;
  String query = "SELECT first_name, last_name, acct_id, balance FROM user_data WHERE acct_id = ?";
  try (Connection connection = dataSource.getConnection()) {
       PreparedStatement statement = connection.prepareStatement(query)) {
     statement.setString(1, accountID);
     ResultSet results = statement.executeQuery();
     if (results != null && results.first()) {
       results.last(); // Only one record should be returned for this query
       if (results.getRow() <= 2) {
         data = processAccount(results);
       } else {
         // Handle the error - Database integrity issue
       }
     } else {
       // Handle the error - no records found }
     }
  } catch (SQLException sqle) {
    // Log and handle the SQL Exception }
  }
  return data;
}

0x05 Try it! Writing safe code

You can see some code down below, but the code is incomplete. Complete the code, so that it’s no longer vulnerable to a SQL injection! Use the classes and methods you have learned before.

The code has to retrieve the status of the user based on the name and the mail address of the user. Both the name and the mail are in the string format.
webgoat-(A1)injection,安全测试,安全

0x06 Try it! Writing safe code

Now it is time to write your own code! Your task is to use JDBC to connect to a database and request data from it.

Requirements:

connect to a database 连接数据库

perform a query on the database which is immune to SQL injection attacks 执行静态查询防止SQL注入攻击

your query needs to contain at least one string parameter 需要包含至少一个string参数

Some tips before you start:
For connecting to the database, you can simply assume the constants DBURL, DBUSER and DBPW as given.
The content of your query does not matter, as long as the SQL is valid and meets the requirements.
All the code you write gets inserted into the main method of a Java class with the name “TestClass” that already imports java.sql.* for you.

Not creative enough to think of your own query? How about you try to retrieve the data of a user with a specific name from a fictional database table called users.

For example; the following code would compile without any error (but of course does not meet the requirements to complete this lesson).

try {
    Connection conn = null;
    System.out.println(conn);   //should output 'null'
} catch (Exception e) {
    System.out.println("Oops. Something went wrong!");
}

Use your knowledge and write some valid code from scratch in the editor window down below! (if you cannot type there it might help to adjust the size of your browser window once, then it should work):
编写一段代码实现查询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!");
}

07 Parameterized Queries - .NET

public static bool isUsernameValid(string username) {
	RegEx r = new Regex("^[A-Za-z0-9]{16}$");
	Return r.isMatch(username);
}

// SqlConnection conn is set and opened elsewhere for brevity.
try {
	string selectString = "SELECT * FROM user_table WHERE username = @userID";
	SqlCommand cmd = new SqlCommand( selectString, conn );
	if ( isUsernameValid( uid ) ) {
		cmd.Parameters.Add( "@userID", SqlDbType.VarChar, 16 ).Value = uid;
		SqlDataReader myReader = cmd.ExecuteReader();
		if ( myReader ) {
			// make the user record active in some way.
			myReader.Close();
		}
	} else { // handle invalid input }
}
catch (Exception e) { // Handle all exceptions... }

08 Input Validation Required? 是否需要输入验证

Since my queries are no longer injectable do I still need to validate my input?

YES!

Prevents other types of attacks from being stored in the database

Stored XSS、Information leakage、Logic errors - business rule validation、SQL injection
often the database is considered trusted

09 Input validation alone is not enough!! 仅有输入验证不够

You need to do both, use parametrized queries and validate the input received from the user. On StackOverflow you will see a lot of answers stating that input validation is enough. However it only takes you so far before you know the validation is broken, and you have an SQL injection in your application.
为了防止SQL注入,需要同时使用参数化查询和输入验证。
A nice read why it is not enough can be found https://twitter.com/marcan42/status/1238004834806067200?s=21

Let’s repeat one of the previous assignments, the developer fixed the possible SQL injection with filtering, can you spot the weakness in this approach?
';select * from user_system_data–
webgoat-(A1)injection,安全测试,安全webgoat-(A1)injection,安全测试,安全
使用//代替空格 ';select //*//from//user_system_data-- 通过
webgoat-(A1)injection,安全测试,安全

使用 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–
webgoat-(A1)injection,安全测试,安全
这一题是为了证明,即使过滤了空格,但如果没做参数化查询,也能够绕过。

10 Input validation alone is not enough!! 仅有输入验证不够

So the last attempt to validate if the query did not contain any spaces failed, the development team went further into the direction of only performing input validation, can you find out where it went wrong this time?
webgoat-(A1)injection,安全测试,安全
';select //*//from//user_system_data-- 提示不允许空格和SQL关键字。
webgoat-(A1)injection,安全测试,安全
考虑采用双写绕过。
';SESELEctLECT/
/*//FrFromom//user_system_data–
webgoat-(A1)injection,安全测试,安全

源代码

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

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

这题也是为了证明,只有输入过滤SQL关键字是不行的,可以绕过。

11 Order by clause

预编译SQL语句不总是能预防SQL注入
Let us take a look at the following statement:

"SELECT * FROM users ORDER BY " + sortColumName + ";"

If we look at the specification of the SQL grammar the definition is as follows:

SELECT ...
FROM tableList
[WHERE Expression]
[ORDER BY orderExpression [, ...]]

orderExpression:
{ columnNr | columnAlias | selectExpression }
    [ASC | DESC]

selectExpression:
{ Expression | COUNT(*) | {
    COUNT | MIN | MAX | SUM | AVG | SOME | EVERY |
    VAR_POP | VAR_SAMP | STDDEV_POP | STDDEV_SAMP
} ([ALL | DISTINCT][2]] Expression) } [[AS] label]

Based on HSQLDB

This means an orderExpression can be a selectExpression which can be a function as well, so for example with a case statement we might be able to ask the database some questions, like:

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

So we can substitute any kind of boolean operation in the when(…​.) part. The statement will just work because it is a valid query whether you use a prepared statement or not. An order by clause can by definition contain an expression.

Mitigation

If you need to provide a sorting column in your web application you should implement a whitelist to validate the value of the order by statement. It should always be limited to something like ‘first name’ or ‘last name’.
即使使用预编译数据,也可能有SQL注入。
SQL中的order语句

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

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

12

题目要求使用order by查找webgoat-prd的ip,需要得到前三位。
webgoat-(A1)injection,安全测试,安全

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

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

(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。

总结:有排序的地方也可能有SQL注入。

13 最小特权

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

思维导图

webgoat-(A1)injection,安全测试,安全文章来源地址https://www.toymoban.com/news/detail-744218.html

到了这里,关于webgoat-(A1)injection的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 开发安全之:SQL Injection

    Overview 调用通过不可信赖的数据源输入构建的 SQL 查询 mysql_query()。通过这种调用,攻击者能够修改语句的含义或执行任意 SQL 命令。 Details SQL injection 错误在以下情况下发生: 1. 数据从一个不可信赖的数据源进入程序。 2. 数据用于动态地构造一个 SQL 查询。 这种情况下,数据

    2024年01月23日
    浏览(49)
  • 开发安全之:XML Injection

    Overview responsemsg() 方法将处理未经验证的 XML 输入。此调用可能允许攻击者将任意元素或属性注入 XML 文档的正文中,导致 Denial of Service 或泄漏敏感信息。XML Injection 之所以不同于 XML External Entity (XXE) Injection,是因为攻击者通常会控制插入到 XML 文档中部或末尾的输入。 Detail

    2024年01月22日
    浏览(38)
  • 开发安全之:JSON Injection

    Overview 在 XXX.php 的第 X 行中,responsemsg() 方法将未经验证的输入写入 JSON。攻击者可以利用此调用将任意元素或属性注入 JSON 实体。 Details JSON injection 会在以下情况中出现: 1. 数据从一个不可信赖的数据源进入程序。 2. 将数据写入到 JSON 流。 在这种情况下,由 XXX.php 的第 X

    2024年01月21日
    浏览(29)
  • 进阶测试知识学习之Fault Injection

    这种方法的基本思想是人为地在系统中引入错误,然后观察系统的反应。这可以帮助测试人员了解系统是否能够恰当地处理错误,并在错误发生时保持正常运行。故障注入可以用来测试各种类型的错误,比如硬件故障、操作系统错误、网络错误,甚至是编程错误。 故障注入可

    2024年02月09日
    浏览(52)
  • Burp Suite配置过滤忽略Ruby code injection和XML injection类型的安全问题

    可以使用扫描配置中的\\\"Active Scan\\\"选项。请按照以下步骤进行配置: 打开Burp Suite并启动您的目标应用程序。 载入您的目标应用程序并确保它已配置为代理Burp Suite。 转到Burp Suite的\\\"Proxy\\\"选项卡,并确保Proxy Server正在运行。确保浏览器或应用程序已配置为使用Burp Suite的代理。

    2024年02月08日
    浏览(45)
  • Flask+ Dependency-injecter+pytest 写测试类

    最近在使用这几个在做项目,因为第一次用这个,所以不免有些问题。总结下踩的坑 首先测试类约定会放在tests里面,不然有可能发生引入包的问题,会报错某些包找不到。 这里我就用的真实的数据库操作,但是我用了一个专门为测试写的事务管理,所有操作都不会commit而是

    2024年01月22日
    浏览(27)
  • [网络安全]一文带你了解SSTI漏洞(结合Web_python_template_injection解题详析)

    SSTI是Server-Side Template Injection的缩写,是一种Web应用程序安全漏洞,主要存在于使用基于模板引擎的Web应用程序中。 SSTI漏洞的主要原因是 在Web应用程序中使用了基于模板引擎的渲染功能,并且没有正确地验证和过滤用户输入的数据。当攻击者能够构造特定的输入并成功地注入

    2024年02月08日
    浏览(45)
  • webgoat靶场攻关

    我们开发软件的方式改变了,开源社区越来越成功,开源软件的可用性越来越丰富,使得我们不需要考虑这些组件的来源。 本节我们要面对管理依赖库的难题,管理这些依赖组件的不是最有风险的,最有风险的是判断我们是否在风险之中。 意识到使用的开源代码与您自己的

    2024年02月06日
    浏览(49)
  • js按顺序定义一万个变量 a1 a2 a3 ......, 并赋值, 然后打印a1 a2的值

    在这个示例中,我们使用了一个对象 variables 来存储变量。通过 for 循环,我们定义了一万个变量,并将对应的值赋给了 variables 对象的属性。最后,我们可以通过 variables.a1 和 variables.a2 来访问并打印出这两个变量的值。 使用对象或数组来管理大量连续的变量,可以更加有效

    2024年02月13日
    浏览(58)
  • 渗透学习-靶场篇-WebGoat靶场(JWT攻击)

    本次主要学习了javaweb项目方面任意出现的一些安全问题,最主要的是有关于JWT身份认证上的攻击,并利用webgoat靶场进行了一些实验。 JWT的全称是Json Web Token。它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验

    2023年04月21日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包