Reverse engineering a Unity-based Android game

My child is playing an Android game that asks for microphone access. And while it doesn’t insist on it and the privacy policy says that no recordings are being kept, I thought that I would take a closer look. The process turned out rather complicated thanks to the fact that the game was built with the Unity framework. Since I have little experience with games in general and Android applications in particular, I thought that I would document the analysis steps here. And maybe this turns out useful for other people as well.

How anti-fingerprinting extensions tend to make fingerprinting easier

Do you have a privacy protection extension installed in your browser? There are so many around, and every security vendor is promoting their own. Typically, these will provide a feature called “anti-fingerprinting” or “fingerprint protection” which is supposed to make you less identifiable on the web. What you won’t notice: this feature is almost universally flawed, potentially allowing even better fingerprinting.

Pig disguised as a bird but still clearly recognizable
Image credits: OpenClipart

I’ve seen a number of extensions misimplement this functionality, yet I rarely bother to write a report. The effort to fully explain the problem is considerable. On the other hand, it is obvious that for most vendors privacy protection is merely a check that they can put on their feature list. Quality does not matter because no user will be able to tell whether their solution actually worked. With minimal resources available, my issue report is unlikely to cause a meaningful action.

That’s why I decided to explain the issues in a blog post, a typical extension will have at least three out of four. Next time I run across a browser extension suffering from all the same flaws I can send them a link to this post. And maybe some vendors will resolve the issues then. Or, even better, not even make these mistakes in the first place.

Adding DKIM support to OpenSMTPD with custom filters

If you, like me, are running your own mail server, you might have looked at OpenSMTPD. There are very compelling reasons for that, most important being the configuration simplicity. The following is a working base configuration handling both mail delivery on port 25 as well as mail submissions on port 587:

pki default cert "/etc/mail/default.pem"
pki default key "/etc/mail/default.key"

table local_domains {"", ""}

listen on eth0 tls pki default
listen on eth0 port 587 tls-require pki default auth

action "local" maildir
action "outbound" relay

match from any for domain <local_domains> action "local"
match for local action "local"
match auth from any for any action "outbound"
match from local for any action "outbound"

You might want to add virtual user lists, aliases, SRS support, but it really doesn’t get much more complicated than this. The best practices are all there: no authentication over unencrypted connections, no relaying of mails by unauthorized parties, all of that being very obvious in the configuration. Compare that to Postfix configuration with its multitude of complicated configuration files where I was very much afraid of making a configuration mistake and inadvertently turning my mail server into an open relay.

There is no DKIM support out of the box however, you have to add filters for that. The documentation suggests using opensmtpd-filter-dkimsign that most platforms don’t have prebuilt packages for. So you have to get the source code from some Dutch web server, presumably run by the OpenBSD developer Martijn van Duren. And what you get is a very simplistic DKIM signer, not even capable of supporting multiple domains.

The documentation suggests opensmtpd-filter-rspamd as an alternative which can indeed both sign and verify DKIM signatures. It relies on rspamd however, an anti-spam solution introducing a fair deal of complexity and clearly overdimensioned in my case.

So I went for writing custom filters. With dkimpy implementing all the necessary functionality in Python, how hard could it be?

What would you risk for free Honey?

Honey is a popular browser extension built by the PayPal subsidiary Honey Science LLC. It promises nothing less than preventing you from wasting money on your online purchases. Whenever possible, it will automatically apply promo codes to your shopping cart, thus saving your money without you lifting a finger. And it even runs a reward program that will give you some money back! Sounds great, what’s the catch?

With such offers, the price you pay is usually your privacy. With Honey, it’s also security. The browser extension is highly reliant on instructions it receives from its server. I found at least four ways for this server to run arbitrary code on any website you visit. So the extension can mutate into spyware or malware at any time, for all users or only for a subset of them – without leaving any traces of the attack like a malicious extension release.

Flies buzzing around an open honeypot, despite the fly swatter nearby.
Image credits: Honey, Glitch, Firkin, j4p4n

Added Webmention support to the blog

A discussion on Mastodon convinced me to take a look at the Webmention standard, and I even implemented a receiver for this blog. Essentially, this is a newer variant of the Pingback mechanism: when one blog links to another, the software behind one blog will notify the other. For my blog, I implemented this as part of the commenting mechanism, and approved Webmentions will appear as comments with minimally different representation.

Given that this website is built via the Hugo static site generator, the commenting system is rather unusual. Comments received are added to the pre-moderation queue. Once approved, they are added to the blog’s GitHub repository and will be built along with the other content. Webmention requests are handled in the same way.

A grim outlook on the future of browser add-ons

