Пример #1
0
def unlockChallengeFile(chalID, code):
    userName = current_user.name
    if chalID in challenges.idToKey:
        cfg = copy.deepcopy(challenges.getChalConfig(chalID))
        allowPostUnlock = ""
        try:
            allowPostUnlock = cfg["unlock_post"].split(",")
        except:
            allowPostUnlock = []
        try:
            unlockCodes = cfg["unlock_codes"].split(",")
        except:
            unlockCodes = []
        if not (len(allowPostUnlock) == len(unlockCodes)):
            return "Inconsistent length of unlock codes"
        postUnlock = dict(zip(unlockCodes, allowPostUnlock))
        if code in postUnlock:
            # unlock code found in configuration file
            fileName = postUnlock[code]
            #print("FOUND POSTUNLOCK:",code,fileName)
            db.unlockFile(userName, chalID, fileName, code,
                          getClientIPAddress())
        else:
            # is someone trying random unlock codes?
            return "ERROR: what are you trying to do?"
    return genericError
Пример #2
0
def getChalHints(chalID):
    if not (chalID in challenges.idToKey):
        return {"results": "Challenge not found!"}
    userName = current_user.name
    chalHints = db.getUserHints(userName, chalID)
    cfg = challenges.getChalConfig(chalID)
    _heartBeat = False
    try:
        _heartBeat = False
        try:
            _heartBeat = request.values["heartbeat"]
        except:
            pass
        if _heartBeat:
            # Handle HeartBeat
            #print("HB:", chalID, userName, getClientIPAddress())
            db.addHeartBeat(userName, chalID, getClientIPAddress())
            # Handle File Cache
            hasFiles = False
            try:
                _files = json.loads(request.values["userfiles"])
                hasFiles = True
            except:
                pass
            if hasFiles:
                allChalDir = db.getCacheDir(userName)
                cacheDir = allChalDir.get(chalID, None)
                if None != cacheDir:
                    for f in _files:
                        fullPath = os.path.normpath(os.path.join(cacheDir, f))
                        #print("Write Cache File:",fullPath)
                        with open(fullPath, "w+") as o:
                            o.write(_files[f])
                    #p(_files)
                else:
                    print("ERROR: could not get the cache dir!!!")
    except Exception as e:
        print("Exception: " + str(e))
    hintsHtml = "<br>"
    for hint in chalHints:
        html = '<div class="box3 sb14">' + hint["html"] + '</div>'
        hintsHtml = html + hintsHtml
    hintsHtml = "<br>" + hintsHtml
    return {"hints": hintsHtml}
Пример #3
0
def postSendAll(chalID):
    if not (chalID in challenges.idToKey):
        return {"results": "Challenge not found!"}
    userName = current_user.name
    userIP = getClientIPAddress()
    db.unlockChallenge(userName, chalID, userIP)
    cfg = copy.deepcopy(challenges.getChalConfig(chalID))
    userData = json.loads(request.values["userfiles"])
    r = challenges.evalChalFromDirStruct(userName, userIP, chalID, userData)
    feedback = cfg.get(
        "feedback",
        "collect")  # by default collect feedback from player on the challenge
    # set feedback to "skip" in challenges.yaml to skip this step
    return {
        "results": r["result"],
        "log-results": r["logger"],
        "solve": r["solve"],
        "feedback": feedback
    }
Пример #4
0
def challengeRoot(chalID):
    userName = current_user.name
    ipAddress = getClientIPAddress()
    #db.addChalCache(userName,chalID,"xxx")
    if chalID in challenges.idToKey:
        cfg = challenges.getChalConfig(chalID)
        rootFile = cfg["root_file"]
        db.unlockChallenge(userName, chalID, ipAddress)
        db.addInteraction(userName, chalID, "ENTRY", "visit challenge", "",
                          ipAddress)
        if cfg["root"] == "template":  # programming challenges
            isAdmin = db.isUserAdmin(userName)
            return render_template(rootFile,
                                   cfg=cfg,
                                   hbTimer=heartBeat,
                                   isAdmin=isAdmin)
        elif cfg["root"] == "challenge":  # multiple choice questions
            chalDir = cfg["directory"]
            tplFile = os.path.join(chalDir, rootFile)
            tpl = open(tplFile, "r").read()
            t = Template(tpl)
            isAdmin = db.isUserAdmin(userName)
            return t.render({
                "cfg": cfg,
                "hbTimer": heartBeat,
                "chalID": chalID,
                "isAdmin": isAdmin
            })
        else:
            return genericError
    else:
        p(chalID)
        p(challenges.idToKey)
        db.addInteraction(userName, chalID, "ENTRY", "unkown challenge", "",
                          ipAddress)
        return genericError
