スポンサーリンク
スポンサーリンク

【KDDIセキュリティの偽アプリ】「システム警告!」と表示されてもapkファイルをインストールしてはいけない【詐欺メッセージ】

インターネット小話スマホ基礎

SMSで「重要なお知らせ」というメッセージが届きました。

リンク先を確認してみると、「システム警告!」と表示されましたが、これは偽物。セキュリティアプリと称して、怪しいアプリをインストールさせようとするページでした。

もし、間違えて指示通りにアプリをインストールすると、本当にマルウェアが侵入してしまうので、気をつけてください。

YouTube動画でも話しています(前半後半)。

ポイント
  • お知らせメッセージを受信しても、リンクにアクセスするときは慎重に。
  • もし「システム警告!」「マルウェアが検出された」などと表示されても、ほとんどは偽物。
  • 慌てて 偽セキュリティソフトをインストールしないように気をつける。
スポンサーリンク

「auからの大事なお知らせ」で「マルウェアが検出されました」?

SMSで「auからの重要なお知らせ」として、メッセージが届きました。

システム警告

マルウェアが検出されました

「マルウェアが検出されました」と表示されるので、びっくりしますがこれは偽物です。

Googleの「メッセージ」アプリにはセキュリティ機能があるので、「スパム」として検知されていますが、利用しているメッセージアプリによっては、通常のメッセージと見分けにくい可能性があります。

偽メッセージに従っていくと、「KDDIセキュリティ」と称して、偽アプリのインストーラがダウンロードされます。

apkファイルと「提供元不明のアプリのインストール許可」

しかも、「ご丁寧に」、Androidシステムのセキュリティを解除して、インストールする手順まで、書いてあります。

これは、「提供元不明のアプリのインストール許可」の設定で、マルウェアが入りこむ一番多い経路です。

apkファイルに潜むマルウェア

ダウンロードフォルダを確認してみると、「KDDIセキュリティ.apk」ファイルが保存されています。

しかし、これをインストールしてはいけません。

ダウンロードした「KDDIセキュリティ.apk」ファイルのウイルスをチェックしてみると、しっかりマルウェアが検出されました。

出典:VirusTotal – File – c8536a5b2ccacc1c883b1cb0196c41554c8128802c36300bf62848e1a0037428

ダウンロードしただけでは実害はありませんが、間違ってインストールしてしまうと、スマホ内で動き出します。外部からの侵入を許してしまったり、データを送信・破壊してしまう危険性が高いので、絶対にしないでください。

偽サイトのURLアドレス

そもそも、怪しいリンクをタップしてはいけませんが、画面上部のアドレスバーを見ると、偽ページであることがわかります。

「この接続は安全ではありません」というのは、相手と自分の間で通信が傍受される可能性がある、という意味です。機密情報を入力すると、途中経路の端末で見られてしまうという危険ですが、アクセスするだけで危険というわけではありません。

ただ、暗号化通信のためのセキュリティ証明書を用意するのは手間がかかるので、すぐに逃げる偽サイトの場合は取得していないことが多いです。

HTMLソースから動作を確認する

この「マルウェアが検出されました」って表示されているけど、ほんとに大丈夫なの?

どうして表示が出ているのかは、ページの中身をみることで確認できます。パソコンからアクセスして、このページのHTMLソースを見てみました。

このように、JavaScriptのプログラムが丸見えで、とくにスマホの中身をチェックしたわけでもなく、適当に「2個の脅威が見つかりました」と表示させているだけのようです。

誰がアクセスしても同じメッセージなのね

偽サイトは、見せかけだけの「ハリボテ」。

よく見るとたくさんの粗がある。

偽サイトで記録されたCookie

ブラウザにどんなCookieが記録されるのかも確認してみました。

保存されていたCookieは、全部で4項目でした。

保存されたCookie
  • __51cke__
  • __51laig__
  • __tins__21143359
  • count_download

「count_download」だけは、apkファイルをダウンロードをクリックした後に記録されていました。

4つのCookieの値を見てみます。

HTMLソースに直接 参照されているのは、count_downloadだけでした。この値がセットされていると、「My auログイン」にリダイレクトするようになっています。

つまり、一度ダウンロードしたスマホは、auの公式ページに飛ばす仕掛けになっています。

__tins__21143359

「__tins__21143359」の値だけが、長い文字列です。

%7B%22sid%22%3A%201636611960753%2C%20%22vd%22%3A%203%2C%20%22expires%22%3A%201636613777718%7D

「%##」というパターンが含まれているので、URLエンコードされた文字列のようですので、デコードします。

{"sid": 1636611960753, "vd": 3, "expires": 1636613777718}

URLエンコード・デコード| Tech-Unlimited

「sid」は、セッションID、
「expires」は、セッション有効期限 のようです。

ページ内で呼び出されている外部スクリプト「https://js.users.51.la/21143359.js」内で記録されていました。

おそらく「セッション」を記録している、つまり同一端末からのアクセスを確認しているだけだと思います。

