I've got mail

Recently I've started to notice that I'm getting my mail notifications late, I used to get the inbox directly with the atom.xml that Gmail provides and be notified by checking my RSS feed, the problem is that this only gets updated every 20 minutes or so.

The obvious solution would be to have a mail app that is constantly updating the inbox and getting notified that way, but this is costly for my phone, which is kind of old and not in the best debloated shape.

So for this I wanted to make something like I've already done previously, which is a way to relay this to a server process and be notified via Telegram.

IMAP

Internet Message Access Protocol is one of the two standard protocols for retrieving mails from a remote mail server. Being the most used one I chose it over POP3, but this could have been done with POP3 as well.

It works like normal application layers old internet protocols such as SMTP, in the way that the session is managed via plain text querying commands and retrieving the results.

Programming the solution

For my purposes, I only wanted to get the latest unread mails, so the only query that I need to do is to fetch the mails on the inbox. However, being that this is a little more complicated than SMTP, this time I will be using an external library, so no hardcoding commands this time.

I used NodeJs for this and used the node-imap library. The code for this is kind of ugly as it's event-based so it doesn't follow a sequential flow.

Basically what I did was:

  1. Establish a connection
  2. Open the inbox
  3. Fetch the messages, filtering only the headers fields SUBJECT and FROM
  4. For each message do some parsing, both of its headers as well as its metadata
  5. If the message doesn't have a \\Seen flag and hasn't already been cached, send it to Telegram
  6. Save the message to the cache
  7. Exit

You can check out the full code here.

Seeing it in action

On Telegram I've created yet another bot for this specific purpose, that way I can customize its notification sound to be the iconical "You've got mail" voice alert each time I get a new mail.

The iconical voice alert

And here's a censored screenshot of it in action:

Now I can get notified for my mails right away, without having bloat running on my phone!

Hacking my health insurance security token generation

Following up with my quest to clean my phone from apps that I was forced to install by living in a civilization that doesn't care about bloated software. This time it was the turn of my health insurance app.

I have OSDE. On there, in order to have a medical appointment, purchase discounted medications and other related actions, you MUST have installed the OSDE app, not only for presenting the card credential number, but for it to give you a "token" that generates every 5 minutes.

You show this token to the person who is taking your medical appointment or purchase, thus validating that you are authorized to do it.

OSDE App with generated token, in this case is 602 and it will be valid for 2 minutes

I don't think this seem like a particularly bad way to validate your authority to use the service, but I'd rather not have an app installed for something that could be a card. And I knew this could be circunvented because it works offline.

So here we go with the hack.

OTP

Asking to a friend about this, I realized that this app implements a cryptographic One-Time Password (OTP) just like Google Authenticator.

In short this takes a static identity seed, the current timestamp (mod by 5 minutes), and hashes it, producing a number that should guarantee the user's identity in that moment.

Knowing this, and having my phone rooted, I could grep the app's storage and find the needed seed.

After a few attempts I found what I was looking for:

$ strings /data/data/ar.com.osde.ads/databases/credencialDigitalSqlite | grep OTP
credenciales"[ ... ,\"semilla\":\"( This is it )\" ... ]"/

Matching the token

Having the seed, all I had to do was replicate the same encodings and options that the app uses.

After a few failed attempts with publicly available OTP libraries, I realized that it would be easier to decompile the app and take a look at how the app is actually hashing the seed.

As with the trains app hack, I used the jadx program and took a peek inside.

Quickly I found it:

otplib_otplib_browser__WEBPACK_IMPORTED_MODULE_4__["totp"].options = {
    digits: 3,
    step: 300,
    algorithm: 'sha256',
    createHmacSecret: function (secret, params) {
        return secret;
    }

With this I've got both the encodings and the js library used (otplib).

And finally I was able to reproduce the same token generation as the app:

const { totp } = require('otplib');

const seed = "...";

totp.options = {
    digits: 3,
    step: 300,
    algorithm: "sha256",
    createHmacSecret: function (secret, params) {
        return secret;
    }
};

console.log(totp.generate(seed));
$ node index.js
602

Minimizing the code

From previous work experience, I have had major problems relying on external cryptographic libraries. So this time I would like to not depend on otplib and have it to manually generate the token by myself.

By scrapping the otplib code and minimizing it to only do the generation for this type of token, I ended up with a compact version of it:

const { createHmac } = require("crypto");

const seed = "...";

const generateToken = (secret) => {
  const counter = Math.floor(new Date().getTime() / 300000)
    .toString(16)
    .padStart(16, "0");
  const digest = createHmac("sha256", secret)
    .update(Buffer.from(counter, "hex"))
    .digest();
  const offset = digest[digest.length - 1] & 0xf;
  const binary =
    ((digest[offset] & 0x7f) << 24) |
    ((digest[offset + 1] & 0xff) << 16) |
    ((digest[offset + 2] & 0xff) << 8) |
    (digest[offset + 3] & 0xff);
  const tokenNumber = binary % Math.pow(10, 3);
  return tokenNumber.toString().padStart(3, "0");
};

console.log(generateToken(seed));

OSDE-CLI

For the final touch I ended up adding a few optional parameters and printing extra information. This way anyone could use this "terminal version of the OSDE app", without the need to use the official one.

Running it on Termux, much faster than the OSDE app

I published it on a github repository, so anyone can use it freely.

I hope you liked this blogpost, until next time.