├── .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 | ![Usage_gif](/.github/updatedrecording.gif?raw=true "Usage") 11 | 12 | 13 | Sample output file: 14 | 15 | ![Output_file_gif](/.github/outputrecording.gif?raw=true "Output") 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 | --------------------------------------------------------------------------------