もし、興味があればコードを読んでみて下さい。

(function() {
    var config = {
        itv: 1800000,
        url1: '//ia.51.la/go1?id=21143359',
        ekc: ''
    };
    ! function(e) {
        function t(r) {
            if (n[r]) return n[r].exports;
            var o = n[r] = {
                exports: {},
                id: r,
                loaded: !1
            };
            return e[r].call(o.exports, o, o.exports, t), o.loaded = !0, o.exports
        }
        var n = {};
        return t.m = e, t.c = n, t.p = "", t(0)
    }([function(e, t, n) {
        "use strict";

        function r() {
            var e = void 0,
                t = /id=(\d+)/.exec(config.url1)[1] || "";
            try {
                e = u.get("__tins__" + t)
            } catch (t) {
                e = !1
            }
            var n = e && i.isN(e.sid) && i.isN(e.expires) && g - e.sid < 18e5 ? 0 : 1,
                r = n ? 1 : e.vd + 1,
                o = n ? g : e.sid,
                c = g + 18e5;
            return u.set("__tins__" + t, s.stringify({
                sid: o,
                vd: r,
                expires: c
            }), null, "/"), [n, n ? o : u.get("__tins__" + t).sid, r]
        }

        function o() {
            var e = s.parse(s.stringify(i.extend({}, y, v))),
                t = i.obj2url(e),
                n = config.url1 + "&rt=" + g + "&" + t,
                r = new Image(1, 1);
            r.src = n
        }
        var i = n(4),
            c = n(5),
            u = n(7).store,
            s = n(6),
            a = window,
            f = a.location,
            l = a.screen,
            p = a.navigator,
            g = i.now(),
            d = !0,
            m = r(),
            v = {
                ekc: config.ekc,
                sid: m[1],
                tt: c.getMeta.tt,
                kw: c.getMeta.kw,
                cu: f.href,
                pu: c.getRef()
            },
            y = {
                rl: l.width + "*" + l.height,
                lang: p.language || p.browserLanguage,
                ct: function() {
                    var e = p.connection || p.mozConnection || p.webkitConnection || p.oConnection,
                        t = i.hasIt(p.userAgent, "mobile") && e ? e.type : "unknow";
                    return t
                }(),
                pf: function() {
                    var e = d ? 1 : 0;
                    return d = 0, e
                }(),
                ins: m[0],
                vd: m[2],
                ce: p.cookieEnabled ? 1 : 0,
                cd: l.colorDepth || l.pixelDepth,
                ds: c.getMeta.ds
            };
        o.version = "2.2.1.2", n(10)(y), o()
    }, , , , function(e, t) {
        "use strict";

        function n(e, t) {
            return void 0 !== e && e.indexOf(t) !== -1
        }

        function r(e) {
            return function(t) {
                return Object.prototype.toString.call(t) === "[object " + e + "]"
            }
        }

        function o() {
            for (var e = 0, t = {}; e < arguments.length; e++) {
                var n = arguments[e];
                for (var r in n) t[r] = n[r]
            }
            return t
        }

        function i(e) {
            return e.replace(/&/g, "~_~")
        }

        function c(e) {
            var t = "";
            for (var n in e) "" !== t && (t += "&"), t += n + "=" + a(a(i(String(e[n]))));
            return t
        }

        function u(e) {
            return e.replace(/^\s+|\s+$/g, "")
        }

        function s() {
            return +new Date
        }
        var a = encodeURIComponent,
            f = r("Object"),
            l = r("Number"),
            p = r("String"),
            g = r("Array"),
            d = r("Function"),
            m = r("RegExp");
        e.exports = {
            isO: f,
            isN: l,
            isF: d,
            isR: m,
            isS: p,
            isA: g,
            hasIt: n,
            extend: o,
            obj2url: c,
            trim: u,
            now: s
        }
    }, function(e, t, n) {
        "use strict";

        function r(e) {
            return u.getElementsByTagName(e.toLowerCase())
        }

        function o() {
            var e = "";
            try {
                e = c.top.document.referrer
            } catch (t) {
                if (c.parent) try {
                    e = c.parent.document.referrer
                } catch (t) {
                    e = ""
                }
            }
            return "" === e && (e = u.referrer), e
        }
        var i = n(4),
            c = window,
            u = c.document,
            s = function() {
                var e = r("meta"),
                    t = r("title"),
                    n = {
                        kw: "",
                        ds: ""
                    },
                    o = void 0;
                n.tt = i.trim(t.length ? t[0].innerHTML : "");
                for (var c = 0; c < e.length; c++) e[c].name && (o = e[c].name.toLowerCase(), i.hasIt("keywords", o) && (n.kw = e[c].content.slice(0, 100)), i.hasIt("description", o) && (n.ds = e[c].content.slice(0, 30)));
                return n
            }();
        e.exports = {
            getMeta: s,
            getRef: o
        }
    }, function(module, exports) {
        "use strict";
        var _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) {
            return typeof e
        } : function(e) {
            return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e
        };
        module.exports = {
            parse: function parse(sJSON) {
                return eval("(" + sJSON + ")")
            },
            stringify: function() {
                function e(o) {
                    if (null == o) return "null";
                    if ("number" == typeof o) return isFinite(o) ? o.toString() : "null";
                    if ("boolean" == typeof o) return o.toString();
                    if ("object" === ("undefined" == typeof o ? "undefined" : _typeof(o))) {
                        if ("function" == typeof o.toJSON) return e(o.toJSON());
                        if (r(o)) {
                            for (var u = "[", s = 0; s < o.length; s++) u += (s ? ", " : "") + e(o[s]);
                            return u + "]"
                        }
                        if ("[object Object]" === t.call(o)) {
                            var a = [];
                            for (var f in o) n.call(o, f) && a.push(e(f) + ": " + e(o[f]));
                            return "{" + a.join(", ") + "}"
                        }
                    }
                    return '"' + o.toString().replace(c, i) + '"'
                }
                var t = Object.prototype.toString,
                    n = Object.prototype.hasOwnProperty,
                    r = Array.isArray || function(e) {
                        return "[object Array]" === t.call(e)
                    },
                    o = {
                        '"': '\\"',
                        "\\": "\\\\",
                        "\b": "\\b",
                        "\f": "\\f",
                        "\n": "\\n",
                        "\r": "\\r",
                        "\t": "\\t"
                    },
                    i = function(e) {
                        return o[e] || "\\u" + (e.charCodeAt(0) + 65536).toString(16).substr(1)
                    },
                    c = /[\\"\u0000-\u001F\u2028\u2029]/g;
                return e
            }()
        }
    }, function(e, t, n) {
        "use strict";
        var r = n(5),
            o = n(6),
            i = {
                get: function(e) {
                    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(e).replace(/[-.+*]/g, "\\$&") + "\\s*\\=s*([^;]*).*$)|^.*$"), "$1")) || null
                },
                set: function(e, t, n, r, o, i) {
                    if (!e || /^(?:expires|max-age|path|domain|secure)$/i.test(e)) return !1;
                    var c = "";
                    if (n) switch (n.constructor) {
                        case Number:
                            c = n === 1 / 0 ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + n;
                            break;
                        case String:
                            c = "; expires=" + n;
                            break;
                        case Date:
                            c = "; expires=" + n.toUTCString()
                    }
                    return document.cookie = encodeURIComponent(e) + "=" + encodeURIComponent(t) + c + (o ? "; domain=" + o : "") + (r ? "; path=" + r : "") + (i ? "; secure" : ""), !0
                }
            },
            c = {
                get: function(e) {
                    return o.parse((r.isMobi ? window.localStorage.getItem(e) : i.get(e)) || "{}")
                },
                set: function(e, t, n, o) {
                    return r.isMobi ? window.localStorage.setItem(e, t) : i.set(e, t, n, o)
                }
            };
        e.exports = {
            cookie: i,
            store: c
        }
    }, , , function(e, t, n) {
        "use strict";
        var r = n(4),
            o = n(7);
        e.exports = function(e) {
            var t = o.store.get("__51laig__");
            t = r.isN(t) ? parseInt(t) + 1 : 1, o.cookie.set("__51cke__", config.ekc, null, "/"), e.ing = t, o.store.set("__51laig__", t, null, "/")
        }
    }]);
}());

