This challenge was a lot of fun for me. We have the source of a webpage.
Copy <html>
<head>
<title>canvas</title>
<link rel="stylesheet" href="css/style.css"/>
<script src="js/login.js"></script>
</head>
<body>
<div class="container">
<div class="main">
<h2>Canvas login</h2>
<form id="form_id" method="post" name="myform">
<label>User Name :</label>
<input type="text" name="username" id="username"/>
<label>Password :</label>
<input type="password" name="password" id="password"/>
<input type="button" value="Login" id="submit" onclick="validate()"/>
</form>
</div>
</div>
</body>
</html>
I used jq to beautify the code, renamed variables and decoded strings etc. until I found an interesting function and array that I thought was likely the flag:
Copy function validate() {
var _0x4d1a17 = _0x20fe,
_0x32b344 = document['getElementById']('username')['value'],
_0x5997a2 = document[_0x4d1a17('0xd')]('password')[_0x4d1a17('0x0')];
if (_0x32b344 == _0x4d1a17('0x12') && _0x5997a2 == _0x4d1a17('0x12')) return alert(_0x4d1a17('0x9')), window['location'] = 'dashboard.html', ![];
else {
attempt--, alert(_0x4d1a17('0x2') + attempt + _0x4d1a17('0x15'));
if (attempt == 0x0) return document[_0x4d1a17('0xd')](_0x4d1a17('0xb'))['disabled'] = !![], document[_0x4d1a17('0xd')]('password')[_0x4d1a17('0x10')] = !![], document[_0x4d1a17('0xd')]('submit')[_0x4d1a17('0x10')] = !![], ![];
}
}
var res = String['fromCharCode'](0x48, 0x54, 0x42, 0x7b, 0x57, 0x33, 0x4c, 0x63, 0x30, 0x6d, 0x33, 0x5f, 0x37, 0x30, 0x5f, 0x4a, 0x34, 0x56, 0x34, 0x35, 0x43, 0x52, 0x31, 0x70, 0x37, 0x5f, 0x64, 0x33, 0x30, 0x62, 0x46, 0x75, 0x35, 0x43, 0x34, 0x37, 0x31, 0x30, 0x4e, 0x7d, 0xa);
Decoding the 'res' array, I got the flag.