about summary refs log tree commit diff
path: root/web/blog/posts
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2020-02-08T13·34+0000
committerVincent Ambo <tazjin@google.com>2020-02-08T13·34+0000
commitcc2c130352eddb78c8b690320f0a765bb77b5bf6 (patch)
treea4f1a67b38eae06f6bedaee251409f484c8957c5 /web/blog/posts
parent15b871806b5ceb0a1c6f563e02c1ef79ee761412 (diff)
feat(web/blog): Check in blog posts that I want to keep r/485
Diffstat (limited to 'web/blog/posts')
-rw-r--r--web/blog/posts/make-object-t-again.md98
-rw-r--r--web/blog/posts/nsa-zettabytes.md93
-rw-r--r--web/blog/posts/reversing-watchguard-vpn.md158
-rw-r--r--web/blog/posts/sick-in-sweden.md26
-rw-r--r--web/blog/posts/the-smu-problem.md151
5 files changed, 526 insertions, 0 deletions
diff --git a/web/blog/posts/make-object-t-again.md b/web/blog/posts/make-object-t-again.md
new file mode 100644
index 000000000000..420b57c0fde9
--- /dev/null
+++ b/web/blog/posts/make-object-t-again.md
@@ -0,0 +1,98 @@
+A few minutes ago I found myself debugging a strange Java issue related
+to Jackson, one of the most common Java JSON serialization libraries.
+
+The gist of the issue was that a short wrapper using some types from
+[Javaslang](http://www.javaslang.io/) was causing unexpected problems:
+
+```java
+public <T> Try<T> readValue(String json, TypeReference type) {
+  return Try.of(() -> objectMapper.readValue(json, type));
+}
+```
+
+The signature of this function was based on the original Jackson
+`readValue` type signature:
+
+```java
+public <T> T readValue(String content, TypeReference valueTypeRef)
+```
+
+While happily using my wrapper function I suddenly got an unexpected
+error telling me that `Object` is incompatible with the type I was
+asking Jackson to de-serialize, which got me to re-evaluate the above
+type signature again.
+
+Lets look for a second at some code that will *happily compile* if you
+are using Jackson\'s own `readValue`:
+
+```java
+// This shouldn't compile!
+Long l = objectMapper.readValue("\"foo\"", new TypeReference<String>(){});
+```
+
+As you can see there we ask Jackson to decode the JSON into a `String`
+as enclosed in the `TypeReference`, but assign the result to a `Long`.
+And it compiles. And it failes at runtime with
+`java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long`.
+Huh?
+
+Looking at the Jackson `readValue` implementation it becomes clear
+what\'s going on here:
+
+```java
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public <T> T readValue(String content, TypeReference valueTypeRef)
+    throws IOException, JsonParseException, JsonMappingException
+{
+    return (T) _readMapAndClose(/* whatever */);
+}
+```
+
+The function is parameterised over the type `T`, however the only place
+where `T` occurs in the signature is in the parameter declaration and
+the function return type. Java will happily let you use generic
+functions and types without specifying type parameters:
+
+```java
+// Compiles fine!
+final List myList = List.of(1,2,3);
+
+// Type is now myList : List<Object>
+```
+
+Meaning that those parameters default to `Object`. Now in the code above
+Jackson also explicitly casts the return value of its inner function
+call to `T`.
+
+What ends up happening is that Java infers the expected return type from
+the context of the `readValue` and then happily uses the unchecked cast
+to fit that return type. If the type hints of the context aren\'t strong
+enough we simply get `Object` back.
+
+So what\'s the fix for this? It\'s quite simple:
+
+```java
+public <T> T readValue(String content, TypeReference<T> valueTypeRef)
+```
+
+By also making the parameter appear in the `TypeReference` we \"bind\"
+`T` to the type enclosed in the type reference. The cast can then also
+safely be removed.
+
+The cherries on top of this are:
+
+1.  `@SuppressWarnings({ "rawtypes" })` explicitly disables a
+    warning that would\'ve caught this
+
+2.  the `readValue` implementation using the less powerful `Class`
+    class to carry the type parameter does this correctly: `public <T>
+    T readValue(String content, Class<T> valueType)`
+
+The big question I have about this is *why* does Jackson do it this way?
+Obviously the warning did not just appear there by chance, so somebody
+must have thought about this?
+
+If anyone knows what the reason is, I\'d be happy to hear from you.
+
+PS: Shoutout to David & Lucia for helping me not lose my sanity over
+this.
diff --git a/web/blog/posts/nsa-zettabytes.md b/web/blog/posts/nsa-zettabytes.md
new file mode 100644
index 000000000000..f8b326f2fb42
--- /dev/null
+++ b/web/blog/posts/nsa-zettabytes.md
@@ -0,0 +1,93 @@
+I've been reading a few discussions on Reddit about the new NSA data
+centre that is being built and stumbled upon [this
+post](http://www.reddit.com/r/restorethefourth/comments/1jf6cx/the_guardian_releases_another_leaked_document_nsa/cbe5hnc),
+putting its alleged storage capacity at *5 zettabytes*.
+
+That seems to be a bit much which I tried to explain to that guy, but I
+was quickly blocked by the common conspiracy argument that government
+technology is somehow far beyond the wildest dreams of us mere mortals -
+thus I wrote a very long reply that will most likely never be seen by
+anybody. Therefore I've decided to repost it here.
+
+------------------------------------------------------------------------
+
+I feel like I've entered /r/conspiracy. Please have some facts (and do
+read them!)
+
+A one terabyte SSD (I assume that\'s what you meant by flash-drive)
+would require 5000000000 of those. That is *five billion* of those flash
+drives. Can you visualise how much five billion flash-drives are?
+
+A single SSD is roughly 2cm\*13cm\*13cm with an approximate weight of
+80g. That would make 400 000 metric tons of SSDs, a weight equivalent to
+*over one thousand Boeing 747 airplanes*. Even if we assume that they
+solder the flash chips directly onto some kind of controller (which also
+weighs something), the raw material for that would be completely insane.
+
+Another visualization: If you stacked 5 billion SSDs on top of each
+other you would get an SSD tower that is a hundred thousand kilometres
+high, that is equivalent to 2,5 x the equatorial circumference of
+*Earth* or 62000 miles.
+
+The volume of those SSDs would be clocking in at 1690000000 cubic
+metres, more than the Empire State building. Are you still with me?
+
+Lets speak cost. The Samsung SSD that I assume you are referring to will
+clock in at \$600, lets assume that the NSA gets a discount when buying
+*five billion* of those and gets them at the cheap price of \$250. That
+makes 1.25 trillion dollars. That would be a significant chunk of the
+current US national debt.
+
+And all of this is just SSDs to stick into servers and storage units,
+which need a whole bunch of other equipment as well to support them -
+the cost would probably shoot up to something like 8 trillion dollars if
+they were to build this. It would with very high certainty be more than
+the annual production of SSDs (I can\'t find numbers on that
+unfortunately) and take up *slightly* more space than they have in the
+Utah data centre (assuming you\'re not going to tell me that it is in
+fact attached to an underground base that goes down to the core of the
+Earth).
+
+Lets look at the \"But the government has better technologies!\" idea.
+
+Putting aside the fact that the military *most likely* does not have a
+secret base on Mars that deals with advanced science that the rest of us
+can only dream of, and doing this under the assumption that they do have
+this base, lets assume that they build a storage chip that stores 100TB.
+This reduces the amount of needed chips to \"just\" 50 million, lets say
+they get 10 of those into a server / some kind of specialized storage
+unit and we only need 5 million of those specially engineered servers,
+with custom connectors, software, chips, storage, most likely also power
+sources and whatever - 10 million completely custom units built with
+technology that is not available to the market. Google is estimated to
+have about a million servers in total, I don\'t know exactly in how many
+data centres those are placed but numbers I heard recently said that
+it\'s about 40. When Apple assembles a new iPhone model they need
+massive factories with thousands of workers and supplies from many
+different countries, over several months, to assemble just a few million
+units for their launch month.
+
+You are seriously proposing that the NSA is better than Google and Apple
+and the rest of the tech industry, world-wide, combined at designing
+*everything* in tech, manufacturing *everything* in tech, without *any*
+information about that leaking and without *any* of the science behind
+it being known? That\'s not just insane, that\'s outright impossible.
+
+And we haven\'t even touched upon how they would route the necessary
+amounts of bandwidth (crazy insane) to save *the entire internet* into
+that data center.
+
+------------------------------------------------------------------------
+
+I\'m not saying that the NSA is not building a data center to store
+surveillance information, to have more capacity to spy on people and all
+that - I\'m merely making the point that the extent in which conspiracy
+sites say they do this vastly overestimates their actual abilities. They
+don\'t have magic available to them! Instead of making up insane figures
+like that you should focus on what we actually know about their
+operations, because using those figures in a debate with somebody who is
+responsible for this (and knows what they\'re talking about) will end
+with you being destroyed - nobody will listen to the rest of what
+you\'re saying when that happens.
+
+\"Stick to the facts\" is valid for our side as well.
diff --git a/web/blog/posts/reversing-watchguard-vpn.md b/web/blog/posts/reversing-watchguard-vpn.md
new file mode 100644
index 000000000000..1f84e9e143cf
--- /dev/null
+++ b/web/blog/posts/reversing-watchguard-vpn.md
@@ -0,0 +1,158 @@
+**Update**: WatchGuard has
+[responded](https://www.reddit.com/r/netsec/comments/5tg0f9/reverseengineering_watchguard_mobile_vpn/dds6knx/)
+to this post on Reddit. If you haven\'t read the post yet I\'d recommend
+doing that first before reading the response to have the proper context.
+
+------------------------------------------------------------------------
+
+One of my current client makes use of
+[WatchGuard](http://www.watchguard.com/help/docs/fireware/11/en-US/Content/en-US/mvpn/ssl/mvpn_ssl_client-install_c.html)
+Mobile VPN software to provide access to the internal network.
+
+Currently WatchGuard only provides clients for OS X and Windows, neither
+of which I am very fond of. In addition an OpenVPN configuration file is
+provided, but it quickly turned out that this was only a piece of the
+puzzle.
+
+The problem is that this VPN setup is secured using 2-factor
+authentication (good!), but it does not use OpenVPN\'s default
+[challenge/response](https://openvpn.net/index.php/open-source/documentation/miscellaneous/79-management-interface.html)
+functionality to negotiate the credentials.
+
+Connecting with the OpenVPN config that the website supplied caused the
+VPN server to send me a token to my phone, but I simply couldn\'t figure
+out how to supply it back to the server. In a normal challenge/response
+setting the token would be supplied as the password on the second
+authentication round, but the VPN server kept rejecting that.
+
+Other possibilities were various combinations of username&password
+(I\'ve seen a lot of those around) so I tried a whole bunch, for example
+`$password:$token` or even a `sha1(password, token)` - to no avail.
+
+At this point it was time to crank out
+[Hopper](https://www.hopperapp.com/) and see what\'s actually going on
+in the official OS X client - which uses OpenVPN under the hood!
+
+Diving into the client
+----------------------
+
+The first surprise came up right after opening the executable: It had
+debug symbols in it - and was written in Objective-C!
+
+![Debug symbols](https://i.imgur.com/EacIeXH.png)
+
+A good first step when looking at an application binary is going through
+the strings that are included in it, and the WatchGuard client had a lot
+to offer. Among the most interesting were a bunch of URIs that looked
+important:
+
+![Some URIs](https://i.imgur.com/4rg24K5.png)
+
+I started with the first one
+
+`%@?action=sslvpn_download&filename=%@&fw_password=%@&fw_username=%@`
+
+and just =curl=ed it on the VPN host, replacing the username and
+password fields with bogus data and the filename field with
+`client.wgssl` - another string in the executable that looked like a
+filename.
+
+To my surprise this endpoint immediately responded with a GZIPed file
+containing the OpenVPN config, CA certificate, and the client
+*certificate and key*, which I previously thought was only accessible
+after logging in to the web UI - oh well.
+
+The next endpoint I tried ended up being a bit more interesting still:
+
+`/?action=sslvpn_logon&fw_username=%@&fw_password=%@&style=fw_logon_progress.xsl&fw_logon_type=logon&fw_domain=Firebox-DB`
+
+Inserting the correct username and password into the query parameters
+actually triggered the process that sent a token to my phone. The
+response was a simple XML blob:
+
+``` {.example}
+<?xml version="1.0" encoding="UTF-8"?>
+<resp>
+  <action>sslvpn_logon</action>
+  <logon_status>4</logon_status>
+  <auth-domain-list>
+    <auth-domain>
+      <name>RADIUS</name>
+    </auth-domain>
+  </auth-domain-list>
+  <logon_id>441</logon_id>
+  <chaStr>Enter Your 6 Digit Passcode </chaStr>
+</resp>
+```
+
+Somewhat unsurprisingly that `chaStr` field is actually the challenge
+string displayed in the client when logging in.
+
+This was obviously going in the right direction so I proceeded to the
+procedures making use of this string. The first step was a relatively
+uninteresting function called `-[VPNController sslvpnLogon]` which
+formatted the URL, opened it and checked whether the `logon_status` was
+`4` before proceeding with the `logon_id` and `chaStr` contained in the
+response.
+
+*(Code snippets from here on are Hopper\'s pseudo-Objective-C)*
+
+![sslvpnLogon](https://i.imgur.com/KUK6MPz.png)
+
+It proceeded to the function `-[VPNController processTokenPrompt]` which
+showed the dialog window into which the user enters the token, sent it
+off to the next URL and checked the `logon_status` again:
+
+(`r12` is the reference to the `VPNController` instance, i.e. `self`).
+
+![processTokenPrompt](https://i.imgur.com/y6eYHxG.png)
+
+If the `logon_status` was `1` (apparently \"success\" here) it proceeded
+to do something quite interesting:
+
+![processTokenPrompt2](https://i.imgur.com/f5dAsHD.png)
+
+The user\'s password was overwritten with the (verified) OTP token -
+before OpenVPN had even been started!
+
+Reading a bit more of the code in the subsequent
+`-[VPNController doLogin]` method revealed that it shelled out to
+`openvpn` and enabled the management socket, which makes it possible to
+remotely control an `openvpn` process by sending it commands over TCP.
+
+It then simply sent the username and the OTP token as the credentials
+after configuring OpenVPN with the correct config file:
+
+![doLogin](https://i.imgur.com/YLxxpKD.png)
+
+... and the OpenVPN connection then succeeds.
+
+TL;DR
+-----
+
+Rather than using OpenVPN\'s built-in challenge/response mechanism, the
+WatchGuard client validates user credentials *outside* of the VPN
+connection protocol and then passes on the OTP token, which seems to be
+temporarily in a \'blessed\' state after verification, as the user\'s
+password.
+
+I didn\'t check to see how much verification of this token is performed
+(does it check the source IP against the IP that performed the challenge
+validation?), but this certainly seems like a bit of a security issue -
+considering that an attacker on the same network would, if they time the
+attack right, only need your username and 6-digit OTP token to
+authenticate.
+
+Don\'t roll your own security, folks!
+
+Bonus
+-----
+
+The whole reason why I set out to do this is so I could connect to this
+VPN from Linux, so this blog post wouldn\'t be complete without a
+solution for that.
+
+To make this process really easy I\'ve written a [little
+tool](https://github.com/tazjin/watchblob) that performs the steps
+mentioned above from the CLI and lets users know when they can
+authenticate using their OTP token.
diff --git a/web/blog/posts/sick-in-sweden.md b/web/blog/posts/sick-in-sweden.md
new file mode 100644
index 000000000000..0c43c5832d73
--- /dev/null
+++ b/web/blog/posts/sick-in-sweden.md
@@ -0,0 +1,26 @@
+I\'ve been sick more in the two years in Sweden than in the ten years
+before that.
+
+Why? I have a theory about it and after briefly discussing it with one
+of my roommates (who is experiencing the same thing) I\'d like to share
+it with you:
+
+Normally when people get sick, are coughing, have a fever and so on they
+take a few days off from work and stay at home. The reasons are twofold:
+You want to rest a bit in order to get rid of the disease and you want
+to *avoid infecting your co-workers*.
+
+In Sweden people will drag themselves into work anyways, because of a
+concept called the
+[karensdag](https://www.forsakringskassan.se/wps/portal/sjukvard/sjukskrivning_och_sjukpenning/karensdag_och_forstadagsintyg).
+The TL;DR of this is \'if you take days off sick you won\'t get paid for
+the first day, and only 80% of your salary on the remaining days\'.
+
+Many people are not willing to take that financial hit. In combination
+with Sweden\'s rather mediocre healthcare system you end up constantly
+being surrounded by sick people, not just in your own office but also on
+public transport and basically all other public places.
+
+Oh and the best thing about this? Swedish politicians [often ignore
+this](https://www.aftonbladet.se/nyheter/article10506886.ab) rule and
+just don\'t report their sick days. Nice.
diff --git a/web/blog/posts/the-smu-problem.md b/web/blog/posts/the-smu-problem.md
new file mode 100644
index 000000000000..f411e3116046
--- /dev/null
+++ b/web/blog/posts/the-smu-problem.md
@@ -0,0 +1,151 @@
+After having tested countless messaging apps over the years, being
+unsatisfied with most of them and finally getting stuck with
+[Telegram](https://telegram.org/) I have developed a little theory about
+messaging apps.
+
+SMU stands for *Security*, *Multi-Device* and *Usability*. Quite like
+the [CAP-theorem](https://en.wikipedia.org/wiki/CAP_theorem) I believe
+that you can - using current models - only solve two out of three things
+on this list. Let me elaborate what I mean by the individual points:
+
+**Security**: This is mainly about encryption of messages, not so much
+about hiding identities to third-parties. Commonly some kind of
+asymmetric encryption scheme. Verification of keys used must be possible
+for the user.
+
+**Multi-Device**: Messaging-app clients for multiple devices, with
+devices being linked to the same identifier, receiving the same messages
+and being independent of each other. A nice bonus is also an open
+protocol (like Telegram\'s) that would let people write new clients.
+
+**Usability**: Usability is a bit of a broad term, but what I mean by it
+here is handling contacts and identities. It should be easy to create
+accounts, give contact information to people and have everything just
+work in a somewhat automated fashion.
+
+Some categorisation of popular messaging apps:
+
+**SU**: Threema
+
+**MU**: Telegram, Google Hangouts, iMessage, Facebook Messenger
+
+**SM**:
+[Signal](https://gist.github.com/TheBlueMatt/d2fcfb78d29faca117f5)
+
+*Side note: The most popular messaging app - WhatsApp - only scores a
+single letter (U). This makes it completely uninteresting to me.*
+
+Let\'s talk about **SM** - which might contain the key to solving SMU.
+Two approaches are interesting here.
+
+The single key model
+--------------------
+
+In Signal there is a single identity key which can be used to register a
+device on the server. There exists a process for sharing this identity
+key from a primary device to a secondary one, so that the secondary
+device can register itself (see the link above for a description).
+
+This *almost* breaks M because there is still a dependence on a primary
+device and newly onboarded devices can not be used to onboard further
+devices. However, for lack of a better SM example I\'ll give it a pass.
+
+The other thing it obviously breaks is U as the process for setting it
+up is annoying and having to rely on the primary device is a SPOF (there
+might be a way to recover from a lost primary device, but I didn\'t find
+any information so far).
+
+The multiple key model
+----------------------
+
+In iMessage every device that a user logs into creates a new key pair
+and submits its public key to a per-account key pool. Senders fetch all
+available public keys for a recipient and encrypt to all of the keys.
+
+Devices that join can catch up on history by receiving it from other
+devices that use its public key.
+
+This *almost* solves all of SMU, but its compliance with S breaks due to
+the fact that the key pool is not auditable, and controlled by a
+third-party (Apple). How can you verify that they don\'t go and add
+another key to your pool?
+
+A possible solution
+-------------------
+
+Out of these two approaches I believe the multiple key one looks more
+promising. If there was a third-party handling the key pool but in a way
+that is verifiable, transparent and auditable that model could be used
+to solve SMU.
+
+The technology I have been thinking about for this is some kind of
+blockchain model and here\'s how I think it could work:
+
+1.  Bob installs the app and begins onboarding. The first device
+    generates its keypair, submits the public key and an account
+    creation request.
+
+2.  Bob\'s account is created on the messaging apps\' servers and a
+    unique identifier plus the fingerprint of the first device\'s public
+    key is written to the chain.
+
+3.  Alice sends a message to Bob, her device asks the messaging service
+    for Bob\'s account\'s identity and public keys. Her device verifies
+    the public key fingerprint against the one in the blockchain before
+    encrypting to it and sending the message.
+
+4.  Bob receives Alice\'s message on his first device.
+
+5.  Bob logs in to his account on a second device. The device generates
+    a key pair and sends the public key to the service, the service
+    writes it to the blockchain using its identifier.
+
+6.  The messaging service requests that Bob\'s first device signs the
+    second device\'s key and triggers a simple confirmation popup.
+
+7.  Bob confirms the second device on his first device. It signs the key
+    and writes the signature to the chain.
+
+8.  Alice sends another message, her device requests Bob\'s current keys
+    and receives the new key. It verifies that both the messaging
+    service and one of Bob\'s older devices have confirmed this key in
+    the chain. It encrypts the message to both keys and sends it on.
+
+9.  Bob receives Alice\'s message on both devices.
+
+After this the second device can request conversation history from the
+first one to synchronise old messages.
+
+Further devices added to an account can be confirmed by any of the
+devices already in the account.
+
+The messaging service could not add new keys for an account on its own
+because it does not control any of the private keys confirmed by the
+chain.
+
+In case all devices were lost, the messaging service could associate the
+account with a fresh identity in the block chain. Message history
+synchronisation would of course be impossible.
+
+Feedback welcome
+----------------
+
+I would love to hear some input on this idea, especially if anyone knows
+of an attempt to implement a similar model already. Possible attack
+vectors would also be really interesting.
+
+Until something like this comes to fruition, I\'ll continue using
+Telegram with GPG as the security layer when needed.
+
+**Update:** WhatsApp has launched an integration with the Signal guys
+and added their protocol to the official WhatsApp app. This means
+WhatsApp now firmly sits in the SU-category, but it still does not solve
+this problem.
+
+**Update 2:** Facebook Messenger has also integrated with Signal, but
+their secret chats do not support multi-device well (it is Signal
+afterall). This means it scores either SU or MU depending on which mode
+you use it in.
+
+An interesting service I have not yet evaluated properly is
+[Matrix](http://matrix.org/).