「ドコモの重要なお知らせ」を偽装するパターンもあった

家族に聞いてみると、「ドコモの重要なお知らせ」として、同じようなメッセージが届いていたそうです。

安全なスマホでアクセスしてみると、メッセージでは「ドコモ」を騙っているわりに、アクセスしたページでは au が表示されました。

アクセスしたスマホをページ内部で選別しているのかと思って、ページのHTMLを比較してみましたが、完全に一緒です。

ドメインのトップページ

ちなみに「http://lvkfcfczio.duckdns.org/」にアクセスすると、このように中国語簡体字でエラーが表示されました。

「http://ffvsvoolhi.duckdns.org/」の方は、パソコンからアクセスすると、「?」とだけ表示されました。

不審に思って、HTMLソースを見てみると、iPhoneやAndroidなど端末の種類によって、アクセスページを振り分けるコードが書かれていました。

iPhoneで、「http://erysowzsxb.duckdns.org/」にアクセスしてみましたが、ページにアクセスできませんでした。

いずれにしても、
http://ffvsvoolhi.duckdns.org/
http://lvkfcfczio.duckdns.org/
http://erysowzsxb.duckdns.org/
と、同じドメイン「duckdns.org」で、いくつもサブドメインを作成して、偽サイトを構築しているようです。

QRコードを読み込むと、関連記事を確認できます。
【KDDIセキュリティの偽アプリ】「システム警告!」と表示されてもapkファイルをインストールしてはいけない【詐欺メッセージ】
タイトルとURLをコピーしました