Wednesday, July 15, 2009

Makecert - by example

So, I have finally had a chance to start getting back to looking more closely at the makecert utility. Since I am a big fan of looking at binary, I will examine the basic structure of certificates created by makecert to try and get a better understanding of certificates in general, but, also, to learn how the utility works to create these files.

One thing I did to make life easy for myself was to add the SDK path to my path variable so I can just run it from cmd without having to renavigate to the appropriate directory every time. That path can be located at:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\


Next, I made a little directory on my Users directory:

C:\Users\will>md makecert


Then I started working in there:

C:\Users\will>cd makecert
C:\Users\will\makecert>


So, off we go. A quick start shows the basic options:

C:\Users\Will>makecert
Usage: MakeCert [ basicextended options] [outputCertificateFile]
Basic Options
-sk Subject's key container name; To be created if not present
-pe Mark generated private key as exportable
-ss Subject's certificate store name that stores the output
certificate
-sr Subject's certificate store location.
. Default to 'CurrentUser'
-# Serial Number from 1 to 2^31-1. Default to be unique
-$ The signing authority of the certificate

-n Certificate subject X500 name (eg: CN=Fred Dews)
-? Return a list of basic options
-! Return a list of extended options


Alright, lets see what happens if you run it with only 1 param, and no file name.

C:\Users\Will\makecert>dir
Volume in drive C is OS
Volume Serial Number is 3AE9-EFFF

Directory of C:\Users\Will\makecert

07/15/2009 09:03 PM <dir>.
07/15/2009 09:03 PM <dir>..
07/15/2009 09:03 PM 459 a


Note that the file, with only an output file name takes up 459 bytes. The file itself was named a. Curious as to whether an extension would make a difference, I ran this:

C:\Users\Will\makecert>makecert a.cer
Succeeded

C:\Users\Will\makecert>dir
Volume in drive C is OS
Volume Serial Number is 3AE9-EFFF

Directory of C:\Users\Will\makecert

07/15/2009 09:04 PM <dir>.
07/15/2009 09:04 PM <dir>..
07/15/2009 09:03 PM 459 a
07/15/2009 09:04 PM 459 a.cer


Using fc in binary mode I could easily spot the differences, but, I needed something a little cleaner:

C:\Users\Will\makecert>fc /b a a.cer
Comparing files a and A.CER
0000000F: 04 8F
00000010: 0F B1
00000011: B1 9C
00000012: DD F7
00000013: C8 FD
00000014: BA F9
00000015: 0F 29
00000016: AD 8A
00000017: 4F 4D
00000018: 0B D3
00000019: D8 C1
0000001A: 56 71
0000001B: B2 F0
0000001C: B5 A0
0000001D: DB 41
0000001E: 1E BB
00000053: 33 34
00000054: 31 35
00000055: 36 30
0000018B: 43 68
0000018C: BB 88
0000018D: BB F3
0000018E: 59 70
0000018F: B8 D6
00000190: 15 84
00000191: DB F0
00000192: 86 54
00000193: EB E5
00000194: 58 81
00000195: 77 95
00000196: 79 1E
00000197: 1B 0A
00000198: A7 2E
00000199: 14 84
0000019A: 09 90
0000019B: FE B1
0000019C: 16 4B
0000019D: 71 03
0000019E: 2E 39
0000019F: 1B C6
000001A0: 73 52
000001A1: BE 22
000001A2: 32 93
000001A3: 9B 56
000001A4: AD A6
000001A5: D7 DC
000001A6: 71 F1
000001A7: E3 65
000001A8: F9 54
000001A9: 74 51
000001AA: 4B 75
000001AB: E2 55
000001AC: 29 61
000001AD: 7F 7B
000001AE: 02 C6
000001AF: EC 38
000001B0: 4D 69
000001B1: 45 E8
000001B2: 48 F1
000001B3: D7 DF
000001B4: FA F3
000001B5: 27 65
000001B6: 60 6B
000001B7: 61 63
000001B8: 7D 06
000001B9: F6 AE
000001BA: 4E 9B
000001BB: 7C E9
000001BC: AB 67
000001BD: 50 31
000001BE: 3B E1
000001BF: 13 7B
000001C0: A2 35
000001C1: E0 98
000001C2: E8 76
000001C3: 62 F6
000001C4: 84 E3
000001C5: DE D4
000001C6: 69 D1
000001C7: 2A 77
000001C8: 84 C6
000001C9: 09 5F
000001CA: 8A AB


So, I switched to HxD to check out the files. It was much easier to spot the specific changes:

File Offset Data
a.cer 0F-1E 8F B1 9C F7 FD F9 29 8A 4D D3 C1 71 F0 A0 41 BB
a 0F-1E 04 0F B1 DD C8 BA 0F AD 4F 0B D8 56 B2 B5 DB 1E


When I looked in the certificates, these were clearly the certificate serial numbers.

Next, I looked at the next differences:

File Offset Data
a.cer 0F-1E 34 35 30
a 0F-1E 33 31 36


Knowing what this was from looking at the ASCII data, I identified this as the portion of the time stamp identified in the certificate itself. The ASCII data for the a.cer file (produced at Wednesday, July 15, 2009 9:04:50 PM) was 090716020450. Quickly reformatting the data it shows:

Year: (20)09
Month: 07
Date: 16
Hour: 02
Minute: 04
Second: 50


