Fedezze fel a legfrissebb kiberbiztonsági híreket

Blog / Az Evilginx 3 használata egyéni tanúsítványokkal
Az Evilginx 3 egyéni TLS-tanúsítványokkal való használatáról szóló cikk borítóképe.

Az Evilginx 3 használata egyéni tanúsítványokkal

Bence Szabo
2025. március 31.
redteamphishingevilginx

Bevezetés

Az Evilginx hasznos eszköz az engedélyezett adathalászat-szimulációkhoz, mert könnyen beállítható, és általában különösebb módosítás nélkül működik. Közösségi és professzionális változata is van. A közösségi kiadás BSD-3 licencű, és sajnos két olyan funkció hiányzik belőle, amely kevésbé feltűnő működést biztosíthatna.

Ez a két funkció:

  1. Wildcard vagy egyéni TLS-tanúsítványok használata.
  2. Az X-Evilginx HTTP-fejlécek elküldésének elhagyása.

A második szempont O365-szimulációknál kevésbé számít; úgy gondolom, ez a legtöbb etikus adathalászat-felmérés célpontja. Kétlem, hogy a blue team hozzáférne ezekhez a HTTP-kérésfejlécekhez, amikor egyik AD-felhasználója bejelentkezik az OWA-ba (Outlook webalkalmazás). Erre röviden szintén kitérek, de a cikk fő témája az egyéni tanúsítványok támogatásának hiánya.

Miért fontos ez?

A rövid válasz: nem szeretnénk nyilvánosan felfedni a szimulációban használt aldomaint, ezért wildcard tanúsítványra van szükségünk.

Alapértelmezésben az Evilginxet névszerverként kell beállítani. Az 53-as porton figyel, és automatikusan létrehozza a megfelelő TXT-rekordokat. A hitelesítési kihívás folyamata:

  • Tanúsítványt kérünk a login.microsoft.fake.com címhez a Let’s Encrypttől.
  • A Let’s Encryptnek ellenőriznie kell, hogy valóban a login.fake.com kéri a tanúsítványt, ezért véletlenszerű karakterláncot küld.
  • Az Evilginx ezt a karakterláncot _acme-challenge nevű DNS TXT-rekordként állítja be.
  • Várunk a DNS-változás érvényesülésére.
  • Jelezzük a Let’s Encryptnek, hogy ellenőrizheti a karakterláncot.
  • A Let’s Encrypt megtalálja a helyes értéket a TXT-rekordban.
  • A tanúsítvány kiadásának folyamata befejeződik.

Ezzel a folyamattal felfedtük, hogy a login.fake.com címhez kellett tanúsítvány, hiszen legalább a létrehozás idejére megjelent a DNS-rekordjainkban.

Ehelyett inkább *.fake.com Common Name értékű wildcard tanúsítványt szeretnénk. Ezt az Evilginx „közösségi változata nem támogatja” — a professzionális kiadást nem használtam; itt lazán idézem Kuba Gretzkyt.

Több lehetőségünk is van.

Nginx + Evilginx

Egyéni TLS-tanúsítvány használatához az Evilginx reverse proxy, például Nginx — vagy igény szerint Apache2 — mögé helyezhető. Ennek lehetnek buktatói; szeretnék némi időt megspórolni az olvasónak.

A megoldás buktatói:

  • Tapasztalatom szerint az Evilginx más porton nem hajlandó működni. Olyan környezetben kell futtatni, ahol elérhető a 443-as port: másik gépen, virtuális gépen vagy Docker-konténerben.
  • A másik gép hostnevei számítanak, mert az Evilginx az Nginxhez és az Apache-hoz hasonlóan saját virtuális hostokat hoz létre.
  • Az Nginx portja eltérhet a 443-tól. Olyan konfigurációt mutatok, amely ezt is figyelembe veszi.

Ebben a példában Docker-konténerbe helyezem az Evilginxet, majd Nginx reverse proxy mögött futtatom. Az alapértelmezett „snakeoil” tanúsítványokat használom, amelyeket természetesen cserélni kell. A fake.com domaint is használom — ez nem az enyém. Ehhez néhány bejegyzést kellett hozzáadnom a hosts fájlhoz. A példában O365-szimulációhoz állítom be, egy GitHub-tárhelyen talált működő phishlettel.