Пример #5
0
def postSend(chalID):
    if not (chalID in challenges.idToKey):
        return {"results": "Challenge not found!"}
    userName = current_user.name
    userIP = getClientIPAddress()
    db.unlockChallenge(userName, chalID, userIP)
    cfg = copy.deepcopy(challenges.getChalConfig(chalID))
    mainFileContent = request.values["usercontent"]
    #print("----mainFileContent----------------------")
    #print(mainFileContent)
    #print("-----------------------------------------")
    inputFileContent = ""
    try:
        inputFileContent = request.values["inputfile"]
        #print("~~~~inputFileContent~~~~~~~~~~~~~~~~~~~~~")
        #print(inputFileContent)
        #print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    except:
        pass
    (result, d, tcDir) = challenges.evalChalFromString(userName, chalID,
                                                       mainFileContent,
                                                       inputFileContent)
    chalLogLines = challenges.collectChallengeEvalLogs(tcDir)
    chalLog = []
    for s in chalLogLines:
        chalLog.append(escape(s))
    chalLog = "<br>".join(chalLog)
    failMsg = None
    failPrio = None
    tag = None
    if result == False:
        try:
            for e in d:
                if d[e]["pass"] == "FAIL":
                    newPrio = int(d[e]["nr"])
                    if None == failPrio:
                        failPrio = newPrio
                        failMsg = d[e]["msg"]
                        tag = d[e]["x"]
                    else:
                        if newPrio < failPrio:
                            failPrio = newPrio
                            failMsg = d[e]["msg"]
                            tag = d[e]["x"]
            if failMsg:
                hintHtml = ""
                if tag in challenges.allTags:
                    myTag = challenges.allTags[tag]
                    tagDesc = myTag["description"]
                    hintHtml = tagDesc.format(**myTag)
                    db.addHintTag(userName, chalID, tag, hintHtml,
                                  getClientIPAddress())
                if False:  # Toggle this to test a new tag
                    myTag = challenges.allTags["TEST_TAG"]
                    tagDesc = myTag["description"]
                    hintHtml = tagDesc.format(**myTag)
                    #print("HINT:",hintHtml)
                    db.addHintTag(userName, chalID, "TEST_TAG", hintHtml,
                                  getClientIPAddress())
                db.addInteraction(userName, chalID, "FAIL", failMsg, tcDir,
                                  getClientIPAddress())
                return {"results": failMsg, "log-results": chalLog}
            else:
                msg = "Oops! please contact one of the coaches"
                db.addInteraction(userName, chalID, "OOPS", msg, tcDir,
                                  getClientIPAddress())
                return {"results": msg, "log-results": chalLog}
        except:
            pass
        #p(d)
        msg = "Oops! - where did the failed result go to?"
        db.addInteraction(userName, chalID, "OOPS", msg, tcDir,
                          getClientIPAddress())
        return {"results": msg, "log-results": chalLog}
    else:
        flag = str(cfg["flag"])
        db.addInteraction(userName, chalID, "SOLVE", flag, tcDir,
                          getClientIPAddress())
        return {
            "results": "Well done, here is your flag: " + flag,
            "log-results": chalLog
        }
Пример #6
0
def sendFile(chalID):
    userName = current_user.name
    ipAddress = getClientIPAddress()
    try:
        resetChal = False
        try:
            resetChal = request.values["reset"] == "true"
        except:
            pass
        if not (chalID in challenges.idToKey):
            db.addInteraction(userName, chalID, "OOPS", "challenge not found",
                              "", ipAddress)
            return "Not Found!"
        else:
            chalKey = challenges.idToKey[chalID]
            chalPath = challenges.allChallenges[chalKey]["directory"]
            allChalDir = db.getCacheDir(userName)
            chalDir = allChalDir.get(chalID, None)
            cacheFiles = False
            if None != chalDir:
                # We have already a Cache... use it...
                #print("GET Cache: for user", userName)
                srcDir = chalDir
            else:
                # We do not have a Cache... we will create it...
                newUUID = str(uuid.uuid4())  # Generate new random UUID
                cacheDir = "upload/cache/" + newUUID
                srcDir = chalPath
                cacheFiles = True
                os.mkdir(cacheDir)
                db.addChalCache(userName, chalID, cacheDir)
                #print("GEN Cache:",cacheDir," for chalID",chalID," for user", userName)
            #print("Send Challenge Directory")
            cfg = challenges.getChalConfig(chalID)
            files = cfg.get("files", "")
            filesToSend = []
            if not (files == ""):
                filesToSend = cfg.get("files", "").split(",")
                firstFile = filesToSend[0]
                if firstFile[:2] != "./": firstFile = "./" + firstFile
            # Make sure that each file starts with "./"
            allFiles = []
            for f in filesToSend:
                if f[:2] != "./":
                    allFiles.append("./" + f)
                else:
                    allFiles.append(f)
            filesToSend = sorted(allFiles)
            fContent = {}
            #print("filesToSend: ",filesToSend)
            for f in filesToSend:
                if resetChal:
                    # this time we need to create a cache for the files
                    _srcFile = os.path.join(chalPath, f)
                    _dstFile = os.path.join(srcDir, f)
                    #print("FROM: "+_srcFile+" TO: "+_dstFile)
                    utils.copyWithFullPath(_srcFile, _dstFile)
                if cacheFiles:
                    # this time we need to create a cache for the files
                    _srcFile = os.path.join(srcDir, f)
                    _dstFile = os.path.join(cacheDir, f)
                    #print("FROM: "+_srcFile+" TO: "+_dstFile)
                    utils.copyWithFullPath(_srcFile, _dstFile)
                fContent[f] = utils.fileContents(os.path.join(srcDir, f))
            jstree = utils.jstreeJSON(filesToSend)
            r = {
                "fcontent": fContent,
                "dirstruct": jstree,
                "workFile": firstFile
            }
            #print("Send Files (r):")
            #p(r)
            return r
    except Exception as e:
        userName = current_user.name
        db.addInteraction(userName, chalID, "OOPS",
                          "error loading main challenge file", "", ipAddress)
        print("ERROR:", str(e))
        return "Error loading main challenge file"
