EvilQR Phishing / QRLJacking
QR (Quick Response) codes have become increasingly common. QR codes are designed to store a tiny amount of data that can be used to browse to a link, sign-into WiFi, access payment information, download an app etc. Essentially QR codes are designed to make life easier but have a fundamental flaw; the code is not readable to the human eye (Security vs Usability). For years we’ve been encouraging people to identify phishing emails by looking for mistakes such as context, content, URLs, only for QR codes to spice it up.
Users can often find QR codes on login pages of websites. These are known as QRL (Quick Response Login codes). These sites will require you to be signed into their mobile app. From there, you can typically use a scan QR code function which will allow you to scan the QRL code on a webpage which will authenticate you and allow you access to your account.
QRL login pages will typically look like the following:
The attack I will be demonstrating is called QRLJacking / Quick Response Code Login Jacking and can allow for:
Easy access to an account (bypassing MFA)
Information disclosure (GPS disclosure, IMEI, SIM Card Information etc)
Callback Data Manipulation
The QR code on the sign-in pages of these websites are dynamic and will change every few minutes or on each refresh of a page. To successfully exploit this, we need to ensure the victim scans the code we see on our web browser. This is challenging as the code is ever changing and we have to find a way to present the code to the victim. Luckily, there’s a tool that fixes that problem.
What is EvilQR?
EvilQR was created by Kuba Gretzky. It is a spin-off of a QRLJacking attack that can allow attackers to successfully take over accounts by convincing users to scan a QRL code.
Kuba also created Evilginx which is a MITM tool that creates a reverse proxy and can allow the bypass of MFA. I did a blog post on Evilginx recently that can be found here: Evilginx - Bypassing Multi-Factor Authentication
EvilQR works for a handful of sites currently. It will also create a relevant phishing page for the site to help it look more authentic.
Supported sites:
https://discord.com/login
https://web.telegram.org/k/
https://whatsapp.com
https://store.steampowered.com/login/
https://accounts.binance.com/en/login
https://www.tiktok.com/login
How it works:
The attacker opens the official website with the QRL code on within their web browser to generate the sign-in QR code.
Using the Evil QR browser extension, the attacker is able to extract the sign-in QRL code from the login page and upload it to the Evil QR server, where the phishing page is hosted.
The phishing page, hosted by the attacker, dynamically displays the most recent sign-in QR code controlled by the attacker.
Once the target successfully scans the QR code, the attacker takes over the phished account.
In our example of Discord, the victim will browse to a webpage which will look like the following:
How to defend against QRLJacking:
There are SIX key ways to help defend and mitigate against QRL Jacking. The best mitigation is prevention and not scanning a QR code to begin with.
DON’T SCAN QR CODES
If possible, refrain from scanning QR codes.
Use a trusted QR Scanner
Some scanners provide additional security and will scan any links including redirects to ensure they’re safe. QRL codes probably won’t be picked up as the content is technically safe but it may help provide some additional information. They often provide audit logs of previous scans which can help audibility and accountability.
Session Confirmation
Implementing a confirmation message/notification displaying characteristic information about the session made by the client/server.
IP Restrictions
Restricting any authentication process on different networks (WANs) will minimize the attack window.
Location-based Restrictions
Restricting any authentication process based on different locations will minimize the attack window.
Sound-based Authentication
One of the techniques to mitigate this kind of attack [And maintain the same usability level as to not require any additional interaction from the user other than scanning the QR is to add sound-based authentication step to the process , we have seen this kind of technology where it is possible to generate unique data and convert it to audio that can be recognized back into its original form [SlickLogin and Sound-Proof] so it is possible to include this technology in the process.
How to setup EvilQR? (QRLJacking)
Prerequisites
VPS with public facing IP
Windows box with Chrome INSTALLED
How to setup EvilQR?
Step 1 - Purchase a VPS
I would recommend purchasing a server via https://www.hetzner.com. They’re cheap and their servers are quick to setup.
There are no official requirements for EvilQR but I am using the following:
Step 2 - Setup the firewall
The firewall configuration is pretty simple. I am only focusing on inbound and don’t really care about outbound but if this is staying in a live enviroment or used for any serious purposes, please ensure that any outbound ports are closed if not needed.
Inbound ports are simple:
TCP 22 - SSH port for remote configuration (restrict this to IP)
TCP 35000 - HTTP Server (Can be changed to your preference)
Step 3 - Installing GO (At least version v1.20)
wget https://go.dev/dl/go1.20.6.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.20.6.linux-amd64.tar.gz
If you have an older version of go installed run sudo rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.6.linux-amd64.tar.gz
sudo nano /etc/profile
Add export PATH=$PATH:/usr/local/go/bin to the bottom
Verify that you've installed Go by opening a command prompt and typing the following command:
go version
If nothing is returned, you will likely need to logout and back in.
Step 4 - Downloading EvilQR
sudo apt install git
git clone https://github.com/kgretzky/evilqr.git
EvilQR users some parameters that are hard-coded into the extension and server source code. These will need to be changed before we build and deploy the tool kit. The four default parameters are the following:
There are three (3) areas this information needs to be changed:
server/core/config.go:
const API_TOKEN = "00000000-0000-0000-0000-000000000000"
const BIND_ADDRESS = "127.0.0.1:35000"
server/templates/index.html:
const API_URL = "http://127.0.0.1:35000";
const QRCODE_ID = "11111111-1111-1111-1111-111111111111";
extension/background.js:
const API_TOKEN = "00000000-0000-0000-0000-000000000000";
const API_URL = "http://127.0.0.1:35000";
const QRCODE_ID = "11111111-1111-1111-1111-111111111111";
Step 5 - Modifying the parameters
I would recommend copying the values above into a text editor and changing them so you can copy and paste the identicle values when required. If the values do not match up, the EvilQR extension and EvilQR Server will not be able to talk to each other and will be unable to upload and display the QR code.
sudo nano /root/evilqr/server/core/config.go
sudo nano /root/evilqr/server/templates/index.html
Now we need to edit the Extension config. I did this on my windows box. Download the extension from the github extension folder, unzip and edit the background file in notepad:
Step 6 - Setting up the web extension
MAKE SURE YOU EDITED THE BACKGROUND FILE AND ADDED YOUR API-TOKEN AND API-URL
Enter chrome://extensions in the URL of Chrome
Then enable ‘Developer mode’
Once enabled, click ‘Load Unpacked’ and ensure ‘Extension’ is highlighted and click ‘Select Folder’
Your chrome should now display the following:
Don’t forget to pin it.
Remember, EvilQR will only currently work on the following:
https://discord.com/login
https://web.telegram.org/k/
https://whatsapp.com
https://store.steampowered.com/login/
https://accounts.binance.com/en/login
https://www.tiktok.com/login
The extension icon will change depending if you’re on one of these login pages:
Good:
Bad:
Step 7 - Setting up the server
On step 4, we used git clone to download the EvilQR repository. Make sure you have configured config.go and index.html with the appropriate parameters before continuing.
We now want to change directory (cd) to the /evilqr/server
chmod 700 build.sh
./buildsh
This will create a new folder called ‘build’ with a binary called evilqr-serverr
FOLLOW THIS STEP OR IT WON’T WORK:
change directory to evilqr and then run the following:
./server/build/evilqr-server -d ./server/templates/
For some reason, trying to run evilqr-server via any other method and from any other directory did not work for me. I had to be in the /evilqr/ directory and run the above command.
You should now be able to browse to your external IP on your listener port (35000 by default) http://externalip:35000
If you browse to the externalip:listener port, you should see the following on your linux box. If you have the extension open on a login page, you shoud also see the API communicating to the server.
On the left is my Windows 10 VM with the EvilQR extension that is uploaded the QRL token to my VPS on the right. The QR codes are identical.
EvilQR is smart enough to update the .html for the relevant app. For Discord, it will display the typicaly blue/purple-ish background with some click bait information “join server”.
For other apps, it will also match similar criteria (TikTok will have a white background with red/pink buttons etc)
If the victim opens the mobile app and scans the code, they will be presented with the following:
Now, a warning message is a fantastic idea by Discord to encourage good security practices but unfortunately, many users don’t read warnings. On top of this, social engineering attacks can be designed to ensure the victim feels safe and confident that the QR code is safe. Context and reassurance is everything when performing social engineering.
When the victim clicks ‘Login’ they will then be presented with the following:
As the victim authenticated with the QR code on the attackers web browser, they have now authenticated their session and the attacker is now in!
Conclusion
QR codes are designed for usability, not security. They are designed to be convenient at the cost of certain security features. Security vs Usability is always an ever lasting battle, as something becomes more usable, it becomes less secure. As something becomes more secure, it becomes less useable.
With the right precautions, QR codes can pose less risk but sometimes, prevention and education is the best mitigation. EvilQR is not going to pose a great risk currently but there is opportunity with the right social engineering, an account compromise is entirely possible. Phishing using techniques like Evilginx poses a sufficiently greater risk to organisations and end users.
I will not be surprised to discover an attack performed using EvilQR. QRLjacking has been a thing for years and it’s a relatively rare occurrence in the wild. That being said, malicious QR codes are far more common and can lead to several other attacks.
References:
https://breakdev.org/evilqr-phishing/
https://owasp.org/www-community/attacks/Qrljacking
https://seekurity.com/blog/2016/11/04/admin/phishing-analysis/qrljacking-your-qr-based-session-belongs-to-us