Let’s Encrypt wildcard tanúsítvány beszerzése

Ezt itt nem részletezem, de certbottal és DNS-kihívással megoldható. Néhány percet vehet igénybe.

Az Evilginx klónozása és fordítása

E lépésekhez telepített git, go és make szükséges.

mkdir ~/opt
cd ~/opt
git clone https://github.com/kgretzky/evilginx2.git
cd evilginx2
make

Alternatívaként az én forkom is használható. A cikk írásakor naprakész volt az Evilginx fő ágához képest, és Dockerhez kapcsolódó .sh fájlokat, valamint néhány további kapcsolót adtam hozzá.

A tárhelyem:

https://github.com/hacker-szabo/evilginx2

A futtatható fájl a build mappába kerül. Ellenőrizzük, hogy a 443-as port szabad-e! Az alábbi paranccsal kipróbálható:

./build/evilginx -p phishlets -developer

A -p paraméter adja meg a phishletek mappáját. A tárhely alapértelmezésben egy exampe.yaml fájlt tartalmaz.

A -developer kapcsoló kikapcsolja az aldomainenkénti automatikus tanúsítványkérelmeket — ezt szeretnénk elkerülni —, és helyettük önaláírt tanúsítványokat használ. Ebben a példában a Docker-konténeren belüli önaláírt tanúsítvány megfelelő.

Phishletek beszerzése

Az alábbi tárhely O365-phishletjét használtam:

https://github.com/An0nUD4Y/Evilginx2-Phishlets/blob/master/o365(April-latest).yaml

A fájlt a phishlets mappába kell helyezni.

Docker-konténer készítése

Ha a hivatalos tárhely helyett az enyémet klónoztuk, több hozzáadott fájlt is találunk.

Az első a Dockerfile:

# Use Ubuntu 22.04 as the base image
FROM ubuntu:22.04

# Install only necessary dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# Create app directory
RUN mkdir -p /app

# Copy the Evilginx build to the /app/evilginx directory
COPY build/evilginx /app/evilginx

# Expose port 443
EXPOSE 443

# Define the mount points for phishlets and config folders
VOLUME ["/phishlets", "/root/.evilginx"]

# Define the command to run Evilginx with mounted folders
CMD ["/app/evilginx", "-p", "/phishlets", "-c", "/root/.evilginx", "-developer"]

Ebben a Dockerfile-ban a Go-program futtatható állományát az /app/evilginx helyre másolom.

Az /phishlets csatolási ponthoz a phishlets mappát kapcsoljuk, amelyet a -p paraméter ad meg. Végül a /root/.evilginx mappát is csatoljuk: az Evilginx alapértelmezésben itt tárolja a konfigurációját. Ez biztosítja a beállítások megmaradását; nélküle minden konténerindításkor újra kellene konfigurálni az eszközt.

Az image elkészítéséhez használható a tárhelyem build_image.sh fájlja vagy az alábbi parancs:

docker build -t evilginx-image .

Ezzel létrejött az evilginx-image nevű Docker-image, amelyből konténerek indíthatók.

Egyetlen konténert állítok be, és a 192.168.100.10 statikus IP-címet szeretném használni. Ehhez Docker-hálózatot kell konfigurálni a tárhelyem create_network.sh fájljával. A tartalma:

docker network create --subnet=192.168.100.0/24 evilginx-network

Ezzel létrehoztuk az evilginx-network nevű alhálózatot a konténereink számára.

Végül létrehozhatjuk és elindíthatjuk a konténert a run_docker.sh fájllal. Tartalma:

# Stop and remove any existing container with the name evilginx-container
docker stop evilginx-container 2>/dev/null || true
docker rm evilginx-container 2>/dev/null || true

# Run the container interactively with a bash shell
docker run -it \
  --network evilginx-network \
  --ip 192.168.100.10 \
  -v $(pwd)/phishlets:/phishlets \
  -v ~/.evilginx:/root/.evilginx \
  --name evilginx-container \
  evilginx-image \
  /bin/bash

Ez leállítja és eltávolítja az esetleg már létező evilginx-container nevű Docker-konténert, majd létrehoz egy újat.

A konténer IP-címe a --ip argumentumnak megfelelően 192.168.100.10.

