October 31, 2026
The Untrusted Certificate Attack: Breaking HTTPS on a Company Firewall
An Untrusted Certificate Can Still Get You Breached
By 0xMarik
5 min read
An Untrusted Certificate Can Still Get You Breached
We're told the padlock means we're safe โ but what it actually confirms is that we're talking to the right entity, the one whose name is on the certificate. HTTPS is encrypted, so whatever we send is only readable by us and whoever holds that certificate.
But encryption only protects a connection if you're actually connected to the right server. All it takes to break that is one untrusted certificate the user clicks past โ and the data in transit is still technically encrypted the whole time โ it's just encrypted to an attacker instead of the real server. The browser won't show a padlock for a connection like that โ not before the warning, and not after the user clicks past it either. It keeps marking the page as not secure for the rest of that session; clicking through only stops it from blocking the page, it doesn't bring the padlock back.
In this lab, I position an attacker machine between a victim and a company firewall, exploit exactly that untrusted-certificate warning, and intercept a login to the firewall's own admin dashboard โ credentials and all.
This is a lab, not an invitation._ Every step below was carried out against machines I own, on an isolated, host-only VMware network with no route to the internet or any production system. ARP spoofing and traffic interception against systems you don't own or don't have explicit written authorization to test are illegal in most jurisdictions, Morocco included. Build this to learn the mechanism and the defenses โ not to point it at anything else._
How HTTPS Is Supposed to Work
During a TLS handshake, the server presents its certificate to the client. The client checks whether it's signed by a trusted Certificate Authority, that it hasn't expired, and that its hostname matches the site being visited. If all three check out, the connection proceeds and data flows encrypted between the two parties.
The whole system rests on that first check โ trust. The client isn't verifying the server directly; it's trusting that a CA already did. Break that chain of trust, and the protections built on top of it stop mattering.
The Lab Setup
To simulate a real company environment, the lab uses three machines:
- Victim โ a Windows machine, representing an employee
- Attacker โ Kali Linux
- Server โ a FortiGate firewall, specifically its web login portal
All three sit on an isolated, host-only VMware network with no bridge to any other network. The first step is just reconnaissance โ confirming each machine's IP address on that segment.
Step 1: Positioning the Attacker โ ARP Spoofing
To intercept traffic between the victim and the server, the attacker first needs to sit between them. ARP spoofing poisons both machines' ARP tables: the victim is told the attacker's MAC address belongs to the server, and the server is told the attacker's MAC address belongs to the victim.
sudo ettercap -T -q -i eth0 -M arp:remote /192.168.1.101// /192.168.1.100//sudo ettercap -T -q -i eth0 -M arp:remote /192.168.1.101// /192.168.1.100//-T -qโ text UI, quiet output-i eth0โ the interface to attack from-M arp:remoteโ launch ARP poisoning, withremoteenabling interception of traffic routed through a gateway- The two
/ip//arguments are the targets being poisoned against each other
Step 2: Letting Traffic Flow โ IP Forwarding
ARP spoofing alone breaks the connection rather than intercepting it โ by default, the kernel drops packets addressed to an IP that isn't its own, so without this next step the victim simply loses connectivity.
echo 1 > /proc/sys/net/ipv4/ip_forwardecho 1 > /proc/sys/net/ipv4/ip_forwardThis tells the kernel to forward packets it receives that aren't addressed to itself, routing them to their real destination. The victim and server keep talking normally โ every packet now just passes through the attacker first.
Step 3: Terminating TLS โ mitmweb
Forwarding alone would just pass the victim's traffic straight through, unmodified โ still encrypted, so unreadable. To actually read HTTPS traffic, the attacker needs something that terminates TLS with the victim and opens a separate connection to the real server, relaying data between the two.
mitmweb --mode transparent --showhost --ssl-insecuremitmweb --mode transparent --showhost --ssl-insecure--mode transparentโ intercepts redirected traffic with no proxy configuration needed on the victim's side--showhostโ shows the original Host header rather than the proxy's own address--ssl-insecureโ skips verifying the real server's certificate on the upstream connection, needed here because the FortiGate's login portal ships with a self-signed certificate by default
Step 4: Redirecting the Traffic
IP forwarding alone sends traffic straight past the attacker to the real server. Before that happens, port 443 traffic needs to be redirected into mitmweb's listening port, so it stops at the proxy first.
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080With this rule in place, TCP traffic arriving on port 443 is redirected to port 8080, where mitmweb is listening, before the kernel ever considers forwarding it onward.
The Attack, From the Victim's Side
With everything running, the victim opens a browser and navigates to the firewall's login IP. Because mitmweb is presenting its own certificate instead of the FortiGate's โ and that certificate isn't trusted by the victim's machine โ the browser shows a warning page: untrusted certificate, possible wrong entity.
A user with no reason to be suspicious clicks through. From there, the login page loads normally, credentials are entered, and the dashboard opens โ all while the attacker has already captured the credentials passing through the proxy, and can now log into the same firewall dashboard directly. A single login, on a connection the victim believed was secure, is enough to compromise the device meant to protect everything behind it.
Red Flags a User Could Have Caught
None of these are foolproof, and most require more attention than a routine login usually gets โ but they're worth knowing:
- The certificate's issuer. A proxy's generated certificate can show telltale details, like "mitmproxy" as the issuing authority โ though an attacker who clones the real certificate's displayed fields can make this far less obvious at a glance. It won't fix the underlying trust failure, just the field a human might read.
- A warning on a site you've visited safely before. Some browsers, Firefox notably, remember a previously accepted self-signed certificate's public key; a warning reappearing on a site that didn't show one before can mean the certificate changed.
- A different error than usual. If a site has always shown one kind of error โ an expired cert, a hostname mismatch โ and suddenly shows "untrusted certificate" instead, that's a meaningfully different failure worth a second look.
What Actually Prevents This
Red flags rely on a human noticing something they probably won't. Two real fixes remove the decision from the user entirely:
- Deploy a proper internal CA. When a company's own certificate authority is installed and trusted on every host, every legitimate internal certificate verifies cleanly โ and anything else is immediately flagged as untrusted, no judgment call required.
- Enable HSTS. HSTS has the server tell the browser, "only ever connect to me securely, for the next however many days." Once a browser holds that instruction for a domain, it won't just block plain HTTP โ it refuses any HTTPS connection with certificate errors outright, no "proceed anyway" option at all. The warning dialog the victim clicked through in this lab simply never appears.
One Mistake We Made Too
The same shortcut that made this attack possible is a vulnerability in its own right. --ssl-insecure told mitmweb to ignore the real server's certificate entirely โ so if a second attacker were sitting between the lab's Kali machine and the real FortiGate, mitmweb would trust that attacker's certificate just as blindly, and we'd become the victim in someone else's man-in-the-middle without knowing it.
The better practice is to download and verify the real server's certificate once, then pin mitmweb to trust only that specific certificate:
mitmweb --mode transparent --showhost --set ssl_verify_upstream_trusted_ca=/path/to/downloaded_cert.pemmitmweb --mode transparent --showhost --set ssl_verify_upstream_trusted_ca=/path/to/downloaded_cert.pemEven this isn't airtight โ if an attacker is already in the middle at the moment that certificate is downloaded, you'd be verifying their certificate instead of the real one. It's the same trust-on-first-use weakness that shows up anywhere a credential is accepted with no independent way to confirm it. But it's a meaningfully smaller attack surface than ignoring certificate errors by default โ and a good reminder that even the tools built to demonstrate an attack can carry the same flaw they're demonstrating.
Visit the full video at : https://youtu.be/7FYNN40fLxg