ctf-ssrf

[De1CTF 2019]SSRF Me

来源:在这里插入图片描述

源码分析

看到有源码的提示直接去代码审计

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

先来一个ai生成的大刚看一下:
1-2: 设置编码格式和导入所需模块。
4: 生成一个随机的16字节密钥用于签名。
6-13: 定义Task类,用于处理接收到的任务请求,包括执行动作、验证签名及结果反馈。
15-17: 检查沙箱目录是否存在,不存在则创建,用于隔离不同客户端的请求结果。
19-24: Exec方法,根据不同的action执行相应操作,并返回执行结果。
26-29: checkSign方法,验证请求中的签名是否正确。
31-40: /geneSign路由,用于生成特定参数和动作的签名。
42-63: /De1ta路由,处理主要的挑战请求,包括解析参数、创建Task实例并执行任务,返回JSON格式的结果。
65-68: '/'路由,简单地返回code.txt文件内容作为主页。
70-77: scan函数,尝试访问指定URL并返回前50个字符,超时则返回错误信息。
79-82: getSign函数,生成基于密钥、参数和动作的MD5签名。
84-87: md5函数,计算给定内容的MD5哈希值。
89-94: waf函数,基础的WAF逻辑,检查请求参数是否包含可能的攻击字符串(如以"gopher"或"file"开头),返回布尔值表示是否拦截请求。
96-104: 主程序部分,设置Flask应用的调试模式为关闭,并在所有接口上监听。

genesign路由

由上面代码和分析我们可以知道当我们访问/geneSign路由时那个页面会返回secert_key + param + action的MD5值,在genesign中secert_key,action是固定值,可操作的只有param。

/De1ta路由

看/De1ta路由它调用了Task类我们最终获得flag的代码就在这个类中,所以我们必须通过/De1ta来获取flag,对于这个路由,param,action,sign都是我们可以操作的。

Task类

从这个类中我们可以分析出当访问/De1ta路由时会获取action, param, sign的值,然后初始化result字典 并设置result[‘code’] = 500,然后self.checkSign()判断计算出的sign值和传入的sign是否相同相同则执行if中的内容if “scan” in self.action:当这个条件成立会将self.param中的内容赋值给resp中,在这里param需要为flag.txt我们才能读取到flag,tmpfile.write(resp)然后这个语句会将flag内容写入到/result.txt文件中。if “read” in self.action:如果在action中有read则会将/result.txt的内容赋值给result[‘data’] 最终会返回result中的内容即flag。

所以我们需要在genesign路由中获取secert_key+flag.txtread+scan的md5值。

然后在/De1ta路由中传入参数param=flag.txt在cookie中传入action=readscan;sign=在genesign路由中获取secert_key+flag.txtread+scan的md5值

演示

获取secert_key+flag.txtread+scan的md5值。
在这里插入图片描述

访问/De1ta路由构造参数获取flag

在这里插入图片描述

还有一个方法是(哈希拓展攻击)

参考大佬链接:https://blog.csdn.net/2301_76690905/article/details/135464067
https://blog.csdn.net/2301_76690905/article/details/135177452?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170471062516800185859013%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170471062516800185859013&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-135177452-null-null.nonecase&utm_term=%E5%93%88%E5%B8%8C&spm=1018.2226.3001.4450

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CTFHub是一个CTF(Capture The Flag)比赛平台,提供了各种安全挑战和漏洞利用的题目。在引用\[1\]中提到了一些与SSRF(Server-Side Request Forgery)相关的内容,包括伪协议读取文件、端口扫描、POST请求上传文件、FastCGI、Redis协议、URL Bypass、数字IP Bypass、302跳转Bypass和DNS重绑定 Bypass。引用\[2\]中提到了CGI和FastCGI协议的运行原理,并介绍了使用Gopherus工具生成攻击FastCGI的payload。引用\[3\]中提到了一个使用Python脚本进行端口扫描的例子。 所以,CTFHub ssrf是指在CTFHub平台上与SSRF相关的内容和挑战。 #### 引用[.reference_title] - *1* [CTFHub—SSRF](https://blog.csdn.net/qq_45927819/article/details/123400074)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [CTFHUB--SSRF详解](https://blog.csdn.net/qq_49422880/article/details/117166929)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [CTFHub技能树笔记之SSRF:内网访问、伪协议读取文件、端口扫描](https://blog.csdn.net/weixin_48799157/article/details/123886077)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值