Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FAST 5688S] Unable to login #297

Open
bunnis opened this issue Apr 17, 2024 · 5 comments
Open

[FAST 5688S] Unable to login #297

bunnis opened this issue Apr 17, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@bunnis
Copy link

bunnis commented Apr 17, 2024

Model information

Key Value
Model name FAST 5688S
Hardware Version 1.0
Software Version SG_SIB2_05.008

Describe the bug

I used the quickstart script. I have tried both encryptions and I receive the usual error "Request timed-out. This is mainly due to using the wrong encryption method."

To Reproduce

Steps to reproduce the behavior:

  1. Copy the quickstart script. Fill out the necessary details
  2. Run it, observe error
  3. Change encryption method to MD5
  4. Run it, observe error

Expected behavior

Login would be succesfull and script would print additional inforamtion

Screenshots

If applicable, add screenshots to help explain your problem.

Additional context

This device is not supported in your page, however I would be happy to work with you to make it supported. I suspect the encryption is sha1 because of the following payload when logging in (Note the ha1 field)

session={"req_id":80,"sess_id":1605671195,"basic":false,"user":"admin","dataModel":{"name":"Internal","nss":[{"name":"gtw","uri":"http://sagemcom.com/gateway-data"}]},"ha1":"REDACTED","nonce":"1890188387"}'

Running $.xmo.getValuesTree("Device/DeviceInfo") yields:

$.xmo.getValuesTree("Device/DeviceInfo")
{
    "DeviceInfo": {
        "DeviceCategory": "",
        "Manufacturer": "Sagemcom",
        "ManufacturerOUI": "001556",
        "ModelName": "SIB2",
        "ModelNumber": "Fast5688s_Sunrise",
        "Description": "",
        "ProductClass": "FAST5688s",
        "SerialNumber": "REDACTED",
        "HardwareVersion": "1.0",
        "SoftwareVersion": "SG_SIB2_05.008",
        "AdditionalHardwareVersion": "1.0",
        "AdditionalSoftwareVersion": "",
        "ExternalFirmwareVersion": "SG_SIB2_05.008",
        "InternalFirmwareVersion": "F5688s_RC5_v5.0.71",
        "GUIFirmwareVersion": "",
        "GUIAPIVersion": "",
        "ProvisioningCode": "LM-PONA0000004288.120",
        "UpTime": 598238,
        "FirstUseDate": "2021-01-29T12:58:28+0100",
        "MACAddress": "REDACTED",
        "Mode": "GW",
        "Country": "fr",
        "RebootCount": 33,
        "NodesToRestore": "",
        "VendorConfigFiles": [
            {
                "uid": 1,
                "Alias": "DEVICE_CONFIG",
                "Name": "device.cfg",
                "Version": "",
                "Date": "1-01-01T01:00:00+0100",
                "Description": "Gateway device configuration",
                "UseForBackupRestore": false
            }
        ],
        "MemoryStatus": {
            "Total": 457276,
            "Free": 137444
        },
        "TemperatureStatus": {
            "TemperatureSensors": []
        },
        "NetworkProperties": {
            "MaxTCPWindowSize": 0,
            "TCPImplementation": "",
            "EthernetWanType": "XGS\n"
        },
        "RouterName": "Sunrise_Wi-Fi_REDACTED",
        "RebootStatus": 0,
        "ResetStatus": 0,
        "UpdateStatus": 0,
        "SNMP": false,
        "FirstConnection": false,
        "SimpleLogs": {
            "SystemLog": "",
            "FirewallLog": "",
            "CallLog": ""
        },
        "BuildDate": "2023-07-11T20:51:02+0200",
        "SpecVersion": "1.0",
        "CLID": "",
        "FlushDeviceLog": false,
        "Processors": [],
        "VendorLogFiles": [
            {
                "uid": 1,
                "Alias": "operator_log_X",
                "Name": "",
                "MaximumSize": 0,
                "Persistent": false,
                "LogData": "",
                "DiagnosticState": "NONE",
                "ReverseChronological": true
            }
        ],
        "ProxierInfo": {
            "ManufacturerOUI": "",
            "ProductClass": "",
            "SerialNumber": "",
            "ProxyProtocol": ""
        },
        "Locations": [],
        "APIVersion": "",
        "Logging": {
            "LogLevel": "Warning",
            "ResetLogOper": false
        },
        "BackupTimeStamp": "2024-04-11T00:47:05+0200",
        "ConfigBackupRestoreEnable": false,
        "LastBackupDate": "2024-04-11T00:47:05+0200",
        "LastRestoreDate": "1-01-01T01:00:00+0100",
        "EventLog": "",
        "BackupSoftwareVersion": "SG_SIB2_04.038",
        "BootloaderVersion": "3.12.6-sec",
        "FlashMemoryStatus": {
            "Total": 0,
            "Free": 0
        },
        "CustomerModelName": "",
        "UserConfigFiles": []
    }
}

