[De1CTF 2019]SSRF Me 1


1.介绍

1.python代码审计

2.python的flask框架

2.步骤

2.1将代码整理,开始进行代码审计。

#! /usr/bin/env python 
#encoding=utf-8 
from flask import Flask 
from flask import request 
import socket 
import hashlib 
import urllib 
import sys 
import os 
import json 
reload(sys) 
sys.setdefaultencoding('latin1') 

app = Flask(__name__) 

secert_key = os.urandom(16) 

class Task: 
    def __init__(self, action, param, sign, ip): 
        self.action = action 
        self.param = param 
        self.sign = sign 
        self.sandbox = md5(ip) 
        if(not os.path.exists(self.sandbox)):   
        #SandBox For    Remote_Addr 
            os.mkdir(self.sandbox) 
    def Exec(self): 
        result = {} 
        result['code'] = 500 
        if (self.checkSign()): 
            if "scan" in self.action: 
                tmpfile = open("./%s/result.txt" % self.sandbox, 'w') 
                resp = scan(self.param) 
                if (resp == "Connection Timeout"): 
                    result['data'] = resp 
                else: 
                    print resp 
                    tmpfile.write(resp) 
                    tmpfile.close() 
                result['code'] = 200 
            if "read" in self.action: 
                f = open("./%s/result.txt" % self.sandbox, 'r') result['code'] = 200 
                result['data'] = f.read() 
                if result['code'] == 500: 
                    result['data'] = "Action Error" 
            else: 
                result['code'] = 500 
                result['msg'] = "Sign Error" 
            return result 
            
        def checkSign(self): 
            if (getSign(self.action, self.param) == self.sign):     return True 
            else: return False 
            #generate Sign For Action Scan. 
@app.route("/geneSign", methods=['GET', 'POST']) 
def geneSign(): 
    param = urllib.unquote(request.args.get("param", "")) 
    action = "scan" 
    return getSign(action, param) 
    
@app.route('/De1ta',methods=['GET','POST']) 
def challenge(): 
    action = urllib.unquote(request.cookies.get("action")) 
    param = urllib.unquote(request.args.get("param", "")) 
    sign = urllib.unquote(request.cookies.get("sign")) 
    ip = request.remote_addr 
    if(waf(param)): 
        return "No Hacker!!!!" 
    task = Task(action, param, sign, ip) 
    return json.dumps(task.Exec()) 
    
@app.route('/') 
def index(): 
    return open("code.txt","r").read() 
   
def scan(param): 
    socket.setdefaulttimeout(1) 
    try: 
        return urllib.urlopen(param).read()[:50] 
    except: return "Connection Timeout" 
   
def getSign(action, param): 
    return hashlib.md5(secert_key + param + action).hexdigest() 
    
def md5(content): 
    return hashlib.md5(content).hexdigest() 
    
def waf(param): 
    check=param.strip().lower() 
    if check.startswith("gopher") or check.startswith("file"):      return True 
    else: return False 
    
if __name__ == '__main__': 
    app.debug = False 
    app.run(host='0.0.0.0',port=80) 

 2.2根据代码代码提示,首先GET传入geneSign?flag.txtread

 得到,sign的值。

2.3GET传入De1ta?param=flag.txt

POST传入action=readscan; sign=7de33f8c2b83938e7fa3ec1c87efa4f4

 得到flag。

3.借鉴

https://guokeya.github.io/post/3aEFZGLd6/

https://www.jianshu.com/p/eb60c856f2a3

https://zhuanlan.zhihu.com/p/34143669

https://www.cnblogs.com/chaojiyingxiong/p/9549987.html

https://blog.csdn.net/icehui2012/article/details/76635534

https://docs.python.org/zh-cn/3/library/os.html?highlight=os#module-os

相关