Пример #7
0
def challengeFile(chalID, fileName):
    userName = current_user.name
    if chalID in challenges.idToKey:
        cfg = copy.deepcopy(challenges.getChalConfig(chalID))
    else:
        return genericError
    if request.method == 'GET':
        #print("Try allow_get...")
        try:
            allowHtml = cfg["allow_get"]
        except:
            allowHtml = ""
        allowHtml = allowHtml.split(",")
        #print("allow: ",allowHtml)
        if fileName in allowHtml:
            chalDir = cfg["directory"]
            fileName = os.path.join(chalDir, fileName)
            return send_file(fileName)
        else:
            return genericError
    _postValuesAsDict = request.values.to_dict(flat=False)
    postValuesAsDict = {}
    # ugly hack...
    for k in _postValuesAsDict:
        newK = "".join("_".join(k.split("[")).split("]"))
        postValuesAsDict[newK] = _postValuesAsDict[k]
    postValuesAsDict = utils.processPost(postValuesAsDict)
    limitFile = int(cfg["limitFile"]) if ("limitFile" in cfg) else 0
    db.unlockChallenge(userName, chalID, getClientIPAddress())
    if limitFile > 0:
        n = db.getChalNrTimes(userName, chalID)
        if (n >= limitFile):
            return "Limit exceeded"
    db.incChalNrTimes(userName, chalID, getClientIPAddress())
    allowPost = ""
    try:
        allowPost = cfg["allow_post"]
    except:
        allowPost = ""
    allowPost = allowPost.split(",")
    #print("Try allow_post...")
    if fileName in allowPost:
        chalDir = cfg["directory"]
        tplFile = os.path.join(chalDir, fileName)
        tpl = open(tplFile, "r").read()
        t = Template(tpl)
        try:
            cfg["unlock_codes"] = cfg["unlock_codes"].split(",")
        except Exception as e:
            cfg["unlock_codes"] = []
        html = t.render({
            "post": postValuesAsDict,
            "cfg": cfg,
            "chalID": chalID
        })
        #print("Rendered HTML")
        #print(html)
        #print("")
        # if we can find the flag in the HTML code, then the challenge was solved
        if re.search(cfg["flag"], html):
            db.addInteraction(userName, chalID, "SOLVE", "", "",
                              getClientIPAddress())
        # if we can find this comment in the code, it means that we have failed the challenge
        if re.search("<!-- FAIL -->", html):
            db.addInteraction(userName, chalID, "FAIL", "", "",
                              getClientIPAddress())
        return html
    #print("Try unlock_post...")
    allowPostUnlock = ""
    try:
        allowPostUnlock = cfg["unlock_post"].split(",")
    except:
        allowPostUnlock = []
    try:
        unlockCodes = cfg["unlock_codes"].split(",")
    except:
        unlockCodes = []
    if not (len(allowPostUnlock) == len(unlockCodes)):
        return "Inconsistent length of unlock codes"
    postUnlock = dict(zip(allowPostUnlock, unlockCodes))
    if fileName in allowPostUnlock:
        chalUnlocks = db.getChallengeUnlockFiles(userName)
        flagFound = False
        for u in chalUnlocks:
            if (u["chalID"] == chalID) and (u["unlockCode"]
                                            == postUnlock[fileName]):
                #print("FOUND")
                chalDir = cfg["directory"]
                tplFile = os.path.join(chalDir, fileName)
                tpl = open(tplFile, "r").read()
                t = Template(tpl)
                try:
                    cfg["unlock_codes"] = cfg["unlock_codes"].split(",")
                except Exception as e:
                    cfg["unlock_codes"] = []
                p(postValuesAsDict)
                html = t.render({
                    "post": postValuesAsDict,
                    "cfg": cfg,
                    "chalID": chalID
                })
                #print("Rendered HTML")
                #print(html)
                #print("")
                # if we can find the flag in the HTML code, then the challenge was solved
                if re.search(cfg["flag"], html):
                    db.addInteraction(userName, chalID, "SOLVE", "", "",
                                      getClientIPAddress())
                # if we can find this comment in the code, it means that we have failed the challenge
                if re.search("<!-- FAIL -->", html):
                    db.addInteraction(userName, chalID, "FAIL", "", "",
                                      getClientIPAddress())
                return html
        return "ERROR: a team of highly trained monkeys was just dispatched to ignore your request"
    else:
        return genericError