Skip to content

Discovering the Bypass

The /testsite endpoint showed what was understood to be the amazing site that was expected to debut on 12/25 I suppose. You can view the site here. It really isn't anything that special, just a site describing how awesome their casino is. One particular endpoint caught my attention, and it was the /contact GET endpoint, linked from the site as well:

Contact Us

Don't want to contact anyone just yet, but I can click on that Dashboard Login link to get yet another endpoint, /login GET.

Login

Whenever I am presented with a login, I always try some of the low-hanging-fruit password combinations, like admin:password, admin:admin, admin:1234, etc. Nothing seemed to work here, but there was a password recovery link...

Password Recovery

But I need a valid email! Gah, oh well. Most likely I will need an email account to obtain the token, even though the email code is commented out in the source code...hm.

Speaking of source code, it was at this point that I started reviewing the source code with a fine toothed comb, and eventually came across something of interest!

In the server.js file, by the /contact POST endpoint, I noticed the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
app.post('/postcontact', function(req, res, next){
    var fullname = xss( ReplaceAnyMatchingWords(req.body.fullname) );
    var email = xss( ReplaceAnyMatchingWords( req.body.email) );
    var phone = xss( ReplaceAnyMatchingWords( req.body.phone) );
    var country = xss( ReplaceAnyMatchingWords( req.body.country ) );
    var date = new Date();
    var d = date.getDate();
    var mo = date.getMonth();
    var yr = date.getFullYear();
    var current_hour = date.getHours();
    var date_created = dateFormat(date, "yyyy-mm-dd hh:MM:ss");

    tempCont.query("SELECT * from uniquecontact where email="+tempCont.escape(email), function(error, rows, fields){

        if (error) {
            console.log(error);
            return res.sendStatus(500);
        }

        var rowlength = rows.length;
        if (rowlength >= "1"){
            session = req.session;
            session.uniqueID = email;
            req.flash('info', 'Email Already Exists');
            res.redirect("/contact");

        } else {

            tempCont.query("INSERT INTO uniquecontact (full_name, email, phone, country, date_created) VALUE (?, ?, ?, ?, ?)", [fullname, email, phone, country, date_created], function(error, rows, fields) {

                if (error) {
                    console.log(error);
                    return res.sendStatus(500);
                }
        // snip...

I noticed this very interesting conditional. If I add a new contact to the form, it accepts it happily. But if I re-enter the same email address, it checks to see if that email exists, and if it does, it creates a new session.uniqueID variable and sets it to the email I already added! Wait a minute, if I wanted to see the /dashboard GET endpoint, how exactly does it check if I've logged in?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
app.get('/dashboard', function(req, res, next){

    session = req.session;

    if (session.uniqueID){

        tempCont.query("SELECT * from uniquecontact order by date_created desc", function(error, rows, fields){

            if (error) {
                return res.sendStatus(500);
            }

            var rowdata = rows.length;

            //set default variables
            var totalRecord = rowdata,
                pageSize = 10,
                pageCount = Math.ceil(rowdata/10),
                currentPage = 1,
                encontact = rows,
                encontactArrays = [],
        // snip...

It just checks to see if I have the session.uniqueID variable set! Does this mean I can access the dashboard now?

YUP!

Yup!