🔑

2段階認証を楽に突破しよう

2024/12/17に公開

この記事は、team411アドベントカレンダー Advent Calendar 2024の17日目の記事です。
昨日はあかあくさんの、「MO フロント編 #1」でした。

はじめに

みなさん、2段階認証は使っていますか?
2段階認証とは、IDとパスワードによる認証に加えて、別の認証を行うセキュリティ対策です。
よくあるものだと、SMS(ショートメッセージ)、電子メール、電話などで数桁程度の数字を受け取り、それを入力するという認証などがあります。

2段階認証はたいてい1分以内に終わるので、たまに行う分にはそんなに手間ではありません。
しかし、私が通ってる電気通信大学のアカウントにログインする際に2段階認証が必要なのですが、そのログイン大変だったのでどうにか楽できないかといろいろやってみました。

セッション時間が短い

私が通っている電気通信大学では、学務情報システムや、大学側で用意したLMSにアクセスするのに、
「UECアカウント」と呼ばれるアカウントでログインする必要があります。しかし、セッション期間が短かすぎて不便です。

電気通信大学統合認証のログインページ
セッション情報がブラウザに保存されず、ブラウザを閉じるともう一度ログインする必要があります。なので毎回ログインする必要があってとてもめんどくさいです。
また、一部の学内LMSではありえないほどセッション期限が短く、課題をといてメニューに戻ろうとしたらそこで再度ログインを求められるということもあり、とても不便です。

余談

電気通信大学の学務情報システムにはログアウトボタンがあるのですが、そのボタンを押してもブラウを閉じるように案内されるだけです。
意味がないボタン作らないでほしいですね...

2段階認証がめんどくさい

電気通信大学の統合認証にアクセスする際に2段階認証を利用しないといけないということになっていますが、これがめんどくさいです。
標準だとメールアドレスに6桁のワンタイムパスが送られてきてそれを入力する必要があるのですが、上記のようにすぐセッションが切れて何回もログインする必要があるので、手間です。

1日に14通も来た2段階認証のメール

楽をする方法

こんなの毎回やってられないです。なのでどうにか回避する方法を考えました。

学内ネットワークから接続する

VPN等を使って学内からの接続にすれば2段階認証をパスすることができます。
しかし、それには次のような問題点がありました。

  1. L2TP/IPsecしか対応していない
    学内VPNで無料で使えるのはL2TP/IPsecのみですが、これはちょっと古いプロトコルです。
    その証拠に、Android12以降の端末で新しくL2TP/IPsecの接続設定を作成できなくなりました。
  2. 学内VPNは数十分で切断される
  3. 関係ないトラフィックも大学に流すのはなんか嫌
  4. いちいちVPNオンオフするのめんどい
    以上のような理由があって、学内ネットワークから接続するのは諦めました。
    幸い、電気通信大学の2段階認証には学内接続とメール以外に、TOTPが用意されているので、それを使ってみることにしました。

TOTPを使う

TOTPとは、Time-based One-time Passwordのことで、時間とシークレットキーをもとに計算をすることで求められるワンタイムパスワードです。
TOTPはRFC6238で定義されています。

パスワードマネージャーを使う

iOS15以降のiCloudキーチェーンではTOTPに対応してるので、それを使うことで便利にTOTPの2段階認証を突破できます。
登録用のQRコードを標準カメラアプリもしくはパスワードアプリ(iOS18以降)で読み取ることでiCloudキーチェーンに登録することができます。


OTPパスを自動で入力してくれる

ただ、これだとChromeで使えないという問題があります。そこで、他のパスワードマネージャを使ってもいいのですが、ここでは自動で2段階認証をしてくれるChrome拡張機能を作ってみることとしました。

Chrome拡張機能を作ってみる

Chromeの拡張機能は簡単に作ることがきます。
最低限manifest.jsonとjavascriptファイルがあれば作ることができます。

extension/
├── 1st-step.js
├── 2nd-step.js
├── jsrsasign-all-min.js
├── generate-TOTP.js
└── manifest.json

https://developer.chrome.com/docs/extensions/reference/manifest#minimal-manifest

manifest.js
{
    "name": "UEC Auto Login",
    "description": "UEC Auto Login",
    "version": "0.1",
    "manifest_version": 3,
    "content_scripts": [
        {
            "matches": [
                "https://shibboleth.cc.uec.ac.jp/idp/*"
            ],
            "js": [
                "1st-step.js"
            ]
        },
      {
            "matches": [
                "https://shibboleth.cc.uec.ac.jp/mfa/*"
            ],
            "js": [
                "jsrsasign-all-min.js",
                "generate-TOTP.js",
                "2nd-step.js"
            ]
        }
    ]
}

いろいろ書いてありますが重要なのは、content_scriptsの部分です。
この部分は、開いているURLが
https://shibboleth.cc.uec.ac.jp/idp/*の時に、1st-step.jsを実行し、
https://shibboleth.cc.uec.ac.jp/mfa/*のときに、jsrsasign-all-min.js,generate-TOTP.js,2nd-step.jsを実行するようにすることを意味しています。

1st-step.json
    try{
        document.querySelector('[name="j_username"]').value="ID";
        document.querySelector('[name="j_password"]').value="password";
        document.querySelector('[name="_eventId_proceed"]').click();
        }
        catch(e){
            console.log(e);
        }

generate-TOTP.jsの中には、TOTPをを生成するコードが入っています。
今回は、この記事を参考にさせていただき、Google共有シークレットのところに自分のシークレットキーを入れました。
https://www.secioss.co.jp/blog/20180507

2nd-step.json
window.onload = function() {
    document.querySelector('[name="authcode"]').value=totp();
    document.querySelector('[name="login"]').click();
  };

Google Chromeでchrome://extensions/を開き、右上のデベロッパーモードをONにし、左上のパッケージ化されていない拡張機能を読み込むで実際に作った拡張機能を利用することができます。

このように動作しました

最後に

2段階認証は不正ログインを防ぐ上では重要な要素ですが、さすがに一日に何回もログインするのは大変です。今後は脆弱にならない程度に楽していこうと思います。

明日はKanaruさんの「マインクラフトで始める論理設計学」です。是非読んでみてください〜

Discussion