Skip to content

Blog

Installing OpenWRT 19.07.2 on TP-Link WA801ND v5

I recently had some success installing OpenWRT 19.07.2 on my TP-Link WA801ND v5 wireless access point, which I was happy to do since the stock firmware was untouched since 2017.

I’ve documented the process in a video. This isn’t a tutorial with absolutely everything covered — I don’t want to encourage people to brick their devices, so you’ll need competence and proficiency with configuring your network settings in your operating system, and running a TFTP server.

It’s all, obviously, at your own risk. Stay safe and don’t brick your only access point!

Sorry for the inconsistency in audio quality.

Provisioning Raspbian with WiFi and SSH

Raspberry Pi logo

UPDATE: This does not work since Raspberry Pi OS based on bullseye. sdm might be a good alternative approach.

I’ve been playing with some Raspberry Pi Zero W machines for a few projects. They are inexpensive, with a form factor that makes for all sorts of interesting possibilities.

They are also a pain to initially provision, because you need adapter cables for mini-HDMI and micro-USB to get a monitor and keyboard connected.

With some help from this post from Linuxconfig.org, here’s what I’ve been doing to get the Pi Zero W up and running, on the network and ready for SSH access without having to plug anything in except power and the SD card!

Mount the image

$ fdisk -l *raspbian.img 

The initial FAT /boot partition lies at 8192 sectors in. A sector is 512 bytes. So, now we’ll mount the /boot partition using the loop pseudo-device.

$ mkdir boot
$ mount -o loop,offset=$(( 512 * 8192)) *raspbian.img boot

Set up SSH

Let’s go into our new boot subfolder where the image’s first partition is now mounted.

All we need to do to enable SSH is create an empty file called ssh.

$ cd boot
$ sudo touch ssh

Configure WiFi

To configure WiFi, we’ll need to drop a wpa-supplicant.conf file in this folder. Upon first boot, Raspbian moves this into the correct config location and the Pi will be able to talk to our network out of the box.

Create a file called wpa-supplicant.conf with these contents:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=GB

network={
	ssid="Your network name"
	psk="Your network password"
	key_mgmt=WPA-PSK
}

You’ll need to replace the placeholders with your network name and password, and possibly change country too.

Unmount the image

$ cd ..
$ umount boot

Write the image

Insert the target SD card and verify which device it is using fdisk.

Take great care to ensure that the command below is run with the correct device as the target, or you’ll overwrite a hard drive on your local system.

$ sudo fdisk -l

Disk /dev/sdb ...
Model: Card Reader

I am confident that sdb is correct, because I see from fdisk that the model is Card Reader.

$ sudo dd if=*raspbian.img of=/dev/sdb

Security

Remember that once you’ve booted, you’ve just spun up a Raspberry Pi on your network with the default username of pi and the default password of raspberry. Check your router or network logs for the assigned DHCP address of the new Pi, log in promptly over SSH and change that password!

Licensing: Restricting the ability to prevent others exercising their rights

There is great potential in using open source and free software licensing to support and encourage the ethical use of technology — and indeed to deter its use in violating human rights and provide some legal mechanisms to challenge this when it happens.

But it’s also an extremely complex and difficult issue, as there are always a great number of implications, and they’re not always easy to anticipate.

This is an area I watch with keen interest, and I was interested to read Matthew Garrett posing some interesting questions around how a clause relating to taking away another’s ability to exercise their rights under the licence might work. The idea is taking the moral goal of preventing harm being done to others by means of the software and expressing that goal in terms of prohibiting actions that would prevent others from exercising their rights under the same licence.

This work may not be used in any way that impairs any individual’s ability to exercise the permissions granted by this license, whether or not they have received a copy of the covered work

To be clear, I don’t think this is a good license – it has a bunch of unfortunate consequences like it being impossible to use covered code in self-defence if doing so would impair your attacker’s ability to use the software. I’m not advocating this as a solution to anything. But I am interested in seeing whether the perception of the argument changes when we refocus it on user freedom as opposed to an independent ethical goal.

Matthew Garrett

Why is a website connecting to “localhost”?? — Socky and SockyNotifier (macOS)

