The Phish Report threats team have identified an organised threat actor (codenamed RedLungfish) who are targeting fintech customers with realtime phishing kits.
First observed in March 2023, RedLungfish have deployed phishing sites targeting a wide range of fintech customers from the point-of-sale solution Clover to the trading platform E-Trade:
Screenshots via urlscan.io |
Every phishing site deployed, no matter the brand, connects back to the same admin panel (at the time of writing, hosted on hunting-panel[.]cc
).
However, unlike Phishing as a Service kits, there are no license keys to identify individual sites, leading us to believe that these sites are all being operated by the same actors.
All RedLungfish phishing kits follow the same pattern:
rl-script.js
is inserted which communicates with the admin panel via websockets and controls the journey of the victim through the different screensThe rl
prefix is used throughout the kit from filenames to CSS classes (leading to our codename "RedLungfish").
The code in rl-script.js
loads a config file which controls where collected credentials are sent to as well as where victims are redirected after the phish is complete (or if they're "banned" manually or via an IP reputation check):
/* /rl-script/config.js */
export const backUrl = "https://api.hunting-panel.cc";
export const apiKey =
"<redacted>";
export const apiUrl = `https://api.ipdata.co?api-key=${apiKey}`;
export const project = `barclaycard`;
export const banLink = `https://identify1.business.barclaycard/login#gcpidvlogon`;
All RedLungfish phishing kits communicate with a single admin panel where the operators can see the credentials that victims have entered and send them to the next stage of the phishing flow.
The admin panel is password protected with a username and password which we've been unable to bypass.
However, because the admin panel is built with React as a single page application, we are able to see all the capabilities present in the source code. And, by intercepting requests to the server and returning our own mock data, we can see what the admin panel would look like in real use.
./hunting-panel/services
├── auth
│ ├── ifValidJwtFunc.js
│ ├── loginService.js
│ ├── logout.js
│ └── transformUserData.js
├── news
│ ├── deleteNews.js
│ ├── getAllNews.js
│ └── postNewNews.js
├── projects
│ ├── allowToProjectBtns.js
│ ├── createNewProject.js
│ ├── deleteProject.js
│ ├── getProjPossBtns.js
│ └── getProjects.js
├── sessions
│ ├── deleteSession.js
│ ├── getAllSessions.js
│ ├── getOpenedSession.js
│ ├── sendUserTakeLog.js
│ └── sendUserThrowLog.js
├── socket
│ └── socketIoService.js
└── users
├── allowUserProjects.js
├── changeUserActive.js
├── changeUserRole.js
├── createUser.js
├── deleteUser.js
└── getUsers.js
The RedLungfish admin panel support multiple users with varying permission levels. At creation time, each user is given one of the following roles:
The RedLungfish admin panel supports many simultaneous "projects" corresponding to the different brand being phished.
The project ID is specified by the project
value in the phishing kit's /rl-script/config.js
file.
Admins are able to see which workers are currently logged in and active and move them between working on different projcts.
The admin panel also has a basic "news" feature where admins can write messages which are displayed on the homepage to all workers.
Detection rule for phishing sites operated by RedLungfish:
title: redlungfish-kit
description: |
This site loads config files and assets used by the
RedLungfish threat actor
references:
- https://phish.report/blog/red-lungfish-hunting-panel
detection:
config:
requests|endswith: "/rl-script/config.js"
js:
requests|endswith: "/rl-script/rl-script.js"
css:
requests|endswith: "/rl-style/rl-style.css"
condition: 1 of them
Detection rule for the current version of the RedLungfish admin panel (version 1.13):
title: redlungfish-hunting-panel
description: RedLungfish admin panel
references:
- https://phish.report/blog/red-lungfish-hunting-panel
detection:
version1_13:
title: "Hunting panel"
requests|endswith|all:
- main.eff5ae4f.js
- main.6061ba32.css
condition: 1 of them