// notes/ Exploitation & Tooling
🔐

Finding & Exploiting Exposed VPNs

Discovering internet-exposed VPNs and turning them into initial access.

#vpn#initial access#exploitation

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

🐺 howlsec@kali
01id: keyword-checker
02
03info:
04 name: VPN Keyword Checker
05 author: Your Name
06 severity: info
07 description: Checks for the presence of VPN-related keywords and URLs in the response body.
08 tags: tech,cisco,vpn,forticlient,forti
09
10requests:
11 - method: GET
12 path:
13 - "{{BaseURL}}/"
14 - "{{BaseURL}}/vpn"
15 - "{{BaseURL}}/remote"
16 - "{{BaseURL}}/owa"
17
18 redirects: true
19 max-redirects: 4
20 matchers:
21 - type: word
22 words:
23 - "Cisco"
24 - "forticlient"
25 - "Citrix"
26 - "VPN"
27 - "Forti"
28 - "Outlook"
29 - "CSCOE"
30 - "GlobalProtect"
31 - "+webvpn+"
32 - "AzureAttend"
33
34 condition: or
35 part: response
36
37 extractors:
38 - type: regex
39 part: response
40 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: GET
53 path:
54 - "{{BaseURL}}/"
55 matchers:
56 - type: word
57 words:
58 - "top.location=window.location;top.location="
59 - "window.location.href="
60 - "document.location="
61
62 condition: or
63 part: response
64
65 extractors:
66 - type: regex
67 part: response
68 regex:
69 - '(?i)top.location=window.location;top.location='
70 - '(?i)window.location.href='
71 - '(?i)document.location='

nuclei template for vpns

🐺 howlsec@kali
01id: keyword-checker
02
03info:
04 name: VPN Keyword Checker
05 author: Your Name
06 severity: info
07 description: Checks for the presence of VPN-related keywords and URLs in the response body.
08 tags: tech,cisco,vpn,forticlient,forti
09
10requests:
11 - method: GET
12 path:
13 - "{{BaseURL}}/"
14 - "{{BaseURL}}/vpn"
15 - "{{BaseURL}}/remote"
16 - "{{BaseURL}}/owa"
17
18 redirects: true
19 max-redirects: 4
20 matchers:
21 - type: word
22 words:
23 - "Cisco"
24 - "forticlient"
25 - "Citrix"
26 - "VPN"
27 - "Forti"
28 - "Outlook"
29 - "CSCOE"
30 - "GlobalProtect"
31 - "+webvpn+"
32 - "AzureAttend"
33
34 condition: or
35 part: response
36
37 extractors:
38 - type: regex
39 part: response
40 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: GET
53 path:
54 - "{{BaseURL}}/"
55 matchers:
56 - type: word
57 words:
58 - "top.location=window.location;top.location="
59 - "window.location.href="
60 - "document.location="
61
62 condition: or
63 part: response
64
65 extractors:
66 - type: regex
67 part: response
68 regex:
69 - '(?i)top.location=window.location;top.location='
70 - '(?i)window.location.href='
71 - '(?i)document.location='

VPN

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 rustunnamed_18b2746c8809418b8f2741df79535261