Inspired by Davy Wybiral’s demonstration (explanation) of how web pages can often enumerate services running on localhost using JavaScript, I put together Socky and SockyNotifier.

The idea is that you have Socky listen on target ports, and any connection attempts that come in to those target ports will fire a user notification at the top right of your screen (that’s the job of SockyNotifier — to show those notifications).

Note: that this is not particularly serious or practical, but I wanted a project that let me work directly with the Core Foundation APIs in C, and this seemed a good opportunity.

Idle Lock Lite (Going Lower-Level 2.0)

In this post, I said

Maybe next the whole program should do the workstation locking, warning message and idle detection in one program.

Well, here it is — Idle Lock Lite.

It’s a lightweight application designed to run in the background, detecting if the computer is idle (based on keyboard or mouse movement) and presenting a timed warning that the computer will be locked. It then locks the computer if it is still idle once the grace period expires.

Idle Lock Lite

It is functional, but its real world usability isn’t there yet — it’s not going to be usable in practice if it isn’t aware of things like playing back video, presentations and other states that are not idle, but don’t involve user input for longer periods of time. It isn’t aware of those things at the time of writing!

However, it has been an enjoyable and informative further exploration of working with the Win32 API directly.

I found myself drawn to working in C/Win32 for this application and its predecessor — the result here is less than 50 KiB in size and uses about 1.4 MiB of RAM (Private Bytes). Any similar application you would create in .NET, for example, would be an order of magnitude more demanding in terms of resources, just because of the nature of the framework.

Here’s an explanation of how it works:

  • It accepts two command line arguments — the number of seconds before displaying the warning window and the number of grace period seconds while that window is open.
  • It measures the number of GetTickCount64 ticks taken for a SetTimer with 1000 ms to be fired. This is used to calculate idle periods and grace periods in terms of ticks.
  • It sets up two SetWindowsHookEx hooks — one for keyboard activity and one for the mouse. These yield execution some of the time to avoid performance issues from the frequency with which they are called. These update our last interaction tick number to indicate the computer is in use.
  • Every ten seconds, a SetTimer-based timer calls a function which evaluates if we’ve reached the idle condition. If so, the warning dialogue is displayed.
  • The warning dialogue counts down the grace period with the progress bar and another SetTimer callback. Upon expiry, LockWorkStation is called to lock the computer.
  • The WM_WTSSESSION_CHANGE window event is listened for — we take notice of WTS_SESSION_LOCK and UNLOCK events to ensure that we don’t try to detect idle conditions if the screen is already locked, and that when unlocked, any previous idle period is reset.

Learning about how Windows operates at a lower-level — windows, window messages and some of the more primitive operations has been illuminating! This is the perfect bi(y)te-sized project to help me move forward with learning about this!

DfontSplitter 1.0 on the Mac App Store

I recently completed my rewrite of DfontSplitter for Mac, my tool for converting Mac-formatted Dfont, Font Suitcase and TTC font files into TTF files.

This new version is written in Swift, targets macOS Mojave (10.14) and later and meets all the requirements that soon will be required of Mac software (code signing, notarisation/delivery via Mac App Store).

It’s available on the Mac App Store, with source code now available on GitHub.

The “T with chisel” DfontSplitter icon is licensed under the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. The icon includes a modified version of “Chisel wood 24mm” by Isabelle Grosjean, which is also licensed as such.

The old “T with pencil” DfontSplitter icon is from the Oxygen Icon set and is licensed under the Creative Commons BY-SA 3.0 Unported licence. Please see the More Information pages for Windows and Mac for full licensing information.

Apple, the Apple logo and Mac are trademarks of Apple Inc., registered in the U.S. and other countries and regions. App Store is a service mark of Apple Inc.

Extract List of ADFS Failed Logins to CSV

Keeping an eye on failed logins and the user accounts that are being targeted is an important part of being responsible for an Office 365/Azure Active Directory tenant.

If you can afford the higher-level O365/Azure AD plans, there are great tools built in to the Azure Portal that allow useful intelligence into your security posture.

For The Rest of Us(tm), we sometimes need to be a little creative to gather the information needed. For on-premises Active Directory Federation Services (ADFS) servers, I put together a simple, quick and, perhaps slightly hacky script to extract the usernames from recent failed login events from the Windows Event Log and dump them, along with the rest of the Windows Event, to a CSV file for later analysis.