What's interesting to note is that the timestamp was in GMT. I created the file at 9:04 on July 15th. Since I'm CST (GMT -600), that, when translated back, would make it be 5 hours off. Curious. Perhaps it assumes a timestamp for EST regardless of what time zone you are in by default.

Also, the ending time stamp was actually identical. It assumes Saturday, December 31, 2039 6:59:59 PM as an ending time. Over 30 years, but, not to the date. Otherwise, it would be July 16th, not December 31st. And, the timestamp was interesting as well. Why not 11:59:59 PM? Moving on...

Actually, the remainder of the file was different from 18B-1CA.

a.cer

68 88 F3 70 D6 84 F0 54 E5 81 95 1E 0A 2E 84 90 B1 4B 03 39 C6 52 22 93 56 A6 DC F1 65 54 51 75 55 61 7B C6 38 69 E8 F1 DF F3 65 6B 63 06 AE 9B E9 67 31 E1 7B 35 98 76 F6 E3 D4 D1 77 C6 5F AB


As opposed to:

a

43 BB BB 59 B8 15 DB 86 EB 58 77 79 1B A7 14 09 FE 16 71 2E 1B 73 BE 32 9B AD D7 71 E3 F9 74 4B E2 29 7F 02 EC 4D 45 48 D7 FA 27 60 61 7D F6 4E 7C AB 50 3B 13 A2 E0 E8 62 84 DE 69 2A 84 09 8A


Next, I ran a command to apply the same timestamp to see if each cert, by design, had to be different. Theoretically, this would create two with identical, or near identical time stamps, so, if the last field were based on a seed directly associated with the timestamp of the operation, it would negate that...unless it uses CPU clock time and not file timestamp. Then, all bets are off.

C:\Users\Will\makecert>makecert a.cer & makecert b.cer
Succeeded
Succeeded


Even though I got the same time stamp in the file, the serial number and the last portion of the certificates were different. From a quick review of the certificate through the certificate properties, I could not find a direct mapping between the two field sets to identify what the relationship was between the data in the file properties and the raw data itself. That will be saved for a little more expirimentation later.

For the sake of completeness, I tried running makecert without the extensions to see if that made a difference, thinking perhaps the extension modified the file as well. I got the same results as above: identical timestamps (within the file at least) and variations on the serial number and the bottom of the certificate. In both cases, we still had a 459 byte file for the files with no extension and the .cer extension.

C:\Users\Will\makecert>makecert a & makecert b
Succeeded
Succeeded


Thus far, we've found that the serial number and timestamp are easily identifiable with a hex editor with the default options using makecert. So, let's try adding a little more to the mix. Since we can actually specify the desired serial number, let's see how that works and what the outcome is on two different files using that option. The syntax for defining a serial number is:

-# Serial Number from 1 to 2^31-1. Default to be unique

Making a default cert would by default, then, be unique. How did this work though? To make a certificate with a serial number of 0 I ran:

C:\Users\Will\makecert>makecert -# 0 #.cer
Succeeded


So, what do we see if we control this param? Interestingly, I found that varying the serial number from 1 to 2147483647 modified the file size by a few bytes. Since we're essentially dealing with a 32-bit field, the range 444 to 447 makes sense. Converting a 32-bit decimal to an 8-byte value (in the case of the 2147483647 cert) or a single field (in the case of the 0 cert) would reduce the serial, when translated to hex, by 3 bytes, although the hex would still require a value of 00 for the low end of the serial number range to indicate a blank field.

C:\Users\Will\makecert>makecert -# 0 #0.cer
Succeeded

C:\Users\Will\makecert>makecert -# 2147483647 #2147483647.cer
Succeeded

C:\Users\Will\makecert>dir

07/15/2009 09:51 PM 444 #0.cer
07/15/2009 09:52 PM 447 #2147483647.cer


I ran out of time to dig more, but, my intial review displayed that the obvious 3 byte difference (#0.cer - 444 to #2147483647.cer - 447 bytes) started at the same position:

File Offset Data
#0.cer 0F-0F 00
#2147483647.cer 0F-18 7F FF FF FF


Using calc in scientific mode, I quickly converted these hex values to decimal values:

File Data Decimal
#0.cer 00 0
#2147483647.cer 7F FF FF FF 2147483647


So, there was not much confusion about how that worked any longer; serial numbers started, in this case, at 0F and appended hexidecimal data until the 8-byte, hexidecimal field was fully used.

To wrap up this test, I ran the same command in a single call with the same serial number on two files created at the same time using serial numbers of 0 and 1:

C:\Users\Will\makecert>makecert -# 0 #0.cer & makecert -# 1 #1.cer
Succeeded
Succeeded


They were, as expected, the same size:

07/15/2009 10:06 PM 444 #0.cer
07/15/2009 10:06 PM 444 #1.cer


Checking the major discrepencies I got two sets of data:

1) the serial number (0F) values of 00 and 01
2) the ending segment (17C-1BB) as noted in the earlier examinations.

Summing up, timestamps are clearly directly correlated with the thread process itself. Serial numbers (and file sizes) are dependent on using the -# switch, but, are randomized by default. And, the last segment of the file is tied to another, separate set of variables I have yet to determine.

That's all for tonight.

1 comments:

  1. There is also a web site you can use to easily create self-signed certificates. http://MakeCert.com

    ReplyDelete