Siker esetén interaktív Bash-parancssort kapunk a konténerben.

Az Evilginx indítása:

/app/evilginx -p /phishlets -developer -c /root/.evilginx

Az Evilginx domainek beállítása

Ahogyan említettem, az Evilginx a 443-as porton figyel, és virtuális hostokat hoz létre a phishletek számára. A helyes beállítás elengedhetetlen a működéshez.

A fake.com domaint szeretném használni, és a hivatkozott phishlet további három aldomaint használna:

  • login.fake.com
  • www.fake.com
  • aadcdn.fake.com

Először indítsuk el az Evilginxet a konténerben, és állítsuk be a fő domaint fake.com értékre:

config domain fake.com

Állítsuk be az IP-címet, amely a Docker-konténer címe:

config ipv4 192.168.100.10

Ezután engedélyezzük az o365 phishletet, és adjuk meg hozzá ugyanazt a hostnevet, a fake.com domaint:

phishlets enable o365
phishlets hostname o365 fake.com

Megjegyzés: más érték, például very.fake.com is megadható, de akkor a meglévő *.fake.com helyett *.very.fake.com tanúsítványra lesz szükség.

Ha helyi gépen tesztelünk, az aldomaineket a hosts fájlba is fel kell venni. Az Evilginxnek van erre parancsa, de a kimenete ebben a helyzetben nem a szükséges címet adja:

phishlets get-hosts o365 

192.168.100.10 login.microsoft.fake.com
192.168.100.10 www.microsoft.fake.com
192.168.100.10 aadcdn.microsoft.fake.com

Az IP-címet 127.0.0.1-re kell módosítani, és a bejegyzéseket az Nginxet futtató gép hosts fájljába kell helyezni.

127.0.0.1 login.microsoft.fake.com
127.0.0.1 www.microsoft.fake.com
127.0.0.1 aadcdn.microsoft.fake.com

Az Nginx beállítása

Az Nginxet ugyanarra a gépre telepítettem, amelyen a Docker-konténer futott.

Röviden, minden domainnél ugyanazokat a lépéseket kell elvégezni:

  1. Virtuális host beállítása a 443-as porton.
  2. SSL konfigurálása.
  3. Reverse proxy beállítása a proxy_pass és egy IP-cím használatával.
  4. A Host fejléc megfelelő értékre módosítása.
  5. Opcionálisan a 80-as port átirányítása 30X HTTP-válasszal.
server {
    listen 80;
    server_name login.microsoft.fake.com;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name login.microsoft.fake.com;

    # SSL Configuration (Snakeoil certificates)
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

    # Proxy and Forwarded Headers
    location / {
	proxy_pass https://192.168.100.10:443;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
		
		proxy_set_header Host login.microsoft.fake.com;
		proxy_ssl_server_name on;
		proxy_ssl_name login.microsoft.fake.com;
		proxy_ssl_verify off;
    }

    # Custom 404 error page
    error_page 404 /custom_404.html;
    location = /custom_404.html {
        internal;
        return 404 "Sorry, the page you are looking for does not exist.";
    }
}

Ismételjük meg ugyanezt a másik két domainnel:

  1. www.microsoft.fake.com
  2. aadcdn.microsoft.fake.com

A további konfiguráció innen másolható:

server {
    listen 80;
    server_name www.microsoft.fake.com;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name www.microsoft.fake.com;

    # SSL Configuration (Snakeoil certificates)
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

    # Proxy and Forwarded Headers
    location / {
	proxy_pass https://192.168.100.10:443;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header Host www.microsoft.fake.com;

	proxy_ssl_server_name on;
	proxy_ssl_name www.microsoft.fake.com;

	proxy_ssl_verify off;
    }

    # Custom 404 error page
    error_page 404 /custom_404.html;
    location = /custom_404.html {
        internal;
        return 404 "Sorry, the page you are looking for does not exist.";
    }
}

server {
    listen 80;
    server_name aadcdn.microsoft.fake.com;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name aadcdn.microsoft.fake.com;

    # SSL Configuration (Snakeoil certificates)
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

    # Proxy and Forwarded Headers
    location / {
	proxy_pass https://192.168.100.10:443;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header Host aadcdn.microsoft.fake.com;

	proxy_ssl_server_name on;
	proxy_ssl_name aadcdn.microsoft.fake.com;

	proxy_ssl_verify off;
    }

    # Custom 404 error page
    error_page 404 /custom_404.html;
    location = /custom_404.html {
        internal;
        return 404 "Sorry, the page you are looking for does not exist.";
    }
}

