题目描述:Your task is pretty simple: Upload two PDF files. The first should contain the string “NO FLAG!” and the other one “GIVE FLAG!”, but both should have the same MD5 hash! 您的任务非常简单:上传两个PDF文件。 第一个应该包含字符串”NO FLAG!”另一个”GIVE FLAG!”,但两者都应该有相同的MD5哈希! 源代码中提示My source is at /src.tgz,下载下来 主要代码
题目描述:Our web admin name's "Mc Donald" and he likes apples and always forgets to throw away his apple cores... robots.txt中发现Disallow: /backup/.DS_Store 使用.DS_Store文件泄漏利用脚本 找到flag
Not(e) accessible
网页源码中提示My source is at /src.tgz。 关键源码 app.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
require'sinatra' set :bind, '0.0.0.0'
get '/get/:id'do File.read("./notes/#{params['id']}.note") end
get '/store/:id/:note'do File.write("./notes/#{params['id']}.note", params['note']) puts "OK" end
题目描述 To enable secure microservices (or whatever, we don’t know yet) over Wee in the future, we created a specific DB_SECRET, only known to us. This token is super important and extremely secret, hence the name. The only way an attacker could get hold of it is to serve good booze to the admins. Pretty sure it’s otherwise well protected on our secure server. 提示源码:/pyserver/server.py 漏洞代码
return jsonify_projects(query_db( "SELECT code, userName, title, public, type, lastModified, created, content FROM projects WHERE created < '{}' " "ORDER BY {} LIMIT 10".format(offset, sql_sorting), one=False), username, "admin")
json数据没有经过过滤被直接拼接进sql语句中,因此存在sql注入。 但是还要绕过if name != "admin":,name从cookie中直接获取,因此我们登陆后,把cookie中的name改成admin即可。
Localhost
题目描述 We came up with some ingenious solutions to the problem of password reuse. For users, we don’t use password auth but send around mails instead. This works well for humans but not for robots. To make test automation possible, we didn’t want to send those mails all the time, so instead we introduced the localhost header. If we send a request to our server from the same host, our state-of-the-art python server sets the localhost header to a secret only known to the server. This is bullet-proof, luckily. 提示源码:/pyserver/server.py 搜索localhost可以找到 after_request: 每一个请求之后绑定一个函数 由于使用了remote_addr,因此我们无法伪造源ip,只能找一个ssrf的点。 发现/api/proxyimage存在ssrf。
题目描述:Phew, we totally did not set up our mail server yet. This is bad news since nobody can get into their accounts at the moment… It’ll be in our next sprint. Until then, since you cannot login: enjoy our totally finished software without account. 意思就是没有邮件服务器,你无法登陆。所以我们想办法登陆进去即可。 提示 源码/pyserver/server.py 关键源码
@app.route("/api/signup", methods=["POST"]) defsignup(): usertype = "user" json = request.get_json(force=True) name = escape(json["name"].strip()) email = json["email"].strip() iflen(name) == 0: raise Exception("InvalidUserName") iflen(email) == 0: raise Exception("InvalidEmailAddress") ifnotlen(email.split("@")) == 2: raise Exception("InvalidEmailAddress") email = escape(email.strip()) # Make sure the user name is 4-25 letters/digits only. iflen(name) < 4orlen(name) > 25: raise Exception("InvalidUserName")
ifnotall([x in string.ascii_letters or x in string.digits for x in name]): raise Exception("InvalidUserName") # Check if name exists if query_db("SELECT name FROM users WHERE name=?", name): raise Exception("UserExists") if query_db("Select id, name FROM users WHERE email=?", email): raise Exception("EmailExists") # Insert user // TODO: implement the verification email db = get_db() c = db.cursor() c.execute("INSERT INTO users(name, email, type) values(?, ?, ?)", (name, email, usertype)) db.commit() return jsonify({"success": True})
@app.route("/api/login", methods=["POST"]) deflogin(): print("Logging in?") # TODO Send Mail json = request.get_json(force=True) login = json["email"].strip() try: userid, name, email = query_db("SELECT id, name, email FROM users WHERE email=? OR name=?", (login, login)) except Exception as ex: raise Exception("UserDoesNotExist") return get_code(name)
@app.route("/api/verify", methods=["POST"]) defverify(): code = request.get_json(force=True)["code"].strip() ifnot code: raise Exception("CouldNotVerifyCode") userid, = query_db("SELECT userId FROM userCodes WHERE code=?", code) db = get_db() c = db.cursor() c.execute("DELETE FROM userCodes WHERE userId=?", (userid,)) token = random_code(32) c.execute("INSERT INTO userTokens (userId, token) values(?,?)", (userid, token)) db.commit() name, = query_db("SELECT name FROM users WHERE id=?", (userid,)) resp = make_response() resp.set_cookie("token", token, max_age=2 ** 31 - 1) resp.set_cookie("name", name, max_age=2 ** 31 - 1) resp.set_cookie("logged_in", LOGGED_IN) return resp