The suggested soundtrack for this post comes from MASTER BOOT RECORD. The genre is called “chiptune” and a big shout-out to my friend, Wes, on keying me into them.

In one of my previous posts, I covered using the YubiKey to lock the machine when it’s removed. I intend to do one on configuring the machine to require the YubiKey for login but that’ll be for another day (if I get around to it). For now, the last remaining piece is to tie the disk’s encryption to the Yubikey, which is what we’ll be doing in this post.

Now that we know Slot 0 was the O.G. key holder (because we added to Slot 7 and the rest of the slots are disabled), we can target it for removal.

To do that, we’ll run the following command.

(BE FOREWARNED: You will deleting the only passphrase that doesn’t require the YubiKey to be present in the system. If you haven’t rebooted the machine to verify the passphrase+YubiKey combination, I strongly urge you not to do this step.):

And, now, the disk is only protected by the password+YubiKey combination. So, if the device gets stolen and the YubiKey isn’t in it (say, when I’m travelling), then the device is pretty useless – that is, unless you reformat it and start with new operating system.

Thanks for coming to this NERDTalk™ and I hope it helps you in your security endeavours in the future. 🙂

…and the lessons I’ve learned. (Seemed like it needed a continuation, yeah?)

So, one of my many (now backlogged) personal projects is to write a Windows Service that copies files from a source directory to a target directory (or directories) and then encrypts the files via the LSA account (if so configured in the app config file). The idea was bourne out of two premises:

As someone who doesn’t currently have a cloud provider, I still need disaster recovery and, if I’m in this position, surely there’s at least one other person in the world in the same boat. Maybe.

This is, perhaps, the more crucial part. We take for granted that we have pretty fat pipes with which to fit all of the cats that we could ever want into the tubes and still have room left over. Other areas of the world still don’t have this luxury. What opportunities are available to them, now that we’re in a mobile-first, cloud-first world?

So, since we’re dealing with disks, I wanted to prevent it being an attack surface and/or prevent disk queuing or thrashing. If you’ve ever seen my project for the Windows Service to download the Bing Images, then you’re already familiar with my preferred route of semaphore use, which is the SemaphoreSlim.

So, I write my service, compile it (via Visual Studio), and install on my machine (via InstallUtil). I fire it up and drop a file into the source folder and, when the timer hits, it copies and encrypts the files to the destinations. O.k., so far, so good. I add a second file and nothing happens. Wait a few more minutes, still nothing.

O.k., I shot myself in the foot, somewhere, but nowhere I need to solve the crime, where I’m also the murderer; which isn’t, necessarily, the easiest task in the world.

So, I check task manager. The service is still running, so we didn’t hit a second-chance exception and the service terminated. O.k., I’m not a total idiot, at least (I hope).

I check the Wait Chain Traversal in Task Manager and it says the process is running fine, nothing is blocked.

O.k…. That makes even less sense. Time to debug it. I create a dump of the process in task manager and crack it open in WinDbg.

I’m using a tool called PDE, which you can get from the public OneDrive shared by Andrew Richards here. I’ll be using it to look for a thread with the most amount of frames. Why? Well, just because nothing is happening, it doesn’t mean that nothing is actually happening.

The properties that we care about are the m_currentCount and the m_waitCount. We can look at the source code for SemaphoreSlim and see that these signify what the problem is:

m_currentCount – The semaphore count, initialized in the constructor to the initial value, every release call increments it and every wait call decrements it as long as its value is positive otherwise the wait will block. Its value must be between the maximum semaphore value and zero.

m_waitCount – The number of synchronously waiting threads, it is set to zero in the constructor and increments before blocking the threading and decrements it back after that. It is used as flag for the release call to know if there are waiting threads in the monitor or not.

So, here’s what happened: I leveraged Parallel.ForEach and for each disk action I required the caller to request wait on the semaphore, until it completes and releases the semaphore. The Semaphore’s initial value was stupid-low: 10. So, as soon as the second file was added, we created a condition in which multiple threads (because of parallelization) were requesting locks on the Semaphore and starving it out of being available for any further work.

In theory, this would be 1 lock for the source directory, 2 locks for the two target directories, 1 lock per file (so 2x2x2)… You can quickly see why this was a bad approach, even though it had the best intentions, at heart.

So, for a project for a friend with cancer, I was setting up something leveraging NextCloud (which another friend set up an account for me on their local instance for). It isn’t important who the friends were or what the project was but it’s slight backdrop into why I didn’t just use another program.

