Manually Input/Sync BitLocker Keys

179 views
Skip to first unread message

Neil Azzaro

unread,
Jul 29, 2016, 9:36:46 AM7/29/16
to cauliflowervest-discuss
My company operates in a bit of a unique manner, we have ~1100 computers, with little to no infrastructure.  i.e. no VPN tunnels between offices, no Active Directory domain/forest, and a mixture of Mac's and PC's.  I've successfully set up the Cauliflower Vest server, and we've successfully encrypted Mac's using it.  My question is, since we don't have any AD infrastructure, is there a way to modify the AD BitLocker Sync script to manually enter the fields and run the script?  For example, if a tech is encrypting a new user's laptop, and we want to escrow the key, is there a way to run the script so that it prompts the tech for the key and inputs the other fields for them, then uploads the info to the server.  I was trying to pull apart the script, but I'm not all that familiar with Python.  Any help or suggestions would be much appreciated.

Justin McWilliams

unread,
Jul 29, 2016, 12:24:38 PM7/29/16
to cauliflower...@googlegroups.com
It would probably easier to write a small CLI which allows for pushing this data from machines directly to CauliflowerVest, instead of extending the existing BitLocker AD Sync source.  The Linux CLI is probably the best reference we have for how this could be done:

This would at least give you a way to push the data to CauliflowerVest.  The next challenge is programmatically fetching the recovery data from Windows (locally), to avoid having to copy/paste it.



Caveat: I haven't looked into this previously, and only just now searched for a few minutes.

It seems there are various ways to obtain the recovery key locally (e.g. dump it to a file, as seen in #10): http://www.eightforums.com/tutorials/21818-bitlocker-recovery-key-back-up-windows-8-a.html

The "manage-bde" CLI doesn't seem to document a way to obtain the recovery key while enabling BitLocker, but perhaps there's some undocumented way of doing so: https://technet.microsoft.com/en-us/library/ff829849(v=ws.11).aspx

This doc overviews how you can setup recovery sync to AD (which in theory could be ported to backup elsewhere): https://technet.microsoft.com/en-us/library/dn383583(v=ws.11).aspx



Let us know if that helps or not,

- Justin



On Fri, Jul 29, 2016 at 9:36 AM, 'Neil Azzaro' via cauliflowervest-discuss <cauliflower...@googlegroups.com> wrote:
My company operates in a bit of a unique manner, we have ~1100 computers, with little to no infrastructure.  i.e. no VPN tunnels between offices, no Active Directory domain/forest, and a mixture of Mac's and PC's.  I've successfully set up the Cauliflower Vest server, and we've successfully encrypted Mac's using it.  My question is, since we don't have any AD infrastructure, is there a way to modify the AD BitLocker Sync script to manually enter the fields and run the script?  For example, if a tech is encrypting a new user's laptop, and we want to escrow the key, is there a way to run the script so that it prompts the tech for the key and inputs the other fields for them, then uploads the info to the server.  I was trying to pull apart the script, but I'm not all that familiar with Python.  Any help or suggestions would be much appreciated.

--
You received this message because you are subscribed to the Google Groups "cauliflowervest-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cauliflowervest-d...@googlegroups.com.
To post to this group, send email to cauliflower...@googlegroups.com.
Visit this group at https://groups.google.com/group/cauliflowervest-discuss.
For more options, visit https://groups.google.com/d/optout.

Neil Azzaro

unread,
Aug 2, 2016, 2:15:09 PM8/2/16
to cauliflowervest-discuss
Thanks for the info.  I've been trying to pick apart the LUKS script and trying to determine what variables I need to account for and how to populate/provide them, but my lack of Python experience is severely hindering me (I've even gone so far as to start taking CodeAcademy courses on the topic to try to expedite things).  I think we'll be able to survive with manually entering each field for a "put" command, but even deciphering what the most basic method for that is appearing to be a challenge.  

Is there a way to enter in the options as arguments/switches for any of the client scripts?  I'm assuming that the main.py script for Linux could handle this if it was modified to use the bitlocker entry format instead of LUKS.  