This specifically searches event logs from the past 12 hours (43200000 milliseconds in the $query).

Note that this is heavily dependent upon the format of the event message having the username on the (zero-indexed) line 14. Works for us — no warranties, etc. etc.!

Installing RSAT on 1903 from the Features on Demand ISO

Installing the Remote System Administration Tools on a Windows 10 1903 system that uses System Center Configuration Manager to receive Windows updates seems to be challenging. The process of pulling the RSAT bits down from Windows Update in my experience was not succeeding – perhaps because the SCCM WSUS instance did not have them.

The CBS.log showed:

CBS    Exec: Failed to download FOD from WU, retry onece. [HRESULT = 0x800f0954 - CBS_E_INVALID_WINDOWS_UPDATE_COUNT_WSUS]

Some solutions online seemed to suggest temporarily switching the Windows Update source in the registry to Windows Update (online) rather than WSUS, but editing the registry this way and upsetting the software update system seemed… unwise.

I ended up doing it a different way: downloading the Features on Demand DVD ISO from the Volume Licensing Service Center (in my case, SW_DVD9_NTRL_Win_10_1903_64Bit_MultiLang_FOD_1_X22-01658.ISO), mounting the ISO and using this modified version of Martin Bengtsson’s script to install the components from that ISO without contacting Windows Update.

With any luck, this might help someone else.

Going Lower-Level

I just released, on GitHub, IdleTaskTerminatorLite, my first foray into the lower-level world of programming directly with the Win32 API.

We use an old custom shutdown.exe (BeyondLogic Shutdown) to provide a timed screen lock feature, where a user is notified their screen will lock in a period of time and can cancel the locking of the workstation.

Clicking the Cancel button within the time limit, however, seems unnecessary and requires precisely clicking the Cancel button when the user is under time pressure! This is not a good user experience. A simple change to the idle state of the machine (any keypress or mouse movement) should cancel the timed locking of the workstation.

This lightweight background application detects user activity and forcibly kills the beyondlogic.shutdown.exe process, effectively cancelling the locking of the workstation without requiring the user to actually click Cancel.

This is currently rather ‘opinionated’ in that it specifically checks for hard-coded named processes running. It Works for Us(tm), but you may need to modify it for your environment. 😉

This whole solution is a little bit hacky, but it works. 😐

I had written something along these lines to terminate this workstation lock program in C#, but as a .NET process running in the background, you were looking at dozens of megabytes of RAM for something always running in the background. It felt thoroughly inefficient and unnecessary for something so simple.

I have always found myself honestly a little frightened of C and C++. Horror stories around coding securely, the undefined behaviour of doing ‘pointer stuff’ yourself… but this little project represented an opportunity to take this relatively rudimentary functionality and learn how to implement it the Win32 API directly in a C program — and in doing so, cut resource usage (hopefully) significantly.

So, I did. Using the oft-abused WH_KEYBOARD_LL hook (and its WH_MOUSE_LL cousin), I periodically update a counter as to the user’s last idle time. If the hook is called (i.e. the user is typing or moving the mouse) and it’s been long enough since we last noticed such interaction, I check for the beyondlogic.shutdown.exe process and, if present, kill it.

This began life as whatever Visual Studio template gave me a buildable project that let me work with the right APIs, so there is likely unnecessary stuff still present and it could be more lightweight still. And, there’s a good chance I’ve made mistakes that need correcting, so please do get in contact if you’re willing to educate me in some small (or large) way!

I have tried to be particularly careful with buffers — string handling is either done with (I guess, inefficient) fixed-size buffers where I check what I put in will fit first, and I’ve tried to use the ‘safe’ string functions where possible too.

So, it’s a baby step towards working on more low-level projects. But, I’ve taken some action to tackle my pointer anxiety. 🙂

Maybe next the whole program should do the workstation locking, warning message and idle detection in one program.

Red Hat Certified System Administrator

This was a whole month and a bit ago, and I never got around to throwing it here on the site, but I will now announce that I am a Red Hat Certified System Adminstrator!