So, I installed the NextCloud desktop client on a Win10 (x64) machine and went to fire it up. Then came this gloriously (and mundanely) generic error message:

Very descriptive and actionable, yeah? (hint: LoadLibrary actually hints as to what’s going on, if you’ve run into assembly referencing before, but we’ll cover that later in this post.)

Well, the first thought is to go to the Event Viewer to see what happened. Only problem is: No events were logged. Anywhere. It never happened. It never even existed.

O.k., time to get medieval on this. Since the window never renders for the application and this seems to happen on initialisation, we’ll have to hook into the application to catch the event[s] in question.

Enter ADPlus. ADPlus has been around for hot-minute and isn’t, precisely, my go-to for debugging puposes; however, it’s definitely handy when you want to catch things happening on start-up.

So, we need to tell adplus to start and to monitor for an instance of the nextcloud application to loaded/referenced/scheduled by the kernel. (Littletid-bit here: The load happens before it’s reference is available in the process list, which is why we get the results you’ll see later-on.)

To tell adplus to “listen” for an instance of this application, we’ll do something like the following:

Normally, you might have to go frame by frame to understand what’s going on but since we don’t have the symbols for nextcloud or qwindow, we can kind of wing it and still figure out what’s going.

As the frames are read from bottom to top (in terms of processing order), the frames of interest to us will be 09 to 02 (which are in bold above). This shows us that GDI and/or OpenGL are looking for a driver that maps to a specific pixel format. We hit a frame in the ATI driver code that we can’t resolve to a method but then we see the call to terminate the process; so, we can probably discern that this is where the error screen is shown (the one with the LoadLibrary error).

So, if we going perusing around the interwebs, we should be able to confirm our suspicions and we’ll find this on MSDN, which has the following notation: “If the function fails, the return value is NULL. To get extended error information, call GetLastError.” Since this happens in native code and we’re unable to ascertain the method called in the ATI driver, it’s safe for us to assume that the ATI driver attempts to load a specified assembly and that assembly doesn’t exist. Also, since the exception is trapped and throw into the window, this is why the .excr record doesn’t exist on the stack. (Yay for native and scopes.)

Easiest solution: Install the nextcloud client on a different machine and do what I need to do or attempt to update the ATI video driver and hope that it resolves the issue. The former is a much more assured way to resolve it, though, so that’s what I did.

When developing programs, it’s important to consider that exceptions might occur in third-party dependencies. This mightn’t be the most productive error messages for users to figure out what’s going on. In fact, I whole-heartedly believe that if I hadn’t ever dealt with loading libraries or debugging, I’d have no clue as to why the program was broken.

This makes the error message one of the world’s crappiest error messages simply because it is inactionable by a user, if a user hasn’t the necessary tools and experience explained above.

So, then, what is the point of the error message?

I get the point, don’t get me wrong, in that lets someone know something went wrong. However, the general nature of the error message, itself, leads much to be desired. What library was it trying to load? Why did it fail? I’m sure I could eventually find a mapping for the NT Status errors that relate to this but why should I, as an end-user, have to resort to that level of depth just to figure out the problem?

The problem is shared between the application writers (nextcloud), GDI, OpenGL, and ATI. Each layer should expect an exception to be possible and to trap and raise it with the requisite information to make it actionable.

This is just… “Something happened. Good luck!”

Thanks for coming to this TEDTalk and I hope that it hasn’t bored you to death, despite it’s brevity.

It took me a while to piece this together, so I figured that I would write a handy “how-to”, in order to prevent someone else from losing the man-hours that it took to piecemeal this together.

The first thing that we’ll need to do is to create the monitoring rule. This rule is specifically used to key-off of the event that is trigged when the YubiKey is removed; however, we’ll need some information for that before we can write the rule.

You can use the below command to obtain the device-specific information:

udevadm monitor --environment --udev

With the command running, remove the YubiKey device from the system. I would suggest copying all of the properties that you see in the output to a text file. We’ll use some of these to define your rule.

Right. So, let’s create the rule. Run this command to start the text editor:

sudo nano /etc/udev/rules.d/85-yubikey.rules

In the text editor, you’ll add the rule. Below is mine, for an example:

The most specific piece that you’ll copy, verbatum, is the overloaded “Run” section.

Press Ctrl+X in the text editor window, when you’re done. Press your key for confirmation (‘Y’ in English, ‘J’ in Swedish, etc.). Then press ‘Enter’ (a.k.a.: carriage return) to confirm the path we specified when we started the text editor.

