AndrewNohawk
Security

Alternate DNS Names in Certificates

I know, its been forever since I posted, but I do have two things i’m working on (there are drafts, but they need to be finished) – Its just the effort to actually finishing. Its on Magstripe spoofing and using the RTLSDR -shrug-.

Anyway, a discussion started in #zacon based on a post I thought was interesting about SSL-enabled mail servers and how very very seldomly its actually used for mail: http://ritter.vg/blog-no_email_security.html. The gist of the story is that mail goes from your client via MTA to another MTA to be delivered and while you might have an SSL enabled session for your gmail interface its highly unlikely that the actual mail will be going over SSL the entire trip. In fact gmail’s SSL certs are for mx.gmail.com not aspmx.l.google.com!

But back to the Alternate DNS names. So one chap in chat ‘dru’ mentioned that he has a single cert for multiple domains, I wasn’t entirely sure this was possible as I have never seen it, however after looking a bit more closely at his SSL certificates on https://mail.sybaweb.com/ it appeared that all his other linked domains (technically DNS names) were actually in the certificate. This is a great way to find out other domains/dns names linked to your target domain.

Few minutes in PHP and I whipped up a little (but ugly) script to pull this out, check it out at https://andrewmohawk.com/SSLAssociated/

Alternate SSL Names for sybaweb.com

Alternate SSL Names for sybaweb.com

Code:

The script is trivial, but the code as always:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
	echo "<h2>Get Alternate Names for Certificate</h2>
		<form action='index.php'>
		<strong>HTTPS enabled site: https://</strong><input type='text' name='h'/><br/>
		<input type='submit' value='Lookup!'/><br/>
		</form>
		";
	if(isset($_GET["h"]))
	{
		echo "<pre>";
		set_time_limit(0); 
		ob_implicit_flush();
		$host = $_GET["h"];
		$context = stream_context_create(array(
		  'ssl' => array('capture_peer_cert' => TRUE)
		));
		echo "[+] Fetching SSL Cert...";
		@$html = file_get_contents('https://'.$host, NULL, $context);
		$opts = stream_context_get_options($context);
		echo "Done<br/>";
		echo "[+] Parsing SSL Cert...<br/>";
		if(isset($opts["ssl"]) && isset($opts['ssl']['peer_certificate']))
		{
			$ssl = openssl_x509_parse($opts['ssl']['peer_certificate']);
			if(isset($ssl["extensions"]))
			{
				if(isset($ssl["extensions"]["subjectAltName"]))
				{
					echo " [-] Found Alternate DNS names:<br/>";
					$altNamesTmp = $ssl["extensions"]["subjectAltName"];
					$altNames = explode(",",$altNamesTmp);
					$hostnames = array();
					$unknown = array();
					foreach($altNames as $a)
					{
						if(strpos($a,"DNS:") !== false)
						{
 
							$hostname = substr($a,strpos($a,"DNS:")+4);
 
							$hostnames[] = $hostname;
 
 
						}
						else
						{
							$unknown[] = $a;
						}
 
					}
					foreach(array_unique($hostnames) as $ud)
					{
						echo " [*] Found Alternate DNS Name: $ud <br/>";
					}
					foreach(array_unique($unknown) as $ud)
					{
						echo " [*] Unknown Entry: $ud <br/>";
					}
				}
			}
		}
		else
		{
			echo "[!] Could not parse certificate... https enabled?";
		}
	}

 

Leave a Reply

Your email address will not be published. Required fields are marked *