Egy gyakorlott Nginx-felhasználó — velem ellentétben — változókkal is megoldhatná ezt. Ennek azonban lehet egy további buktatója: ha az Nginx nem a 443-as porton fut, a Host a portszámot is tartalmazhatja. Az Evilginx ilyen Host értékekre nem válaszol.

curl -vvv http://localhost:9090
*   Trying 127.0.0.1:9090...
* Connected to localhost (127.0.0.1) port 9090 (#0)
> GET / HTTP/1.1
> Host: localhost:9090

Az Nginx-konfiguráció hibái az alábbi paranccsal ellenőrizhetők:

nginx -t

Ha nincs hiba, az Nginx újratölthető vagy újraindítható.

sudo service nginx restart

Evilginx wildcard tanúsítványokkal

Ez a második, véleményem szerint sokkal egyszerűbb megoldás. Végül ezt választottam, és egy olcsó Amazon EC2-példányt szántam rá.

Ahogyan korábban írtam, a hivatalos Evilginx2-tárhely közösségi változata ezt a funkciót nem támogatja. Ezért készítettem egy forkot, és két új parancssori kapcsolót adtam hozzá:

  • -cert: a tanúsítványfájl PEM-formátumban.
  • -key: a privát kulcs fájlja PEM-formátumban.

A tanúsítványok használatához a -developer kapcsoló is szükséges, mert az önaláírt tanúsítványokat használó kódrészt módosítottam. Ez csak e kapcsoló megadásakor fut le.

A tárhelyem az alábbi címen található:

https://github.com/hacker-szabo/evilginx2

A programot a make paranccsal kell lefordítani:

git clone https://github.com/hacker-szabo/evilginx2.git
cd evilginx2
make

Fordítás után a további argumentumokkal futtatható:

./evilginx -developer -cert /path/to/cert.pem -key /path/to/key.pem -p phishlets/

Természetesen tanúsítványokat is be kell szerezni, például a Let’s Encrypttől.

Ennyi! Átirányítók is használhatók, így a szimuláció résztvevőinek kialakított landing oldalhoz nincs feltétlenül szükség még egy Nginx-szerverre, hacsak nem szeretnénk összetettebb szűrőket megvalósítani.

Ha érdekli, mit módosítottam:

  • Megkerestem az önaláírt tanúsítványokat létrehozó és visszaadó függvényt a certdb.go fájlban.
  • Lemásoltam és módosítottam, a Copilot és a ChatGPT meglehetősen jelentős segítségével.
  • Megkerestem, hol hívják meg.
  • Hozzáadtam a két kapcsolót a main.go fájlhoz, és továbbadtam az értéküket a megfelelő függvénynek.
  • Mindkét érték megadásakor a program ezeket használja új tanúsítvány generálása helyett.

Az X-Evilginx fejlécek eltávolítása

Ezt a problémát a cikk elején említettem. Az Evilginx közösségi változata további fejléceket küld, így a Microsoft könnyen elutasíthatná az Evilginxen közvetítőként áthaladó kéréseket. A felmérésem során ezt nem ellenőrizte, ezért a hivatalos tárhellyel is működött.

A kód obfuszkált, de találtam egy javítást. Elnézést kérek, hogy nem nevezem meg a szerzőjét; nem találom a forrást, de a javítást hozzáadtam a tárhelyemhez.

Az alábbi sort kell megkeresni és kikommentelni:

req.Header.Set(p.getHomeDir(), o_host)

Igen, a p.getHomeDir() a fejléc nevét adja vissza.

Fedezze fel a legfrissebb kiberbiztonsági híreket

Maradjon egy lépéssel a kiberveszélyek előtt a Naunet szakértői blogbejegyzéseivel! Ismerje meg a legújabb védelmi trendeket, technikákat és technológiákat, hogy növelhesse vállalkozása biztonságát. Csatlakozzon közösségünkhöz, és fejlődjön minden bejegyzéssel!