Finding & Exploiting Exposed VPNs
Discovering internet-exposed VPNs and turning them into initial access.
Finding & Exploiting Exposed VPNs
Finding Exposed VPNs
Mapping out target infrastructure and targeting VPNs.
Why do we even care? The reason we care is because a VPN is the gateway to their internal network. That is a companies biggest fear. Due to persistance, stealing sensitive data, ransomware etc. Hacking a webapp is likely to be in it's own seperate network in a DMZ. If you can mao out and exploit their VPNs, it\s game over.
Strategy 1: Map out target infrastructure and find VPNs (ONLY IF SELF HOSTED):
Map out targets full IP range first. Find their main domain and simply ping them to get their IP. ping testphp.vulnweb.com
We can also run reverse dns on IP to see corresponding domain name. dig -x 44.228.249.3
In output we can easily see this is an EC2 instance hosted in amazon: 3.249.228.44.in-addr.arpa. 0 IN PTR ec2-44-228-249-3.us-west-2.compute.amazonaws.com.
Then take that IP and run a whois to see who owns target and get their full IP range to widen the attack surface: whois 44.228.249.3
Assuming this is self hosted infrastructure, then scan the entire IP range with either nmap or rustscan. I'd recommend rustscan. Much faster.
If you're after VPNs, I'd recommend scanning all Ips in IP range for these ports:
- UDP 500 for Ike
- UDP 4500 for IPSEC Nat-Traversal Mode
- If port number 443 is open, it is an SSL VPN.
- If port number 3389 is open, it is RDP.
- If port number 22 is open, it's SSH.
These are common ports for either VPNs based or UDP based VPNs, and 22 and 3389 is in case of jump boxes for the targeted organization. All valuable data to have if you want to get into the internal network of that company for ethical penetration tests.
After this resolve the IPs with dnsx or dig -x and save to a list for domains. And save all IPs elsewhere. You can scan the domains with httpx like shown under, and IPs are better suited for nuclei due to self signed certifcate will likely cause issues for httpx when it comes to exposed VPNs.
This technique will not work in scenarious it's being hosted in by cloudflare or in the cloud as cloud ranges is given to more than just one company. So unlses the company is hosting the infrastructure themselves which some do, be careful with scanning out of scope. Pay close attention to the Netname, OrgName, and Route fields in the whois lookup.
Strategy 2: Map out target infrastructure and find VPNs (If not self hosted, but works eitherway):
If you have issues downloading tools, you'll find info at the bottom of this document.
Find every passive DNS related domain related to tesla.com subfinder -all -silent -d tesla.com | dnsx -silent | tee subdomains.txt
Check for sensitive keywords grep -Ei "vpn|cisco|citrix|forti|forticlient|Outlook|login" subdomains.txt
In this example we found 8 exposed live VPN related domains for tesla.com apacvpn.tesla.com apacvpn1.tesla.com apacvpn2.tesla.com cnvpn1.tesla.com cnvpn.tesla.com vpn2.tesla.com vpn1.tesla.com vpn3.tesla.com
Using httpx to check for more sensitive exposed VPNs, emails, or general login panels in the html response of the page. cat subdomains.txt | httpx -sc -title -mr "\bVpn\b|\bCisco\b|\bCitrix\b|\bForti|forticlient|\bOutlook\b|\blogin\b|\bGlobalProtect\b|\bAzureAttend\b" -p 80,443,8000,8080,8443 -follow-redirects | tee vpn.txt
httpx has an issue where it won't accept self signed certificates. This is an issue because a lot of VPNs are exposed with self signed certs. Luckily we have a way around this using Nuclei. nuclei -no-interactsh -nh -stats -follow-host-redirects -l "httpx_domains.clean" -o "nuclei-results.txt" -t "/opt/tools/test.yaml" -vv Keep in mind “httpx_domains.clean” is the domains and subdomain we want to target, and test.yaml is our nuclei template we will be using.
This is a great methodology for finding companies most valuable treasures. Plenty more guides are coming soon.
Setting up tools: subfinder: apt install subfinder -y
DNSX: apt install dnsx -y
HTTPX: rm /usr/bin/httpx wget https://github.com/projectdiscovery/httpx/releases/download/v1.6.9/httpx_1.6.9_linux_amd64.zip unzip httpx_1.6.9_linux_amd64.zip cp httpx /usr/bin/httpx
01id: keyword-checker02 03info:04 name: VPN Keyword Checker05 author: Your Name06 severity: info07 description: Checks for the presence of VPN-related keywords and URLs in the response body.08 tags: tech,cisco,vpn,forticlient,forti09 10requests:11 - method: GET12 path:13 - "{{BaseURL}}/"14 - "{{BaseURL}}/vpn"15 - "{{BaseURL}}/remote"16 - "{{BaseURL}}/owa"17 18 redirects: true19 max-redirects: 420 matchers:21 - type: word22 words:23 - "Cisco"24 - "forticlient"25 - "Citrix"26 - "VPN"27 - "Forti"28 - "Outlook"29 - "CSCOE"30 - "GlobalProtect"31 - "+webvpn+"32 - "AzureAttend"33 34 condition: or35 part: response36 37 extractors:38 - type: regex39 part: response40 regex:41 - '(?i)Cisco'42 - '(?i)forticlient'43 - '(?i)Citrix'44 - '(?i)VPN'45 - '(?i)Forti'46 - '(?i)Outlook'47 - '(?i)CSCOE'48 - '(?i)GlobalProtect'49 - '(?i)webvpn'50 - '(?i)AzureAttend'51 52 - method: GET53 path:54 - "{{BaseURL}}/"55 matchers:56 - type: word57 words:58 - "top.location=window.location;top.location="59 - "window.location.href="60 - "document.location="61 62 condition: or63 part: response64 65 extractors:66 - type: regex67 part: response68 regex:69 - '(?i)top.location=window.location;top.location='70 - '(?i)window.location.href='71 - '(?i)document.location='nuclei template for vpns
01id: keyword-checker02 03info:04 name: VPN Keyword Checker05 author: Your Name06 severity: info07 description: Checks for the presence of VPN-related keywords and URLs in the response body.08 tags: tech,cisco,vpn,forticlient,forti09 10requests:11 - method: GET12 path:13 - "{{BaseURL}}/"14 - "{{BaseURL}}/vpn"15 - "{{BaseURL}}/remote"16 - "{{BaseURL}}/owa"17 18 redirects: true19 max-redirects: 420 matchers:21 - type: word22 words:23 - "Cisco"24 - "forticlient"25 - "Citrix"26 - "VPN"27 - "Forti"28 - "Outlook"29 - "CSCOE"30 - "GlobalProtect"31 - "+webvpn+"32 - "AzureAttend"33 34 condition: or35 part: response36 37 extractors:38 - type: regex39 part: response40 regex:41 - '(?i)Cisco'42 - '(?i)forticlient'43 - '(?i)Citrix'44 - '(?i)VPN'45 - '(?i)Forti'46 - '(?i)Outlook'47 - '(?i)CSCOE'48 - '(?i)GlobalProtect'49 - '(?i)webvpn'50 - '(?i)AzureAttend'51 52 - method: GET53 path:54 - "{{BaseURL}}/"55 matchers:56 - type: word57 words:58 - "top.location=window.location;top.location="59 - "window.location.href="60 - "document.location="61 62 condition: or63 part: response64 65 extractors:66 - type: regex67 part: response68 regex:69 - '(?i)top.location=window.location;top.location='70 - '(?i)window.location.href='71 - '(?i)document.location='VPN
-
UDP 500 for Ike | Check for this vuln https://raxis.com/blog/ike-vpns-supporting-aggressive-mode/
-
UDP 4500 for IPSEC Nat-Traversal Mode
-
If port number 443 is open, it is an SSL VPN.
-
If port number 3389 is open, it is RDP.
-
If port number 22 is open, it's SSH.
https://serverfault.com/questions/451381/which-ports-for-ipsec-lt2p
Scan IP ranges of ASN for port 3389, 22, 500 and 443. Get all subdomains of websites to look for vpn subdomain.
subfinder -d edu.ee -all -v -o subs.txt cat subs.txt | httpx -probe | grep -i SUCCESS | cut -d '[' -f1 | tee subs.alive
cat subs.alive | grep -i vpn cat subs.alive | grep -i vps cat subs.alive | grep -i dev cat subs.alive | grep -i test
cat subs.alive | httpx -sc -title -ms 'VPN' -p 80,443,8080,8443 -follow-redirects | tee httpx.log cat subs.alive | httpx -sc -title -ms 'citrix' -p 80,443,8080,8443 -follow-redirects | tee httpx.log (httpx doesnt scan non http/s ports lol)
go to https://bgp.he.net/ and search ipv4 address of the website you wanna use to find the rest of comapny ASN and ip ranges. grab the ip range/s you wanna test. rustscan -a 193.40.0.0/16 -p 80,443 --ulimit 5000 -g | tee rust.grep && cut -d ' ' -f1 rust.grep | tee rust.ip
next you can do this to resolve all IPs to the corresponding domains. this will basically find all the alive subdomains in their ip range: for ip in $(cat rust.ip); do domain=$(dig +short -x $ip) echo "$ip: $domain" >> ip_domains.txt done && awk -F ': ' '{print $2}' ip_domains.txt | sed 's/.$//; /^$/d' | tee ip_domains_clean.txt
check for IPSec based VPNs over UDP: (might wanna run 2-3 times to verify) rustscan -a rust.ip -p 500 --ulimit 5000 -g -- -sU -v
Go through all domains/subdomains and scout for exposed VPNs: cat ip_domains_clean.txt | httpx -sc -title -ms 'VPN' -p 80,443,8080,8443 -follow-redirects | tee VPNs.txt cat ip_domains_clean.txt | httpx -sc -title -ms 'citrix' -p 80,443,8080,8443 -follow-redirects | tee VPNs.txt
Seems to work well: cat equinor_subs.alive.txt | httpx -sc -title -mr "\bVpn\b|\bCisco\b|\bCitrix\b|\bForti" -p 80,443 -follow-redirects | tee vpn.txt
All over tor technique: proxychains -q masscan -p0 193.40.0.0/16 --ping --rate=500 | tee pingsweep.txt && cat pingsweep.txt | cut -d 'n' -f 3 | grep -o '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' | tee ips.txt && for ip in $(cat ips.txt); do domain=$(proxychains -q dig +short -x $ip) echo "$domain" done >> domains.txt && cat domains.txt| sed 's/.$//; /^$/d' | grep -v ';;' | tee domains.txt
This works well, but wont work over self signed certificates sadly: cat equinor_subs.alive.txt | httpx -sc -title -mr "\bVpn\b|\bCisco\b|\bCitrix\b|\bForti|forticlient|\Ooutlook\b" -p 80,443,8000,8080,8443 -follow-redirects | tee vpn.txt
This does, but wont be able to naturally follow redirects and grab the word-matching from the endsite, if its been redirected. Only works on initial one unfortunately: nuclei -no-interactsh -stats -follow-host-redirects -l "test.txt" -o "nuclei-results.txt" -t "./test.yaml" -vv
#The Nuclei developers are aware of this limitation and are working on a solution to remove nested callbacks and properly follow redirects, as indicated by the open issue (#4980) and the ongoing work in the "feat-4980-callbacks" branch1.
Best workflow <3 proxychains -q masscan -p0 147.91.0.0/16 --ping --rate=500 | tee pingsweep.txt && cat pingsweep.txt | cut -d 'n' -f 3 | grep -o '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' | tee ips.txt && for ip in $(cat ips.txt); do domain=$(proxychains -q dig +short -x $ip) echo "$domain" done >> domains.txt && cat domains.txt| sed 's/.$//; /^$/d' | grep -v ';;' | tee domains.txt
cat ips.txt | httpx -sc -title -fr -silent | tee httpx.log | cut -d '[' -f 1 | tee httpx_ips.clean cat domains.txt | httpx -sc -title -fr -silent | tee httpx.log | cut -d '[' -f 1 | tee httpx_domains.clean
nuclei -no-interactsh -nh -stats -follow-host-redirects -l "httpx_ips.clean" -o "nuclei-results.txt" -t "/opt/tools/test.yaml" -vv nuclei -no-interactsh -nh -stats -follow-host-redirects -l "httpx_domains.clean" -o "nuclei-results.txt" -t "/opt/tools/test.yaml" -vv
DOESNT WORK OVER TOR, BE MINDFUL
rustscan -p 4500,500 -a ips.txt -g -- -sU | tee rust