网站安全漏洞 | 青训营

188 阅读12分钟

什么是漏洞

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。


具体举例来说,比如在Intel Pentium芯片中存在的逻辑错误,在Sendmail早期版本中的编程错误,在NFS协议中认证方式上的弱点,在Unix系统管理员设置匿名Ftp服务时配置不当的问题都可能被攻击者使用,威胁到系统的安全。因而这些都可以认为是系统中存在的安全漏洞。


漏洞是指一个系统存在的弱点或缺陷,系统对特定威胁攻击或危险事件的敏感性,或进行攻击的威胁作用的可能性。漏洞可能来自应用软件或操作系统设计时的缺陷或编码时产生的错误,也可能来自业务在交互处理过程中的设计缺陷或逻辑流程上的不合理之处。

网站的基本构成

ad7ca95080455ea6b53f3f7891230c6.png

  • 前端:JavaScript/vue/react【负责页面的展示,接口的调用】
  • 网关:nginx
  • 后端:Go/Java/node 【提供一些数据的接口,处理一些业务的逻辑,数据的处理】
  • 前后端交互:HHTTP/WebSocket

常听到的安全事件

  1. 数据泄露
  2. 服务瘫痪
  3. 成果失窃
  4. 系统劫持

攻击

  • 针对客户端的漏洞攻击
  • 针对服务端(后端)的漏洞攻击

漏洞的分类

709da97e647b3cdcb6d0f301aa6b05e.png

服务端漏洞

第三方组件漏洞

第三方漏洞是非windows本身操作系统的漏洞,比如realone player ,MPC等软件自身程序的漏洞。

当大部分用户已养成定时给系统打漏洞补丁的习惯后,木马制造者又看中了第三方软件漏洞传播这一“隐蔽”渠道。被利用的第三方ActiveX插件漏洞,涉及迅雷、暴风影音、百度超级搜霸、realplayer等多款常见软件的部分版本中,而且其中多数漏洞曾经是或者现在仍是0day漏洞。它是相对于系统漏洞后一些插件的漏洞来说的,所以叫第三方漏洞。

所谓第三方软件指的是该非线性编辑系统生产商以外的软件公司提供的软件。这些软件大都不能直接与非线性卡挂靠,进行输入/输出,但可以对已进入了硬盘阵列的视音频素材进行加工处理和编辑,或者制作自己的二维和三维图像再与那些视频素材合成,合成后的作品再由输入/输出软件输出。这些软件的品种非常丰富,功能十分强大,有些甚至是从工作站转移过来的,可以这么说,非线性编辑系统之所以能做到效果变幻莫测,匪夷所思,吸引众人的视线,完全取决于第三方软件。


防护方式:

针对Java可以选择使用dependency-check-maven检查项目以来的组件是否存在安全漏洞


SQL注入

SQL注入(SQL lnjection)是发生在Web程序中数据库层的安全漏洞,是比较常用的网络攻击方式之一,他不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至修改数据库。也就是说,SQL注入就是在用户输入的字符串中添加SQL语句,如果在设计不良的程序中忽略了检查,那么这些注入进去的SQL语句就会被数据库服务器误认为是正常的SQL语句而运行,攻击者就可以执行计划外的命令或者访问未授权的数据。

SQL语句静态模板和动态数据部分没有严格的区分,如果在数据项中加入了某些SQL语句关键字(比如说SELECT、DEOP等等),这些SQL语句就很可以在数据库写入或读取数据时得到执行

注入原理:

1.恶意拼接查询

SQL语句可以对数据进行增删改查,且使用分号来分隔不同命令。例如:

SELECT * FROM user WHERE user_id = $user_id

 其中user_id是传入的参数,如果传入参数的值为"1234;DELETE FROM user",那么最终执行的查询为:

SELECT * FROM users WHERE user_id = 1234; DELETE FROM users

如果执行以上语句,则会删除user表中的所有数据

2.利用注释执行非法命令  SQL语句中可以插入注释,例如

SELECT COUNT(*) AS 'num' FROM score WHERE id=24411 AND version=$version

如果version包含了恶意的字符串" '-1' OR 3 AND SLEEP(500) ",那么最终查询的语句会变为