You should now be back at the terminal.

Now that the rule is in place, we need to define the action. We’ve already declared where it will go to fetch the action definition (see the overloaded “Run” declaration above) and now we need to create that file.

The above snippet is from when the executing script looked quite different and, thus, it was failing to execute. Keep in mind that you may need to define different parameters in your monitoring rule, for example, if your device has a different vendor or model id and the removal isn’t creating the logging event:

EN: Can we talk about “update descriptions” for a minute? I have seen updates for Windows didn’t have a good description for a long time. I had to look for a description to understand what was wrong (broken) and why it was needed.

Why couldn’t they write anything? And why do I need the update? I know I could look for a description, if the application is open-source (like Signal), but why should I? And I’m not going to want to do it for every app…

Okej… Jag är trött. Jag tänkta att jag skulle har mer att skriver om men jag tänkte fel. Eller kanske jag vill inte att skriver mer… Vilken. Både är sanningen. Kvantmekaniska påstår. Är jag katten? Kanske…EN: I think that I’m going to have a new job, soon. I can’t say who its with but I am happy/lucky that I could find it. Well… I say, “I found it,” but my friend knew of the job and he wanted that I could come and work with him.

I have written a program while I was waiting (looking for a job). The program has more than 3,000 lines of code – all written by me. It was difficult to write and it isn’t finished; so, I have more that I have write… The program (itself) has a problem with SQL Server and I don’t know what I could do to fix it. Do you speak SQL (Server)? 🙂

I have to go to Sweden, soon, to visit with my lawyer and, afterwards, I have to go to the USA to see my friend, who has cancer. She has been my friend for more than twenty years and I have loved her that whole time. I think that I have known her since I was 13? I’m sad (more sad than I want anyone to know) that I can do nothing about it. But that is life: happiness and sadness.

In other news… I found my first Swedish movie that I didn’t like. Borders. In the beginngin it was o.k. but I didn’t like hwere it went.

O.k…. I’m tired. I thought that I would have more to write about but I was wrong. Or maybe I don’t want to write more… Whichever. Both are the truth. Quantum states. Am I the cat? Maybe…

I hardly ever post photos, anymore (unless it’s on Instagram), so here’s the test pattern from Sveriges Television. Note the 2.0 and 5.1 surround-sound test on the left-hand side.

So, I had a pretty large problem to figure out: How to configure 170+ different OVPN (Swedish/English) configurations in NetworkManager, without having to enter my username and password over 170 friggin’, fraggin’ times.

(NOTE: If you’re highly security conscious, then this probably isn’t going to be very palatable for you. You have been warned.)

I use [REDACTED] VPN service and they offer a zip file that you can download with containing multiple OVPN configuration files; a unique file for each server that you can use. After filtering the list down to my targets, I had a resultant list to import into Network Manager.

In order to have NetworkManager leverage ovpn, though, you need to install two packages, first.

Now that we have the files imported, we need to modify them. To do this, the easiest way is to use Python to read in the files and write our changes. Modify the script below to include your username and password.

Now that the files are modified, we need to restart NetworkManager to allow the configurations to be re-read on the connection’s instantiation.

sudo service network-manager restart

(Personally, bouncing the machine was more of a formidable option, here, but that’s because I messed-up the initial script – due to indenting – and wiped all of my configuration files; thus, the warning in the script.)

Now that this has been configured, I needed a way to randomly choose which VPN connection to use, so as to not always land on a static connection. To do this, I used Python again and randomised the choice of which VPN server to connect to. (You’ll note that I’m using a pretty large seed and that’s because the default random.random() method isn’t random in a secure manner [read: it’s predictable].)