[bug]

@pgaskin
Copy link

pgaskin commented May 3, 2024

Check if GUI_PASSWORD_SALT has a value in /gui/js/gui-core.js. If so, the _password_hash variable will need to hash password:salt rather than just password. This python library doesn't appear to handle that possibility.

Also see if there's another key like GUI_ACTIVATE_SHA512ENCODE_OPT defined in that same file. At least based on the code from the F5689E on GUI 7.3.28, this would mean SHA512 is used if 1, and MD5 otherwise.

@bunnis
Copy link
Author

bunnis commented May 3, 2024

GUI_PASSWORD_SALT and GUI_ACTIVATE_SHA512ENCODE_OPT don't exist in /gui/js/gui-core.js. Looking for SHA, PASS, SALT in this file yields 0 results.

I see some functions and variables with password in file gui/js/gui-api.js

The file is actually quite small:

/*!
 * Copyright : (C) 2008,2009 SAGEM Communications - URD2
 *
 * This JavaScript file is the property of Sagem Communications
 * and may not be copied or used without prior written consent.
 *
 * vim: set fileencoding=utf-8
 */
jQuery.gui = {};
jQuery.gui.api = {};
jQuery.gui.opt = {
    GUI_VERSION_OPT: "0.1",
    GUI_LANGUAGES_OPT: "en:fr",
    GUI_DEFAULT_DATAMODEL_OPT: "gtw",
    GUI_DEFAULT_LANG_OPT: "fr",
    GUI_I18N_CGI_OPT: false,
    GUI_SAVE_LOGIN_OPT: true,
    XMO_REMOTE_HOST: "",
    GUI_AJAX_TIMEOUT_OPT: 30,
    GUI_ACTIVATE_GUI_CONSOLE_OPT: false,
};
(function (b, a) {
    a.i18n = b.extend(
        {},
        {
            files: [],
            add: function (c) {
                this.files.push.apply(this.files, arguments);
            },
            load: function (f, e) {
                var c = function (j) {
                    var g = j.catalog;
                    for (var h in g) {
                        if (g.hasOwnProperty(h)) {
                            a.i18n[h] = g[h];
                        }
                    }
                };
                for (i = 0; i < this.files.length; i++) {
                    var d = this.files[i];
                    if (e !== undefined) {
                        d = d.replace(/%P/g, e);
                    }
                    d = d.replace(/%L/g, f);
                    b.ajax({ async: false, type: "GET", url: d, success: c, dataType: "json" });
                }
            },
            msg: function (f, d) {
                var e = this[f];
                if (e !== undefined) {
                    var c = arguments;
                    if (c.length > 1) {
                        c[0] = e;
                        return b.sprintf.apply(b, c);
                    } else {
                        return e;
                    }
                } else {
                    return b.sprintf(this.GUI_UNDEFINED_I18N_MSG, f);
                }
            },
            alert: function (e, d) {
                var c = arguments;
                c[0] = this.msg(e);
                a.alert.apply(a, c);
            },
        }
    );
    b.fn.guiTranslate = function () {
        return this.each(function (c) {
            b(this)
                .find("*[xmsg]")
                .each(function (d) {
                    var e = b(this);
                    e.html(a.i18n.msg(e.attr("xmsg")));
                })
                .end()
                .find("*[xtitle]")
                .each(function (d) {
                    var e = b(this);
                    e.attr("title", a.i18n.msg(e.attr("xtitle")));
                })
                .end()
                .find("*[xhref]")
                .each(function (d) {
                    var e = b(this);
                    e.attr("href", a.i18n.msg(e.attr("xhref")));
                })
                .end()
                .find("*[xvalue]")
                .each(function (d) {
                    var e = b(this);
                    e.attr("value", a.i18n.msg(e.attr("xvalue")));
                });
        });
    };
    b.extend(a.i18n, { GUI_UNDEFINED_I18N_MSG: "Undefined (%s)" });
})(jQuery, jQuery.gui);
(function (b, a) {
    b.extend(
        a,
        {
            INTMIN: -2147483648,
            INTMAX: 2147483647,
            UINTMIN: 0,
            UINTMAX: 4294967295,
            cnf: function (c) {
                c.forceExtend = true;
                c.isGuiConf = true;
                return c;
            },
            array: function (d, c) {
                if (arguments.length === 1 && a.isArray(d)) {
                    c = d;
                    d = null;
                }
                c.forceExtend = true;
                c.isGuiArray = true;
                c.elementConf = a.cnf(d);
                c.compareElement = function (f, e) {
                    return e.id === f.id;
                };
                return c;
            },
            max: function (d, c) {
                return d > c ? d : c;
            },
            min: function (d, c) {
                return d < c ? d : c;
            },
            url: function (c) {
                return c === undefined ? "" : 'url("/' + a.opt.GUI_VERSION_OPT + "/" + c + '")';
            },
            slice: function (f, j, d) {
                var e = [],
                    h = arguments.length;
                if (d !== undefined && d < h) {
                    h = d;
                }
                for (var g = j; g < h; g++) {
                    var c = f[g];
                    if (a.isArray(c)) {
                        e = e.concat(c);
                    } else {
                        e.push(c);
                    }
                }
                return e;
            },
            concat: function () {
                var d = [],
                    f = arguments.length;
                for (var e = 0; e < f; e++) {
                    var c = arguments[e];
                    if (a.isArray(c)) {
                        d = d.concat(c);
                    } else {
                        d.push(c);
                    }
                }
                return d;
            },
            typeOf: function (d) {
                var c = typeof d;
                if (c === "object") {
                    if (d) {
                        if (typeof d.length === "number" && !d.propertyIsEnumerable("length") && typeof d.splice === "function") {
                            c = "array";
                        }
                    } else {
                        c = "null";
                    }
                }
                return c;
            },
            isNull: function (c) {
                return this.typeOf(c) === "null";
            },
            isString: function (c) {
                return this.typeOf(c) === "string";
            },
            isNumber: function (c) {
                return this.typeOf(c) === "number" && !isNaN(c);
            },
            isBoolean: function (c) {
                return this.typeOf(c) === "boolean";
            },
            isArray: function (c) {
                return this.typeOf(c) === "array";
            },
            isObject: function (d, c) {
                return this.typeOf(d) === "object" && (c === undefined || d.constructor === c);
            },
            isFunction: function (c) {
                return this.typeOf(c) === "function";
            },
            dump: function (c) {},
            callTrace: function (c, d) {},
            getMsg: function (c, d) {
                if (a.isObject(c)) {
                    d = c.msg;
                    c = c.type;
                }
                if (c === "user") {
                    return d;
                } else {
                    var e = a.messages[c];
                    if (e !== undefined && a.isString(e[d])) {
                        return e[d];
                    } else {
                        return a.messages.error.unknownMsg;
                    }
                }
            },
            alert: function (d, c) {
                alert(b.sprintf.apply(b, arguments));
            },
            messages: {
                error: { unknownMsg: "Unknown GUI message !", noLoginForm: "You must define a login form !", noRefreshPage: "You must define a refresh function" },
                warning: {},
                info: { loading: "Loading '%s'. Please wait..." },
                label: {},
            },
            pathValue: function (g, f, d) {
                var e = f.split(".");
                var h = g;
                while (e.length) {
                    for (var c in h) {
                        if (c === e[0]) {
                            if (e.length === 1) {
                                if (d !== undefined) {
                                    h[c] = d;
                                    return;
                                } else {
                                    return h[c];
                                }
                            }
                            h = h[c];
                            break;
                        }
                    }
                    e.shift();
                }
            },
            uiNamespace: "gui",
            uiWidget: function (e) {
                var j = { uiClasses: "", prototype: {}, widgetDef: { setter: "", getter: "", getterSetter: "" } },
                    k,
                    h,
                    d,
                    c = function (o, p) {
                        var l,
                            n = { setter: "", getter: "", getterSetter: "" };
                        for (l in n) {
                            if (n.hasOwnProperty(l)) {
                                n[l] = o[l] + (p[l] ? " " + p[l] : "");
                            }
                        }
                        return n;
                    };
                for (var f = 1; b.isFunction(arguments[f]); f++) {
                    b.extend(j.prototype, arguments[f].prototype);
                    if (j.uiClasses) {
                        j.uiClasses += " ";
                    }
                    j.uiClasses += arguments[f].uiClasses;
                    d = c(j.widgetDef, arguments[f].widgetDef);
                    b.extend(j.widgetDef, arguments[f].widgetDef, d);
                }
                h = arguments[f + 1];
                k = arguments[f];
                b.widget(this.uiNamespace + "." + e, b.extend(j.prototype, h));
                var g = b[this.uiNamespace][e];
                if (j.uiClasses) {
                    g.uiClasses = j.uiClasses + " " + e;
                } else {
                    g.uiClasses = e;
                }
                d = c(g, j.widgetDef);
                d = c(d, k);
                g.widgetDef = b.extend(j.widgetDef, k, d);
                b.extend(g, g.widgetDef);
            },
            access: function (c, d) {
                if (d.check === undefined) {
                    d.check = function (e) {
                        return true;
                    };
                }
                b.fn[c] = function (e) {
                    if (e !== undefined) {
                        if (d.check(e)) {
                            return this.each(function (g) {
                                if (this.gui && b.isFunction(this.gui[d.set])) {
                                    this.gui[d.set](e);
                                }
                            });
                        } else {
                            return this;
                        }
                    } else {
                        if (this.length === 1) {
                            var f = this.get(0);
                            if (f.gui && b.isFunction(f.gui[d.get])) {
                                return f.gui[d.get]();
                            }
                        }
                    }
                };
            },
            formatTime: function (k, e, f) {
                var n = Math.floor(k / 86400),
                    j = Math.floor(k / 3600) % 24,
                    c = Math.floor(k / 60) % 60,
                    g = k % 60,
                    l;
                if (n > 0) {
                    l = f.replace("%j", String(n)).replace("%H", b.sprintf("%02d", j)).replace("%M", b.sprintf("%02d", c)).replace("%S", b.sprintf("%02d", g));
                } else {
                    l = e.replace("%H", b.sprintf("%02d", j)).replace("%M", b.sprintf("%02d", c)).replace("%S", b.sprintf("%02d", g));
                }
                return l;
            },
        },
        {
            itemPath: [],
            init: function (d) {
                if (this.isString(d)) {
                    d = { language: arguments[0], dataModel: arguments[1] };
                }
                var e = b.extend({ language: this.opt.GUI_DEFAULT_LANG_OPT, dataModel: this.opt.GUI_DEFAULT_DATAMODEL_OPT, refreshPage: true }, d);
                this.dataModel = this.dataModels[e.dataModel];
                this.defaultClient = new this.api.Client();
                if (e.language !== null) {
                    var g = b.cookie("lang", { path: "/" }) || e.language;
                    if (g) {
                        this.setLanguage(g, e.refreshPage);
                    } else {
                        if (navigator.userLanguage) {
                            this.setLanguage(navigator.userLanguage, e.refreshPage);
                        } else {
                            if (navigator.language) {
                                this.setLanguage(navigator.language, e.refreshPage);
                            } else {
                                this.setLanguage(e.refreshPage);
                            }
                        }
                    }
                }
                var c = this,
                    f = window.location.search.slice(1, window.location.search.length).split("&");
                b.each(f, function () {
                    var h = this.split("=");
                    if (h[0] === "item") {
                        c.itemPath = h[1].split("/");
                    }
                });
            },
            dataModels: [],
            dataModel: null,
            languages: [],
            language: null,
            setLanguage: function (d, c) {
                if (!a.isString(d)) {
                    c = d;
                    d = undefined;
                }
                var e = this.languages[0];
                for (i = 0; i < this.languages.length; i++) {
                    if (d === this.languages[i].lang) {
                        e = this.languages[i];
                        break;
                    }
                }
                c = (c === undefined ? true : c) && this.language && this.language.lang !== e.lang;
                b.cookie("lang", e.lang, { path: "/", expires: 365 });
                if (this.language === null || this.language.lang !== e.lang) {
                    this.i18n.load(e.lang);
                }
                this.language = e;
                if (c) {
                    a.refreshPage();
                }
            },
            openLoginForm: function () {},
            refreshPage: function () {
                a.i18n.alert("noRefreshPage");
            },
        }
    );
    b.ajaxSetup({ timeout: a.opt.GUI_AJAX_TIMEOUT_OPT * 1000 });
    a.loadURL = function (d, c) {
        if (!a.isBoolean(d)) {
            c = d;
            d = true;
        }
        if (c !== undefined && !a.isString(c)) {
            c = b(c).attr("url");
        }
        return this.each(function (e) {
            var g = this;
            var f = c;
            if (f === undefined) {
                f = b(this).attr("url");
            }
            if (f === undefined) {
                f = this.id.toLowerCase() + ".gtpl";
            }
            if (a.opt.GUI_I18N_CGI_OPT) {
                f = "tpl/" + a.language.lang + "/" + f;
            } else {
                f = "tpl/src/" + f;
            }
            b(g).html("<div class='pageLoader'/>");
            b.ajax({
                async: d,
                url: f,
                success: function (h) {
                    a.currentTarget = g;
                    if (a.opt.GUI_I18N_CGI_OPT) {
                        b(g).html(h);
                    } else {
                        var j = '<script type="text/javascript">jQuery(function($){$($.gui.currentTarget).guiTranslate();});</script>';
                        b(g).html(j + h);
                    }
                    a.currentTarget = undefined;
                },
                error: function (h, j, k) {
                    b(g).html("<div id='errorBox'><div id='errorMsg'>" + a.i18n.msg("ERROR_TPL_LABEL") + "</div></div>");
                },
            });
        });
    };
    jQuery.fn.guiLoadURL = a.loadURL;
    b.fn.guiResize = function (d, c) {
        if (b.browser.msie && b.browser.version < 7) {
            this.each(function (g) {
                var l = null;
                var k = null;
                if (d !== undefined) {
                    var j = b(this).css("left");
                    var f = b(this).css("right");
                    if (j !== "auto" && f !== "auto") {
                        l = d - (Number(j.replace("px", "")) + Number(f.replace("px", "")));
                        b(this).width(l);
                    }
                }
                if (c !== undefined) {
                    var h = b(this).css("top");
                    var e = b(this).css("bottom");
                    if (h !== "auto" && e !== "auto") {
                        k = c - (Number(h.replace("px", "")) + Number(e.replace("px", "")));
                        b(this).height(k);
                    }
                }
                if (l !== null || k !== null) {
                    b(this).children("div").guiResize(l, k);
                }
            });
        }
        return this;
    };
    a.isConf = function (c) {
        return a.isObject(c) && c.isGuiConf;
    };
    a.isConfArray = function (c) {
        return a.isArray(c) && c.isGuiArray;
    };
    a.extendFromDiv = function (d, f) {
        if (f) {
            var e = function (k) {
                if (k !== undefined) {
                    var g = b(f).attr(c);
                    var h = b(f).children("div." + c + ", div#" + c);
                    if (g === undefined && h.length === 1) {
                        g = b(h).text();
                    }
                    var j = a.typeOf(k);
                    if (k === null) {
                        if (h.length) {
                            d[c] = h;
                        } else {
                            if (typeof g === "string") {
                                d[c] = g;
                            }
                        }
                    } else {
                        if (j === "string") {
                            if (h.length) {
                                d[c] = h.html();
                            } else {
                                if (typeof g === "string") {
                                    d[c] = g;
                                } else {
                                    if (c === "text" && d.text.length === 0) {
                                        d.text = b(f).text();
                                    }
                                }
                            }
                        } else {
                            if (j === "boolean") {
                                if (typeof g === "string") {
                                    if (g.toLowerCase() === "true") {
                                        d[c] = true;
                                    } else {
                                        if (g.toLowerCase() === "false") {
                                            d[c] = false;
                                        } else {
                                            d[c] = Boolean(g);
                                        }
                                    }
                                }
                            } else {
                                if (j === "number") {
                                    if (typeof g === "string") {
                                        d[c] = Number(g);
                                    }
                                } else {
                                    if (a.isConf(k)) {
                                        if (h.length === 1) {
                                            a.extendFromDiv(d[c], h);
                                        }
                                    } else {
                                        if (a.isConfArray(k)) {
                                            b(h)
                                                .children("div")
                                                .each(function (m) {
                                                    var l,
                                                        n = k.length;
                                                    for (l = 0; l < n; l++) {
                                                        if (k.compareElement(this, k[l])) {
                                                            a.extendFromDiv(k[l], this);
                                                            break;
                                                        }
                                                    }
                                                    if (l === n) {
                                                        k.push(a.extend(this, k.elementConf));
                                                    }
                                                });
                                        }
                                    }
                                }
                            }
                        }
                    }
                    h.remove();
                }
            };
            for (var c in d) {
                if (d.hasOwnProperty(c)) {
                    e(d[c]);
                }
            }
        }
        return d;
    };
    a.extend = function (d) {
        var r = [],
            l = arguments.length,
            u;
        var q, s;
        var n, m, h;
        for (n = 1; n < l; n++) {
            s = a.typeOf((u = arguments[n]));
            if (s === "object") {
                r.push(u);
            } else {
                if (s === "array") {
                    for (m in u) {
                        if (u.hasOwnProperty(m)) {
                            q = u[m];
                            if (a.typeOf(q) === "object") {
                                r.push(q);
                            }
                        }
                    }
                }
            }
        }
        q = a.isConf(this) ? this : a.cnf({});
        for (n in r) {
            if (r.hasOwnProperty(n)) {
                u = r[n];
                for (var c in u) {
                    if (u.hasOwnProperty(c)) {
                        var g = u[c];
                        s = a.typeOf(g);
                        if (a.isConf(g)) {
                            if (a.isConf(q[c])) {
                                a.extend.call(q[c], null, g);
                            } else {
                                if (q[c] === undefined) {
                                    q[c] = a.extend(null, g);
                                }
                            }
                        } else {
                            if (a.isArray(g)) {
                                var o = q[c];
                                var f = 0,
                                    p,
                                    t;
                                if (a.isArray(o)) {
                                    f = o.length;
                                    p = o.elementConf;
                                    t = o.compareElement;
                                } else {
                                    if (o === undefined) {
                                        p = g.elementConf;
                                        t = g.compareElement;
                                        o = q[c] = a.array(p, []);
                                        o.compareElement = t;
                                    }
                                }
                                var e = g.length;
                                for (m = 0; m < e; m++) {
                                    for (h = 0; h < f; h++) {
                                        if (t(o[h], g[m])) {
                                            a.extend.call(o[h], null, g[m]);
                                            break;
                                        }
                                    }
                                    if (h === f && a.typeOf(g[m]) === "object") {
                                        o.push(a.extend(null, p, g[m]));
                                    }
                                }
                            } else {
                                if (s === "null") {
                                    q[c] = null;
                                } else {
                                    if (c !== "isGuiConfig" && g !== undefined) {
                                        q[c] = g;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return a.extendFromDiv(q, d);
    };
    b.fn.guiCookie = function (c, e) {
        if (e) {
            return this.each(function (h) {
                if (this.id) {
                    var g = this.id + "." + c;
                    b.cookie(g, e);
                }
            });
        } else {
            if (this.length === 1) {
                var f = this.get(0);
                if (f.id) {
                    var d = f.id + "." + c;
                    return b.cookie(d);
                }
            }
        }
    };
    b.QueryString = function (e) {
        var g,
            c = null,
            d,
            j = {};
        if (e === undefined) {
            c = window.location.search.substr(1);
        } else {
            d = e.indexOf("?");
            if (d === -1) {
                return {};
            }
            c = e.substring(d + 1);
        }
        g = c.split("&");
        if (g === "") {
            return {};
        }
        for (var f = 0; f < g.length; ++f) {
            var h = g[f].split("=");
            if (h.length !== 2) {
                continue;
            }
            j[h[0]] = decodeURIComponent(h[1].replace(/\+/g, " "));
        }
        return j;
    };
    a.fval = function (c) {
        if (c !== undefined) {
            if (typeof c === "string") {
                if (!(c.indexOf("http") === 0)) {
                    c = b("<div>").text(c).html();
                }
            } else {
                b.each(c, function (d, e) {
                    c[d] = a.fval(e);
                });
            }
        }
        return c;
    };
    a.fec = function (c) {
        if (c !== undefined && typeof c === "string") {
            c = c.replace(/`|"|;|\$\(/g, "");
        }
        return c;
    };
})(jQuery, jQuery.gui);
if (!window.console) {
    var console = {};
}
$.each(["log", "error", "warn", "info", "debug", "assert", "count", "dir", "dirxml", "trace", "group", "groupEnd", "time", "timeEnd", "profile", "profileEnd"], function (a, b) {
    if (!console[b]) {
        console[b] = function () {};
    }
});
(function (a) {
    a.languages.push({ lang: "en", name: "English" });
})(jQuery.gui);
(function (a) {
    a.languages.push({ lang: "fr", name: "Français" });
})(jQuery.gui);
jQuery.gui.dataModels.gtw = { name: "Internal", nss: [{ name: "gtw", uri: "http://sagemcom.com/gateway-data" }] };
jQuery.gui.dataModels.push(jQuery.gui.dataModels.gtw);
jQuery.gui.dataModels.tr181 = { name: "TR-181", nss: [{ name: "tr181", uri: "http://sagemcom.com/tr181-data" }] };
jQuery.gui.dataModels.push(jQuery.gui.dataModels.tr181);
jQuery.gui.dataModels.tr181sunrise = {
    name: "TR-181 Sunrise",
    nss: [
        { name: "tr181", uri: "http://sagemcom.com/tr181-data" },
        { name: "tr181sunrise", uri: "http://sagemcom.com/tr181sunrise-data" },
    ],
};
jQuery.gui.dataModels.push(jQuery.gui.dataModels.tr181sunrise);

@pgaskin
Copy link

pgaskin commented May 3, 2024

Hmm, that seems pretty different than the HH4000 and GH4000, which are the only ones I've personally used. There's no hashEncoder function in gui-core in yours.

I'd probably look at gui-api.js and search for :JSON:/cgi/json-req, and see what the code to build the auth token looks like there.

Some relevant snippets from the GH4000:

n=c.random(a.UINTMAX);lNonce="";if(g._nonce!=undefined&&g._nonce!=""){lNonce=g._nonce}g._ha1=a.hashEncoder(g.user+":"+lNonce+":"+g._hashEncoderPass);e=a.hashEncoder(g._ha1+":"+f+":"+n+":JSON:/cgi/json-req");c.extend(t.request,{cnonce:n,"auth-key":e})
if(a.opt.GUI_PASSWORD_SALT!==""){l._hashEncoderPass=a.hashEncoder(k+":"+a.opt.GUI_PASSWORD_SALT)}else{l._hashEncoderPass=a.hashEncoder(k)}}l._nonce="";l._ha1=a.hashEncoder(l.user+"::"+l._hashEncoderPass)

Another observation: GUI_VERSION_OPT is pretty old...

@bunnis
Copy link
Author

bunnis commented May 11, 2024

Jquery library used is from April 2012

// jQuery Form Plugin
//version: 3.09 (16-APR-2012)
// @requires jQuery v1.3.2 or later

With your hints I was able to figure out the way the password encryption is done. I have created a simple HTML page that will perform this math, basically its just a bunch of md5's together with a nounce. The request payload will then look like this, relevant fields are cnonce and auth-key.

{"request":{"id":0,"session-id":"0","priority":true,"actions":[{"id":0,"method":"logIn","parameters":{"user":"admin","persistent":"true","session-options":{"nss":[{"name":"gtw","uri":"http://sagemcom.com/gateway-data"}],"language":"ident","context-flags":{"get-content-name":true,"local-time":true},"capability-depth":2,"capability-flags":{"name":true,"default-value":false,"restriction":true,"description":false},"time-format":"ISO_8601"}}}],"cnonce":3557024231,"auth-key":"8e84346a12415de0a87c85851c8bfa77"}}

The HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MD5 Hash Example</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.18.0/js/md5.min.js"></script>
</head>
<body>
    <h1>MD5 Hash Calculation</h1>
    <form id="hashForm">
        <label for="username">User:</label>
        <input type="text" id="username" name="username" required>
        <label for="md5password">Password:</label>
        <input type="text" id="md5password" name="md5password" required>
        <button type="button" onclick="calculateHash()">Calculate Hash</button>
    </form>
    <p>Nonce: <span id="nonce"></span></p>
    <p>Random Number (n): <span id="randomNumber"></span></p>
    <p>Hash (e): <span id="hashValue"></span></p>

    <script>
        function calculateHash() {
            const UINTMAX = 4294967295;

            function random(max) {
                return Math.floor(Math.random() * max);
            }

            const user = document.getElementById('username').value;
            const md5Pass = md5(document.getElementById('md5password').value);
            let n = random(UINTMAX);
			//n=3557024231
            let f = 0;
            let lNonce = "";                // Initialize lNonce if needed

            function hex_md5(input) {
                return md5(input);
            }

            let ha1 = hex_md5(user + ":" + lNonce + ":" + md5Pass);
            let e = hex_md5(ha1 + ":" + f + ":" + n + ":JSON:/cgi/json-req");

            // Output to HTML
           $('#nonce').text(n);
            document.getElementById('randomNumber').textContent = n;
            document.getElementById('hashValue').textContent = e;
        }
    </script>
</body>
</html>

@iMicknl
Copy link
Owner

iMicknl commented Jun 2, 2024

Great research all!

@bunnis would you be open to do a PR to add this to this repository? Otherwise I am happy to have a look, but would be great to understand in more detail what is currently missing.

@iMicknl iMicknl added the bug Something isn't working label Jun 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants