There is no such thing as a "fully qualified" certificate. That term simply does not exist in the vocabulary surrounding certificates and PKI. I believe you mean "trusted" certificates - which would be a certificate, which has been signed by a trusted certificate authority (or which can establish a chain of trust to such an authority).
The opposite of that would be a self-signed certificate, or a certificate signed by an untrusted root certificate.
I was then told that MitM only happens when it's an unqualified TLS cert.
That is not exactly true. Man-in-the-Middle attacks can occur regardless of whether a certificate is trusted by the host or not. Where it differs is in what the client sees during a Man-in-the-Middle attack.
The attacker will not have a certificate, which is signed by trusted certificate authority, which relates to the server in question. As a result, the connection will always display an error, that the certificate in question is untrusted.
If the original certificate is self-signed as well and has not been manually added to the trust store (more on this later), then users will expect to get a certificate error, whenever they connect to the application. Thus, they will not realize that their connection is being highjacked.
If the original certificate is signed by a trusted certificate authority (either public or internal), then users would be faced with an unfamiliar error message. This should cause users to suspect that something is wrong and cause them to not blindly click on "Click here to connect anyways and lose all your data to hackers".
The important distinction is not that a trusted certificate will prevent a Man-in-the-Middle attack, but that it will make it detectable. And depending on the configuration of the client, make it impossible for the user to connect to an untrusted endpoint.
can't I also create an unqualified and self-signed certificate with the same certificate SubjectName and then gain access?
I presume that this relates to client certificates, not server certificates. And depending on the setup of the server, this may be possible. However, if it is possible, then the server has a critical configuration vulnerability.
So first, allow me to explain how it should work. First, a certificate authority is created and the certificate of that authority is copied to the server. Second, legitimate users are given certificates, signed by that certificate authority. Finally, the server is configured to only give access to users, which have certificates signed by that specific certificate authority.
An attacker could try to create a self-signed certificate and "impersonate" the certificate authority, by using - as you said - the same data the certificate authority uses (same name, etc.). However, the private key of the certificate authority is unknown to the attacker, so they cannot create an identical copy. If the attacker would now attempt to issue a certificate for themselves using their bogus certificate authority, the validation of that certificate on the server would fail, as the public key mismatches.
This is how it should be, and how it likely is in the vast majority of scenarios. However, there are systems, which use client certificates completely wrong. They merely check for the fields in the certificate, and not for the signatures. In this case, it becomes trivial to forge a certificate, which impersonates arbitrary users. And while that may seem like a contrived example, I have seen this during penetration tests and red teaming assessments in multiple companies. Unfortunately, the people, who build these systems, are often not very familiar with cryptography and so tend to use cryptographic tools wrong.
Is this considered Man-in-the-Middle?
No, it's not. You are not intercepting an existing connection and act as a "Man-in-the-Middle" between client and server. Rather, you are forging an "access token" in the broadest sense and use it to gain unauthorized access.
I would consider such an attack to be an "authentication bypass".
As I mentioned before, self-signed certificates can be secure, if they are explicitly trusted on an endpoint. So for example, I could create a self-signed certificate for a server called mediaserver.local
and explicitly add that certificate to the trust store of my computer.
This certificate would then indeed be trusted and I would not receive an error message, if I attempted to connect to this server. In the eyes of my computer, the certificate is issued by a trusted party.
Regarding non-FQDNs
This depends how your client is set up. For example, a DNS server can interpret a query to exchange
as meaning exchange.company.local
. In such a case, a certificate merely for exchange
would be valid. In many cases, if such a behavior is desired, it makes sense to set exchange.company.local
as the common name, and exchange
as a subject alternative name (SAN).
This does not fundamentally change anything regarding the security of the certificate. Even if an attacker could cause the local DNS to resolve exchange
to a machine controlled by the attacker, the attacker still would not be able to create a certificate, which would be trusted by the client.
In short: Using non-fully qualified domain names does not make the process less secure.
To summarize
- There is no such thing as a "qualified" or "unqualified" certificate.
- A certificate can either be "trusted" or "untrusted".
- Man-in-the-Middle attacks can be performed regardless of whether a certificate is originally trusted.
- Trust exists to be able to detect such attacks.
- A server must verify the signature of a certificate, not just the contents of the fields.