The automation aspect of this isn't by any means a top priority, we're more concerned with using the basic functionality to escrow the keys, and we'll build upwards from there later on.  This would also allow us to escrow any pre-existing bitlocker keys we've generated, which are all sitting on an external HDD in a server room.  (I twitch at the thought of it, wasn't my idea.)

If I'm overlooking a function/feature that's right in front of me, please let me know.  I'll happily wear the dunce cap.  

Thanks for the help again,
Neil

Dan O'Boyle

unread,
Aug 10, 2016, 11:12:29 AM8/10/16
to cauliflowervest-discuss
I am also looking into this for our team.  (We're interested in retrieving the key on our own, and posting it to CFV)

Following the Luks script is seems the following events are happening:

- Get the Appengine specific local credentials (A script would have to instead use a separate set of generated credentials (from cloud console), as it would assumedly not be running on the AppEngine instance)
- Build a payload matching what CFV expects (That can be found by looking at main.py for the route that receives bitlocker keys)
- Use those credentials to post that payload to CFV (Example code would be very helpful here)

Anyone that can fill in for steps 2 or 3 would be very helpful :)

Guillermo Fuentes

unread,
Nov 1, 2016, 4:25:47 PM11/1/16
to cauliflowervest-discuss
Hi group,

I'm also testing this by using the manage-bde.exe command:

def EncryptVolumeC():
    output = subprocess.check_output(["C:/WINDOWS/system32/manage-bde.exe","-on", "C:", "-recoverypassword"])
    key = ""

    keys = re.findall("[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}", output)
    if len(keys) > 0:
        key = keys[0]

    return key
   

def EscrowKey(self, hostname, recovery_guid, recovery_password):
    metadata = {
        'hostname': hostname,
        'dn': "fqdn=" + hostname + ",cn=computers,dc=example,dc=com",
        'when_created': strftime('%Y%m%d%H%M%S.0Z', gmtime()),
        'parent_guid': "00000000-0000-0000-0000-000000000000",
        'owner': "username",
    }
    self.client.UploadPassphrase(recovery_guid, recovery_password, metadata)

def _find_between( s, first, last ):
    try:
        start = s.index( first ) + len( first )
        end = s.index( last, start )
        return s[start:end]
    except ValueError:
        return ""

client = win_client.BitLockerClient(server_url, opener, headers=headers)
bitlocker_escrow = BitLockerEscrow(client)
hostname =  socket.gethostname()
recovery_guid =  _find_between(subprocess.check_output(["mountvol","C:", "/L"]), "{","}")
recovery_password = EncryptVolumeC()
bitlocker_escrow.EscrowKey(hostname, recovery_guid, recovery_password)



This way I'm able to escrow the key and volume id.
The problem I'm having is when I try to search by hostname. It won't find the record. If I search by volume id, both, with prefix or full match search, it finds the record.

Is there any special metadata I would need to add for the hostname search to work?

Thanks in advance,
Guillermo

Maxim Ermilov

unread,
Nov 1, 2016, 5:46:49 PM11/1/16
to cauliflower...@googlegroups.com
Hi,

> Is there any special metadata I would need to add for the hostname search to work?

It should just work.
Is hostname uploaded correctly?
(You can check it in Cloud Console > Datastore > Entities. Entity Kind: BitLockerVolume)

Thanks,
Maxim

--
You received this message because you are subscribed to the Google Groups "cauliflowervest-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cauliflowervest-discuss+unsub...@googlegroups.com.
To post to this group, send email to cauliflowervest-discuss@googlegroups.com.

Guillermo Fuentes

unread,
Nov 1, 2016, 5:56:20 PM11/1/16
to cauliflower...@googlegroups.com
Hi Maxim,
Thanks for the quick reply!
Yes, it is uploaded correctly. I'm able to retrieve the record with a GQL query:
select * from BitLockerVolume where hostname="host1"

And via the "Query by Kind" interface.
Thanks for looking into this!
Guillermo

Maxim Ermilov

unread,
Nov 1, 2016, 5:59:37 PM11/1/16
to cauliflower...@googlegroups.com
And via the "Query by Kind" interface.

Does hostname contain non-ascii characters?
_____
Maxim

On Tue, Nov 1, 2016 at 5:56 PM, Guillermo Fuentes <gfuen...@gmail.com> wrote:
Hi Maxim,
Thanks for the quick reply!
Yes, it is uploaded correctly. I'm able to retrieve the record with a GQL query:
select * from BitLockerVolume where hostname="host1"

And via the "Query by Kind" interface.
Thanks for looking into this!
Guillermo

On Tue, Nov 1, 2016 at 5:46 PM, 'Maxim Ermilov' via cauliflowervest-discuss <cauliflowervest-discuss@googlegroups.com> wrote:
Hi,

> Is there any special metadata I would need to add for the hostname search to work?

It should just work.
Is hostname uploaded correctly?
(You can check it in Cloud Console > Datastore > Entities. Entity Kind: BitLockerVolume)

Thanks,
Maxim

Guillermo Fuentes

unread,
Nov 1, 2016, 6:03:49 PM11/1/16
to cauliflower...@googlegroups.com
No non-ascii characters are used.
Only alphanumeric and hyphen are used for the hostname.
Example: win-pc1


On Tue, Nov 1, 2016 at 5:59 PM, 'Maxim Ermilov' via cauliflowervest-discuss <cauliflower...@googlegroups.com> wrote:
And via the "Query by Kind" interface.

Does hostname contain non-ascii characters?
_____
Maxim

On Tue, Nov 1, 2016 at 5:56 PM, Guillermo Fuentes <gfuen...@gmail.com> wrote:
Hi Maxim,
Thanks for the quick reply!
Yes, it is uploaded correctly. I'm able to retrieve the record with a GQL query:
select * from BitLockerVolume where hostname="host1"

And via the "Query by Kind" interface.
Thanks for looking into this!
Guillermo

On Tue, Nov 1, 2016 at 5:46 PM, 'Maxim Ermilov' via cauliflowervest-discuss <cauliflowervest-discuss@googlegroups.com> wrote:
Hi,

> Is there any special metadata I would need to add for the hostname search to work?

It should just work.
Is hostname uploaded correctly?
(You can check it in Cloud Console > Datastore > Entities. Entity Kind: BitLockerVolume)

Thanks,
Maxim

--
You received this message because you are subscribed to the Google Groups "cauliflowervest-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cauliflowervest-discuss+unsubscr...@googlegroups.com.

To post to this group, send email to cauliflowervest-discuss@googlegroups.com.
Visit this group at https://groups.google.com/group/cauliflowervest-discuss.
For more options, visit https://groups.google.com/d/optout.

Maxim Ermilov

unread,
Nov 1, 2016, 6:09:57 PM11/1/16
to cauliflower...@googlegroups.com
strange.
are you using most recent version?

Thanks,
Maxim

On Tue, Nov 1, 2016 at 6:03 PM, Guillermo Fuentes <gfuen...@gmail.com> wrote:
No non-ascii characters are used.
Only alphanumeric and hyphen are used for the hostname.
Example: win-pc1

Guillermo Fuentes

unread,
Nov 1, 2016, 6:14:11 PM11/1/16
to cauliflower...@googlegroups.com

Yes.
v0.10.2

Maxim Ermilov

unread,
Nov 1, 2016, 6:18:31 PM11/1/16
to cauliflower...@googlegroups.com
> v0.10.2

version number was not increased for long time.
Can you try current git master ?

Thanks,
Maxim

On Tue, Nov 1, 2016 at 6:14 PM, Guillermo Fuentes <gfuen...@gmail.com> wrote:

Yes.
v0.10.2

Guillermo Fuentes

unread,
Nov 1, 2016, 6:33:09 PM11/1/16
to cauliflower...@googlegroups.com

I use current git master about 3 weeks ago.
I'll use current one and report back.
Thanks

Guillermo Fuentes

unread,
Nov 1, 2016, 9:37:08 PM11/1/16
to cauliflower...@googlegroups.com
Same result:

$ cd cauliflowervest
$ make test
...
ValueError: jpeg is required unless explicitly disabled using --disable-jpeg, aborting
make: *** [test] Error 1
$ source VE/bin/activate
$ pip install --upgrade pip
$ pip install  pillow
$ deactivate
$ make test
...
ALL TESTS COMPLETED SUCCESSFULLY

# Updated settings

$ make server_config
$ make release


On Tue, Nov 1, 2016 at 6:33 PM, Guillermo Fuentes <gfuen...@gmail.com> wrote:

I use current git master about 3 weeks ago.
I'll use current one and report back.
Thanks

Guillermo Fuentes

unread,
Nov 8, 2016, 12:32:19 PM11/8/16
to cauliflowervest-discuss
The BitLockerVolume.NormalizeHostname() makes the hostname value uppercase which causes the search to fail when the hostname field in the database is not all capitalized.
Saving the capitalized hostname value in the database fixes the search issue:

hostname =  socket.gethostname().upper()

Maxim, thanks so much for your help.

Guillermo

Maxim Ermilov

unread,
Nov 9, 2016, 8:00:58 PM11/9/16
to cauliflower...@googlegroups.com
Thank you for reporting this issue.

Thanks,
Maxim

--
You received this message because you are subscribed to the Google Groups "cauliflowervest-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cauliflowervest-discuss+unsub...@googlegroups.com.

Guillermo Fuentes

unread,
Nov 10, 2016, 5:20:13 PM11/10/16
to cauliflowervest-discuss
Even better Maxim.
Thanks for fixing it!
Guillermo


On Wednesday, November 9, 2016 at 8:00:58 PM UTC-5, Maxim Ermilov wrote:
Thank you for reporting this issue.

Thanks,
Maxim
On Tue, Nov 8, 2016 at 12:32 PM, Guillermo Fuentes <gfuen...@gmail.com> wrote:
The BitLockerVolume.NormalizeHostname() makes the hostname value uppercase which causes the search to fail when the hostname field in the database is not all capitalized.
Saving the capitalized hostname value in the database fixes the search issue:

hostname =  socket.gethostname().upper()

Maxim, thanks so much for your help.

Guillermo

--
You received this message because you are subscribed to the Google Groups "cauliflowervest-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cauliflowervest-discuss+unsub...@googlegroups.com.
To post to this group, send email to cauliflower...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages