FDEU-CVE-2026-0a18

Summary

Abuse of shared hosting to steal a subdomain's Lets Encrypt private key.

Tech details

Serveriai.lt shared hosting can be abused to generate an arbitrary Lets Encrypt key pair for any parked neighbour subdomain.

About serveriai.lt shared hosting

Serveriai.lt offers cheap shared LAMP hosting. Every customer gets a linux user on a CentOS server with Apache and php installed (but no ssh access). Users are isolated, have their own home dir, can put php files there and get a hostname-based web service. Php has some dangerous functions disabled to avoid users escaping their home dir and accessing other customers' files.

A decade ago an SSL certificate was a paid feature, where you had to buy a certificate from a commercial thirdparty provider. But since the Lets Encrypt era, serveriai.lt allows you to generate a cert and use it for free.

The hosting also offers a web-based administration tool DirectAdmin that allows doing a lot of useful actions using a browser. Including SSL cert configuration. This is the feature we are going to exploit.

About GyvaFoto

Gyva Foto (gyvafoto.lt) is just a random shared hosting user that we selected for the PoC. There was no harm, no destructive actions and no personal data leaked during our testing. We are not affiliated with them and they probably don't even know we exist. However we would like to sincerely thank them for being part of the PoC.

Lets Encrypt domain verification

When you generate a free cert, Lets Encrypt needs to verify that you really own the domain. Proof of ownership may be done using various methods. We are going to target the HTTP method: your domain name must point to an IP that is reachable on TCP port 80 and where you can run code. In a nutshell, Lets Encrypt will resolve the requested domain name, generate some cryptographical stuff, make a few requests to the IP and validate that the one who requested the cert in fact controls the machine and can run a web service on port 80.

For example, if you can ssh as root into the 1.1.1.1 machine and run arbitrary code there that is able to listen on port 80 - you can issue a Lets Encrypt cert for https://one.one.one.one/, no problem. But in fact most of us cannot ssh as root there, therefore nobody can issue a rogue Cloudflare DNS cert. Sad.

But things are different with shared hosting. There all the parked domains resolve to the same IP. If you have an account on the same server as gyvafoto.lt, you can actually prove that you own that requested cert domain, because Lets Encrypt will connect to a host that you control.

vilkas.serveriai.lt -> 79.98.24.15
full-disclosure.eu -> 79.98.24.15
gyvafoto.lt -> 79.98.24.15

How to abuse

The missing puzzle piece in this flow is DirectAdmin. In theory, it should not allow you to initiate a request for a neighbour's domain name. But in fact, it doesn't really know if you own the domain or not. The server will only check if the subdomain is already parked. All you need to do is:

  1. park a not-yet-parked subdomain of a victim (ex, poc.gyvafoto.lt)
  2. navigate to /CMD_SSL?domain=poc.gyvafoto.lt
  3. select Free & automatic certificate from Lets Encrypt
  4. let DirectAdmin initiate and validate the request
  5. copy the generated private key and the corresponding cert

Now having that cert you can do two main things:

PoC

The now-expired cert:

FDEU-CVE-2026-0a18-gyvafoto.crt

FDEU-CVE-2026-0a18-gyvafoto.jpg

Proof of the private key ownership:

FDEU-CVE-2026-0a18-gyvafoto.sig

openssl x509 -in FDEU-CVE-2026-0a18-gyvafoto.crt -pubkey -noout > FDEU-CVE-2026-0a18-gyvafoto.pub
echo pwned | openssl dgst -sha256 -verify FDEU-CVE-2026-0a18-gyvafoto.pub -signature FDEU-CVE-2026-0a18-gyvafoto.sig

How to fix

  1. do not allow parking subdomains that the current user does not own
  2. do not allow initiating Lets Encrypt for domains the current user does not own

Timeline

2026-06-15 - initial research
2026-06-18 - contacted serveriai.lt, no response
2026-07-08 - serveriai.lt came back, sent the report and PoC
2026-10-27 - deadline notification sent
2026-10-30 - full disclosure