#!/usr/bin/env python
"""Randomly connections to a random VPN profile (if any are found).
Uses NetworkManager (https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.html#) to
enumerate the devices and connections. First, we enumerate the wireless devices to ensure that we have one. Next, we
enumerate the VPN connections and put them into a list. After that, we randomly select one of the VPN connections to
connect to. Once we've accomplished this, we disconnect the current VPN connection (if one is found) and connect to
the randomly chosen VPN connection.
REQUIREMENTS:
python-networkmanager
TO RUN:
python NetworkManager_VPN.py
"""
__author__ = "felsokning"
__copyright__ = "Copyright 2019"
__license__ = "MIT"
import os
import random
import time
# Externals
import NetworkManager
# Find all of the VPN connections on the machine.
vpns = list()
current_vpn = None
wireless_device = None
connections = NetworkManager.Settings.ListConnections()
for c in connections:
if "vpn" in c.GetSettings()['connection']['type']:
path = c.object_path
vpns.append(path)
# If there are no VPN connections, there's no point in proceeding.
if vpns.__len__() > 0:
# We find the Wireless Network Interface.
# If you're running some kind of weird, three wireless network cards situation, then...
# Change this code to work in your use-case scenario.
devices = NetworkManager.Device.all()
for d in devices:
if "wifi" in d.Driver:
wireless_device = d
# Validate that we found a wireless network interface
if wireless_device is not None:
# Get the currently active VPN connection.
# If you're running some kind of weird, three active VPNs scenario, then...
# Change this code to work in your use-case.
active = NetworkManager.NetworkManager.ActiveConnections
for a in active:
if "vpn" in a.Type:
current_vpn = a
# Choose a random one to connect to. We use the far more secure random method, with a larger seed,
# to try and prevent the random generation from being a predictable pattern (well, to try to make
# it far less predictable with our sample, at least).
rand = random.SystemRandom(os.urandom(99999999))
random_int = rand.randint(0, (vpns.__len__() - 1))
random_vpn = vpns.__getitem__(random_int)
new_connection = NetworkManager.Connection(random_vpn)
# Validate that we have a current VPN connection to disconnect from before we do.
if current_vpn is not None:
# Disconnect the old & busted.
NetworkManager.NetworkManager.DeactivateConnection(current_vpn)
# To prevent collision in NetworkManager, we allow background clean-up before reconnecting.
time.sleep(10)
# Connect the new hotness.
print("Connecting to: {}".format(random_vpn))
NetworkManager.NetworkManager.ActivateConnection(new_connection, wireless_device, "/")
# No wireless interfaces were found, so let's abort.
else:
raise Exception("No wireless interfaces were found.")
# No VPN connections were found, so let's abort.
else:
raise Exception("The hull has been breached and the science is leaking out! "
"(We didn't find any valid VPN connections on this machine via NetworkManager.)")

That should just about do it. …but WAIT! That’s not all! If you act now…

I’ve also written a script to remove all of the OVPN configurations from NetworkManager, in case you made a mistake somewhere (I know that I did and this came in pretty useful.)

It is, by no small irony, that it’s been some time that I’ve written a post. A lot’s been going on – including, but not limited to, travelling betwixt Ireland and Sweden. As a result of that, I haven’t – quite – had the free time nor desire to really sit down and dedicate time solely to creating a post but, after my recent ventures in programming for the same resultant set in multiple languages, I have a bit more of a reason and desire to make one.

Someone made a website that you can refer to, to look at what the week number is.

My friend/previous manager in Sweden suggested the idea, since I was already working on creating a variation of the week number site in Docker/Python.

The Idea

Since week numbers are a prominent feature, it would be worthwhile to write reusable code, which could be imported, to save others the time of having to write it – themselves.

Implementation

The first problem was that the implementation, to achieve the same desired net-effect result, would – obviously – be different between languages. So, for example, C# has the premise of extension methods but Rust requires Trait and Implementation to extend a given type.

To do this, it required a lot of research, trials, and much errors but, first, the pseudo-code needed to be defined so that I had a blueprint to use across the languages.

if($obj-eq date from datetime){obtain week number from the object via method}

With the pseudo-code defined, it was time for the implementation via code. Most of the development occurred on an Ubuntu 18.04LTS machine – save for the C#/C++ code, which occurred on a Windows 10 machine.

I’m only going to show two of the four implementations, here, so as to save on space.

So, the lessons learned weren’t very numerous but I suppose that the most prevalent is that documentation is quite worthwhile but it can oft be extremely difficult to find. Even if you find the documentation, it isn’t going to be as implicitly straightforward as one might think. For example, defining the return-type in Rust is vastly different than any other language that I’ve ever programmed in.

As you can see, the return-type (u32) is strongly-typed and appears after the initial function (read: method) definition and is always on the right of an arrow.

Also, while languages might seem different, the conceps behind their implementations have the same underlying concepts. Take the concept of ‘this‘ in C# and of ‘self‘ in Python. While, syntatically, they’re different in definition and use, their end-goal is effectively the same thing: Effect a specific instance of the type, which – at runtime – is the instance in question (well, any instance, in scope really but I’m cluttering this with abstraction).

Conclusion

Programming the same action across multiple languages causes us to learn more about those languages (it was my second program in Rust) and, while it can be a pain, the net result could be that it’s more of a benefit to the overall open-source community.