SELECT COUNT(*) AS 'num' FROM score WHERE id=24411 AND version='-1' OR 3 AND SLEEP(500)

以上恶意查询只是想耗尽系统资源,SLEEP(500) 将导致 SQL 语句一直运行。如果其中添加了修改、删除数据的恶意指令,那么将会造成更大的破坏。

3.传入非法参数

SQL 语句中传入的字符串参数是用单引号引起来的,如果字符串本身包含单引号而没有被处理,那么可能会篡改原本 SQL 语句的作用。 例如:

SELECT * FROM user_name WHERE user_name = $user_name

如果 user_name 传入参数值为 G'chen,那么最终的查询语句会变为:

SELECT * FROM user_name WHERE user_name ='G'chen'

一般情况下,以上语句会执行出错,这样的语句风险比较小。虽然没有语法错误,但可能会恶意产生 SQL 语句,并且以一种你不期望的方式运行。

4.添加额外条件 在 SQL 语句中添加一些额外条件,以此来改变执行行为。条件一般为真值表达式。例如:

UPDATE users SET userpass='$userpass' WHERE user_id=$user_id;

如果 user_id 被传入恶意的字符串“1234 OR TRUE”,那么最终的 SQL 语句会变为:

UPDATE users SET userpass= '123456' WHERE user_id=1234 OR TRUE;

