首页 > 其他分享 >BUUCTF [De1CTF 2019]SSRF Me

BUUCTF [De1CTF 2019]SSRF Me

时间:2023-09-06 09:56:42浏览次数:57  
标签:Me BUUCTF return De1CTF self param sign result action

源码

#! /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) 

发现有三个路由分别是:

/geneSign

@app.route("/geneSign", methods=['GET', 'POST']) 
def geneSign(): 
    param = urllib.unquote(request.args.get("param", "")) 
    action = "scan" 
    return getSign(action, param) 

取得传递的参数param和固定的action,传入和调用getSign()函数。

/De1ta

@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()) 

取得传递的参数param和从cookie传递的actionsign,绕过waf()函数后,创建Task对象,并调用Exec方法,最后以json形式返回结果。

/

@app.route('/') 
def index(): 
    return open("code.txt","r").read() 

获取首页源码

Task-Exec()

首先我们要通过

if (self.checkSign()):

并且两个action的判断都要满足

if "scan" in self.action:
if "read" in self.action:

因为用的是in,所以action是scanreadreadscan都可行。
接下来读取flag.txt,并通过

tmpfile.write(resp)

写入result.txt给json.dumps。

self.checkSign()

满足self.checkSign(),就需要满足

hashlib.md5(secert_key + param + action).hexdigest() = self.sign

但是我们不知道secret_key的值是多少,它只存在于服务端。注意到/geneSign中已经将action定为scan,所以我们传入的param可以为flag.txtread,这样的话还是会拼接为secert_key + 'flag.txtread' + 'scan'

构建payload1:/geneSign?param=flag.txtread
得到哈希值ee67bf7b971abc8fc4bc3c3c5694563b

构建payload2:

/De1ta?param=flag.txt
Cookie: action=readscan;sign=ee67bf7b971abc8fc4bc3c3c5694563b

得到flag{bad42dee-4118-4c77-809b-9adfaa0387b7}

方法2-哈希长度扩展攻击

当md5加密参数存在用户可控变量时

(md5(secret+args); args可控)

我们可以通过手动填充args部分,添加(控制)最后一组明文,并根据上一次加密的结果逆向再和库中固定的加密轮密钥来演算出我们新添加的一组明文的加密结果,进而推出最后的新密文。
简单地说就是用户可以用过控制args变量来来控制最后的加密结果md5(....)而不需要知道secret值。

需要工具hashpump

待补充




参考链接:
https://blog.csdn.net/RABCDXB/article/details/115412359

标签:Me,BUUCTF,return,De1CTF,self,param,sign,result,action
From: https://www.cnblogs.com/darkcyan/p/17679902.html

相关文章

  • Vue3 setup 如何添加name
    Vue3setup如何添加name小满zs2022-11-2915:5810778 开启掘金成长之旅!这是我参与「掘金日新计划·12月更文挑战」的第2天,点击查看活动详情Vue3中name有什么用呢?1.在递归组件的时候需要定义name2.配合keep-aliveincludeexclude可以缓存组件3.在Vue有报错或......
  • Metinfo6.0.0任意文件读取漏洞复现
    1.1、漏洞描述漏洞名称:MetInfo任意文件读取漏洞简介:MetInfo是一套使用PHP和MySQL开发的内容管理系统,其中的/app/system/include/module/old_thumb.class.php文件存在任意文件读取漏洞,攻击者可利用该漏洞读取网站的敏感文件。下载地址:历史版本安装文件下载Ver_6.0.01.2、漏洞......
  • Metinfo5.0.4-任意文件包含漏洞复现
    目录文件包含漏洞描述:漏洞等级影响版本漏洞利用蚁剑连接图片马读取敏感目录读取php源码登录管理员界面http://127.0.0.1/MetInfo5.0.4/admin/上传一句话木马,或者图片马制作图片木马copy1.jpg/b+1.php/a2.jpg文件包含首页漏洞描述:MetInfo是一个专业的企业级CMS建......
  • pytest.mark.parametrize() 列表2
    yaml文件:--list_order-南京--list_order-北京--list_order-郑州--list_order-西安 代码:importjsonimportpprintimportpytestfromSlience.utils.login_utilimportLoginfromSlience.utils.request_utilimportSendReque......
  • Proj CDeepFuzz Paper Reading: Framework for Evaluating Faithfulness of Local Exp
    Abstract本文:Task:1.studythefaithfulnessofanexplanationsystemtotheunderlyingpredictionmodelonconsistencyandsufficiency2.introducequantitativemeasuresofconsistencyandsufficiency3.provideestimatorsandsamplecomplexityboundsfo......
  • pytest.mark.parametrize() 字典
    yaml文件-action:list_orderkeywords:南京-action:list_orderkeywords:郑州-action:list_orderkeywords:西安代码:importjsonimportpprintimportpytestfromSlience.utils.login_utilimportLoginfromSlience.utils.request_utilimpo......
  • pytest.mark.parametrize() 列表1
    yaml文件:-南京-北京-郑州-西安  代码:importjsonimportpprintimportpytestfromSlience.utils.login_utilimportLoginfromSlience.utils.request_utilimportSendRequestfromSlience.utils.yaml_utilimportread_yaml@pytest.fixture(scope=......
  • centos7安装桌面-GNOME
    CENTOS7安装桌面系统GNOME桌面#yum安装#更新已安装软件yumupgrade-y#安装额外yum源yuminstallepel-release-y#安装XWindowSystemyumgroupinstall"XWindowSystem"-y#安装Xfce4yumgroupinstallXfce-y#安装中文字体和输入法yuminstallcjkuni-ukai......
  • Element UI实现每次只弹出一个Message消息提示
    前言在开发Web应用程序时,我们经常需要使用消息提示来向用户展示重要信息。ElementUI提供了一个方便易用的组件——Message,可以用于显示各种类型的消息提示。然而,默认情况下,当多个消息提示同时触发时,它们会依次累积在页面上,导致界面上出现多个消息提示。本篇博客将介绍如何通过对......
  • 【css兼容】flex在低版本 chrome 浏览器的兼容问题
    https://blog.csdn.net/weixin_43841308/article/details/111246537 前言【感官】使用ElementUI构建如下布局【逻辑】具体代码:【现象】谷歌浏览器44.0.2403.125m版本显示main内容不全谷歌浏览器57.0.2987.133版本页面正常flex兼容性【猜想】display:flex在网站兼容性......