A few days ago Mozilla announced the release of their new Android browser. This release, dubbed “Firefox Daylight,” is supposed to achieve nothing less than to “revolutionize mobile browsing.” And that also goes for browser extensions of course:

Last but not least, we revamped the extensions experience. We know that add-ons play an important role for many Firefox users and we want to make sure to offer them the best possible experience when starting to use our newest Android browsing app. We’re kicking it off with the top 9 add-ons for enhanced privacy and user experience from our Recommended Extensions program.

What this text carefully avoids stating directly: that’s the only nine (as in: single-digit 9) add-ons which you will be able to install on Firefox for Android now. After being able to use thousands of add-ons before, this feels like a significant downgrade. Particularly given that there appears to be no technical reason why none of the other add-ons are allowed any more, it being merely a policy decision. I already verified that my add-ons can still run on Firefox for Android but aren’t allowed to, same should be true for the majority of other add-ons.

Historical Firefox browser extension icons (puzzle pieces) representing the past, an oddly shaped and inconvenient puzzle piece standing for the present and a tombstone for the potential future
Evolution of browser extensions. Image credits: Mozilla, jean_victor_balin

Dismantling BullGuard Antivirus’ online protection

Just like so many other antivirus applications, BullGuard antivirus promises to protect you online. This protection consists of the three classic components: protection against malicious websites, marking of malicious search results and BullGuard Secure Browser for your special web surfing needs. As so often, this functionality comes with issues of its own, some being unusually obvious.

Chihuahua looking into a mirror and seeing a bulldog (BullGuard logo) there
Image credits: BullGuard, kasiagrafik, GDJ, rygle

Exploiting Bitdefender Antivirus: RCE from any website

My tour through vulnerabilities in antivirus applications continues with Bitdefender. One thing shouldn’t go unmentioned: security-wise Bitdefender Antivirus is one of the best antivirus products I’ve seen so far, at least in the areas that I looked at. The browser extensions minimize attack surface, the crypto is sane and the Safepay web browser is only suggested for online banking where its use really makes sense. Also very unusual: despite jQuery being used occasionally, the developers are aware of Cross-Site Scripting vulnerabilities and I only found one non-exploitable issue. And did I mention that reporting a vulnerability to them was a straightforward process, with immediate feedback and without any terms to be signed up front? So clearly security isn’t an afterthought which is sadly different for way too many competing products.

Bitdefender's online protection and Safepay components exploding when brought together
Image credits: Bitdefender, ImageFreak, matheod, Public Domain Vectors

But they aren’t perfect of course, or I wouldn’t be writing this post. I found a combination of seemingly small weaknesses, each of them already familiar from other antivirus products. When used together, the effect was devastating: any website could execute arbitrary code on user’s system, with the privileges of the current user (CVE-2020-8102). Without any user interaction whatsoever. From any browser, regardless of what browser extensions were installed.

Does Signal’s “secure value recovery” really work?

If you care about privacy, Signal messenger is currently the gold standard of how messenger services should be build. It provides strong end-to-end encryption, without requiring any effort on the user’s side. It gives users an easy way to validate connection integrity via another channel. Its source code is available for anybody to inspect, and it’s generally well-regarded by experts.

The strong commitment to privacy comes with some usability downsides. One particularly important one was the lack of a cloud backup – if you ever lost your phone, all your messages would be gone. The reason is obviously that it’s hard to secure this sensitive data on an untrusted server. That isn’t an issue that other apps care about, these will simply upload the data to their server unencrypted and require you to trust them. Signal is expected to do better, and they finally announced a secure way to implement this feature.

Their approach is based on something they call “secure value recovery” and relies on a PIN that is required to access data. As the PIN is only known to you, nobody else (including administrators of Signal infrastructure) should be able to access your data. This sounds great, in theory. But does that approach also work in practice?

Signal app communicating with an Intel SGX secure enclave in the cloud
Image credits: Signal, VD64992, schoolfreeware, gl367, eternaltyro

The easier way to use lunr search with Hugo

It might not be immediately obvious but my blog is a collection of static pages, generated by Hugo static site generator and updated automatically whenever I push to the GitHub repository. Back when I started using it, I had to decide on a search solution. I ruled out a third-party service (because privacy) and a server-supported one (because security). Instead, I went with lunr.js which works entirely on the client side.

Now if you want to do the same, you better don’t waste your time on the solution currently proposed by the Hugo documentation. It relies on updating the search index manually using an external tool whenever you update the content. And that tool will often deduce page addresses incorrectly, only some Hugo configurations are supported.

Eventually I realized that Hugo is perfectly capable of generating a search index by itself. I recently contributed the necessary code to the MemE theme, so by using this theme you get search capability “for free.” But in case you don’t want to switch to a new theme right now, I’ll walk you through the necessary changes.