如果执行以上语句,将更改所有用户的密码



  1. [java]错误使用语言框架,或者语言框架本身存在安全问题

    使用Mybatis-plus的危险函数,比如inSql,支持直接SQL拼接,存在SQL注入风险

  2. Mybatis使用 [$] 构建SQL模板

    使用 [#] ,实际的SQL语句:SELECT id,name,pwd,age FROM t_user_info WHERE id =?

    使用 [$] ,实际的SQL语句:SELECT id,name,pwd,age FEOM t_user_info WHERE id ='xx'

  3. Golang常见错误写法

    业务场景经常遇到根据用户定义的字段进行排序的功能,如果直接将用户输入字段作为维度带到Order则会产生SQL注入,假设GORM语句为:db.Order(param).Find(&products)

    正常情况用户输入唯独字段即可实现自定义排序
    param:code
    SQL语句:SELECT*FROM'products'WHERE'products'.'deleted_at'IS NULL ORDER BY code
    
    攻击者可以输入SQL语句,改变原始SQL语义
    param:if(1,sleep(10),'code')
    SQL语句:SELECT*FROM'products'WHERE'products'.'deleted_at'IS NULL ORRDER BY if(1,sleep(10),'code')
    
  • 防护方式:

    1.尽量不要基于DB的Raw方法拼接构造SQL语句,而应该使用预编译、ORM框架

    2.使用ORM框架时,应该注意框架中的特性,可能存在不安全的写法导致SQL注入问题

    3.在复杂场景一定要使用拼接SQL,需要对外部输入进行转义


命令执行

原理:

应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。

分类:

  • 远程命令执行漏洞

    远程命令执行漏洞,指用户通过浏览器提交执行操作命令,由于服务器端,没有针对执行函数做过率,就执行了恶意命令

  • 远程代码执行漏洞

    代码执行漏洞也叫代码注入漏洞,指用户通过浏览器提交执行恶意脚本代码,执行恶意构造的脚本代码

命令连接符:

  1. Windows

    -&:无论左边是false还是true,右边都执行按顺序执行

    -&&:具有短路效果,左边是false,右边不执行

    -|:表示A命令语句的输出,作为B命令语句的输入执行。当A为false的时候将不会执行

    -||:A||B,表示A命令语句执行失败,然后才执行B命令语句。


  2. Linux

    -&:在后台运行

    -:分号(;) 可以进行多条命令的无关联执行,每一条执行结果不会影响其他命令的执行

    -&&:按照顺序执行,如果前面应该正确就会执行下一个,如果错误那么就不会执行下一个

    -||:如果 || 左边的命令执行失败(返回1表示失败),才执行||右边的命令,否则不执行右边的命令,具有短路功能。

    -():如果想执行几个命令,则需要用命令分隔符分号隔开每个命令,并使用圆括号()把所有命令组合起

防护方式

  1. 对动态的值尽可能设置白名单进行验证
  2. 如果某些位置无法白名单,需要尝试对数据类型进行校验
  3. 特殊字符和名单的过滤,或者转义

客户端漏洞

开放重定向

某些需要重定向到其他站点的功能,往往在参数中携带需要重定向的URL,但实际程序逻辑没有控制好重定向的范围,导致攻击者可以构造恶意链接,诱导用户重定向的恶意站点

危害:钓鱼攻击

修复方案:对重定向严格进行白名单控制,并正确校验白名单

XSS

常用攻击语法:

<script>alert(1)</script>

<img src=x onerror=alert("hano")>

<svg onload=alert(1)>

<a href=javascript:alert(1)>

<script>alert('dreeee')</script>
用于探测的万能语句:
<SCRscriptIPT>'"()Oonnjavascript

跨站脚本

Cross-Site Scripting简称“CSS”,为避免与前端叠成样式表CSS冲突,故又称XSS

一般XSS分为以下几种类型:
  • 反射性XSS

    交互的数据一般不会被存在在数据库里,一次性,一般出现在查询类等页面

  • 存储型XSS

    交互的数据被存储在数据库里,永久存储,一般出现在留言板,注册类等页面

  • DOM型XSS

    不与后台服务器产生数据交互,通过DOM操作前端代码输出的时候产生的问题,一次性,也属于反射型

XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位

【XSS是一种发生在前端浏览器的漏洞,所以其危害的对象也是前端用户】

形成xss漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害


因此在xss漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:

  • 输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
  • 输出转义:根据输出点的位置对输出到前端的内容进行适当转义

攻击流程:

3d7d50c4d685c99a779cbf20f0d39b2.png

跨站脚本漏洞测试流程:

  1. 在目标站点找到输入点,比如查询接口,留言板等;
  2. 输入一组“特殊字符+唯一识别字符”,点击提交后,查看返回的源码,是否有做对应的处理
  3. 通过搜素定位到唯一字符,结合唯一字符前后语法确认是否可以构造执行KS代码的条件(构造闭合);
  4. 提交payload,成功执行则存在xss漏洞

CSRF

  • 跨站请求伪造**(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。(网站恶意利用)

XSS(跨站脚本)——利用站点内的信任用户

 *CSRF(跨站请求伪造)——通过伪装成受信任的网站*

在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。 很多人搞不清楚CSRF的概念,甚至有时候会将其和XSS混淆,更有甚者会将其和越权问题混为一谈,这都是对原理没搞清楚导致的。


如何确认一个web系统存在csrf漏洞

1、对目标网站增删改的地方进行标记,并观察其逻辑,判断请求是否可以被伪造

例如:修改管理员账号时,并不需要验证旧密码,导致请求容易被伪造
例如:对于敏感信息的修改并没有使用安全的token验证,导致请求容易被伪造

2、确认凭证的有效期(这个问题会提高CSRF被利用的概率) 虽然退出或者关闭了浏览器,但cookie仍然有效,或者session并没有过期,导致CSRF攻击变得简单。


CSRF漏洞常见防范措施:

增加token验证(常用的做法):   1、对关键操作增加token参数,token值必须随机,每次都不一样;   关于安全的会话管理(避免会话被利用,及时关闭登录态)   1、不要在客户端保存敏感信息(比如身份认证信息);   2、测试直接关闭,退出时的会话过期机制;   3、设置会话过期机制,比如15分钟内无操作,则自动登入超时;   访问控制安全管理:   1、敏感信息的修改时需要对身份进行二次认证,比如修改账号时,需要判断旧密码;   2、敏感信息的修改尽量使用post,而不是get;(post的安全性比get高些)   3、通过http 头部中的referer来限制原页面   一般用在登录(防暴力破解),也可以用在其他重要信息操作的表单中(需要考虑可用性)


点击劫持(clickjacking)

点击劫持是一种在网页中将恶意代码等隐藏在看似无害或者存在诱导的内容(如按钮)之下,并诱使用户点击的手段,用户点击后往往会执行一些非预期的操作

漏洞场景:考虑如下删除账号功能,如果目标站点CSRF防护做的很到位,无法直接构造CSRF钓鱼页面,这时候可以考虑在钓鱼页面iframe原始页面,并且覆盖一层诱导性的文字