├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── logo.png
├── outputrecording.gif
├── updatedrecording.gif
└── usage.png
├── .gitignore
├── README.md
├── requirements.txt
├── resources
├── __init__.py
└── user_agents.py
├── samples
├── dir.txt
├── results.txt
└── sub.txt
├── subforce.py
└── subforce
├── __init__.py
└── core.py
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Rozendantz/subforce/e399640c7598d4186a8cb5de33baaca63b9addfb/.github/logo.png
--------------------------------------------------------------------------------
/.github/outputrecording.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Rozendantz/subforce/e399640c7598d4186a8cb5de33baaca63b9addfb/.github/outputrecording.gif
--------------------------------------------------------------------------------
/.github/updatedrecording.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Rozendantz/subforce/e399640c7598d4186a8cb5de33baaca63b9addfb/.github/updatedrecording.gif
--------------------------------------------------------------------------------
/.github/usage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Rozendantz/subforce/e399640c7598d4186a8cb5de33baaca63b9addfb/.github/usage.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dir.txt
2 | file.txt
3 | results.txt
4 | sub.txt
5 | sub_bak3.txt
6 | resources/__pycache__/
7 | subforce/__pycache__/
8 | tags
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | NOTE: Files must be in linebyline format, csv is not currently supported
9 |
10 | 
11 |
12 |
13 | Sample output file:
14 |
15 | 
16 |
17 |
18 | # Current State
19 |
20 | v0.1:
21 | - ingest subdomain and subdirectory files
22 | - forced-browsing/content-discovery across all given subdomains
23 | - output response headers, links, scripts (stripped from response object) to results.txt file
24 | - swaps out user agents between requests
25 |
26 |
27 | # Development Roadmap
28 |
29 | v1.0:
30 | - add support for api tokens and custom cookies in header
31 | - target domain with sub wordlist
32 | - full input sanitization i.e. input domain without .com.* namespace or http/https
33 | - custom output
34 | - add proxy support
35 | - csv formatted subdomain and subdir files
36 | - custom response exclude i.e. 400, 403, Server Not Found
37 | - better print to screen format (tabled, paged etc)
38 | - randomized delays between requests
39 | - native open with w3m
40 |
41 | v2.0:
42 | - database support (NoSQL not sure whether mongo or redis, feel free to yell suggestions xx)
43 | - input data from database via flags e.g. --use-cookie, --load-forms
44 | - intelligent content sniffing, scan through http-200 responses in output file and flag interesting finds
45 | - special store: auth cookies, api tokens, keys
46 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | asyncio
2 | linecache
3 | requests
4 | random
5 | urllib
6 | concurrent
7 | bs4
8 |
--------------------------------------------------------------------------------
/resources/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Rozendantz/subforce/e399640c7598d4186a8cb5de33baaca63b9addfb/resources/__init__.py
--------------------------------------------------------------------------------
/resources/user_agents.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | def swap():
4 | rand_num = random.randrange(len(user_agents_list))
5 | return user_agents_list[rand_num]
6 |
7 | user_agents_list = [
8 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246',
9 | 'Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36',
10 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9',
11 | 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36',
12 | 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1',
13 | 'Mozilla/5.0 CK={} (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
14 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
15 | 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
16 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36',
17 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)',
18 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',
19 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)',
20 | 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
21 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
22 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763',
23 | 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; KTXN)',
24 | 'Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1',
25 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
26 | 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
27 | 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1',
28 | 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',
29 | 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
30 | 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
31 | 'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
32 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko)',
33 | 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0',
34 | 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
35 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
36 | 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
37 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko)',
38 | 'Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)',
39 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)',
40 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362',
41 | 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko',
42 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)',
43 | 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36',
44 | 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1',
45 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
46 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
47 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393',
48 | 'Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)',
49 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
50 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363',
51 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
52 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
53 | 'Mozilla/5.0 (Windows NT 5.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
54 | 'Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
55 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/605.1.15 (KHTML, like Gecko)',
56 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
57 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)',
58 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',
59 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063',
60 | 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
61 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
62 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36']
63 |
64 |
65 |
--------------------------------------------------------------------------------
/samples/dir.txt:
--------------------------------------------------------------------------------
1 | /.git
2 | /testing
3 | /manage
4 | /login
5 |
--------------------------------------------------------------------------------
/samples/sub.txt:
--------------------------------------------------------------------------------
1 | mail.myresmed.com
2 | www.resmed.com
3 | bcg29k.2163007t.resmed.com
4 | account.resmed.com
5 | account-uat.resmed.com
6 | www.account-uat.resmed.com
7 | adfs.resmed.com
8 | admin-mysleep.resmed.com
9 | admin-mysleep-u.resmed.com
10 | admin-shop-u.resmed.com
11 | agm-app-api.resmed.com
12 | www.agm-app-api.resmed.com
13 | airapp.resmed.com
14 | airfitf30.resmed.com
15 | www.airfitf30.resmed.com
16 | airfitn30i.resmed.com
17 | www.airfitn30i.resmed.com
18 | airmini.resmed.com
19 | www.airmini.resmed.com
20 | airtouchsweepstakes.resmed.com
21 | www.airtouchsweepstakes.resmed.com
22 | airview.resmed.com
23 | airviewcare.resmed.com
24 | airviewmaintenance.resmed.com
25 | airviewstatus.resmed.com
26 | airwatch.resmed.com
27 | ams-preview.resmed.com
28 | amsprod-www.resmed.com
29 | amsuat-www.resmed.com
30 | www.amsuat-www.resmed.com
31 | analytics.resmed.com
32 | ap.resmed.com
33 | ap-airview.resmed.com
34 | apac.resmed.com
35 | api.resmed.com
36 | api-iir.resmed.com
37 | apiaccount.resmed.com
38 | apiaccount-uat.resmed.com
39 | apigateway.resmed.com
40 | apigateway-dev.resmed.com
41 | apigateway-uat.resmed.com
42 | apim.resmed.com
43 | pre-prod.apim.resmed.com
44 | app.resmed.com
45 | selfie.app.resmed.com
46 | autodiscover.resmed.com
47 | avgweb.resmed.com
48 | b2baccounts.resmed.com
49 | b2baccounts-uat.resmed.com
50 | backend-iir.resmed.com
51 | benefits.resmed.com
52 | bpla.resmed.com
53 | businessgateway.resmed.com
54 | careers.resmed.com
55 | am.ccg.resmed.com
56 | prod-c-na2-content-force-com.am.ccg.resmed.com
57 | prod-c-na87-content-force-com.am.ccg.resmed.com
58 | amuat.ccg.resmed.com
59 | apuat.ccg.resmed.com
60 | eu.ccg.resmed.com
61 | eudev.ccg.resmed.com
62 | euuat.ccg.resmed.com
63 | cdn-uat-onlinestore.resmed.com
64 | china.resmed.com
65 | citrix.resmed.com
66 | click.resmed.com
67 | www.click.resmed.com
68 | dev3-onlinestore.resmed.com.resmed.com
69 | uat2-onlinestore.resmed.com.resmed.com
70 | connect.resmed.com
71 | covid19.resmed.com
72 | cpap-masks-ebook.resmed.com
73 | creditapp.resmed.com
74 | data.resmed.com
75 | demo-airview.resmed.com
76 | demo-airview-amr.resmed.com
77 | demo-airview-apac.resmed.com
78 | demo-airview-eu.resmed.com
79 | demo-myair.resmed.com
80 | design.resmed.com
81 | dev-api.resmed.com
82 | dev-apim.resmed.com
83 | dev-data.resmed.com
84 | dev-internal-apim.resmed.com
85 | dev-internal-data.resmed.com
86 | dev-learninghub.resmed.com
87 | dev-media.resmed.com
88 | dev-onlinestore.resmed.com
89 | dev2-api.resmed.com
90 | dev2-onlinestore.resmed.com
91 | dev3-api.resmed.com
92 | dev3-onlinestore.resmed.com
93 | document.resmed.com
94 | document-dev.resmed.com
95 | document-sbx.resmed.com
96 | document-uat.resmed.com
97 | documents.resmed.com
98 | mail.e.resmed.com
99 | edi.resmed.com
100 | edi-dev.resmed.com
101 | edi-uat.resmed.com
102 | eneu.resmed.com
103 | engna.resmed.com
104 | ers.resmed.com
105 | mail.eu.resmed.com
106 | eudev-www.resmed.com
107 | www.eudev-www.resmed.com
108 | euuat-www.resmed.com
109 | www.euuat-www.resmed.com
110 | fixmysleep.resmed.com
111 | forms.resmed.com
112 | freu.resmed.com
113 | gel.resmed.com
114 | globaltableau.resmed.com
115 | globaltableaudev.resmed.com
116 | globaltableauuat.resmed.com
117 | gslb.resmed.com
118 | vpn.gslb.resmed.com
119 | help.resmed.com
120 | hubspot-api.resmed.com
121 | www.hubspot-api.resmed.com
122 | id.resmed.com
123 | www.id.resmed.com
124 | id-it-sbx.resmed.com
125 | www.id-it-sbx.resmed.com
126 | id-sbx.resmed.com
127 | idmapi-dev.resmed.com
128 | iir.resmed.com
129 | iir-test.resmed.com
130 | iir-uat.resmed.com
131 | im.resmed.com
132 | im1au.resmed.com
133 | images.resmed.com
134 | inbound-mx.resmed.com
135 | internal-apim.resmed.com
136 | internal-data.resmed.com
137 | investor.resmed.com
138 | investors.resmed.com
139 | iphone.resmed.com
140 | it-support.resmed.com
141 | jamf.resmed.com
142 | jivd.resmed.com
143 | learninghub.resmed.com
144 | legacy.resmed.com
145 | madmoney1.resmed.com
146 | mail.resmed.com
147 | legacy.mail.resmed.com
148 | mobile.mail.resmed.com
149 | mailtest.resmed.com
150 | mcintmyair.resmed.com
151 | me.resmed.com
152 | media.resmed.com
153 | mobile.resmed.com
154 | mon-amr.resmed.com
155 | mon-apac.resmed.com
156 | mon-eu.resmed.com
157 | muirex.resmed.com
158 | muirex4.resmed.com
159 | myaccount.resmed.com
160 | myair.resmed.com
161 | myairlinktracker.resmed.com
162 | myairoct.resmed.com
163 | myairpulse.resmed.com
164 | www.myairpulse.resmed.com
165 | myairrestservice.resmed.com
166 | myitpeople.resmed.com
167 | mynight.resmed.com
168 | mynight-api.resmed.com
169 | mynight-api-uat.resmed.com
170 | mynightapi-uat.resmed.com
171 | myosa.resmed.com
172 | myresupply.resmed.com
173 | mysleep.resmed.com
174 | api.mysleep.resmed.com
175 | mysleep-u.resmed.com
176 | api.mysleep-u.resmed.com
177 | api.shop.mysleep-u.resmed.com
178 | narval-easy.resmed.com
179 | newsroom.resmed.com
180 | www.newsroom.resmed.com
181 | nightowl-api.resmed.com
182 | www.nightowl-api.resmed.com
183 | niv-trial.resmed.com
184 | odysseyweb.resmed.com
185 | onlinestore.resmed.com
186 | www.onlinestore.resmed.com
187 | opentext-poc.resmed.com
188 | www.opentext-poc.resmed.com
189 | orgnuat-www.resmed.com
190 | origin.resmed.com
191 | origin-dk.resmed.com
192 | origin-es.resmed.com
193 | origin-mysleep.resmed.com
194 | origin-mysleep-u.resmed.com
195 | origin-shop-u.resmed.com
196 | origin-supplier.resmed.com
197 | origin-supplier-uat.resmed.com
198 | origin-www.resmed.com
199 | origin-wwwuat.resmed.com
200 | originconnect.resmed.com
201 | osahub.resmed.com
202 | owa.resmed.com
203 | pages.resmed.com
204 | www.pages.resmed.com
205 | partner.resmed.com
206 | pdeftp.resmed.com
207 | portal.resmed.com
208 | www.portal.resmed.com
209 | pretherapyapp.resmed.com
210 | en.pretherapyapp.resmed.com
211 | preview.resmed.com
212 | previewuat.resmed.com
213 | ps-mon-amr.resmed.com
214 | ps-mon-apac.resmed.com
215 | ps-mon-eu.resmed.com
216 | ps0-airapp.resmed.com
217 | pulse.resmed.com
218 | pulse-dev.resmed.com
219 | pulse-uat.resmed.com
220 | reclaimyoursleep.resmed.com
221 | restapi.resmed.com
222 | de.restapi.resmed.com
223 | orgnprd.de.restapi.resmed.com
224 | www.orgnprd.de.restapi.resmed.com
225 | orgnuat.de.restapi.resmed.com
226 | www.orgnuat.de.restapi.resmed.com
227 | de-uat.restapi.resmed.com
228 | restapi-uat.resmed.com
229 | resteasy.resmed.com
230 | www.resteasy.resmed.com
231 | resupply.resmed.com
232 | rms.resmed.com
233 | rmsviewer.resmed.com
234 | sds.resmed.com
235 | mask-selector.sds.resmed.com
236 | search.resmed.com
237 | secure.resmed.com
238 | securemail.resmed.com
239 | www.securemail.resmed.com
240 | secureuat.resmed.com
241 | sftp.resmed.com
242 | shop.resmed.com
243 | api.shop.resmed.com
244 | shop-u.resmed.com
245 | api.shop-u.resmed.com
246 | sip.resmed.com
247 | smtp.resmed.com
248 | smtptls.resmed.com
249 | sparc.resmed.com
250 | mail.sparc-mail.resmed.com
251 | sparc-uat.resmed.com
252 | mail.sparc-uat-mail.resmed.com
253 | mail.spglobal.resmed.com
254 | splus.resmed.com
255 | www.splus.resmed.com
256 | ssl.resmed.com
257 | ssluat.resmed.com
258 | sslvpn.resmed.com
259 | sso-dev.resmed.com
260 | www.sso-dev.resmed.com
261 | staging-data.resmed.com
262 | staging-internal-data.resmed.com
263 | stladmin.resmed.com
264 | storage.resmed.com
265 | store.resmed.com
266 | supplier.resmed.com
267 | supplier-uat.resmed.com
268 | support.resmed.com
269 | ex.support.resmed.com
270 | support-dev.resmed.com
271 | support-mysleep.resmed.com
272 | support-mysleep-u.resmed.com
273 | support-sbx.resmed.com
274 | support-shop.resmed.com
275 | support-shop-u.resmed.com
276 | support-uat.resmed.com
277 | techsupportindia.resmed.com
278 | testsupport.resmed.com
279 | tia.resmed.com
280 | tls.resmed.com
281 | uat-airapp.resmed.com
282 | uat-api.resmed.com
283 | uat-b2baccounts.resmed.com
284 | uat-mon-amr.resmed.com
285 | uat-mon-apac.resmed.com
286 | uat-mon-eu.resmed.com
287 | uat-onlinestore.resmed.com
288 | uat2-onlinestore.resmed.com
289 | uc.resmed.com
290 | uk-resupply.resmed.com
291 | us1-mrs.resmed.com
292 | ux-coe1.resmed.com
293 | ux-coe2.resmed.com
294 | ux-coe3.resmed.com
295 | ux-coe4.resmed.com
296 | ux-coe5.resmed.com
297 | ux-coe6.resmed.com
298 | ux-coe7.resmed.com
299 | ux-coe8.resmed.com
300 | victoria-dev.resmed.com
301 | video.resmed.com
302 | vipau.resmed.com
303 | vipportal.resmed.com
304 | vnv-mon-eu.resmed.com
305 | waf-mysleep.resmed.com
306 | webforms.resmed.com
307 | webforms-api.resmed.com
308 | www.webforms-api.resmed.com
309 | webmail.resmed.com
310 | wp-me-www.resmed.com
311 | wwworgn1.resmed.com
312 | wwwuat.resmed.com
313 |
314 |
--------------------------------------------------------------------------------
/subforce.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | import sys
3 | import asyncio
4 | import linecache
5 | import json
6 | import requests
7 | import random
8 | import urllib.parse
9 | import colorama
10 | from colorama import Fore, Back, Style
11 |
12 | from concurrent.futures import ThreadPoolExecutor
13 | from bs4 import BeautifulSoup as bs
14 |
15 | from subforce import core
16 | from resources import user_agents
17 |
18 |
19 |
20 | # check if the provided list files exist
21 |
22 | sub_file = core.args.sublist_file[0]
23 | dir_file = core.args.dirlist_file[0]
24 |
25 | subfile_iterator = [0]
26 | dirfile_iterator = [0]
27 |
28 | subfile_readstack = []
29 | dirfile_readstack = [""] #first element is blank so the base url will be fetched
30 |
31 | domains_list = []
32 | results_list = []
33 |
34 | sleep_inc = 0.0001
35 | stack_size = 100
36 |
37 | results = []
38 |
39 | '''
40 | ***************************************************************************************************************************************************************************
41 | FILE FNs
42 | ***************************************************************************************************************************************************************************
43 | '''
44 | async def write_to_file(results_list):
45 | file = open('results.txt', 'a')
46 | print(Fore.YELLOW, end="")
47 | print("\n\n=== Writing to log ===\n\n")
48 | print(Style.RESET_ALL, end="")
49 | for result in results_list:
50 | headers = result.headers
51 | cookiejar = result.cookies
52 | cookies = cookiejar.items()
53 | file.write("\n\n")
54 | file.write("***************************************************************************************************************************************\n")
55 | file.write("---------------------------------------------------------------------------------------------------------------------------------------\n")
56 | file.write("---------------------------------------------------------------------------------------------------------------------------------------\n")
57 | file.write(" {} \n".format(result.url))
58 | file.write("---------------------------------------------------------------------------------------------------------------------------------------\n")
59 | file.write("---------------------------------------------------------------------------------------------------------------------------------------\n")
60 | file.write("- status: {}\n".format(result.status_code))
61 | file.write("- reason: {}\n".format(result.reason))
62 | #file.write("- is redirect? {}\n".format(result.is_redirect))
63 | #if result.is_redirect:
64 | # file.write("is permanent redirect? {}\n".format(result.is_permanent.redirect))
65 | file.write("\n- headers: \n")
66 | for key,value in headers.items():
67 | file.write("\t{keys}: {values}\n".format(keys=key, values=value))
68 | file.write("\n- cookies: \n")
69 | for cookie in cookies:
70 | file.write("\t{}\n".format(cookie))
71 | result_bytes = result.content
72 | html_formatted = result_bytes.decode('utf-8')
73 | soup = bs(html_formatted, "html.parser")
74 | file.write("\n----------------------\n")
75 | file.write("- style tags: \n")
76 | file.write("----------------------\n\n")
77 | for tags in soup.find_all('style'):
78 | #prettify the css
79 | file.write("{}\n\n".format(tags))
80 | file.write("\n----------------------\n")
81 | file.write("- script tags: \n")
82 | file.write("----------------------\n\n")
83 | for tags in soup.find_all('script'):
84 | #prettify the javascript
85 | file.write("{}\n\n".format(tags))
86 | file.write("\n----------------------\n")
87 | file.write("- links: \n")
88 | file.write("----------------------\n\n")
89 | for tags in soup.find_all('a'):
90 | #prettify the links
91 | file.write("{}\n".format(tags))
92 | file.write("---------------------------------------------------------------------------------------------------------------------------------------\n")
93 | file.write("---------------------------------------------------------------------------------------------------------------------------------------\n")
94 | file.write("***************************************************************************************************************************************\n")
95 | file.write("\n")
96 | file.close()
97 |
98 |
99 | def files_exist(subfile, dirfile):
100 | if os.path.isfile(subfile):
101 | subfile_exist = True
102 | else:
103 | print(Style.BRIGHT, end="")
104 | print(Fore.RED, end="")
105 | print('sub_file does not exit')
106 | print(Style.RESET_ALL, end="")
107 |
108 | if os.path.isfile(dirfile):
109 | dirfile_exist = True
110 | else:
111 | print(Style.BRIGHT, end="")
112 | print(Fore.RED, end="")
113 | print('dir_file does not exit')
114 | print(Style.RESET_ALL, end="")
115 |
116 | if subfile_exist and dirfile_exist:
117 | return True
118 | else:
119 | sys.exit()
120 |
121 |
122 | async def read_from_file(list_file, file_lines, read_stack, file_iterator):
123 | global sleep_inc
124 |
125 | if file_iterator[-1] >= file_lines -1:
126 | return
127 |
128 | if len(read_stack) < stack_size -1:
129 | with open(list_file) as f:
130 | for i in range(1, file_lines+1):
131 | file_iterator.append(i)
132 | line = linecache.getline(list_file, i, module_globals=None).strip()
133 | if len(line) > 0:
134 | print(Fore.YELLOW, end="")
135 | print("reading: ", end="")
136 | print(Fore.CYAN, end="")
137 | print(line)
138 | print(Style.RESET_ALL, end="")
139 | read_stack.append(line)
140 | await asyncio.sleep(sleep_inc)
141 | if i == stack_size:
142 | await asyncio.sleep(sleep_inc)
143 | else:
144 | await asyncio.sleep(sleep_inc)
145 |
146 |
147 | async def get_lines(list_file):
148 | with open(list_file) as f:
149 | f.seek(0) #ensure you're at the start of the file..
150 | first_char = f.read(1) #get the first character
151 | if not first_char:
152 | print(Style.BRIGHT, end="")
153 | print(Fore.RED, end="")
154 | print("FAIL: the sub or dir files (or both) are empty") #first character is the empty string..
155 | print(Style.RESET_ALL, end="")
156 | sys.exit()
157 | else:
158 | f.seek(0) #f
159 | for i, l in enumerate(f):
160 | await asyncio.sleep(sleep_inc)
161 | pass
162 | return i + 1
163 |
164 |
165 | async def file_lines():
166 | global sub_file
167 | global dir_file
168 | #global subfile_lines
169 | #global dirfile_lines
170 |
171 | if files_exist(sub_file, dir_file):
172 | print(Fore.YELLOW, end="")
173 | print("Reading files... ")
174 | print(Style.RESET_ALL, end="")
175 | subfile_lines = files_read_loop.create_task(get_lines(sub_file))
176 | dirfile_lines = files_read_loop.create_task(get_lines(dir_file))
177 | await asyncio.wait([subfile_lines, dirfile_lines])
178 | return (subfile_lines, dirfile_lines)
179 |
180 |
181 | async def load_files():
182 | global sub_file
183 | global dir_file
184 | global subfile_iterator
185 | global dirfile_iterator
186 | global subfile_readstack
187 | global dirfile_readstack
188 |
189 | (subfile_lines, dirfile_lines) = await file_lines()
190 |
191 | read_from_sub_file = files_read_loop.create_task(read_from_file(sub_file, subfile_lines.result(), subfile_readstack, subfile_iterator))
192 | read_from_dir_file = files_read_loop.create_task(read_from_file(dir_file, dirfile_lines.result(), dirfile_readstack, dirfile_iterator))
193 | concat_sub_to_dir = files_read_loop.create_task(concat_addr(subfile_readstack, dirfile_readstack))
194 | await asyncio.wait([read_from_sub_file, read_from_dir_file, concat_sub_to_dir])
195 |
196 |
197 | async def concat_addr(subread, dirread):
198 | global results_list
199 | global domains_list
200 | global sleep_inc
201 | global subfile_readstack
202 | global dirfile_readstack
203 | global subfile_lines
204 | global dirfile_lines
205 |
206 | domains_list_size = len(domains_list)
207 |
208 | if domains_list_size < stack_size -1:
209 | for i, j in enumerate(subfile_readstack):
210 | for j, k in enumerate(dirfile_readstack):
211 | print(Fore.YELLOW, end="")
212 | print("adding: ", end="")
213 | if len(k) and k[0] != '/':
214 | domains_list.insert(0, subfile_readstack[i] + '/' + dirfile_readstack[j])
215 | print(Fore.CYAN, end="")
216 | print("{domain}".format(domain=domains_list[0]))
217 | print(Style.RESET_ALL, end="")
218 | else:
219 | domains_list.insert(0, subfile_readstack[i] + dirfile_readstack[j])
220 | print(Fore.CYAN, end="")
221 | print("{domain}".format(domain=domains_list[0]))
222 | print(Style.RESET_ALL, end="")
223 | await asyncio.sleep(sleep_inc)
224 | else:
225 | await asyncio.sleep(sleep_inc)
226 |
227 |
228 |
229 | async def write_log():
230 | global results
231 | ret = files_write_loop.create_task(write_to_file(results))
232 |
233 |
234 | '''
235 | ***************************************************************************************************************************************************************************
236 | NETWORK FNs
237 | ***************************************************************************************************************************************************************************
238 | '''
239 |
240 | def fetch(session, url):
241 | FQDM = "https://{domain}?".format(domain=url)
242 | try:
243 | fresh_agent = user_agents.swap()
244 | custom_header = {'user-agent': fresh_agent}
245 | with session.get(FQDM, headers=custom_header, timeout=10) as response:
246 | status = response.status_code
247 | url = response.url
248 | print(Style.NORMAL, end="")
249 | print(Fore.WHITE, end="")
250 | print("[ ", end="")
251 | if status == 200:
252 | print(Fore.GREEN, end="")
253 | elif status == 403:
254 | print(Fore.MAGENTA, end="")
255 | else:
256 | print(Fore.RED, end="")
257 | print(status, end="")
258 | print(Fore.WHITE, end="")
259 | print(" ] - ", end="")
260 | print(Fore.CYAN, end="")
261 | print(url)
262 | print(Style.RESET_ALL, end="")
263 | results.append(response)
264 | return response
265 | except:
266 | print(Fore.RED, end="")
267 | print(Style.DIM, end="")
268 | print("Server at ", end="")
269 | print(Fore.CYAN, end="")
270 | print(url, end="")
271 | print(Fore.RED, end="")
272 | print(" not found")
273 | finally:
274 | pass
275 |
276 |
277 | async def get(domains):
278 | global results
279 | with ThreadPoolExecutor(max_workers=50) as executor:
280 | with requests.Session() as session:
281 | loop = asyncio.get_event_loop()
282 | print('''
283 | \n\n
284 | ------------------------
285 | RESULTS
286 | ------------------------
287 | \n
288 | '''
289 | )
290 | for url in domains:
291 | loop.run_in_executor( executor, fetch, *(session, url))
292 |
293 | return True
294 |
295 | '''
296 | def get(page_url, timeout=10):
297 | fresh_agent = user_agents.swap()
298 | response = requests.get(url=page_url, timeout=timeout, headers=custom_header)
299 |
300 | async def threadpool():
301 | with concurrent.futures.ThreadPoolExecutor() as executor:
302 | futures = []
303 | for url in wiki_page_urls:
304 | futures.append(
305 | executor.submit(
306 | get_wiki_page_existence, wiki_page_url=url, timeout=0.00001
307 | )
308 | )
309 | for future in concurrent.futures.as_completed(futures):
310 | try:
311 | print(future.result())
312 | except requests.ConnectTimeout:
313 | print("ConnectTimeout.")
314 | '''
315 | async def iterate_domains():
316 | global results
317 | global domains_list
318 | ret = domains_loop.create_task(get(domains_list))
319 | return
320 |
321 | '''
322 | ***************************************************************************************************************************************************************************
323 | MAIN
324 | ***************************************************************************************************************************************************************************
325 | '''
326 |
327 | if __name__ == "__main__":
328 | try:
329 | #file_sema = asyncio.BoundedSemaphore(value=10)
330 |
331 | files_read_loop = asyncio.get_event_loop()
332 | files_read_loop.run_until_complete(load_files())
333 |
334 | domains_loop = asyncio.get_event_loop()
335 | domains_loop.run_until_complete(iterate_domains())
336 |
337 | files_write_loop = asyncio.get_event_loop()
338 | files_write_loop.run_until_complete(write_log())
339 | except Exception as e:
340 | print(Fore.RED, end="")
341 | print(Style.BRIGHT, end="")
342 | print("****** EXCEPTION: {} ".format(e))
343 | print(Style.RESET_ALL, end="")
344 | pass
345 | finally:
346 | files_read_loop.close()
347 | domains_loop.close()
348 | files_write_loop.close()
349 |
350 |
351 |
--------------------------------------------------------------------------------
/subforce/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/subforce/core.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import time
3 |
4 | import colorama
5 | from colorama import Fore, Back, Style
6 | colorama.init()
7 | print(Style.RESET_ALL, end="")
8 | #print(colorama.ansi.clear_screen())
9 | print(Fore.MAGENTA, end="")
10 | print(Style.BRIGHT, end="")
11 | print('''
12 |
13 | --------------------------------------------------------------------------------------
14 | _______ ______ _______ _______ _______ _______ _______
15 | ---- ( ____ \|\ /|( ___ \ ( ____ \( ___ )( ____ )( ____ \( ____ \ ----
16 | --- | ( \/| ) ( || ( ) )| ( \/| ( ) || ( )|| ( \/| ( \/ ---
17 | -- | (_____ | | | || (__/ / | (__ | | | || (____)|| | | (__ --
18 | - (_____ )| | | || __ ( | __) | | | || __)| | | __) -
19 | ) || | | || ( \ \ | ( | | | || (\ ( | | | (
20 | /\____) || (___) || )___) )| ) | (___) || ) \ \__| (____/\| (____/
21 | \_______)(_______)|/ \___/ |/ (_______)|/ \__/(_______/(_______/
22 |
23 | --------------------------------------------------------------------------------------
24 |
25 | A tool that enables forced browsing over all known subdomains
26 | Enumerate through a list of subdomains and conduct forced browsing using a dictionary file
27 |
28 | ''')
29 |
30 | print(Style.NORMAL)
31 |
32 | time.sleep(1)
33 |
34 | parser = argparse.ArgumentParser(prog='subforce', usage='''%(prog)s --sublist/-s --dirlist/-s
35 | File must be linebyline format, csv is not currently supported''',
36 | description='''Enumerate through a list of subdomains and conduct forced browsing using a dictionary file.
37 | Files must be in linebyline format, csv is not currently supported''')
38 |
39 | required = parser.add_argument_group('required named arguments')
40 |
41 | required.add_argument('-s', '--sublist', dest='sublist_file', action='append',
42 | default=None, required=True,
43 | help='subdomain wordlist (e.g. generated from sublist3r)')
44 | required.add_argument('-d', '--dirlist', dest='dirlist_file', action='append',
45 | default=None, required=True,
46 | help='subdirectory wordlist (e.g. /.git, /test, /login, /wp-admin etc)')
47 |
48 | #parser.parse_args(['-h'])
49 |
50 | args = parser.parse_args()
51 |
--------------------------------------------------------------------------------