Codigo JS en router ClearAcess, vulnerable?

Iniciado por CloudswX, 7 Septiembre 2011, 05:26 AM

0 Miembros y 1 Visitante están viendo este tema.

CloudswX

Pues wenas gente..

Sucede que me han instalado un router wireless marca ClearAcces y para entrar a su configuracion (obvio despues de estar conectado) es necesario digitar usuario y pass los cuales son el numero serial que viene en la caja del router. Mi pregunta es la siguiente, es posible vulnerar el sistema del login (que esta hecho en JS) aprovechando alguna brecha en el codigo.

Se muy poco o casi nada de JS (solo lo suficiente para superar el reto de zona cero, jejej) por eso pegare aqui el codigo para que todos les hechen un ojo y me digan si hallan algun hueco por donde vulnerar.

/*
REQUIRES:
prototype
jQuery
Gateway
SubscriberAttribute
SubscriberLogin
SubscriberLoginReset
SubscriberLoginSession
SubscriberManagementGroups
Cookies
Branding
*/

jQuery(document).ready(function() {

    // position the ISP's logo the hard way because CSS can't handle it.
    function alignISPLogo() {
        var logoWidth = $j("#isplogo IMG").width();
        var hPos = logoWidth > $j("#isplogo").width() ? "left" : "center";
        var vPos = ((80 - $j("#isplogo IMG").height()) / 2) + "px";
        $j("#isplogo").css("background-position", hPos + " " + vPos);
        if (logoWidth > 230) {
            //
            $j("#login").css("margin-top", "80px");
            $j("#isplogo").width("598px");
        }
        $j("#isplogo IMG").remove();
    }

    $j("#isplogo IMG").load(alignISPLogo);
    if ($j("#isplogo IMG").height()) alignISPLogo();

    CA.CP.Cookies.clearAll();

    var skipSync = false;
    // http://en.wikipedia.org/wiki/Konami_Code
    // alert([38,40,38,40,37,39,37,39,66,65].inject(0, function (a,c) { return (a * 733 + c) & 0xFFFFFFFF; }));
    var skipSyncSequenceHash = 1947954279;
    var skipSyncSequenceLength = 10;

    function setSkipSync() {
        var lastChars = [];
        return function(ev) {
            lastChars.push(ev.keyCode);
            if (lastChars.length > skipSyncSequenceLength) lastChars.splice(0, 1);
            if (lastChars.length == skipSyncSequenceLength &&
                    skipSyncSequenceHash == lastChars.inject(0, function (a, c) {
                        return (a * 733 + c) & 0xFFFFFFFF;
                    })) {
                skipSync = !skipSync;
                $j("#skipSyncDisplay")[skipSync ? "show" : "hide"](true);
            }
        };
    }

    $j(document).keydown(setSkipSync());

    function log() {
        if (typeof console != 'object') return;
        if (typeof console.log != 'function') return;
        if (Prototype.Browser.Gecko || Prototype.Browser.WebKit) {
            console.log.apply(console, arguments);
        }
    }

    Object.extend(CA.CP.ErrorHandlers, {
        ligthbox: null,
        showError: function (options) {
            options = options || {};
            var box = $j("#errorMessageBox");
            box.find(".title").text(options.title || "Error"),
                    box.find(".heading").text(options.heading);
            box.find(".message").text(options.message);
            var opts = {};
            var lightbox = null;
            if (options.autoClose) {
                opts.close = function() {
                    ligthbox = null;
                };
                window.setTimeout(function () {
                    if (lightbox) lightbox.close();
                }, 5000);
            }
            lightbox = CA.CP.modalWindow(box, opts);
            this.lightbox = lightbox;
            $j("#closeErrorMessageBoxButton").unbind("click").click(function () {
                this.close();
            }.bind(this));
        },
        close: function () {
            this.lightbox.close();
            this.lightbox = null;
        },
        pageError: function (obj) {
            this.showError({
                heading:CA.CP.getResource("Password.loginErrorHeading.label"),
                message:CA.CP.getResource("Password.loginErrorMessage.label")
            });
            log(obj.statusText + "\n[HTTP Error " + obj.status + "]\n" + obj.thrownError);
        },
        clientError: function (obj) {
            this.showError({
                heading:CA.CP.getResource("Password.clientErrorHeading.label"),
                message:CA.CP.getResource("Password.clientErrorMessage.label")
            });
            log(obj.statusText + "\n[HTTP Error " + obj.status + "]");
        },
        communicationError: function () {
            this.showError({
                title:CA.CP.getResource("Password.communicationErrorTitle.label"),
                heading:CA.CP.getResource("Password.communicationErrorHeading.label"),
                message:CA.CP.getResource("Password.communicationErrorMessage.label")
            });
            log("Server connection error");
        },
        serverError: function (obj) {
            this.showError({
                title:CA.CP.getResource("Password.communicationErrorTitle.label"),
                heading:CA.CP.getResource("Password.serverErrorHeading.label"),
                message:CA.CP.getResource("Password.serverErrorMessage.label")
            });
            log(obj.statusText + "\n[HTTP Error " + obj.status + "]");
        }
    });

    var newPasswordValidator = new CA.ui.LengthValidator("#passwordEntryValidator", "#passwordEntry", {min:5,max:-1});

    function PasswordChange() {
        this.lightbox = null;
    }

    Object.extend(PasswordChange.prototype, {
        show: function() {
            var box = $j("#changePasswordBox");
            var submitPasswordChange = this.changePassword.bind(this);
            $j("#changePasswordButton").unbind("click").click(submitPasswordChange);
            $j("INPUT#passwordEntry, INPUT.confirm", box).unbind("keydown").keydown(invokeOnEnter.curry(submitPasswordChange)).val("");
            this.sessionId = CA.CP.Cookies.sessionId(); // store the session id
            CA.CP.Cookies.sessionId(null); // prevent the session from being valid
            this.lightbox = CA.CP.modalWindow(box);
            newPasswordValidator.validate();
            $j(".confirm", box).keyup();
        },

        changePassword: function() {
            var box = $j("#changePasswordBox");
            var newPassword = box.find("#passwordEntry").val();
            var confirmPassword = box.find("input.confirm").val();

            if (!newPasswordValidator.isValid()) return false;

            if (newPassword == confirmPassword) {
                var service = new CA.CP.SubscriberLogin(CA.CP.Cookies.subscriberId());
                CA.CP.Cookies.sessionId(this.sessionId); // set the session id for the request
                service.changePassword(loginForm.find(".password").val(), newPassword, {
                    complete: function(xhr) {
                        if (xhr.status < 300) {
                            passwordChangeRequired = false;
                            loginForm.find(".password").val(newPassword);
                            submit();
                            this.lightbox.close();
                        } else {
                            CA.CP.Cookies.sessionId(null); // prevent the session from being valid
                        }
                    }.bind(this),
                    on403: function() {
                        this.lightbox.close();
                        showInvalidPassword();
                    }.bind(this)
                });
            }
            return false;
        }
    });

    function ForgotPassword() {
        this.lightbox = null;
        this.service = new CA.CP.SubscriberLoginReset();
    }

    Object.extend(ForgotPassword.prototype, {
        setVisible: function() {
            var box = $j("#forgotPasswordBox");
            var all = [".instructions", ".failed", ".success", ".input"];
            var show = $A(arguments);
            var hide = all.reject(function(a) {
                return show.include(a);
            });
            show.each(function(i) {
                box.find(i).show();
            });
            hide.each(function(i) {
                box.find(i).hide();
            });
        },

        show: function() {
            this.setVisible(".instructions", ".input");
            var box = $j("#forgotPasswordBox");
            $j("INPUT.email", box).unbind("keydown").keydown(invokeOnEnter.curry(this.resetPassword.bind(this)));
            $j("#resetPasswordButton", box).show().unbind("click").click(this.resetPassword.bind(this));
            $j("#resetPasswordContinueButton", box).hide().unbind("click").click(this.close.bind(this));
            this.lightbox = CA.CP.modalWindow(box);
        },

        showResetFailed: function(cause) {
            var box = $j("#forgotPasswordBox");
            box.find(".failed .cause").text(cause);
            this.setVisible(".failed");
            $j("#resetPasswordButton").hide();
            $j("#resetPasswordContinueButton").show();
        },

        showResetSuccess: function() {
            this.setVisible(".success");
            $j("#resetPasswordButton").hide();
            $j("#resetPasswordContinueButton").show();
        },

        resetPassword: function() {
            var box = $j("#forgotPasswordBox");
            var email = box.find(".email");
            this.service.reset(email.val(), {
                success: function() {
                    this.showResetSuccess();
                }.bind(this),
                on404: function() {
                    this.showResetFailed(CA.CP.getResource("Password.resetPasswordFailed.label") + " \"" + email.val() + "\"");
                }.bind(this)
            });
            return false;
        },

        close: function() {
            this.lightbox.close();
            this.lightbox = null;
        }
    });

    var passwordChange = new PasswordChange();
    var forgotPassword = new ForgotPassword();

    var subscriberLoginSessionService = new CA.CP.SubscriberLoginSession();
    var loginForm = $j("#form-login");
    var loginProblems = $j("#login-problems");
    var passwordChangeRequired = false;

    function invokeOnEnter(callback, e) {
        switch (e.keyCode) {
            case 13: //return
                callback();
                break;
        }
    }

    $j("#passwordEntry").attr("tabindex", "20");
    $j("INPUT.login", loginForm).keydown(invokeOnEnter.curry(submit)).keyup(clearSession).each(function () {
        this.focus();
    });
    $j("INPUT.password", loginForm).keydown(invokeOnEnter.curry(submit)).keyup(clearSession);
    $j("#submitButton", loginForm).click(function () {
        if (!$j("#submitButton", loginForm).hasClass("inactive")) submit();
    });
    $j("#selectDeviceButton", loginProblems).click(submit);
    $j("#cancelButton", loginProblems).click(function () {
        loginForm.find("#submitButton, #problemlink").removeClass("inactive");
        loginForm.find("INPUT").removeAttr("disabled");
        loginProblems.find(".devicesRow").hide();
    });

    $j("#problemlink").click(function() {
        if (!$j("#problemlink", loginForm).hasClass("inactive")) {
            log("forgot password");
            forgotPassword.show();
        }
    });

    function clearSession() {
        if (currentSession &&
                currentSession.sessionId &&
                ($j(".login", loginForm).val() != currentSession.$$username ||
                        $j(".password", loginForm).val() != currentSession.$$password)) {
            CA.CP.Cookies.clearAll();
            // remove the session
            new CA.CP.SubscriberLoginSession().logout(currentSession.sessionId, {
                suppressGeneralErrorHandling: true
            });
            currentSession = null;
        }
    }

    function submit() {
        log("submit called");
        if (okToContinue()) {
            if (skipSync)    CA.CP.Cookies.hasSynced(skipSync);
            window.location = window.location.href;
        } else {
            if (currentSession) {
                onAuthenticated(currentSession);
            } else {
                var login = $j(".login", loginForm).val();
                var password = $j(".password", loginForm).val();
                subscriberLoginSessionService.login(login, password, {
                    success: function(session) {
                        log(session);
                        passwordChangeRequired = session.expired;
                        onAuthenticated(session);
                    },
                    on401: function() {
                        showInvalidPassword();
                    }
                });
            }
        }
    }

    function showResetPassword(subscriberId) {
        log("password has expired");
        CA.CP.Cookies.subscriberId(subscriberId);
        passwordChange.show();
    }

    function showInvalidPassword() {
        CA.CP.ErrorHandlers.showError({
            title:CA.CP.getResource("Password.showInvalidPasswordTitle.label"),
            heading:CA.CP.getResource("Password.showInvalidPasswordHeading.label"),
            message:CA.CP.getResource("Password.showInvalidPasswordMessage.label"),
            autoClose: true
        });
        log("invalid username / password");
    }

    function showInvalidDevice() {
        CA.CP.ErrorHandlers.showError({
            title:CA.CP.getResource("Password.deviceError.label"),
            heading:CA.CP.getResource("Password.showInvalidDeviceHeading.label"),
            message:CA.CP.getResource("Password.showInvalidDeviceMessage.label")
        });
        log("device not found");
    }

    function showDeviceBelongsToAnotherSubscriber() {
        CA.CP.ErrorHandlers.showError({
            title:CA.CP.getResource("Password.showDeviceBelongsToAnotherSubscriberTitle.label"),
            heading:CA.CP.getResource("Password.showDeviceBelongsToAnotherSubscriberHeading.label"),
            message:CA.CP.getResource("Password.showDeviceBelongsToAnotherSubscriberMessage.label")
        });
        log("device belongs to a different subscriber");
    }

    function showSubscriberHasNoDevices() {
        CA.CP.ErrorHandlers.showError({
            title:CA.CP.getResource("Password.deviceError.label"),
            heading:CA.CP.getResource("Password.showSubscriberHasNoDevicesHeading.label"),
            message:CA.CP.getResource("Password.showSubscriberHasNoDevicesMessage.label")
        });
        log("the subscriber has no devices");
    }

    function showGeneralError(status, what) {
        CA.CP.ErrorHandlers.showError({
            heading:CA.CP.getResource("Password.showGeneralErrorHeading.label"),
            message:CA.CP.getResource("Password.showGeneralErrorMessage.label")
        });
        log(status, what);
    }

    function deviceId() {
        var deviceId = null;
        if (loginProblems.find(".devicesRow").is(":visible")) {
            log("using device id from drop down");
            deviceId = loginProblems.find(".devices").val();
        } else if (queryParameters.device) {
            log("using device id from query parameters");
            deviceId = queryParameters.device;
        } else {
            log("no device context");
        }
        return deviceId;
    }

    var currentSession = null;

    function onAuthenticated(session) {
        if (currentSession != session) {
            currentSession = session;
            currentSession.$$username = $j(".login", loginForm).val();
            currentSession.$$password = $j(".password", loginForm).val();
        }

        // set credentials
        CA.CP.Cookies.sessionId(session.sessionId);
        CA.CP.Cookies.subscriberId(session.subscriberId);

        log("session id: " + CA.CP.Cookies.sessionId());

        function withManagementGroups(subscriberId, allManagementGroups, f) {
            new CA.CP.SubscriberManagementGroups(subscriberId)[allManagementGroups ? 'get' : 'getControlPanelManagementGroups']({
                success: function(managementGroups) {
                    f(managementGroups);
                },
                error: function(xhr) {
                    showGeneralError(xhr.status, CA.CP.getResource("Password.withManagementGroupsGetError.label"));
                }
            });
        }

        function setDeviceAndSubmit(deviceId, managementGroupId) {
            CA.CP.Cookies.deviceId(deviceId);
            CA.CP.Cookies.managementGroupId(managementGroupId);
            if (passwordChangeRequired) {
                showResetPassword(session.subscriberId);
            } else {
                CA.CP.Cookies.sessionId(session.sessionId);

                if (CA.CP.Language.isLanguageSet()) {
                    var settingsSubscriber = new CA.CP.SubscriberAttribute(session.subscriberId);
                    settingsSubscriber.setLocale(CA.CP.Language.getLanguage(), {});
                }
                submit();
            }
        }

        if (deviceId()) {
            withManagementGroups(session.subscriberId, false, function(managementGroups) {
                var mg = $A(managementGroups).find(function(mg) {
                    var device = deviceId().split(":");
                    var oui = device[0];
                    var sn = device[1];
                    return oui.toUpperCase() == mg.managedDevice.oui.toUpperCase()
                            && sn.toUpperCase() == mg.managedDevice.serialNumber.toUpperCase();
                });
                if (mg) {
                    setDeviceAndSubmit(mg.managedDevice.id, mg.id);
                } else {
                    /* FIX THIS WITH MANAGEMENT GROUP */
                    new CA.CP.Gateway("ouisn:" + deviceId()).getDevice({
                        success: function(device) {
                            if (device.subscriberId) {
                                if (device.subscriberId != session.subscriberId) {
                                    showDeviceBelongsToAnotherSubscriber();
                                } else {
                                    setDeviceAndSubmit(device.id);
                                }
                            } else {
                                withManagementGroups(session.subscriberId, true, function(allManagementGroups) {
                                    // need to assign this device to a SMG for this subscriber
                                    // first see if there is a SMG with a CP Provisioning ID available
                                    var cpProvisioningManagementGroup = $A(allManagementGroups).reject(function(mg) {
                                        return Object.isUndefined(mg.deviceSignature) || Object.isUndefined(mg.deviceSignature.cpProvisioningId);
                                    }).sortBy(function(mg) {
                                        return Number(mg.deviceSignature.cpProvisioningId);
                                    }).first();
                                    if (!Object.isUndefined(cpProvisioningManagementGroup)) {
                                        // found a SMG with a CP Provisioning ID
                                        // so, convert it to a management group for this managed device
                                        new CA.CP.SubscriberManagementGroup(session.subscriberId, cpProvisioningManagementGroup.id).post({
                                            success: function() {
                                                setDeviceAndSubmit(device.id);
                                            },
                                            error: function(xhr) {
                                                showGeneralError(xhr.status, CA.CP.getResource("Password.withManagementGroupsConvertError.label"));
                                            },
                                            data: Object.toJSON({managedDevice: {id: device.id}})
                                        });
                                    } else {
                                        // did not find a SMG with a CP Provisioning ID
                                        // so, create a new management group for this managed device
                                        new CA.CP.SubscriberManagementGroups(session.subscriberId).put({
                                            success: function () {
                                                setDeviceAndSubmit(device.id);
                                            },
                                            error: function (xhr) {
                                                showGeneralError(xhr.status, CA.CP.getResource("Password.withManagementGroupsCreateError.label"));
                                            },
                                            data: Object.toJSON({managedDevice: {id: device.id}})
                                        });
                                    }
                                });
                            }
                        },
                        on404:showInvalidDevice,
                        on403:showDeviceBelongsToAnotherSubscriber,
                        error:showGeneralError
                    });
                }
            });
        } else if (CA.CP.Cookies.deviceId() && CA.CP.Cookies.managementGroupId()) {
            setDeviceAndSubmit(CA.CP.Cookies.deviceId(), CA.CP.Cookies.managementGroupId());
        } else {
            withManagementGroups(session.subscriberId, false, function(managementGroups) {
                switch (managementGroups.length) {
                    case 0:
                        showSubscriberHasNoDevices();
                        break;
                    case 1:
                        setDeviceAndSubmit(managementGroups[0].managedDevice.id, managementGroups[0].id);
                        break;
                    default:
                        var devices = loginProblems.find(".devices").empty();
                        managementGroups.each(function(managementGroup) {
                            var md = managementGroup.managedDevice;
                            var text = md.friendlyName + ": " + md.serialNumber;
                            var value = md.oui + ":" + md.serialNumber;
                            var option = $j("<option>").val(value).text(text);
                            devices.append(option);
                        });
                        loginForm.find("#submitButton, #problemlink").addClass("inactive");
                        $j(".authFields", loginForm).find("INPUT").attr("disabled", "disabled");
                        loginProblems.find(".devicesRow").show();
                }
            });
        }
    }

    function hasValue(s) {
        return s != null && s.length > 0;
    }

    function okToContinue() {
        return (!passwordChangeRequired)
                && hasValue(CA.CP.Cookies.sessionId())
                && hasValue(CA.CP.Cookies.subscriberId())
                && hasValue(CA.CP.Cookies.deviceId())
                && hasValue(CA.CP.Cookies.managementGroupId());
    }

    new CA.CP.Branding("Global.UserInterface.ISPHelpDesk").getText({
        success: function(ispPhoneSupport) {
            $j(".ispPhoneSupport").text(ispPhoneSupport);
            $j(".onHaveIspPhoneSupport").removeClass("invisible");
        }
    });

    function isDeviceWithoutSubscriber() {
        if (!queryParameters.device) return false;
        if (queryParameters.subscriber) return false;
        return true;
    }

    if (isDeviceWithoutSubscriber()) {
        new CA.CP.Branding("Global.UserInterface.ISPWithoutSubscriberLoginExplanation").getText({
            success: function(ispExplanation) {
                $j(".ispWithoutSubscriber #explanation").html(ispExplanation);
                $j(".ispWithoutSubscriber").removeClass("invisible");
                $j("#loginBackground").hide();
                $j("#problemlink").hide();
            }
        });
    }

});


P.D Este router es de mi propiedad, si alguno quiere pruebas les enviare fotos y manuales del mismo por mp.

Saludos por alla.


«Dios no juega a los dados, usa /dev/random.»
twitter: @cloudswx